beeos-claw 0.5.72 → 0.5.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/errors/classify.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const ERROR_PATTERNS={billing:[/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|\b(?:got|returned|received)\s+(?:a\s+)?402\b|^\s*402\s+payment/i,"payment required","insufficient credits",/insufficient[_ ]quota/i,"credit balance","plans & billing","insufficient balance","insufficient usd or diem balance","billing error","add more credits"],rateLimit:[/rate[_ ]limit|too many requests|429/,"model_cooldown","exceeded your current quota","resource has been exhausted","quota exceeded","resource_exhausted","usage limit",/\btpm\b/i,"tokens per minute","tokens per day"],overloaded:[/overloaded_error|"type"\s*:\s*"overloaded_error"/i,"overloaded",/service[_ ]unavailable.*(?:overload|capacity|high[_ ]demand)|(?:overload|capacity|high[_ ]demand).*service[_ ]unavailable/i,"high demand"],timeout:["timeout","timed out","service unavailable","deadline exceeded","connection error","network error","network request failed","fetch failed","socket hang up",/\beconn(?:refused|reset|aborted)\b/i,/\benotfound\b/i],auth:[/invalid[_ ]?api[_ ]?key/,"incorrect api key","invalid token","unauthorized","forbidden","access denied","insufficient permissions",/\b401\b/,/\b403\b/,"no credentials found","no api key found",/api[_ ]?key[_ ]?(?:revoked|invalid|deactivated|deleted)/i,"invalid_api_key","key has been disabled","permission_error"],contextOverflow:["request_too_large","context length exceeded","maximum context length","prompt is too long","exceeds model context window","context overflow:","context_window_exceeded"]};function matchesPatterns(e,t){if(!e)return!1;const
|
|
1
|
+
const ERROR_PATTERNS={modelCapability:["no endpoints found that support image","support image input","unknown variant image_url","model is not registered","model_not_found","no alias rule matches",/does not support (?:image|vision|multimodal)/i],billing:[/["']?(?:status|code)["']?\s*[:=]\s*402\b|\bhttp\s*402\b|\berror(?:\s+code)?\s*[:=]?\s*402\b|\b(?:got|returned|received)\s+(?:a\s+)?402\b|^\s*402\s+payment/i,"payment required","insufficient credits",/insufficient[_ ]quota/i,"credit balance","plans & billing","insufficient balance","insufficient usd or diem balance","billing error","add more credits"],rateLimit:[/rate[_ ]limit|too many requests|429/,"model_cooldown","exceeded your current quota","resource has been exhausted","quota exceeded","resource_exhausted","usage limit",/\btpm\b/i,"tokens per minute","tokens per day"],overloaded:[/overloaded_error|"type"\s*:\s*"overloaded_error"/i,"overloaded",/service[_ ]unavailable.*(?:overload|capacity|high[_ ]demand)|(?:overload|capacity|high[_ ]demand).*service[_ ]unavailable/i,"high demand"],timeout:["timeout","timed out","service unavailable","deadline exceeded","connection error","network error","network request failed","fetch failed","socket hang up",/\beconn(?:refused|reset|aborted)\b/i,/\benotfound\b/i],auth:[/invalid[_ ]?api[_ ]?key/,"incorrect api key","invalid token","unauthorized","forbidden","access denied","insufficient permissions",/\b401\b/,/\b403\b/,"no credentials found","no api key found",/api[_ ]?key[_ ]?(?:revoked|invalid|deactivated|deleted)/i,"invalid_api_key","key has been disabled","permission_error"],contextOverflow:["request_too_large","context length exceeded","maximum context length","prompt is too long","exceeds model context window","context overflow:","context_window_exceeded"]};function matchesPatterns(e,t){if(!e)return!1;const i=e.toLowerCase();return t.some(e=>e instanceof RegExp?e.test(i):i.includes(e))}function classifyErrorReason(e){return e?matchesPatterns(e,ERROR_PATTERNS.modelCapability)?"model_capability":matchesPatterns(e,ERROR_PATTERNS.billing)?"billing":matchesPatterns(e,ERROR_PATTERNS.contextOverflow)?"context_overflow":matchesPatterns(e,ERROR_PATTERNS.rateLimit)?"rate_limit":matchesPatterns(e,ERROR_PATTERNS.overloaded)?"overloaded":matchesPatterns(e,ERROR_PATTERNS.timeout)?"timeout":matchesPatterns(e,ERROR_PATTERNS.auth)?"auth":null:null}const FRIENDLY_MESSAGES={model_capability:"The selected model cannot handle this request (for example image input is not supported, or the model id is not registered). Switch to a vision-capable model such as Gemini or GPT-4o and try again.",billing:"API provider returned a billing error — your API key may have run out of credits or has an insufficient balance. Check your provider's billing dashboard and top up, or switch to a different API key.",rate_limit:"API rate limit reached. Please wait a moment and try again.",auth:"API authentication failed — your API key may be invalid, revoked, or lacking permissions. Check your provider settings.",timeout:"LLM request timed out or the service is temporarily unavailable. Please try again.",overloaded:"The AI service is temporarily overloaded. Please try again in a moment.",context_overflow:"Context overflow: prompt too large for the model. Try starting a fresh session or use a model with a larger context window."};export function formatFriendlyError(e){if(!e)return e;if(e.startsWith("⚠️"))return matchesPatterns(e,ERROR_PATTERNS.modelCapability)?FRIENDLY_MESSAGES.model_capability:e;const t=classifyErrorReason(e);return t?FRIENDLY_MESSAGES[t]:e}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash,randomUUID}from"node:crypto";import{dispatchRuntimeReplyWithRoute,hasRuntimeReplyApi}from"./runtime/reply-router.js";import{createImReplySink}from"./runtime/im-reply-sink.js";import{SerializedCallbackQueue}from"./runtime/callback-queue.js";import{promptRunKey}from"./runtime/prompt-run-store.js";import{classifyAgentRuntimeFailure}from"./runtime/agent-runtime-failure-classifier.js";import{SESSION_RECOVERY_REQUIRED_CODE,SESSION_RECOVERY_REQUIRED_MESSAGE}from"./runtime/session-mutation-coordinator.js";import{interceptAgentRuntimeFailures,messageStopReasonForRuntimeFailure,SESSION_BUSY_PUBLIC_MESSAGE}from"./runtime/im-runtime-failure-policy.js";const normalizePromptTimeoutMs=e=>{if("number"!=typeof e||!Number.isFinite(e))return;const n=Math.max(0,Math.trunc(e));return n>0?n:void 0},formatErrMessage=e=>{if(e instanceof Error)return e.message;if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}},deterministicMessageId=(e,n,r,a)=>`${e}_${createHash("sha256").update(`${n}:${r}:${a}`).digest("hex").slice(0,32)}`;export const dispatchImInboundPrompt=async e=>{const{runtime:n,prompt:r,client:a,logger:t,promptRunStore:i,sessionMutationCoordinator:s,abortTransport:o,activeRunAuthority:d}=e;if(!hasRuntimeReplyApi(n))return t.warn?.(`[im] runtime dispatch skipped reason=reply_api_unavailable channel=${r.channelId} in_reply_to=${r.inboundMessageId}`),e.onLifecycleEvent?.({type:"skipped",reason:"reply_api_unavailable",channelId:r.channelId,inboundMessageId:r.inboundMessageId}),!1;const c=`im_req_${randomUUID().replace(/-/g,"")}`,l=randomUUID(),u=Date.now(),m=e.origin??"im",p={protocol:"im",requestId:c,sessionId:r.sessionKey??"agent:main",sourceMessageId:r.inboundMessageId,chatId:r.channelId,origin:m},I=normalizePromptTimeoutMs(e.promptTimeoutMs),h=promptRunKey(r.channelId,r.inboundMessageId),g=r.sessionKey??"agent:main",y=new AbortController;let _,f,E;const b=new Promise((e,n)=>{E=n}),R=async e=>{if(f??=e,y.abort(e),!_)return{ok:!0};const n=await s.requestCancel(_,o);return n.ok?n.terminalObservation.then(e=>{e.ok||E(new Error(SESSION_RECOVERY_REQUIRED_CODE))}):E(new Error(SESSION_RECOVERY_REQUIRED_CODE)),{ok:n.ok}};if(!i.register(h,{requestId:c,channelId:r.channelId,requestCancel:R,startedAt:u,sessionKey:g}))return t.warn?.(`[im] runtime dispatch rejected duplicate inboundMessageId=${r.inboundMessageId} requestId=${c} channel=${r.channelId}`),e.onLifecycleEvent?.({type:"dispatch_error",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,error:"duplicate_inbound_message_id",cause:"abort"}),!1;const $=a.messages.startStream({conversationId:r.channelId,id:deterministicMessageId("asst",r.channelId,r.inboundMessageId,r.selfPrincipalId),replyTo:e.inReplyTo??r.inboundMessageId,type:"agent_reply"},{onError:(e,n)=>{const a="terminal"===n?t.warn:t.debug;a?.(`[im] runtime stream ${n} PATCH error requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId}: ${e.message}`)}},{sender:r.selfPrincipalId});let w,M=!1;try{M=!0===(await $.opened()).idempotent}catch(e){t.debug?.(`[im] runtime reply stream open probe failed requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId}: ${formatErrMessage(e)}; continuing so terminal fallback can land an error row`)}if(M)return t.info?.(`[im] runtime dispatch skipped existing deterministic reply requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId}`),e.onLifecycleEvent?.({type:"skipped",reason:"idempotent_reply_exists",channelId:r.channelId,inboundMessageId:r.inboundMessageId}),i.unregister(h),!1;const S=new SerializedCallbackQueue,v=createImReplySink({stream:$,openReasoningStream:()=>(w=a.messages.startStream({conversationId:r.channelId,id:deterministicMessageId("rsn",r.channelId,r.inboundMessageId,r.selfPrincipalId),replyTo:e.inReplyTo??r.inboundMessageId,type:"agent_reasoning"},{onError:(e,n)=>{const a="terminal"===n?t.warn:t.debug;a?.(`[im] runtime reasoning stream ${n} PATCH error requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId}: ${e.message}`)}},{sender:r.selfPrincipalId}),w),abortSignal:y.signal,callbackQueue:S,logger:t,requestId:c,runId:l,channelId:r.channelId,inboundMessageId:r.inboundMessageId,origin:m,onAgentRunStart:e=>{s.bindRun(_,e)}}),q=interceptAgentRuntimeFailures(v,"im_runtime",e=>t.warn?.(`[im] runtime failure reply suppressed requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId} error_code=${e.errorCode}`)),k=q.sink,C=async(e,n)=>{if(!w)return!1;try{return"cancel"===e?await w.cancel({stopReason:"user_stop"}):"fail"===e?await w.fail(n?{stopReason:n}:void 0):await w.finalize({stopReason:"end_turn"}),!1}catch(e){return t.warn?.(`[im] runtime reasoning stream terminal write failed requestId=${c} channel=${r.channelId}: ${formatErrMessage(e)}`),!0}};let O,D,U=!1;const A=async e=>{k.dispatcher.markComplete(e);try{await k.dispatcher.waitForIdle()}catch{}},T=()=>{if(!y.signal.aborted)return;const e=y.signal.reason;throw e instanceof Error?e:new Error(String(e??"runtime dispatch aborted"))};let K,F,P;const N=async e=>{if(!_)throw new Error("session_mutation_not_acquired");const n=await s.converge(_,e);return n.ok?(K=n.permit,!0):(t.error?.(`[im] session mutation recovery required requestId=${c} sessionKey=${g} reason=${n.recovery.reason}`),F={code:n.recovery.code,reason:n.recovery.reason,sessionKey:n.recovery.sessionKey,operationId:n.recovery.operationId,surface:"message_service",...n.recovery.terminalKind?{terminalKind:n.recovery.terminalKind}:{}},!1)};try{T();const a=s.tryStartInteractive({sessionKey:g,label:"im_chat_message"},"message_service");if(!a.ok){try{await $.fail({body:SESSION_BUSY_PUBLIC_MESSAGE,stopReason:"error"})}catch(e){t.warn?.(`[im] session busy terminal write failed channel=${r.channelId} in_reply_to=${r.inboundMessageId}: ${formatErrMessage(e)}`)}return t.warn?.(`[im] session write gate busy sessionKey=${g} channel=${r.channelId} in_reply_to=${r.inboundMessageId} active_operation=${a.activeOperationId??"unknown"}`),e.onLifecycleEvent?.({type:"dispatch_error",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,error:"session_busy",cause:"runtime_error"}),!1}if(_=a.token,s.bindRun(_,l),d){const e=s.snapshot(g);P={runtimeConversationUid:r.channelId,runtimeSessionKey:r.channelId,historyGeneration:d.historyGeneration(r.channelId),targetMessageId:r.inboundMessageId,runtimeRunId:l,activeRunRegistrationId:`im:${e?.operationId??l}`},d.activeRuns.register(P,async()=>{const e=`chat_cancel:activeRun:${P.activeRunRegistrationId}`,n=await i.abort(h,e);return n.ok||"already_aborted"===n.reason?"accepted":"terminal_committing"===n.reason||"not_found"===n.reason?"already_terminal":"recovery_required"})}T(),t.info?.(`[im] runtime dispatching requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId} origin=${m}`),e.onLifecycleEvent?.({type:"dispatch_start",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId});const o=dispatchRuntimeReplyWithRoute({runtime:n,pluginConfig:e.pluginConfig,preparedPrompt:r.dispatchInput,replyRoute:p,replySinks:{im:k},onDispatchInvoked:()=>{U=!0}});void 0!==I&&(O=setTimeout(()=>{D=new Error(`IM runtime dispatch timed out after ${I}ms`),t.warn?.(`[im] runtime dispatch timeout requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId} timeout_ms=${I}`),R(D)},I));const y=Promise.race([o,b]),f=await y.finally(()=>{O&&(clearTimeout(O),O=void 0)}),E=q.detectedFailure();if(E)throw new Error(E.diagnosticMessage);if(T(),await A("success"),T(),!i.claimTerminal(h,"completion")){if(T(),"cancelling"===i.phase(h))throw new Error("cancellation in progress");throw new Error("terminal outcome already claimed")}if(!await N("completed"))return await C("fail"),await $.fail({body:SESSION_RECOVERY_REQUIRED_MESSAGE,stopReason:"error"}).catch(()=>{}),e.onLifecycleEvent?.({type:"dispatch_error",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,error:SESSION_RECOVERY_REQUIRED_CODE,cause:"runtime_error",...F?{recovery:F}:{}}),!1;const w=await C("complete");let M=!1;try{await $.finalize({stopReason:"end_turn"})}catch(e){M=!0,t.warn?.(`[im] runtime reply stream finalize failed requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId}: ${formatErrMessage(e)}`)}return d&&P&&d.activeRuns.markTerminal(P,"completed"),t.info?.(`[im] runtime dispatch completed requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId} counts=${JSON.stringify(f.counts)} elapsed_ms=${Date.now()-u}`),e.onLifecycleEvent?.({type:"dispatch_complete",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,counts:f.counts,...M?{terminalWriteFailed:!0}:{},...w?{reasoningTerminalWriteFailed:!0}:{}}),!0}catch(n){await A("failure");const a=y.signal.aborted,s=a?y.signal.reason:void 0,o="cancelling"===i.phase(h),l=void 0!==D,u=s??f,m=!l&&"string"==typeof u&&u.startsWith("chat_cancel");let p="runtime_error";l?p="timeout":(a||o)&&(p="abort");const I=o||m||l||a?"cancellation":"completion";if(!i.claimTerminal(h,I))throw t.warn?.(`[im] terminal write skipped because another outcome already committed requestId=${c} channel=${r.channelId}`),n;const g=m?"cancelled":l?"timeout":"error";if(d&&P&&d.activeRuns.markTerminal(P,"cancelled"===g?"cancelled":"failed"),_&&!await N(g))throw await C("fail"),await $.fail({body:SESSION_RECOVERY_REQUIRED_MESSAGE,stopReason:"error"}).catch(()=>{}),e.onLifecycleEvent?.({type:"dispatch_error",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,error:SESSION_RECOVERY_REQUIRED_CODE,cause:p,...F?{recovery:F}:{}}),n;const E=classifyAgentRuntimeFailure({raw:n,source:"im_runtime",runtimeKind:"openclaw",requestAborted:m}),b=m?E:q.detectedFailure()??E;m?await C("cancel"):l?await C("fail","timeout"):await C("fail");try{m?await $.cancel({stopReason:"user_stop"}):await $.fail({body:b.publicMessage,stopReason:messageStopReasonForRuntimeFailure(b)})}catch(e){t.warn?.(`[im] runtime stream terminal write failed requestId=${c} channel=${r.channelId}: ${formatErrMessage(e)}`)}throw t.warn?.(`[im] runtime dispatch failed requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId} cause=${p} dispatchInvoked=${U} error_code=${b.errorCode}`),e.onLifecycleEvent?.({type:"dispatch_error",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,error:b.errorCode,cause:p}),n}finally{i.unregister(h),U?K&&s.release(K):s.releaseBeforeRuntime(_)}};
|
|
1
|
+
import{createHash,randomUUID}from"node:crypto";import{dispatchRuntimeReplyWithRoute,hasRuntimeReplyApi}from"./runtime/reply-router.js";import{createImReplySink}from"./runtime/im-reply-sink.js";import{SerializedCallbackQueue}from"./runtime/callback-queue.js";import{promptRunKey}from"./runtime/prompt-run-store.js";import{classifyAgentRuntimeFailure}from"./runtime/agent-runtime-failure-classifier.js";import{SESSION_RECOVERY_REQUIRED_CODE,SESSION_RECOVERY_REQUIRED_MESSAGE}from"./runtime/session-mutation-coordinator.js";import{interceptAgentRuntimeFailures,messageStopReasonForRuntimeFailure,SESSION_BUSY_PUBLIC_MESSAGE}from"./runtime/im-runtime-failure-policy.js";const normalizePromptTimeoutMs=e=>{if("number"!=typeof e||!Number.isFinite(e))return;const n=Math.max(0,Math.trunc(e));return n>0?n:void 0},formatErrMessage=e=>{if(e instanceof Error)return e.message;if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}},deterministicMessageId=(e,n,r,a)=>`${e}_${createHash("sha256").update(`${n}:${r}:${a}`).digest("hex").slice(0,32)}`;export const dispatchImInboundPrompt=async e=>{const{runtime:n,prompt:r,client:a,logger:t,promptRunStore:i,sessionMutationCoordinator:s,abortTransport:o,activeRunAuthority:d}=e;if(!hasRuntimeReplyApi(n))return t.warn?.(`[im] runtime dispatch skipped reason=reply_api_unavailable channel=${r.channelId} in_reply_to=${r.inboundMessageId}`),e.onLifecycleEvent?.({type:"skipped",reason:"reply_api_unavailable",channelId:r.channelId,inboundMessageId:r.inboundMessageId}),!1;const c=`im_req_${randomUUID().replace(/-/g,"")}`,l=randomUUID(),u=Date.now(),m=e.origin??"im",p={protocol:"im",requestId:c,sessionId:r.sessionKey??"agent:main",sourceMessageId:r.inboundMessageId,chatId:r.channelId,origin:m},I=normalizePromptTimeoutMs(e.promptTimeoutMs),h=promptRunKey(r.channelId,r.inboundMessageId),g=r.sessionKey??"agent:main",y=new AbortController;let _,f,E;const R=new Promise((e,n)=>{E=n}),b=async e=>{if(f??=e,y.abort(e),!_)return{ok:!0};const n=await s.requestCancel(_,o);return n.ok?n.terminalObservation.then(e=>{e.ok||E(new Error(SESSION_RECOVERY_REQUIRED_CODE))}):E(new Error(SESSION_RECOVERY_REQUIRED_CODE)),{ok:n.ok}};if(!i.register(h,{requestId:c,channelId:r.channelId,requestCancel:b,startedAt:u,sessionKey:g}))return t.warn?.(`[im] runtime dispatch rejected duplicate inboundMessageId=${r.inboundMessageId} requestId=${c} channel=${r.channelId}`),e.onLifecycleEvent?.({type:"dispatch_error",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,error:"duplicate_inbound_message_id",cause:"abort"}),!1;const $=a.messages.startStream({conversationId:r.channelId,id:deterministicMessageId("asst",r.channelId,r.inboundMessageId,r.selfPrincipalId),replyTo:e.inReplyTo??r.inboundMessageId,type:"agent_reply"},{onError:(e,n)=>{const a="terminal"===n?t.warn:t.debug;a?.(`[im] runtime stream ${n} PATCH error requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId}: ${e.message}`)}},{sender:r.selfPrincipalId});let w,M=!1;try{M=!0===(await $.opened()).idempotent}catch(e){t.debug?.(`[im] runtime reply stream open probe failed requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId}: ${formatErrMessage(e)}; continuing so terminal fallback can land an error row`)}if(M)return t.info?.(`[im] runtime dispatch skipped existing deterministic reply requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId}`),e.onLifecycleEvent?.({type:"skipped",reason:"idempotent_reply_exists",channelId:r.channelId,inboundMessageId:r.inboundMessageId}),i.unregister(h),!1;const S=new SerializedCallbackQueue,v=createImReplySink({stream:$,openReasoningStream:()=>(w=a.messages.startStream({conversationId:r.channelId,id:deterministicMessageId("rsn",r.channelId,r.inboundMessageId,r.selfPrincipalId),replyTo:e.inReplyTo??r.inboundMessageId,type:"agent_reasoning"},{onError:(e,n)=>{const a="terminal"===n?t.warn:t.debug;a?.(`[im] runtime reasoning stream ${n} PATCH error requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId}: ${e.message}`)}},{sender:r.selfPrincipalId}),w),abortSignal:y.signal,callbackQueue:S,logger:t,requestId:c,runId:l,channelId:r.channelId,inboundMessageId:r.inboundMessageId,origin:m,onAgentRunStart:e=>{s.bindRun(_,e)}}),q=interceptAgentRuntimeFailures(v,"im_runtime",e=>t.warn?.(`[im] runtime failure reply suppressed requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId} error_code=${e.errorCode}`)),k=q.sink,C=async(e,n)=>{if(!w)return!1;try{return"cancel"===e?await w.cancel({stopReason:"user_stop"}):"fail"===e?await w.fail(n?{stopReason:n}:void 0):await w.finalize({stopReason:"end_turn"}),!1}catch(e){return t.warn?.(`[im] runtime reasoning stream terminal write failed requestId=${c} channel=${r.channelId}: ${formatErrMessage(e)}`),!0}};let O,D,U=!1;const A=async e=>{k.dispatcher.markComplete(e);try{await k.dispatcher.waitForIdle()}catch{}},T=()=>{if(!y.signal.aborted)return;const e=y.signal.reason;throw e instanceof Error?e:new Error(String(e??"runtime dispatch aborted"))};let K,F,P;const N=async e=>{if(!_)throw new Error("session_mutation_not_acquired");const n=await s.converge(_,e);return n.ok?(K=n.permit,!0):(t.error?.(`[im] session mutation recovery required requestId=${c} sessionKey=${g} reason=${n.recovery.reason}`),F={code:n.recovery.code,reason:n.recovery.reason,sessionKey:n.recovery.sessionKey,operationId:n.recovery.operationId,surface:"message_service",...n.recovery.terminalKind?{terminalKind:n.recovery.terminalKind}:{}},!1)};try{T();const a=s.tryStartInteractive({sessionKey:g,label:"im_chat_message"},"message_service");if(!a.ok){try{await $.fail({body:SESSION_BUSY_PUBLIC_MESSAGE,stopReason:"error"})}catch(e){t.warn?.(`[im] session busy terminal write failed channel=${r.channelId} in_reply_to=${r.inboundMessageId}: ${formatErrMessage(e)}`)}return t.warn?.(`[im] session write gate busy sessionKey=${g} channel=${r.channelId} in_reply_to=${r.inboundMessageId} active_operation=${a.activeOperationId??"unknown"}`),e.onLifecycleEvent?.({type:"dispatch_error",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,error:"session_busy",cause:"runtime_error"}),!1}if(_=a.token,s.bindRun(_,l),d){const e=s.snapshot(g);P={runtimeConversationUid:r.channelId,runtimeSessionKey:r.channelId,historyGeneration:d.historyGeneration(r.channelId),targetMessageId:r.inboundMessageId,runtimeRunId:l,activeRunRegistrationId:`im:${e?.operationId??l}`},d.activeRuns.register(P,async()=>{const e=`chat_cancel:activeRun:${P.activeRunRegistrationId}`,n=await i.abort(h,e);return n.ok||"already_aborted"===n.reason?"accepted":"terminal_committing"===n.reason||"not_found"===n.reason?"already_terminal":"recovery_required"})}T(),t.info?.(`[im] runtime dispatching requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId} origin=${m}`),e.onLifecycleEvent?.({type:"dispatch_start",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId});const o=dispatchRuntimeReplyWithRoute({runtime:n,pluginConfig:e.pluginConfig,preparedPrompt:r.dispatchInput,replyRoute:p,replySinks:{im:k},onDispatchInvoked:()=>{U=!0}});void 0!==I&&(O=setTimeout(()=>{D=new Error(`IM runtime dispatch timed out after ${I}ms`),t.warn?.(`[im] runtime dispatch timeout requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId} timeout_ms=${I}`),b(D)},I));const y=Promise.race([o,R]),f=await y.finally(()=>{O&&(clearTimeout(O),O=void 0)}),E=q.detectedFailure();if(E)throw new Error(E.diagnosticMessage);if(T(),await A("success"),T(),!i.claimTerminal(h,"completion")){if(T(),"cancelling"===i.phase(h))throw new Error("cancellation in progress");throw new Error("terminal outcome already claimed")}if(!await N("completed"))return await C("fail"),await $.fail({body:SESSION_RECOVERY_REQUIRED_MESSAGE,stopReason:"error"}).catch(()=>{}),e.onLifecycleEvent?.({type:"dispatch_error",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,error:SESSION_RECOVERY_REQUIRED_CODE,cause:"runtime_error",...F?{recovery:F}:{}}),!1;const w=await C("complete");let M=!1;try{await $.finalize({stopReason:"end_turn"})}catch(e){M=!0,t.warn?.(`[im] runtime reply stream finalize failed requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId}: ${formatErrMessage(e)}`)}return d&&P&&d.activeRuns.markTerminal(P,"completed"),t.info?.(`[im] runtime dispatch completed requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId} counts=${JSON.stringify(f.counts)} elapsed_ms=${Date.now()-u}`),e.onLifecycleEvent?.({type:"dispatch_complete",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,counts:f.counts,...M?{terminalWriteFailed:!0}:{},...w?{reasoningTerminalWriteFailed:!0}:{}}),!0}catch(n){await A("failure");const a=y.signal.aborted,s=a?y.signal.reason:void 0,o="cancelling"===i.phase(h),l=void 0!==D,u=s??f,m=!l&&"string"==typeof u&&u.startsWith("chat_cancel");let p="runtime_error";l?p="timeout":(a||o)&&(p="abort");const I=o||m||l||a?"cancellation":"completion";if(!i.claimTerminal(h,I))throw t.warn?.(`[im] terminal write skipped because another outcome already committed requestId=${c} channel=${r.channelId}`),n;const g=m?"cancelled":l?"timeout":"error";if(d&&P&&d.activeRuns.markTerminal(P,"cancelled"===g?"cancelled":"failed"),_&&!await N(g))throw m?(await C("cancel"),await $.cancel({stopReason:"user_stop"}).catch(()=>{})):(await C("fail"),await $.fail({body:SESSION_RECOVERY_REQUIRED_MESSAGE,stopReason:"error"}).catch(()=>{})),e.onLifecycleEvent?.({type:"dispatch_error",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,error:SESSION_RECOVERY_REQUIRED_CODE,cause:p,...F?{recovery:F}:{}}),n;const E=classifyAgentRuntimeFailure({raw:n,source:"im_runtime",runtimeKind:"openclaw",requestAborted:m}),R=m?E:q.detectedFailure()??E;m?await C("cancel"):l?await C("fail","timeout"):await C("fail");try{m?await $.cancel({stopReason:"user_stop"}):await $.fail({body:R.publicMessage,stopReason:messageStopReasonForRuntimeFailure(R)})}catch(e){t.warn?.(`[im] runtime stream terminal write failed requestId=${c} channel=${r.channelId}: ${formatErrMessage(e)}`)}throw t.warn?.(`[im] runtime dispatch failed requestId=${c} channel=${r.channelId} in_reply_to=${r.inboundMessageId} cause=${p} dispatchInvoked=${U} error_code=${R.errorCode}`),e.onLifecycleEvent?.({type:"dispatch_error",requestId:c,channelId:r.channelId,inboundMessageId:r.inboundMessageId,error:R.errorCode,cause:p}),n}finally{i.unregister(h),U?K&&s.release(K):s.releaseBeforeRuntime(_)}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{canonicalizeJcs,verifyAndDeriveCoreExecutionAttempt}from"@beeos-ai/beeos-types/runtime";const TRUSTED_CORE_ATTEMPT=Symbol("beeos.trusted-core-attempt"),VERIFIED_MESSAGE_GRANT=Symbol("beeos.verified-message-grant");export function createAcpCoreExecutionAttempt(e){if(e.historyBoundary&&"local"!==e.historyBoundary.kind)throw new Error("ACP attempt cannot use a Message Service history boundary");return Object.freeze({...e,origin:"acp",[TRUSTED_CORE_ATTEMPT]:!0})}export async function verifyAndCreateServiceCoreExecutionAttempt(e){let t;try{t=verifyAndDeriveCoreExecutionAttempt(e.authorization,e.derivationContext,e.verifier)}catch{return{ok:!1,violations:["MALFORMED_EXECUTION_AUTHORIZATION"]}}if(!t.ok)return t;await e.recordVerifiedAttempt(t.attempt);const
|
|
1
|
+
import{canonicalizeJcs,verifyAndDeriveCoreExecutionAttempt}from"@beeos-ai/beeos-types/runtime";const TRUSTED_CORE_ATTEMPT=Symbol("beeos.trusted-core-attempt"),VERIFIED_MESSAGE_GRANT=Symbol("beeos.verified-message-grant");export function createAcpCoreExecutionAttempt(e){if(e.historyBoundary&&"local"!==e.historyBoundary.kind)throw new Error("ACP attempt cannot use a Message Service history boundary");return Object.freeze({...e,origin:"acp",[TRUSTED_CORE_ATTEMPT]:!0})}export async function verifyAndCreateServiceCoreExecutionAttempt(e){let t;try{t=verifyAndDeriveCoreExecutionAttempt(e.authorization,e.derivationContext,e.verifier)}catch{return{ok:!1,violations:["MALFORMED_EXECUTION_AUTHORIZATION"]}}if(!t.ok)return t;await e.recordVerifiedAttempt(t.attempt);const n=await e.resolvePorts();if(n.historyBoundary&&"message-service"!==n.historyBoundary.kind)throw new Error("Service attempt cannot fall back to local conversation history");return{ok:!0,context:Object.freeze({operationId:e.operationId,runtimeEpoch:e.runtimeEpoch,fence:e.fence,resources:n.resources,...n.historyBoundary?{historyBoundary:n.historyBoundary}:{},...n.canvasControl?{canvasControl:n.canvasControl}:{},...e.abortSignal?{abortSignal:e.abortSignal}:{},verifiedAttempt:t.attempt,origin:"service",[TRUSTED_CORE_ATTEMPT]:!0})}}export async function verifyAndCreateMessageServiceCoreExecutionAttempt(e){const t=e.verifier.verifyAndDecodeGrant(e.executionGrant);if(!t)return{ok:!1,violations:["GRANT_SIGNATURE_INVALID"]};if(t.compactHash!==e.request.executionGrantHash)return{ok:!1,violations:["GRANT_HASH_MISMATCH"]};const n=t.claims,r=validateMessageGrant(n,e.request,e.lease,e.nowEpochSeconds??Math.floor(Date.now()/1e3),!0===e.allowExpiredGrant);if(r.length)return{ok:!1,violations:r};const o=await e.resolvePorts();if(o.historyBoundary&&"message-service"!==o.historyBoundary.kind)throw new Error("Service attempt cannot fall back to local conversation history");const i=Object.freeze({[VERIFIED_MESSAGE_GRANT]:!0,claims:Object.freeze({...n}),compactHash:t.compactHash});return{ok:!0,grant:i,context:Object.freeze({operationId:e.request.operationId,runtimeEpoch:e.runtimeEpoch,resources:o.resources,...o.historyBoundary?{historyBoundary:o.historyBoundary}:{},...o.canvasControl?{canvasControl:o.canvasControl}:{},...e.abortSignal?{abortSignal:e.abortSignal}:{},verifiedMessageGrant:i,origin:"service",[TRUSTED_CORE_ATTEMPT]:!0})}}export function assertTrustedCoreExecutionAttempt(e,t){if(!e||!0!==e[TRUSTED_CORE_ATTEMPT]||e.operationId!==t.operationId||e.runtimeEpoch!==t.runtimeEpoch)throw new Error("untrusted or mismatched Core execution attempt context");if(!("service"!==e.origin||e.verifiedMessageGrant||e.fence&&e.verifiedAttempt))throw new Error("Service Core execution attempt lacks verified authorization")}function validateMessageGrant(e,t,n,r,o){if(!e||"object"!=typeof e)return["MALFORMED_EXECUTION_GRANT"];const i="historyGeneration"in e?e.historyGeneration:void 0,a="instance"===e.scope&&"runtimeAgentUid"in e?e.runtimeAgentUid:void 0;if(!exactKeys(e,["iss","aud","purpose","sub","jti","iat","exp","operationId","requestMessageId","instanceId","handlerIdentity","dispatchEpoch","method","requestHash","paramsHash","commandHash","idempotencyKeyHash","callerUserId","callerIdentityId","scope","command","executionMode",..."instance"===e.scope?void 0!==a?["runtimeAgentUid"]:[]:"agent"===e.scope?["platformAgentId","runtimeAgentUid"]:"conversation"===e.scope?["platformConversationId","runtimeConversationUid","runtimeSessionKey","platformAgentId","runtimeAgentUid",...void 0!==i?["historyGeneration"]:[]]:[]]))return["GRANT_FIELDS_INVALID"];const s=[];"beeos-gateway"===e.iss&&"beeos-runtime-command"===e.aud&&"runtime-execution-grant"===e.purpose&&e.sub===t.runtimeHandlerIdentity&&e.handlerIdentity===t.runtimeHandlerIdentity&&"start"===e.executionMode||s.push("GRANT_IDENTITY_MISMATCH"),(!Number.isSafeInteger(e.iat)||!Number.isSafeInteger(e.exp)||"string"!=typeof e.jti||0===e.jti.length||e.iat>r||e.exp<=e.iat||!o&&e.exp<=r||e.exp-e.iat>60)&&s.push("GRANT_TIME_INVALID");if([[e.operationId,t.operationId],[e.requestMessageId,t.requestMessageId],[e.instanceId,t.instanceId],[e.dispatchEpoch,t.dispatchEpoch],[e.method,t.method],[e.requestHash,t.requestHash],[e.paramsHash,t.paramsHash],[e.commandHash,t.commandHash],[e.idempotencyKeyHash,t.idempotencyKeyHash],[e.callerUserId,t.callerUserId],[e.callerIdentityId,t.callerIdentityId],[n.instanceId,t.instanceId],[n.handlerIdentity,t.runtimeHandlerIdentity],[n.runtimeEpoch,t.dispatchEpoch]].some(([e,t])=>e!==t)&&s.push("GRANT_REQUEST_MISMATCH"),semanticEqual(e.command,t.command)||s.push("GRANT_COMMAND_MISMATCH"),targetMatches(e,t)||s.push("GRANT_TARGET_MISMATCH"),"conversation"===e.scope){const n=t.command.context,r=n?.agent;n&&"conversation"===n.scope&&r?.platformAgentId===e.platformAgentId&&r?.runtimeAgentUid===e.runtimeAgentUid||s.push("GRANT_TARGET_MISMATCH");const o=n?.historyGeneration;"session/cancel"===e.method?"string"==typeof i&&0!==i.length&&i===o||s.push("GRANT_HISTORY_GENERATION_MISMATCH"):void 0!==i&&s.push("GRANT_HISTORY_GENERATION_MISMATCH")}return s}function semanticEqual(e,t){try{return canonicalizeJcs(e)===canonicalizeJcs(t)}catch{return!1}}function targetMatches(e,t){const n=t.command.context,r=t.request.params;if(!n||n.scope!==e.scope)return!1;if("instance"===n.scope){if(!("runtimeAgentUid"in e))return!0;const n=e.runtimeAgentUid;if("string"!=typeof n||0===n.length)return!1;const r=t.command.params;return r?.runtimeAgentUid===n}if("agent"===n.scope)return n.agent.runtimeAgentUid===e.runtimeAgentUid&&null!==r&&"object"==typeof r&&!Array.isArray(r)&&r.platformAgentId===e.platformAgentId;const o=null===r||"object"!=typeof r||Array.isArray(r)?void 0:"string"==typeof r.conversationId?r.conversationId:"string"==typeof r.sessionId?r.sessionId:void 0;return n.conversation.runtimeConversationUid===e.runtimeConversationUid&&n.conversation?.runtimeSessionKey===e.runtimeSessionKey&&o===e.platformConversationId}function exactKeys(e,t){const n=Object.keys(e).sort(),r=[...t].sort();return n.length===r.length&&n.every((e,t)=>e===r[t])}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beeos-claw",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.74",
|
|
4
4
|
"description": "OpenClaw plugin that bridges the BeeOS platform with the local OpenClaw Gateway, providing file transfer, ACP bridge, and observability.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "BeeOS <dev@beeos.ai>",
|