beeos-claw 0.5.86 → 0.5.87
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{listMcpServers,setMcpServer,unsetMcpServer,OpenClawCliError}from"../openclaw-cli.js";import{Errors}from"../errors/index.js";import{requireSecretFreeMcpServerName}from"./mcp-public-config-security.js";const RESTART_DEBOUNCE_MS=750;export class McpService{transport;logger;state;exit;restartTimer;list;set;unset;resolveDefinition;desiredState;desiredStateStarted=!1;constructor(e){this.transport=e.transport,this.logger=e.logger,this.state=e.state,this.exit=e.exit??(e=>process.exit(e)),this.list=e.list??listMcpServers,this.set=e.set??setMcpServer,this.unset=e.unset??unsetMcpServer,this.resolveDefinition=e.resolveDefinition,this.desiredState=e.desiredState}setRuntimeReceiptHistoryPort(e){this.desiredState?.setRuntimeReceiptHistoryPort(e)}async execute(e,t,r){const i=e;if("mcp.list"===i.name){if(this.desiredState){await this.ensureDesiredState();const e=await this.desiredState.list();if(e.servers.some(e=>void 0===e.config))throw new Error("Service MCP config is available only within its active operation");return{servers:e.servers.map(e=>({name:e.name,definitionRef:e.definitionRef,transport:e.config.transport,...e.config.url?{url:e.config.url}:{},...e.config.command?{command:e.config.command}:{},...e.config.args?{args:e.config.args}:{},...e.config.cwd?{cwd:e.config.cwd}:{},connected:e.connected,...e.config.connectionTimeoutMs?{connectionTimeoutMs:e.config.connectionTimeoutMs}:{}}))}}const e=await this.list();return{servers:Object.entries(e).map(([e,t])=>sanitizeMcpConfig(e,t))}}if(this.hasInFlightPrompts())throw new Error("PROMPT_IN_FLIGHT");if("service"===r.origin&&!this.desiredState)throw new Error("Service MCP mutations require the desired-state controller");if("mcp.set"===i.name){const e=i;requireSecretFreeMcpServerName(e.params.name);const t=r.resources.resolveMcpDefinition??("acp"===r.origin?this.resolveDefinition:void 0);if(!t)throw new Error("operation-scoped MCP definition resolver is not configured");const s=await t(e.params.definition);return this.desiredState?(await this.ensureDesiredState(),await this.desiredState.set(desiredServer(e.params.name,e.params.definition,publicConfig(s)),commitBinding(e,r)),{applied:!0,restartRequired:!1}):(await this.set(e.params.name,s),{applied:!0,restartRequired:!0})}const s=i.params.name;return requireSecretFreeMcpServerName(s),this.desiredState?(await this.ensureDesiredState(),await this.desiredState.unset(s,commitBinding(i,r)),{applied:!0,restartRequired:!1}):(await this.unset(s),{applied:!0,restartRequired:!0})}afterCommit(e){this.desiredState||"mcp.set"!==e.name&&"mcp.unset"!==e.name||this.scheduleRestart()}async projectCommitted(e,t,r){if(!this.desiredState||"mcp.set"!==e.name&&"mcp.unset"!==e.name)return;await this.ensureDesiredState();const i=e.params?.name;if("string"!=typeof i||!i)throw new Error("committed MCP projection lacks a server name");const s=r?"mcp.set"===e.name?{operationId:e.context.operationId,method:"mcp.set",source:"service"===r.origin?"service":"acp_local",paramsHash:e.context.paramsHash,runtimeEpoch:e.context.dispatchEpoch,expected:{name:i,definitionRef:e.params.definition.definitionRef,version:e.params.definition.version,sha256:e.params.definition.sha256,...e.params.definition.credentialRef?{credentialRef:e.params.definition.credentialRef}:{}}}:{operationId:e.context.operationId,method:"mcp.unset",source:"service"===r.origin?"service":"acp_local",paramsHash:e.context.paramsHash,runtimeEpoch:e.context.dispatchEpoch,expected:{name:i,absent:!0}}:void 0;let n;if("service"===r?.origin&&"mcp.set"===e.name){const t=e.params.definition,i=r.resources.resolveMcpDefinition;if(!i)throw new Error("operation-scoped MCP definition resolver is not configured");n={config:publicConfig(await i(t)),runtimeEpoch:r.runtimeEpoch,...r.resources.resolveMcpCredential?{credential:await r.resources.resolveMcpCredential(t)}:{}}}return n?await this.desiredState.project(i,r?.abortSignal,s,n):await this.desiredState.project(i,r?.abortSignal,s)}async removeCredentialIfUnreferenced(e){return!!this.desiredState&&(await this.desiredState.removeLocalCredentialIfUnreferenced(e),!0)}async handleList(e){try{if(this.desiredState){await this.ensureDesiredState();const t=await this.desiredState.list();return void this.transport.sendResult(e.id,{revision:t.revision,servers:t.servers})}const t=await this.list();this.transport.sendResult(e.id,{servers:t})}catch(t){this.logger.warn?.(`[mcp-service] list failed: ${t instanceof Error?t.message:t}`),this.sendMappedError(e,t,!0)}}async handleSet(e){const t=e.params,r=t?.name,i=t?.server;if(r&&i&&"object"==typeof i){if(!this.rejectIfInFlight(e))try{if(requireSecretFreeMcpServerName(r),this.desiredState){const t=asDesiredServer(r,i);return await this.ensureDesiredState(),await this.desiredState.set(t),await this.desiredState.project(r),this.logger.info?.(`[mcp-service] desired state applied name=${r}`),void this.transport.sendResult(e.id,{ok:!0,restarting:!1})}await this.set(r,i),this.logger.info?.(`[mcp-service] set applied name=${r}`),this.transport.sendResult(e.id,{ok:!0,restarting:!0}),this.scheduleRestart()}catch(t){this.logger.error?.(`[mcp-service] set failed name=${r}: ${t instanceof Error?t.message:t}`),this.sendMappedError(e,t,!1)}}else this.transport.sendAcpError(e.id,Errors.InvalidParams,{message:"Missing 'name' or 'server' config"})}async handleUnset(e){const t=e.params,r=t?.name;if(r){if(!this.rejectIfInFlight(e))try{if(requireSecretFreeMcpServerName(r),this.desiredState)return await this.ensureDesiredState(),await this.desiredState.unset(r),await this.desiredState.project(r),void this.transport.sendResult(e.id,{ok:!0,restarting:!1});await this.unset(r),this.logger.info?.(`[mcp-service] unset applied name=${r}`),this.transport.sendResult(e.id,{ok:!0,restarting:!0}),this.scheduleRestart()}catch(t){this.logger.error?.(`[mcp-service] unset failed name=${r}: ${t instanceof Error?t.message:t}`),this.sendMappedError(e,t,!1)}}else this.transport.sendAcpError(e.id,Errors.InvalidParams,{message:"Missing 'name'"})}hasInFlightPrompts(){for(const e of this.state.sessions.values())if(void 0!==e.pendingPromptId||void 0!==e.currentRunId)return!0;return!1}rejectIfInFlight(e){return!!this.hasInFlightPrompts()&&(this.transport.sendError(e.id,Errors.InvalidParams.rpcCode,"Agent is busy",{code:Errors.InvalidParams.code,reason:"PROMPT_IN_FLIGHT",message:"Agent is processing a message; please retry after it completes."}),!0)}scheduleRestart(){this.restartTimer&&clearTimeout(this.restartTimer),this.restartTimer=setTimeout(()=>{this.logger.info?.("[mcp-service] mcp change applied — exiting for container restart"),this.exit(0)},750)}async ensureDesiredState(){if(!this.desiredStateStarted){if(!this.desiredState)throw new Error("MCP desired-state controller is unavailable");await this.desiredState.start(),this.desiredStateStarted=!0}}async stop(){this.desiredState&&this.desiredStateStarted&&(this.desiredStateStarted=!1,await this.desiredState.stop())}sendMappedError(e,t,r){const i=cliErrToAcpError(t,r);this.transport.sendError(e.id,i.code,i.message,i.data)}}function desiredServer(e,t,r){return{name:e,definitionRef:t.definitionRef,version:t.version,sha256:t.sha256,...t.credentialRef?{credentialRef:t.credentialRef}:{},config:r}}function commitBinding(e,t){return{source:"service"===t.origin?"service":"acp_local",operationId:e.context.operationId,method:e.name,paramsHash:e.context.paramsHash,runtimeEpoch:e.context.dispatchEpoch}}function publicConfig(e){if(void 0!==e.headers||void 0!==e.env)throw new Error("resolved MCP secrets must not enter desired state");return{transport:e.transport??(e.command?"stdio":"streamable-http"),..."string"==typeof e.url?{url:e.url}:{},..."string"==typeof e.command?{command:e.command}:{},...Array.isArray(e.args)?{args:e.args}:{},..."string"==typeof e.cwd?{cwd:e.cwd}:{},..."number"==typeof e.connectionTimeoutMs?{connectionTimeoutMs:e.connectionTimeoutMs}:{}}}function asDesiredServer(e,t){const r=t;if("string"!=typeof r.definitionRef||"string"!=typeof r.version||"string"!=typeof r.sha256)throw new Error("ACP mcp/set requires a verified definitionRef, version and sha256");if(void 0!==r.headers||void 0!==r.env)throw new Error("ACP mcp/set accepts credentialRef, not resolved headers or env");return desiredServer(e,{definitionRef:r.definitionRef,version:r.version,sha256:r.sha256,..."string"==typeof r.credentialRef?{credentialRef:r.credentialRef}:{},..."number"==typeof r.connectionTimeoutMs?{connectionTimeoutMs:r.connectionTimeoutMs}:{}},publicConfig(t))}function sanitizeMcpConfig(e,t){const r=t.transport??(t.command?"stdio":"streamable-http");return{name:e,definitionRef:`runtime-mcp:${encodeURIComponent(e)}`,transport:r,..."number"==typeof t.connectionTimeoutMs?{connectionTimeoutMs:t.connectionTimeoutMs}:{},..."string"==typeof t.url?{url:t.url}:{},..."string"==typeof t.command?{command:t.command}:{},...Array.isArray(t.args)?{args:t.args}:{},..."string"==typeof t.cwd?{cwd:t.cwd}:{}}}export function cliErrToAcpError(e,t){if(e instanceof OpenClawCliError){const r=e.stderr??"";return null===e.exitCode||t?{code:Errors.InternalError.rpcCode,message:e.message,data:{code:Errors.InternalError.code}}:/No MCP server named/i.test(r)?{code:Errors.InvalidParams.rpcCode,message:e.message,data:{code:Errors.InvalidParams.code,reason:"NOT_FOUND"}}:{code:Errors.InvalidParams.rpcCode,message:e.message,data:{code:Errors.InvalidParams.code}}}return{code:Errors.InternalError.rpcCode,message:e instanceof Error?e.message:String(e),data:{code:Errors.InternalError.code}}}
|
|
1
|
+
import{listMcpServers,setMcpServer,unsetMcpServer,OpenClawCliError}from"../openclaw-cli.js";import{Errors}from"../errors/index.js";import{requireSecretFreeMcpServerName}from"./mcp-public-config-security.js";const RESTART_DEBOUNCE_MS=750;export class McpService{transport;logger;state;exit;restartTimer;list;set;unset;resolveDefinition;desiredState;desiredStateStarted=!1;constructor(e){this.transport=e.transport,this.logger=e.logger,this.state=e.state,this.exit=e.exit??(e=>process.exit(e)),this.list=e.list??listMcpServers,this.set=e.set??setMcpServer,this.unset=e.unset??unsetMcpServer,this.resolveDefinition=e.resolveDefinition,this.desiredState=e.desiredState}setRuntimeReceiptHistoryPort(e){this.desiredState?.setRuntimeReceiptHistoryPort(e)}async execute(e,t,r){const i=e;if("mcp.list"===i.name){if(this.desiredState){await this.ensureDesiredState();const e=await this.desiredState.list();if(e.servers.some(e=>void 0===e.config))throw new Error("Service MCP config is available only within its active operation");return{servers:e.servers.map(e=>({name:e.name,definitionRef:e.definitionRef,transport:e.config.transport,...e.config.url?{url:e.config.url}:{},...e.config.command?{command:e.config.command}:{},...e.config.args?{args:e.config.args}:{},...e.config.cwd?{cwd:e.config.cwd}:{},connected:e.connected,...e.config.connectionTimeoutMs?{connectionTimeoutMs:e.config.connectionTimeoutMs}:{}}))}}const e=await this.list();return{servers:Object.entries(e).map(([e,t])=>sanitizeMcpConfig(e,t))}}if(this.hasInFlightPrompts())throw new Error("PROMPT_IN_FLIGHT");if("service"===r.origin&&!this.desiredState)throw new Error("Service MCP mutations require the desired-state controller");if("mcp.set"===i.name){const e=i;requireSecretFreeMcpServerName(e.params.name);const t=r.resources.resolveMcpDefinition?.bind(r.resources)??("acp"===r.origin?this.resolveDefinition:void 0);if(!t)throw new Error("operation-scoped MCP definition resolver is not configured");const s=await t(e.params.definition);return this.desiredState?(await this.ensureDesiredState(),await this.desiredState.set(desiredServer(e.params.name,e.params.definition,publicConfig(s)),commitBinding(e,r)),{applied:!0,restartRequired:!1}):(await this.set(e.params.name,s),{applied:!0,restartRequired:!0})}const s=i.params.name;return requireSecretFreeMcpServerName(s),this.desiredState?(await this.ensureDesiredState(),await this.desiredState.unset(s,commitBinding(i,r)),{applied:!0,restartRequired:!1}):(await this.unset(s),{applied:!0,restartRequired:!0})}afterCommit(e){this.desiredState||"mcp.set"!==e.name&&"mcp.unset"!==e.name||this.scheduleRestart()}async projectCommitted(e,t,r){if(!this.desiredState||"mcp.set"!==e.name&&"mcp.unset"!==e.name)return;await this.ensureDesiredState();const i=e.params?.name;if("string"!=typeof i||!i)throw new Error("committed MCP projection lacks a server name");const s=r?"mcp.set"===e.name?{operationId:e.context.operationId,method:"mcp.set",source:"service"===r.origin?"service":"acp_local",paramsHash:e.context.paramsHash,runtimeEpoch:e.context.dispatchEpoch,expected:{name:i,definitionRef:e.params.definition.definitionRef,version:e.params.definition.version,sha256:e.params.definition.sha256,...e.params.definition.credentialRef?{credentialRef:e.params.definition.credentialRef}:{}}}:{operationId:e.context.operationId,method:"mcp.unset",source:"service"===r.origin?"service":"acp_local",paramsHash:e.context.paramsHash,runtimeEpoch:e.context.dispatchEpoch,expected:{name:i,absent:!0}}:void 0;let n;if("service"===r?.origin&&"mcp.set"===e.name){const t=e.params.definition,i=r.resources.resolveMcpDefinition?.bind(r.resources);if(!i)throw new Error("operation-scoped MCP definition resolver is not configured");n={config:publicConfig(await i(t)),runtimeEpoch:r.runtimeEpoch,...r.resources.resolveMcpCredential?{credential:await r.resources.resolveMcpCredential(t)}:{}}}return n?await this.desiredState.project(i,r?.abortSignal,s,n):await this.desiredState.project(i,r?.abortSignal,s)}async removeCredentialIfUnreferenced(e){return!!this.desiredState&&(await this.desiredState.removeLocalCredentialIfUnreferenced(e),!0)}async handleList(e){try{if(this.desiredState){await this.ensureDesiredState();const t=await this.desiredState.list();return void this.transport.sendResult(e.id,{revision:t.revision,servers:t.servers})}const t=await this.list();this.transport.sendResult(e.id,{servers:t})}catch(t){this.logger.warn?.(`[mcp-service] list failed: ${t instanceof Error?t.message:t}`),this.sendMappedError(e,t,!0)}}async handleSet(e){const t=e.params,r=t?.name,i=t?.server;if(r&&i&&"object"==typeof i){if(!this.rejectIfInFlight(e))try{if(requireSecretFreeMcpServerName(r),this.desiredState){const t=asDesiredServer(r,i);return await this.ensureDesiredState(),await this.desiredState.set(t),await this.desiredState.project(r),this.logger.info?.(`[mcp-service] desired state applied name=${r}`),void this.transport.sendResult(e.id,{ok:!0,restarting:!1})}await this.set(r,i),this.logger.info?.(`[mcp-service] set applied name=${r}`),this.transport.sendResult(e.id,{ok:!0,restarting:!0}),this.scheduleRestart()}catch(t){this.logger.error?.(`[mcp-service] set failed name=${r}: ${t instanceof Error?t.message:t}`),this.sendMappedError(e,t,!1)}}else this.transport.sendAcpError(e.id,Errors.InvalidParams,{message:"Missing 'name' or 'server' config"})}async handleUnset(e){const t=e.params,r=t?.name;if(r){if(!this.rejectIfInFlight(e))try{if(requireSecretFreeMcpServerName(r),this.desiredState)return await this.ensureDesiredState(),await this.desiredState.unset(r),await this.desiredState.project(r),void this.transport.sendResult(e.id,{ok:!0,restarting:!1});await this.unset(r),this.logger.info?.(`[mcp-service] unset applied name=${r}`),this.transport.sendResult(e.id,{ok:!0,restarting:!0}),this.scheduleRestart()}catch(t){this.logger.error?.(`[mcp-service] unset failed name=${r}: ${t instanceof Error?t.message:t}`),this.sendMappedError(e,t,!1)}}else this.transport.sendAcpError(e.id,Errors.InvalidParams,{message:"Missing 'name'"})}hasInFlightPrompts(){for(const e of this.state.sessions.values())if(void 0!==e.pendingPromptId||void 0!==e.currentRunId)return!0;return!1}rejectIfInFlight(e){return!!this.hasInFlightPrompts()&&(this.transport.sendError(e.id,Errors.InvalidParams.rpcCode,"Agent is busy",{code:Errors.InvalidParams.code,reason:"PROMPT_IN_FLIGHT",message:"Agent is processing a message; please retry after it completes."}),!0)}scheduleRestart(){this.restartTimer&&clearTimeout(this.restartTimer),this.restartTimer=setTimeout(()=>{this.logger.info?.("[mcp-service] mcp change applied — exiting for container restart"),this.exit(0)},750)}async ensureDesiredState(){if(!this.desiredStateStarted){if(!this.desiredState)throw new Error("MCP desired-state controller is unavailable");await this.desiredState.start(),this.desiredStateStarted=!0}}async stop(){this.desiredState&&this.desiredStateStarted&&(this.desiredStateStarted=!1,await this.desiredState.stop())}sendMappedError(e,t,r){const i=cliErrToAcpError(t,r);this.transport.sendError(e.id,i.code,i.message,i.data)}}function desiredServer(e,t,r){return{name:e,definitionRef:t.definitionRef,version:t.version,sha256:t.sha256,...t.credentialRef?{credentialRef:t.credentialRef}:{},config:r}}function commitBinding(e,t){return{source:"service"===t.origin?"service":"acp_local",operationId:e.context.operationId,method:e.name,paramsHash:e.context.paramsHash,runtimeEpoch:e.context.dispatchEpoch}}function publicConfig(e){if(void 0!==e.headers||void 0!==e.env)throw new Error("resolved MCP secrets must not enter desired state");return{transport:e.transport??(e.command?"stdio":"streamable-http"),..."string"==typeof e.url?{url:e.url}:{},..."string"==typeof e.command?{command:e.command}:{},...Array.isArray(e.args)?{args:e.args}:{},..."string"==typeof e.cwd?{cwd:e.cwd}:{},..."number"==typeof e.connectionTimeoutMs?{connectionTimeoutMs:e.connectionTimeoutMs}:{}}}function asDesiredServer(e,t){const r=t;if("string"!=typeof r.definitionRef||"string"!=typeof r.version||"string"!=typeof r.sha256)throw new Error("ACP mcp/set requires a verified definitionRef, version and sha256");if(void 0!==r.headers||void 0!==r.env)throw new Error("ACP mcp/set accepts credentialRef, not resolved headers or env");return desiredServer(e,{definitionRef:r.definitionRef,version:r.version,sha256:r.sha256,..."string"==typeof r.credentialRef?{credentialRef:r.credentialRef}:{},..."number"==typeof r.connectionTimeoutMs?{connectionTimeoutMs:r.connectionTimeoutMs}:{}},publicConfig(t))}function sanitizeMcpConfig(e,t){const r=t.transport??(t.command?"stdio":"streamable-http");return{name:e,definitionRef:`runtime-mcp:${encodeURIComponent(e)}`,transport:r,..."number"==typeof t.connectionTimeoutMs?{connectionTimeoutMs:t.connectionTimeoutMs}:{},..."string"==typeof t.url?{url:t.url}:{},..."string"==typeof t.command?{command:t.command}:{},...Array.isArray(t.args)?{args:t.args}:{},..."string"==typeof t.cwd?{cwd:t.cwd}:{}}}export function cliErrToAcpError(e,t){if(e instanceof OpenClawCliError){const r=e.stderr??"";return null===e.exitCode||t?{code:Errors.InternalError.rpcCode,message:e.message,data:{code:Errors.InternalError.code}}:/No MCP server named/i.test(r)?{code:Errors.InvalidParams.rpcCode,message:e.message,data:{code:Errors.InvalidParams.code,reason:"NOT_FOUND"}}:{code:Errors.InvalidParams.rpcCode,message:e.message,data:{code:Errors.InvalidParams.code}}}return{code:Errors.InternalError.rpcCode,message:e instanceof Error?e.message:String(e),data:{code:Errors.InternalError.code}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION}from"@beeos-ai/beeos-types/runtime";import{parseAndValidateTemplatePackage}from"../acp-gateway/agent-template-package.js";import{HttpRuntimeOperationResourceResolver,RuntimeResourceResolutionError}from"./runtime-operation-resource-resolver.js";import{MessageServiceRuntimeMessageChannel}from"./message-service-runtime-message-channel.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{RuntimeJwksVerifier}from"./runtime-jwks-verifier.js";import{GatewayGrantJwksVerifier}from"./split-runtime-authorization-verifier.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,{agentGatewayUrl:new URL(e.agentGatewayUrl).toString()})}}export class AgentGatewaySplitJwksReadinessAdapter extends AgentGatewayGrantJwksReadinessAdapter{}const transportOptions=new WeakMap;export class RuntimeServiceTransportReadinessAdapter{constructor(e){transportOptions.set(this,{messageService:e.messageService,scopedDeliveryKey:e.scopedDeliveryKey,agentGatewayUrl:new URL(e.agentGatewayUrl).toString(),boundAgentFetch:e.boundAgentFetch})}}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])};let t;if(e.authorizationAdapter)try{t=await probeGatewayGrantJwks(e.authorizationAdapter)}catch{}const r=e.transportAdapter?transportOptions.get(e.transportAdapter):void 0;if(!r)return{status:"unavailable",blockers:Object.freeze([TRANSPORT_BLOCKER,...t?[]:[JWKS_BLOCKER]])};if(!t)return{status:"unavailable",blockers:Object.freeze([JWKS_BLOCKER])};try{const n=await r.messageService.ready(),a=new MessageServiceRuntimeMessageChannel({serviceUrl:n.serviceUrl,transport:r.messageService,scopedDeliveryKey:r.scopedDeliveryKey}),i=runtimeMethods(),s=e.attemptPorts??runtimeMessageAttemptPorts(r,n.serviceUrl);return{status:"ready",blockers:[],capabilityBlockers:CAPABILITY_BLOCKERS,serviceMethods:i,factory:new MsRuntimeMessageChannelConsumerFactory({channel:a,verifier:t,ports:s,journal:e.commandJournal,allowedMethods:new Set(i),options:{poisonJournal:e.poisonJournal,...e.onConsumerDeliveryError?{onDeliveryError:e.onConsumerDeliveryError}:{},...e.onConsumerRequestTerminalAccepted?{onRequestTerminalAccepted:e.onConsumerRequestTerminalAccepted}:{},...e.onConsumerRequestAcknowledged?{onRequestAcknowledged:e.onConsumerRequestAcknowledged}:{}}}),...void 0===e.attemptPorts?{resourceBindingContractRevision:RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION}:{}}}catch{return{status:"unavailable",blockers:Object.freeze([TRANSPORT_BLOCKER])}}}async function probeGatewayGrantJwks(e){const t=grantAdapterOptions.get(e);if(!t)throw new Error("untrusted Gateway grant readiness adapter");const r=t.agentGatewayUrl.replace(/\/+$/,""),n=new GatewayGrantJwksVerifier(new RuntimeJwksVerifier(`${r}/.well-known/runtime-execution-grant-jwks.json`));return await n.refresh(!0),n}export function runtimeMessageAttemptPorts(e,t){const r=new MessageServiceConversationClearHttpAuthority({messageServiceUrl:t,fetchAuthorized:async(t,r)=>await e.messageService.fetch(t,r)})
|
|
1
|
+
import{RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION}from"@beeos-ai/beeos-types/runtime";import{parseAndValidateTemplatePackage}from"../acp-gateway/agent-template-package.js";import{HttpRuntimeOperationResourceResolver,RuntimeResourceResolutionError}from"./runtime-operation-resource-resolver.js";import{MessageServiceRuntimeMessageChannel}from"./message-service-runtime-message-channel.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{RuntimeJwksVerifier}from"./runtime-jwks-verifier.js";import{GatewayGrantJwksVerifier}from"./split-runtime-authorization-verifier.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,{agentGatewayUrl:new URL(e.agentGatewayUrl).toString()})}}export class AgentGatewaySplitJwksReadinessAdapter extends AgentGatewayGrantJwksReadinessAdapter{}const transportOptions=new WeakMap;export class RuntimeServiceTransportReadinessAdapter{constructor(e){transportOptions.set(this,{messageService:e.messageService,scopedDeliveryKey:e.scopedDeliveryKey,agentGatewayUrl:new URL(e.agentGatewayUrl).toString(),boundAgentFetch:e.boundAgentFetch})}}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])};let t;if(e.authorizationAdapter)try{t=await probeGatewayGrantJwks(e.authorizationAdapter)}catch{}const r=e.transportAdapter?transportOptions.get(e.transportAdapter):void 0;if(!r)return{status:"unavailable",blockers:Object.freeze([TRANSPORT_BLOCKER,...t?[]:[JWKS_BLOCKER]])};if(!t)return{status:"unavailable",blockers:Object.freeze([JWKS_BLOCKER])};try{const n=await r.messageService.ready(),a=new MessageServiceRuntimeMessageChannel({serviceUrl:n.serviceUrl,transport:r.messageService,scopedDeliveryKey:r.scopedDeliveryKey}),i=runtimeMethods(),s=e.attemptPorts??runtimeMessageAttemptPorts(r,n.serviceUrl);return{status:"ready",blockers:[],capabilityBlockers:CAPABILITY_BLOCKERS,serviceMethods:i,factory:new MsRuntimeMessageChannelConsumerFactory({channel:a,verifier:t,ports:s,journal:e.commandJournal,allowedMethods:new Set(i),options:{poisonJournal:e.poisonJournal,...e.onConsumerDeliveryError?{onDeliveryError:e.onConsumerDeliveryError}:{},...e.onConsumerRequestTerminalAccepted?{onRequestTerminalAccepted:e.onConsumerRequestTerminalAccepted}:{},...e.onConsumerRequestAcknowledged?{onRequestAcknowledged:e.onConsumerRequestAcknowledged}:{}}}),...void 0===e.attemptPorts?{resourceBindingContractRevision:RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION}:{}}}catch{return{status:"unavailable",blockers:Object.freeze([TRANSPORT_BLOCKER])}}}async function probeGatewayGrantJwks(e){const t=grantAdapterOptions.get(e);if(!t)throw new Error("untrusted Gateway grant readiness adapter");const r=t.agentGatewayUrl.replace(/\/+$/,""),n=new GatewayGrantJwksVerifier(new RuntimeJwksVerifier(`${r}/.well-known/runtime-execution-grant-jwks.json`));return await n.refresh(!0),n}export function runtimeMessageAttemptPorts(e,t){const r=new MessageServiceConversationClearHttpAuthority({messageServiceUrl:t,fetchAuthorized:async(t,r)=>await e.messageService.fetch(t,r)});return{async resolve({request:n,command:a,executionGrant:i,getLease:s,journalRecord:o,abortSignal:c}){const u="skills.install"===a.name||"agent.applyTemplate"===a.name?a.params.artifact:void 0,d="mcp.set"===a.name?a.params.definition:void 0;if((u||d)&&(n.resourceBindingContractRevision!==RUNTIME_RESOURCE_BINDING_CONTRACT_REVISION||!n.resourceBindings))throw new RuntimeResourceResolutionError("resolution_rejected","resource-bound Service delivery requires the Types 4.1 binding carrier");const m=new HttpRuntimeOperationResourceResolver({gatewayUrl:e.agentGatewayUrl,operationId:n.operationId,requestMessageId:n.requestMessageId,instanceId:n.instanceId,paramsHash:n.paramsHash,bindings:n.resourceBindings??[],getAuthorization:()=>{const e=s();return{executionGrant:i,runtimeLeaseCredential:e.runtimeLeaseCredential,fence:deliveryFence(n,e)}},fetchAuthorized:async(t,r)=>await e.boundAgentFetch(t,r??{}),parseSkillArtifact:e=>parseAndValidateTemplatePackage(Buffer.from(e)),signal:c});if("prepared"!==o.phase&&"started"!==o.phase||(u&&await m.readVerifiedArtifact(u),d&&await m.resolveMcpDefinition(d)),"session.setModel"===a.name)return{resources:m,sessionModelProjection:{project:async({conversationId:r,modelOverrideId:a})=>{const i=s(),o=new MessageServiceSessionModelHttpAuthority({messageServiceUrl:t,fetchAuthorized:async(t,r)=>await e.messageService.fetchRuntimeChannel(t,{runtimeLeaseCredential:i.runtimeLeaseCredential,scopedDeliveryKey:e.scopedDeliveryKey},r)});return await o.project({conversationId:r,operationId:n.operationId,requestMessageId:n.requestMessageId,requestHash:n.requestHash,modelOverrideId:a,runtimeLeaseCredential:i.runtimeLeaseCredential})}}};if("session.clear"!==a.name)return{resources:m};const l=a.context.conversation,p=s();return{resources:m,historyBoundary:new MessageServiceConversationHistoryBoundary({operationId:n.operationId,requestMessageId:n.requestMessageId,expectedGeneration:await r.currentGeneration(l.runtimeConversationUid),fence:deliveryFence(n,p),authority:r})}}}}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 deliveryFence(e,t){if(t.handlerIdentity!==e.runtimeHandlerIdentity||t.runtimeEpoch!==e.dispatchEpoch)throw new Error("runtime delivery fence does not match the retained request");return{claimId:e.requestMessageId,handlerIdentity:t.handlerIdentity,runtimeEpoch:t.runtimeEpoch,fencingToken:t.runtimeEpoch,journalStoreId:t.handlerIdentity,journalGeneration:t.runtimeEpoch}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beeos-claw",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.87",
|
|
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>",
|
|
@@ -78,5 +78,8 @@
|
|
|
78
78
|
"terser": "^5.39.0",
|
|
79
79
|
"typescript": "^5.6.3",
|
|
80
80
|
"vitest": "^4.1.0"
|
|
81
|
+
},
|
|
82
|
+
"overrides": {
|
|
83
|
+
"fast-uri": ">=3.1.4"
|
|
81
84
|
}
|
|
82
85
|
}
|