beeos-claw 0.6.93 → 0.6.96
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/config.js +1 -1
- package/dist/gateway-client.js +1 -1
- package/dist/index.js +1 -1
- package/dist/runtime/central-native-composition.js +1 -1
- package/dist/runtime/central-native-context-engine.js +1 -1
- package/dist/runtime/central-native-credentials.js +1 -1
- package/dist/runtime/central-native-host.js +1 -1
- package/dist/runtime/central-native-output-files.js +1 -0
- package/dist/runtime/central-native-production.js +1 -1
- package/dist/runtime/central-native-response.js +1 -1
- package/dist/runtime/message-service-runtime-message-channel.js +1 -1
- package/dist/runtime/ms-runtime-message-channel-consumer-factory.js +1 -1
- package/dist/runtime/native-cloud-prompt-bridge.js +1 -1
- package/dist/runtime/native-output-file-attempt.js +1 -1
- package/dist/runtime/prepare-openclaw-tool-catalog.js +1 -1
- package/dist/runtime/sandbox-native-activation.js +1 -1
- package/dist/upload/native-output-tool-hook.js +1 -1
- package/dist/upload/tool.js +1 -1
- package/dist/upload/upload-file.js +1 -1
- package/openclaw.plugin.json +4 -0
- package/package.json +6 -3
package/dist/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{mkdirSync,writeFileSync}from"node:fs";import{homedir}from"node:os";import{dirname,join}from"node:path";function trimStr(e){if("string"==typeof e){const
|
|
1
|
+
import{mkdirSync,writeFileSync}from"node:fs";import{homedir}from"node:os";import{dirname,join}from"node:path";function trimStr(e){if("string"==typeof e){const a=e.trim();return a.length>0?a:void 0}}function readInt(e){if("number"==typeof e&&Number.isFinite(e))return Math.trunc(e);if("string"==typeof e){const a=parseInt(e,10);return Number.isFinite(a)?a:void 0}}function readBool(e){return"boolean"==typeof e?e:"true"===e||"false"!==e&&void 0}function pick(e,a){for(const a of e)if(void 0!==a.value)return{value:a.value,source:a.source};return a}const CURRENT_CONFIG_PROTOCOL=1;function shouldTrustOperationalConfig(e){const a=e._generator;if(!a)return!1;return("number"==typeof a.configProtocol?a.configProtocol:0)>=1}const DEFAULT_GATEWAY_URL="ws://127.0.0.1:18789",DEFAULT_LOG_DIR=join(process.env.OPENCLAW_HOME||join(homedir(),".openclaw"),"beeos-logs"),DEFAULT_OPENCLAW_CONFIG_PATH=join(homedir(),".openclaw","openclaw.json");export function resolveConfigWithMeta(e){const a=e.pluginConfig??{},o=e.openclawConfig??{},r=e.openclawConfigPath??DEFAULT_OPENCLAW_CONFIG_PATH,l=shouldTrustOperationalConfig(a),n=pick([{source:"pluginConfig",value:trimStr(a.agentGatewayUrl)},{source:"pluginConfig",value:trimStr(a.platformUrl)},{source:"env",value:trimStr(process.env.AGENT_GATEWAY_URL)}],{source:"default",value:""}),u=a.gateway??{},s=(o.gateway??{}).auth??{},t=pick([...l?[{source:"pluginConfig",value:trimStr(u.url)}]:[],{source:"env",value:trimStr(process.env.BEEOS_GATEWAY_URL)}],{source:"default",value:DEFAULT_GATEWAY_URL}),i=pick([{source:"openclawConfig",value:trimStr(s.token)},{source:"pluginConfig",value:trimStr(u.token)},{source:"env",value:trimStr(process.env.BEEOS_GATEWAY_TOKEN)}],{source:"default",value:""}),c=pick([...l?[{source:"pluginConfig",value:readInt(u.protocol)}]:[]],{source:"default",value:3}),v=pick([...l?[{source:"pluginConfig",value:trimStr(u.clientId)}]:[]],{source:"default",value:`beeos-claw-${process.pid}`}),p=pick([...l?[{source:"pluginConfig",value:trimStr(u.agentId)}]:[]],{source:"default",value:""}),d=a.bridge??{},g=pick([{source:"pluginConfig",value:trimStr(a.keyFile)},{source:"pluginConfig",value:trimStr(d.keyFile)},{source:"env",value:trimStr(process.env.BRIDGE_KEY_FILE)}],{source:"default",value:""}),E=pick([{source:"env",value:trimStr(process.env.BRIDGE_URL)}],{source:"default",value:""}),f=pick([...l?[{source:"pluginConfig",value:trimStr(d.service)}]:[],{source:"env",value:trimStr(process.env.BRIDGE_SERVICE)}],{source:"default",value:"acp"}),m=d.shell??{},_=pick([...l?[{source:"pluginConfig",value:readBool(m.enabled)}]:[],{source:"env",value:readBool(process.env.BEEOS_SHELL_ENABLED)}],{source:"default",value:!0}),S=a.retry??{},A=pick([...l?[{source:"pluginConfig",value:readInt(S.baseMs)}]:[]],{source:"default",value:1e3}),C=pick([...l?[{source:"pluginConfig",value:readInt(S.maxMs)}]:[]],{source:"default",value:6e5}),O=pick([...l?[{source:"pluginConfig",value:readInt(S.maxAttempts)}]:[]],{source:"default",value:0}),I=a.log??{},y=pick([...l?[{source:"pluginConfig",value:readBool(I.enabled)}]:[],{source:"env",value:readBool(process.env.BEEOS_LOG_ENABLED)}],{source:"default",value:!0}),w=pick([...l?[{source:"pluginConfig",value:readBool(I.verbose)}]:[]],{source:"default",value:!1}),T=pick([{source:"pluginConfig",value:trimStr(I.dir)}],{source:"default",value:DEFAULT_LOG_DIR}),R=pick([...l?[{source:"pluginConfig",value:readInt(a.terminalWsPort)}]:[],{source:"env",value:readInt(process.env.BEEOS_TERMINAL_WS_PORT)}],{source:"default",value:18801}),B=(l?trimStr(a.terminalWsAllowedOrigins):void 0)??trimStr(process.env.BEEOS_TERMINAL_WS_ALLOWED_ORIGINS),L=B?B.split(",").map(e=>e.trim()).filter(Boolean):void 0,M=pick([{source:B?"pluginConfig":"default",value:L?.length?L:void 0}],{source:"default",value:["localhost","127.0.0.1","::1"]}),b=!0===readBool(process.env.BEEOS_OPENCLAW_DESKTOP)||"1"===process.env.BEEOS_OPENCLAW_DESKTOP,k=pick([{source:"env",value:readBool(process.env.BEEOS_TERMINAL_SERVICE_ENABLED)},...l&&!0===a.terminalServiceEnabled?[{source:"pluginConfig",value:!0}]:[]],{source:"default",value:b}),h=pick([...l?[{source:"pluginConfig",value:readBool(a.legacyTerminalWsEnabled)}]:[],{source:"env",value:readBool(process.env.BEEOS_LEGACY_TERMINAL_WS_ENABLED)}],{source:"default",value:!1}),N=pick([...l?[{source:"pluginConfig",value:readInt(a.streamIdleTimeoutMs)}]:[],{source:"env",value:readInt(process.env.BEEOS_STREAM_IDLE_TIMEOUT_MS)}],{source:"default",value:15e3}),G=pick([...l?[{source:"pluginConfig",value:readInt(a.streamStaleTimeoutMs)}]:[],{source:"env",value:readInt(process.env.BEEOS_STREAM_STALE_TIMEOUT_MS)}],{source:"default",value:6e5}),W=pick([...l?[{source:"pluginConfig",value:readInt(a.cronSignalWindowMs)}]:[],{source:"env",value:readInt(process.env.BEEOS_CRON_SIGNAL_WINDOW_MS)}],{source:"default",value:6e4}),P=pick([{source:"env",value:trimStr(process.env.CANVAS_RELAY_URL)},{source:"pluginConfig",value:trimStr(a.canvasRelayUrl)}],{source:"default",value:"https://canvas-relay.beeos.ai"}),U=pick([...l?[{source:"pluginConfig",value:readBool(a.canvasEnabled)}]:[],{source:"env",value:readBool(process.env.BEEOS_CANVAS_ENABLED)}],{source:"default",value:!0}),D=pick([...l?[{source:"pluginConfig",value:readBool(a.openclawCanvasCompat)}]:[],{source:"env",value:readBool(process.env.BEEOS_OPENCLAW_CANVAS_COMPAT)}],{source:"default",value:!1}),F=a.messageBus??{},x=pick([{source:"pluginConfig",value:trimStr(F.serviceUrl)},{source:"env",value:trimStr(process.env.MESSAGE_SERVICE_URL)}],{source:"default",value:""}),j=pick([{source:"pluginConfig",value:trimStr(F.principalId)},{source:"env",value:trimStr(process.env.BEEOS_PRINCIPAL_ID)}],{source:"default",value:""}),Y=pick([{source:"pluginConfig",value:readBool(F.a2aEnabled)},{source:"env",value:readBool(process.env.BEEOS_A2A_ENABLED)}],{source:"default",value:!0}),H=pick([{source:"pluginConfig",value:readBool(F.enabled)},{source:"env",value:readBool(process.env.BEEOS_MESSAGE_BUS_ENABLED)}],{source:"default",value:!(!x.value&&!n.value)}),$={agentGatewayUrl:n.value.replace(/\/+$/,""),keyFile:g.value,bridge:{url:E.value,service:f.value,mode:trimStr(d.mode),shell:{enabled:_.value}},gateway:{url:t.value,token:i.value,protocol:c.value,clientId:v.value,agentId:p.value},retry:{baseMs:Math.max(0,A.value),maxMs:Math.max(0,C.value),maxAttempts:Math.max(0,O.value)},log:{enabled:y.value,verbose:w.value,dir:T.value},terminalWsPort:R.value,terminalWsAllowedOrigins:M.value,terminalServiceEnabled:k.value,legacyTerminalWsEnabled:h.value,streamIdleTimeoutMs:Math.max(0,N.value),streamStaleTimeoutMs:Math.max(0,G.value),cronSignalWindowMs:Math.max(0,W.value),canvasRelayUrl:P.value.replace(/\/+$/,""),canvasEnabled:U.value,openclawCanvasCompat:D.value,messageBus:{enabled:H.value,serviceUrl:x.value,principalId:j.value,a2aEnabled:Y.value}},V={agentGatewayUrl:n.source,keyFile:g.source,bridge:{url:E.source,service:f.source,shell:{enabled:_.source}},gateway:{url:t.source,token:i.source,protocol:c.source,clientId:v.source,agentId:p.source},retry:{baseMs:A.source,maxMs:C.source,maxAttempts:O.source},log:{enabled:y.source,verbose:w.source,dir:T.source},terminalWsPort:R.source,terminalWsAllowedOrigins:M.source,terminalServiceEnabled:k.source,legacyTerminalWsEnabled:h.source,streamIdleTimeoutMs:N.source,streamStaleTimeoutMs:G.source,cronSignalWindowMs:W.source,canvasRelayUrl:P.source,canvasEnabled:U.source,openclawCanvasCompat:D.source,messageBus:{enabled:H.source,serviceUrl:x.source,principalId:j.source,a2aEnabled:Y.source}},K=[];$.agentGatewayUrl||K.push({code:"CONFIG_AGENT_GATEWAY_URL_MISSING",severity:"error",message:"agentGatewayUrl is required for file uploads and Agent Gateway callbacks",nextSteps:[`Set plugins.entries.beeos-claw.config.agentGatewayUrl in ${r}`,"Or set the AGENT_GATEWAY_URL environment variable"]}),$.gateway.token||K.push({code:"CONFIG_GATEWAY_TOKEN_MISSING",severity:"warn",message:"gateway.token is empty; Gateway auth may fail if authentication is enabled",nextSteps:[`Set gateway.auth.token in ${r}`,`Or set plugins.entries.beeos-claw.config.gateway.token in ${r}`]});const q=o.tools,J=q&&"object"==typeof q&&!Array.isArray(q)?q.allow:void 0;return Array.isArray(J)&&0===J.length&&K.push({code:"CONFIG_TOOLS_ALLOW_EMPTY",severity:"warn",message:'openclaw.json tools.allow is an empty array; OpenClaw treats an explicit empty allowlist as no tools, so the model only sees tool_search/tool_call/tool_describe and every real tool call fails with "Unknown tool id"',nextSteps:[`Remove tools.allow from ${r}, or list the tools the agent may call`,"Restart the Gateway after changing openclaw.json"]}),{config:$,sources:V,validation:K,openclawConfigPath:r}}export function resolveConfig(e){const{config:a,validation:o}=resolveConfigWithMeta({pluginConfig:e}),r=o.find(e=>"error"===e.severity);if(r)throw new Error(`[beeos-claw] ${r.message}`);return a}const MIRROR_PATH=join(process.env.OPENCLAW_HOME||join(homedir(),".openclaw"),"beeos-claw","openclaw.json");export function mirrorOpenClawConfig(e){if(!e||"object"!=typeof e||Array.isArray(e))return{copied:!1,destinationPath:MIRROR_PATH,reason:"config_invalid"};try{return mkdirSync(dirname(MIRROR_PATH),{recursive:!0}),writeFileSync(MIRROR_PATH,JSON.stringify(e,null,2)+"\n",{encoding:"utf8",mode:384}),{copied:!0,destinationPath:MIRROR_PATH}}catch(e){return{copied:!1,destinationPath:MIRROR_PATH,reason:e instanceof Error?e.message:"write_failed"}}}
|
package/dist/gateway-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WebSocket}from"ws";import{EventEmitter}from"node:events";import{randomUUID,createHash}from"node:crypto";import{loadOrCreateDeviceIdentity,buildDeviceAuthPayload,signDeviceAuth,ensureDevicePaired,warmupCryptoSign}from"./device-identity.js";const MIN_PROTOCOL_VERSION=3,MAX_PROTOCOL_VERSION=4,CONNECT_TIMEOUT_MS=3e4,HEARTBEAT_INTERVAL_MS=15e3,LIVENESS_TIMEOUT_MS=6e4,CHAT_HISTORY_PAGE_TIMEOUT_MS=1e4,AUTH_FAILURE_CLOSE_CODE=4001,EL_LAG_INTERVAL_MS=200,EL_LAG_THRESHOLD_MS=500,RECONNECT_NOTIFY_MIN_MS=6e4,RECONNECT_NOTIFY_MAX_MS=18e4,RECONNECT_NOTIFY_METHOD="server/reconnect";export class GatewayHandshakeError extends Error{code;retryable;retryAfterMs;constructor(e){super(e?.message||"Gateway connect rejected"),this.name="GatewayHandshakeError",this.code=e?.code,this.retryable=!0===e?.retryable||"UNAVAILABLE"===e?.code,this.retryAfterMs="number"==typeof e?.retryAfterMs?e.retryAfterMs:void 0}}export function decodeChatAbortResult(e){if("object"!=typeof e||null===e||Array.isArray(e))throw new Error("Invalid chat.abort response: expected object");const t=e;if("boolean"!=typeof t.aborted)throw new Error("Invalid chat.abort response: expected boolean aborted");if(!Array.isArray(t.runIds)||t.runIds.some(e=>"string"!=typeof e))throw new Error("Invalid chat.abort response: expected string[] runIds");return{aborted:t.aborted,runIds:[...t.runIds]}}function wsUrlToHttpBase(e){try{const t=new URL(e),n="wss:"===t.protocol?"https:":"ws:"===t.protocol?"http:":null;return n?`${n}//${t.host}`:null}catch{return null}}const MANUAL_RECONNECT_SIGNAL="SIGUSR1";function registerReconnectSignal(e,t,n){detachReconnectSignal(e),e.handler=t;try{process.on("SIGUSR1",t),n?.info?.("[gateway] manual reconnect enabled signal=SIGUSR1")}catch{n?.warn?.("[gateway] manual reconnect signal not supported")}}function detachReconnectSignal(e){if(e.handler){try{process.off("SIGUSR1",e.handler)}catch{}e.handler=null}}export class GatewayClient extends EventEmitter{ws=null;config;pending=new Map;connected=!1;stopped=!1;authFailed=!1;connectPromise=null;reconnectTimer=null;reconnectAttempt=0;nextReconnectDelayHintMs=null;signalState={handler:null};deviceIdentity;heartbeatTimer=null;lastPongTs=0;_connectionSeq=0;_currentConnectionId=null;_lastReadyAt=0;reconnectNotifyTimer=null;constructor(e){super(),this.config=e,this.deviceIdentity=loadOrCreateDeviceIdentity();try{ensureDevicePaired(this.deviceIdentity)}catch(e){}Date.now();warmupCryptoSign(this.deviceIdentity)}async start(){this.stopped=!1,this.reconnectAttempt=0,registerReconnectSignal(this.signalState,()=>{this.stopped||(this.emit("manual-reconnect"),this.reconnectNow())}),await this.connect()}stop(){this.stopped=!0,this.stopHeartbeat(),this.clearReconnectNotify(),detachReconnectSignal(this.signalState),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.close()}async connect(){if(this.connectPromise)return this.connectPromise;this.connectPromise=this._connect();try{await this.connectPromise}finally{this.connectPromise=null}}_connect(){return new Promise((e,t)=>{if(this.authFailed)return void t(new Error("Authentication failed — not retrying"));const n=Date.now();this.emit("transport",{event:"connect_start",url:this.config.url,attempt:this.reconnectAttempt});const s=new WebSocket(this.config.url);this.ws=s;let r,i=null,o=!1;const c=setTimeout(()=>{this.emit("transport",{event:"connect_fail",reason:"timeout",durationMs:Date.now()-n}),s.close(),t(new Error("Gateway connection timeout"))},3e4),a=t=>{clearTimeout(c),o=!0,this.connected=!0,this.reconnectAttempt=0,this.authFailed=!1,this._connectionSeq++,this._currentConnectionId=randomUUID(),this._lastReadyAt=Date.now(),this.startHeartbeat(),this.emit("transport",{event:"connect_ok",connectionSeq:this._connectionSeq,connectionId:this._currentConnectionId,durationMs:Date.now()-n}),this.emit("connected",{...t,connectionSeq:this._connectionSeq,connectionId:this._currentConnectionId}),e()},h=e=>{const r="string"==typeof e?e:e.message;clearTimeout(c),this.authFailed=!0,this.emit("transport",{event:"connect_fail",reason:r,durationMs:Date.now()-n}),this.emit("auth-failed",{reason:r}),s.close(),t("string"==typeof e?new Error(e):e)};s.on("open",()=>{this.emit("transport",{event:"ws_open",durationMs:Date.now()-n})}),s.on("message",e=>{const o="string"==typeof e?e:e.toString("utf-8");if("pong"===o)return void(this.lastPongTs=Date.now());let l;this.emitMessageHash(o);try{l=JSON.parse(o)}catch{return}const d=l.method;d&&!l.id&&(this.isReconnectNotification(d)?this.scheduleReconnectNotify():this.reconnectNotifyTimer&&this.clearReconnectNotify(),this.emit("notification",d,l.params));const u=l.type;if("event"===u&&this.reconnectNotifyTimer&&this.clearReconnectNotify(),"event"===u){const e=l.event,t=l.payload;if("connect.challenge"===e){const e=Date.now();this.emit("transport",{event:"handshake.challenge_recv",durationMs:e-n});const s=t?.nonce;i=this._sendConnect(s),this.emit("transport",{event:"handshake.connect_sent",durationMs:Date.now()-n}),r?.();let o=0;const c=setInterval(()=>{o++},200),a=Date.now(),h=setInterval(()=>{const e=Date.now()-a,t=e-200*o;t>500&&this.emit("transport",{event:"eventloop_lag",lagMs:t,elapsedMs:e,probeSeq:o})},200);let l;const d=()=>{clearInterval(c),clearInterval(h),l&&clearTimeout(l),this.off("connected",d),r===d&&(r=void 0)};r=d,l=setTimeout(d,3e4),this.once("connected",d)}else"chat"===e?this.emit("chat",t):"agent"===e?this.emit("agent",t):"cron"===e?this.emit("cron",t):"canvas"===e?this.emit("canvas",t):"session.message"===e?this.emit("sessionMessage",t):this.emit("gateway-event",e,t)}else if("hello-ok"===u)this.emit("transport",{event:"handshake.hello_ok_recv",durationMs:Date.now()-n}),a(l);else if("hello-error"===u||"connect-error"===u)h("Authentication rejected by Gateway");else if("res"===u){const e=l.id;if(e&&e===i){if(this.emit("transport",{event:"handshake.connect_res_recv",ok:!!l.ok,durationMs:Date.now()-n}),l.ok){const e=l.payload;a(e??l)}else{const e=l.error,r=new GatewayHandshakeError(e);r.retryable?(clearTimeout(c),this.emit("transport",{event:"connect_fail",reason:r.message,retryable:!0,retryAfterMs:r.retryAfterMs,durationMs:Date.now()-n}),"number"==typeof r.retryAfterMs&&r.retryAfterMs>0&&(this.nextReconnectDelayHintMs=r.retryAfterMs),s.close(),t(r)):h(r)}return}const r=this.pending.get(e);if(r)if(this.pending.delete(e),clearTimeout(r.timer),l.ok)r.resolve(l.payload);else{const e=l.error;r.reject(new Error(e?.message||"Gateway request failed"))}else this.emit("response",l)}}),s.on("pong",()=>{this.lastPongTs=Date.now()}),s.on("close",e=>{const s=o;r?.(),this.stopHeartbeat(),this.clearReconnectNotify(),this.emit("transport",{event:"close",code:e,durationMs:Date.now()-n}),this.connected=!1,this.connectPromise=null;for(const[,e]of this.pending)clearTimeout(e.timer),e.reject(new Error("Connection closed"));this.pending.clear(),s||(clearTimeout(c),t(new Error(`Connection closed during handshake (code=${e})`))),4001===e&&(this.authFailed=!0,this.emit("auth-failed",{code:e})),s&&this.emit("disconnected"),this.stopped||this.authFailed||this.scheduleReconnect()}),s.on("error",e=>{this.emit("transport",{event:"error",message:e.message,durationMs:Date.now()-n}),this.stopped?clearTimeout(c):(this.connected||(clearTimeout(c),t(e)),this.emit("error",e))})})}emitMessageHash(e){if(e.length<32)return;const t=createHash("sha256").update(e).digest("hex").slice(0,16);this.emit("transport",{event:"message_recv",hash:t,size:e.length})}startHeartbeat(){this.stopHeartbeat(),this.lastPongTs=Date.now(),this.heartbeatTimer=setInterval(()=>{if(!this.ws||!this.connected)return;try{this.ws.ping()}catch{}const e=Date.now()-this.lastPongTs;e>6e4&&(this.emit("liveness-timeout",{elapsed:e}),this.ws.close())},15e3),"object"==typeof this.heartbeatTimer&&"unref"in this.heartbeatTimer&&this.heartbeatTimer.unref()}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}isReconnectNotification(e){return"server/reconnect"===e||e.endsWith("/reconnect")}scheduleReconnectNotify(){this.clearReconnectNotify();const e=6e4+12e4*Math.random();this.emit("reconnect-notify-scheduled",{delayMs:Math.round(e)}),this.reconnectNotifyTimer=setTimeout(()=>{this.reconnectNotifyTimer=null,!this.stopped&&this.connected&&(this.emit("reconnect-notify-fired"),this.reconnectNow())},e),"object"==typeof this.reconnectNotifyTimer&&"unref"in this.reconnectNotifyTimer&&this.reconnectNotifyTimer.unref()}clearReconnectNotify(){this.reconnectNotifyTimer&&(clearTimeout(this.reconnectNotifyTimer),this.reconnectNotifyTimer=null)}scheduleReconnect(){if(this.stopped)return;if(this.reconnectTimer)return;const e=this.config.retry??{baseMs:1e3,maxMs:6e5,maxAttempts:0};if(e.maxAttempts>0&&this.reconnectAttempt>=e.maxAttempts)return void this.emit("reconnect-exhausted",this.reconnectAttempt);let t;const n=this.nextReconnectDelayHintMs,s=null!==n&&n>0;s?(t=Math.min(n,e.maxMs),this.nextReconnectDelayHintMs=null):(t=Math.min(e.baseMs*Math.pow(2,this.reconnectAttempt)+500*Math.random(),e.maxMs),this.reconnectAttempt++),this.emit("reconnecting",{attempt:s?this.reconnectAttempt+1:this.reconnectAttempt,delayMs:t}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.stopped||this.connect().catch(e=>{this.emitReconnectFailure(e)})},t),"object"==typeof this.reconnectTimer&&"unref"in this.reconnectTimer&&this.reconnectTimer.unref()}reconnectNow(){this.stopped||(this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.close(),this.reconnectAttempt=0,this.connect().catch(e=>{this.emitReconnectFailure(e)}))}emitReconnectFailure(e){this.stopped||this.authFailed||this.emit("error",e instanceof Error?e:new Error(String(e)))}_sendConnect(e){const t=Date.now(),n=Date.now(),s="operator",r=["operator.admin","operator.approvals","operator.pairing"],i={id:this.deviceIdentity.deviceId,publicKey:this.deviceIdentity.publicKeyB64url,signedAt:n};if(e){const t=Date.now(),o=buildDeviceAuthPayload({deviceId:this.deviceIdentity.deviceId,clientId:"cli",clientMode:"cli",role:s,scopes:r,signedAtMs:n,token:this.config.token,nonce:e}),c=Date.now()-t,a=Date.now();i.nonce=e,i.signature=signDeviceAuth(this.deviceIdentity,o);const h=Date.now()-a;this.emit("transport",{event:"handshake.sign_done",buildPayloadMs:c,signMs:h})}const o=randomUUID(),c={type:"req",id:o,method:"connect",params:{minProtocol:3,maxProtocol:4,client:{id:"cli",displayName:"BeeOS Platform Bridge",version:"0.1.0",platform:"beeos",mode:"cli"},caps:this.config.openclawCanvasCompat?["tool-events","approvals","canvas"]:["tool-events","approvals"],role:s,scopes:r,auth:{token:this.config.token},device:i}},a=Date.now(),h=JSON.stringify(c),l=Date.now()-a,d=Date.now();this.ws?.send(h);const u=Date.now()-d;return this.emit("transport",{event:"handshake._sendConnect_done",totalMs:Date.now()-t,serializeMs:l,sendMs:u}),o}async request(e,t,n=6e4){if(!this.ws||!this.connected)throw new Error("Not connected to Gateway");const s=randomUUID(),r={type:"req",id:s,method:e,params:t};return new Promise((t,i)=>{const o=setTimeout(()=>{this.pending.delete(s),i(new Error(`Gateway request timeout: ${e}`))},n);this.pending.set(s,{resolve:t,reject:i,timer:o}),this.ws.send(JSON.stringify(r))})}async agentSend(e,t,n,s,r){const i={agentId:n,sessionKey:e,message:t,deliver:!1,idempotencyKey:randomUUID()};s?.length&&(i.attachments=s),r&&(i.inputProvenance=r);return await this.request("agent",i,12e4)}async chatSend(e,t,n){const s={sessionKey:e,message:t,deliver:!1,idempotencyKey:randomUUID()};n?.length&&(s.attachments=n);return await this.request("chat.send",s,12e4)}async chatAbort(e,t){const n={sessionKey:e};t&&(n.runId=t);return decodeChatAbortResult(await this.request("chat.abort",n))}sendFrame(e){if(!this.ws||!this.connected)return!1;try{return this.ws.send(JSON.stringify(e)),!0}catch{return!1}}agentCancel(e,t){const n={sessionKey:e};t?.runId&&(n.runId=t.runId);const s=`abort_${t?.runId??t?.requestId??e}`;return this.sendFrame({type:"req",id:s,method:"chat.abort",params:n})}async chatHistory(e,t){return this.request("chat.history",{sessionKey:e,limit:t})}async chatHistoryPage(e,t){const n=wsUrlToHttpBase(this.config.url);if(!n)return null;let s;try{s=new URL(`${n}/sessions/${encodeURIComponent(e)}/history`)}catch{return null}null!=t?.limit&&s.searchParams.set("limit",String(t.limit)),t?.cursor&&s.searchParams.set("cursor",t.cursor);try{const e=await fetch(s,{method:"GET",headers:{accept:"application/json",authorization:`Bearer ${this.config.token}`},signal:AbortSignal.timeout(1e4)});if(!e.ok)return null;const t=await e.json(),n=Array.isArray(t.messages)?t.messages:Array.isArray(t.items)?t.items:[];return{messages:n.filter(e=>"object"==typeof e&&null!==e),nextCursor:"string"==typeof t.nextCursor&&t.nextCursor.length>0?t.nextCursor:void 0,hasMore:!0===t.hasMore}}catch{return null}}async sessionsMessagesSubscribe(e){return this.request("sessions.messages.subscribe",{key:e})}async sessionsMessagesUnsubscribe(e){return this.request("sessions.messages.unsubscribe",{key:e})}async skillsStatus(e){return this.request("skills.status",e?{agentId:e}:{})}async sessionsList(){return this.request("sessions.list",{includeDerivedTitles:!0})}async sessionsResolve(e){return this.request("sessions.resolve",{sessionKey:e})}async sessionsPatch(e,t){return this.request("sessions.patch",{key:e,...t})}async sessionsDelete(e){return this.request("sessions.delete",{key:e})}async sessionsReset(e){return this.request("sessions.reset",{key:e,reason:"new"})}close(){if(this.ws)try{this.ws.close()}catch{}this.ws=null,this.connected=!1,this.connectPromise=null,this._currentConnectionId=null}get isConnected(){return this.connected}get connectionSeq(){return this._connectionSeq}get currentConnectionId(){return this._currentConnectionId}get lastReadyAt(){return this._lastReadyAt}}
|
|
1
|
+
import{WebSocket}from"ws";import{EventEmitter}from"node:events";import{randomUUID,createHash}from"node:crypto";import{loadOrCreateDeviceIdentity,buildDeviceAuthPayload,signDeviceAuth,ensureDevicePaired,warmupCryptoSign}from"./device-identity.js";const MIN_PROTOCOL_VERSION=3,MAX_PROTOCOL_VERSION=4,CONNECT_TIMEOUT_MS=3e4,HEARTBEAT_INTERVAL_MS=15e3,LIVENESS_TIMEOUT_MS=6e4,CHAT_HISTORY_PAGE_TIMEOUT_MS=1e4,AUTH_FAILURE_CLOSE_CODE=4001,EL_LAG_INTERVAL_MS=200,EL_LAG_THRESHOLD_MS=500,RECONNECT_NOTIFY_MIN_MS=6e4,RECONNECT_NOTIFY_MAX_MS=18e4,RECONNECT_NOTIFY_METHOD="server/reconnect";export class GatewayHandshakeError extends Error{code;retryable;retryAfterMs;constructor(e){super(e?.message||"Gateway connect rejected"),this.name="GatewayHandshakeError",this.code=e?.code,this.retryable=!0===e?.retryable||"UNAVAILABLE"===e?.code,this.retryAfterMs="number"==typeof e?.retryAfterMs?e.retryAfterMs:void 0}}export function decodeChatAbortResult(e){if("object"!=typeof e||null===e||Array.isArray(e))throw new Error("Invalid chat.abort response: expected object");const t=e;if("boolean"!=typeof t.aborted)throw new Error("Invalid chat.abort response: expected boolean aborted");if(!Array.isArray(t.runIds)||t.runIds.some(e=>"string"!=typeof e))throw new Error("Invalid chat.abort response: expected string[] runIds");return{aborted:t.aborted,runIds:[...t.runIds]}}function wsUrlToHttpBase(e){try{const t=new URL(e),n="wss:"===t.protocol?"https:":"ws:"===t.protocol?"http:":null;return n?`${n}//${t.host}`:null}catch{return null}}const MANUAL_RECONNECT_SIGNAL="SIGUSR1";function registerReconnectSignal(e,t,n){detachReconnectSignal(e),e.handler=t;try{process.on("SIGUSR1",t),n?.info?.("[gateway] manual reconnect enabled signal=SIGUSR1")}catch{n?.warn?.("[gateway] manual reconnect signal not supported")}}function detachReconnectSignal(e){if(e.handler){try{process.off("SIGUSR1",e.handler)}catch{}e.handler=null}}export function waitForGatewayConnected(e,t){return e.isConnected?Promise.resolve():new Promise((n,s)=>{const r=()=>{clearTimeout(o),n()},o=setTimeout(()=>{e.off("connected",r),s(new Error("OpenClaw gateway is not connected"))},t);o.unref?.(),e.once("connected",r)})}export class GatewayClient extends EventEmitter{ws=null;config;pending=new Map;connected=!1;stopped=!1;authFailed=!1;connectPromise=null;reconnectTimer=null;reconnectAttempt=0;nextReconnectDelayHintMs=null;signalState={handler:null};deviceIdentity;heartbeatTimer=null;lastPongTs=0;_connectionSeq=0;_currentConnectionId=null;_lastReadyAt=0;reconnectNotifyTimer=null;constructor(e){super(),this.config=e,this.deviceIdentity=loadOrCreateDeviceIdentity();try{ensureDevicePaired(this.deviceIdentity)}catch(e){}Date.now();warmupCryptoSign(this.deviceIdentity)}async start(){this.stopped=!1,this.reconnectAttempt=0,registerReconnectSignal(this.signalState,()=>{this.stopped||(this.emit("manual-reconnect"),this.reconnectNow())}),await this.connect()}stop(){this.stopped=!0,this.stopHeartbeat(),this.clearReconnectNotify(),detachReconnectSignal(this.signalState),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.close()}async connect(){if(this.connectPromise)return this.connectPromise;this.connectPromise=this._connect();try{await this.connectPromise}finally{this.connectPromise=null}}_connect(){return new Promise((e,t)=>{if(this.authFailed)return void t(new Error("Authentication failed — not retrying"));const n=Date.now();this.emit("transport",{event:"connect_start",url:this.config.url,attempt:this.reconnectAttempt});const s=new WebSocket(this.config.url);this.ws=s;let r,o=null,i=!1;const c=setTimeout(()=>{this.emit("transport",{event:"connect_fail",reason:"timeout",durationMs:Date.now()-n}),s.close(),t(new Error("Gateway connection timeout"))},3e4),a=t=>{clearTimeout(c),i=!0,this.connected=!0,this.reconnectAttempt=0,this.authFailed=!1,this._connectionSeq++,this._currentConnectionId=randomUUID(),this._lastReadyAt=Date.now(),this.startHeartbeat(),this.emit("transport",{event:"connect_ok",connectionSeq:this._connectionSeq,connectionId:this._currentConnectionId,durationMs:Date.now()-n}),this.emit("connected",{...t,connectionSeq:this._connectionSeq,connectionId:this._currentConnectionId}),e()},h=e=>{const r="string"==typeof e?e:e.message;clearTimeout(c),this.authFailed=!0,this.emit("transport",{event:"connect_fail",reason:r,durationMs:Date.now()-n}),this.emit("auth-failed",{reason:r}),s.close(),t("string"==typeof e?new Error(e):e)};s.on("open",()=>{this.emit("transport",{event:"ws_open",durationMs:Date.now()-n})}),s.on("message",e=>{const i="string"==typeof e?e:e.toString("utf-8");if("pong"===i)return void(this.lastPongTs=Date.now());let l;this.emitMessageHash(i);try{l=JSON.parse(i)}catch{return}const d=l.method;d&&!l.id&&(this.isReconnectNotification(d)?this.scheduleReconnectNotify():this.reconnectNotifyTimer&&this.clearReconnectNotify(),this.emit("notification",d,l.params));const u=l.type;if("event"===u&&this.reconnectNotifyTimer&&this.clearReconnectNotify(),"event"===u){const e=l.event,t=l.payload;if("connect.challenge"===e){const e=Date.now();this.emit("transport",{event:"handshake.challenge_recv",durationMs:e-n});const s=t?.nonce;o=this._sendConnect(s),this.emit("transport",{event:"handshake.connect_sent",durationMs:Date.now()-n}),r?.();let i=0;const c=setInterval(()=>{i++},200),a=Date.now(),h=setInterval(()=>{const e=Date.now()-a,t=e-200*i;t>500&&this.emit("transport",{event:"eventloop_lag",lagMs:t,elapsedMs:e,probeSeq:i})},200);let l;const d=()=>{clearInterval(c),clearInterval(h),l&&clearTimeout(l),this.off("connected",d),r===d&&(r=void 0)};r=d,l=setTimeout(d,3e4),this.once("connected",d)}else"chat"===e?this.emit("chat",t):"agent"===e?this.emit("agent",t):"cron"===e?this.emit("cron",t):"canvas"===e?this.emit("canvas",t):"session.message"===e?this.emit("sessionMessage",t):this.emit("gateway-event",e,t)}else if("hello-ok"===u)this.emit("transport",{event:"handshake.hello_ok_recv",durationMs:Date.now()-n}),a(l);else if("hello-error"===u||"connect-error"===u)h("Authentication rejected by Gateway");else if("res"===u){const e=l.id;if(e&&e===o){if(this.emit("transport",{event:"handshake.connect_res_recv",ok:!!l.ok,durationMs:Date.now()-n}),l.ok){const e=l.payload;a(e??l)}else{const e=l.error,r=new GatewayHandshakeError(e);r.retryable?(clearTimeout(c),this.emit("transport",{event:"connect_fail",reason:r.message,retryable:!0,retryAfterMs:r.retryAfterMs,durationMs:Date.now()-n}),"number"==typeof r.retryAfterMs&&r.retryAfterMs>0&&(this.nextReconnectDelayHintMs=r.retryAfterMs),s.close(),t(r)):h(r)}return}const r=this.pending.get(e);if(r)if(this.pending.delete(e),clearTimeout(r.timer),l.ok)r.resolve(l.payload);else{const e=l.error;r.reject(new Error(e?.message||"Gateway request failed"))}else this.emit("response",l)}}),s.on("pong",()=>{this.lastPongTs=Date.now()}),s.on("close",e=>{const s=i;r?.(),this.stopHeartbeat(),this.clearReconnectNotify(),this.emit("transport",{event:"close",code:e,durationMs:Date.now()-n}),this.connected=!1,this.connectPromise=null;for(const[,e]of this.pending)clearTimeout(e.timer),e.reject(new Error("Connection closed"));this.pending.clear(),s||(clearTimeout(c),t(new Error(`Connection closed during handshake (code=${e})`))),4001===e&&(this.authFailed=!0,this.emit("auth-failed",{code:e})),s&&this.emit("disconnected"),this.stopped||this.authFailed||this.scheduleReconnect()}),s.on("error",e=>{this.emit("transport",{event:"error",message:e.message,durationMs:Date.now()-n}),this.stopped?clearTimeout(c):(this.connected||(clearTimeout(c),t(e)),this.emit("error",e))})})}emitMessageHash(e){if(e.length<32)return;const t=createHash("sha256").update(e).digest("hex").slice(0,16);this.emit("transport",{event:"message_recv",hash:t,size:e.length})}startHeartbeat(){this.stopHeartbeat(),this.lastPongTs=Date.now(),this.heartbeatTimer=setInterval(()=>{if(!this.ws||!this.connected)return;try{this.ws.ping()}catch{}const e=Date.now()-this.lastPongTs;e>6e4&&(this.emit("liveness-timeout",{elapsed:e}),this.ws.close())},15e3),"object"==typeof this.heartbeatTimer&&"unref"in this.heartbeatTimer&&this.heartbeatTimer.unref()}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}isReconnectNotification(e){return"server/reconnect"===e||e.endsWith("/reconnect")}scheduleReconnectNotify(){this.clearReconnectNotify();const e=6e4+12e4*Math.random();this.emit("reconnect-notify-scheduled",{delayMs:Math.round(e)}),this.reconnectNotifyTimer=setTimeout(()=>{this.reconnectNotifyTimer=null,!this.stopped&&this.connected&&(this.emit("reconnect-notify-fired"),this.reconnectNow())},e),"object"==typeof this.reconnectNotifyTimer&&"unref"in this.reconnectNotifyTimer&&this.reconnectNotifyTimer.unref()}clearReconnectNotify(){this.reconnectNotifyTimer&&(clearTimeout(this.reconnectNotifyTimer),this.reconnectNotifyTimer=null)}scheduleReconnect(){if(this.stopped)return;if(this.reconnectTimer)return;const e=this.config.retry??{baseMs:1e3,maxMs:6e5,maxAttempts:0};if(e.maxAttempts>0&&this.reconnectAttempt>=e.maxAttempts)return void this.emit("reconnect-exhausted",this.reconnectAttempt);let t;const n=this.nextReconnectDelayHintMs,s=null!==n&&n>0;s?(t=Math.min(n,e.maxMs),this.nextReconnectDelayHintMs=null):(t=Math.min(e.baseMs*Math.pow(2,this.reconnectAttempt)+500*Math.random(),e.maxMs),this.reconnectAttempt++),this.emit("reconnecting",{attempt:s?this.reconnectAttempt+1:this.reconnectAttempt,delayMs:t}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.stopped||this.connect().catch(e=>{this.emitReconnectFailure(e)})},t),"object"==typeof this.reconnectTimer&&"unref"in this.reconnectTimer&&this.reconnectTimer.unref()}reconnectNow(){this.stopped||(this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.close(),this.reconnectAttempt=0,this.connect().catch(e=>{this.emitReconnectFailure(e)}))}emitReconnectFailure(e){this.stopped||this.authFailed||this.emit("error",e instanceof Error?e:new Error(String(e)))}_sendConnect(e){const t=Date.now(),n=Date.now(),s="operator",r=["operator.admin","operator.approvals","operator.pairing"],o={id:this.deviceIdentity.deviceId,publicKey:this.deviceIdentity.publicKeyB64url,signedAt:n};if(e){const t=Date.now(),i=buildDeviceAuthPayload({deviceId:this.deviceIdentity.deviceId,clientId:"cli",clientMode:"cli",role:s,scopes:r,signedAtMs:n,token:this.config.token,nonce:e}),c=Date.now()-t,a=Date.now();o.nonce=e,o.signature=signDeviceAuth(this.deviceIdentity,i);const h=Date.now()-a;this.emit("transport",{event:"handshake.sign_done",buildPayloadMs:c,signMs:h})}const i=randomUUID(),c={type:"req",id:i,method:"connect",params:{minProtocol:3,maxProtocol:4,client:{id:"cli",displayName:"BeeOS Platform Bridge",version:"0.1.0",platform:"beeos",mode:"cli"},caps:this.config.openclawCanvasCompat?["tool-events","approvals","canvas"]:["tool-events","approvals"],role:s,scopes:r,auth:{token:this.config.token},device:o}},a=Date.now(),h=JSON.stringify(c),l=Date.now()-a,d=Date.now();this.ws?.send(h);const u=Date.now()-d;return this.emit("transport",{event:"handshake._sendConnect_done",totalMs:Date.now()-t,serializeMs:l,sendMs:u}),i}async request(e,t,n=6e4){if(!this.ws||!this.connected)throw new Error("Not connected to Gateway");const s=randomUUID(),r={type:"req",id:s,method:e,params:t};return new Promise((t,o)=>{const i=setTimeout(()=>{this.pending.delete(s),o(new Error(`Gateway request timeout: ${e}`))},n);this.pending.set(s,{resolve:t,reject:o,timer:i}),this.ws.send(JSON.stringify(r))})}async agentSend(e,t,n,s,r){const o={agentId:n,sessionKey:e,message:t,deliver:!1,idempotencyKey:randomUUID()};s?.length&&(o.attachments=s),r&&(o.inputProvenance=r);return await this.request("agent",o,12e4)}async chatSend(e,t,n){const s={sessionKey:e,message:t,deliver:!1,idempotencyKey:randomUUID()};n?.length&&(s.attachments=n);return await this.request("chat.send",s,12e4)}async chatAbort(e,t){const n={sessionKey:e};t&&(n.runId=t);return decodeChatAbortResult(await this.request("chat.abort",n))}sendFrame(e){if(!this.ws||!this.connected)return!1;try{return this.ws.send(JSON.stringify(e)),!0}catch{return!1}}agentCancel(e,t){const n={sessionKey:e};t?.runId&&(n.runId=t.runId);const s=`abort_${t?.runId??t?.requestId??e}`;return this.sendFrame({type:"req",id:s,method:"chat.abort",params:n})}async chatHistory(e,t){return this.request("chat.history",{sessionKey:e,limit:t})}async chatHistoryPage(e,t){const n=wsUrlToHttpBase(this.config.url);if(!n)return null;let s;try{s=new URL(`${n}/sessions/${encodeURIComponent(e)}/history`)}catch{return null}null!=t?.limit&&s.searchParams.set("limit",String(t.limit)),t?.cursor&&s.searchParams.set("cursor",t.cursor);try{const e=await fetch(s,{method:"GET",headers:{accept:"application/json",authorization:`Bearer ${this.config.token}`},signal:AbortSignal.timeout(1e4)});if(!e.ok)return null;const t=await e.json(),n=Array.isArray(t.messages)?t.messages:Array.isArray(t.items)?t.items:[];return{messages:n.filter(e=>"object"==typeof e&&null!==e),nextCursor:"string"==typeof t.nextCursor&&t.nextCursor.length>0?t.nextCursor:void 0,hasMore:!0===t.hasMore}}catch{return null}}async sessionsMessagesSubscribe(e){return this.request("sessions.messages.subscribe",{key:e})}async sessionsMessagesUnsubscribe(e){return this.request("sessions.messages.unsubscribe",{key:e})}async skillsStatus(e){return this.request("skills.status",e?{agentId:e}:{})}async sessionsList(){return this.request("sessions.list",{includeDerivedTitles:!0})}async sessionsResolve(e){return this.request("sessions.resolve",{sessionKey:e})}async sessionsPatch(e,t){return this.request("sessions.patch",{key:e,...t})}async sessionsDelete(e){return this.request("sessions.delete",{key:e})}async sessionsReset(e){return this.request("sessions.reset",{key:e,reason:"new"})}close(){if(this.ws)try{this.ws.close()}catch{}this.ws=null,this.connected=!1,this.connectPromise=null,this._currentConnectionId=null}get isConnected(){return this.connected}waitForConnected(e=3e4){return waitForGatewayConnected(this,e)}get connectionSeq(){return this._connectionSeq}get currentConnectionId(){return this._currentConnectionId}get lastReadyAt(){return this._lastReadyAt}}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{claimedSandboxId,identityLaneFromEnvironment}from"./runtime/identity-lane-lease.js";import{createCentralNativeComposition,requireCentralNativeSessionHost}from"./runtime/central-native-composition.js";import{createSandboxNativeTargetLookup,registerSandboxNativeActivation}from"./runtime/sandbox-native-activation.js";import{registerCentralNativeMemoryTools}from"./runtime/central-native-memory.js";import{harnessConnectorToolCaller}from"./connectors/harness-connector-mcp.js";import{registerCentralNativeContextEngine,centralNativeChatEnabled}from"./runtime/central-native-runtime.js";import{relayCentralAskUser}from"./runtime/central-native-interactions.js";import{consumeNativeOutputTool,nativeHtmlDeliveryForRun}from"./runtime/native-output-file-attempt.js";import{uploadNativeOutputFile}from"./upload/upload-file.js";import{nativeOutputToolCallGate}from"./upload/native-output-tool-hook.js";import{NativeInputFilesHttpClient}from"./runtime/native-input-files-http.js";import{fileDeliveryFinalizeDecision}from"./upload/finalize-hook.js";import{resolveConfigWithMeta,mirrorOpenClawConfig}from"./config.js";import{hasRuntimeReplyApi}from"./runtime/reply-router.js";import{PromptRunStore}from"./runtime/prompt-run-store.js";import{createMcpNativeProjectionNudge,fingerprintMcpServers}from"./acp-gateway/mcp-native-projection-nudge.js";import{createImHotPathDeferral}from"./runtime/im-hot-path-deferral.js";import{SessionWriteGate}from"./acp-gateway/session-write-gate.js";import{OpenClawSessionWriteQuiescence}from"./runtime/openclaw-session-write-quiescence.js";import{SessionMutationCoordinator}from"./runtime/session-mutation-coordinator.js";import{scheduleProcessRuntimeRestart}from"./runtime/runtime-restart-scheduler.js";import{createImInboundHandler}from"./im-inbound-handler.js";import{AgentGatewayClient,NodeRuntimeDeliveryPort,agentIdentityFromKeyPair,loadAgentKeyPair,signAgentMessage}from"@beeos-ai/cloud-harness-sdk";import{MessageServiceConversationRunBoundary}from"./runtime/message-service-conversation-run-boundary.js";import{AutomationTurnPolicy}from"./automation/turn-policy.js";import{registerAutomationTools}from"./automation/tools.js";import{extractBeeosConversationIdFromSessionKey}from"./runtime/openclaw-session-key-resolution.js";import{setOpenClawConfigSnapshot}from"./runtime/openclaw-session-model.js";import{BeeosClawMessageClientProcessOwner,createBeeosClawMessageTokenProvider}from"./message-client-composition.js";import{MessageProjectionInboundConsumer}from"./message-projection-inbound-consumer.js";import{MessageClientTerminalStateRecovery}from"./runtime/message-client-terminal-state-recovery.js";import{RuntimeAuthorityMessageBusLifecycle}from"./runtime/runtime-authority-message-bus-lifecycle.js";import{createNativeCloudChatComposition,nativeCloudChatAuthorityFromRuntimeAuthority}from"./runtime/native-cloud-chat-composition.js";import{MSConnectionStatusSnapshot}from"./runtime/ms-connection-status.js";import{FileInboundExecutionJournal}from"./inbound-execution-journal.js";import{completeA2ATask,registerA2ATools,TaskHandleRegistry}from"./a2a/tools.js";import{BEEOS_UPLOAD_TOOL_NAME,BEEOS_UPLOAD_TOOL_SCHEMA,BEEOS_UPLOAD_TOOL_DESCRIPTION,REQUEST_TIMEOUT_MS as BEEOS_UPLOAD_REQUEST_TIMEOUT_MS,executeUpload}from"./upload/tool.js";import{BEEOS_DESKTOP_SCREENSHOT_TOOL_NAME,BEEOS_DESKTOP_SCREENSHOT_TOOL_SCHEMA,BEEOS_DESKTOP_SCREENSHOT_TOOL_DESCRIPTION,executeDesktopScreenshot}from"./upload/desktop-screenshot-tool.js";import{BEEOS_LIST_FILES_TOOL_NAME,BEEOS_LIST_FILES_TOOL_SCHEMA,BEEOS_LIST_FILES_TOOL_DESCRIPTION,executeListFiles}from"./files/list-tool.js";import{BEEOS_FETCH_FILE_TOOL_NAME,BEEOS_FETCH_FILE_TOOL_SCHEMA,BEEOS_FETCH_FILE_TOOL_DESCRIPTION,executeFetchFile}from"./files/fetch-tool.js";import{writeUploadToolResult,cleanupUploadToolResultCache}from"./upload/result-cache.js";import{handleFileStage}from"./upload/file-stage.js";import{handleStatusRequest}from"./status.js";import{ACPServer}from"./acp-server.js";import{GatewayClient}from"./gateway-client.js";import{createObsEventWriter}from"./observability.js";import{resolvePluginVersion}from"./plugin-version.js";import{createTerminalWebSocketService}from"./terminal/websocket.js";import{TerminalManager}from"./terminal/session-manager.js";import{readDiscoveryCache,writeDiscoveryCache}from"./discovery-cache.js";import{setClaimedCloudRuntimeInstanceId,setUploadDeps}from"./upload/upload-file.js";import{registerLocalFileExtractor}from"./upload/local-file-extractors.js";import{browserScreenshotExtractor}from"./browser/screenshot-extractor.js";import{deliverableFileExtractor}from"./upload/deliverable-extractor.js";import{observeToolCallForDelivery,rememberDeliveryWorkspace}from"./upload/delivery-observe.js";import{BEEOS_FILE_RESOURCE_ROUTING_RULE}from"./files/beeos-file-uri.js";import{marksFullRuntimeRegistered,planPluginRegistration,replayCachedPluginTools,resolveCapabilityToolReplay}from"./plugin-registration-plan.js";import{buildAppendSystemContext,buildToolRoutingHint,canvasToolBlockReason}from"./prompt-system-context.js";import{CanvasStateManager}from"./canvas/state.js";import{createStaticCanvasHtmlPublisher}from"./canvas/static-html.js";import{CanvasRelayClient}from"./canvas/relay-client.js";import{createSandboxCanvasTokenProvider}from"./canvas/runtime-lease-token.js";import{createCanvasRelayService}from"./canvas/relay-service.js";import{RENDER_UI_TOOL_NAME,RENDER_UI_TOOL_DESCRIPTION,RENDER_UI_TOOL_SCHEMA,CLOSE_UI_TOOL_NAME,CLOSE_UI_TOOL_DESCRIPTION,CLOSE_UI_TOOL_SCHEMA,createRenderUiToolExecutor,createCloseUiHandler,CANVAS_PRESENTATION_GATE,CANVAS_SYSTEM_PROMPT}from"./canvas/tools.js";import{FormSchemaRegistry}from"./surface/form-schema-registry.js";import{buildCronSchemas}from"./surface/cron-schemas.js";import{RENDER_FORM_TOOL_NAME,RENDER_FORM_TOOL_SCHEMA,buildRenderFormDescription,createRenderFormHandler}from"./surface/render-form-tool.js";import{ResourceDescriptorRegistry}from"./surface/resource-descriptor-registry.js";import{CRON_RESOURCE}from"./surface/cron-resource.js";import{generateActionTools}from"./surface/action-tool-generator.js";import{buildThirdPartyChannelSet,isThirdPartyChannel}from"./channel-detection.js";import{registerArouterMediaProviders}from"./media/index.js";import{homedir}from"node:os";import{join}from"node:path";import{RuntimeProductionAuthority,cloudRuntimeTargetInstanceId}from"./runtime/runtime-production-authority.js";import{FileRuntimeCommandJournal}from"./runtime/runtime-command-journal.js";import{FileRuntimePoisonDeliveryJournal}from"./runtime/runtime-poison-delivery-journal.js";import{OpenClawNativeMcpProjection}from"./acp-gateway/openclaw-native-mcp-projection.js";import{LocalEncryptedCredentialReferenceVault}from"./acp-gateway/mcp-credential-reference-port.js";import{AgentGatewayGrantJwksReadinessAdapter,CloudRuntimeServiceTransportReadinessAdapter,RuntimeServiceTransportReadinessAdapter,createRuntimeServiceProductionCandidate}from"./runtime/runtime-service-production-candidate.js";import{fetchRuntimeLeaseAttempt}from"./runtime/message-service-runtime-authenticated-fetch.js";import{MessageServiceCronDeliveryHttpAuthority}from"./runtime/message-service-cron-delivery-http-authority.js";import{AgentMappingRegistry}from"./runtime/agent-mapping-registry.js";import{OpenClawRuntimeProcessOwner}from"./runtime/openclaw-runtime-process-owner.js";import{AgentGatewayHttpProjectionTransport,AgentGatewayTemplateOriginReporter,AgentProjectionProduction,OpenClawAgentProjectionSource}from"./runtime/agent-projection-production.js";import{MessageServiceRunOutputChannel}from"./runtime/message-service-run-output-channel.js";import{AssistantMessageCommitRouter}from"./runtime/assistant-message-commit-router.js";import{OpenClawApprovalBridge}from"./approval/bridge.js";import{APPROVAL_DECISION_MESSAGE_TYPE,isApprovalDocument}from"./approval/protocol.generated.js";import{isQuestionResponseDocument,OpenClawQuestionBridge}from"./question/bridge.js";import{ToolResultObservationRouter}from"./runtime/tool-result-observation-router.js";import{ModelCallObservationRouter,registerModelCallObservationHooks}from"./runtime/model-call-observability.js";import{registerArouterLatencyRouting}from"./runtime/arouter-latency-routing.js";import{createPeerRunOutputRouterFactory}from"./runtime/run-output-composition.js";const PLUGIN_VERSION=resolvePluginVersion();let agentKeys=null,agentGateway=null,sharedCanvasState=null,sharedAcpServer=null;const sharedSessionWriteGate=new SessionWriteGate,sharedPromptRunStore=new PromptRunStore,sharedAutomationTurnPolicy=new AutomationTurnPolicy;let lastOpenclawConfig;const sharedMcpNativeProjectionNudge=createMcpNativeProjectionNudge({getActiveImRunCount:()=>sharedPromptRunStore.size(),nudge:()=>{sharedAcpServer?.nudgeMcpNativeProjection()}}),sharedImHotPathDeferral=createImHotPathDeferral({getActiveImRunCount:()=>sharedPromptRunStore.size()});sharedPromptRunStore.setOnBecameIdle(()=>{sharedMcpNativeProjectionNudge.flushIfIdle({fingerprint:fingerprintMcpServers(lastOpenclawConfig)}),sharedImHotPathDeferral.notifyIdle()});const sharedAssistantMessageCommitRouter=new AssistantMessageCommitRouter,sharedToolResultObservationRouter=new ToolResultObservationRouter;let approvalLogger;const sharedApprovalBridge=new OpenClawApprovalBridge({request:(e,t)=>sharedGatewayClient?sharedGatewayClient.request(e,t):Promise.reject(new Error("Not connected to Gateway")),logger:{info:e=>approvalLogger?.info?.(e),warn:e=>approvalLogger?.warn?.(e)}}),sharedQuestionBridge=new OpenClawQuestionBridge({request:(e,t)=>sharedGatewayClient?sharedGatewayClient.request(e,t):Promise.reject(new Error("Not connected to Gateway")),logger:{info:e=>approvalLogger?.info?.(e),warn:e=>approvalLogger?.warn?.(e)}}),sharedModelCallObservationRouter=new ModelCallObservationRouter;let sharedSessionMutationCoordinator,sharedCentralPrompt,sharedRuntimeAuthority,sharedNativeChatService,sharedNativeCloudChat,sharedWriteObs=()=>{};const sharedMSConnectionStatus=new MSConnectionStatusSnapshot,sharedAgentMappings=new AgentMappingRegistry;let sharedGatewayClient,sharedRuntimeOwner,sharedAgentProjection,sharedRuntimeAgentCapabilities,sharedMcpProjection,sharedMcpCredentialVault;const sharedMessageClientOwner=new BeeosClawMessageClientProcessOwner;let sharedActiveMessageConsumer,sharedInboundExecutionJournal;const sharedTerminalManager=new TerminalManager;let _initializing=!1,_pluginRegisteredAt=0,_fullRuntimeRegistered=!1;const cachedCapabilityTools=[];let rawRegisterTool,wrappedRegisterTool;const cachedRuntimeServices=[],cachedRuntimeHooks=[];let rawRegisterService,wrappedRegisterService,rawOn,wrappedOn;function cacheRuntimeRegistrations(e){const t=e.registerService===wrappedRegisterService?rawRegisterService:e.registerService;if(rawRegisterService=t,wrappedRegisterService=r=>{cachedRuntimeServices.push(r),t.call(e,r)},e.registerService=wrappedRegisterService,cachedRuntimeServices.length=0,cachedRuntimeHooks.length=0,e.on){const t=e.on===wrappedOn?rawOn:e.on;rawOn=t,wrappedOn=(...r)=>{cachedRuntimeHooks.push(r),t.call(e,...r)},e.on=wrappedOn}}function replayRuntimeRegistrations(e){const t=e.registerService===wrappedRegisterService?rawRegisterService:e.registerService,r=e.on===wrappedOn?rawOn:e.on;for(const t of cachedRuntimeHooks)r.call(e,...t);for(const r of cachedRuntimeServices)t.call(e,r)}const ensureRegisterToolCache=e=>{const t=e.registerTool===wrappedRegisterTool?rawRegisterTool:e.registerTool;rawRegisterTool=t.bind(e),wrappedRegisterTool=(e,t)=>(cachedCapabilityTools.push({tool:e,options:t}),rawRegisterTool(e,t)),e.registerTool=wrappedRegisterTool};function agentKeyPairToIdentity(e){return{publicKeyBase64:()=>Buffer.from(e.publicKey).toString("base64"),sign:async t=>signAgentMessage(t,e.privateKey)}}let sharedPluginContext=null,unhandledRejectionObserverInstalled=!1;function installUnhandledRejectionObserver(e,t,r){unhandledRejectionObserverInstalled||(unhandledRejectionObserverInstalled=!0,process.on("unhandledRejection",r=>{const o=r instanceof Error?r.message:String(r),a=r instanceof Error?r.stack:void 0;e.logger.error?.(`[beeos-claw] unhandledRejection: ${o}${a?`\n${a}`:""}`),t({component:"plugin",domain:"fatal",name:"unhandled_rejection",severity:"error",summary:o,error:{code:"unhandled_rejection",message:o,...a?{stack:a}:{}}})}),process.on("uncaughtException",r=>{const o=r instanceof Error?r.message:String(r);e.logger.error?.(`[beeos-claw] uncaughtException: ${r instanceof Error?r.stack??r.message:String(r)}`),t({component:"plugin",domain:"fatal",name:"uncaught_exception",severity:"error",summary:o,error:{code:"uncaught_exception",message:o}})}))}function initializePlugin(e){let t,r;try{t=e.runtime?.config?.loadConfig?.()}catch{}try{r=resolveConfigWithMeta({pluginConfig:e.pluginConfig??{},openclawConfig:t})}catch(t){return e.logger.error?.(`[beeos-claw] Failed to resolve config: ${t instanceof Error?t.message:String(t)}`),null}const o=r.config,a=buildThirdPartyChannelSet(t);a.size>0&&e.logger.info?.(`[beeos-claw] Third-party channels detected: ${[...a].join(", ")}`);const n=o.log.enabled?createObsEventWriter({dir:o.log.dir,redaction:{gatewayToken:o.gateway.token},logger:e.logger}):()=>{};n({component:"plugin",domain:"lifecycle",name:"lifecycle.startup",severity:"info",payload:{pluginVersion:PLUGIN_VERSION,pid:process.pid,nodeVersion:process.version,cwd:process.cwd()}}),n({component:"plugin",domain:"config",name:"config.resolved",severity:"info",payload:{config:o,sources:r.sources,openclawConfigPath:r.openclawConfigPath}});for(const t of r.validation)n({component:"plugin",domain:"config",name:"config.validation",severity:t.severity,summary:t.message,error:{code:t.code,message:t.message,nextSteps:t.nextSteps}}),"error"===t.severity?e.logger.error?.(`[beeos-claw] ${t.message}`):e.logger.warn?.(`[beeos-claw] ${t.message}`);if(r.validation.some(e=>"error"===e.severity)&&e.logger.error?.("[beeos-claw] Plugin has configuration errors — some features may not work."),o.keyFile)try{agentKeys=loadAgentKeyPair(o.keyFile),agentGateway=o.agentGatewayUrl?new AgentGatewayClient({baseUrl:o.agentGatewayUrl,identity:agentIdentityFromKeyPair(agentKeys),onRetry:({method:t,path:r,attempt:o,delayMs:a,error:n})=>e.logger.warn?.(`[beeos-claw] Agent Gateway ${t} ${r} retry ${o} in ${a}ms: ${n instanceof Error?n.message:String(n)}`)}):null;const t=Buffer.from(agentKeys.publicKey).toString("base64");e.logger.info?.(`[beeos-claw] v${PLUGIN_VERSION} registering (publicKey: ${t})`)}catch(t){e.logger.warn?.(`[beeos-claw] Failed to load agent key pair: ${t}`),e.logger.info?.(`[beeos-claw] v${PLUGIN_VERSION} registering (no key pair — signed requests disabled)`)}else e.logger.info?.(`[beeos-claw] v${PLUGIN_VERSION} registering (no keyFile configured)`);return agentGateway&&(setUploadDeps({gateway:agentGateway,logger:e.logger}),registerLocalFileExtractor(browserScreenshotExtractor),registerLocalFileExtractor(deliverableFileExtractor),e.logger.info?.("[beeos-claw] Upload deps + local file extractors registered")),lastOpenclawConfig=t,sharedWriteObs=n,setOpenClawConfigSnapshot(t),{cfg:o,writeObs:n,thirdPartyChannels:a,openclawConfig:t}}function registerUploadTools(e,t,r){const{cfg:o,writeObs:a}=t,n=Boolean(pluginCloudRuntimeTarget(e));if(n){if(!e.on)throw new Error("native output Files Host hook unavailable");e.on("before_tool_call",nativeOutputToolCallGate)}cleanupUploadToolResultCache().catch(t=>{e.logger.warn?.(`[beeos_upload_file] cache cleanup failed on startup: ${String(t)}`)}),e.registerTool({name:BEEOS_UPLOAD_TOOL_NAME,description:BEEOS_UPLOAD_TOOL_DESCRIPTION,parameters:BEEOS_UPLOAD_TOOL_SCHEMA,async execute(t,r,i){const s=n?consumeNativeOutputTool(t):void 0,l=await executeUpload(r,agentGateway,i,s?(e,t)=>uploadNativeOutputFile(e,o.agentGatewayUrl,s,t,i,BEEOS_UPLOAD_REQUEST_TIMEOUT_MS):void 0,e.logger);return e.logger.debug?.(`[beeos_upload_file] toolCallId=${t} ok=${l.ok}`),a({component:"upload-tool",domain:"tool",name:l.ok?"upload.success":"upload.failure",severity:l.ok?"info":"warn",payload:{toolCallId:t,ok:l.ok,fileCount:l.files?.length??0,error:l.error}}),(async r=>{try{await writeUploadToolResult(t,BEEOS_UPLOAD_TOOL_NAME,r),await cleanupUploadToolResultCache()}catch(r){e.logger.warn?.(`[beeos_upload_file] persist cache failed toolCallId=${t}: ${String(r)}`)}return r})(l)}}),e.registerTool({name:BEEOS_DESKTOP_SCREENSHOT_TOOL_NAME,description:BEEOS_DESKTOP_SCREENSHOT_TOOL_DESCRIPTION,parameters:BEEOS_DESKTOP_SCREENSHOT_TOOL_SCHEMA,async execute(t,r,o){e.logger.debug?.(`[beeos_desktop_screenshot] toolCallId=${t} params=${JSON.stringify(r)}`);const n=await executeDesktopScreenshot(r,agentGateway,o);return e.logger.debug?.(`[beeos_desktop_screenshot] toolCallId=${t} ok=${n.ok}`),a({component:"desktop-screenshot-tool",domain:"tool",name:n.ok?"desktop_screenshot.success":"desktop_screenshot.failure",severity:n.ok?"info":"warn",payload:{toolCallId:t,ok:n.ok,path:n.path,fileCount:n.files?.length??0,error:n.error}}),(async r=>{try{await writeUploadToolResult(t,BEEOS_DESKTOP_SCREENSHOT_TOOL_NAME,r),await cleanupUploadToolResultCache()}catch(r){e.logger.warn?.(`[beeos_desktop_screenshot] persist cache failed toolCallId=${t}: ${String(r)}`)}return r})(n)}}),e.registerHttpRoute({path:"/beeos/files/stage",auth:"gateway",async handler(e,r){await handleFileStage(e,r,t.cfg)}}),e.registerHttpRoute({path:"/beeos/status",auth:"plugin",handler(e,t){handleStatusRequest(e,t,{publicKey:agentKeys?.publicKey??null,pluginVersion:PLUGIN_VERSION})}}),e.registerTool({name:BEEOS_LIST_FILES_TOOL_NAME,description:BEEOS_LIST_FILES_TOOL_DESCRIPTION,parameters:BEEOS_LIST_FILES_TOOL_SCHEMA,async execute(t,r,o){e.logger.debug?.(`[beeos_list_files] toolCallId=${t} params=${JSON.stringify(r)}`);const n=await executeListFiles(r,agentGateway,o);return a({component:"file-list-tool",domain:"tool",name:n.ok?"list_files.success":"list_files.failure",severity:n.ok?"info":"warn",payload:{toolCallId:t,ok:n.ok,fileCount:n.files?.length??0,error:n.error}}),n}}),e.registerTool(t=>({name:BEEOS_FETCH_FILE_TOOL_NAME,description:BEEOS_FETCH_FILE_TOOL_DESCRIPTION,parameters:BEEOS_FETCH_FILE_TOOL_SCHEMA,async execute(r,i,s){e.logger.debug?.(`[beeos_fetch_file] toolCallId=${r} params=${JSON.stringify(i)}`);const l=await executeFetchFile(i,agentGateway,{signal:s,workspaceDir:t.workspaceDir,...n?{native:{gatewayUrl:o.agentGatewayUrl,capability:consumeNativeOutputTool(r)}}:{}});return a({component:"file-fetch-tool",domain:"tool",name:l.ok?"fetch_file.success":"fetch_file.failure",severity:l.ok?"info":"warn",payload:{toolCallId:r,ok:l.ok,path:l.path,size:l.size,error:l.error}}),l}}),{name:BEEOS_FETCH_FILE_TOOL_NAME})}function registerServices(e,t,r){const{cfg:o,writeObs:a,thirdPartyChannels:n}=t,i=centralNativeChatEnabled()?requireCentralNativeSessionHost(e.runtime):void 0;if(sharedAutomationTurnPolicy.disable(),"function"==typeof e.on)try{e.on("before_tool_call",(e,t)=>sharedAutomationTurnPolicy.check(e.toolName,{sessionKey:t?.sessionKey,runId:t?.runId??e.runId}),{priority:100}),sharedAutomationTurnPolicy.enable()}catch{e.logger.warn?.("[beeos-claw] Automation Wake disabled: tool guard unavailable")}if("function"!=typeof e.on){if(o.messageBus.enabled)throw new Error("openclaw_before_message_write_hook_unavailable")}else registerModelCallObservationHooks((t,r)=>e.on(t,r),sharedModelCallObservationRouter),e.on("before_message_write",(t,r)=>{const o=t.sessionKey??r.sessionKey;if(!o)return void e.logger.debug?.("[before_message_write] ignored assistant write without sessionKey");sharedAssistantMessageCommitRouter.route(o,t.message)||e.logger.debug?.(`[before_message_write] no active IM commit target sessionKey=${o} active_targets=${sharedAssistantMessageCommitRouter.size()}`)}),e.on("before_tool_call",(e,t)=>{if("ask_user"!==(e.toolName||t.toolName))return;const r={sessionKey:t.sessionKey,runId:t.runId??e.runId,toolCallId:t.toolCallId??e.toolCallId};sharedQuestionBridge.observeAskUser(r),relayCentralAskUser((e,t)=>sharedGatewayClient?sharedGatewayClient.request(e,t):Promise.reject(new Error("Not connected to Gateway")),r).catch(e=>approvalLogger?.warn?.(`[question] central relay failed: ${e instanceof Error?e.message:String(e)}`))}),e.on("after_tool_call",(t,r)=>{const o=r.sessionKey,a=t.toolCallId??r.toolCallId,n=t.toolName||r.toolName;if(t.runId&&r.runId&&t.runId!==r.runId||t.toolCallId&&r.toolCallId&&t.toolCallId!==r.toolCallId||nativeHtmlDeliveryForRun(t.runId??r.runId)?.observe(n,t.params,t.result,Boolean(t.error),a),!o||!a||!n)return void e.logger.debug?.(`[after_tool_call] ignored structured result without correlation sessionKey=${o??"missing"} toolCallId=${a??"missing"}`);observeToolCallForDelivery(t,o);sharedToolResultObservationRouter.route(o,{toolCallId:a,toolName:n,rawResult:t.result,isError:Boolean(t.error)})||e.logger.debug?.(`[after_tool_call] no active IM observation target sessionKey=${o} active_targets=${sharedToolResultObservationRouter.size()}`)});const s=agentKeys?Buffer.from(agentKeys.publicKey).toString("base64"):void 0,l=join(process.env.OPENCLAW_HOME||join(homedir(),".openclaw"),"beeos"),c=sharedInboundExecutionJournal??=new FileInboundExecutionJournal(join(l,"inbound-execution-journal.v1.jsonl"));sharedMcpProjection??=new OpenClawNativeMcpProjection,!sharedMcpCredentialVault&&agentKeys&&s&&(sharedMcpCredentialVault=new LocalEncryptedCredentialReferenceVault(join(l,"mcp-credential-vault.json"),s,agentKeys.privateKey));const u=pluginCloudRuntimeTarget(e);if(setClaimedCloudRuntimeInstanceId(u),u&&(!agentKeys||!agentGateway))throw new Error("Cloud runtime authority requires an agent identity and gateway transport");const d=sharedRuntimeAuthority?.cloudTargetInstanceId;if(d&&u&&d!==u)throw new Error("Cloud runtime authority target changed during process lifetime");if(sharedRuntimeAuthority&&!d&&u&&sharedRuntimeAuthority.bindCloudTarget(u),!sharedRuntimeAuthority&&agentKeys&&agentGateway&&(sharedRuntimeAuthority=new RuntimeProductionAuthority({stateDirectory:l,gateway:agentGateway,keys:agentKeys,targetInstanceId:u,logger:e.logger,getMSConnectionStatus:e=>sharedMSConnectionStatus.get(e),identityLane:identityLaneFromEnvironment()})),sharedGatewayClient||(sharedGatewayClient=new GatewayClient({url:o.gateway.url,token:o.gateway.token||"",clientId:o.gateway.clientId,openclawCanvasCompat:!!o.openclawCanvasCompat,retry:{baseMs:o.retry.baseMs,maxMs:o.retry.maxMs,maxAttempts:o.retry.maxAttempts}}),sharedGatewayClient.on("gateway-event",(e,t)=>{sharedApprovalBridge.onGatewayEvent(e,t),sharedQuestionBridge.onGatewayEvent(e,t)})),approvalLogger??=e.logger,sharedRuntimeAgentCapabilities??={canvas:o.canvasEnabled,terminal:!1,webSsh:!1,fileSystem:!0,image:!0,audio:!1,mcp:!0,cron:!0,streaming:!0,pushNotifications:o.messageBus.enabled,...o.messageBus.enabled&&sharedAutomationTurnPolicy.isReady()&&agentGateway?{automationWake:!0}:{}},!sharedAgentProjection&&sharedRuntimeAuthority&&agentGateway){const t=sharedRuntimeAuthority;sharedAgentProjection=new AgentProjectionProduction({authority:t,stateFile:join(t.stateDirectory,"runtime-agent-projection.json"),journal:t.journal,identities:t.identities,source:new OpenClawAgentProjectionSource(()=>sharedGatewayClient),transport:new AgentGatewayHttpProjectionTransport({gateway:agentGateway,getRuntimeLeaseCredential:e=>{const r=t.authorityLease;if(!r||r.instanceId!==e.instanceId||r.leaseId!==e.leaseId||r.runtimeEpoch!==e.runtimeEpoch||r.handlerIdentity!==e.handlerIdentity)throw new Error("agent projection fenced by current runtime lease");return r.runtimeLeaseCredential},onAccepted:t=>{0!==t.size&&sharedAgentMappings.replace(t).catch(t=>{e.logger.warn?.("[agent-projection] mapping publication failed: "+(t instanceof Error?t.message:String(t)))})}}),capabilities:sharedRuntimeAgentCapabilities,logger:e.logger})}sharedRuntimeOwner??=new OpenClawRuntimeProcessOwner(sharedGatewayClient,sharedAgentProjection,e.logger);const g=sharedRuntimeOwner;sharedSessionMutationCoordinator??=new SessionMutationCoordinator(sharedSessionWriteGate,new OpenClawSessionWriteQuiescence(e.logger,{agentId:o.gateway.agentId||"main",...i?{nativeWritersQuiescent:e=>i.nativeWritersQuiescent({sessionKey:e})}:{}}),e.logger,{onRecoveryRequired:t=>{scheduleProcessRuntimeRestart(t,e.logger)}});const m=sharedSessionMutationCoordinator;if(i&&!sharedCentralPrompt){if(!sharedRuntimeAuthority?.cloudTargetInstanceId)throw new Error("central native chat requires the provisioned Cloud runtime authority");sharedCentralPrompt=createCentralNativeComposition({runtime:e.runtime,host:i,gatewayOrigin:o.agentGatewayUrl,stateDirectory:l,authority:sharedRuntimeAuthority,coordinator:m,logger:e.logger})}if(i&®isterCentralNativeMemoryTools(e),!sharedAcpServer){const t=sharedRuntimeAuthority&&agentGateway?new AgentGatewayTemplateOriginReporter({gateway:agentGateway}):void 0;sharedAcpServer=new ACPServer(o,e.logger,m,a,agentGateway??void 0,s,n,sharedTerminalManager,sharedRuntimeAuthority,void 0,sharedMcpProjection,sharedMcpCredentialVault,{gateway:g.client,agentProjection:sharedAgentProjection,markAgentProjectionDirty:()=>sharedAgentProjection?.markDirty(),templateOriginReporter:t,agentMappings:sharedAgentMappings,agentCapabilities:sharedRuntimeAgentCapabilities,createRunOutputRouter:createPeerRunOutputRouterFactory(new MessageServiceRunOutputChannel({getClient:()=>sharedMessageClientOwner.current?.client??null,logger:e.logger,writeObs:a})),runExclusive:(t,r,o)=>sharedImHotPathDeferral.runExclusive(t,r,e.logger,o)})}const p=sharedAcpServer,h=()=>sharedAgentMappings.snapshot()?.values().next().value;r.current=p,sharedMcpNativeProjectionNudge.request({registrationMode:e.registrationMode,fingerprint:fingerprintMcpServers(t.openclawConfig),logger:e.logger});const y=sharedPromptRunStore,{enabled:v,principalId:w,a2aEnabled:f}=o.messageBus;let C;!u&&o.agentGatewayUrl&&agentKeys&&(C=createBeeosClawMessageTokenProvider({agentGatewayUrl:o.agentGatewayUrl,identity:agentKeyPairToIdentity(agentKeys)}));const R=process.env.MESSAGE_RUNTIME_DELIVERY_KEY?.trim(),b=w||process.env.BEEOS_PRINCIPAL_ID||"",S=C?sharedMessageClientOwner.configure({tokenProvider:C,identityId:b,...o.messageBus.serviceUrl?{serviceUrl:o.messageBus.serviceUrl}:{},logger:e.logger,...sharedRuntimeAuthority&&R?{runtimeDelivery:{scopedDeliveryKey:R,authority:{currentLease:()=>{const e=sharedRuntimeAuthority?.authorityLease,t=sharedRuntimeAuthority?.currentConsumerBinding();return e&&t?{...e,journalStoreId:t.journalStoreId,journalGeneration:t.journalGeneration}:null}}}}:{}}):void 0,E=u&&o.messageBus.serviceUrl&&sharedRuntimeAuthority?new NodeRuntimeDeliveryPort({serviceOrigin:async()=>o.messageBus.serviceUrl},{currentLease:()=>{const e=sharedRuntimeAuthority?.authorityLease,t=sharedRuntimeAuthority?.currentConsumerBinding();return e&&t&&e.instanceId===u?{...e,journalStoreId:t.journalStoreId,journalGeneration:t.journalGeneration}:null},subscribeAuthority:e=>sharedRuntimeAuthority.subscribeAuthority(e)}):void 0;attachNativeCloudChat(e,o);const O=sharedRuntimeAuthority,_=o.messageBus.serviceUrl;S&&O&&_&&R?p.setCronConversationDelivery({deliver:async e=>{const t=O.authorityLease;if(!t)throw new Error("current runtime authority lease unavailable for cron delivery");const r=new MessageServiceCronDeliveryHttpAuthority({messageServiceUrl:_,scopedDeliveryKey:R,fetchAuthorized:(e,t)=>fetchRuntimeLeaseAttempt(e,t??{})});return await r.deliver({...e,runtimeLeaseCredential:t.runtimeLeaseCredential})}}):p.setCronConversationDelivery(void 0);const A=sharedRuntimeAuthority?.journal??new FileRuntimeCommandJournal(join(l,"runtime-command-journal.json"),void 0,void 0,{onMaintenanceError:t=>e.logger.error?.(`[runtime-journal] event=checkpoint_failed trigger=threshold error=${t instanceof Error?t.message:String(t)}`)}),I=g.createRegistrationToken();e.registerService({id:"beeos-acp",async start(){const t=Date.now(),r=_pluginRegisteredAt?t-_pluginRegisteredAt:-1;e.logger.info?.(`[beeos-claw] beeos-acp service start() begin, sincePluginRegister=${r}ms, bridge.url=${o.bridge.url||"(empty)"}`);const a=await createRuntimeServiceProductionCandidate({...agentGateway?{authorizationAdapter:new AgentGatewayGrantJwksReadinessAdapter({gateway:agentGateway})}:{},onGrantJwksWarm:t=>{t.ready?e.logger.info?.("[beeos-claw] Gateway grant keyset loaded"):e.logger.warn?.(`[beeos-claw] Gateway grant keyset not ready yet (attempt ${t.attempt}): ${t.error instanceof Error?t.error.message:String(t.error)}`)},...S&&agentGateway&&R?{transportAdapter:new RuntimeServiceTransportReadinessAdapter({gateway:agentGateway,messageService:S.nodeTransport,messageClient:S.client,configuredServiceUrl:o.messageBus.serviceUrl,scopedDeliveryKey:R})}:{},...E&&agentGateway&&o.messageBus.serviceUrl?{cloudTransportAdapter:new CloudRuntimeServiceTransportReadinessAdapter({gateway:agentGateway,configuredServiceUrl:o.messageBus.serviceUrl,runtimeDelivery:E,...sharedCentralPrompt?{centralPrompt:sharedCentralPrompt}:{},...sharedNativeCloudChat?{sessionNewConversation:sharedNativeCloudChat.sessionNewConversation,nativePrompt:{http:sharedNativeCloudChat.http,inputFiles:new NativeInputFilesHttpClient(o.agentGatewayUrl,()=>sharedRuntimeAuthority.authorityLease,(e,t)=>fetch(e,t)),runBoundary:new MessageServiceConversationRunBoundary({transport:{start:e=>E.startConversationRun(e),finish:e=>E.finishConversationRun(e)}}),host:{htmlDeliveryEnabled:o.canvasEnabled,resolveNativePromptSessionKey:(e,t)=>p.resolveNativePromptSessionKey(e,t),prepareNativePromptModel:(e,t,r)=>p.prepareNativePromptModel(e,t,r),runtime:e.runtime,pluginConfig:o,logger:e.logger,promptRunStore:y,assistantMessageCommitRouter:sharedAssistantMessageCommitRouter,toolResultObservationRouter:sharedToolResultObservationRouter,approvalStreams:sharedApprovalBridge,questionStreams:sharedQuestionBridge,modelCallObservationRouter:sharedModelCallObservationRouter,sessionMutationCoordinator:m,abortTransport:{chatAbort:(e,t)=>p.chatAbort(e,t)},activeRunAuthority:p.getActiveRunAuthority(),waitIfExclusive:(t,r)=>sharedImHotPathDeferral.waitIfExclusive(t,e.logger,r).then(()=>{})}}}:{}})}:{},commandJournal:A,poisonJournal:new FileRuntimePoisonDeliveryJournal(join(l,"runtime-poison-deliveries.json")),onConsumerDeliveryError:t=>{const r=null!==t&&"object"==typeof t?t:{},o=e=>"string"==typeof e&&e.length>0&&e.length<=256&&!/[\u0000-\u001f\u007f]/.test(e)?JSON.stringify(e):JSON.stringify("unavailable"),a="string"==typeof r.code&&/^[A-Za-z0-9_.:-]{1,64}$/.test(r.code)?r.code:"unavailable",n="number"==typeof r.status&&Number.isInteger(r.status)&&r.status>=100&&r.status<=599?String(r.status):"unavailable";e.logger.error?.(`[runtime-service] delivery worker failed before acknowledgement; delivery retained for retry: operation_id=${o(r.operationId)} delivery_id=${o(r.deliveryId)} code=${a} status=${n}`)},onConsumerLeaseStarvation:({starvedForMs:t,recovered:r})=>{const o=Math.round(t/1e3);r?e.logger.info?.(`[runtime-service] runtime authority lease restored after ${o}s without delivery reads`):e.logger.warn?.(`[runtime-service] no runtime authority lease for ${o}s; delivery reads suspended, queued runtime operations (model switch, session control) will not be consumed`)},onConsumerRequestFailure:t=>e.logger.error?.(`[runtime-service] request failed operationId=${t.operationId} method=${t.method}: ${t.error instanceof Error?t.error.stack??t.error.message:String(t.error)}`)});if(sharedRuntimeAuthority?.setRuntimeServiceMethods("ready"===a.status?a.serviceMethods:[]),sharedRuntimeAuthority?.setRuntimeResourceBindingContractRevision("ready"===a.status?a.resourceBindingContractRevision:void 0),p.setRuntimeRpcConsumerFactory("ready"===a.status?a.factory:void 0),"unavailable"===a.status?e.logger.warn?.("[runtime-service] capability fenced: "+a.blockers.map(e=>e.id).join(",")):a.capabilityBlockers.length&&e.logger.warn?.("[runtime-service] method capability fenced: "+a.capabilityBlockers.map(e=>e.method).join(",")),!o.bridge.url&&agentGateway){const t=Date.now(),r=await agentGateway.bridge.config();if(e.logger.info?.(`[beeos-claw] bridge discovery took ${Date.now()-t}ms result=${r?.url??"null"}`),r)o.bridge.url=r.url,writeDiscoveryCache({bridge:{url:r.url,discoveredAt:Date.now()}}),e.logger.info?.(`[beeos-claw] Bridge URL discovered from Agent Gateway: ${r.url}`);else{const t=readDiscoveryCache();t?.bridge?.url?(o.bridge.url=t.bridge.url,e.logger.info?.(`[beeos-claw] Bridge URL from cache (GW unreachable): ${t.bridge.url}`)):e.logger.debug?.("[beeos-claw] Bridge URL not available (no GW, no cache) — bridge disabled")}}await g.acquire(I);try{await p.start(o.bridge.url||void 0)}catch(e){throw await g.release(I),e}e.logger.info?.(`[beeos-claw] ACP Server started (total service start: ${Date.now()-t}ms)`)},async stop(){try{await g.release(I)}finally{await p.stop()}await A.checkpoint(),e.logger.info?.("[runtime-service] command journal checkpoint completed"),e.logger.info?.("[beeos-claw] ACP Server stopped")}});if(v&&void 0!==C&&C){const t=sharedMessageClientOwner.createRegistrationToken(),r=async(e,t)=>{const r=await C(e);if(!r.identityId||r.identityId!==e)throw new Error("Message SDK token identity did not match the current runtime authority");return{principalId:e,runtimeEpoch:t}},o=(e,t,r)=>({getLocalAgentId:()=>t,resolveLocalAgentId:e=>e===r?t:void 0,getDefaultPlatformAgent:()=>({instanceId:e.principalId}),ensureImInboundSession:(e,t,r,o)=>{p.ensureImInboundSession(e,t,r,o)},chatAbort:(e,t)=>p.chatAbort(e,t)}),n=sharedRuntimeAuthority?new RuntimeAuthorityMessageBusLifecycle({authority:sharedRuntimeAuthority,logger:e.logger,bus:{connect:async n=>{await sharedMessageClientOwner.acquire(t,async t=>{const i=await r(n.instanceId,n.runtimeEpoch),s=t.client,l={leaseId:n.leaseId,runtimeEpoch:n.runtimeEpoch};sharedMSConnectionStatus.bind(l);const u=new Map,d=new MessageProjectionInboundConsumer({client:s,bindings:()=>{const t=sharedRuntimeAuthority?.authorityLease;if(!t||t.instanceId!==i.principalId||t.runtimeEpoch!==i.runtimeEpoch)return[];const r=sharedAgentMappings.snapshot();return r?[...r.entries()].flatMap(([r,n])=>{if(!n.id||n.instanceId!==i.principalId)return[];let l=u.get(n.id);return l&&l.localAgentId===r||(l={localAgentId:r,inbound:createImInboundHandler({automationTurnPolicy:sharedAutomationTurnPolicy,runtime:e.runtime,pluginConfig:e.pluginConfig,client:s,localServer:o(i,r,n.id),promptRunStore:y,waitIfExclusive:(t,r)=>sharedImHotPathDeferral.waitIfExclusive(t,e.logger,r).then(()=>{}),assistantMessageCommitRouter:sharedAssistantMessageCommitRouter,toolResultObservationRouter:sharedToolResultObservationRouter,approvalStreams:sharedApprovalBridge,questionStreams:sharedQuestionBridge,modelCallObservationRouter:sharedModelCallObservationRouter,sessionMutationCoordinator:m,logger:e.logger,writeObs:a,principalIdOverride:i.principalId,activeRunAuthority:p.getActiveRunAuthority(),applyTurnModel:(e,t)=>p.applyImTurnModel(e,t),restoreTurnModel:e=>p.restoreImTurnModel(e),...agentGateway?{completeA2ATask:(t,r,o)=>completeA2ATask({gateway:agentGateway,logger:e.logger},t,r,o)}:{}})},u.set(n.id,l)),[{principalId:i.principalId,targetAgentId:n.id,runtimeEpoch:t.runtimeEpoch,inbound:l.inbound}]}):[]},executionJournal:c,logger:e.logger}),g=sharedAgentMappings.subscribe(()=>{sharedActiveMessageConsumer===d&&d.refresh()}),h=sharedRuntimeAuthority?.subscribeAuthority(()=>{sharedActiveMessageConsumer===d&&d.refresh()})??(()=>{}),v=new MessageClientTerminalStateRecovery({logger:e.logger,isCurrent:()=>{if(sharedActiveMessageConsumer!==d)return!1;const e=sharedRuntimeAuthority?.authorityLease;return null!=e&&e.instanceId===i.principalId&&e.runtimeEpoch===i.runtimeEpoch&&e.leaseId===n.leaseId&&e.handlerIdentity===n.handlerIdentity},reconnect:async()=>{if("failed"===s.getSnapshot().connection){await s.connect();try{await p.rebindRuntimeDelivery()}catch(t){e.logger.warn?.(`[beeos-claw] runtime Service delivery rebind failed after MessageClient recovery: ${t instanceof Error?t.message:String(t)}`)}}}});let w=s.getSnapshot().connection;sharedMSConnectionStatus.setIfCurrent(l,w);const f=s.subscribe(()=>{const t=s.getSnapshot();t.connection!==w&&(w=t.connection,sharedMSConnectionStatus.setIfCurrent(l,t.connection),"connected"===t.connection?(v.notifyConnected(),e.logger.info?.(`[beeos-claw] connection transport=message_service_realtime state=connected localAgentId=${p.getLocalAgentId()} principalId=${i.principalId}`)):"failed"===t.connection?(e.logger.warn?.(`[beeos-claw] connection transport=message_service_realtime state=failed principalId=${i.principalId} recoveryError=${t.recoveryError??"unknown"}`),v.notifyFailed()):"disconnected"!==t.connection&&"reconnecting"!==t.connection||e.logger.warn?.(`[beeos-claw] connection transport=message_service_realtime state=${t.connection} principalId=${i.principalId}; SDK owns reconnect/recovery`))});sharedActiveMessageConsumer=d,d.start();try{await s.connect()}catch(e){throw sharedActiveMessageConsumer===d&&(sharedActiveMessageConsumer=void 0),sharedMSConnectionStatus.resetIfCurrent(l),v.dispose(),await d.stop(),g(),h(),f(),await s.disconnect().catch(()=>{}),e}try{await p.rebindRuntimeDelivery()}catch(t){e.logger.warn?.(`[beeos-claw] runtime Service delivery rebind failed after MessageClient connect: ${t instanceof Error?t.message:String(t)}`)}return async()=>{sharedActiveMessageConsumer===d&&(sharedActiveMessageConsumer=void 0),sharedMSConnectionStatus.resetIfCurrent(l),v.dispose(),await d.stop(),h(),f(),await s.disconnect(),e.logger.info?.("[beeos-claw] MessageClient disconnected")}})},disconnect:async()=>{await sharedMessageClientOwner.release(t)}}}):void 0;e.registerService({id:"beeos-message-bus",async start(){n?n.start():e.logger.warn?.("[beeos-claw] Message bus requires runtime authority; waiting is unavailable without Agent Gateway runtime identity")},async stop(){await(n?.stop())}})}else v?e.logger.warn?.("[beeos-claw] Message bus enabled but Agent Gateway token provider is unavailable — disabled"):e.logger.info?.(`[beeos-claw] Message bus disabled (enabled=${v})`);if(o.messageBus.enabled&&u&&!sharedNativeCloudChat&&e.logger.warn?.("[beeos-claw] Cloud message bus enabled but native composition unavailable (messageBus.serviceUrl or runtime authority missing) — disabled"),!1!==f&&agentGateway){const t=e=>p.getGatewaySessionKeyForToolCall(e),r=e=>p.getMentionsForToolCall(e),o=(e,t)=>{p.broadcastNotification(e,t)},a=new TaskHandleRegistry;registerA2ATools(e,{gateway:agentGateway,logger:e.logger},a,t,r,o,()=>h()?.instanceId),e.logger.info?.("[beeos-claw] A2A tools registered (beeos_discover_agents, beeos_call_agent) via REST")}if(agentGateway&&(registerAutomationTools(e,{gateway:agentGateway,callConnectorTool:harnessConnectorToolCaller(),logger:e.logger,getDefaultAgent:()=>{const e=h();return e?{id:e.id,instanceId:e.instanceId}:void 0},getCurrentConversationId:e=>{const t=p.getGatewaySessionKeyForToolCall(e);return t?extractBeeosConversationIdFromSessionKey(t):void 0}}),e.logger.info?.("[beeos-claw] Automation tools registered (create/create_webhook/capabilities/preflight/list/get/run/runs/get_run)")),o.canvasEnabled){sharedCanvasState||(sharedCanvasState=new CanvasStateManager);const t=sharedCanvasState;if(agentGateway&&agentKeys){t.setLogger(e.logger);const r=claimedSandboxId(),a=createSandboxCanvasTokenProvider(agentGateway,r,()=>sharedRuntimeAuthority?.authorityLease),n=n=>{const i=new CanvasRelayClient({canvasRelayUrl:o.canvasRelayUrl,agentKeys:agentKeys,...r?{}:{agentId:n.id},displayName:n.displayName,avatarUrl:n.avatarUrl,tokenProvider:a,onConnected:()=>p.flushPendingCanvasLinks(),onReconnect:()=>p.onRelayReconnected(),logger:e.logger});t.setRelayClient(i),t.setAgentId(n.id),p.wireRelayActionHandler(),i.connect(),e.logger.info?.(`[beeos-claw] Canvas Relay multiplexed client connected (agentId=${n.id}, name=${n.name??"none"})`)};e.registerService(createCanvasRelayService({getAgent:r?()=>({id:`sandbox:${r}`}):h,onceAgentReady:e=>sharedAgentMappings.onceReady(e),initRelay:n,stopRelay:()=>t.getRelayClient()?.disconnect(),logger:e.logger})),e.logger.info?.("[beeos-claw] Canvas Relay configured")}else e.logger.warn?.("[beeos-claw] Canvas Relay unavailable: agentGatewayUrl or agentKeys missing");const r={stateManager:t,logger:e.logger,writeObs:e=>a(e),getActiveSessionId:e=>p.getSessionIdForToolCall(e),getPlatformAgentId:e=>p.getPlatformAgentIdForToolCall(e),getGatewaySessionKey:e=>p.getGatewaySessionKeyForToolCall(e),waitForAgentSync:()=>sharedAgentMappings.waitForSynchronization(),publishStaticHtml:createStaticCanvasHtmlPublisher(pluginCloudRuntimeTarget(e)?o.agentGatewayUrl:void 0)},i=new FormSchemaRegistry,s=buildCronSchemas(n);i.register(s.create),i.register(s.update);const l=new ResourceDescriptorRegistry;l.register(CRON_RESOURCE);const c=e=>async(t,r,o)=>(p.preMapToolCallSession(t),e(t,r));e.registerTool({name:RENDER_UI_TOOL_NAME,description:RENDER_UI_TOOL_DESCRIPTION,parameters:RENDER_UI_TOOL_SCHEMA,execute:c(createRenderUiToolExecutor(r))}),e.registerTool({name:CLOSE_UI_TOOL_NAME,description:CLOSE_UI_TOOL_DESCRIPTION,parameters:CLOSE_UI_TOOL_SCHEMA,execute:c(createCloseUiHandler(r))}),p.setCanvasState(t,{schemaRegistry:i,descriptorRegistry:l});const u=p.getFormBuilder();u&&e.registerTool({name:RENDER_FORM_TOOL_NAME,description:buildRenderFormDescription(i),parameters:RENDER_FORM_TOOL_SCHEMA,execute:c(createRenderFormHandler({registry:i,builder:u,logger:e.logger}))});const d=p.getResourceRenderer();if(d){generateActionTools(l,e,async(e,t)=>p.gatewayRequest(e,t),d,e.logger)}const g=buildToolRoutingHint(BEEOS_FILE_RESOURCE_ROUTING_RULE,BEEOS_DESKTOP_SCREENSHOT_TOOL_NAME),m=new Set([RENDER_UI_TOOL_NAME,CLOSE_UI_TOOL_NAME,RENDER_FORM_TOOL_NAME]),y=256,v=new Map;if("function"==typeof e.on){try{e.on("before_prompt_build",(e,t)=>{if(t?.sessionKey){if(v.size>=y&&!v.has(t.sessionKey)){const e=v.keys().next().value;void 0!==e&&v.delete(e)}v.set(t.sessionKey,t.channelId),rememberDeliveryWorkspace(t.sessionKey,t.workspaceDir)}const r=isThirdPartyChannel(n,{sessionKey:t?.sessionKey,channelId:t?.channelId});return t?.sessionKey||r?{appendSystemContext:buildAppendSystemContext({thirdParty:r,canvasSystemPrompt:`${CANVAS_PRESENTATION_GATE}\n\n${CANVAS_SYSTEM_PROMPT}`,toolRoutingHint:g})}:{appendSystemContext:g}}),e.logger.debug?.("[beeos-claw] Canvas system prompt hook registered: before_prompt_build")}catch{e.logger.debug?.("[beeos-claw] before_prompt_build hook not supported")}try{e.on("before_tool_call",(e,t)=>{if(t?.sessionKey&&p.setPendingToolCallSessionKey(t.sessionKey),!m.has(e.toolName))return;const r=t?.sessionKey?v.get(t.sessionKey):void 0,o=isThirdPartyChannel(n,{sessionKey:t?.sessionKey,channelId:r}),a=canvasToolBlockReason({thirdParty:o,hasSession:Boolean(t?.sessionKey)});return a?{block:!0,blockReason:a}:void 0}),e.logger.debug?.("[beeos-claw] Canvas tool guard registered: before_tool_call")}catch{e.logger.debug?.("[beeos-claw] before_tool_call hook not supported")}}e.logger.info?.("[beeos-claw] Canvas tools registered (render_ui, close_ui, render_form + auto-action tools)")}else e.logger.info?.("[beeos-claw] Canvas disabled by config (canvasEnabled=false)");if(o.bridge.shell.enabled&&!0===o.legacyTerminalWsEnabled){const t=createTerminalWebSocketService({config:{port:o.terminalWsPort,token:agentKeys?Buffer.from(agentKeys.publicKey).toString("base64"):"",allowedOrigins:o.terminalWsAllowedOrigins},terminalMgr:sharedTerminalManager,logger:e.logger,writeObs:a});e.registerService({id:"beeos-terminal-ws",start(){t.start(),e.logger.info?.(`[beeos-claw] Terminal WS started on port ${o.terminalWsPort}`)},stop(){t.stop(),e.logger.info?.("[beeos-claw] Terminal WS stopped")}})}else o.bridge.shell.enabled?e.logger.info?.("[beeos-claw] Legacy static-token Terminal WS disabled (default)"):e.logger.info?.("[beeos-claw] Terminal/shell disabled by config (bridge.shell.enabled=false)");if(t.openclawConfig){const r=mirrorOpenClawConfig(t.openclawConfig);r.copied?e.logger.info?.(`[beeos-claw] mirrored openclaw config to ${r.destinationPath}`):e.logger.debug?.(`[beeos-claw] openclaw config mirror skipped: ${r.reason}`)}}export function pluginCloudRuntimeTarget(e){const t=e.pluginConfig?.cloudRuntimeInstanceId;return cloudRuntimeTargetInstanceId("string"==typeof t?t:claimedSandboxId())}function attachNativeCloudChat(e,t){if(sharedNativeChatService)return e.registerService(sharedNativeChatService),sharedNativeCloudChat;const r=sharedRuntimeAuthority,o=t.messageBus.serviceUrl,a=sharedAcpServer,n=sharedSessionMutationCoordinator;if(!(r&&r.cloudTargetInstanceId&&o&&a&&n))return sharedNativeCloudChat;const i=sharedNativeCloudChat??createNativeCloudChatComposition({authority:nativeCloudChatAuthorityFromRuntimeAuthority(r),serviceUrl:o,logger:e.logger});if(sharedNativeCloudChat=i,!t.messageBus.enabled)return i;const s=i,l=r;let c;const u=new Map,d=new RuntimeAuthorityMessageBusLifecycle({authority:l,logger:e.logger,bus:{connect:async t=>{c?.(),u.clear(),c=s.adapter.listen({eventTypes:["message.created"]},r=>{if(r.type===APPROVAL_DECISION_MESSAGE_TYPE&&r.senderId?.startsWith("user:")&&isApprovalDocument(r.content))return void sharedApprovalBridge.onDecision(r.content);if("user.continue"===r.type&&isQuestionResponseDocument(r.content))return void sharedQuestionBridge.onResponse(r);const o=(r.content??{}).metadata??{},i="string"==typeof o.target_agent_id?o.target_agent_id:"",l=i?((t,r)=>{const o=sharedAgentMappings.snapshot();if(o)for(const[i,l]of o.entries()){if(l.id!==r)continue;if(l.instanceId!==t.instanceId)continue;const o=`${i}\0${l.id}`;let c=u.get(o);return c||(c={localAgentId:i,inbound:createImInboundHandler({runtime:e.runtime,pluginConfig:e.pluginConfig,client:s.adapter,localServer:{getLocalAgentId:()=>i,resolveLocalAgentId:e=>e===l.id?i:void 0,getDefaultPlatformAgent:()=>({instanceId:t.instanceId}),ensureImInboundSession:(e,t,r,o)=>{a.ensureImInboundSession(e,t,r,o)},chatAbort:(e,t)=>a.chatAbort(e,t)},promptRunStore:sharedPromptRunStore,waitIfExclusive:(t,r)=>sharedImHotPathDeferral.waitIfExclusive(t,e.logger,r).then(()=>{}),assistantMessageCommitRouter:sharedAssistantMessageCommitRouter,toolResultObservationRouter:sharedToolResultObservationRouter,approvalStreams:sharedApprovalBridge,questionStreams:sharedQuestionBridge,modelCallObservationRouter:sharedModelCallObservationRouter,sessionMutationCoordinator:n,logger:e.logger,writeObs:sharedWriteObs,principalIdOverride:t.instanceId,activeRunAuthority:a.getActiveRunAuthority(),applyTurnModel:(e,t)=>a.applyImTurnModel(e,t),restoreTurnModel:e=>a.restoreImTurnModel(e),...agentGateway?{completeA2ATask:(t,r,o)=>completeA2ATask({gateway:agentGateway,logger:e.logger},t,r,o)}:{}})},u.set(o,c)),c}})(t,i):void 0;if(!l)return void e.logger.warn?.(`[beeos-claw] native cloud chat dropped unresolvable target_agent_id=${i||"missing"} message_id=${r.id}`);("chat_cancel"===r.type?l.inbound.onChatCancel(r):l.inbound.onChatMessage(r)).catch(t=>{e.logger.error?.(`[beeos-claw] native cloud chat dispatch failed message_id=${r.id}: ${t instanceof Error?t.message:String(t)}`)})});try{await s.adapter.connect()}catch(e){throw c?.(),c=void 0,e}},disconnect:async()=>{c?.(),c=void 0,u.clear(),await s.adapter.disconnect()}}});return sharedNativeChatService={id:"beeos-native-cloud-chat",async start(){d.start()},async stop(){await d.stop()}},e.registerService(sharedNativeChatService),e.logger.info?.("[beeos-claw] native Cloud personal-chat composition registered"),i}const plugin={id:"beeos-claw",name:"beeos-claw",description:"BeeOS platform bridge plugin for OpenClaw. Provides file upload/download, ACP bridge, and observability.",version:PLUGIN_VERSION,register(e){if(_initializing)return;registerCentralNativeContextEngine(e),registerSandboxNativeActivation(e,()=>{if(!sharedSessionMutationCoordinator)throw new Error("native session writer coordinator is unavailable");return sharedSessionMutationCoordinator.activeMutationCount},createSandboxNativeTargetLookup(()=>sharedRuntimeAuthority,()=>sharedGatewayClient),async()=>{if(!sharedGatewayClient?.isConnected)throw new Error("OpenClaw gateway is not connected");await sharedGatewayClient.request("secrets.reload",{})});const t=pluginCloudRuntimeTarget(e),r=void 0!==t&&t!==sharedRuntimeAuthority?.cloudTargetInstanceId,o=planPluginRegistration(e.registrationMode,_fullRuntimeRegistered,r);if("skip"!==o){_initializing=!0;try{if(!hasRuntimeReplyApi(e.runtime))throw e.logger.error?.("[beeos-claw] FATAL: OpenClaw runtime.channel.reply.dispatchReplyFromConfig not exposed. Upgrade OpenClaw or revert beeos-claw."),new Error("openclaw_runtime_reply_api_unavailable");const t=(t,r)=>{registerUploadTools(e,t,r),registerArouterLatencyRouting(e),registerArouterMediaProviders(e)};if("capabilities"===o&&sharedPluginContext){if(cachedCapabilityTools.length>0){const t=resolveCapabilityToolReplay({currentRegisterTool:e.registerTool,wrappedRegisterTool:wrappedRegisterTool,originalRegisterTool:rawRegisterTool}),r=replayCachedPluginTools((r,o)=>t.call(e,r,o),cachedCapabilityTools);return registerArouterLatencyRouting(e),registerArouterMediaProviders(e),void e.logger.info?.(`[beeos-claw] capability re-register mode=${e.registrationMode} tools_only count=${r}`)}const r={current:sharedAcpServer??null};return t(sharedPluginContext,r),registerServices(e,sharedPluginContext,r),void e.logger.info?.(`[beeos-claw] capability re-register mode=${e.registrationMode} capabilities_only`)}const r=initializePlugin(e);if(!r)return;const a={current:null};installUnhandledRejectionObserver(e,r.writeObs,a),ensureRegisterToolCache(e),cacheRuntimeRegistrations(e),cachedCapabilityTools.length=0,t(r,a),agentGateway&&(e.on?e.on("before_agent_finalize",async(e,t)=>{if(await fileDeliveryFinalizeDecision(e),!e.runId||!t?.runId||e.runId===t.runId)return nativeHtmlDeliveryForRun(e.runId??t?.runId)?.beforeFinalize(e)}):e.logger.warn?.("[file-delivery] OpenClaw plugin hooks unavailable; finalization check disabled")),registerServices(e,r,a),sharedPluginContext=r,marksFullRuntimeRegistered(e.registrationMode,o)&&(_fullRuntimeRegistered=!0),_pluginRegisteredAt=Date.now(),e.logger.info?.("[beeos-claw] Plugin registered successfully")}finally{_initializing=!1}}else if(!e.registrationMode||"full"===e.registrationMode){const t=resolveCapabilityToolReplay({currentRegisterTool:e.registerTool,wrappedRegisterTool:wrappedRegisterTool,originalRegisterTool:rawRegisterTool});replayCachedPluginTools((r,o)=>t.call(e,r,o),cachedCapabilityTools),replayRuntimeRegistrations(e),registerArouterLatencyRouting(e),registerArouterMediaProviders(e)}}};export default plugin;
|
|
1
|
+
import{claimedSandboxId,identityLaneFromEnvironment}from"./runtime/identity-lane-lease.js";import{createCentralNativeComposition,requireCentralNativeSessionHost}from"./runtime/central-native-composition.js";import{createSandboxNativeTargetLookup,registerSandboxNativeActivation}from"./runtime/sandbox-native-activation.js";import{registerCentralNativeMemoryTools}from"./runtime/central-native-memory.js";import{harnessConnectorToolCaller}from"./connectors/harness-connector-mcp.js";import{registerCentralNativeContextEngine,centralNativeChatEnabled}from"./runtime/central-native-runtime.js";import{relayCentralAskUser}from"./runtime/central-native-interactions.js";import{consumeNativeOutputTool,nativeHtmlDeliveryForRun}from"./runtime/native-output-file-attempt.js";import{uploadNativeOutputFile}from"./upload/upload-file.js";import{nativeOutputToolCallGate}from"./upload/native-output-tool-hook.js";import{NativeInputFilesHttpClient}from"./runtime/native-input-files-http.js";import{fileDeliveryFinalizeDecision}from"./upload/finalize-hook.js";import{resolveConfigWithMeta,mirrorOpenClawConfig}from"./config.js";import{hasRuntimeReplyApi}from"./runtime/reply-router.js";import{PromptRunStore}from"./runtime/prompt-run-store.js";import{createMcpNativeProjectionNudge,fingerprintMcpServers}from"./acp-gateway/mcp-native-projection-nudge.js";import{createImHotPathDeferral}from"./runtime/im-hot-path-deferral.js";import{SessionWriteGate}from"./acp-gateway/session-write-gate.js";import{OpenClawSessionWriteQuiescence}from"./runtime/openclaw-session-write-quiescence.js";import{SessionMutationCoordinator}from"./runtime/session-mutation-coordinator.js";import{scheduleProcessRuntimeRestart}from"./runtime/runtime-restart-scheduler.js";import{createImInboundHandler}from"./im-inbound-handler.js";import{AgentGatewayClient,NodeRuntimeDeliveryPort,agentIdentityFromKeyPair,loadAgentKeyPair,signAgentMessage}from"@beeos-ai/cloud-harness-sdk";import{MessageServiceConversationRunBoundary}from"./runtime/message-service-conversation-run-boundary.js";import{AutomationTurnPolicy}from"./automation/turn-policy.js";import{registerAutomationTools}from"./automation/tools.js";import{extractBeeosConversationIdFromSessionKey}from"./runtime/openclaw-session-key-resolution.js";import{setOpenClawConfigSnapshot}from"./runtime/openclaw-session-model.js";import{BeeosClawMessageClientProcessOwner,createBeeosClawMessageTokenProvider}from"./message-client-composition.js";import{MessageProjectionInboundConsumer}from"./message-projection-inbound-consumer.js";import{MessageClientTerminalStateRecovery}from"./runtime/message-client-terminal-state-recovery.js";import{RuntimeAuthorityMessageBusLifecycle}from"./runtime/runtime-authority-message-bus-lifecycle.js";import{createNativeCloudChatComposition,nativeCloudChatAuthorityFromRuntimeAuthority}from"./runtime/native-cloud-chat-composition.js";import{MSConnectionStatusSnapshot}from"./runtime/ms-connection-status.js";import{FileInboundExecutionJournal}from"./inbound-execution-journal.js";import{completeA2ATask,registerA2ATools,TaskHandleRegistry}from"./a2a/tools.js";import{BEEOS_UPLOAD_TOOL_NAME,BEEOS_UPLOAD_TOOL_SCHEMA,BEEOS_UPLOAD_TOOL_DESCRIPTION,REQUEST_TIMEOUT_MS as BEEOS_UPLOAD_REQUEST_TIMEOUT_MS,executeUpload}from"./upload/tool.js";import{BEEOS_DESKTOP_SCREENSHOT_TOOL_NAME,BEEOS_DESKTOP_SCREENSHOT_TOOL_SCHEMA,BEEOS_DESKTOP_SCREENSHOT_TOOL_DESCRIPTION,executeDesktopScreenshot}from"./upload/desktop-screenshot-tool.js";import{BEEOS_LIST_FILES_TOOL_NAME,BEEOS_LIST_FILES_TOOL_SCHEMA,BEEOS_LIST_FILES_TOOL_DESCRIPTION,executeListFiles}from"./files/list-tool.js";import{BEEOS_FETCH_FILE_TOOL_NAME,BEEOS_FETCH_FILE_TOOL_SCHEMA,BEEOS_FETCH_FILE_TOOL_DESCRIPTION,executeFetchFile}from"./files/fetch-tool.js";import{writeUploadToolResult,cleanupUploadToolResultCache}from"./upload/result-cache.js";import{handleFileStage}from"./upload/file-stage.js";import{handleStatusRequest}from"./status.js";import{ACPServer}from"./acp-server.js";import{GatewayClient}from"./gateway-client.js";import{createObsEventWriter}from"./observability.js";import{resolvePluginVersion}from"./plugin-version.js";import{createTerminalWebSocketService}from"./terminal/websocket.js";import{TerminalManager}from"./terminal/session-manager.js";import{readDiscoveryCache,writeDiscoveryCache}from"./discovery-cache.js";import{setClaimedCloudRuntimeInstanceId,setUploadDeps}from"./upload/upload-file.js";import{registerLocalFileExtractor}from"./upload/local-file-extractors.js";import{browserScreenshotExtractor}from"./browser/screenshot-extractor.js";import{deliverableFileExtractor}from"./upload/deliverable-extractor.js";import{observeToolCallForDelivery,rememberDeliveryWorkspace}from"./upload/delivery-observe.js";import{sessionWorkspaceDir}from"./upload/delivery-ledger.js";import{BEEOS_FILE_RESOURCE_ROUTING_RULE}from"./files/beeos-file-uri.js";import{marksFullRuntimeRegistered,planPluginRegistration,replayCachedPluginTools,resolveCapabilityToolReplay}from"./plugin-registration-plan.js";import{buildAppendSystemContext,buildToolRoutingHint,canvasToolBlockReason}from"./prompt-system-context.js";import{CanvasStateManager}from"./canvas/state.js";import{createStaticCanvasHtmlPublisher}from"./canvas/static-html.js";import{CanvasRelayClient}from"./canvas/relay-client.js";import{createSandboxCanvasTokenProvider}from"./canvas/runtime-lease-token.js";import{createCanvasRelayService}from"./canvas/relay-service.js";import{RENDER_UI_TOOL_NAME,RENDER_UI_TOOL_DESCRIPTION,RENDER_UI_TOOL_SCHEMA,CLOSE_UI_TOOL_NAME,CLOSE_UI_TOOL_DESCRIPTION,CLOSE_UI_TOOL_SCHEMA,createRenderUiToolExecutor,createCloseUiHandler,CANVAS_PRESENTATION_GATE,CANVAS_SYSTEM_PROMPT}from"./canvas/tools.js";import{FormSchemaRegistry}from"./surface/form-schema-registry.js";import{buildCronSchemas}from"./surface/cron-schemas.js";import{RENDER_FORM_TOOL_NAME,RENDER_FORM_TOOL_SCHEMA,buildRenderFormDescription,createRenderFormHandler}from"./surface/render-form-tool.js";import{ResourceDescriptorRegistry}from"./surface/resource-descriptor-registry.js";import{CRON_RESOURCE}from"./surface/cron-resource.js";import{generateActionTools}from"./surface/action-tool-generator.js";import{buildThirdPartyChannelSet,isThirdPartyChannel}from"./channel-detection.js";import{registerArouterMediaProviders}from"./media/index.js";import{homedir}from"node:os";import{join}from"node:path";import{RuntimeProductionAuthority,cloudRuntimeTargetInstanceId}from"./runtime/runtime-production-authority.js";import{FileRuntimeCommandJournal}from"./runtime/runtime-command-journal.js";import{FileRuntimePoisonDeliveryJournal}from"./runtime/runtime-poison-delivery-journal.js";import{OpenClawNativeMcpProjection}from"./acp-gateway/openclaw-native-mcp-projection.js";import{LocalEncryptedCredentialReferenceVault}from"./acp-gateway/mcp-credential-reference-port.js";import{AgentGatewayGrantJwksReadinessAdapter,CloudRuntimeServiceTransportReadinessAdapter,RuntimeServiceTransportReadinessAdapter,createRuntimeServiceProductionCandidate}from"./runtime/runtime-service-production-candidate.js";import{fetchRuntimeLeaseAttempt}from"./runtime/message-service-runtime-authenticated-fetch.js";import{MessageServiceCronDeliveryHttpAuthority}from"./runtime/message-service-cron-delivery-http-authority.js";import{AgentMappingRegistry}from"./runtime/agent-mapping-registry.js";import{OpenClawRuntimeProcessOwner}from"./runtime/openclaw-runtime-process-owner.js";import{AgentGatewayHttpProjectionTransport,AgentGatewayTemplateOriginReporter,AgentProjectionProduction,OpenClawAgentProjectionSource}from"./runtime/agent-projection-production.js";import{MessageServiceRunOutputChannel}from"./runtime/message-service-run-output-channel.js";import{AssistantMessageCommitRouter}from"./runtime/assistant-message-commit-router.js";import{OpenClawApprovalBridge}from"./approval/bridge.js";import{APPROVAL_DECISION_MESSAGE_TYPE,isApprovalDocument}from"./approval/protocol.generated.js";import{isQuestionResponseDocument,OpenClawQuestionBridge}from"./question/bridge.js";import{ToolResultObservationRouter}from"./runtime/tool-result-observation-router.js";import{ModelCallObservationRouter,registerModelCallObservationHooks}from"./runtime/model-call-observability.js";import{registerArouterLatencyRouting}from"./runtime/arouter-latency-routing.js";import{createPeerRunOutputRouterFactory}from"./runtime/run-output-composition.js";const PLUGIN_VERSION=resolvePluginVersion();let agentKeys=null,agentGateway=null,sharedCanvasState=null,sharedAcpServer=null;const sharedSessionWriteGate=new SessionWriteGate,sharedPromptRunStore=new PromptRunStore,sharedAutomationTurnPolicy=new AutomationTurnPolicy;let lastOpenclawConfig;const sharedMcpNativeProjectionNudge=createMcpNativeProjectionNudge({getActiveImRunCount:()=>sharedPromptRunStore.size(),nudge:()=>{sharedAcpServer?.nudgeMcpNativeProjection()}}),sharedImHotPathDeferral=createImHotPathDeferral({getActiveImRunCount:()=>sharedPromptRunStore.size()});sharedPromptRunStore.setOnBecameIdle(()=>{sharedMcpNativeProjectionNudge.flushIfIdle({fingerprint:fingerprintMcpServers(lastOpenclawConfig)}),sharedImHotPathDeferral.notifyIdle()});const sharedAssistantMessageCommitRouter=new AssistantMessageCommitRouter,sharedToolResultObservationRouter=new ToolResultObservationRouter;let approvalLogger;const sharedApprovalBridge=new OpenClawApprovalBridge({request:(e,t)=>sharedGatewayClient?sharedGatewayClient.request(e,t):Promise.reject(new Error("Not connected to Gateway")),logger:{info:e=>approvalLogger?.info?.(e),warn:e=>approvalLogger?.warn?.(e)}}),sharedQuestionBridge=new OpenClawQuestionBridge({request:(e,t)=>sharedGatewayClient?sharedGatewayClient.request(e,t):Promise.reject(new Error("Not connected to Gateway")),logger:{info:e=>approvalLogger?.info?.(e),warn:e=>approvalLogger?.warn?.(e)}}),sharedModelCallObservationRouter=new ModelCallObservationRouter;let sharedSessionMutationCoordinator,sharedCentralPrompt,sharedRuntimeAuthority,sharedNativeChatService,sharedNativeCloudChat,sharedWriteObs=()=>{};const sharedMSConnectionStatus=new MSConnectionStatusSnapshot,sharedAgentMappings=new AgentMappingRegistry;let sharedGatewayClient,sharedRuntimeOwner,sharedAgentProjection,sharedRuntimeAgentCapabilities,sharedMcpProjection,sharedMcpCredentialVault;const sharedMessageClientOwner=new BeeosClawMessageClientProcessOwner;let sharedActiveMessageConsumer,sharedInboundExecutionJournal;const sharedTerminalManager=new TerminalManager;let _initializing=!1,_pluginRegisteredAt=0,_fullRuntimeRegistered=!1;const cachedCapabilityTools=[];let rawRegisterTool,wrappedRegisterTool;const cachedRuntimeServices=[],cachedRuntimeHooks=[];let rawRegisterService,wrappedRegisterService,rawOn,wrappedOn;function cacheRuntimeRegistrations(e){const t=e.registerService===wrappedRegisterService?rawRegisterService:e.registerService;if(rawRegisterService=t,wrappedRegisterService=r=>{cachedRuntimeServices.push(r),t.call(e,r)},e.registerService=wrappedRegisterService,cachedRuntimeServices.length=0,cachedRuntimeHooks.length=0,e.on){const t=e.on===wrappedOn?rawOn:e.on;rawOn=t,wrappedOn=(...r)=>{cachedRuntimeHooks.push(r),t.call(e,...r)},e.on=wrappedOn}}function replayRuntimeRegistrations(e){const t=e.registerService===wrappedRegisterService?rawRegisterService:e.registerService,r=e.on===wrappedOn?rawOn:e.on;for(const t of cachedRuntimeHooks)r.call(e,...t);for(const r of cachedRuntimeServices)t.call(e,r)}const ensureRegisterToolCache=e=>{const t=e.registerTool===wrappedRegisterTool?rawRegisterTool:e.registerTool;rawRegisterTool=t.bind(e),wrappedRegisterTool=(e,t)=>(cachedCapabilityTools.push({tool:e,options:t}),rawRegisterTool(e,t)),e.registerTool=wrappedRegisterTool};function agentKeyPairToIdentity(e){return{publicKeyBase64:()=>Buffer.from(e.publicKey).toString("base64"),sign:async t=>signAgentMessage(t,e.privateKey)}}let sharedPluginContext=null,unhandledRejectionObserverInstalled=!1;function installUnhandledRejectionObserver(e,t,r){unhandledRejectionObserverInstalled||(unhandledRejectionObserverInstalled=!0,process.on("unhandledRejection",r=>{const o=r instanceof Error?r.message:String(r),a=r instanceof Error?r.stack:void 0;e.logger.error?.(`[beeos-claw] unhandledRejection: ${o}${a?`\n${a}`:""}`),t({component:"plugin",domain:"fatal",name:"unhandled_rejection",severity:"error",summary:o,error:{code:"unhandled_rejection",message:o,...a?{stack:a}:{}}})}),process.on("uncaughtException",r=>{const o=r instanceof Error?r.message:String(r);e.logger.error?.(`[beeos-claw] uncaughtException: ${r instanceof Error?r.stack??r.message:String(r)}`),t({component:"plugin",domain:"fatal",name:"uncaught_exception",severity:"error",summary:o,error:{code:"uncaught_exception",message:o}})}))}function initializePlugin(e){let t,r;try{t=e.runtime?.config?.loadConfig?.()}catch{}try{r=resolveConfigWithMeta({pluginConfig:e.pluginConfig??{},openclawConfig:t})}catch(t){return e.logger.error?.(`[beeos-claw] Failed to resolve config: ${t instanceof Error?t.message:String(t)}`),null}const o=r.config,a=buildThirdPartyChannelSet(t);a.size>0&&e.logger.info?.(`[beeos-claw] Third-party channels detected: ${[...a].join(", ")}`);const n=o.log.enabled?createObsEventWriter({dir:o.log.dir,redaction:{gatewayToken:o.gateway.token},logger:e.logger}):()=>{};n({component:"plugin",domain:"lifecycle",name:"lifecycle.startup",severity:"info",payload:{pluginVersion:PLUGIN_VERSION,pid:process.pid,nodeVersion:process.version,cwd:process.cwd()}}),n({component:"plugin",domain:"config",name:"config.resolved",severity:"info",payload:{config:o,sources:r.sources,openclawConfigPath:r.openclawConfigPath}});for(const t of r.validation)n({component:"plugin",domain:"config",name:"config.validation",severity:t.severity,summary:t.message,error:{code:t.code,message:t.message,nextSteps:t.nextSteps}}),"error"===t.severity?e.logger.error?.(`[beeos-claw] ${t.message}`):e.logger.warn?.(`[beeos-claw] ${t.message}`);if(r.validation.some(e=>"error"===e.severity)&&e.logger.error?.("[beeos-claw] Plugin has configuration errors — some features may not work."),o.keyFile)try{agentKeys=loadAgentKeyPair(o.keyFile),agentGateway=o.agentGatewayUrl?new AgentGatewayClient({baseUrl:o.agentGatewayUrl,identity:agentIdentityFromKeyPair(agentKeys),onRetry:({method:t,path:r,attempt:o,delayMs:a,error:n})=>e.logger.warn?.(`[beeos-claw] Agent Gateway ${t} ${r} retry ${o} in ${a}ms: ${n instanceof Error?n.message:String(n)}`)}):null;const t=Buffer.from(agentKeys.publicKey).toString("base64");e.logger.info?.(`[beeos-claw] v${PLUGIN_VERSION} registering (publicKey: ${t})`)}catch(t){e.logger.warn?.(`[beeos-claw] Failed to load agent key pair: ${t}`),e.logger.info?.(`[beeos-claw] v${PLUGIN_VERSION} registering (no key pair — signed requests disabled)`)}else e.logger.info?.(`[beeos-claw] v${PLUGIN_VERSION} registering (no keyFile configured)`);return agentGateway&&(setUploadDeps({gateway:agentGateway,logger:e.logger}),registerLocalFileExtractor(browserScreenshotExtractor),registerLocalFileExtractor(deliverableFileExtractor),e.logger.info?.("[beeos-claw] Upload deps + local file extractors registered")),lastOpenclawConfig=t,sharedWriteObs=n,setOpenClawConfigSnapshot(t),{cfg:o,writeObs:n,thirdPartyChannels:a,openclawConfig:t}}function registerUploadTools(e,t,r){const{cfg:o,writeObs:a}=t,n=Boolean(pluginCloudRuntimeTarget(e));if(n){if(!e.on)throw new Error("native output Files Host hook unavailable");e.on("before_tool_call",(t,r)=>nativeOutputToolCallGate(t,r,e.logger))}cleanupUploadToolResultCache().catch(t=>{e.logger.warn?.(`[beeos_upload_file] cache cleanup failed on startup: ${String(t)}`)}),e.registerTool(t=>({name:BEEOS_UPLOAD_TOOL_NAME,description:BEEOS_UPLOAD_TOOL_DESCRIPTION,parameters:BEEOS_UPLOAD_TOOL_SCHEMA,async execute(r,i,s){const l=n?consumeNativeOutputTool(r):void 0,c=t.workspaceDir??sessionWorkspaceDir(t.sessionKey),u=await executeUpload(i,agentGateway,s,l?(e,t)=>uploadNativeOutputFile(e,o.agentGatewayUrl,l,t,s,BEEOS_UPLOAD_REQUEST_TIMEOUT_MS):void 0,e.logger,l?c:void 0);return e.logger.debug?.(`[beeos_upload_file] toolCallId=${r} ok=${u.ok}`),a({component:"upload-tool",domain:"tool",name:u.ok?"upload.success":"upload.failure",severity:u.ok?"info":"warn",payload:{toolCallId:r,ok:u.ok,fileCount:u.files?.length??0,error:u.error}}),(async t=>{try{await writeUploadToolResult(r,BEEOS_UPLOAD_TOOL_NAME,t),await cleanupUploadToolResultCache()}catch(t){e.logger.warn?.(`[beeos_upload_file] persist cache failed toolCallId=${r}: ${String(t)}`)}return t})(u)}}),{name:BEEOS_UPLOAD_TOOL_NAME}),e.registerTool({name:BEEOS_DESKTOP_SCREENSHOT_TOOL_NAME,description:BEEOS_DESKTOP_SCREENSHOT_TOOL_DESCRIPTION,parameters:BEEOS_DESKTOP_SCREENSHOT_TOOL_SCHEMA,async execute(t,r,o){e.logger.debug?.(`[beeos_desktop_screenshot] toolCallId=${t} params=${JSON.stringify(r)}`);const n=await executeDesktopScreenshot(r,agentGateway,o);return e.logger.debug?.(`[beeos_desktop_screenshot] toolCallId=${t} ok=${n.ok}`),a({component:"desktop-screenshot-tool",domain:"tool",name:n.ok?"desktop_screenshot.success":"desktop_screenshot.failure",severity:n.ok?"info":"warn",payload:{toolCallId:t,ok:n.ok,path:n.path,fileCount:n.files?.length??0,error:n.error}}),(async r=>{try{await writeUploadToolResult(t,BEEOS_DESKTOP_SCREENSHOT_TOOL_NAME,r),await cleanupUploadToolResultCache()}catch(r){e.logger.warn?.(`[beeos_desktop_screenshot] persist cache failed toolCallId=${t}: ${String(r)}`)}return r})(n)}}),e.registerHttpRoute({path:"/beeos/files/stage",auth:"gateway",async handler(e,r){await handleFileStage(e,r,t.cfg)}}),e.registerHttpRoute({path:"/beeos/status",auth:"plugin",handler(e,t){handleStatusRequest(e,t,{publicKey:agentKeys?.publicKey??null,pluginVersion:PLUGIN_VERSION})}}),e.registerTool({name:BEEOS_LIST_FILES_TOOL_NAME,description:BEEOS_LIST_FILES_TOOL_DESCRIPTION,parameters:BEEOS_LIST_FILES_TOOL_SCHEMA,async execute(t,r,o){e.logger.debug?.(`[beeos_list_files] toolCallId=${t} params=${JSON.stringify(r)}`);const n=await executeListFiles(r,agentGateway,o);return a({component:"file-list-tool",domain:"tool",name:n.ok?"list_files.success":"list_files.failure",severity:n.ok?"info":"warn",payload:{toolCallId:t,ok:n.ok,fileCount:n.files?.length??0,error:n.error}}),n}}),e.registerTool(t=>({name:BEEOS_FETCH_FILE_TOOL_NAME,description:BEEOS_FETCH_FILE_TOOL_DESCRIPTION,parameters:BEEOS_FETCH_FILE_TOOL_SCHEMA,async execute(r,i,s){e.logger.debug?.(`[beeos_fetch_file] toolCallId=${r} params=${JSON.stringify(i)}`);const l=await executeFetchFile(i,agentGateway,{signal:s,workspaceDir:t.workspaceDir,...n?{native:{gatewayUrl:o.agentGatewayUrl,capability:consumeNativeOutputTool(r)}}:{}});return a({component:"file-fetch-tool",domain:"tool",name:l.ok?"fetch_file.success":"fetch_file.failure",severity:l.ok?"info":"warn",payload:{toolCallId:r,ok:l.ok,path:l.path,size:l.size,error:l.error}}),l}}),{name:BEEOS_FETCH_FILE_TOOL_NAME})}function registerServices(e,t,r){const{cfg:o,writeObs:a,thirdPartyChannels:n}=t,i=centralNativeChatEnabled()?requireCentralNativeSessionHost(e.runtime):void 0;if(sharedAutomationTurnPolicy.disable(),"function"==typeof e.on)try{e.on("before_tool_call",(e,t)=>sharedAutomationTurnPolicy.check(e.toolName,{sessionKey:t?.sessionKey,runId:t?.runId??e.runId}),{priority:100}),sharedAutomationTurnPolicy.enable()}catch{e.logger.warn?.("[beeos-claw] Automation Wake disabled: tool guard unavailable")}if("function"!=typeof e.on){if(o.messageBus.enabled)throw new Error("openclaw_before_message_write_hook_unavailable")}else registerModelCallObservationHooks((t,r)=>e.on(t,r),sharedModelCallObservationRouter),e.on("before_message_write",(t,r)=>{const o=t.sessionKey??r.sessionKey;if(!o)return void e.logger.debug?.("[before_message_write] ignored assistant write without sessionKey");sharedAssistantMessageCommitRouter.route(o,t.message)||e.logger.debug?.(`[before_message_write] no active IM commit target sessionKey=${o} active_targets=${sharedAssistantMessageCommitRouter.size()}`)}),e.on("before_tool_call",(e,t)=>{if("ask_user"!==(e.toolName||t.toolName))return;const r={sessionKey:t.sessionKey,runId:t.runId??e.runId,toolCallId:t.toolCallId??e.toolCallId};sharedQuestionBridge.observeAskUser(r),relayCentralAskUser((e,t)=>sharedGatewayClient?sharedGatewayClient.request(e,t):Promise.reject(new Error("Not connected to Gateway")),r).catch(e=>approvalLogger?.warn?.(`[question] central relay failed: ${e instanceof Error?e.message:String(e)}`))}),e.on("after_tool_call",(t,r)=>{const o=r.sessionKey,a=t.toolCallId??r.toolCallId,n=t.toolName||r.toolName;if(t.runId&&r.runId&&t.runId!==r.runId||t.toolCallId&&r.toolCallId&&t.toolCallId!==r.toolCallId||nativeHtmlDeliveryForRun(t.runId??r.runId)?.observe(n,t.params,t.result,Boolean(t.error),a),!o||!a||!n)return void e.logger.debug?.(`[after_tool_call] ignored structured result without correlation sessionKey=${o??"missing"} toolCallId=${a??"missing"}`);observeToolCallForDelivery(t,o);sharedToolResultObservationRouter.route(o,{toolCallId:a,toolName:n,rawResult:t.result,isError:Boolean(t.error)})||e.logger.debug?.(`[after_tool_call] no active IM observation target sessionKey=${o} active_targets=${sharedToolResultObservationRouter.size()}`)});const s=agentKeys?Buffer.from(agentKeys.publicKey).toString("base64"):void 0,l=join(process.env.OPENCLAW_HOME||join(homedir(),".openclaw"),"beeos"),c=sharedInboundExecutionJournal??=new FileInboundExecutionJournal(join(l,"inbound-execution-journal.v1.jsonl"));sharedMcpProjection??=new OpenClawNativeMcpProjection,!sharedMcpCredentialVault&&agentKeys&&s&&(sharedMcpCredentialVault=new LocalEncryptedCredentialReferenceVault(join(l,"mcp-credential-vault.json"),s,agentKeys.privateKey));const u=pluginCloudRuntimeTarget(e);if(setClaimedCloudRuntimeInstanceId(u),u&&(!agentKeys||!agentGateway))throw new Error("Cloud runtime authority requires an agent identity and gateway transport");const d=sharedRuntimeAuthority?.cloudTargetInstanceId;if(d&&u&&d!==u)throw new Error("Cloud runtime authority target changed during process lifetime");if(sharedRuntimeAuthority&&!d&&u&&sharedRuntimeAuthority.bindCloudTarget(u),!sharedRuntimeAuthority&&agentKeys&&agentGateway&&(sharedRuntimeAuthority=new RuntimeProductionAuthority({stateDirectory:l,gateway:agentGateway,keys:agentKeys,targetInstanceId:u,logger:e.logger,getMSConnectionStatus:e=>sharedMSConnectionStatus.get(e),identityLane:identityLaneFromEnvironment()})),sharedGatewayClient||(sharedGatewayClient=new GatewayClient({url:o.gateway.url,token:o.gateway.token||"",clientId:o.gateway.clientId,openclawCanvasCompat:!!o.openclawCanvasCompat,retry:{baseMs:o.retry.baseMs,maxMs:o.retry.maxMs,maxAttempts:o.retry.maxAttempts}}),sharedGatewayClient.on("gateway-event",(e,t)=>{sharedApprovalBridge.onGatewayEvent(e,t),sharedQuestionBridge.onGatewayEvent(e,t)})),approvalLogger??=e.logger,sharedRuntimeAgentCapabilities??={canvas:o.canvasEnabled,terminal:!1,webSsh:!1,fileSystem:!0,image:!0,audio:!1,mcp:!0,cron:!0,streaming:!0,pushNotifications:o.messageBus.enabled,...o.messageBus.enabled&&sharedAutomationTurnPolicy.isReady()&&agentGateway?{automationWake:!0}:{}},!sharedAgentProjection&&sharedRuntimeAuthority&&agentGateway){const t=sharedRuntimeAuthority;sharedAgentProjection=new AgentProjectionProduction({authority:t,stateFile:join(t.stateDirectory,"runtime-agent-projection.json"),journal:t.journal,identities:t.identities,source:new OpenClawAgentProjectionSource(()=>sharedGatewayClient),transport:new AgentGatewayHttpProjectionTransport({gateway:agentGateway,getRuntimeLeaseCredential:e=>{const r=t.authorityLease;if(!r||r.instanceId!==e.instanceId||r.leaseId!==e.leaseId||r.runtimeEpoch!==e.runtimeEpoch||r.handlerIdentity!==e.handlerIdentity)throw new Error("agent projection fenced by current runtime lease");return r.runtimeLeaseCredential},onAccepted:t=>{0!==t.size&&sharedAgentMappings.replace(t).catch(t=>{e.logger.warn?.("[agent-projection] mapping publication failed: "+(t instanceof Error?t.message:String(t)))})}}),capabilities:sharedRuntimeAgentCapabilities,logger:e.logger})}sharedRuntimeOwner??=new OpenClawRuntimeProcessOwner(sharedGatewayClient,sharedAgentProjection,e.logger);const g=sharedRuntimeOwner;sharedSessionMutationCoordinator??=new SessionMutationCoordinator(sharedSessionWriteGate,new OpenClawSessionWriteQuiescence(e.logger,{agentId:o.gateway.agentId||"main",...i?{nativeWritersQuiescent:e=>i.nativeWritersQuiescent({sessionKey:e})}:{}}),e.logger,{onRecoveryRequired:t=>{scheduleProcessRuntimeRestart(t,e.logger)}});const m=sharedSessionMutationCoordinator;if(i&&!sharedCentralPrompt){if(!sharedRuntimeAuthority?.cloudTargetInstanceId)throw new Error("central native chat requires the provisioned Cloud runtime authority");sharedCentralPrompt=createCentralNativeComposition({runtime:e.runtime,host:i,gatewayOrigin:o.agentGatewayUrl,stateDirectory:l,authority:sharedRuntimeAuthority,coordinator:m,logger:e.logger})}if(i&®isterCentralNativeMemoryTools(e),!sharedAcpServer){const t=sharedRuntimeAuthority&&agentGateway?new AgentGatewayTemplateOriginReporter({gateway:agentGateway}):void 0;sharedAcpServer=new ACPServer(o,e.logger,m,a,agentGateway??void 0,s,n,sharedTerminalManager,sharedRuntimeAuthority,void 0,sharedMcpProjection,sharedMcpCredentialVault,{gateway:g.client,agentProjection:sharedAgentProjection,markAgentProjectionDirty:()=>sharedAgentProjection?.markDirty(),templateOriginReporter:t,agentMappings:sharedAgentMappings,agentCapabilities:sharedRuntimeAgentCapabilities,createRunOutputRouter:createPeerRunOutputRouterFactory(new MessageServiceRunOutputChannel({getClient:()=>sharedMessageClientOwner.current?.client??null,logger:e.logger,writeObs:a})),runExclusive:(t,r,o)=>sharedImHotPathDeferral.runExclusive(t,r,e.logger,o)})}const p=sharedAcpServer,h=()=>sharedAgentMappings.snapshot()?.values().next().value;r.current=p,sharedMcpNativeProjectionNudge.request({registrationMode:e.registrationMode,fingerprint:fingerprintMcpServers(t.openclawConfig),logger:e.logger});const y=sharedPromptRunStore,{enabled:v,principalId:w,a2aEnabled:f}=o.messageBus;let C;!u&&o.agentGatewayUrl&&agentKeys&&(C=createBeeosClawMessageTokenProvider({agentGatewayUrl:o.agentGatewayUrl,identity:agentKeyPairToIdentity(agentKeys)}));const R=process.env.MESSAGE_RUNTIME_DELIVERY_KEY?.trim(),b=w||process.env.BEEOS_PRINCIPAL_ID||"",S=C?sharedMessageClientOwner.configure({tokenProvider:C,identityId:b,...o.messageBus.serviceUrl?{serviceUrl:o.messageBus.serviceUrl}:{},logger:e.logger,...sharedRuntimeAuthority&&R?{runtimeDelivery:{scopedDeliveryKey:R,authority:{currentLease:()=>{const e=sharedRuntimeAuthority?.authorityLease,t=sharedRuntimeAuthority?.currentConsumerBinding();return e&&t?{...e,journalStoreId:t.journalStoreId,journalGeneration:t.journalGeneration}:null}}}}:{}}):void 0,E=u&&o.messageBus.serviceUrl&&sharedRuntimeAuthority?new NodeRuntimeDeliveryPort({serviceOrigin:async()=>o.messageBus.serviceUrl},{currentLease:()=>{const e=sharedRuntimeAuthority?.authorityLease,t=sharedRuntimeAuthority?.currentConsumerBinding();return e&&t&&e.instanceId===u?{...e,journalStoreId:t.journalStoreId,journalGeneration:t.journalGeneration}:null},subscribeAuthority:e=>sharedRuntimeAuthority.subscribeAuthority(e)}):void 0;attachNativeCloudChat(e,o);const O=sharedRuntimeAuthority,_=o.messageBus.serviceUrl;S&&O&&_&&R?p.setCronConversationDelivery({deliver:async e=>{const t=O.authorityLease;if(!t)throw new Error("current runtime authority lease unavailable for cron delivery");const r=new MessageServiceCronDeliveryHttpAuthority({messageServiceUrl:_,scopedDeliveryKey:R,fetchAuthorized:(e,t)=>fetchRuntimeLeaseAttempt(e,t??{})});return await r.deliver({...e,runtimeLeaseCredential:t.runtimeLeaseCredential})}}):p.setCronConversationDelivery(void 0);const A=sharedRuntimeAuthority?.journal??new FileRuntimeCommandJournal(join(l,"runtime-command-journal.json"),void 0,void 0,{onMaintenanceError:t=>e.logger.error?.(`[runtime-journal] event=checkpoint_failed trigger=threshold error=${t instanceof Error?t.message:String(t)}`)}),I=g.createRegistrationToken();e.registerService({id:"beeos-acp",async start(){const t=Date.now(),r=_pluginRegisteredAt?t-_pluginRegisteredAt:-1;e.logger.info?.(`[beeos-claw] beeos-acp service start() begin, sincePluginRegister=${r}ms, bridge.url=${o.bridge.url||"(empty)"}`);const a=await createRuntimeServiceProductionCandidate({...agentGateway?{authorizationAdapter:new AgentGatewayGrantJwksReadinessAdapter({gateway:agentGateway})}:{},onGrantJwksWarm:t=>{t.ready?e.logger.info?.("[beeos-claw] Gateway grant keyset loaded"):e.logger.warn?.(`[beeos-claw] Gateway grant keyset not ready yet (attempt ${t.attempt}): ${t.error instanceof Error?t.error.message:String(t.error)}`)},...S&&agentGateway&&R?{transportAdapter:new RuntimeServiceTransportReadinessAdapter({gateway:agentGateway,messageService:S.nodeTransport,messageClient:S.client,configuredServiceUrl:o.messageBus.serviceUrl,scopedDeliveryKey:R})}:{},...E&&agentGateway&&o.messageBus.serviceUrl?{cloudTransportAdapter:new CloudRuntimeServiceTransportReadinessAdapter({gateway:agentGateway,configuredServiceUrl:o.messageBus.serviceUrl,runtimeDelivery:E,...sharedCentralPrompt?{centralPrompt:sharedCentralPrompt}:{},...sharedNativeCloudChat?{sessionNewConversation:sharedNativeCloudChat.sessionNewConversation,nativePrompt:{http:sharedNativeCloudChat.http,inputFiles:new NativeInputFilesHttpClient(o.agentGatewayUrl,()=>sharedRuntimeAuthority.authorityLease,(e,t)=>fetch(e,t)),runBoundary:new MessageServiceConversationRunBoundary({transport:{start:e=>E.startConversationRun(e),finish:e=>E.finishConversationRun(e)}}),host:{htmlDeliveryEnabled:o.canvasEnabled,resolveNativePromptSessionKey:(e,t)=>p.resolveNativePromptSessionKey(e,t),prepareNativePromptModel:(e,t,r)=>p.prepareNativePromptModel(e,t,r),runtime:e.runtime,pluginConfig:o,logger:e.logger,promptRunStore:y,assistantMessageCommitRouter:sharedAssistantMessageCommitRouter,toolResultObservationRouter:sharedToolResultObservationRouter,approvalStreams:sharedApprovalBridge,questionStreams:sharedQuestionBridge,modelCallObservationRouter:sharedModelCallObservationRouter,sessionMutationCoordinator:m,abortTransport:{chatAbort:(e,t)=>p.chatAbort(e,t)},activeRunAuthority:p.getActiveRunAuthority(),waitIfExclusive:(t,r)=>sharedImHotPathDeferral.waitIfExclusive(t,e.logger,r).then(()=>{})}}}:{}})}:{},commandJournal:A,poisonJournal:new FileRuntimePoisonDeliveryJournal(join(l,"runtime-poison-deliveries.json")),onConsumerDeliveryError:t=>{const r=null!==t&&"object"==typeof t?t:{},o=e=>"string"==typeof e&&e.length>0&&e.length<=256&&!/[\u0000-\u001f\u007f]/.test(e)?JSON.stringify(e):JSON.stringify("unavailable"),a="string"==typeof r.code&&/^[A-Za-z0-9_.:-]{1,64}$/.test(r.code)?r.code:"unavailable",n="number"==typeof r.status&&Number.isInteger(r.status)&&r.status>=100&&r.status<=599?String(r.status):"unavailable";e.logger.error?.(`[runtime-service] delivery worker failed before acknowledgement; delivery retained for retry: operation_id=${o(r.operationId)} delivery_id=${o(r.deliveryId)} code=${a} status=${n}`)},onConsumerLeaseStarvation:({starvedForMs:t,recovered:r})=>{const o=Math.round(t/1e3);r?e.logger.info?.(`[runtime-service] runtime authority lease restored after ${o}s without delivery reads`):e.logger.warn?.(`[runtime-service] no runtime authority lease for ${o}s; delivery reads suspended, queued runtime operations (model switch, session control) will not be consumed`)},onConsumerRequestFailure:t=>e.logger.error?.(`[runtime-service] request failed operationId=${t.operationId} method=${t.method}: ${t.error instanceof Error?t.error.stack??t.error.message:String(t.error)}`)});if(sharedRuntimeAuthority?.setRuntimeServiceMethods("ready"===a.status?a.serviceMethods:[]),sharedRuntimeAuthority?.setRuntimeResourceBindingContractRevision("ready"===a.status?a.resourceBindingContractRevision:void 0),p.setRuntimeRpcConsumerFactory("ready"===a.status?a.factory:void 0),"unavailable"===a.status?e.logger.warn?.("[runtime-service] capability fenced: "+a.blockers.map(e=>e.id).join(",")):a.capabilityBlockers.length&&e.logger.warn?.("[runtime-service] method capability fenced: "+a.capabilityBlockers.map(e=>e.method).join(",")),!o.bridge.url&&agentGateway){const t=Date.now(),r=await agentGateway.bridge.config();if(e.logger.info?.(`[beeos-claw] bridge discovery took ${Date.now()-t}ms result=${r?.url??"null"}`),r)o.bridge.url=r.url,writeDiscoveryCache({bridge:{url:r.url,discoveredAt:Date.now()}}),e.logger.info?.(`[beeos-claw] Bridge URL discovered from Agent Gateway: ${r.url}`);else{const t=readDiscoveryCache();t?.bridge?.url?(o.bridge.url=t.bridge.url,e.logger.info?.(`[beeos-claw] Bridge URL from cache (GW unreachable): ${t.bridge.url}`)):e.logger.debug?.("[beeos-claw] Bridge URL not available (no GW, no cache) — bridge disabled")}}await g.acquire(I);try{await p.start(o.bridge.url||void 0)}catch(e){throw await g.release(I),e}e.logger.info?.(`[beeos-claw] ACP Server started (total service start: ${Date.now()-t}ms)`)},async stop(){try{await g.release(I)}finally{await p.stop()}await A.checkpoint(),e.logger.info?.("[runtime-service] command journal checkpoint completed"),e.logger.info?.("[beeos-claw] ACP Server stopped")}});if(v&&void 0!==C&&C){const t=sharedMessageClientOwner.createRegistrationToken(),r=async(e,t)=>{const r=await C(e);if(!r.identityId||r.identityId!==e)throw new Error("Message SDK token identity did not match the current runtime authority");return{principalId:e,runtimeEpoch:t}},o=(e,t,r)=>({getLocalAgentId:()=>t,resolveLocalAgentId:e=>e===r?t:void 0,getDefaultPlatformAgent:()=>({instanceId:e.principalId}),ensureImInboundSession:(e,t,r,o)=>{p.ensureImInboundSession(e,t,r,o)},chatAbort:(e,t)=>p.chatAbort(e,t)}),n=sharedRuntimeAuthority?new RuntimeAuthorityMessageBusLifecycle({authority:sharedRuntimeAuthority,logger:e.logger,bus:{connect:async n=>{await sharedMessageClientOwner.acquire(t,async t=>{const i=await r(n.instanceId,n.runtimeEpoch),s=t.client,l={leaseId:n.leaseId,runtimeEpoch:n.runtimeEpoch};sharedMSConnectionStatus.bind(l);const u=new Map,d=new MessageProjectionInboundConsumer({client:s,bindings:()=>{const t=sharedRuntimeAuthority?.authorityLease;if(!t||t.instanceId!==i.principalId||t.runtimeEpoch!==i.runtimeEpoch)return[];const r=sharedAgentMappings.snapshot();return r?[...r.entries()].flatMap(([r,n])=>{if(!n.id||n.instanceId!==i.principalId)return[];let l=u.get(n.id);return l&&l.localAgentId===r||(l={localAgentId:r,inbound:createImInboundHandler({automationTurnPolicy:sharedAutomationTurnPolicy,runtime:e.runtime,pluginConfig:e.pluginConfig,client:s,localServer:o(i,r,n.id),promptRunStore:y,waitIfExclusive:(t,r)=>sharedImHotPathDeferral.waitIfExclusive(t,e.logger,r).then(()=>{}),assistantMessageCommitRouter:sharedAssistantMessageCommitRouter,toolResultObservationRouter:sharedToolResultObservationRouter,approvalStreams:sharedApprovalBridge,questionStreams:sharedQuestionBridge,modelCallObservationRouter:sharedModelCallObservationRouter,sessionMutationCoordinator:m,logger:e.logger,writeObs:a,principalIdOverride:i.principalId,activeRunAuthority:p.getActiveRunAuthority(),applyTurnModel:(e,t)=>p.applyImTurnModel(e,t),restoreTurnModel:e=>p.restoreImTurnModel(e),...agentGateway?{completeA2ATask:(t,r,o)=>completeA2ATask({gateway:agentGateway,logger:e.logger},t,r,o)}:{}})},u.set(n.id,l)),[{principalId:i.principalId,targetAgentId:n.id,runtimeEpoch:t.runtimeEpoch,inbound:l.inbound}]}):[]},executionJournal:c,logger:e.logger}),g=sharedAgentMappings.subscribe(()=>{sharedActiveMessageConsumer===d&&d.refresh()}),h=sharedRuntimeAuthority?.subscribeAuthority(()=>{sharedActiveMessageConsumer===d&&d.refresh()})??(()=>{}),v=new MessageClientTerminalStateRecovery({logger:e.logger,isCurrent:()=>{if(sharedActiveMessageConsumer!==d)return!1;const e=sharedRuntimeAuthority?.authorityLease;return null!=e&&e.instanceId===i.principalId&&e.runtimeEpoch===i.runtimeEpoch&&e.leaseId===n.leaseId&&e.handlerIdentity===n.handlerIdentity},reconnect:async()=>{if("failed"===s.getSnapshot().connection){await s.connect();try{await p.rebindRuntimeDelivery()}catch(t){e.logger.warn?.(`[beeos-claw] runtime Service delivery rebind failed after MessageClient recovery: ${t instanceof Error?t.message:String(t)}`)}}}});let w=s.getSnapshot().connection;sharedMSConnectionStatus.setIfCurrent(l,w);const f=s.subscribe(()=>{const t=s.getSnapshot();t.connection!==w&&(w=t.connection,sharedMSConnectionStatus.setIfCurrent(l,t.connection),"connected"===t.connection?(v.notifyConnected(),e.logger.info?.(`[beeos-claw] connection transport=message_service_realtime state=connected localAgentId=${p.getLocalAgentId()} principalId=${i.principalId}`)):"failed"===t.connection?(e.logger.warn?.(`[beeos-claw] connection transport=message_service_realtime state=failed principalId=${i.principalId} recoveryError=${t.recoveryError??"unknown"}`),v.notifyFailed()):"disconnected"!==t.connection&&"reconnecting"!==t.connection||e.logger.warn?.(`[beeos-claw] connection transport=message_service_realtime state=${t.connection} principalId=${i.principalId}; SDK owns reconnect/recovery`))});sharedActiveMessageConsumer=d,d.start();try{await s.connect()}catch(e){throw sharedActiveMessageConsumer===d&&(sharedActiveMessageConsumer=void 0),sharedMSConnectionStatus.resetIfCurrent(l),v.dispose(),await d.stop(),g(),h(),f(),await s.disconnect().catch(()=>{}),e}try{await p.rebindRuntimeDelivery()}catch(t){e.logger.warn?.(`[beeos-claw] runtime Service delivery rebind failed after MessageClient connect: ${t instanceof Error?t.message:String(t)}`)}return async()=>{sharedActiveMessageConsumer===d&&(sharedActiveMessageConsumer=void 0),sharedMSConnectionStatus.resetIfCurrent(l),v.dispose(),await d.stop(),h(),f(),await s.disconnect(),e.logger.info?.("[beeos-claw] MessageClient disconnected")}})},disconnect:async()=>{await sharedMessageClientOwner.release(t)}}}):void 0;e.registerService({id:"beeos-message-bus",async start(){n?n.start():e.logger.warn?.("[beeos-claw] Message bus requires runtime authority; waiting is unavailable without Agent Gateway runtime identity")},async stop(){await(n?.stop())}})}else v?e.logger.warn?.("[beeos-claw] Message bus enabled but Agent Gateway token provider is unavailable — disabled"):e.logger.info?.(`[beeos-claw] Message bus disabled (enabled=${v})`);if(o.messageBus.enabled&&u&&!sharedNativeCloudChat&&e.logger.warn?.("[beeos-claw] Cloud message bus enabled but native composition unavailable (messageBus.serviceUrl or runtime authority missing) — disabled"),!1!==f&&agentGateway){const t=e=>p.getGatewaySessionKeyForToolCall(e),r=e=>p.getMentionsForToolCall(e),o=(e,t)=>{p.broadcastNotification(e,t)},a=new TaskHandleRegistry;registerA2ATools(e,{gateway:agentGateway,logger:e.logger},a,t,r,o,()=>h()?.instanceId),e.logger.info?.("[beeos-claw] A2A tools registered (beeos_discover_agents, beeos_call_agent) via REST")}if(agentGateway&&(registerAutomationTools(e,{gateway:agentGateway,callConnectorTool:harnessConnectorToolCaller(),logger:e.logger,getDefaultAgent:()=>{const e=h();return e?{id:e.id,instanceId:e.instanceId}:void 0},getCurrentConversationId:e=>{const t=p.getGatewaySessionKeyForToolCall(e);return t?extractBeeosConversationIdFromSessionKey(t):void 0}}),e.logger.info?.("[beeos-claw] Automation tools registered (create/create_webhook/capabilities/preflight/list/get/run/runs/get_run)")),o.canvasEnabled){sharedCanvasState||(sharedCanvasState=new CanvasStateManager);const t=sharedCanvasState;if(agentGateway&&agentKeys){t.setLogger(e.logger);const r=claimedSandboxId(),a=createSandboxCanvasTokenProvider(agentGateway,r,()=>sharedRuntimeAuthority?.authorityLease),n=n=>{const i=new CanvasRelayClient({canvasRelayUrl:o.canvasRelayUrl,agentKeys:agentKeys,...r?{}:{agentId:n.id},displayName:n.displayName,avatarUrl:n.avatarUrl,tokenProvider:a,onConnected:()=>p.flushPendingCanvasLinks(),onReconnect:()=>p.onRelayReconnected(),logger:e.logger});t.setRelayClient(i),t.setAgentId(n.id),p.wireRelayActionHandler(),i.connect(),e.logger.info?.(`[beeos-claw] Canvas Relay multiplexed client connected (agentId=${n.id}, name=${n.name??"none"})`)};e.registerService(createCanvasRelayService({getAgent:r?()=>({id:`sandbox:${r}`}):h,onceAgentReady:e=>sharedAgentMappings.onceReady(e),initRelay:n,stopRelay:()=>t.getRelayClient()?.disconnect(),logger:e.logger})),e.logger.info?.("[beeos-claw] Canvas Relay configured")}else e.logger.warn?.("[beeos-claw] Canvas Relay unavailable: agentGatewayUrl or agentKeys missing");const r={stateManager:t,logger:e.logger,writeObs:e=>a(e),getActiveSessionId:e=>p.getSessionIdForToolCall(e),getPlatformAgentId:e=>p.getPlatformAgentIdForToolCall(e),getGatewaySessionKey:e=>p.getGatewaySessionKeyForToolCall(e),waitForAgentSync:()=>sharedAgentMappings.waitForSynchronization(),publishStaticHtml:createStaticCanvasHtmlPublisher(pluginCloudRuntimeTarget(e)?o.agentGatewayUrl:void 0)},i=new FormSchemaRegistry,s=buildCronSchemas(n);i.register(s.create),i.register(s.update);const l=new ResourceDescriptorRegistry;l.register(CRON_RESOURCE);const c=e=>async(t,r,o)=>(p.preMapToolCallSession(t),e(t,r));e.registerTool({name:RENDER_UI_TOOL_NAME,description:RENDER_UI_TOOL_DESCRIPTION,parameters:RENDER_UI_TOOL_SCHEMA,execute:c(createRenderUiToolExecutor(r))}),e.registerTool({name:CLOSE_UI_TOOL_NAME,description:CLOSE_UI_TOOL_DESCRIPTION,parameters:CLOSE_UI_TOOL_SCHEMA,execute:c(createCloseUiHandler(r))}),p.setCanvasState(t,{schemaRegistry:i,descriptorRegistry:l});const u=p.getFormBuilder();u&&e.registerTool({name:RENDER_FORM_TOOL_NAME,description:buildRenderFormDescription(i),parameters:RENDER_FORM_TOOL_SCHEMA,execute:c(createRenderFormHandler({registry:i,builder:u,logger:e.logger}))});const d=p.getResourceRenderer();if(d){generateActionTools(l,e,async(e,t)=>p.gatewayRequest(e,t),d,e.logger)}const g=buildToolRoutingHint(BEEOS_FILE_RESOURCE_ROUTING_RULE,BEEOS_DESKTOP_SCREENSHOT_TOOL_NAME),m=new Set([RENDER_UI_TOOL_NAME,CLOSE_UI_TOOL_NAME,RENDER_FORM_TOOL_NAME]),y=256,v=new Map;if("function"==typeof e.on){try{e.on("before_prompt_build",(e,t)=>{if(t?.sessionKey){if(v.size>=y&&!v.has(t.sessionKey)){const e=v.keys().next().value;void 0!==e&&v.delete(e)}v.set(t.sessionKey,t.channelId),rememberDeliveryWorkspace(t.sessionKey,t.workspaceDir)}const r=isThirdPartyChannel(n,{sessionKey:t?.sessionKey,channelId:t?.channelId});return t?.sessionKey||r?{appendSystemContext:buildAppendSystemContext({thirdParty:r,canvasSystemPrompt:`${CANVAS_PRESENTATION_GATE}\n\n${CANVAS_SYSTEM_PROMPT}`,toolRoutingHint:g})}:{appendSystemContext:g}}),e.logger.debug?.("[beeos-claw] Canvas system prompt hook registered: before_prompt_build")}catch{e.logger.debug?.("[beeos-claw] before_prompt_build hook not supported")}try{e.on("before_tool_call",(e,t)=>{if(t?.sessionKey&&p.setPendingToolCallSessionKey(t.sessionKey),!m.has(e.toolName))return;const r=t?.sessionKey?v.get(t.sessionKey):void 0,o=isThirdPartyChannel(n,{sessionKey:t?.sessionKey,channelId:r}),a=canvasToolBlockReason({thirdParty:o,hasSession:Boolean(t?.sessionKey)});return a?{block:!0,blockReason:a}:void 0}),e.logger.debug?.("[beeos-claw] Canvas tool guard registered: before_tool_call")}catch{e.logger.debug?.("[beeos-claw] before_tool_call hook not supported")}}e.logger.info?.("[beeos-claw] Canvas tools registered (render_ui, close_ui, render_form + auto-action tools)")}else e.logger.info?.("[beeos-claw] Canvas disabled by config (canvasEnabled=false)");if(o.bridge.shell.enabled&&!0===o.legacyTerminalWsEnabled){const t=createTerminalWebSocketService({config:{port:o.terminalWsPort,token:agentKeys?Buffer.from(agentKeys.publicKey).toString("base64"):"",allowedOrigins:o.terminalWsAllowedOrigins},terminalMgr:sharedTerminalManager,logger:e.logger,writeObs:a});e.registerService({id:"beeos-terminal-ws",start(){t.start(),e.logger.info?.(`[beeos-claw] Terminal WS started on port ${o.terminalWsPort}`)},stop(){t.stop(),e.logger.info?.("[beeos-claw] Terminal WS stopped")}})}else o.bridge.shell.enabled?e.logger.info?.("[beeos-claw] Legacy static-token Terminal WS disabled (default)"):e.logger.info?.("[beeos-claw] Terminal/shell disabled by config (bridge.shell.enabled=false)");if(t.openclawConfig){const r=mirrorOpenClawConfig(t.openclawConfig);r.copied?e.logger.info?.(`[beeos-claw] mirrored openclaw config to ${r.destinationPath}`):e.logger.debug?.(`[beeos-claw] openclaw config mirror skipped: ${r.reason}`)}}export function pluginCloudRuntimeTarget(e){const t=e.pluginConfig?.cloudRuntimeInstanceId;return cloudRuntimeTargetInstanceId("string"==typeof t?t:claimedSandboxId())}function attachNativeCloudChat(e,t){if(sharedNativeChatService)return e.registerService(sharedNativeChatService),sharedNativeCloudChat;const r=sharedRuntimeAuthority,o=t.messageBus.serviceUrl,a=sharedAcpServer,n=sharedSessionMutationCoordinator;if(!(r&&r.cloudTargetInstanceId&&o&&a&&n))return sharedNativeCloudChat;const i=sharedNativeCloudChat??createNativeCloudChatComposition({authority:nativeCloudChatAuthorityFromRuntimeAuthority(r),serviceUrl:o,logger:e.logger});if(sharedNativeCloudChat=i,!t.messageBus.enabled)return i;const s=i,l=r;let c;const u=new Map,d=new RuntimeAuthorityMessageBusLifecycle({authority:l,logger:e.logger,bus:{connect:async t=>{c?.(),u.clear(),c=s.adapter.listen({eventTypes:["message.created"]},r=>{if(r.type===APPROVAL_DECISION_MESSAGE_TYPE&&r.senderId?.startsWith("user:")&&isApprovalDocument(r.content))return void sharedApprovalBridge.onDecision(r.content);if("user.continue"===r.type&&isQuestionResponseDocument(r.content))return void sharedQuestionBridge.onResponse(r);const o=(r.content??{}).metadata??{},i="string"==typeof o.target_agent_id?o.target_agent_id:"",l=i?((t,r)=>{const o=sharedAgentMappings.snapshot();if(o)for(const[i,l]of o.entries()){if(l.id!==r)continue;if(l.instanceId!==t.instanceId)continue;const o=`${i}\0${l.id}`;let c=u.get(o);return c||(c={localAgentId:i,inbound:createImInboundHandler({runtime:e.runtime,pluginConfig:e.pluginConfig,client:s.adapter,localServer:{getLocalAgentId:()=>i,resolveLocalAgentId:e=>e===l.id?i:void 0,getDefaultPlatformAgent:()=>({instanceId:t.instanceId}),ensureImInboundSession:(e,t,r,o)=>{a.ensureImInboundSession(e,t,r,o)},chatAbort:(e,t)=>a.chatAbort(e,t)},promptRunStore:sharedPromptRunStore,waitIfExclusive:(t,r)=>sharedImHotPathDeferral.waitIfExclusive(t,e.logger,r).then(()=>{}),assistantMessageCommitRouter:sharedAssistantMessageCommitRouter,toolResultObservationRouter:sharedToolResultObservationRouter,approvalStreams:sharedApprovalBridge,questionStreams:sharedQuestionBridge,modelCallObservationRouter:sharedModelCallObservationRouter,sessionMutationCoordinator:n,logger:e.logger,writeObs:sharedWriteObs,principalIdOverride:t.instanceId,activeRunAuthority:a.getActiveRunAuthority(),applyTurnModel:(e,t)=>a.applyImTurnModel(e,t),restoreTurnModel:e=>a.restoreImTurnModel(e),...agentGateway?{completeA2ATask:(t,r,o)=>completeA2ATask({gateway:agentGateway,logger:e.logger},t,r,o)}:{}})},u.set(o,c)),c}})(t,i):void 0;if(!l)return void e.logger.warn?.(`[beeos-claw] native cloud chat dropped unresolvable target_agent_id=${i||"missing"} message_id=${r.id}`);("chat_cancel"===r.type?l.inbound.onChatCancel(r):l.inbound.onChatMessage(r)).catch(t=>{e.logger.error?.(`[beeos-claw] native cloud chat dispatch failed message_id=${r.id}: ${t instanceof Error?t.message:String(t)}`)})});try{await s.adapter.connect()}catch(e){throw c?.(),c=void 0,e}},disconnect:async()=>{c?.(),c=void 0,u.clear(),await s.adapter.disconnect()}}});return sharedNativeChatService={id:"beeos-native-cloud-chat",async start(){d.start()},async stop(){await d.stop()}},e.registerService(sharedNativeChatService),e.logger.info?.("[beeos-claw] native Cloud personal-chat composition registered"),i}const plugin={id:"beeos-claw",name:"beeos-claw",description:"BeeOS platform bridge plugin for OpenClaw. Provides file upload/download, ACP bridge, and observability.",version:PLUGIN_VERSION,register(e){if(_initializing)return;registerCentralNativeContextEngine(e),registerSandboxNativeActivation(e,()=>{if(!sharedSessionMutationCoordinator)throw new Error("native session writer coordinator is unavailable");return sharedSessionMutationCoordinator.activeMutationCount},createSandboxNativeTargetLookup(()=>sharedRuntimeAuthority,()=>sharedGatewayClient,{logger:e.logger}),async()=>{const e=sharedGatewayClient;if(!e)throw new Error("OpenClaw gateway is not connected");await e.waitForConnected(3e4),await e.request("secrets.reload",{})});const t=pluginCloudRuntimeTarget(e),r=void 0!==t&&t!==sharedRuntimeAuthority?.cloudTargetInstanceId,o=planPluginRegistration(e.registrationMode,_fullRuntimeRegistered,r);if("skip"!==o){_initializing=!0;try{if(!hasRuntimeReplyApi(e.runtime))throw e.logger.error?.("[beeos-claw] FATAL: OpenClaw runtime.channel.reply.dispatchReplyFromConfig not exposed. Upgrade OpenClaw or revert beeos-claw."),new Error("openclaw_runtime_reply_api_unavailable");const t=(t,r)=>{registerUploadTools(e,t,r),registerArouterLatencyRouting(e),registerArouterMediaProviders(e)};if("capabilities"===o&&sharedPluginContext){if(cachedCapabilityTools.length>0){const t=resolveCapabilityToolReplay({currentRegisterTool:e.registerTool,wrappedRegisterTool:wrappedRegisterTool,originalRegisterTool:rawRegisterTool}),r=replayCachedPluginTools((r,o)=>t.call(e,r,o),cachedCapabilityTools);return registerArouterLatencyRouting(e),registerArouterMediaProviders(e),void e.logger.info?.(`[beeos-claw] capability re-register mode=${e.registrationMode} tools_only count=${r}`)}const r={current:sharedAcpServer??null};return t(sharedPluginContext,r),registerServices(e,sharedPluginContext,r),void e.logger.info?.(`[beeos-claw] capability re-register mode=${e.registrationMode} capabilities_only`)}const r=initializePlugin(e);if(!r)return;const a={current:null};installUnhandledRejectionObserver(e,r.writeObs,a),ensureRegisterToolCache(e),cacheRuntimeRegistrations(e),cachedCapabilityTools.length=0,t(r,a),agentGateway&&(e.on?e.on("before_agent_finalize",async(e,t)=>{if(await fileDeliveryFinalizeDecision(e),!e.runId||!t?.runId||e.runId===t.runId)return nativeHtmlDeliveryForRun(e.runId??t?.runId)?.beforeFinalize(e)}):e.logger.warn?.("[file-delivery] OpenClaw plugin hooks unavailable; finalization check disabled")),registerServices(e,r,a),sharedPluginContext=r,marksFullRuntimeRegistered(e.registrationMode,o)&&(_fullRuntimeRegistered=!0),_pluginRegisteredAt=Date.now(),e.logger.info?.("[beeos-claw] Plugin registered successfully")}finally{_initializing=!1}}else if(!e.registrationMode||"full"===e.registrationMode){const t=resolveCapabilityToolReplay({currentRegisterTool:e.registerTool,wrappedRegisterTool:wrappedRegisterTool,originalRegisterTool:rawRegisterTool});replayCachedPluginTools((r,o)=>t.call(e,r,o),cachedCapabilityTools),replayRuntimeRegistrations(e),registerArouterLatencyRouting(e),registerArouterMediaProviders(e)}}};export default plugin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RuntimeChatStore,RuntimeLeaseHttp,RuntimeOriginalIntent,RuntimeMemory,createCloudGrantVerifier}from"@beeos-ai/cloud-harness-sdk";import{StateCentralNativeStore}from"./central-native-production.js";import{FileCentralNativePendingJournal}from"./central-native-pending-journal.js";import{installCentralNativeRuntime}from"./central-native-runtime.js";import{createCentralNativeHost}from"./central-native-host.js";import{NativeInputFilesHttpClient}from"./native-input-files-http.js";import{join}from"node:path";import{CentralNativeCredentials}from"./central-native-credentials.js";import{installSandboxNativeExecutionResolver}from"./sandbox-native-activation.js";import{createSandboxNativeExecutionResolver}from"./sandbox-native-execution-resolver.js";import{installCentralNativeMemoryCall}from"./central-native-memory.js";import{DECISION_ROUTE}from"./central-native-interactions.js";import{generateAndRecordSessionTitle,RuntimeLeaseHttpSessionTitles}from"./central-native-titles.js";import{resolveArouterApiKey,resolveArouterBaseUrl}from"../media/arouter-config.js";export function requireCentralNativeSessionHost(e){const t=e,r=t?.agent?.session;for(const e of["readNativeTranscript","pendingNativeTurns","nativeWritersQuiescent","drainNativeTurns","replaceNativeTranscript","compactNativeTranscript"])if("function"!=typeof r?.[e])throw new Error(`pinned OpenClaw central native API unavailable: ${e}`);if("function"!=typeof t?.config?.current)throw new Error("pinned OpenClaw current config API unavailable");return r}export function createCentralNativeComposition(e){const t=()=>e.authority.authorityLease,r=new CentralNativeCredentials({authority:e.authority,http:new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1})}),n=new StateCentralNativeStore(new RuntimeChatStore(new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1})),e=>r.credential(e),new RuntimeLeaseHttpSessionTitles(new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1}))),i=new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1}),a=new FileCentralNativePendingJournal(join(e.stateDirectory,"central-native-pending")),o=new RuntimeMemory(new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1}));installCentralNativeMemoryCall(async(e,t,i,a,s)=>{try{const l=await o.call(t,await r.credential(e),r.execution(e),i,a,s);if("recall"===t){if("string"!=typeof l.read_watermark||!l.read_watermark)throw new Error("native Memory read returned no original watermark");n.recordMemoryRead(e,{status:"read",watermark:l.read_watermark})}return l}catch(r){throw"recall"===t&&n.recordMemoryRead(e,{status:"unavailable",watermark:null}),r}});const s=new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1}),l=(e,t,n,i)=>r.bind(e,t,n,i);return installSandboxNativeExecutionResolver(createSandboxNativeExecutionResolver({authority:e.authority,original:new RuntimeOriginalIntent(new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1})),verifier:createCloudGrantVerifier(e.gatewayOrigin),bindCredential:l})),installCentralNativeRuntime({store:n,pending:a,host:e.host,activeWriters:()=>e.coordinator.activeMutationCount,observe:(e,t)=>n.bindExecutionObservation(e,t)}),{store:n,pending:a,bindCredential:l,recordGeneratedTitle:({binding:t,question:r,answer:i})=>{generateAndRecordSessionTitle({recordGeneratedTitle:(e,t)=>n.recordGeneratedTitle(e,t),binding:t,question:r,answer:i,resolveModelCredential:()=>{const t=e.runtime.config.current(),r=resolveArouterApiKey(t)??process.env.AROUTER_API_KEY??process.env.OPENAI_API_KEY;return r?{apiKey:r,baseUrl:resolveArouterBaseUrl(t)}:void 0},logger:e.logger})},host:createCentralNativeHost({runtime:e.runtime,native:e.host,currentConfig:()=>e.runtime.config.current(),coordinator:e.coordinator,getLease:t,logger:e.logger,publishDelta:async(e,t)=>{const n=await i.postJson("/api/v1/runtime/chat-store/stream",await r.credential(e),{context:e.context,session_id:e.sessionId,history_generation:e.historyGeneration,branch_id:e.branchId,response_id:e.responseId,attempt_id:e.attemptId,writer:e.writer,...t},{retry:!1});if(await(n.body?.cancel()),!n.ok)throw new Error(`central output delta rejected (${n.status})`)},recordPublicEvent:(e,t)=>(n.recordPublicEvent(e,t),n.commitPublicProgress(e,a)),decideInteraction:async(e,t)=>{const n=await s.postJson(DECISION_ROUTE,await r.credential(e),{context:e.context,session_id:e.sessionId,history_generation:e.historyGeneration,branch_id:e.branchId,response_id:e.responseId,interaction_id:t},{retry:!1});if(!n.ok)throw new Error(`central Interaction decision read failed (${n.status})`);const i=await n.json();return i.decision?.reply??null},inputFiles:new NativeInputFilesHttpClient(e.gatewayOrigin,t,(e,t)=>fetch(e,t))})}}
|
|
1
|
+
import{RuntimeChatStore,RuntimeLeaseHttp,RuntimeOriginalIntent,RuntimeMemory,RuntimeOperationFiles,createCloudGrantVerifier}from"@beeos-ai/cloud-harness-sdk";import{StateCentralNativeStore}from"./central-native-production.js";import{FileCentralNativePendingJournal}from"./central-native-pending-journal.js";import{installCentralNativeRuntime}from"./central-native-runtime.js";import{createCentralNativeHost}from"./central-native-host.js";import{NativeInputFilesHttpClient}from"./native-input-files-http.js";import{join}from"node:path";import{CentralNativeCredentials}from"./central-native-credentials.js";import{centralNativeOutputFileResolver}from"./central-native-output-files.js";import{installSandboxNativeExecutionResolver}from"./sandbox-native-activation.js";import{createSandboxNativeExecutionResolver}from"./sandbox-native-execution-resolver.js";import{installCentralNativeMemoryCall}from"./central-native-memory.js";import{DECISION_ROUTE}from"./central-native-interactions.js";import{generateAndRecordSessionTitle,RuntimeLeaseHttpSessionTitles}from"./central-native-titles.js";import{resolveArouterApiKey,resolveArouterBaseUrl}from"../media/arouter-config.js";export function requireCentralNativeSessionHost(e){const t=e,r=t?.agent?.session;for(const e of["readNativeTranscript","pendingNativeTurns","nativeWritersQuiescent","drainNativeTurns","replaceNativeTranscript","compactNativeTranscript"])if("function"!=typeof r?.[e])throw new Error(`pinned OpenClaw central native API unavailable: ${e}`);if("function"!=typeof t?.config?.current)throw new Error("pinned OpenClaw current config API unavailable");return r}export function createCentralNativeComposition(e){const t=()=>e.authority.authorityLease,r=new CentralNativeCredentials({authority:e.authority,http:new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1})}),n=new StateCentralNativeStore(new RuntimeChatStore(new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1})),e=>r.credential(e),new RuntimeLeaseHttpSessionTitles(new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1})),centralNativeOutputFileResolver(new RuntimeOperationFiles(new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1})),r)),i=new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1}),a=new FileCentralNativePendingJournal(join(e.stateDirectory,"central-native-pending")),o=new RuntimeMemory(new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1}));installCentralNativeMemoryCall(async(e,t,i,a,s)=>{try{const l=await o.call(t,await r.credential(e),r.execution(e),i,a,s);if("recall"===t){if("string"!=typeof l.read_watermark||!l.read_watermark)throw new Error("native Memory read returned no original watermark");n.recordMemoryRead(e,{status:"read",watermark:l.read_watermark})}return l}catch(r){throw"recall"===t&&n.recordMemoryRead(e,{status:"unavailable",watermark:null}),r}});const s=new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1}),l=(e,t,n,i)=>r.bind(e,t,n,i);return installSandboxNativeExecutionResolver(createSandboxNativeExecutionResolver({authority:e.authority,original:new RuntimeOriginalIntent(new RuntimeLeaseHttp({origin:e.gatewayOrigin,retry:!1})),verifier:createCloudGrantVerifier(e.gatewayOrigin),bindCredential:l})),installCentralNativeRuntime({store:n,pending:a,host:e.host,activeWriters:()=>e.coordinator.activeMutationCount,observe:(e,t)=>n.bindExecutionObservation(e,t)}),{store:n,pending:a,bindCredential:l,recordGeneratedTitle:({binding:t,question:r,answer:i})=>{generateAndRecordSessionTitle({recordGeneratedTitle:(e,t)=>n.recordGeneratedTitle(e,t),binding:t,question:r,answer:i,resolveModelCredential:()=>{const t=e.runtime.config.current(),r=resolveArouterApiKey(t)??process.env.AROUTER_API_KEY??process.env.OPENAI_API_KEY;return r?{apiKey:r,baseUrl:resolveArouterBaseUrl(t)}:void 0},logger:e.logger})},host:createCentralNativeHost({runtime:e.runtime,native:e.host,currentConfig:()=>e.runtime.config.current(),coordinator:e.coordinator,getLease:t,logger:e.logger,publishDelta:async(e,t)=>{const n=await i.postJson("/api/v1/runtime/chat-store/stream",await r.credential(e),{context:e.context,session_id:e.sessionId,history_generation:e.historyGeneration,branch_id:e.branchId,response_id:e.responseId,attempt_id:e.attemptId,writer:e.writer,...t},{retry:!1});if(await(n.body?.cancel()),!n.ok)throw new Error(`central output delta rejected (${n.status})`)},recordPublicEvent:(e,t)=>(n.recordPublicEvent(e,t),n.commitPublicProgress(e,a)),decideInteraction:async(e,t)=>{const n=await s.postJson(DECISION_ROUTE,await r.credential(e),{context:e.context,session_id:e.sessionId,history_generation:e.historyGeneration,branch_id:e.branchId,response_id:e.responseId,interaction_id:t},{retry:!1});if(!n.ok)throw new Error(`central Interaction decision read failed (${n.status})`);const i=await n.json();return i.decision?.reply??null},inputFiles:new NativeInputFilesHttpClient(e.gatewayOrigin,t,(e,t)=>fetch(e,t))})}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash}from"node:crypto";import{isDeepStrictEqual}from"node:util";export const CENTRAL_NATIVE_ENGINE_ID="beeos-central-chat";export const OPENCLAW_NATIVE_CODEC="openclaw-session-events-v1";export function nativePayloadDigest(e){const t=e=>Array.isArray(e)?e.map(t):null!==e&&"object"==typeof e?Object.fromEntries(Object.entries(e).sort(([e],[t])=>e<t?-1:e>t?1:0).map(([e,n])=>[e,t(n)])):e;return createHash("sha256").update(JSON.stringify(t(e))).digest("hex")}export function nativeBindingDigest(e){const{context:t,...n}=e;return nativePayloadDigest({...n,tenant_ref:t.tenant_ref,scope_ref:t.scope_ref})}export function assertCentralNativeReceipt(e,t){const n=e.wire,i=n.events;if(!Array.isArray(i)||i.some(e=>!e||"object"!=typeof e||"string"!=typeof e.event_id))throw new Error("central native append has invalid prepared State event identities");if(!(t.receipt_id&&t.idempotency_key===e.idempotencyKey&&t.payload_sha256===e.payloadDigest&&t.read_watermark&&t.operation_id===e.binding.operationId&&t.session_id===e.binding.sessionId&&t.history_generation===e.binding.historyGeneration&&t.branch_id===e.binding.branchId&&isDeepStrictEqual(t.writer,e.binding.writer)&&t.previous_watermark===e.expectedWatermark&&isDeepStrictEqual(t.terminal,n.terminal)&&isDeepStrictEqual(t.event_ids,i.map(e=>e.event_id))&&/^(0|[1-9][0-9]*)$/.test(t.read_watermark)&&t.read_watermark===String(BigInt(e.expectedWatermark)+BigInt(i.length))))throw new Error("central native append returned no matching durable transaction receipt")}export class CentralNativeContextEngine{options;info={id:"beeos-central-chat",name:"BeeOS central native chat",version:"1",failureMode:"strict",acceptedHostParams:["sessionKey","sessionTarget","runtimeContext","runtimeSettings","prompt"],transcriptSemantics:{currentTurnFence:"before-current-turn-entry-v1",turnAdvancementIdempotency:"atomic-idempotent-v1",nativeEvents:"lossless-v1"}};terminalOperations=new Set;loaded=new Map;constructor(e){this.options=e}source(e){const t=this.loaded.get(e);if(!t)throw new Error("central native session has no loaded source");return structuredClone(t)}forBindings(e){const t=new CentralNativeContextEngine({...this.options,resolveBinding:e});for(const[e,n]of this.loaded)t.loaded.set(e,structuredClone(n));for(const e of this.terminalOperations)t.terminalOperations.add(e);return t}binding(e){if(!e)throw new Error("central native session key is required");return this.options.resolveBinding(e)}async hydrateNativeSession(e){const t=this.binding(e.sessionKey);for(const e of await this.options.pending.list(t.sessionId)){const n=await this.options.store.receipt({...e,binding:{...e.binding,context:t.context}});if(!n)throw new Error("central native append outcome is unknown");this.acceptReceipt(e,n),await this.options.pending.complete(e,n)}const n=await this.options.store.load(t);if(n.codec!==OPENCLAW_NATIVE_CODEC||!Array.isArray(n.events)||!isDeepStrictEqual(n.writer,t.writer)||!n.watermark)throw new Error("central native load does not match the authorized codec/fence");return n.terminal?.response_id===t.responseId&&this.terminalOperations.add(t.operationId),this.loaded.set(e.sessionKey,structuredClone(n)),{events:structuredClone(n.events)}}async bootstrap(){return{bootstrapped:!0}}async ingest(){throw new Error("central native writes require an atomic native turn commit")}async assemble(e){if(this.binding(e.sessionKey),!e.sessionKey||!this.loaded.has(e.sessionKey))throw new Error("central native context was not hydrated by the pinned host");return{messages:e.messages,estimatedTokens:0}}async admitTurn(e){const{admission:t}=e,n=this.binding(t.sessionKey);if(this.terminalOperations.has(n.operationId))throw new Error("original Response is already terminal; new native admission is forbidden");const i=await this.options.readNativeEvents(t.sessionKey);if(!Number.isSafeInteger(t.rawSeq)||t.rawSeq<0||t.rawSeq>=i.length)throw new Error("native admission has no exact transcript row");await this.commitSnapshot(t.sessionKey,n,`admit:${n.operationId}:${t.logicalTurnId}`,i.slice(0,t.rawSeq+1),t)}nativeTranscriptBase(e){const t=this.source(e.sessionKey);return{eventCount:t.events.length,snapshotDigest:nativePayloadDigest(t.events),bindingDigest:nativeBindingDigest(this.binding(e.sessionKey))}}async commitTurn(e){const t=this.binding(e.sessionKey);if(!e.nativeEvents)throw new Error("pinned host omitted native transcript events");const n=e.nativeBase;if(n?.bindingDigest!==nativeBindingDigest(t))throw new Error("native accepted-turn binding changed");const i=0===n?.eventCount?[]:this.source(e.sessionKey).events;if(!n||!Number.isSafeInteger(n.eventCount)||n.eventCount<0||n.eventCount>i.length||nativePayloadDigest(i.slice(0,n.eventCount))!==n.snapshotDigest)throw new Error("native accepted-turn base differs from the exact central prefix");const a=[...i.slice(0,n.eventCount),...e.nativeEvents];if(!e.nativeOutcome)throw new Error("pinned host omitted actual native terminal outcome");return this.commitSnapshot(e.sessionKey,t,e.advancementKey,a,e.terminal,e.nativeOutcome)}async finalizeNativeOutcome(e){const t=this.binding(e.sessionKey),n=await this.options.readNativeEvents(e.sessionKey);await this.commitSnapshot(e.sessionKey,t,`outcome:${t.operationId}:${nativePayloadDigest(e.nativeOutcome)}`,n,e.terminal,e.nativeOutcome)}async commitSnapshot(e,t,n,i,a,r){return this.options.store.withWrite(t,()=>this.commitSnapshotUnserialized(e,t,n,i,a,r))}async commitSnapshotUnserialized(e,t,n,i,a,r){const s=await this.options.pending.completed(n);if(s){const{context:e,...o}=s.binding,{context:c,...d}=t;if(!isDeepStrictEqual(o,d)||e.tenant_ref!==c.tenant_ref||e.scope_ref!==c.scope_ref)throw new Error("central native duplicate binding changed");if(s.nativeSnapshotDigest!==nativePayloadDigest({events:i,nativeTerminalAnchor:a??null,nativeOutcome:r??null}))throw new Error("central native duplicate turn has different native events");const p=await this.options.store.receipt({binding:{...s.binding,context:t.context},idempotencyKey:n,payloadDigest:s.receipt.payload_sha256});if(!p||!isDeepStrictEqual(p,s.receipt))throw new Error("central native duplicate receipt is unavailable or changed");return p.terminal&&this.terminalOperations.add(s.binding.operationId),this.options.onReceipt?.(s.binding,p),{status:"duplicate"}}const o=await this.options.pending.get(n);if(o){const{context:e,...n}=o.binding,{context:s,...c}=t;if(!isDeepStrictEqual(n,c)||e.tenant_ref!==s.tenant_ref||e.scope_ref!==s.scope_ref||o.nativeSnapshotDigest!==nativePayloadDigest({events:i,nativeTerminalAnchor:a??null,nativeOutcome:r??null}))throw new Error("central native idempotency conflict: pending advancement changed");const d=await this.options.store.receipt({...o,binding:t});if(!d)throw new Error("central native append outcome is unknown");return this.acceptReceipt(o,d),await this.options.pending.complete(o,d),{status:"duplicate"}}if(!this.loaded.has(e))throw new Error("central native commit has no exact loaded source");const c=await this.options.store.load(t);if(c.codec!==OPENCLAW_NATIVE_CODEC||!isDeepStrictEqual(c.writer,t.writer))throw new Error("central native refreshed source changed its codec/writer");if(c.terminal?.response_id===t.responseId&&this.terminalOperations.add(t.operationId),this.loaded.set(e,structuredClone(c)),this.terminalOperations.has(t.operationId))throw new Error("original Response is already terminal; new native advancement is forbidden");if(i.length<c.events.length||!isDeepStrictEqual(i.slice(0,c.events.length),c.events))throw new Error("native cache diverged from the exact central transcript prefix");const d=nativePayloadDigest({events:i,nativeTerminalAnchor:a??null,nativeOutcome:r??null});let p=c;if(i.length===p.events.length&&!r)throw new Error("native advancement contains no new native events");let l=!1;for(;p.events.length<i.length||r&&!l;){const s=p.events.length,o=i.length-s,c=this.options.store.nativeEventCapacity(t,!1),h=this.options.store.nativeEventCapacity(t,Boolean(r)),m=r&&o>h?s+Math.min(c,o-1):Math.min(s+h,i.length),v=m===i.length?n:`${n}:native:${s}`,u={binding:t,expectedWatermark:p.watermark,idempotencyKey:v,nativeSnapshotDigest:d,events:i.slice(s,m),...a?{nativeTerminalAnchor:a}:{},...r&&m===i.length?{nativeOutcome:r}:{}},g=await this.options.pending.get(v),w=g??this.options.store.prepareAppend(u),{context:f,...y}=w.binding,{context:E,...b}=t;if(w.idempotencyKey!==v||w.nativeSnapshotDigest!==u.nativeSnapshotDigest||w.expectedWatermark!==p.watermark||!isDeepStrictEqual(y,b)||f.tenant_ref!==E.tenant_ref||f.scope_ref!==E.scope_ref||!isDeepStrictEqual(w.events,u.events)||!isDeepStrictEqual(w.nativeOutcome,u.nativeOutcome))throw new Error("central native SDK changed the prepared native append identity");let _;if(g){const e=await this.options.store.receipt({...g,binding:t});if(!e)throw new Error("central native append outcome is unknown");_=e}else await this.options.pending.put(w),_=await this.options.store.append(w);this.acceptReceipt(w,_),p={...p,events:structuredClone(i.slice(0,m)),watermark:_.read_watermark},this.loaded.set(e,p),await this.options.pending.complete(w,_),l=Boolean(r&&m===i.length)}return{status:"committed"}}acceptReceipt(e,t){assertCentralNativeReceipt(e,t),t.terminal&&this.terminalOperations.add(e.binding.operationId),this.options.onReceipt?.(e.binding,t)}async compact(e){const t="string"==typeof e.sessionKey?e.sessionKey:void 0,n=this.binding(t);if(this.terminalOperations.has(n.operationId))return{ok:!0,compacted:!1,reason:"central terminal already committed; compaction requires another admitted operation"};const i=await this.options.compact(e);if(i.ok&&i.compacted){const e=await this.options.readNativeEvents(t);await this.commitSnapshot(t,n,`compact:${n.operationId}:${nativePayloadDigest(e)}`,e)}return i}}
|
|
1
|
+
import{createHash}from"node:crypto";import{isDeepStrictEqual}from"node:util";export const CENTRAL_NATIVE_ENGINE_ID="beeos-central-chat";export const OPENCLAW_NATIVE_CODEC="openclaw-session-events-v1";export function nativePayloadDigest(e){const t=e=>Array.isArray(e)?e.map(t):null!==e&&"object"==typeof e?Object.fromEntries(Object.entries(e).sort(([e],[t])=>e<t?-1:e>t?1:0).map(([e,n])=>[e,t(n)])):e;return createHash("sha256").update(JSON.stringify(t(e))).digest("hex")}export function nativeBindingDigest(e){const{context:t,...n}=e;return nativePayloadDigest({...n,tenant_ref:t.tenant_ref,scope_ref:t.scope_ref})}export function assertCentralNativeReceipt(e,t){const n=e.wire,i=n.events;if(!Array.isArray(i)||i.some(e=>!e||"object"!=typeof e||"string"!=typeof e.event_id))throw new Error("central native append has invalid prepared State event identities");if(!(t.receipt_id&&t.idempotency_key===e.idempotencyKey&&t.payload_sha256===e.payloadDigest&&t.read_watermark&&t.operation_id===e.binding.operationId&&t.session_id===e.binding.sessionId&&t.history_generation===e.binding.historyGeneration&&t.branch_id===e.binding.branchId&&isDeepStrictEqual(t.writer,e.binding.writer)&&t.previous_watermark===e.expectedWatermark&&isDeepStrictEqual(t.terminal,n.terminal)&&isDeepStrictEqual(t.event_ids,i.map(e=>e.event_id))&&/^(0|[1-9][0-9]*)$/.test(t.read_watermark)&&t.read_watermark===String(BigInt(e.expectedWatermark)+BigInt(i.length))))throw new Error("central native append returned no matching durable transaction receipt")}export class CentralNativeContextEngine{options;info={id:"beeos-central-chat",name:"BeeOS central native chat",version:"1",failureMode:"strict",acceptedHostParams:["sessionKey","sessionTarget","runtimeContext","runtimeSettings","prompt"],transcriptSemantics:{currentTurnFence:"before-current-turn-entry-v1",turnAdvancementIdempotency:"atomic-idempotent-v1",nativeEvents:"lossless-v1"}};terminalOperations=new Set;loaded=new Map;constructor(e){this.options=e}source(e){const t=this.loaded.get(e);if(!t)throw new Error("central native session has no loaded source");return structuredClone(t)}forBindings(e){const t=new CentralNativeContextEngine({...this.options,resolveBinding:e});for(const[e,n]of this.loaded)t.loaded.set(e,structuredClone(n));for(const e of this.terminalOperations)t.terminalOperations.add(e);return t}binding(e){if(!e)throw new Error("central native session key is required");return this.options.resolveBinding(e)}async hydrateNativeSession(e){const t=this.binding(e.sessionKey);for(const e of await this.options.pending.list(t.sessionId)){const n=await this.options.store.receipt({...e,binding:{...e.binding,context:t.context}});if(!n)throw new Error("central native append outcome is unknown");this.acceptReceipt(e,n),await this.options.pending.complete(e,n)}const n=await this.options.store.load(t);if(n.codec!==OPENCLAW_NATIVE_CODEC||!Array.isArray(n.events)||!isDeepStrictEqual(n.writer,t.writer)||!n.watermark)throw new Error("central native load does not match the authorized codec/fence");return n.terminal?.response_id===t.responseId&&this.terminalOperations.add(t.operationId),this.loaded.set(e.sessionKey,structuredClone(n)),{events:structuredClone(n.events)}}async bootstrap(){return{bootstrapped:!0}}async ingest(){throw new Error("central native writes require an atomic native turn commit")}async assemble(e){if(this.binding(e.sessionKey),!e.sessionKey||!this.loaded.has(e.sessionKey))throw new Error("central native context was not hydrated by the pinned host");return{messages:e.messages,estimatedTokens:0}}async admitTurn(e){const{admission:t}=e,n=this.binding(t.sessionKey);if(this.terminalOperations.has(n.operationId))throw new Error("original Response is already terminal; new native admission is forbidden");const i=await this.options.readNativeEvents(t.sessionKey);if(!Number.isSafeInteger(t.rawSeq)||t.rawSeq<0||t.rawSeq>=i.length)throw new Error("native admission has no exact transcript row");await this.commitSnapshot(t.sessionKey,n,`admit:${n.operationId}:${t.logicalTurnId}`,i.slice(0,t.rawSeq+1),t)}nativeTranscriptBase(e){const t=this.source(e.sessionKey);return{eventCount:t.events.length,snapshotDigest:nativePayloadDigest(t.events),bindingDigest:nativeBindingDigest(this.binding(e.sessionKey))}}async commitTurn(e){const t=this.binding(e.sessionKey);if(!e.nativeEvents)throw new Error("pinned host omitted native transcript events");const n=e.nativeBase;if(n?.bindingDigest!==nativeBindingDigest(t))throw new Error("native accepted-turn binding changed");const i=0===n?.eventCount?[]:this.source(e.sessionKey).events;if(!n||!Number.isSafeInteger(n.eventCount)||n.eventCount<0||n.eventCount>i.length||nativePayloadDigest(i.slice(0,n.eventCount))!==n.snapshotDigest)throw new Error("native accepted-turn base differs from the exact central prefix");const a=[...i.slice(0,n.eventCount),...e.nativeEvents];if(!e.nativeOutcome)throw new Error("pinned host omitted actual native terminal outcome");return this.commitSnapshot(e.sessionKey,t,e.advancementKey,a,e.terminal,e.nativeOutcome)}async finalizeNativeOutcome(e){const t=this.binding(e.sessionKey),n=await this.options.readNativeEvents(e.sessionKey);await this.commitSnapshot(e.sessionKey,t,`outcome:${t.operationId}:${nativePayloadDigest(e.nativeOutcome)}`,n,e.terminal,e.nativeOutcome)}async commitSnapshot(e,t,n,i,a,r){return this.options.store.withWrite(t,()=>this.commitSnapshotUnserialized(e,t,n,i,a,r))}async commitSnapshotUnserialized(e,t,n,i,a,r){const s=await this.options.pending.completed(n);if(s){const{context:e,...o}=s.binding,{context:c,...d}=t;if(!isDeepStrictEqual(o,d)||e.tenant_ref!==c.tenant_ref||e.scope_ref!==c.scope_ref)throw new Error("central native duplicate binding changed");if(s.nativeSnapshotDigest!==nativePayloadDigest({events:i,nativeTerminalAnchor:a??null,nativeOutcome:r??null}))throw new Error("central native duplicate turn has different native events");const p=await this.options.store.receipt({binding:{...s.binding,context:t.context},idempotencyKey:n,payloadDigest:s.receipt.payload_sha256});if(!p||!isDeepStrictEqual(p,s.receipt))throw new Error("central native duplicate receipt is unavailable or changed");return p.terminal&&this.terminalOperations.add(s.binding.operationId),this.options.onReceipt?.(s.binding,p),{status:"duplicate"}}const o=await this.options.pending.get(n);if(o){const{context:e,...n}=o.binding,{context:s,...c}=t;if(!isDeepStrictEqual(n,c)||e.tenant_ref!==s.tenant_ref||e.scope_ref!==s.scope_ref||o.nativeSnapshotDigest!==nativePayloadDigest({events:i,nativeTerminalAnchor:a??null,nativeOutcome:r??null}))throw new Error("central native idempotency conflict: pending advancement changed");const d=await this.options.store.receipt({...o,binding:t});if(!d)throw new Error("central native append outcome is unknown");return this.acceptReceipt(o,d),await this.options.pending.complete(o,d),{status:"duplicate"}}if(!this.loaded.has(e))throw new Error("central native commit has no exact loaded source");const c=await this.options.store.load(t);if(c.codec!==OPENCLAW_NATIVE_CODEC||!isDeepStrictEqual(c.writer,t.writer))throw new Error("central native refreshed source changed its codec/writer");if(c.terminal?.response_id===t.responseId&&this.terminalOperations.add(t.operationId),this.loaded.set(e,structuredClone(c)),this.terminalOperations.has(t.operationId))throw new Error("original Response is already terminal; new native advancement is forbidden");if(i.length<c.events.length||!isDeepStrictEqual(i.slice(0,c.events.length),c.events))throw new Error("native cache diverged from the exact central transcript prefix");const d=nativePayloadDigest({events:i,nativeTerminalAnchor:a??null,nativeOutcome:r??null});let p=c;if(i.length===p.events.length&&!r)throw new Error("native advancement contains no new native events");let l=!1;for(;p.events.length<i.length||r&&!l;){const s=p.events.length,o=i.length-s,c=this.options.store.nativeEventCapacity(t,!1),h=this.options.store.nativeEventCapacity(t,Boolean(r)),m=r&&o>h?s+Math.min(c,o-1):Math.min(s+h,i.length),v=m===i.length?n:`${n}:native:${s}`,u={binding:t,expectedWatermark:p.watermark,idempotencyKey:v,nativeSnapshotDigest:d,events:i.slice(s,m),...a?{nativeTerminalAnchor:a}:{},...r&&m===i.length?{nativeOutcome:r}:{}},g=await this.options.pending.get(v),w=g??await this.options.store.prepareAppend(u),{context:f,...y}=w.binding,{context:E,...b}=t;if(w.idempotencyKey!==v||w.nativeSnapshotDigest!==u.nativeSnapshotDigest||w.expectedWatermark!==p.watermark||!isDeepStrictEqual(y,b)||f.tenant_ref!==E.tenant_ref||f.scope_ref!==E.scope_ref||!isDeepStrictEqual(w.events,u.events)||!isDeepStrictEqual(w.nativeOutcome,u.nativeOutcome))throw new Error("central native SDK changed the prepared native append identity");let _;if(g){const e=await this.options.store.receipt({...g,binding:t});if(!e)throw new Error("central native append outcome is unknown");_=e}else await this.options.pending.put(w),_=await this.options.store.append(w);this.acceptReceipt(w,_),p={...p,events:structuredClone(i.slice(0,m)),watermark:_.read_watermark},this.loaded.set(e,p),await this.options.pending.complete(w,_),l=Boolean(r&&m===i.length)}return{status:"committed"}}acceptReceipt(e,t){assertCentralNativeReceipt(e,t),t.terminal&&this.terminalOperations.add(e.binding.operationId),this.options.onReceipt?.(e.binding,t)}async compact(e){const t="string"==typeof e.sessionKey?e.sessionKey:void 0,n=this.binding(t);if(this.terminalOperations.has(n.operationId))return{ok:!0,compacted:!1,reason:"central terminal already committed; compaction requires another admitted operation"};const i=await this.options.compact(e);if(i.ok&&i.compacted){const e=await this.options.readNativeEvents(t);await this.commitSnapshot(t,n,`compact:${n.operationId}:${nativePayloadDigest(e)}`,e)}return i}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RuntimeOriginalIntent}from"@beeos-ai/cloud-harness-sdk";import{nativeBindingDigest}from"./central-native-context-engine.js";import{verifyCentralNativeIntent}from"./central-native-response.js";export class CentralNativeCredentials{options;sources=new Map;original;constructor(e){this.options=e,this.original=new RuntimeOriginalIntent(e.http)}bind(e,t,i,n){const r=nativeBindingDigest(e),a=this.sources.get(e.operationId),s=n.verifier.verifyAndDecodeGrant(t),o=this.options.authority.authorityLease,d=s?.claims;if(!t||!i||!n.requestMessageId||!s||!o||d?.instanceId!==o.instanceId||d.leaseId!==o.leaseId||d.handlerIdentity!==o.handlerIdentity||d.dispatchEpoch!==o.runtimeEpoch||!Number.isSafeInteger(s.claims.exp)||"string"!=typeof s.claims.runtimeAgentUid||!s.claims.runtimeAgentUid||s.claims.requestHash!==i||s.claims.requestMessageId!==n.requestMessageId||a&&(a.identity!==r||a.hash!==i||a.requestMessageId!==n.requestMessageId||a.runtimeAgentUid!==s.claims.runtimeAgentUid))throw new Error("original central native execution grant changed");this.sources.set(e.operationId,{identity:r,grant:t,hash:i,requestMessageId:n.requestMessageId,expiresAt:1e3*s.claims.exp,runtimeAgentUid:s.claims.runtimeAgentUid,leaseId:o.leaseId,instanceId:o.instanceId,handlerIdentity:o.handlerIdentity,runtimeEpoch:o.runtimeEpoch,verifier:n.verifier})}execution(e){const{source:t}=this.current(e);return{operation_id:e.operationId,request_message_id:t.requestMessageId,native_request_hash:t.hash,attempt_id:e.attemptId}}current(e){const t=this.sources.get(e.operationId),i=this.options.authority.authorityLease;if(!i?.runtimeLeaseCredential||!Number.isFinite(Date.parse(i.leaseExpiresAt))||Date.parse(i.leaseExpiresAt)<=Date.now()||!t||t.identity!==nativeBindingDigest(e)||t.instanceId!==i.instanceId||t.leaseId!==i.leaseId||t.handlerIdentity!==i.handlerIdentity||t.runtimeEpoch!==i.runtimeEpoch)throw new Error("central native current lease/original execution grant is unavailable");return{lease:i,source:t}}async credential(e){const{lease:t,source:i}=this.current(e);i.expiresAt<=Date.now()+5e3&&(i.refreshing??=(async()=>{const n=await this.original.read(t,{operation_id:e.operationId,request_message_id:i.requestMessageId,native_request_hash:i.hash});await i.verifier.refresh();const r=verifyCentralNativeIntent({request:n.request,executionGrant:n.execution_grant,lease:t,getLease:()=>this.options.authority.authorityLease,verifier:i.verifier});if(nativeBindingDigest(r.binding)!==i.identity||n.native_request_hash!==i.hash)throw new Error("renewed original native binding changed");const a=i.verifier.verifyAndDecodeGrant(n.execution_grant);if(a.claims.runtimeAgentUid!==i.runtimeAgentUid)throw new Error("renewed original native target changed");if(1e3*a.claims.exp!==Date.parse(n.execution_grant_expires_at))throw new Error("renewed native grant expiry differs from its signed source");i.grant=n.execution_grant,i.expiresAt=1e3*a.claims.exp})().finally(()=>{i.refreshing=void 0}),await i.refreshing);const n=this.options.authority.authorityLease;if(!n||n.instanceId!==t.instanceId||n.leaseId!==t.leaseId||n.handlerIdentity!==t.handlerIdentity||n.runtimeEpoch!==t.runtimeEpoch||Date.parse(n.leaseExpiresAt)<=Date.now())throw new Error("central native execution is fenced");return{runtimeLeaseCredential:n.runtimeLeaseCredential,executionGrant:i.grant}}}
|
|
1
|
+
import{RuntimeOriginalIntent}from"@beeos-ai/cloud-harness-sdk";import{nativeBindingDigest}from"./central-native-context-engine.js";import{verifyCentralNativeIntent}from"./central-native-response.js";export class CentralNativeCredentials{options;sources=new Map;original;constructor(e){this.options=e,this.original=new RuntimeOriginalIntent(e.http)}bind(e,t,i,n){const r=nativeBindingDigest(e),a=this.sources.get(e.operationId),s=n.verifier.verifyAndDecodeGrant(t),o=this.options.authority.authorityLease,d=s?.claims,c=d?.paramsHash;if(!t||!i||!n.requestMessageId||!s||!o||d?.operationId!==e.operationId||"string"!=typeof c||!/^[0-9a-f]{64}$/.test(c)||d?.instanceId!==o.instanceId||d.leaseId!==o.leaseId||d.handlerIdentity!==o.handlerIdentity||d.dispatchEpoch!==o.runtimeEpoch||!Number.isSafeInteger(s.claims.exp)||"string"!=typeof s.claims.runtimeAgentUid||!s.claims.runtimeAgentUid||s.claims.requestHash!==i||s.claims.requestMessageId!==n.requestMessageId||a&&(a.identity!==r||a.hash!==i||a.paramsHash!==c||a.requestMessageId!==n.requestMessageId||a.runtimeAgentUid!==s.claims.runtimeAgentUid))throw new Error("original central native execution grant changed");this.sources.set(e.operationId,{identity:r,grant:t,hash:i,paramsHash:c,requestMessageId:n.requestMessageId,expiresAt:1e3*s.claims.exp,runtimeAgentUid:s.claims.runtimeAgentUid,leaseId:o.leaseId,instanceId:o.instanceId,handlerIdentity:o.handlerIdentity,runtimeEpoch:o.runtimeEpoch,verifier:n.verifier})}execution(e){const{source:t}=this.current(e);return{operation_id:e.operationId,request_message_id:t.requestMessageId,native_request_hash:t.hash,attempt_id:e.attemptId}}outputFileBinding(e){const{source:t}=this.current(e);return{requestMessageId:t.requestMessageId,paramsHash:t.paramsHash,activeRunRegistrationId:e.operationId}}current(e){const t=this.sources.get(e.operationId),i=this.options.authority.authorityLease;if(!i?.runtimeLeaseCredential||!Number.isFinite(Date.parse(i.leaseExpiresAt))||Date.parse(i.leaseExpiresAt)<=Date.now()||!t||t.identity!==nativeBindingDigest(e)||t.instanceId!==i.instanceId||t.leaseId!==i.leaseId||t.handlerIdentity!==i.handlerIdentity||t.runtimeEpoch!==i.runtimeEpoch)throw new Error("central native current lease/original execution grant is unavailable");return{lease:i,source:t}}async credential(e){const{lease:t,source:i}=this.current(e);i.expiresAt<=Date.now()+5e3&&(i.refreshing??=(async()=>{const n=await this.original.read(t,{operation_id:e.operationId,request_message_id:i.requestMessageId,native_request_hash:i.hash});await i.verifier.refresh();const r=verifyCentralNativeIntent({request:n.request,executionGrant:n.execution_grant,lease:t,getLease:()=>this.options.authority.authorityLease,verifier:i.verifier});if(nativeBindingDigest(r.binding)!==i.identity||n.native_request_hash!==i.hash)throw new Error("renewed original native binding changed");const a=i.verifier.verifyAndDecodeGrant(n.execution_grant);if(a.claims.runtimeAgentUid!==i.runtimeAgentUid)throw new Error("renewed original native target changed");if(a.claims.paramsHash!==i.paramsHash)throw new Error("renewed original native params changed");if(1e3*a.claims.exp!==Date.parse(n.execution_grant_expires_at))throw new Error("renewed native grant expiry differs from its signed source");i.grant=n.execution_grant,i.expiresAt=1e3*a.claims.exp})().finally(()=>{i.refreshing=void 0}),await i.refreshing);const n=this.options.authority.authorityLease;if(!n||n.instanceId!==t.instanceId||n.leaseId!==t.leaseId||n.handlerIdentity!==t.handlerIdentity||n.runtimeEpoch!==t.runtimeEpoch||Date.parse(n.leaseExpiresAt)<=Date.now())throw new Error("central native execution is fenced");return{runtimeLeaseCredential:n.runtimeLeaseCredential,executionGrant:i.grant}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RUNTIME_HASH_DOMAINS}from"@beeos-ai/beeos-types/runtime";import{centralNativeRuntime}from"./central-native-runtime.js";import{createCentralNativeMemoryAttempt}from"./central-native-memory.js";import{preparedSandboxNativeExecution}from"./sandbox-native-activation.js";import{dispatchRuntimeReplyWithRoute}from"./reply-router.js";import{prepareNativePromptInput}from"./native-prompt-preflight.js";import{downloadNativeInputFile}from"./native-input-files.js";import{runtimeMessageHash}from"./runtime-message-channel-contract.js";import{createCentralNativeDeltaStream}from"./central-native-delta.js";import{bindCentralInteractions}from"./central-native-interactions.js";export function createCentralNativeHost(e){return{async run(t){t.assertCurrent(),t.signal.throwIfAborted();const n=preparedSandboxNativeExecution(t.params,t.binding),r=t.params.runtimeRunId;if("string"!=typeof r||!r)throw new Error("original native RunID is unavailable");const
|
|
1
|
+
import{RUNTIME_HASH_DOMAINS}from"@beeos-ai/beeos-types/runtime";import{centralNativeRuntime}from"./central-native-runtime.js";import{createCentralNativeMemoryAttempt}from"./central-native-memory.js";import{createNativeOutputFileAttempt,registerNativeOutputRunContext}from"./native-output-file-attempt.js";import{preparedSandboxNativeExecution}from"./sandbox-native-activation.js";import{dispatchRuntimeReplyWithRoute}from"./reply-router.js";import{prepareNativePromptInput}from"./native-prompt-preflight.js";import{downloadNativeInputFile}from"./native-input-files.js";import{runtimeMessageHash}from"./runtime-message-channel-contract.js";import{createCentralNativeDeltaStream}from"./central-native-delta.js";import{bindCentralInteractions}from"./central-native-interactions.js";export function createCentralNativeHost(e){return{async run(t){t.assertCurrent(),t.signal.throwIfAborted();const n=preparedSandboxNativeExecution(t.params,t.binding),r=t.params.runtimeRunId;if("string"!=typeof r||!r)throw new Error("original native RunID is unavailable");const i=e.coordinator.tryStartExclusive({sessionKey:n.sessionKey,label:t.binding.operationId},"message_service");if(!i.ok)throw new Error("central native physical session is busy");const a=i.token;let s=!1;const o=new AbortController,l=AbortSignal.any([t.signal,o.signal]),p=createCentralNativeMemoryAttempt({binding:t.binding,signal:l,assertCurrent:t.assertCurrent}),d=runtimeMessageHash(RUNTIME_HASH_DOMAINS.params,{method:"session/prompt",params:t.params}),c=createNativeOutputFileAttempt({operationId:t.binding.operationId,requestMessageId:t.requestMessageId,paramsHash:d,activeRunRegistrationId:t.binding.operationId,responseId:t.binding.responseId,attemptId:t.binding.attemptId,sessionKey:n.sessionKey,getLease:()=>{const t=e.getLease();if(!t)throw new Error("central native output lease is unavailable");return t},assertAttempt:t.assertCurrent,signal:l}),m=registerNativeOutputRunContext({runId:r,sessionKey:n.sessionKey,operationId:t.binding.operationId,activeRunRegistrationId:t.binding.operationId,responseId:t.binding.responseId,attemptId:t.binding.attemptId}),u=new Set;let g;const I=(n,r)=>{if(centralNativeRuntime().receipt(t.binding.operationId)?.terminal)return;const i={type:"response.beeos.part",response_id:t.binding.responseId,kind:n,data:JSON.stringify(r)};let a;try{a=e.recordPublicEvent(t.binding,i)}catch(e){a=Promise.reject(e)}u.add(a),a.then(()=>u.delete(a),e=>{u.delete(a),g??=e,o.abort(e)})},b=createCentralNativeDeltaStream(t.binding,e.publishDelta,t=>{e.logger.warn?.(`central output delta was not published: ${t instanceof Error?t.name:"error"}`)}),v=()=>centralNativeRuntime().receipt(t.binding.operationId)?.terminal,y=e=>{v()||b.partial(e.text)},f=e=>{v()||b.block(e.text)},h=()=>{v()||b.beginMessage()};let w="";const R=(e,n)=>(t.assertCurrent(),"final"===e&&"string"==typeof n.text&&n.text.length>0&&(w=w?`${w}\n${n.text}`:n.text),I(e,n),!0),C={sendToolResult:e=>R("tool",e),sendBlockReply:e=>{const t=R("block",e);return t&&f(e),t},sendFinalReply:e=>R("final",e),waitForIdle:async()=>{},getQueuedCounts:()=>({tool:0,block:0,final:0}),markComplete:()=>{}};try{const i=t.params.parts,o=Array.isArray(i)?prepareNativePromptInput(i):"string"==typeof t.params.text?{message:t.params.text,files:[]}:void 0;if(!o)throw new Error("central native signed prompt parts are unavailable");await centralNativeRuntime().prepare(n.sessionKey,t.binding);const m=[],v=[];for(const n of o.files){t.assertCurrent();const r=e.getLease();if(!r)throw new Error("central native input Files lease is unavailable");const i=await e.inputFiles.resolve({operationId:t.binding.operationId,requestMessageId:t.requestMessageId,paramsHash:d,partIndex:n.partIndex,lease:r,signal:t.signal}),a=await downloadNativeInputFile({fileId:n.fileId,...i,signal:t.signal,assertAttempt:t.assertCurrent});m.push(a.path),v.push(a.mimeType)}let R;t.assertCurrent(),t.signal.throwIfAborted();const N=bindCentralInteractions(n.sessionKey,{responseId:t.binding.responseId,attemptId:t.binding.attemptId,mode:t.params.approvalMode,signal:l,publish:n=>e.recordPublicEvent(t.binding,{type:"response.interaction",response_id:t.binding.responseId,interaction:n}),decide:n=>e.decideInteraction(t.binding,n)});try{await dispatchRuntimeReplyWithRoute({runtime:{...e.runtime,config:{loadConfig:e.currentConfig}},preparedPrompt:{message:o.message,mediaPaths:m,mediaTypes:v,nativeSystemContext:n.systemPrompt},replyRoute:{protocol:"acp",requestId:t.binding.operationId,sessionId:n.sessionKey,sourceMessageId:t.requestMessageId,originatingChannel:"webchat",originatingTo:n.localAgentId,accountId:n.localAgentId,origin:"beeos-central-response"},replySinks:{acp:{dispatcher:C,replyOptions:{runId:r,abortSignal:l,disableBlockStreaming:!1,onAgentRunStart:t=>{e.coordinator.bindRun(a,t),p.bindHostRun(t),c.bindHostRun(t)},onPartialReply:y,onBlockReplyQueued:e=>{f(e)},onAssistantMessageStart:h,onReasoningStream:e=>{I("reasoning",e)},onToolStart:e=>{I("tool.start",e)},onItemEvent:e=>{I("item",e)}}}},onDispatchInvoked:()=>{s=!0}})}catch(e){R=e}try{await N()}catch(e){R??=e}await Promise.allSettled([...u,b.close()]),R??=g;const x=t.signal.aborted,S=centralNativeRuntime().receipt(t.binding.operationId)?.terminal,A=await e.coordinator.converge(a,x?"cancelled":"completed"===S?.status?"completed":"error");if(!A.ok)throw new Error("central native physical writer did not quiesce");if(t.assertCurrent(),!e.native.nativeWritersQuiescent({sessionKey:n.sessionKey}))throw new Error("central native admission still owns the physical writer");if(R&&!x)throw R;const E=centralNativeRuntime().receipt(t.binding.operationId)?.terminal;if(!E||E.response_id!==t.binding.responseId)throw new Error("native outcome has no original central terminal transaction receipt");const M=E.status;return t.assertCurrent(),e.coordinator.release(A.permit),{status:M,...w?{finalText:w}:{}}}catch(t){throw s?e.coordinator.snapshot(n.sessionKey)&&e.coordinator.requireRecovery(a,"terminal_not_observed"):e.coordinator.releaseBeforeRuntime(a),t}finally{p.close(),c.close(),m()}}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{HarnessProtocolError}from"@beeos-ai/cloud-harness-sdk";import{parseBeeosFileUri}from"../files/beeos-file-uri.js";const object=e=>null!==e&&"object"==typeof e&&!Array.isArray(e),fileIdPattern=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;export class NativeArtifactDeliveryFailure extends Error{constructor(){super("The native output artifact could not be delivered.")}}export function nativeOutputFileIds(e){const t=[];if(void 0!==e.mediaUrl&&null!==e.mediaUrl&&""!==e.mediaUrl&&t.push(e.mediaUrl),void 0!==e.mediaUrls&&null!==e.mediaUrls){if(!Array.isArray(e.mediaUrls))throw new NativeArtifactDeliveryFailure;t.push(...e.mediaUrls)}return t.map(e=>{const t="string"==typeof e?parseBeeosFileUri(e).fileId:void 0;if(!t||e!==`beeos-file://${t}`||!fileIdPattern.test(t)||"00000000-0000-0000-0000-000000000000"===t)throw new NativeArtifactDeliveryFailure;return t})}function isDefiniteFileNotFound(e){if(!(e instanceof HarnessProtocolError&&404===e.status&&e.body))return!1;let t;try{t=JSON.parse(e.body)}catch{return!1}return object(t)&&"not_found"===t.code&&"file not found"===t.message}export function centralNativeOutputFileResolver(e,t){return async(i,r)=>{const a=await t.credential(i),n=t.outputFileBinding(i);let s;try{s=await e.resolveOutput(a,i.operationId,{...n,fileId:r})}catch(e){if(t.outputFileBinding(i),isDefiniteFileNotFound(e))throw new NativeArtifactDeliveryFailure;throw e}if(t.outputFileBinding(i),!object(s)||s.operationId!==i.operationId||s.requestMessageId!==n.requestMessageId||s.paramsHash!==n.paramsHash||s.activeRunRegistrationId!==n.activeRunRegistrationId||!object(s.file))throw new Error("native output Files response binding invalid");const o=s.file;if(o.file_id!==r||"ready"!==o.status||"string"!=typeof o.filename||!o.filename||"string"!=typeof o.content_type||!o.content_type||"number"!=typeof o.size_bytes||!Number.isSafeInteger(o.size_bytes)||o.size_bytes<0||"string"!=typeof o.checksum_sha256||!/^[0-9a-f]{64}$/.test(o.checksum_sha256)||"string"!=typeof o.created_at||!Number.isFinite(Date.parse(o.created_at)))throw new Error("native output Files metadata invalid");if([...o.filename].length>256||[...o.content_type].length>128||o.size_bytes>67108864)throw new NativeArtifactDeliveryFailure;return{id:r,filename:o.filename,media_type:o.content_type,size_bytes:o.size_bytes,sha256:o.checksum_sha256,status:"ready",owner_scope:"org",owner_id:null,created_at:o.created_at,expires_at:null}}}
|