beeos-claw 0.6.87 → 0.6.91
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/README.md +66 -6
- package/dist/acp-gateway/gateway-events.js +1 -1
- package/dist/acp-gateway/history-artifact-hydrator.js +1 -1
- package/dist/acp-gateway/history-replay.js +1 -1
- package/dist/acp-gateway/local-session-history.js +1 -1
- package/dist/canvas/html-delivery.js +1 -1
- package/dist/canvas/runtime-lease-token.js +1 -0
- package/dist/canvas/tools.js +1 -1
- package/dist/canvas-orchestrator.js +1 -1
- package/dist/index.js +1 -1
- package/dist/message-sanitization/transport-metadata-sanitizer.js +1 -1
- package/dist/runtime/agent-runtime-failure-classifier.js +1 -1
- package/dist/runtime/central-native-composition.js +1 -0
- package/dist/runtime/central-native-context-engine.js +1 -0
- package/dist/runtime/central-native-credentials.js +1 -0
- package/dist/runtime/central-native-delta.js +1 -0
- package/dist/runtime/central-native-host.js +1 -0
- package/dist/runtime/central-native-interactions.js +1 -0
- package/dist/runtime/central-native-memory.js +1 -0
- package/dist/runtime/central-native-pending-journal.js +1 -0
- package/dist/runtime/central-native-production.js +1 -0
- package/dist/runtime/central-native-response.js +1 -0
- package/dist/runtime/central-native-runtime.js +1 -0
- package/dist/runtime/central-native-titles.js +1 -0
- package/dist/runtime/central-session-key.js +1 -0
- package/dist/runtime/conversation-title.js +1 -1
- package/dist/runtime/identity-lane-lease.js +1 -0
- package/dist/runtime/im-reply-sink.js +1 -1
- package/dist/runtime/ms-runtime-message-channel-adapter.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/openclaw-session-write-quiescence.js +1 -1
- package/dist/runtime/reply-router.js +1 -1
- package/dist/runtime/runtime-command-journal.js +1 -1
- package/dist/runtime/runtime-production-authority.js +1 -1
- package/dist/runtime/runtime-service-contract-compatibility.js +1 -1
- package/dist/runtime/runtime-service-production-candidate.js +1 -1
- package/dist/runtime/sandbox-native-activation.js +1 -0
- package/dist/runtime/sandbox-native-credentials.js +1 -0
- package/dist/runtime/sandbox-native-execution-resolver.js +1 -0
- package/dist/runtime/session-mutation-coordinator.js +1 -1
- package/dist/terminal/runtime-terminal-outbound-registration.js +1 -1
- package/dist/terminal/session-manager.js +1 -1
- package/dist/terminal/standalone-runtime-terminal.js +1 -0
- package/dist/upload/native-output-tool-hook.js +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -4
- package/runtime-service-wire-identity.v1.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{harnessConnectorToolCaller}from"./connectors/harness-connector-mcp.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{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,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;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)=>{"ask_user"===(e.toolName||t.toolName)&&sharedQuestionBridge.observeAskUser({sessionKey:t.sessionKey,runId:t.runId??e.runId,toolCallId:t.toolCallId??e.toolCallId})}),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 i=agentKeys?Buffer.from(agentKeys.publicKey).toString("base64"):void 0,s=join(process.env.OPENCLAW_HOME||join(homedir(),".openclaw"),"beeos"),l=sharedInboundExecutionJournal??=new FileInboundExecutionJournal(join(s,"inbound-execution-journal.v1.jsonl"));sharedMcpProjection??=new OpenClawNativeMcpProjection,!sharedMcpCredentialVault&&agentKeys&&i&&(sharedMcpCredentialVault=new LocalEncryptedCredentialReferenceVault(join(s,"mcp-credential-vault.json"),i,agentKeys.privateKey));const c=pluginCloudRuntimeTarget(e);if(setClaimedCloudRuntimeInstanceId(c),c&&(!agentKeys||!agentGateway))throw new Error("Cloud runtime authority requires an agent identity and gateway transport");const u=sharedRuntimeAuthority?.cloudTargetInstanceId;if(u&&c&&u!==c)throw new Error("Cloud runtime authority target changed during process lifetime");if(sharedRuntimeAuthority&&!u&&c&&sharedRuntimeAuthority.bindCloudTarget(c),!sharedRuntimeAuthority&&agentKeys&&agentGateway&&(sharedRuntimeAuthority=new RuntimeProductionAuthority({stateDirectory:s,gateway:agentGateway,keys:agentKeys,targetInstanceId:c,logger:e.logger,getMSConnectionStatus:e=>sharedMSConnectionStatus.get(e)})),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 d=sharedRuntimeOwner;sharedSessionMutationCoordinator??=new SessionMutationCoordinator(sharedSessionWriteGate,new OpenClawSessionWriteQuiescence(e.logger,{agentId:o.gateway.agentId||"main"}),e.logger,{onRecoveryRequired:t=>{scheduleProcessRuntimeRestart(t,e.logger)}});const g=sharedSessionMutationCoordinator;if(!sharedAcpServer){const t=sharedRuntimeAuthority&&agentGateway?new AgentGatewayTemplateOriginReporter({gateway:agentGateway}):void 0;sharedAcpServer=new ACPServer(o,e.logger,g,a,agentGateway??void 0,i,n,sharedTerminalManager,sharedRuntimeAuthority,void 0,sharedMcpProjection,sharedMcpCredentialVault,{gateway:d.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,m=()=>sharedAgentMappings.snapshot()?.values().next().value;r.current=p,sharedMcpNativeProjectionNudge.request({registrationMode:e.registrationMode,fingerprint:fingerprintMcpServers(t.openclawConfig),logger:e.logger});const h=sharedPromptRunStore,{enabled:y,principalId:v,a2aEnabled:f}=o.messageBus;let w;!c&&o.agentGatewayUrl&&agentKeys&&(w=createBeeosClawMessageTokenProvider({agentGatewayUrl:o.agentGatewayUrl,identity:agentKeyPairToIdentity(agentKeys)}));const C=process.env.MESSAGE_RUNTIME_DELIVERY_KEY?.trim(),R=v||process.env.BEEOS_PRINCIPAL_ID||"",b=w?sharedMessageClientOwner.configure({tokenProvider:w,identityId:R,...o.messageBus.serviceUrl?{serviceUrl:o.messageBus.serviceUrl}:{},logger:e.logger,...sharedRuntimeAuthority&&C?{runtimeDelivery:{scopedDeliveryKey:C,authority:{currentLease:()=>{const e=sharedRuntimeAuthority?.authorityLease,t=sharedRuntimeAuthority?.currentConsumerBinding();return e&&t?{...e,journalStoreId:t.journalStoreId,journalGeneration:t.journalGeneration}:null}}}}:{}}):void 0,S=c&&o.messageBus.serviceUrl&&sharedRuntimeAuthority?new NodeRuntimeDeliveryPort({serviceOrigin:async()=>o.messageBus.serviceUrl},{currentLease:()=>{const e=sharedRuntimeAuthority?.authorityLease,t=sharedRuntimeAuthority?.currentConsumerBinding();return e&&t&&e.instanceId===c?{...e,journalStoreId:t.journalStoreId,journalGeneration:t.journalGeneration}:null},subscribeAuthority:e=>sharedRuntimeAuthority.subscribeAuthority(e)}):void 0;attachNativeCloudChat(e,o);const _=sharedRuntimeAuthority,O=o.messageBus.serviceUrl;b&&_&&O&&C?p.setCronConversationDelivery({deliver:async e=>{const t=_.authorityLease;if(!t)throw new Error("current runtime authority lease unavailable for cron delivery");const r=new MessageServiceCronDeliveryHttpAuthority({messageServiceUrl:O,scopedDeliveryKey:C,fetchAuthorized:(e,t)=>fetchRuntimeLeaseAttempt(e,t??{})});return await r.deliver({...e,runtimeLeaseCredential:t.runtimeLeaseCredential})}}):p.setCronConversationDelivery(void 0);const E=sharedRuntimeAuthority?.journal??new FileRuntimeCommandJournal(join(s,"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)}`)}),A=d.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)}`)},...b&&agentGateway&&C?{transportAdapter:new RuntimeServiceTransportReadinessAdapter({gateway:agentGateway,messageService:b.nodeTransport,messageClient:b.client,configuredServiceUrl:o.messageBus.serviceUrl,scopedDeliveryKey:C})}:{},...S&&agentGateway&&o.messageBus.serviceUrl?{cloudTransportAdapter:new CloudRuntimeServiceTransportReadinessAdapter({gateway:agentGateway,configuredServiceUrl:o.messageBus.serviceUrl,runtimeDelivery:S,...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=>S.startConversationRun(e),finish:e=>S.finishConversationRun(e)}}),host:{htmlDeliveryRequired: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:h,assistantMessageCommitRouter:sharedAssistantMessageCommitRouter,toolResultObservationRouter:sharedToolResultObservationRouter,approvalStreams:sharedApprovalBridge,questionStreams:sharedQuestionBridge,modelCallObservationRouter:sharedModelCallObservationRouter,sessionMutationCoordinator:g,abortTransport:{chatAbort:(e,t)=>p.chatAbort(e,t)},activeRunAuthority:p.getActiveRunAuthority(),waitIfExclusive:(t,r)=>sharedImHotPathDeferral.waitIfExclusive(t,e.logger,r).then(()=>{})}}}:{}})}:{},commandJournal:E,poisonJournal:new FileRuntimePoisonDeliveryJournal(join(s,"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 d.acquire(A);try{await p.start(o.bridge.url||void 0)}catch(e){throw await d.release(A),e}e.logger.info?.(`[beeos-claw] ACP Server started (total service start: ${Date.now()-t}ms)`)},async stop(){try{await d.release(A)}finally{await p.stop()}await E.checkpoint(),e.logger.info?.("[runtime-service] command journal checkpoint completed"),e.logger.info?.("[beeos-claw] ACP Server stopped")}});if(y&&void 0!==w&&w){const t=sharedMessageClientOwner.createRegistrationToken(),r=async(e,t)=>{const r=await w(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,c={leaseId:n.leaseId,runtimeEpoch:n.runtimeEpoch};sharedMSConnectionStatus.bind(c);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:h,waitIfExclusive:(t,r)=>sharedImHotPathDeferral.waitIfExclusive(t,e.logger,r).then(()=>{}),assistantMessageCommitRouter:sharedAssistantMessageCommitRouter,toolResultObservationRouter:sharedToolResultObservationRouter,approvalStreams:sharedApprovalBridge,questionStreams:sharedQuestionBridge,modelCallObservationRouter:sharedModelCallObservationRouter,sessionMutationCoordinator:g,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:l,logger:e.logger}),m=sharedAgentMappings.subscribe(()=>{sharedActiveMessageConsumer===d&&d.refresh()}),y=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 f=s.getSnapshot().connection;sharedMSConnectionStatus.setIfCurrent(c,f);const w=s.subscribe(()=>{const t=s.getSnapshot();t.connection!==f&&(f=t.connection,sharedMSConnectionStatus.setIfCurrent(c,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(c),v.dispose(),await d.stop(),m(),y(),w(),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(c),v.dispose(),await d.stop(),y(),w(),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 y?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=${y})`);if(o.messageBus.enabled&&c&&!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,()=>m()?.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=m();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=()=>agentGateway.canvas.token(),a=a=>{const n=new CanvasRelayClient({canvasRelayUrl:o.canvasRelayUrl,agentKeys:agentKeys,agentId:a.id,displayName:a.displayName,avatarUrl:a.avatarUrl,tokenProvider:r,onConnected:()=>p.flushPendingCanvasLinks(),onReconnect:()=>p.onRelayReconnected(),logger:e.logger});t.setRelayClient(n),t.setAgentId(a.id),p.wireRelayActionHandler(),n.connect(),e.logger.info?.(`[beeos-claw] Canvas Relay multiplexed client connected (agentId=${a.id}, name=${a.name??"none"})`)};e.registerService(createCanvasRelayService({getAgent:m,onceAgentReady:e=>sharedAgentMappings.onceReady(e),initRelay:a,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),h=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),!h.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}`)}}function pluginCloudRuntimeTarget(e){const t=e.pluginConfig?.cloudRuntimeInstanceId;return cloudRuntimeTargetInstanceId("string"==typeof t?t:void 0)}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;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{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:f,a2aEnabled:w}=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=f||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 _=sharedRuntimeAuthority,O=o.messageBus.serviceUrl;S&&_&&O&&R?p.setCronConversationDelivery({deliver:async e=>{const t=_.authorityLease;if(!t)throw new Error("current runtime authority lease unavailable for cron delivery");const r=new MessageServiceCronDeliveryHttpAuthority({messageServiceUrl:O,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 f=s.getSnapshot().connection;sharedMSConnectionStatus.setIfCurrent(l,f);const w=s.subscribe(()=>{const t=s.getSnapshot();t.connection!==f&&(f=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(),w(),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(),w(),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!==w&&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));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
|
-
const WEEKDAY=String.raw`(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)`,DATE=String.raw`\d{4}-\d{2}-\d{2}`,CLOCK=String.raw`\d{1,2}:\d{2}(?::\d{2})?`,TIMEZONE=String.raw`(?:UTC|GMT[+-]\d{1,2}(?::?\d{2})?)`,TIMESTAMP_PREFIX_RE=new RegExp(String.raw`^\s*\[${WEEKDAY}\s+${DATE}\s+${CLOCK}\s+${TIMEZONE}\]\s*`,"i"),NESTED_TIME_PREFIX_RE=new RegExp(String.raw`^\s*\[Time:\s*\[${DATE}\s+${WEEKDAY}\s+${CLOCK}\s+${TIMEZONE}\]\]\s*`,"i"),WORKDIR_PREFIX_RE=/^\s*\[working directory:[^\]]*]\s*/i,MESSAGE_ID_PREFIX_RE=/^\s*\[message_id:[^\]]*]\s*/i,SENDER_SHORT_ID_PREFIX_RE=/^\s*\[sender_short_id:[^\]]*]\s*/i,REPLY_TO_CURRENT_PREFIX_RE=/^\s*\[reply_to_current:[^\]]*]\s*/i,USER_MESSAGE_MARKER_PREFIX_RE=/^\s*(?:User Message From|Message From)\s+[A-Za-z0-9_-]+(?:\s+Group Chat Room)?:\s*/i,HEARTBEAT_OK_LINE="HEARTBEAT_OK",HEARTBEAT_OK_LINE_RE=/^[\s\p{P}\p{S}]*HEARTBEAT_OK[\s\p{P}\p{S}]*$/u,UNSUPPORTED_BEEOS_MEDIA_DIRECTIVE_RE
|
|
1
|
+
const WEEKDAY=String.raw`(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)`,DATE=String.raw`\d{4}-\d{2}-\d{2}`,CLOCK=String.raw`\d{1,2}:\d{2}(?::\d{2})?`,TIMEZONE=String.raw`(?:UTC|GMT[+-]\d{1,2}(?::?\d{2})?)`,TIMESTAMP_PREFIX_RE=new RegExp(String.raw`^\s*\[${WEEKDAY}\s+${DATE}\s+${CLOCK}\s+${TIMEZONE}\]\s*`,"i"),NESTED_TIME_PREFIX_RE=new RegExp(String.raw`^\s*\[Time:\s*\[${DATE}\s+${WEEKDAY}\s+${CLOCK}\s+${TIMEZONE}\]\]\s*`,"i"),WORKDIR_PREFIX_RE=/^\s*\[working directory:[^\]]*]\s*/i,MESSAGE_ID_PREFIX_RE=/^\s*\[message_id:[^\]]*]\s*/i,SENDER_SHORT_ID_PREFIX_RE=/^\s*\[sender_short_id:[^\]]*]\s*/i,REPLY_TO_CURRENT_PREFIX_RE=/^\s*\[reply_to_current:[^\]]*]\s*/i,USER_MESSAGE_MARKER_PREFIX_RE=/^\s*(?:User Message From|Message From)\s+[A-Za-z0-9_-]+(?:\s+Group Chat Room)?:\s*/i,HEARTBEAT_OK_LINE="HEARTBEAT_OK",HEARTBEAT_OK_LINE_RE=/^[\s\p{P}\p{S}]*HEARTBEAT_OK[\s\p{P}\p{S}]*$/u,UNSUPPORTED_BEEOS_MEDIA_DIRECTIVE_RE=/^ {0,3}MEDIA[ \t]*:[ \t]*beeos-file:\/\/[^\s)]+[ \t]*$/i;function couldBeMediaDirective(e){if(/^(?: {4}| *\t)/.test(e))return!1;let t=e.trimStart().toLowerCase();for(const e of["media",":","beeos-file://"]){if(e.startsWith(t))return!0;if(!t.startsWith(e))return!1;t=t.slice(e.length),"beeos-file://"!==e&&(t=t.replace(/^[ \t]*/,""))}return/^[^\s)]*[ \t]*$/.test(t)}export class BeeosMediaDirectiveStream{line="";emitted=0;fence;skipLF=!1;write(e){if(!e)return"";this.skipLF&&e.startsWith("\n")&&(e=e.slice(1)),this.skipLF=e.endsWith("\r");const t=normalizeLineEndings(e).split("\n");let n="";for(let e=0;e<t.length;e++)this.line+=t[e],e<t.length-1?n+=this.finishLine("\n"):!this.fence&&couldBeMediaDirective(this.line)||(n+=this.line.slice(this.emitted),this.emitted=this.line.length);return n}finish(){return this.finishLine("")}finishLine(e){const t=!this.fence&&UNSUPPORTED_BEEOS_MEDIA_DIRECTIVE_RE.test(this.line)?"":this.line.slice(this.emitted)+e,n=/^ {0,3}(`{3,}|~{3,})(.*)$/.exec(this.line);return n&&(this.fence||"`"===n[1][0]&&n[2].includes("`")?this.fence&&n[1][0]===this.fence[0]&&n[1].length>=this.fence.length&&!n[2].trim()&&(this.fence=void 0):this.fence=n[1]),this.line="",this.emitted=0,t}}const METADATA_PREFIX_PATTERNS=[TIMESTAMP_PREFIX_RE,NESTED_TIME_PREFIX_RE,WORKDIR_PREFIX_RE,MESSAGE_ID_PREFIX_RE,SENDER_SHORT_ID_PREFIX_RE,REPLY_TO_CURRENT_PREFIX_RE,USER_MESSAGE_MARKER_PREFIX_RE],CONVERSATION_INFO_MARKER="Conversation info (untrusted metadata):",SENDER_UNTRUSTED_MARKER="Sender (untrusted metadata):",SENDER_UNTRUSTED_BLOCK_RE=/Sender\s*\(untrusted[^)]*\)\s*:\s*```[a-zA-Z0-9_-]*\s*[\s\S]*?```/i;function normalizeLineEndings(e){return e.replace(/\r\n/g,"\n").replace(/\r/g,"\n")}function stripMetadataPrefixesFromLine(e){let t=e,n=!1,i=!0;for(;i;){i=!1;for(const e of METADATA_PREFIX_PATTERNS)e.test(t)&&(t=t.replace(e,""),n=!0,i=!0)}return{line:t,changed:n}}function stripConversationInfoBlock(e){const t=e.indexOf(CONVERSATION_INFO_MARKER);if(-1===t)return e;const n=/\nCurrent time:[^\n]*/i.exec(e.slice(t));if(n){const i=t+n.index+n[0].length;return e.slice(0,t)+e.slice(i).replace(/^\n+/,"")}const i=e.indexOf("\n\n",t),s=-1===i?e.length:i;return e.slice(0,t)+e.slice(s).replace(/^\n+/,"")}export function stripLeadingSenderMetadataBlocks(e){let t=normalizeLineEndings(e),n=!0;for(;n;){n=!1;const e=/^\s*/.exec(t)?.[0]??"",i=t.slice(e.length),s=/^Sender\s*\(untrusted[^)]*\)\s*:/i.exec(i);if(!s)break;const r=i.slice(s[0].length),E=/^\s*```[a-zA-Z0-9_-]*\s*[\s\S]*?```\s*/.exec(r);if(E){t=r.slice(E[0].length).replace(/^\n+/,""),n=!0;continue}const c=r.indexOf("\n\n");if(-1!==c){t=r.slice(c).replace(/^\n+/,""),n=!0;continue}const o=r.indexOf("\n");t=-1===o?"":r.slice(o+1),n=!0}return t}function stripSenderMetadataBlocks(e){if(!e.includes(SENDER_UNTRUSTED_MARKER))return e;const t=e.replace(SENDER_UNTRUSTED_BLOCK_RE,"").replace(/^\n+/,"");if(t!==e)return t;const n=e.indexOf(SENDER_UNTRUSTED_MARKER),i=e.indexOf("\n\n",n),s=-1===i?e.length:i;return e.slice(0,n)+e.slice(s).replace(/^\n+/,"")}export function stripTransportMetadata(e,t=!0){const n=normalizeLineEndings(e),i=n.includes(CONVERSATION_INFO_MARKER),s=n.includes(SENDER_UNTRUSTED_MARKER);if(!(n.includes("[")||n.includes("HEARTBEAT_OK")||/MEDIA\s*:/i.test(n)||/User Message From|Message From/i.test(n)||i||s))return n;if(s){const e=stripSenderMetadataBlocks(n).trim();if(e!==n.trim())return e?stripTransportMetadata(e,t):""}if(i){const e=stripConversationInfoBlock(n).trim();if(e!==n.trim())return e?stripTransportMetadata(e,t):""}const r=n.split("\n"),E=[];let c=!1;for(const e of r){const t=stripMetadataPrefixesFromLine(e);HEARTBEAT_OK_LINE_RE.test(t.line.trim())?c=!0:t.changed&&(c=!0,!t.line.trim())||E.push(t.line)}let o=E.join("\n");if(t){const e=new BeeosMediaDirectiveStream;o=e.write(o)+e.finish()}return c||o!==n?o.replace(/^\n+/,"").replace(/\n+$/,""):n}export function normalizeTransportText(e,t=!0){if(!e)return;const n=stripTransportMetadata(e,t);return n.length>0?n:void 0}export function previewSanitizedText(e,t=120){if(!e)return"";const n=e.replace(/\\/g,"\\\\").replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\s+/g," ").trim();if(n.length<=t)return n;const i="...";if(t<=3)return n.slice(0,t);const s=Math.floor((t-3)/2),r=t-3-s;return`${n.slice(0,s)}${i}${n.slice(-r)}`}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{classifyProviderError}from"../errors/classify.js";export const INTERRUPTED_PUBLIC_MESSAGE="The previous run was interrupted before it completed.";export const TIMEOUT_PUBLIC_MESSAGE="The agent task timed out. Please retry.";export const GENERIC_RUNTIME_ERROR_PUBLIC_MESSAGE="The agent could not complete the request. Please retry.";const OPENCLAW_SESSION_LOCK_PATTERNS=[/^\s*(?:⚠️\s*)?agent failed before reply:\s*session file locked\b/i,/^\s*sessionwritelocktimeouterror\b/i,/^\s*OPENCLAW_SESSION_WRITE_LOCK\b/i],ABORT_PATTERNS=[/^\s*request was aborted\.?\s*$/i,/^\s*this operation was aborted\.?\s*$/i,/^\s*aborterror\b/i,/^\s*agent failed before reply:\s*.*\baborted\b/i],AGENT_LOST_PATTERNS=[/^\s*(?:agent failed before reply:\s*)?gateway disconnected\b/i,/^\s*agent lost\b/i,/^\s*no live owner\b/i,/^\s*stale live stream\b/i,/^\s*bridge_not_ready\b/i,/^\s*gateway not connected\b/i],TIMEOUT_PATTERNS=[/^\s*prompt timed out\b/i,/^\s*im runtime dispatch timed out\b/i,/^\s*gateway\b.*\btimed out\b/i,/^\s*deadline exceeded\b/i],ALL_MODELS_FAILED_PATTERNS=[/^\s*(?:⚠️\s*)?(?:embedded\s+)?agent failed before reply:\s*all models failed\b/i,/^\s*all models failed\s*\(/i];function matchesAny(e,r){return r.some(r=>r.test(e))}function extractLockDiagnostics(e){const r=e.match(/\bpid=(\d+)\b/i)?.[1],
|
|
1
|
+
import{HtmlDeliveryError}from"../canvas/html-delivery.js";import{classifyProviderError}from"../errors/classify.js";export const INTERRUPTED_PUBLIC_MESSAGE="The previous run was interrupted before it completed.";export const TIMEOUT_PUBLIC_MESSAGE="The agent task timed out. Please retry.";export const GENERIC_RUNTIME_ERROR_PUBLIC_MESSAGE="The agent could not complete the request. Please retry.";const OPENCLAW_SESSION_LOCK_PATTERNS=[/^\s*(?:⚠️\s*)?agent failed before reply:\s*session file locked\b/i,/^\s*sessionwritelocktimeouterror\b/i,/^\s*OPENCLAW_SESSION_WRITE_LOCK\b/i],ABORT_PATTERNS=[/^\s*request was aborted\.?\s*$/i,/^\s*this operation was aborted\.?\s*$/i,/^\s*aborterror\b/i,/^\s*agent failed before reply:\s*.*\baborted\b/i],AGENT_LOST_PATTERNS=[/^\s*(?:agent failed before reply:\s*)?gateway disconnected\b/i,/^\s*agent lost\b/i,/^\s*no live owner\b/i,/^\s*stale live stream\b/i,/^\s*bridge_not_ready\b/i,/^\s*gateway not connected\b/i],TIMEOUT_PATTERNS=[/^\s*prompt timed out\b/i,/^\s*im runtime dispatch timed out\b/i,/^\s*gateway\b.*\btimed out\b/i,/^\s*deadline exceeded\b/i],ALL_MODELS_FAILED_PATTERNS=[/^\s*(?:⚠️\s*)?(?:embedded\s+)?agent failed before reply:\s*all models failed\b/i,/^\s*all models failed\s*\(/i];function matchesAny(e,r){return r.some(r=>r.test(e))}function extractLockDiagnostics(e){const r=e.match(/\bpid=(\d+)\b/i)?.[1],s=e.match(/([^\s]+\.jsonl\.lock)\b/)?.[1];return{...r?{lockPid:r}:{},...s?{lockPath:s}:{}}}function asString(e){if(e instanceof Error)return e.message;if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}export function classifyAgentRuntimeFailure(e){return detectAgentRuntimeFailure(e)??classifyProviderRuntimeFailure(e)}export function detectAgentRuntimeFailure(e){const r=e.runtimeKind??"openclaw",s=asString(e.raw).trim();return e.requestAborted?{kind:"interrupted",stopReason:"interrupted",publicMessage:INTERRUPTED_PUBLIC_MESSAGE,errorCode:"request_aborted",diagnosticMessage:s,source:e.source,runtimeKind:r}:e.raw instanceof HtmlDeliveryError?{kind:"error",stopReason:"error",publicMessage:GENERIC_RUNTIME_ERROR_PUBLIC_MESSAGE,errorCode:"html_delivery_missing",diagnosticMessage:s,source:e.source,runtimeKind:r}:matchesAny(s,OPENCLAW_SESSION_LOCK_PATTERNS)?{kind:"interrupted",stopReason:"interrupted",publicMessage:INTERRUPTED_PUBLIC_MESSAGE,errorCode:"session_file_locked",diagnosticMessage:s,source:e.source,runtimeKind:r,...extractLockDiagnostics(s)}:matchesAny(s,ABORT_PATTERNS)?{kind:"interrupted",stopReason:"interrupted",publicMessage:INTERRUPTED_PUBLIC_MESSAGE,errorCode:"request_aborted",diagnosticMessage:s,source:e.source,runtimeKind:r}:matchesAny(s,AGENT_LOST_PATTERNS)?{kind:"interrupted",stopReason:"agent_lost",publicMessage:INTERRUPTED_PUBLIC_MESSAGE,errorCode:"agent_lost",diagnosticMessage:s,source:e.source,runtimeKind:r}:matchesAny(s,TIMEOUT_PATTERNS)?{kind:"interrupted",stopReason:"timeout",publicMessage:TIMEOUT_PUBLIC_MESSAGE,errorCode:"gateway_timeout",diagnosticMessage:s,source:e.source,runtimeKind:r}:matchesAny(s,ALL_MODELS_FAILED_PATTERNS)?{kind:"error",stopReason:"error",...providerPublicFields(s),errorCode:"provider_error",diagnosticMessage:s,source:e.source,runtimeKind:r}:void 0}function providerPublicFields(e){const r=classifyProviderError(e);return{publicMessage:r.reason?r.publicMessage:GENERIC_RUNTIME_ERROR_PUBLIC_MESSAGE,...r.businessErrorCode?{businessErrorCode:r.businessErrorCode}:{}}}function classifyProviderRuntimeFailure(e){const r=e.runtimeKind??"openclaw",s=asString(e.raw).trim(),t=s.toLowerCase();return{kind:"error",stopReason:"error",...providerPublicFields(s),errorCode:t?"provider_error":"unknown_runtime_error",diagnosticMessage:s,source:e.source,runtimeKind:r}}export function isRuntimeFailureInterrupted(e){return"interrupted"===e.kind}
|
|
@@ -0,0 +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))})}}
|
|
@@ -0,0 +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}}
|
|
@@ -0,0 +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}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const DELTA_UNITS=4096;export function createCentralNativeDeltaStream(t,e,n){let a,i=-1,s="",l=[];const r=e=>{const n=l.at(-1);n&&n.output_index===i?n.delta+=e:l.push({item_id:`${t.responseId}:message:${i}`,output_index:i,content_index:0,delta:e})};return{partial(o){if("string"==typeof o&&0!==o.length){if(i>=0&&o.startsWith(s)){if(o.length===s.length)return;r(o.slice(s.length))}else{if(i>=0&&s.startsWith(o))return;i+=1,r(o)}s=o,a??=(async()=>{for(;l.length;){const a=l.shift();for(let i=0;i<a.delta.length;i+=4096)try{await e(t,{...a,delta:a.delta.slice(i,i+4096)})}catch(t){n(t)}}a=void 0})()}},async flush(){for(;a;)await a}}}
|
|
@@ -0,0 +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 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 o=!1;const s=new AbortController,l=AbortSignal.any([t.signal,s.signal]),p=createCentralNativeMemoryAttempt({binding:t.binding,signal:l,assertCurrent:t.assertCurrent}),d=new Set;let c;const m=(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)}d.add(a),a.then(()=>d.delete(a),e=>{d.delete(a),c??=e,s.abort(e)})},u=createCentralNativeDeltaStream(t.binding,e.publishDelta,t=>{e.logger.warn?.(`central output delta was not published: ${t instanceof Error?t.name:"error"}`)}),g=e=>{centralNativeRuntime().receipt(t.binding.operationId)?.terminal||u.partial(e.text)};let b="";const v=(e,n)=>(t.assertCurrent(),"final"===e&&"string"==typeof n.text&&n.text.length>0&&(b=b?`${b}\n${n.text}`:n.text),m(e,n),!0),y={sendToolResult:e=>v("tool",e),sendBlockReply:e=>v("block",e),sendFinalReply:e=>v("final",e),waitForIdle:async()=>{},getQueuedCounts:()=>({tool:0,block:0,final:0}),markComplete:()=>{}};try{const i=t.params.parts,s=Array.isArray(i)?prepareNativePromptInput(i):"string"==typeof t.params.text?{message:t.params.text,files:[]}:void 0;if(!s)throw new Error("central native signed prompt parts are unavailable");await centralNativeRuntime().prepare(n.sessionKey,t.binding);const v=[],I=[];for(const n of s.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:runtimeMessageHash(RUNTIME_HASH_DOMAINS.params,{method:"session/prompt",params:t.params}),partIndex:n.partIndex,lease:r,signal:t.signal}),a=await downloadNativeInputFile({fileId:n.fileId,...i,signal:t.signal,assertAttempt:t.assertCurrent});v.push(a.path),I.push(a.mimeType)}let f;t.assertCurrent(),t.signal.throwIfAborted();const h=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:s.message,mediaPaths:v,mediaTypes:I,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:y,replyOptions:{runId:r,abortSignal:l,disableBlockStreaming:!1,onAgentRunStart:t=>{e.coordinator.bindRun(a,t),p.bindHostRun(t)},onPartialReply:g,onReasoningStream:e=>{m("reasoning",e)},onToolStart:e=>{m("tool.start",e)},onItemEvent:e=>{m("item",e)}}}},onDispatchInvoked:()=>{o=!0}})}catch(e){f=e}try{await h()}catch(e){f??=e}await Promise.allSettled([...d,u.flush()]),f??=c;const w=t.signal.aborted,R=centralNativeRuntime().receipt(t.binding.operationId)?.terminal,C=await e.coordinator.converge(a,w?"cancelled":"completed"===R?.status?"completed":"error");if(!C.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(f&&!w)throw f;const N=centralNativeRuntime().receipt(t.binding.operationId)?.terminal;if(!N||N.response_id!==t.binding.responseId)throw new Error("native outcome has no original central terminal transaction receipt");const S=N.status;return t.assertCurrent(),e.coordinator.release(C.permit),{status:S,...b?{finalText:b}:{}}}catch(t){throw o?e.coordinator.snapshot(n.sessionKey)&&e.coordinator.requireRecovery(a,"terminal_not_observed"):e.coordinator.releaseBeforeRuntime(a),t}finally{p.close()}}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{homedir}from"node:os";import{isAbsolute,relative,resolve}from"node:path";import{randomUUID}from"node:crypto";import{askUserQuestionId}from"../question/bridge.js";export const DECISION_ROUTE="/api/v1/runtime/chat-store/decision";const APPROVE="approve_once",APPROVAL_OPTIONS=[{id:APPROVE,label:"Approve once"},{id:"deny",label:"Deny"}],APPROVAL_TIMEOUT_MS=3e5;export function effectiveApprovalMode(e){return"full"===e||"workspace"===e||"ask"===e?e:"ask"}export function workspaceRoots(e){return[...new Set(["/workspace",homedir(),...e?[e]:[]].map(e=>resolve(e)))]}const QUESTION_TOOLS=new Set(["ask_user"]),INTERNAL_TOOLS=new Set(["ask_user","session_status","agents_list"]),FILE_TOOLS={read:["path","file_path"],write:["path","file_path"],edit:["path","file_path"]},NETWORK=/(?:^|[\s;&|(`])(?:curl|wget|ssh|scp|sftp|rsync|nc|ncat|netcat|telnet|ftp|dig|nslookup|ping|pip3?\s+(?:install|download)|uv\s+(?:pip\s+install|add|sync)|npm\s+(?:install|i|ci|publish|update)|pnpm\s+(?:install|add|i)|yarn\s+(?:add|install)|apt(?:-get)?\s|brew\s|apk\s+add|docker\s+(?:pull|push|run|login)|git\s+(?:clone|fetch|pull|push|ls-remote|submodule))\b|[a-z][a-z0-9+.-]*:\/\//i,PRIVILEGE=/(?:^|[\s;&|(`])(?:sudo|su|doas|pkexec|chown|chgrp|setcap|mount|umount|chmod\s+\S*[+=]\S*s)\b/,DESTRUCTIVE=/(?:^|[\s;&|(`])(?:rm\s+-[a-z]*[rf]|rm\s+--(?:recursive|force)|dd\s|mkfs|shred|wipefs|truncate\s|kill\s+-9|killall|pkill|reboot|shutdown|halt|poweroff|git\s+(?:reset\s+--hard|clean\s+-[a-z]*f|push\s+--force))|>\s*\/dev\/(?!null\b)/i;function inside(e,t,s){const o="~"===e||e.startsWith("~/")?homedir()+e.slice(1):e,n=resolve(t,o);return s.some(e=>{const t=relative(e,n);return""===t||!t.startsWith("..")&&!isAbsolute(t)})}function commandPaths(e){if(/[$`]/.test(e)||(e.split("'").length-1)%2||(e.split('"').length-1)%2)return;return(e.match(/"[^"]*"|'[^']*'|[^\s;&|()<>]+/g)??[]).map(e=>e.replace(/^["']|["']$/g,"")).map(e=>e.startsWith("-")&&e.includes("=")?e.slice(e.indexOf("=")+1):e).filter(e=>e.startsWith("/")||e.startsWith("~")||".."===e||e.startsWith("../")||e.includes("/../"))}function patchPaths(e){return[...e.matchAll(/^\*\*\* (?:Add|Update|Delete) File: (.+)$|^\*\*\* Move to: (.+)$/gm)].map(e=>(e[1]??e[2]).trim())}export function classifyOpenClawToolCall(e,t,s,o,n=o[o.length-1]){const i=effectiveApprovalMode(e);if("full"===i||QUESTION_TOOLS.has(t))return;if("ask"===i)return`Approval mode ask: ${t} requires approval`;if(INTERNAL_TOOLS.has(t))return;const r=resolve(n);if(t in FILE_TOOLS||"apply_patch"===t){const e="apply_patch"===t?patchPaths("string"==typeof s.input?s.input:"string"==typeof s.patch?s.patch:""):FILE_TOOLS[t].map(e=>s[e]).filter(e=>"string"==typeof e&&e.length>0);return e.length>0&&e.every(e=>inside(e,r,o))?void 0:`${t} reaches a path outside the workspace`}if("exec"===t){const e=s.command;if("string"!=typeof e||!e.trim())return"exec command is not classifiable";let t=r;if("string"==typeof s.workdir&&s.workdir){if(!inside(s.workdir,r,o))return"exec working directory is outside the workspace";t=resolve(r,s.workdir)}if(!0===s.elevated||"gateway"===s.host||"node"===s.host)return"exec leaves the sandbox or escalates privileges";if(NETWORK.test(e))return"exec command uses network access";if(PRIVILEGE.test(e))return"exec command escalates privileges";if(DESTRUCTIVE.test(e))return"exec command is destructive";const n=commandPaths(e);return n?n.some(e=>!inside(e,t,o))?"exec command reaches a path outside the workspace":void 0:"exec command is not classifiable"}return`${t} is outside the workspace auto-approval rules`}const scopes=new Map,sleep=(e,t)=>new Promise(s=>{const o=setTimeout(s,e);t.addEventListener("abort",()=>{clearTimeout(o),s()},{once:!0})});function interaction(e,t,s,o){return{id:t,response_id:e.responseId,attempt_ref:e.attemptId,revision:1,kind:s,state:"pending",expires_at:new Date(o.expiresAt).toISOString(),tool_call_id:o.toolCallId&&/^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/.test(o.toolCallId)?o.toolCallId:null,tool_name:o.toolName??null,arguments_digest:null,summary:o.summary.slice(0,4096),options:o.options??[],questions:o.questions??[],pause_sequence:null}}async function open(e,t){if(e.closed)throw new Error("central interactions closed");e.open.set(t.id,t),await e.publish(t)}async function finish(e,t,s){const o=e.open.get(t);o&&(e.open.delete(t),await e.publish({...o,revision:o.revision+1,state:s}))}async function waitForReply(e,t,s){const o=e.now??Date.now;for(;!e.signal.aborted&&o()<s&&e.open.has(t);){const s=await e.decide(t);if(s)return s;await sleep(e.pollMs??1e3,e.signal)}return null}export function bindCentralInteractions(e,t){const s={...t,roots:workspaceRoots(t.cwd),open:new Map,closed:!1};return scopes.set(e,s),async()=>{scopes.get(e)===s&&scopes.delete(e),s.closed=!0;for(const e of[...s.open.keys()])await finish(s,e,"cancelled")}}export async function centralApprovalGate(e,t){const s=t.sessionKey?scopes.get(t.sessionKey):void 0;if(!s)return;const o=e.toolName||t.toolName||"",n=classifyOpenClawToolCall(s.mode,o,e.params??{},s.roots,s.cwd);if(n)try{return await askApproval(s,o,n,e.toolCallId??t.toolCallId)}catch(e){return{block:!0,blockReason:`BLOCKED: ${o} approval could not be confirmed (${e instanceof Error?e.message:String(e)}).`}}}async function askApproval(e,t,s,o){const n=e.now??Date.now,i="a"+randomUUID().replaceAll("-",""),r=n()+3e5;await open(e,interaction(e,i,"approval",{summary:s,expiresAt:r,toolName:t,toolCallId:o,options:APPROVAL_OPTIONS}));const a=await waitForReply(e,i,r);return a?(await finish(e,i,"resolved"),a.option_id===APPROVE?void 0:{block:!0,blockReason:`BLOCKED: the user denied ${t}.`}):(await finish(e,i,e.signal.aborted?"cancelled":"expired"),{block:!0,blockReason:`BLOCKED: ${t} was not approved before the request ${e.signal.aborted?"stopped":"expired"}.`})}const record=e=>null!==e&&"object"==typeof e&&!Array.isArray(e);function nativeQuestions(e){if(!Array.isArray(e)||0===e.length||e.length>32)return;const t=[];for(const s of e){if(!record(s)||"string"!=typeof s.questionId||"string"!=typeof s.question)return;const e=Array.isArray(s.options)?s.options.filter(record).map(e=>({label:String(e.label??"")})):[];t.push({questionId:s.questionId,question:s.question,options:e,multiSelect:!0===s.multiSelect})}return t}export async function relayCentralAskUser(e,t,s=200,o=10){const n=t.sessionKey?scopes.get(t.sessionKey):void 0;if(!n||!t.runId||!t.toolCallId)return;const i=askUserQuestionId(t.runId,t.toolCallId);let r;for(let t=0;t<o&&!r;t++){await sleep(s,n.signal);const t=await e("question.get",{id:i}).catch(()=>{});r=record(t)&&record(t.question)&&"pending"===t.question.status?t.question:void 0}const a=r?nativeQuestions(r.questions):void 0;if(!r||!a||"number"!=typeof r.expiresAtMs)return void await e("question.resolve",{id:i,cancel:!0,resolvedBy:"beeos:unsupported"}).catch(()=>{});const l=a.map((e,t)=>({id:`q${t+1}`,prompt:e.question.slice(0,4096),kind:0===e.options.length?"text":e.multiSelect?"multiple_choice":"single_choice",options:e.options.map((e,t)=>({id:`option_${t+1}`,label:e.label.slice(0,256)}))})),c="q"+randomUUID().replaceAll("-","");await open(n,interaction(n,c,"question",{summary:"Please answer to continue.",expiresAt:r.expiresAtMs,toolName:"ask_user",toolCallId:t.toolCallId,questions:l}));const p=await waitForReply(n,c,r.expiresAtMs);if(!p?.answers)return await finish(n,c,n.signal.aborted?"cancelled":"expired"),void await e("question.resolve",{id:i,cancel:!0,resolvedBy:"beeos:unanswered"}).catch(()=>{});const d={};for(const e of p.answers){const t=a[Number(e.question_id.slice(1))-1],s=Array.isArray(e.value)?e.value:[e.value];d[t.questionId]=0===t.options.length?s:s.map(e=>t.options[Number(String(e).replace("option_",""))-1].label)}await e("question.resolve",{id:i,answers:{answers:d},resolvedBy:"beeos:v2",resolutionId:randomUUID()}),await finish(n,c,"resolved")}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isDeepStrictEqual}from"node:util";const runs=new Map,tools=new Map;let call;export function installCentralNativeMemoryCall(e){if(call)throw new Error("native Memory transport is already installed");call=e}export function createCentralNativeMemoryAttempt(e){let r,t=!0;const o={...e,binding:structuredClone(e.binding),assertCurrent(){if(!t)throw new Error("native Memory attempt finished");e.signal.throwIfAborted(),e.assertCurrent()}};return{bindHostRun(e){if(o.assertCurrent(),!e||void 0!==r||runs.has(e))throw new Error("native Memory Host run binding is ambiguous");r=e,runs.set(e,o)},close(){t=!1,r&&runs.get(r)===o&&runs.delete(r);for(const[e,r]of tools)r.assertCurrent===o.assertCurrent&&tools.delete(e)}}}const toolNames={beeos_memory_remember:"remember",beeos_memory_recall:"recall",beeos_memory_revise:"revise",beeos_memory_forget:"forget"},allowed={remember:["content","kind","source_id"],recall:["query","kinds","limit","cursor"],revise:["record_id","expected_revision","content","reason","source_id"],forget:["record_ids","reason"]};function argumentsFor(e,r){if(!r||"object"!=typeof r||Array.isArray(r)||Object.keys(r).some(r=>!allowed[e].includes(r)))throw new Error("native Memory arguments include unsupported fields");return r}export function centralNativeMemoryToolGate(e,r){const t=toolNames[e.toolName];if(t)try{if(e.runId&&r.runId&&e.runId!==r.runId||e.toolCallId&&r.toolCallId&&e.toolCallId!==r.toolCallId)throw new Error("native Memory Host correlation conflict");const o=e.toolCallId??r.toolCallId,n=e.runId??r.runId,i=n?runs.get(n):void 0;if(!i||!o||tools.has(o))throw new Error("native Memory trusted tool-call capability is unavailable");i.assertCurrent(),argumentsFor(t,e.params),tools.set(o,{...i,action:t,params:structuredClone(e.params)})}catch(e){return{block:!0,blockReason:e instanceof Error?e.message:"native Memory authority unavailable"}}}const string={type:"string",minLength:1},kind={type:"string",enum:["core","semantic","episodic","procedural"]},schemas={remember:{type:"object",additionalProperties:!1,required:["content","kind"],properties:{content:string,kind:kind,source_id:string}},recall:{type:"object",additionalProperties:!1,required:["query"],properties:{query:string,kinds:{type:"array",items:kind},limit:{type:"integer",minimum:1},cursor:string}},revise:{type:"object",additionalProperties:!1,required:["record_id","expected_revision","content","reason"],properties:{record_id:string,expected_revision:{type:"integer",minimum:1},content:string,reason:string,source_id:string}},forget:{type:"object",additionalProperties:!1,required:["record_ids","reason"],properties:{record_ids:{type:"array",minItems:1,items:string},reason:string}}};export function registerCentralNativeMemoryTools(e){if(!e.on)throw new Error("native Memory Host hook is unavailable");e.on("before_tool_call",centralNativeMemoryToolGate);for(const[r,t]of Object.entries(toolNames))e.registerTool({name:r,description:`${t} private Agent Memory under the current authorized execution.`,parameters:schemas[t],async execute(e,r,o){const n=tools.get(e);if(tools.delete(e),!n||n.action!==t||!isDeepStrictEqual(n.params,r))throw new Error("native Memory trusted tool-call capability is missing or changed");if(n.assertCurrent(),o?.throwIfAborted(),!call)throw new Error("native Memory current State transport is unavailable");const i=await call(n.binding,t,e,argumentsFor(t,r),o?AbortSignal.any([o,n.signal]):n.signal);return n.assertCurrent(),{content:[{type:"text",text:JSON.stringify(i)}]}}})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash,randomUUID}from"node:crypto";import{link,mkdir,open,readFile,readdir,rename,unlink}from"node:fs/promises";import{dirname,join}from"node:path";import{isDeepStrictEqual}from"node:util";import{nativeBindingDigest}from"./central-native-context-engine.js";export class FileCentralNativePendingJournal{directory;constructor(t){this.directory=t}path(t){return join(this.directory,`${createHash("sha256").update(t).digest("hex")}.json`)}async get(t){try{const i=JSON.parse(await readFile(this.path(t),"utf8"));if(i.idempotencyKey!==t)throw new Error("central pending journal identity mismatch");return i}catch(t){if("ENOENT"===t.code)return null;throw t}}async put(t){const i=await this.get(t.idempotencyKey);if(i){if(!isDeepStrictEqual(i,t))throw new Error("central pending request conflicts");return}await mkdir(this.directory,{recursive:!0,mode:448});const e=this.path(t.idempotencyKey),n=`${e}.${randomUUID()}.tmp`,r=await open(n,"wx",384);try{await r.writeFile(JSON.stringify(t)),await r.sync()}finally{await r.close()}try{await link(n,e)}catch(i){if("EEXIST"!==i.code)throw i;if(!isDeepStrictEqual(await this.get(t.idempotencyKey),t))throw new Error("central pending request conflicts")}finally{await unlink(n)}await this.syncDirectory()}async completed(t){try{return JSON.parse(await readFile(`${this.path(t)}.receipt`,"utf8"))}catch(t){if("ENOENT"===t.code)return null;throw t}}async complete(t,i){const e=`${this.path(t.idempotencyKey)}.receipt`,n=`${e}.${randomUUID()}.tmp`,r=await open(n,"wx",384);try{await r.writeFile(JSON.stringify({nativeSnapshotDigest:t.nativeSnapshotDigest,binding:t.binding,receipt:i})),await r.sync()}finally{await r.close()}await rename(n,e),await this.syncDirectory(),await unlink(this.path(t.idempotencyKey)),await this.syncDirectory()}async list(t){let i;try{i=await readdir(this.directory)}catch(t){if("ENOENT"===t.code)return[];throw t}const e=[];for(const n of i.sort()){if(!/^[a-f0-9]{64}\.json$/.test(n))continue;const i=JSON.parse(await readFile(join(this.directory,n),"utf8"));if(this.path(i.idempotencyKey)!==join(this.directory,n))throw new Error("central pending journal identity mismatch");void 0!==t&&i.binding.sessionId!==t||e.push(i)}return e}async terminal(t){const i=new Map,e=nativeBindingDigest(t);for(const n of await this.list(t.sessionId))n.wire.terminal&&nativeBindingDigest(n.binding)===e&&i.set(n.idempotencyKey,{binding:n.binding,nativeSnapshotDigest:n.nativeSnapshotDigest,request:n});let n;try{n=await readdir(this.directory)}catch(t){if("ENOENT"===t.code)return null;throw t}for(const t of n.sort()){if(!/^[a-f0-9]{64}\.json\.receipt$/.test(t))continue;const n=JSON.parse(await readFile(join(this.directory,t),"utf8"));if(!n.receipt||this.path(n.receipt.idempotency_key)+".receipt"!==join(this.directory,t))throw new Error("central terminal receipt journal identity mismatch");if(n.receipt.terminal&&nativeBindingDigest(n.binding)===e){const t=i.get(n.receipt.idempotency_key);i.set(n.receipt.idempotency_key,{...t,...n})}}if(i.size>1)throw new Error("multiple original central terminals exist for this native binding");return i.values().next().value??null}async syncDirectory(){const t=await open(dirname(join(this.directory,"entry")),"r");try{await t.sync()}finally{await t.close()}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash}from"node:crypto";import{isDeepStrictEqual}from"node:util";import{ChatStoreHttpError,chatAppendDigest,decodeNativeChatEvent,encodeNativeChatEvent}from"@beeos-ai/cloud-harness-sdk";import{OPENCLAW_NATIVE_CODEC,assertCentralNativeReceipt,nativePayloadDigest}from"./central-native-context-engine.js";import{generatedSessionName}from"./central-native-titles.js";const codec={name:"openclaw-session-events",version:"1"};export const CENTRAL_RESPONSE_CONTROL_CODEC={name:"beeos-response-control",version:"1"};const executionObservationType="response.beeos.execution_observation",decimal=e=>"string"==typeof e&&/^(0|[1-9][0-9]*)$/.test(e),key=e=>JSON.stringify([e.context.tenant_ref,e.context.scope_ref,e.sessionId,e.historyGeneration,e.branchId]),operationKey=e=>JSON.stringify([key(e),e.operationId,e.responseId,e.attemptId]),object=e=>null!==e&&"object"==typeof e&&!Array.isArray(e),publicId=e=>"string"==typeof e&&/^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/.test(e)?e:null;export function publicModelRoute(e,t){if("string"==typeof e&&e.includes("/")){const t=e.indexOf("/");return[publicId(e.slice(0,t)),publicId(e.slice(t+1))]}return[publicId(t),publicId(e)]}function executedRoute(e){const t=object(e.meta.agentMeta)?e.meta.agentMeta:{},n=object(t.terminalReceipt)?t.terminalReceipt:{},i=object(n.effective)?n.effective:{},r=object(e.meta.executionTrace)?e.meta.executionTrace:{};return"string"==typeof i.responseModel?i.responseModel:"string"==typeof r.winnerModel?r.winnerModel:i.model}export function publicModelId(e){if("string"==typeof e&&0!==e.length)return publicId(e.includes("/")?`arouter_${e.replaceAll("/","_")}`:e)??void 0}function executedFacts(e){const t=object(e.meta.agentMeta)?e.meta.agentMeta:{},n=object(t.terminalReceipt)?t.terminalReceipt:{},i=object(n.effective)?n.effective:{},r=object(e.meta.executionTrace)?e.meta.executionTrace:{},o=object(e.meta.requestShaping)?e.meta.requestShaping:{},a="string"==typeof n.runId?n.runId:void 0,[s,d]=publicModelRoute(executedRoute(e),"string"==typeof i.provider?i.provider:r.winnerProvider);if(a&&s&&d)return{nativeRunId:a,facts:{actual_provider_id:s,actual_model_id:d,..."boolean"==typeof r.fallbackUsed?{fallback_used:r.fallbackUsed}:{},..."string"==typeof o.reasoning?{reasoning:o.reasoning}:{}}}}function terminalOutputItem(e){const t="string"==typeof e.toolCallId?e.toolCallId:"string"==typeof e.tool_call_id?e.tool_call_id:void 0,n="string"==typeof e.toolName?e.toolName:"string"==typeof e.tool_name?e.tool_name:void 0;if(t||n){if(!t||!n)throw new Error("native tool result lacks its tool call identity");return{type:"tool_summary",tool_call_id:t,tool_name:n,outcome:!0===e.isError?"failed":!1===e.isError?"succeeded":"unknown",summary:"string"==typeof e.text?e.text.slice(0,4096):""}}return"string"==typeof e.text&&e.text.length>0?{type:"output_text",text:e.text}:void 0}function terminalUsage(e){const t=object(e.meta.agentMeta)?e.meta.agentMeta:{},n=object(t.usage)?t.usage:void 0;if(!n)return;const i=e=>"number"==typeof e&&Number.isSafeInteger(e)&&e>=0?e:void 0,r=i(n.input),o=i(n.output);if(void 0===r&&void 0===o)return;const a=publicModelId(executedRoute(e));return{input_tokens:r??0,output_tokens:o??0,source:"provider",...a?{actual_model_id:a}:{}}}function terminalProjection(e,t){const n=t.outcome,i=["cancelled","aborted","superseded"].includes(n.reason)?"cancelled":["hard_timeout","timed_out","abandoned"].includes(n.reason)||["max_tokens","length","max_output_tokens"].includes(n.stopReason??"")?"incomplete":"completed"===n.reason&&"ok"===n.status?"completed":"failed",r=[];for(const e of t.payloads){if(!object(e))throw new Error("native terminal payload is not a typed reply");if(e.mediaUrl||Array.isArray(e.mediaUrls)&&e.mediaUrls.length>0)throw new Error("native media output requires its authorized central file projection");const t=terminalOutputItem(e);t&&r.push(t)}const o=object(t.meta.agentMeta)?t.meta.agentMeta:{},a=terminalUsage(t);return{status:i,event:{type:"cancelled"===i?"response.failed":`response.${i}`,response:{id:e.responseId,status:i,output:r,..."string"==typeof o.model&&o.model.length>0?{model:o.model}:{},...a?{usage:a}:{},error:"failed"===i?{type:"harness_error",code:"harness_error",message:n.error||"The native harness could not complete this response."}:null,incomplete_details:"incomplete"===i?{reason:"completed"===n.reason?"max_output_tokens":"runtime_interrupted"}:null}}}}export class StateCentralNativeStore{client;credential;titles;writes=new Map;heads=new Map;publicEvents=new Map;memoryReads=new Map;executionObservations=new Map;constructor(e,t,n){this.client=e,this.credential=t,this.titles=n}async recordGeneratedTitle(e,t){if(!this.titles)throw new Error("generated Session titles are unavailable");const n=generatedSessionName(t);if(!n)throw new Error("generated Session title is empty");return await this.titles.title(await this.credential(e),{context:e.context,session_id:e.sessionId,history_generation:e.historyGeneration,branch_id:e.branchId,name:n,idempotency_key:`title:${e.operationId}`})}withWrite(e,t){const n=key(e),i=(this.writes.get(n)??Promise.resolve()).then(t);return this.writes.set(n,i),i}async commitPublicProgress(e,t){await this.withWrite(e,async()=>{if(!this.publicEvents.get(operationKey(e))?.length)return;if(0!==(await t.list(e.sessionId)).length)throw new Error("native progress has unresolved original writes");const n=await this.load(e);if(n.terminal?.response_id===e.responseId)throw new Error("original native Response is already terminal");const i=structuredClone(this.publicEvents.get(operationKey(e))??[]),r=nativePayloadDigest(i),o=this.prepareAppend({binding:e,events:[],expectedWatermark:n.watermark,publicProgress:!0,idempotencyKey:`progress:${e.operationId}:${n.watermark}:${r}`,nativeSnapshotDigest:r});await t.put(o);const a=await this.append(o);assertCentralNativeReceipt(o,a),await t.complete(o,a)})}recordPublicEvent(e,t){const n=operationKey(e),i=this.publicEvents.get(n)??[];i.push(structuredClone(t)),this.publicEvents.set(n,i)}recordMemoryRead(e,t){if("read"===t.status&&!t.watermark)throw new Error("actual Memory recall omitted its read watermark");this.memoryReads.set(operationKey(e),structuredClone(t))}bindExecutionObservation(e,t){if(t.admission.attemptId!==e.attemptId)throw new Error("native observation does not bind the original attempt");const n=operationKey(e),i=this.executionObservations.get(n);if(i&&!isDeepStrictEqual(i.source,t))throw new Error("native loaded observation changed");i||this.executionObservations.set(n,{source:structuredClone(t),loaded:!1})}nativeEventCapacity(e,t){const n=this.executionObservations.get(operationKey(e));return 200-(t?1:0)-(n&&!n.loaded?1:0)}async load(e){let t=null,n="0",i=null;const r=[];for(;;){const o=await this.client.load(await this.credential(e),{context:e.context,session_id:e.sessionId,history_generation:e.historyGeneration,branch_id:e.branchId,watermark:t,after:n,limit:200});this.assertPage(o,e,t,n),t=o.watermark;for(const e of o.events){if(e.sequence!==String(BigInt(n)+1n))throw new Error("central native event sequence has a gap");const t=decodeNativeChatEvent(e);if(isDeepStrictEqual(e.codec,codec))r.push(JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(t)));else if(!isDeepStrictEqual(e.codec,CENTRAL_RESPONSE_CONTROL_CODEC))throw new Error("central native event codec is not supported by this pinned Harness");n=e.sequence,i=e.event_id}if(o.next_after!==n||o.has_more&&BigInt(n)>=BigInt(t))throw new Error("central native page cursor does not match its fixed source");if(!o.has_more){if(n!==t)throw new Error("central native source ended before its fixed watermark");return this.heads.set(key(e),{watermark:t,lastEventId:i}),{codec:OPENCLAW_NATIVE_CODEC,events:r,watermark:t,writer:o.writer,terminal:o.terminal}}if(0===o.events.length)throw new Error("central native source made no page progress")}}prepareAppend(e){if(e.events.length>this.nativeEventCapacity(e.binding,Boolean(e.nativeOutcome)))throw new Error("native suffix must reserve its actual observation and terminal control rows");const t=this.heads.get(key(e.binding));if(!t||t.watermark!==e.expectedWatermark)throw new Error("native append has no exact loaded central source");let n=t.lastEventId;const i=e.events.map((t,i)=>{const r=Buffer.from(JSON.stringify(t),"utf8"),o=createHash("sha256").update(JSON.stringify([e.binding.sessionId,e.binding.historyGeneration,e.binding.branchId,String(BigInt(e.expectedWatermark)+BigInt(i)+1n)])).update(r).digest("hex"),a=encodeNativeChatEvent({eventId:`oc-${o}`,parentId:n,kind:t&&"object"==typeof t&&"type"in t&&"string"==typeof t.type?t.type:"native",codec:codec,content:r});return n=a.event_id,a});let r=null;const o=structuredClone(this.publicEvents.get(operationKey(e.binding))??[]),a=this.executionObservations.get(operationKey(e.binding)),s=(t,n,i)=>{const r=a.source,s="executed"===t?this.memoryReads.get(operationKey(e.binding)):void 0;o.push({type:executionObservationType,response_id:e.binding.responseId,attempt_id:e.binding.attemptId,resolved_request_hash:r.resolvedRequestHash,payload:{phase:t,attempt:{...r.admission,...i?{nativeRunId:i.nativeRunId}:{}},read_watermark:r.readWatermark,source_ref:{id:n.event_id,digest:n.sha256},session_config_receipt:"loaded"===t?r.sessionConfigReceipt:null,runtime:null,partial_effective:{...r.loadedFacts,...i?.facts??{},...s?{memory_observation:s.status,memory_read_watermark:s.watermark}:{}}}})};if(a&&!a.loaded){const t=Buffer.from(JSON.stringify({type:"configuration.applied",...a.source}),"utf8"),r=`oc-loaded-${createHash("sha256").update(e.idempotencyKey).update(t).digest("hex")}`,o=encodeNativeChatEvent({eventId:r,parentId:n,kind:"configuration.applied",codec:CENTRAL_RESPONSE_CONTROL_CODEC,content:t});i.push(o),n=r,s("loaded",o)}if(e.publicProgress){if(e.nativeOutcome||0!==e.events.length||0===o.length)throw new Error("public native progress has invalid effect shape");const t=Buffer.from(JSON.stringify({type:"response.progress",response_id:e.binding.responseId,operation_id:e.binding.operationId,public_events_sha256:nativePayloadDigest(o)}),"utf8"),r=`oc-progress-${createHash("sha256").update(e.idempotencyKey).digest("hex")}`;i.push(encodeNativeChatEvent({eventId:r,parentId:n,kind:"response.progress",codec:CENTRAL_RESPONSE_CONTROL_CODEC,content:t})),n=r}if(e.nativeOutcome){const t=terminalProjection(e.binding,e.nativeOutcome),d=`oc-terminal-${createHash("sha256").update(e.idempotencyKey).digest("hex")}`,c={type:"response.terminal",operation_id:e.binding.operationId,response_id:e.binding.responseId,attempt_id:e.binding.attemptId,native_outcome:e.nativeOutcome},l=encodeNativeChatEvent({eventId:d,parentId:n,kind:"response.terminal",codec:CENTRAL_RESPONSE_CONTROL_CODEC,content:Buffer.from(JSON.stringify(c),"utf8")});i.push(l),r={response_id:e.binding.responseId,status:t.status,event_id:d};const p=a?executedFacts(e.nativeOutcome):void 0;p&&s("executed",l,p),o.push(t.event)}const d={context:e.binding.context,session_id:e.binding.sessionId,history_generation:e.binding.historyGeneration,branch_id:e.binding.branchId,response_id:e.binding.responseId,attempt_id:e.binding.attemptId,public_events:o,writer:e.binding.writer,expected_watermark:e.expectedWatermark,operation_id:e.binding.operationId,idempotency_key:e.idempotencyKey,events:i,terminal:r},c=chatAppendDigest(d),l={...d,payload_sha256:c};return{...structuredClone(e),codec:OPENCLAW_NATIVE_CODEC,payloadDigest:c,wire:l}}async append(e){const t=e.wire;if(chatAppendDigest(t)!==e.payloadDigest||t.payload_sha256!==e.payloadDigest)throw new Error("pending native append no longer matches its original digest");const n=await this.client.append(await this.credential(e.binding),t);return this.accept(e.binding,t,n),n}async receipt(e){const t=e.binding;try{const n=await this.client.receipt(await this.credential(t),{context:t.context,session_id:t.sessionId,history_generation:t.historyGeneration,branch_id:t.branchId,idempotency_key:e.idempotencyKey,payload_sha256:e.payloadDigest});if(n.operation_id!==t.operationId||!isDeepStrictEqual(n.writer,t.writer))throw new Error("original native receipt belongs to another operation/writer");return n}catch(e){if(e instanceof ChatStoreHttpError&&404===e.status&&"not_found"===e.code)return null;throw e}}assertPage(e,t,n,i){if(e.session_id!==t.sessionId||e.history_generation!==t.historyGeneration||e.branch_id!==t.branchId||!decimal(e.watermark)||null!==n&&e.watermark!==n||BigInt(e.watermark)<BigInt(i)||!Array.isArray(e.events)||"boolean"!=typeof e.has_more||!isDeepStrictEqual(e.writer,t.writer))throw new Error("central native load does not match the authorized fixed source/writer")}accept(e,t,n){if(!(n.operation_id===e.operationId&&n.previous_watermark===t.expected_watermark&&decimal(n.read_watermark)&&n.read_watermark===String(BigInt(t.expected_watermark)+BigInt(t.events.length))&&isDeepStrictEqual(n.event_ids,t.events.map(e=>e.event_id))&&isDeepStrictEqual(n.terminal,t.terminal)&&isDeepStrictEqual(n.writer,e.writer)))throw new Error("native append returned a receipt for different committed content");const i=this.heads.get(key(e));this.heads.set(key(e),{watermark:n.read_watermark,lastEventId:n.event_ids.at(-1)??i?.lastEventId??null});const r=operationKey(e),o=this.executionObservations.get(r);o&&t.public_events.some(e=>e.type===executionObservationType&&object(e.payload)&&"loaded"===e.payload.phase)&&(o.loaded=!0);const a=this.publicEvents.get(r);if(a){const e=t.public_events.filter(e=>e.type!==executionObservationType),i=e.slice(0,e.length-(t.terminal?1:0));if(!isDeepStrictEqual(a.slice(0,i.length),i))throw new Error("confirmed public events differ from their pending native buffer");n.terminal||a.length===i.length?this.publicEvents.delete(r):this.publicEvents.set(r,a.slice(i.length))}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isDeepStrictEqual}from"node:util";import{RUNTIME_HASH_DOMAINS}from"@beeos-ai/beeos-types/runtime";import{assertCentralNativeReceipt}from"./central-native-context-engine.js";import{runtimeMessageHash}from"./runtime-message-channel-contract.js";const object=e=>null!==e&&"object"==typeof e&&!Array.isArray(e),promptText=e=>{if("string"==typeof e.text&&e.text.length>0)return e.text;return(Array.isArray(e.parts)?e.parts:[]).filter(object).filter(e=>"text"===e.type&&"string"==typeof e.text).map(e=>e.text).join("\n")},text=e=>"string"==typeof e&&e.length>0,decimal=e=>"string"==typeof e&&/^(0|[1-9][0-9]*)$/.test(e),associationKeys=["context","session_id","history_generation","branch_id","writer","response_id","attempt_id","watermark","config_pin","persona_ref"];export function isCentralNativeResponse(e){const t=e.message?.payload,r=t?.request;return 2===t?.schemaVersion&&"session/prompt"===t.method&&object(r)&&object(r.params)&&Object.hasOwn(r.params,"centralChat")}export function verifyCentralNativeIntent(e){const t=e.executionGrant,r=e.request,i=t?e.verifier.verifyAndDecodeGrant(t):null,a=i?.claims,n=object(r.request)?r.request:{},s=object(n.params)?n.params:{},o=object(s.centralChat)?s.centralChat:{},c=object(r.command)?r.command:{},p=object(c.context)?c.context:{},d=object(p.conversation)?p.conversation:{},l=object(o.context)?o.context:{},m=object(o.writer)?o.writer:{},u=object(o.config_pin)?o.config_pin:{},h=u.credential_set_ref,g=()=>{const t=e.getLease();if(!t||t.instanceId!==e.lease.instanceId||t.leaseId!==e.lease.leaseId||t.handlerIdentity!==e.lease.handlerIdentity||t.runtimeEpoch!==e.lease.runtimeEpoch||!Number.isFinite(Date.parse(t.leaseExpiresAt))||Date.parse(t.leaseExpiresAt)<=Date.now())throw new Error("central native execution is fenced")},f=Math.floor(Date.now()/1e3);if(!object(r)||2!==r.schemaVersion||"session/prompt"!==r.method||!Object.hasOwn(s,"centralChat")||!t||!a||"string"!=typeof r.executionGrantHash||!/^[a-f0-9]{64}$/.test(r.executionGrantHash)||"cloud"!==r.authorityRealm||!object(r.cloudSubject)||r.cloudSubject.instanceId!==e.lease.instanceId||!isDeepStrictEqual(r.cloudSubject,a.cloudSubject)||r.instanceId!==e.lease.instanceId||r.leaseId!==e.lease.leaseId||r.runtimeHandlerIdentity!==e.lease.handlerIdentity||r.dispatchEpoch!==e.lease.runtimeEpoch||"cloud"!==a.authorityRealm||"session/prompt"!==a.method||"conversation"!==a.scope||"start"!==a.executionMode||a.platformConversationId!==o.session_id||a.historyGeneration!==o.history_generation||a.platformAgentId!==s.platformAgentId||!text(a.runtimeAgentUid)||s.conversationId!==o.session_id||"conversation"!==p.scope||d.runtimeConversationUid!==o.session_id||d.runtimeSessionKey!==o.session_id||p.historyGeneration!==o.history_generation||p.operationId!==r.operationId||p.runtimeInstanceUid!==r.instanceId||p.dispatchEpoch!==r.dispatchEpoch||p.paramsHash!==r.paramsHash||!isDeepStrictEqual(a.command,c)||!Number.isSafeInteger(a.iat)||!Number.isSafeInteger(a.exp)||a.iat>f||a.exp<=f||a.exp<=a.iat||a.exp-a.iat>60||a.sub!==e.lease.handlerIdentity||a.handlerIdentity!==e.lease.handlerIdentity||["operationId","requestMessageId","instanceId","leaseId","dispatchEpoch","requestHash","paramsHash","commandHash","idempotencyKeyHash"].some(e=>!text(r[e])||a[e]!==r[e])||"2.0"!==n.jsonrpc||"session/prompt"!==n.method||"session.prompt"!==c.name||!text(s.runtimeRunId)||s.taskId!==r.operationId||s.taskRequestMessageId!==r.requestMessageId||runtimeMessageHash(RUNTIME_HASH_DOMAINS.request,n)!==r.requestHash||runtimeMessageHash(RUNTIME_HASH_DOMAINS.params,{method:r.method,params:s})!==r.paramsHash||runtimeMessageHash(RUNTIME_HASH_DOMAINS.command,{command:c})!==r.commandHash||![o.session_id,o.history_generation,o.branch_id,o.response_id,o.attempt_id,l.tenant_ref,l.scope_ref,l.request_id,m.writer_id,m.writer_epoch].every(text)||!Number.isSafeInteger(l.authorization_revision)||l.authorization_revision<1||!Number.isSafeInteger(l.erasure_epoch)||l.erasure_epoch<0||!decimal(o.history_generation)||!decimal(o.watermark)||!decimal(m.writer_epoch)||"0"===m.writer_epoch||Object.keys(o).length!==associationKeys.length||!associationKeys.every(e=>Object.hasOwn(o,e))||4!==Object.keys(u).length||u.agent_id!==s.platformAgentId||!text(u.revision)||"string"!=typeof u.content_sha256||!/^[a-f0-9]{64}$/.test(u.content_sha256)||null!==h&&(!object(h)||2!==Object.keys(h).length||!text(h.set_id)||!Number.isSafeInteger(h.version)||h.version<1)||null!==o.persona_ref&&(!object(o.persona_ref)||2!==Object.keys(o.persona_ref).length||!text(o.persona_ref.persona_id)||!text(o.persona_ref.revision)))throw new Error("central native original signed intent is invalid");g();return{binding:{sessionId:o.session_id,historyGeneration:o.history_generation,branchId:o.branch_id,responseId:o.response_id,attemptId:o.attempt_id,operationId:r.operationId,context:l,writer:m},params:structuredClone(s),assertCurrent:g}}export class CentralNativeResponse{options;constructor(e){this.options=e}async execute(e){const t=this.options;await t.verifier.refresh();const r=e.delivery.message.payload;if("runtime_rpc_request"!==e.delivery.message.type||"completed"!==e.delivery.message.state||e.delivery.message.message_id!==r.requestMessageId||e.delivery.message.channel_id!==r.operationId)throw new Error("central native original delivery is invalid");const i=e.delivery.executionGrant,{binding:a,params:n,assertCurrent:s}=verifyCentralNativeIntent({request:r,executionGrant:i,verifier:t.verifier,lease:e.lease,getLease:t.getLease});e.onVerified?.({operationId:r.operationId,requestMessageId:r.requestMessageId,requestHash:r.requestHash,dispatchEpoch:r.dispatchEpoch,method:"session/prompt"}),t.bindCredential(a,i,r.requestHash,{requestMessageId:r.requestMessageId,verifier:t.verifier});const o=await t.pending.terminal(a);if(o){const e=o.request??{binding:o.binding,idempotencyKey:o.receipt.idempotency_key,payloadDigest:o.receipt.payload_sha256},{context:r,...i}=e.binding,{context:n,...c}=a;if(!isDeepStrictEqual(i,c)||r.tenant_ref!==n.tenant_ref||r.scope_ref!==n.scope_ref)throw new Error("central terminal original binding changed");const p=await t.store.receipt({...e,binding:a});if(s(),!p?.terminal||o.receipt&&!isDeepStrictEqual(p,o.receipt))throw new Error("central terminal outcome is unknown");return o.request&&(assertCentralNativeReceipt(o.request,p),await t.pending.complete(o.request,p)),await this.settleJournal(a.operationId),p}const c=await t.store.load(a);if(c.terminal?.response_id===a.responseId)throw new Error("original Response is already terminal; reconcile its original receipt before native execution");const p="completed"!==c.terminal?.status;if(s(),e.signal.aborted)throw new Error("central native execution stopped before dispatch; original owner stop reconciliation is required");let d=await t.journal.get(a.operationId);if(d&&("session.prompt"!==d.command||d.paramsHash!==r.paramsHash||d.runtimeEpoch!==e.lease.runtimeEpoch||"prepared"!==d.phase))throw new Error("central native execution already started; original terminal reconciliation is required");if(d=await t.journal.acceptMessageRequest({operationId:a.operationId,command:"session.prompt",paramsHash:r.paramsHash,runtimeEpoch:e.lease.runtimeEpoch,requestMessageId:r.requestMessageId,requestHash:r.requestHash}),s(),await t.journal.transition({operationId:a.operationId,expectedRevision:d.revision,phase:"started"}),e.signal.aborted)throw new Error("central native execution stopped before dispatch; original owner stop reconciliation is required");const l=await t.host.run({params:structuredClone(n),binding:a,requestMessageId:r.requestMessageId,signal:e.signal,assertCurrent:s});s();const m=await t.pending.terminal(a);if(!m?.receipt||!m.receipt.terminal||m.receipt.terminal.status!==l.status)throw new Error("native owner did not confirm its original atomic suffix/terminal transaction");const u=await t.store.receipt({binding:a,idempotencyKey:m.receipt.idempotency_key,payloadDigest:m.receipt.payload_sha256});if(s(),!u||!isDeepStrictEqual(u,m.receipt))throw new Error("original native terminal receipt is unavailable");return await this.settleJournal(a.operationId),"completed"===l.status&&p&&t.recordGeneratedTitle?.({binding:a,question:promptText(n),answer:l.finalText??""}),u}async settleJournal(e){let t=await this.options.journal.get(e);"started"===t?.phase&&(t=await this.options.journal.transition({operationId:e,expectedRevision:t.revision,phase:"effect_committed"})),"effect_committed"===t?.phase&&await this.options.journal.transition({operationId:e,expectedRevision:t.revision,phase:"projection_committed"})}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isDeepStrictEqual}from"node:util";import{centralApprovalGate}from"./central-native-interactions.js";import{CENTRAL_NATIVE_ENGINE_ID,CentralNativeContextEngine,assertCentralNativeReceipt}from"./central-native-context-engine.js";let current;export function installCentralNativeRuntime(e){if(current)throw new Error("central native runtime already installed");const n=new Map,t=new Set,r=new Map;let i=!1;const o=new CentralNativeContextEngine({store:e.store,pending:e.pending,resolveBinding:e=>{const t=n.get(e);if(!t)throw new Error("central native session has no authorized binding");return t},compact:n=>e.host.compactNativeTranscript(n),readNativeEvents:async n=>e.host.readNativeTranscript({sessionKey:n}),onReceipt:(e,n)=>{r.get(e.operationId)?.terminal&&!n.terminal||r.set(e.operationId,n)}}),s=async(r,s,a)=>{if(i)throw new Error("central native admission is closed for drain");if(t.delete(r),a&&(0!==(await e.pending.list(s.sessionId)).length||0!==e.host.pendingNativeTurns({sessionKey:r})))throw new Error("prior native owner must drain pending writes before read-only preparation");n.set(r,structuredClone(s));let c=await o.hydrateNativeSession({sessionKey:r});if(a||0===e.host.pendingNativeTurns({sessionKey:r})||(await e.host.drainNativeTurns({sessionKey:r,engine:o.forBindings(()=>structuredClone(s))}),c=await o.hydrateNativeSession({sessionKey:r})),await e.host.replaceNativeTranscript({sessionKey:r,events:c.events}),!isDeepStrictEqual(e.host.readNativeTranscript({sessionKey:r}),c.events))throw new Error("native host did not reconstruct the exact central transcript");t.add(r)};return current={get engine(){if(i)throw new Error("central native admission is closed for drain");const e=new Map([...n].map(([e,n])=>[e,structuredClone(n)]));return o.forBindings(n=>{const t=e.get(n);if(!t)throw new Error("central native run has no pinned session authority");return t})},prepare:(e,n)=>s(e,n,!1),prepareReadOnly:(e,n)=>s(e,n,!0),readEvents(n){if(!t.has(n))throw new Error("central native session is not prepared");return e.host.readNativeTranscript({sessionKey:n,visibleOnly:!0})},receipt:e=>r.get(e),source:e=>o.source(e),bindExecutionObservation:(n,t)=>e.observe(n,t),async drain(){if(i=!0,0!==e.activeWriters())throw new Error("native writers have not quiesced");for(const t of await e.pending.list()){const r=[...n.values()].find(e=>e.sessionId===t.binding.sessionId);if(!r)throw new Error("pending native append has no current authorized session");const i=await e.store.receipt({...t,binding:{...t.binding,context:r.context}});if(!i)throw new Error("native append drain outcome is unknown");assertCentralNativeReceipt(t,i),await e.pending.complete(t,i)}const t=[];for(const[r,i]of n){if(!e.host.nativeWritersQuiescent({sessionKey:r}))throw new Error("native session writer is still admitted");if(await o.hydrateNativeSession({sessionKey:r}),await e.host.drainNativeTurns({sessionKey:r,engine:o.forBindings(()=>structuredClone(i))}),0!==e.host.pendingNativeTurns({sessionKey:r}))throw new Error("native accepted-turn outbox has pending writes");const n=await e.store.load(i);t.push({sessionId:i.sessionId,historyGeneration:i.historyGeneration,branchId:i.branchId,watermark:n.watermark})}if(0!==e.activeWriters()||0!==(await e.pending.list()).length)throw new Error("native writes appeared during drain");return{pendingWrites:0,sourceWatermarks:t}}},current}export function centralNativeRuntime(){if(!current)throw new Error("central native SDK/store startup composition is unavailable");return current}export function centralNativeChatEnabled(e=process.env){return"honcho"===e.BEEOS_CHAT_STORE}const unsupportedCentralNativeTools=new Set(["memory_search","memory_get","cron","beeos_automation_create","beeos_automation_create_webhook","beeos_automation_run","sessions_spawn","sessions_send","conversations_turn","conversations_send","subagents"]);export function centralNativeToolFence(e){if(!e||"object"!=typeof e)return;const n=e.toolName;return"string"==typeof n&&unsupportedCentralNativeTools.has(n)?{block:!0,blockReason:"Central Memory/background execution producer is unavailable for this native tool"}:void 0}export function registerCentralNativeContextEngine(e){if(centralNativeChatEnabled()){if(!e.registerContextEngine||!e.on)throw new Error("pinned central context engine/tool policy registration API unavailable");e.on("before_tool_call",centralNativeToolFence),e.on("before_tool_call",centralApprovalGate),e.registerContextEngine(CENTRAL_NATIVE_ENGINE_ID,()=>centralNativeRuntime().engine)}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{generateTitleFromQA}from"./conversation-title.js";export const GENERATED_NAME_LIMIT=64;const object=e=>null!==e&&"object"==typeof e&&!Array.isArray(e);export function generatedSessionName(e){return[...e.replace(/\s+/gu," ").trim()].filter(e=>{const t=e.codePointAt(0)??0;return t>=32&&127!==t}).slice(0,64).join("").trim()}export class RuntimeLeaseHttpSessionTitles{http;constructor(e){this.http=e}async title(e,t){const r=await this.http.postJson("/api/v1/runtime/session/title",e,t),n=await r.text();if(!r.ok){let e="";try{const t=JSON.parse(n);e=object(t)&&object(t.error)&&"string"==typeof t.error.code?t.error.code:""}catch{e=""}throw new Error(`generated Session title failed (HTTP ${r.status}${e?` ${e}`:""})`)}let o;try{o=JSON.parse(n)}catch{throw new Error("generated Session title returned invalid JSON")}const i=object(o)?o:{};if(i.session_id!==t.session_id||"boolean"!=typeof i.applied||"string"!=typeof i.name||!["manual","generated","provisional",""].includes(String(i.name_source))||!Number.isSafeInteger(i.resource_version))throw new Error("generated Session title answered for another or malformed Session");return{session_id:i.session_id,applied:i.applied,name:i.name,name_source:i.name_source,resource_version:i.resource_version}}}export async function generateAndRecordSessionTitle(e){const{binding:t,logger:r}=e,n=`central-title sid=${t.sessionId}`,o=e.question.trim(),i=e.answer.trim();if(o&&i)try{const s=e.resolveModelCredential();if(!s)return void r?.info?.(`[${n}] SKIP: the Agent has no configured model credential`);const a=await generateTitleFromQA(o,i,{logger:r,logPrefix:n,credentials:s});if(!a)return;const c=generatedSessionName(a);if(!c)return void r?.info?.(`[${n}] SKIP: generated title has no printable characters`);const l=await e.recordGeneratedTitle(t,c);return r?.info?.(`[${n}] ${l.applied?"applied":"kept"} name_source=${l.name_source}`),l}catch(e){return void r?.warn?.(`[${n}] failed: ${e instanceof Error?e.message:String(e)}`)}else r?.debug?.(`[${n}] SKIP: no completed question/answer`)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function centralNativeSessionKey(e,n){return`agent:${e}:central:${n}`}export function centralSessionIdFromSessionKey(e){return e?/^agent:[^:]+:central:(.+)$/.exec(e)?.[1]:void 0}export function canvasEnsureTarget(e,n){const s=centralSessionIdFromSessionKey(e);return s?{sessionId:s,opts:{}}:{sessionId:e,opts:n}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomUUID}from"node:crypto";const TITLE_SYSTEM_PROMPT_BASE='You are a conversation title generator. Your task is to generate a concise, human-readable title summarizing the topic of the user\'s question together with the assistant\'s answer.\n\n### Rules:\n- Length: 3-6 words in English, or 6-20 characters in Chinese/Japanese/Korean/Thai (up to 24 if needed to keep all key domain terms intact).\n- Language: When a Client UI locale is provided below, write the title in THAT language even if the user wrote in a different language (translate the topic). Otherwise match the user\'s input language exactly. Mixed zh/en input → use the dominant language. Do NOT switch languages away from the required locale.\n- Extract the core topic (noun-centric) of the Q&A exchange, not the action verb.\n- Use the assistant\'s answer to disambiguate or enrich the topic when the question alone is vague (e.g. "帮我看下" + an answer about x402 → "x402 支付集成").\n- No punctuation, no quotation marks, no emojis, no markdown.\n- No prefix like "Title:" or "Here is". Output the title only.\n- Avoid generic words: "help", "question", "chat", "problem", "task".\n- Greetings and self-introductions ARE concrete topics — never treat them as vague. Prefer the locale-native self-intro title from the Client UI locale section when present.\n- NEVER return placeholder / empty-chat titles such as "新会话", "新對話", "New chat", "New Conversation", "新しいチャット", "새 채팅", "แชตใหม่". Always invent a concrete noun-centric topic from whatever words are present.\n\n### Input Format:\nThe user message will contain both the question and the assistant\'s answer, delimited like this:\n[User Question]\n...question text...\n\n[Assistant Answer]\n...answer text (may be truncated with "..." in the middle)...\n\n### Output Format:\nRespond ONLY with valid JSON, no other text:\n{"title": "<your title here>"}\n\n### Examples:\nInput:\n[User Question]\n帮我写一个关于BeeOS设备接入的PRD\n\n[Assistant Answer]\n好的,这是 BeeOS 设备接入 PRD 的草稿:1. 目标 ...\nOutput: {"title": "BeeOS 设备接入 PRD"}\n\nInput:\n[User Question]\n帮我看下\n\n[Assistant Answer]\n你说的 x402 支付协议是一个基于 HTTP 402 的链上支付标准 ...\nOutput: {"title": "x402 支付协议解析"}\n\nInput:\n[User Question]\nWhat\'s the best way to integrate x402 payment protocol?\n\n[Assistant Answer]\nYou have three options: 1. Use the official SDK ...\nOutput: {"title": "x402 Payment Integration"}\n\nInput:\n[User Question]\n用一句话介绍一下你自己。\n\n[Assistant Answer]\n我是 BeeOS 智能助手,可以帮助你完成设备控制与任务协作。\nOutput: {"title": "自我介绍"}\n\nInput:\n[User Question]\nhi\n\n[Assistant Answer]\nHello! How can I help you today?\nOutput: {"title": "Greeting"}',SELF_INTRO_BY_LOCALE={zh:"自我介绍","zh-TW":"自我介紹",ja:"自己紹介",ko:"자기소개",th:"แนะนำตัว",en:"Self Introduction"},SELF_INTRO_ALIASES=new Set(Object.values(SELF_INTRO_BY_LOCALE).map(e=>e.toLowerCase())),LOCALE_PROMPT_HINT={zh:'zh (简体中文) — write the title in Simplified Chinese. Self-intro → "自我介绍".',"zh-TW":'zh-TW (繁體中文) — write the title in Traditional Chinese. Self-intro → "自我介紹".',ja:'ja (日本語) — write the title in Japanese. Self-intro → "自己紹介". Never use Chinese "自我介绍".',ko:'ko (한국어) — write the title in Korean. Self-intro → "자기소개".',th:'th (ไทย) — write the title in Thai. Self-intro → "แนะนำตัว".',en:'en (English) — write the title in English. Self-intro → "Self Introduction".'},TITLE_TEMPLATES=[{match:["今日日报","日报"],zh:"今日工作日报",en:"Daily Work Log"},{match:["周报","周报总结","本周周报"],zh:"本周工作周报",en:"Weekly Work Report"},{match:["月报","月度汇报","月度总结"],zh:"本月工作月报",en:"Monthly Work Report"},{match:["工作日志","日志"],zh:"工作日志整理",en:"Work Log Review"},{match:["晨会","今日晨会"],zh:"今日晨会纪要",en:"Daily Standup Notes"},{match:["复盘","今日复盘"],zh:"今日工作复盘",en:"Daily Retrospective"}],PLACEHOLDER_TITLES=new Set(["new chat","new conversation","新会话","新對話","新しいチャット","새 채팅","แชตใหม่"]),PLACEHOLDER_TO_LOCALE={"new chat":"en","new conversation":"en","新会话":"zh","新對話":"zh-TW","新しいチャット":"ja","새 채팅":"ko","แชตใหม่":"th"};export function inferTitleLocaleFromPlaceholder(e){if(!e)return;const t=e.trim().toLowerCase();return PLACEHOLDER_TO_LOCALE[t]??PLACEHOLDER_TO_LOCALE[e.trim()]}export function buildTitleSystemPrompt(e){return e?`${TITLE_SYSTEM_PROMPT_BASE}\n\n### Client UI locale\n${LOCALE_PROMPT_HINT[e]}\nCRITICAL: The title language MUST match this locale, even when [User Question] is in another language.`:TITLE_SYSTEM_PROMPT_BASE}export function alignTitleWithLocale(e,t){return t&&SELF_INTRO_ALIASES.has(e.trim().toLowerCase())?SELF_INTRO_BY_LOCALE[t]:e}export function isPlaceholderTitle(e){if(!e)return!0;const t=e.trim();return!t||(!!PLACEHOLDER_TITLES.has(t.toLowerCase())||(!!/^[0-9a-f]{6,12}\s*\(20\d{2}/i.test(t)||(!!/^Sender\s*\(untrusted/i.test(t)||!!/^Conversation\s+info\s*\(untrusted/i.test(t))))}export function isGuardMessage(e){const t=e.trim();return[...t].length<3||[...t].every(e=>/[\p{P}\p{S}\s]/u.test(e))}export function matchTitleTemplate(e){const t=e.trim().toLowerCase();for(const n of TITLE_TEMPLATES)if(n.match.some(e=>e.toLowerCase()===t))return/[\u4e00-\u9fff]/.test(e)?n.zh:n.en}function truncateQuestionForTitle(e){return e.length>2e3?e.slice(0,1500):e}function truncateAnswerForTitle(e){return e.length<=1e3?e:`${e.slice(0,500)}\n...\n${e.slice(-500)}`}export function fallbackTitleFromQuestion(e){const t=e.replace(/[\r\n\t]+/g," ").replace(/[。!?.!?…]+$/u,"").trim();if(!t||isGuardMessage(t)||isPlaceholderTitle(t))return;const n=[...t];return n.length<=20?t:n.slice(0,18).join("")}export async function generateTitleFromQA(e,t,n,i="title-gen"){let o,r,a=i;if(n&&("locale"in n||"logPrefix"in n||"logger"in n)){const e=n;o=e.logger,
|
|
1
|
+
import{randomUUID}from"node:crypto";const TITLE_SYSTEM_PROMPT_BASE='You are a conversation title generator. Your task is to generate a concise, human-readable title summarizing the topic of the user\'s question together with the assistant\'s answer.\n\n### Rules:\n- Length: 3-6 words in English, or 6-20 characters in Chinese/Japanese/Korean/Thai (up to 24 if needed to keep all key domain terms intact).\n- Language: When a Client UI locale is provided below, write the title in THAT language even if the user wrote in a different language (translate the topic). Otherwise match the user\'s input language exactly. Mixed zh/en input → use the dominant language. Do NOT switch languages away from the required locale.\n- Extract the core topic (noun-centric) of the Q&A exchange, not the action verb.\n- Use the assistant\'s answer to disambiguate or enrich the topic when the question alone is vague (e.g. "帮我看下" + an answer about x402 → "x402 支付集成").\n- No punctuation, no quotation marks, no emojis, no markdown.\n- No prefix like "Title:" or "Here is". Output the title only.\n- Avoid generic words: "help", "question", "chat", "problem", "task".\n- Greetings and self-introductions ARE concrete topics — never treat them as vague. Prefer the locale-native self-intro title from the Client UI locale section when present.\n- NEVER return placeholder / empty-chat titles such as "新会话", "新對話", "New chat", "New Conversation", "新しいチャット", "새 채팅", "แชตใหม่". Always invent a concrete noun-centric topic from whatever words are present.\n\n### Input Format:\nThe user message will contain both the question and the assistant\'s answer, delimited like this:\n[User Question]\n...question text...\n\n[Assistant Answer]\n...answer text (may be truncated with "..." in the middle)...\n\n### Output Format:\nRespond ONLY with valid JSON, no other text:\n{"title": "<your title here>"}\n\n### Examples:\nInput:\n[User Question]\n帮我写一个关于BeeOS设备接入的PRD\n\n[Assistant Answer]\n好的,这是 BeeOS 设备接入 PRD 的草稿:1. 目标 ...\nOutput: {"title": "BeeOS 设备接入 PRD"}\n\nInput:\n[User Question]\n帮我看下\n\n[Assistant Answer]\n你说的 x402 支付协议是一个基于 HTTP 402 的链上支付标准 ...\nOutput: {"title": "x402 支付协议解析"}\n\nInput:\n[User Question]\nWhat\'s the best way to integrate x402 payment protocol?\n\n[Assistant Answer]\nYou have three options: 1. Use the official SDK ...\nOutput: {"title": "x402 Payment Integration"}\n\nInput:\n[User Question]\n用一句话介绍一下你自己。\n\n[Assistant Answer]\n我是 BeeOS 智能助手,可以帮助你完成设备控制与任务协作。\nOutput: {"title": "自我介绍"}\n\nInput:\n[User Question]\nhi\n\n[Assistant Answer]\nHello! How can I help you today?\nOutput: {"title": "Greeting"}',SELF_INTRO_BY_LOCALE={zh:"自我介绍","zh-TW":"自我介紹",ja:"自己紹介",ko:"자기소개",th:"แนะนำตัว",en:"Self Introduction"},SELF_INTRO_ALIASES=new Set(Object.values(SELF_INTRO_BY_LOCALE).map(e=>e.toLowerCase())),LOCALE_PROMPT_HINT={zh:'zh (简体中文) — write the title in Simplified Chinese. Self-intro → "自我介绍".',"zh-TW":'zh-TW (繁體中文) — write the title in Traditional Chinese. Self-intro → "自我介紹".',ja:'ja (日本語) — write the title in Japanese. Self-intro → "自己紹介". Never use Chinese "自我介绍".',ko:'ko (한국어) — write the title in Korean. Self-intro → "자기소개".',th:'th (ไทย) — write the title in Thai. Self-intro → "แนะนำตัว".',en:'en (English) — write the title in English. Self-intro → "Self Introduction".'},TITLE_TEMPLATES=[{match:["今日日报","日报"],zh:"今日工作日报",en:"Daily Work Log"},{match:["周报","周报总结","本周周报"],zh:"本周工作周报",en:"Weekly Work Report"},{match:["月报","月度汇报","月度总结"],zh:"本月工作月报",en:"Monthly Work Report"},{match:["工作日志","日志"],zh:"工作日志整理",en:"Work Log Review"},{match:["晨会","今日晨会"],zh:"今日晨会纪要",en:"Daily Standup Notes"},{match:["复盘","今日复盘"],zh:"今日工作复盘",en:"Daily Retrospective"}],PLACEHOLDER_TITLES=new Set(["new chat","new conversation","新会话","新對話","新しいチャット","새 채팅","แชตใหม่"]),PLACEHOLDER_TO_LOCALE={"new chat":"en","new conversation":"en","新会话":"zh","新對話":"zh-TW","新しいチャット":"ja","새 채팅":"ko","แชตใหม่":"th"};export function inferTitleLocaleFromPlaceholder(e){if(!e)return;const t=e.trim().toLowerCase();return PLACEHOLDER_TO_LOCALE[t]??PLACEHOLDER_TO_LOCALE[e.trim()]}export function buildTitleSystemPrompt(e){return e?`${TITLE_SYSTEM_PROMPT_BASE}\n\n### Client UI locale\n${LOCALE_PROMPT_HINT[e]}\nCRITICAL: The title language MUST match this locale, even when [User Question] is in another language.`:TITLE_SYSTEM_PROMPT_BASE}export function alignTitleWithLocale(e,t){return t&&SELF_INTRO_ALIASES.has(e.trim().toLowerCase())?SELF_INTRO_BY_LOCALE[t]:e}export function isPlaceholderTitle(e){if(!e)return!0;const t=e.trim();return!t||(!!PLACEHOLDER_TITLES.has(t.toLowerCase())||(!!/^[0-9a-f]{6,12}\s*\(20\d{2}/i.test(t)||(!!/^Sender\s*\(untrusted/i.test(t)||!!/^Conversation\s+info\s*\(untrusted/i.test(t))))}export function isGuardMessage(e){const t=e.trim();return[...t].length<3||[...t].every(e=>/[\p{P}\p{S}\s]/u.test(e))}export function matchTitleTemplate(e){const t=e.trim().toLowerCase();for(const n of TITLE_TEMPLATES)if(n.match.some(e=>e.toLowerCase()===t))return/[\u4e00-\u9fff]/.test(e)?n.zh:n.en}function truncateQuestionForTitle(e){return e.length>2e3?e.slice(0,1500):e}function truncateAnswerForTitle(e){return e.length<=1e3?e:`${e.slice(0,500)}\n...\n${e.slice(-500)}`}export function fallbackTitleFromQuestion(e){const t=e.replace(/[\r\n\t]+/g," ").replace(/[。!?.!?…]+$/u,"").trim();if(!t||isGuardMessage(t)||isPlaceholderTitle(t))return;const n=[...t];return n.length<=20?t:n.slice(0,18).join("")}export function chatCompletionsUrl(e){const t=e.replace(/\/$/,"");return t.endsWith("/chat/completions")?t:t.endsWith("/v1")?`${t}/chat/completions`:`${t}/v1/chat/completions`}export async function generateTitleFromQA(e,t,n,i="title-gen"){let o,r,a,s=i;if(n&&("locale"in n||"logPrefix"in n||"logger"in n||"credentials"in n)){const e=n;o=e.logger,s=e.logPrefix??"title-gen",a=e.credentials,r=e.locale}else o=n;if(isGuardMessage(e))return void o?.info?.(`[${s}] SKIP guard message`);const l=matchTitleTemplate(e);if(l){const e=alignTitleWithLocale(l,r);return o?.info?.(`[${s}] template title="${e}"`),e}const c=a?.baseUrl||process.env.AROUTER_BASE_URL||"",u=a?.apiKey||process.env.AROUTER_API_KEY||"";if(!c||!u)return void o?.info?.(`[${s}] SKIP: no Agent model credential`);const h=`[User Question]\n${truncateQuestionForTitle(e)}\n\n[Assistant Answer]\n${truncateAnswerForTitle(t)}`;o?.info?.(`[${s}] CALLING LLM q="${e.slice(0,60)}" aLen=${t.length}${r?` locale=${r}`:""}`);try{const t=await fetch(chatCompletionsUrl(c),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${u}`},body:JSON.stringify({model:"openai/gpt-4o-mini",max_tokens:32,temperature:.3,messages:[{role:"system",content:buildTitleSystemPrompt(r)},{role:"user",content:h}]})});if(!t.ok){const e=await t.text().catch(()=>"");return void o?.info?.(`[${s}] FAILED status=${t.status} body=${e.slice(0,300)}`)}const n=await t.json(),i=n.choices?.[0]?.message?.content?.trim();if(!i)return;const a=i.replace(/^```json\s*/,"").replace(/```$/,"").trim();let l;try{l=JSON.parse(a).title?.trim()??""}catch{return void o?.debug?.(`[${s}] JSON parse failed: ${a}`)}if(!l||isPlaceholderTitle(l)){const t=fallbackTitleFromQuestion(e);if(t){const n=alignTitleWithLocale(t,r),i=r&&n===t&&/介绍一下你自己|介紹一下你自己|introduce yourself|自己紹介|자기소개/i.test(e)?SELF_INTRO_BY_LOCALE[r]:n;return o?.info?.(`[${s}] discarded placeholder/empty title="${l}"; fallback="${i}"`),i}return void o?.info?.(`[${s}] discarded placeholder/empty title="${l}"`)}const d=alignTitleWithLocale(l,r);return o?.info?.(d!==l?`[${s}] OK title="${l}" → locale-aligned="${d}"`:`[${s}] OK title="${l}"`),d}catch(e){return void o?.info?.(`[${s}] ERROR: ${e instanceof Error?e.message:e}`)}}export function createConversationTitleRenameIntent(e,t){return Object.freeze({conversationId:e,title:t,commandId:randomUUID()})}export async function patchMsConversationTitle(e,t){const n=e.conversations;if(!n)throw new Error("conversation title administration is unavailable");await n.update({conversationId:t.conversationId,title:t.title,idempotencyKey:t.commandId})}export async function maybeRenameImConversationTitle(e){const{client:t,conversationId:n,question:i,answer:o,logger:r}=e,a=`im-title-gen conv=${n}`;if(!n||!i.trim()||!o.trim())return void r?.debug?.(`[${a}] SKIP missing conversation/q/a`);const s=t.conversations;if(!s)return void r?.debug?.(`[${a}] SKIP conversation admin unavailable`);let l;try{l=(await s.get(n)).title}catch(e){return void r?.info?.(`[${a}] GET conversation failed: ${e instanceof Error?e.message:e}`)}if(!isPlaceholderTitle(l))return void r?.debug?.(`[${a}] SKIP non-placeholder title="${l}"`);const c=inferTitleLocaleFromPlaceholder(l),u=await generateTitleFromQA(i,o,{logger:r,logPrefix:a,locale:c});if(!u)return;const h=createConversationTitleRenameIntent(n,u);try{return await patchMsConversationTitle(t,h),r?.info?.(`[${a}] PATCH MS title OK title="${u}"`),u}catch(e){return void r?.info?.(`[${a}] PATCH MS title FAILED: ${e instanceof Error?e.message:e}`)}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readFile}from"node:fs/promises";export const IDENTITY_LANE_URL_ENV="BEEOS_RUNTIME_IDENTITY_LANE_URL";export const IDENTITY_LANE_TOKEN_FILE_ENV="BEEOS_RUNTIME_IDENTITY_LANE_TOKEN_FILE";export class IdentityLaneLeaseClient{url;tokenFile;fetchImpl;constructor(e,t,r=fetch){this.url=e,this.tokenFile=t,this.fetchImpl=r}async read(){const e=(await readFile(this.tokenFile,"utf8")).trim(),t=await this.fetchImpl(this.url.replace(/\/+$/,"")+"/lease",{method:"POST",redirect:"error",headers:{authorization:`Bearer ${e}`,"content-type":"application/json"},body:"{}"}),r=await t.json();if(200!==t.status)return{snapshot:null,reason:"string"==typeof r.error_reason?r.error_reason:`HTTP ${t.status}`};const n=e=>{const t=r[e];if("string"!=typeof t||!t)throw new Error(`identity lane lease lacks ${e}`);return t},i=n("journal_generation"),a=n("runtime_epoch");if(!/^[1-9][0-9]*$/.test(i)||!/^[1-9][0-9]*$/.test(a))throw new Error("identity lane lease has an invalid lineage");const s={instanceId:n("instance_id"),leaseId:n("lease_id"),runtimeEpoch:a,runtimeLeaseCredential:n("runtime_lease_credential"),leaseExpiresAt:n("lease_expires_at"),handlerIdentity:n("handler_identity")};return Date.parse(s.leaseExpiresAt)>Date.now()?{snapshot:{lease:s,registrationId:n("registration_id"),journalStoreId:n("journal_store_id"),journalGeneration:i}}:{snapshot:null,reason:"identity lane lease expired"}}}export function claimedSandboxId(e=process.env){if(!identityLaneFromEnvironment(e))return;const t=e.BEEOS_INSTANCE_ID?.trim();if(!t)throw new Error("identity lane requires the claimed BEEOS_INSTANCE_ID");return t}export function identityLaneFromEnvironment(e=process.env){const t=e[IDENTITY_LANE_URL_ENV]?.trim();if(!t)return;const r=e[IDENTITY_LANE_TOKEN_FILE_ENV]?.trim();if(!r)throw new Error("identity lane token file is required with its URL");return new IdentityLaneLeaseClient(t,r)}
|