beeos-claw 0.6.66-cloud.3 → 0.6.66-cloud.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION}from"@beeos-ai/beeos-types/runtime";import{TemplatePackageError,parseAndValidateTemplatePackage}from"../acp-gateway/agent-template-package.js";import{HttpRuntimeOperationResourceResolver,RuntimeResourceResolutionError}from"./runtime-operation-resource-resolver.js";import{CloudGatewayGrantJwksVerifier,GatewayGrantJwksVerifier,RuntimeJwksVerifier,createCloudGrantVerifier,warmGrantJwks}from"@beeos-ai/cloud-harness-sdk";import{fetchRuntimeLeaseAttempt}from"./message-service-runtime-authenticated-fetch.js";import{MessageServiceConversationClearHttpAuthority}from"./message-service-conversation-clear-http-authority.js";import{MessageServiceConversationHistoryBoundary}from"./message-service-conversation-history-boundary.js";import{MessageServiceSessionModelHttpAuthority}from"./message-service-session-model-http-authority.js";import{MsRuntimeMessageChannelConsumerFactory}from"./ms-runtime-message-channel-consumer-factory.js";import{RUNTIME_MESSAGE_CHANNEL_REVISION,RUNTIME_PARITY_MANIFEST}from"./runtime-parity-manifest.js";import{intersectRuntimeServiceMethodsWithBackendCapabilities,loadRuntimeServiceContractIdentity,runtimeServiceContractRequirement}from"./runtime-service-contract-compatibility.js";const CONTRACT_ARTIFACT_BLOCKER=Object.freeze({id:"contract_artifact_mismatch",owner:"backend",requiredContract:"frozen Types manifest and Service wire artifacts"}),TRANSPORT_BLOCKER=Object.freeze({id:"message_channel_transport",owner:"backend",requiredContract:`${RUNTIME_MESSAGE_CHANNEL_REVISION} HTTP delivery/history/append authority`}),JWKS_BLOCKER=Object.freeze({id:"gateway_grant_jwks",owner:"backend",requiredContract:"Purpose-bound Gateway runtime execution-grant JWKS proxy"}),POISON_JOURNAL_BLOCKER=Object.freeze({id:"poison_journal",owner:"openclaw_runtime_client",requiredContract:"Durable bounded runtime poison-delivery journal"}),grantAdapterOptions=new WeakMap;export class AgentGatewayGrantJwksReadinessAdapter{constructor(e){grantAdapterOptions.set(this,{gateway:e.gateway})}}export class AgentGatewaySplitJwksReadinessAdapter extends AgentGatewayGrantJwksReadinessAdapter{}const transportOptions=new WeakMap;export class RuntimeServiceTransportReadinessAdapter{constructor(e){transportOptions.set(this,{messageService:e.messageService,messageClient:e.messageClient,configuredServiceUrl:e.configuredServiceUrl,scopedDeliveryKey:e.scopedDeliveryKey,gateway:e.gateway})}}const cloudTransportOptions=new WeakMap;export class CloudRuntimeServiceTransportReadinessAdapter{constructor(e){cloudTransportOptions.set(this,{...e})}}const CAPABILITY_BLOCKERS=Object.freeze(RUNTIME_PARITY_MANIFEST.filter(e=>"blocked"===e.status).map(e=>Object.freeze({method:e.method,owner:e.blockerOwner,requiredContract:e.contractRevision})));export async function createRuntimeServiceProductionCandidate(e){try{loadRuntimeServiceContractIdentity()}catch{return{status:"unavailable",blockers:Object.freeze([{...CONTRACT_ARTIFACT_BLOCKER,requiredContract:contractArtifactRequirement()}])}}if(!e.poisonJournal)return{status:"unavailable",blockers:Object.freeze([POISON_JOURNAL_BLOCKER])};const r=e.cloudTransportAdapter?cloudTransportOptions.get(e.cloudTransportAdapter):void 0,t=e.authorizationAdapter?startGatewayGrantJwks(e.authorizationAdapter,Boolean(r),e.onGrantJwksWarm):void 0;if(r){if(!r.configuredServiceUrl)return{status:"unavailable",blockers:Object.freeze([TRANSPORT_BLOCKER,...t?[]:[JWKS_BLOCKER]])};if(!(t instanceof CloudGatewayGrantJwksVerifier))return{status:"unavailable",blockers:Object.freeze([JWKS_BLOCKER])};const n=intersectRuntimeServiceMethodsWithBackendCapabilities(["models/list","agent/create","skills/list","skills/update","skills/uninstall","skills/install","mcp/list","mcp/set","mcp/unset"]);return n.includes("models/list")?{status:"ready",blockers:[],capabilityBlockers:[],serviceMethods:n,factory:new MsRuntimeMessageChannelConsumerFactory({runtimeDelivery:r.runtimeDelivery,...r.nativePrompt?{nativePrompt:r.nativePrompt}:{},...r.sessionNewConversation?{sessionNewConversation:r.sessionNewConversation}:{},verifier:t,ports:e.attemptPorts??runtimeMessageAttemptPorts(r,r.configuredServiceUrl,{requireCredentialExpiry:!0}),journal:e.commandJournal,allowedMethods:new Set(n),options:{poisonJournal:e.poisonJournal,requestSchemaVersion:2,...e.onConsumerDeliveryError?{onDeliveryError:e.onConsumerDeliveryError}:{},...e.onConsumerLeaseStarvation?{onLeaseStarvation:e.onConsumerLeaseStarvation}:{},...e.onConsumerRequestTerminalAccepted?{onRequestTerminalAccepted:e.onConsumerRequestTerminalAccepted}:{},...e.onConsumerRequestAcknowledged?{onRequestAcknowledged:e.onConsumerRequestAcknowledged}:{},...e.onConsumerRequestFailure?{onRequestFailure:e.onConsumerRequestFailure}:{}}})}:{status:"unavailable",blockers:Object.freeze([CONTRACT_ARTIFACT_BLOCKER])}}const n=e.transportAdapter?transportOptions.get(e.transportAdapter):void 0;if(!n?.messageClient||!n.configuredServiceUrl)return{status:"unavailable",blockers:Object.freeze([TRANSPORT_BLOCKER,...t?[]:[JWKS_BLOCKER]])};if(!t)return{status:"unavailable",blockers:Object.freeze([JWKS_BLOCKER])};const a=runtimeMethods(),o=e.attemptPorts??runtimeMessageAttemptPorts(n,n.configuredServiceUrl);return{status:"ready",blockers:[],capabilityBlockers:CAPABILITY_BLOCKERS,serviceMethods:a,factory:new MsRuntimeMessageChannelConsumerFactory({client:n.messageClient,verifier:t,ports:o,journal:e.commandJournal,allowedMethods:new Set(a),options:{poisonJournal:e.poisonJournal,...e.onConsumerDeliveryError?{onDeliveryError:e.onConsumerDeliveryError}:{},...e.onConsumerLeaseStarvation?{onLeaseStarvation:e.onConsumerLeaseStarvation}:{},...e.onConsumerRequestTerminalAccepted?{onRequestTerminalAccepted:e.onConsumerRequestTerminalAccepted}:{},...e.onConsumerRequestAcknowledged?{onRequestAcknowledged:e.onConsumerRequestAcknowledged}:{},...e.onConsumerRequestFailure?{onRequestFailure:e.onConsumerRequestFailure}:{}}}),...void 0===e.attemptPorts?{resourceBindingContractRevision:RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION}:{}}}function startGatewayGrantJwks(e,r,t){const n=grantAdapterOptions.get(e);if(!n)throw new Error("untrusted Gateway grant readiness adapter");const a=n.gateway.baseUrl.toString().replace(/\/+$/,""),o=r?createCloudGrantVerifier(a):new GatewayGrantJwksVerifier(new RuntimeJwksVerifier(`${a}/.well-known/runtime-execution-grant-jwks.json`));return warmGrantJwks(o,{onRetry:({attempt:e,error:r})=>t?.({ready:!1,attempt:e,error:r})}).then(e=>t?.({ready:e})),o}export function runtimeMessageAttemptPorts(e,r,t={}){return{async resolve({request:n,command:a,executionGrant:o,getLease:s,journalStoreId:i,journalGeneration:c,journalRecord:u,abortSignal:d}){const l="resourceBindings"in n?n.resourceBindings:void 0,m="resourceBindingContractRevision"in n?n.resourceBindingContractRevision:void 0,p="skills.install"===a.name||"agent.applyTemplate"===a.name?a.params.artifact:void 0,R="mcp.prepare"===a.name||"mcp.set"===a.name?a.params.definition:void 0;if((p||R)&&(m!==RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION||!l))throw new RuntimeResourceResolutionError("resolution_rejected","resource-bound Service delivery requires the Types 4.1 binding carrier",void 0,`binding_contract_revision=${m??"absent"} bindings=${l?"present":"absent"}`);const C=new HttpRuntimeOperationResourceResolver({gateway:e.gateway,operationId:n.operationId,requestMessageId:n.requestMessageId,instanceId:n.instanceId,paramsHash:n.paramsHash,bindings:l??[],getAuthorization:()=>{const e=s();return{executionGrant:o,runtimeLeaseCredential:e.runtimeLeaseCredential,fence:deliveryFence(n,e,i,c)}},parseSkillArtifact:e=>parseSkillPackage(e),signal:d,...t.requireCredentialExpiry?{requireCredentialExpiry:!0}:{}});if("prepared"!==u.phase&&"started"!==u.phase||(p&&await C.readVerifiedArtifact(p),R&&await C.resolveMcpDefinition(R)),"session.setModel"===a.name){if(!e.messageService)throw new Error("Cloud runtime cannot project a personal session model");const t=e.scopedDeliveryKey;if(!t)throw new Error("session model requires X-Runtime-Delivery-Key");return{resources:C,sessionModelProjection:{project:async({conversationId:e,modelOverrideId:a})=>{const o=s(),i=new MessageServiceSessionModelHttpAuthority({messageServiceUrl:r,scopedDeliveryKey:t,fetchAuthorized:(e,r)=>fetchRuntimeLeaseAttempt(e,r??{})});return await i.project({conversationId:e,operationId:n.operationId,requestMessageId:n.requestMessageId,requestHash:n.requestHash,modelOverrideId:a,runtimeLeaseCredential:o.runtimeLeaseCredential})}}}}if("session.clear"!==a.name)return{resources:C};if(!e.messageService)throw new Error("Cloud runtime cannot access personal conversation history");a.context.conversation;const v=s(),y=new MessageServiceConversationClearHttpAuthority({messageServiceUrl:r,runtimeLeaseCredential:v.runtimeLeaseCredential,fetchAuthorized:(e,r)=>fetchRuntimeLeaseAttempt(e,r??{})});return{resources:C,historyBoundary:new MessageServiceConversationHistoryBoundary({operationId:n.operationId,requestMessageId:n.requestMessageId,requestHash:n.requestHash,fence:deliveryFence(n,v,i,c),authority:y})}}}}function runtimeMethods(){return[...intersectRuntimeServiceMethodsWithBackendCapabilities(RUNTIME_PARITY_MANIFEST.filter(e=>"ready"===e.status).map(e=>e.method))]}function contractArtifactRequirement(){try{return runtimeServiceContractRequirement()}catch{return CONTRACT_ARTIFACT_BLOCKER.requiredContract}}function parseSkillPackage(e){try{return parseAndValidateTemplatePackage(Buffer.from(e))}catch(r){if(!(r instanceof TemplatePackageError))throw r;throw new RuntimeResourceResolutionError("resolution_rejected","skill package failed validation",void 0,`package_invalid bytes=${e.byteLength} reason=${r.message}`)}}function deliveryFence(e,r,t,n){if(r.handlerIdentity!==e.runtimeHandlerIdentity||r.runtimeEpoch!==e.dispatchEpoch)throw new Error("runtime delivery fence does not match the retained request");return{claimId:e.requestMessageId,handlerIdentity:r.handlerIdentity,runtimeEpoch:r.runtimeEpoch,fencingToken:r.runtimeEpoch,journalStoreId:t,journalGeneration:n}}
|
|
1
|
+
import{RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION}from"@beeos-ai/beeos-types/runtime";import{TemplatePackageError,parseAndValidateTemplatePackage}from"../acp-gateway/agent-template-package.js";import{HttpRuntimeOperationResourceResolver,RuntimeResourceResolutionError}from"./runtime-operation-resource-resolver.js";import{CloudGatewayGrantJwksVerifier,GatewayGrantJwksVerifier,RuntimeJwksVerifier,createCloudGrantVerifier,warmGrantJwks}from"@beeos-ai/cloud-harness-sdk";import{fetchRuntimeLeaseAttempt}from"./message-service-runtime-authenticated-fetch.js";import{MessageServiceConversationClearHttpAuthority}from"./message-service-conversation-clear-http-authority.js";import{MessageServiceConversationHistoryBoundary}from"./message-service-conversation-history-boundary.js";import{MessageServiceSessionModelHttpAuthority}from"./message-service-session-model-http-authority.js";import{MsRuntimeMessageChannelConsumerFactory}from"./ms-runtime-message-channel-consumer-factory.js";import{RUNTIME_MESSAGE_CHANNEL_REVISION,RUNTIME_PARITY_MANIFEST}from"./runtime-parity-manifest.js";import{intersectRuntimeServiceMethodsWithBackendCapabilities,loadRuntimeServiceContractIdentity,runtimeServiceContractRequirement}from"./runtime-service-contract-compatibility.js";const CONTRACT_ARTIFACT_BLOCKER=Object.freeze({id:"contract_artifact_mismatch",owner:"backend",requiredContract:"frozen Types manifest and Service wire artifacts"}),TRANSPORT_BLOCKER=Object.freeze({id:"message_channel_transport",owner:"backend",requiredContract:`${RUNTIME_MESSAGE_CHANNEL_REVISION} HTTP delivery/history/append authority`}),JWKS_BLOCKER=Object.freeze({id:"gateway_grant_jwks",owner:"backend",requiredContract:"Purpose-bound Gateway runtime execution-grant JWKS proxy"}),POISON_JOURNAL_BLOCKER=Object.freeze({id:"poison_journal",owner:"openclaw_runtime_client",requiredContract:"Durable bounded runtime poison-delivery journal"}),grantAdapterOptions=new WeakMap;export class AgentGatewayGrantJwksReadinessAdapter{constructor(e){grantAdapterOptions.set(this,{gateway:e.gateway})}}export class AgentGatewaySplitJwksReadinessAdapter extends AgentGatewayGrantJwksReadinessAdapter{}const transportOptions=new WeakMap;export class RuntimeServiceTransportReadinessAdapter{constructor(e){transportOptions.set(this,{messageService:e.messageService,messageClient:e.messageClient,configuredServiceUrl:e.configuredServiceUrl,scopedDeliveryKey:e.scopedDeliveryKey,gateway:e.gateway})}}const cloudTransportOptions=new WeakMap;export class CloudRuntimeServiceTransportReadinessAdapter{constructor(e){cloudTransportOptions.set(this,{...e})}}const CAPABILITY_BLOCKERS=Object.freeze(RUNTIME_PARITY_MANIFEST.filter(e=>"blocked"===e.status).map(e=>Object.freeze({method:e.method,owner:e.blockerOwner,requiredContract:e.contractRevision})));export async function createRuntimeServiceProductionCandidate(e){try{loadRuntimeServiceContractIdentity()}catch{return{status:"unavailable",blockers:Object.freeze([{...CONTRACT_ARTIFACT_BLOCKER,requiredContract:contractArtifactRequirement()}])}}if(!e.poisonJournal)return{status:"unavailable",blockers:Object.freeze([POISON_JOURNAL_BLOCKER])};const r=e.cloudTransportAdapter?cloudTransportOptions.get(e.cloudTransportAdapter):void 0,t=e.authorizationAdapter?startGatewayGrantJwks(e.authorizationAdapter,Boolean(r),e.onGrantJwksWarm):void 0;if(r){if(!r.configuredServiceUrl)return{status:"unavailable",blockers:Object.freeze([TRANSPORT_BLOCKER,...t?[]:[JWKS_BLOCKER]])};if(!(t instanceof CloudGatewayGrantJwksVerifier))return{status:"unavailable",blockers:Object.freeze([JWKS_BLOCKER])};const n=intersectRuntimeServiceMethodsWithBackendCapabilities(["models/list","agent/create","agent/applyTemplate","skills/list","skills/update","skills/uninstall","skills/install","mcp/list","mcp/set","mcp/unset"]);return n.includes("models/list")?{status:"ready",blockers:[],capabilityBlockers:[],serviceMethods:n,factory:new MsRuntimeMessageChannelConsumerFactory({runtimeDelivery:r.runtimeDelivery,...r.nativePrompt?{nativePrompt:r.nativePrompt}:{},...r.sessionNewConversation?{sessionNewConversation:r.sessionNewConversation}:{},verifier:t,ports:e.attemptPorts??runtimeMessageAttemptPorts(r,r.configuredServiceUrl,{requireCredentialExpiry:!0}),journal:e.commandJournal,allowedMethods:new Set(n),options:{poisonJournal:e.poisonJournal,requestSchemaVersion:2,...e.onConsumerDeliveryError?{onDeliveryError:e.onConsumerDeliveryError}:{},...e.onConsumerLeaseStarvation?{onLeaseStarvation:e.onConsumerLeaseStarvation}:{},...e.onConsumerRequestTerminalAccepted?{onRequestTerminalAccepted:e.onConsumerRequestTerminalAccepted}:{},...e.onConsumerRequestAcknowledged?{onRequestAcknowledged:e.onConsumerRequestAcknowledged}:{},...e.onConsumerRequestFailure?{onRequestFailure:e.onConsumerRequestFailure}:{}}})}:{status:"unavailable",blockers:Object.freeze([CONTRACT_ARTIFACT_BLOCKER])}}const n=e.transportAdapter?transportOptions.get(e.transportAdapter):void 0;if(!n?.messageClient||!n.configuredServiceUrl)return{status:"unavailable",blockers:Object.freeze([TRANSPORT_BLOCKER,...t?[]:[JWKS_BLOCKER]])};if(!t)return{status:"unavailable",blockers:Object.freeze([JWKS_BLOCKER])};const a=runtimeMethods(),o=e.attemptPorts??runtimeMessageAttemptPorts(n,n.configuredServiceUrl);return{status:"ready",blockers:[],capabilityBlockers:CAPABILITY_BLOCKERS,serviceMethods:a,factory:new MsRuntimeMessageChannelConsumerFactory({client:n.messageClient,verifier:t,ports:o,journal:e.commandJournal,allowedMethods:new Set(a),options:{poisonJournal:e.poisonJournal,...e.onConsumerDeliveryError?{onDeliveryError:e.onConsumerDeliveryError}:{},...e.onConsumerLeaseStarvation?{onLeaseStarvation:e.onConsumerLeaseStarvation}:{},...e.onConsumerRequestTerminalAccepted?{onRequestTerminalAccepted:e.onConsumerRequestTerminalAccepted}:{},...e.onConsumerRequestAcknowledged?{onRequestAcknowledged:e.onConsumerRequestAcknowledged}:{},...e.onConsumerRequestFailure?{onRequestFailure:e.onConsumerRequestFailure}:{}}}),...void 0===e.attemptPorts?{resourceBindingContractRevision:RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION}:{}}}function startGatewayGrantJwks(e,r,t){const n=grantAdapterOptions.get(e);if(!n)throw new Error("untrusted Gateway grant readiness adapter");const a=n.gateway.baseUrl.toString().replace(/\/+$/,""),o=r?createCloudGrantVerifier(a):new GatewayGrantJwksVerifier(new RuntimeJwksVerifier(`${a}/.well-known/runtime-execution-grant-jwks.json`));return warmGrantJwks(o,{onRetry:({attempt:e,error:r})=>t?.({ready:!1,attempt:e,error:r})}).then(e=>t?.({ready:e})),o}export function runtimeMessageAttemptPorts(e,r,t={}){return{async resolve({request:n,command:a,executionGrant:o,getLease:s,journalStoreId:i,journalGeneration:c,journalRecord:u,abortSignal:l}){const d="resourceBindings"in n?n.resourceBindings:void 0,m="resourceBindingContractRevision"in n?n.resourceBindingContractRevision:void 0,p="skills.install"===a.name||"agent.applyTemplate"===a.name?a.params.artifact:void 0,R="mcp.prepare"===a.name||"mcp.set"===a.name?a.params.definition:void 0;if((p||R)&&(m!==RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION||!d))throw new RuntimeResourceResolutionError("resolution_rejected","resource-bound Service delivery requires the Types 4.1 binding carrier",void 0,`binding_contract_revision=${m??"absent"} bindings=${d?"present":"absent"}`);const C=new HttpRuntimeOperationResourceResolver({gateway:e.gateway,operationId:n.operationId,requestMessageId:n.requestMessageId,instanceId:n.instanceId,paramsHash:n.paramsHash,bindings:d??[],getAuthorization:()=>{const e=s();return{executionGrant:o,runtimeLeaseCredential:e.runtimeLeaseCredential,fence:deliveryFence(n,e,i,c)}},parseSkillArtifact:e=>parseSkillPackage(e),signal:l,...t.requireCredentialExpiry?{requireCredentialExpiry:!0}:{}});if("prepared"!==u.phase&&"started"!==u.phase||(p&&await C.readVerifiedArtifact(p),R&&await C.resolveMcpDefinition(R)),"session.setModel"===a.name){if(!e.messageService)throw new Error("Cloud runtime cannot project a personal session model");const t=e.scopedDeliveryKey;if(!t)throw new Error("session model requires X-Runtime-Delivery-Key");return{resources:C,sessionModelProjection:{project:async({conversationId:e,modelOverrideId:a})=>{const o=s(),i=new MessageServiceSessionModelHttpAuthority({messageServiceUrl:r,scopedDeliveryKey:t,fetchAuthorized:(e,r)=>fetchRuntimeLeaseAttempt(e,r??{})});return await i.project({conversationId:e,operationId:n.operationId,requestMessageId:n.requestMessageId,requestHash:n.requestHash,modelOverrideId:a,runtimeLeaseCredential:o.runtimeLeaseCredential})}}}}if("session.clear"!==a.name)return{resources:C};if(!e.messageService)throw new Error("Cloud runtime cannot access personal conversation history");a.context.conversation;const v=s(),y=new MessageServiceConversationClearHttpAuthority({messageServiceUrl:r,runtimeLeaseCredential:v.runtimeLeaseCredential,fetchAuthorized:(e,r)=>fetchRuntimeLeaseAttempt(e,r??{})});return{resources:C,historyBoundary:new MessageServiceConversationHistoryBoundary({operationId:n.operationId,requestMessageId:n.requestMessageId,requestHash:n.requestHash,fence:deliveryFence(n,v,i,c),authority:y})}}}}function runtimeMethods(){return[...intersectRuntimeServiceMethodsWithBackendCapabilities(RUNTIME_PARITY_MANIFEST.filter(e=>"ready"===e.status).map(e=>e.method))]}function contractArtifactRequirement(){try{return runtimeServiceContractRequirement()}catch{return CONTRACT_ARTIFACT_BLOCKER.requiredContract}}function parseSkillPackage(e){try{return parseAndValidateTemplatePackage(Buffer.from(e))}catch(r){if(!(r instanceof TemplatePackageError))throw r;throw new RuntimeResourceResolutionError("resolution_rejected","skill package failed validation",void 0,`package_invalid bytes=${e.byteLength} reason=${r.message}`)}}function deliveryFence(e,r,t,n){if(r.handlerIdentity!==e.runtimeHandlerIdentity||r.runtimeEpoch!==e.dispatchEpoch)throw new Error("runtime delivery fence does not match the retained request");return{claimId:e.requestMessageId,handlerIdentity:r.handlerIdentity,runtimeEpoch:r.runtimeEpoch,fencingToken:r.runtimeEpoch,journalStoreId:t,journalGeneration:n}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash,randomUUID}from"node:crypto";import{EventEmitter}from"node:events";import WebSocket from"ws";import{createTerminalAgentAuth,terminalAgentAuthSigningMessage as harnessTerminalAgentAuthSigningMessage,terminalAgentWebSocketUrl}from"@beeos-ai/cloud-harness-sdk";export function terminalAgentAuthSigningMessage(e){return harnessTerminalAgentAuthSigningMessage({publicKey:e.public_key,timestamp:e.timestamp,nonce:e.nonce,runtimeLeaseCredential:e.runtimeLeaseCredential,handlerIdentity:e.handlerIdentity,runtimeEpoch:e.runtimeEpoch,leaseId:e.leaseId})}export function createTerminalLeaseBoundAgentAuth(e){if(!(32===e.keys.publicKey.length&&[32,48].includes(e.keys.privateKey.length)&&e.lease.instanceId&&e.lease.leaseId&&e.lease.handlerIdentity&&e.lease.runtimeLeaseCredential&&isPositiveRuntimeEpoch(e.lease.runtimeEpoch)&&Number.isSafeInteger(e.timestamp)&&!(e.timestamp<0)&&e.nonce))throw new Error("invalid Terminal runtime lease authority binding");return createTerminalAgentAuth({lease:{instanceId:e.lease.instanceId,leaseId:e.lease.leaseId,runtimeEpoch:e.lease.runtimeEpoch,runtimeLeaseCredential:e.lease.runtimeLeaseCredential,handlerIdentity:e.lease.handlerIdentity},keys:e.keys,timestamp:e.timestamp,nonce:e.nonce})}export class TerminalLeaseBoundBridgeClient extends EventEmitter{options;state="idle";socket;unsubscribe;expiryTimer;reconnectTimer;generation=0;stopped=!0;authenticatedBindingHash;authorityEpochBindingHash;transition=Promise.resolve();constructor(e){super(),this.options=e}async connect(){this.unsubscribe||(this.unsubscribe=this.options.authority.subscribeAuthority((e,t)=>this.onAuthorityChanged(e,t))),this.stopped=!1;const e=this.options.authority.authorityLease;if(!e)throw new Error("active runtime registration lease required for Terminal auth");await this.queueTransition(()=>this.replaceConnection(e))}async send(e){const t=this.socket;if("connected"!==this.state||!t||t.readyState!==WebSocket.OPEN)throw new Error("Terminal lease-bound Bridge is not connected");await new Promise((i,n)=>t.send(e,e=>e?n(e):i()))}async close(e=!0){this.stopped=!0,this.clearTimers(),this.unsubscribe?.(),this.unsubscribe=void 0,this.authenticatedBindingHash=void 0,this.authorityEpochBindingHash=void 0,this.generation++,await this.closeSocket(e),this.state="closed"}onAuthorityChanged(e,t){if(this.stopped)return;if(!e)return void this.fenceAuthority(void 0===t);this.scheduleExpiryFence(e);const i=authorityEpochHash(e),n=authorityBindingHash(e);return this.authorityEpochBindingHash&&i!==this.authorityEpochBindingHash?(this.authorityEpochBindingHash=i,this.emit("transportEpochChanged"),void this.queueTransition(()=>this.replaceConnection(e)).catch(e=>this.emitError(e))):n!==this.authenticatedBindingHash?"connected"===this.state&&this.authenticatedBindingHash?(this.authenticatedBindingHash=n,void(this.authorityEpochBindingHash??=i)):void this.queueTransition(()=>this.replaceConnection(e)).catch(e=>this.emitError(e)):void 0}async replaceConnection(e){if(this.stopped||null===this.options.authority.authorityLease)return;this.clearReconnectTimer();const t=++this.generation;if(await this.closeSocket(!1),this.stopped||t!==this.generation)return;this.state="connecting";const i=new WebSocket(terminalAgentWebSocketUrl(this.options.bridgeUrl));this.socket=i;const n=authorityBindingHash(e);await new Promise((s,r)=>{let o=!1;const a=setTimeout(()=>{c(new Error("Terminal auth timeout")),i.readyState!==WebSocket.CLOSED&&i.terminate()},this.options.authTimeoutMs??1e4),h=()=>{clearTimeout(a),i.off("open",u)},c=e=>{h(),o||r(e)},u=()=>{const e=this.options.authority.authorityLease;if(!e||authorityBindingHash(e)!==n||t!==this.generation)return c(new Error("Terminal runtime lease changed during auth")),void i.close();const s=createTerminalLeaseBoundAgentAuth({lease:e,keys:this.options.keys,timestamp:Math.floor((this.options.now??Date.now)()/1e3),nonce:(this.options.nonce??randomUUID)()});i.send(JSON.stringify(s),e=>{e&&c(e)})};i.on("open",u),i.on("message",r=>{if(!o){try{if("auth_ok"!==JSON.parse(r.toString()).type)return}catch{return}return o=!0,h(),t!==this.generation?void i.close():(this.authenticatedBindingHash=n,this.authorityEpochBindingHash=authorityEpochHash(e),this.state="connected",this.scheduleExpiryFence(e),this.emit("connected",{handlerIdentity:e.handlerIdentity}),void s())}this.emit("message",r)}),i.on("error",e=>{this.emitError(e),c(e)}),i.on("close",(e,i)=>{h(),o||r(new Error(`Terminal auth rejected: ${i.toString()||"connection closed"}`)),t===this.generation&&(this.socket=void 0,this.authenticatedBindingHash=void 0,this.state="idle",this.emit("disconnected",i.toString()||"connection closed"),1008!==e?!this.stopped&&this.options.authority.authorityLease&&this.scheduleReconnect():this.fenceAuthority(!
|
|
1
|
+
import{createHash,randomUUID}from"node:crypto";import{EventEmitter}from"node:events";import WebSocket from"ws";import{createTerminalAgentAuth,terminalAgentAuthSigningMessage as harnessTerminalAgentAuthSigningMessage,terminalAgentWebSocketUrl}from"@beeos-ai/cloud-harness-sdk";export function terminalAgentAuthSigningMessage(e){return harnessTerminalAgentAuthSigningMessage({publicKey:e.public_key,timestamp:e.timestamp,nonce:e.nonce,runtimeLeaseCredential:e.runtimeLeaseCredential,handlerIdentity:e.handlerIdentity,runtimeEpoch:e.runtimeEpoch,leaseId:e.leaseId})}export function createTerminalLeaseBoundAgentAuth(e){if(!(32===e.keys.publicKey.length&&[32,48].includes(e.keys.privateKey.length)&&e.lease.instanceId&&e.lease.leaseId&&e.lease.handlerIdentity&&e.lease.runtimeLeaseCredential&&isPositiveRuntimeEpoch(e.lease.runtimeEpoch)&&Number.isSafeInteger(e.timestamp)&&!(e.timestamp<0)&&e.nonce))throw new Error("invalid Terminal runtime lease authority binding");return createTerminalAgentAuth({lease:{instanceId:e.lease.instanceId,leaseId:e.lease.leaseId,runtimeEpoch:e.lease.runtimeEpoch,runtimeLeaseCredential:e.lease.runtimeLeaseCredential,handlerIdentity:e.lease.handlerIdentity},keys:e.keys,timestamp:e.timestamp,nonce:e.nonce})}export class TerminalLeaseBoundBridgeClient extends EventEmitter{options;state="idle";socket;unsubscribe;expiryTimer;reconnectTimer;generation=0;stopped=!0;authenticatedBindingHash;authorityEpochBindingHash;transition=Promise.resolve();constructor(e){super(),this.options=e}async connect(){this.unsubscribe||(this.unsubscribe=this.options.authority.subscribeAuthority((e,t)=>this.onAuthorityChanged(e,t))),this.stopped=!1;const e=this.options.authority.authorityLease;if(!e)throw new Error("active runtime registration lease required for Terminal auth");await this.queueTransition(()=>this.replaceConnection(e))}async send(e){const t=this.socket;if("connected"!==this.state||!t||t.readyState!==WebSocket.OPEN)throw new Error("Terminal lease-bound Bridge is not connected");await new Promise((i,n)=>t.send(e,e=>e?n(e):i()))}async close(e=!0){this.stopped=!0,this.clearTimers(),this.unsubscribe?.(),this.unsubscribe=void 0,this.authenticatedBindingHash=void 0,this.authorityEpochBindingHash=void 0,this.generation++,await this.closeSocket(e),this.state="closed"}onAuthorityChanged(e,t){if(this.stopped)return;if(!e)return void this.fenceAuthority(void 0===t);this.scheduleExpiryFence(e);const i=authorityEpochHash(e),n=authorityBindingHash(e);return this.authorityEpochBindingHash&&i!==this.authorityEpochBindingHash?(this.authorityEpochBindingHash=i,this.emit("transportEpochChanged"),void this.queueTransition(()=>this.replaceConnection(e)).catch(e=>this.emitError(e))):n!==this.authenticatedBindingHash?"connected"===this.state&&this.authenticatedBindingHash?(this.authenticatedBindingHash=n,void(this.authorityEpochBindingHash??=i)):void this.queueTransition(()=>this.replaceConnection(e)).catch(e=>this.emitError(e)):void 0}async replaceConnection(e){if(this.stopped||null===this.options.authority.authorityLease)return;this.clearReconnectTimer();const t=++this.generation;if(await this.closeSocket(!1),this.stopped||t!==this.generation)return;this.state="connecting";const i=new WebSocket(terminalAgentWebSocketUrl(this.options.bridgeUrl));this.socket=i;const n=authorityBindingHash(e);await new Promise((s,r)=>{let o=!1;const a=setTimeout(()=>{c(new Error("Terminal auth timeout")),i.readyState!==WebSocket.CLOSED&&i.terminate()},this.options.authTimeoutMs??1e4),h=()=>{clearTimeout(a),i.off("open",u)},c=e=>{h(),o||r(e)},u=()=>{const e=this.options.authority.authorityLease;if(!e||authorityBindingHash(e)!==n||t!==this.generation)return c(new Error("Terminal runtime lease changed during auth")),void i.close();const s=createTerminalLeaseBoundAgentAuth({lease:e,keys:this.options.keys,timestamp:Math.floor((this.options.now??Date.now)()/1e3),nonce:(this.options.nonce??randomUUID)()});i.send(JSON.stringify(s),e=>{e&&c(e)})};i.on("open",u),i.on("message",r=>{if(!o){try{if("auth_ok"!==JSON.parse(r.toString()).type)return}catch{return}return o=!0,h(),t!==this.generation?void i.close():(this.authenticatedBindingHash=n,this.authorityEpochBindingHash=authorityEpochHash(e),this.state="connected",this.scheduleExpiryFence(e),this.emit("connected",{handlerIdentity:e.handlerIdentity}),void s())}this.emit("message",r)}),i.on("error",e=>{this.emitError(e),c(e)}),i.on("close",(e,i)=>{h(),o||r(new Error(`Terminal auth rejected: ${i.toString()||"connection closed"}`)),t===this.generation&&(this.socket=void 0,this.authenticatedBindingHash=void 0,this.state="idle",this.emit("disconnected",i.toString()||"connection closed"),1008!==e?!this.stopped&&this.options.authority.authorityLease&&this.scheduleReconnect():this.fenceAuthority(!o))})})}fenceAuthority(e){this.clearTimers(),this.authenticatedBindingHash=void 0,this.authorityEpochBindingHash=void 0,this.generation++;const t=this.socket;this.socket=void 0,this.state="idle",t&&t.readyState!==WebSocket.CLOSED&&t.terminate(),this.emit("authorityLost",{recoverable:e})}scheduleExpiryFence(e){this.expiryTimer&&clearTimeout(this.expiryTimer);const t=authorityBindingHash(e);this.expiryTimer=setTimeout(()=>{const e=this.options.authority.authorityLease;e?authorityBindingHash(e)===t&&(Date.parse(e.leaseExpiresAt)>(this.options.now??Date.now)()?this.scheduleExpiryFence(e):this.fenceAuthority(!0)):this.fenceAuthority(!0)},Math.min(2147483647,Math.max(0,Date.parse(e.leaseExpiresAt)-(this.options.now??Date.now)()))),this.expiryTimer.unref?.()}scheduleReconnect(){this.reconnectTimer||this.stopped||(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0;const e=this.options.authority.authorityLease;e&&this.queueTransition(()=>this.replaceConnection(e)).catch(e=>{this.emitError(e),this.scheduleReconnect()})},this.options.reconnectDelayMs??1e3),this.reconnectTimer.unref?.())}async closeSocket(e){const t=this.socket;this.socket=void 0,t&&t.readyState!==WebSocket.CLOSED&&(e&&t.readyState===WebSocket.OPEN?await new Promise(e=>{t.once("close",()=>e()),t.close()}):t.terminate())}queueTransition(e){const t=this.transition.then(e,e);return this.transition=t.catch(()=>{}),t}clearReconnectTimer(){this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0}clearTimers(){this.clearReconnectTimer(),this.expiryTimer&&clearTimeout(this.expiryTimer),this.expiryTimer=void 0}emitError(e){this.listenerCount("error")>0&&this.emit("error",e instanceof Error?e:new Error(String(e)))}}function authorityEpochHash(e){return createHash("sha256").update(`${e.instanceId}\0${e.leaseId}\0${e.handlerIdentity}\0${e.runtimeEpoch}`).digest("hex")}function authorityBindingHash(e){return createHash("sha256").update(`${e.instanceId}\0${e.leaseId}\0${e.handlerIdentity}\0${e.runtimeEpoch}\0${e.runtimeLeaseCredential}\0${e.leaseExpiresAt}`).digest("hex")}function isPositiveRuntimeEpoch(e){return"string"==typeof e&&/^[1-9][0-9]*$/.test(e)&&BigInt(e)<=18446744073709551615n}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beeos-claw",
|
|
3
|
-
"version": "0.6.66-cloud.
|
|
3
|
+
"version": "0.6.66-cloud.5",
|
|
4
4
|
"description": "OpenClaw plugin that bridges the BeeOS platform with the local OpenClaw Gateway, providing file transfer, ACP bridge, and observability.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "BeeOS <dev@beeos.ai>",
|
|
@@ -88,5 +88,5 @@
|
|
|
88
88
|
"fast-uri": ">=3.1.4",
|
|
89
89
|
"brace-expansion": ">=5.0.9"
|
|
90
90
|
},
|
|
91
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "2e2d94b544e224a005f81c54bf4ef728a730060c"
|
|
92
92
|
}
|