beeos-claw 0.6.29 → 0.6.31
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/acp-gateway/background-run-im-egress.js +1 -0
- package/dist/acp-gateway/bridge-core.js +1 -1
- package/dist/acp-gateway/gateway-events.js +1 -1
- package/dist/acp-gateway/session-state.js +1 -1
- package/dist/acp-server.js +1 -1
- package/dist/im-inbound-handler.js +1 -1
- package/dist/index.js +1 -1
- package/dist/message-projection-inbound-consumer.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/runtime-rpc-consumer.js +1 -1
- package/dist/runtime/session-new-runtime-delivery-bridge.js +1 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RUNTIME_ERROR_DESCRIPTORS,RUNTIME_HASH_DOMAINS,RUNTIME_INVOCATION_PARITY_ENTRIES,RUNTIME_INVOCATION_RECOVERY_CLASSES,SERVICE_CANONICAL_COMMAND_NAMES,mapCanonicalResultToService}from"@beeos-ai/beeos-types/runtime";import{reduceRuntimeRecoveryPolicy}from"@beeos-ai/beeos-types/runtime/internal";import{verifyAndCreateMessageServiceCoreExecutionAttempt}from"./core-execution-attempt-context.js";import{awaitRuntimeProjection,hasEffectReceiptHandoff,RuntimeCommandError}from"./runtime-command-dispatcher.js";import{createRuntimeAppendTimingRecorder}from"./runtime-append-timing.js";import{RUNTIME_MESSAGE_TYPES,runtimeMessageBase,runtimeMessageHash,semanticEqual,validateRuntimeCancelEnvelope,validateRuntimeRequestEnvelope}from"./runtime-message-channel-contract.js";import{RuntimeResourceResolutionError}from"./runtime-operation-resource-resolver.js";import{RuntimeTransportFailurePolicy}from"./runtime-transport-failure-policy.js";const leaseStarvationReportIntervalMs=3e4;export class MsRuntimeMessageChannelAdapter{dispatcher;channel;verifier;ports;journal;getLease;options;controller;running;externalDeliveryOwner;workers=new Map;poisonJournal;renewTransportFailurePolicy=new RuntimeTransportFailurePolicy;leaseStarvedSince;leaseStarvationReportedAt=0;receiptHistory=this;constructor(e,t,o,a,r,n,i){if(this.dispatcher=e,this.channel=t,this.verifier=o,this.ports=a,this.journal=r,this.getLease=n,this.options=i,!i.poisonJournal)throw new Error("durable poison journal is required");if(this.poisonJournal=i.poisonJournal,!Number.isSafeInteger(i.poisonDeliveryLimit??3)||(i.poisonDeliveryLimit??3)<=0)throw new Error("poison delivery limit must be a positive integer")}start(){if(this.externalDeliveryOwner)return void this.externalDeliveryOwner.start();if(this.running)return;const e=new AbortController;this.controller=e;const t=this.loop(e.signal).catch(t=>{e.signal.aborted||this.observeDeliveryError(t)}).finally(()=>{this.running===t&&(this.running=void 0)});this.running=t}async stop(e){this.controller?.abort();for(const e of this.workers.values())e.cancel?.();if(this.externalDeliveryOwner)return await this.externalDeliveryOwner.stop(e),void await Promise.allSettled([...this.workers.values()].map(e=>e.completion));this.running&&await abortable(this.running,e)}attachExternalDeliveryOwner(e){if(this.running||this.externalDeliveryOwner)throw new Error("runtime delivery owner is already attached");this.externalDeliveryOwner=e}async acceptDelivery(e,t,o){if(this.currentLease(t),e.message.type===RUNTIME_MESSAGE_TYPES.cancel)return void await this.handleCancel(e,t);const a=validateRuntimeRequestEnvelope(e.message),r=a.ok?a.envelope.payload.operationId:e.message.channel_id;if(this.workers.has(r))return;const n={deliveryId:e.deliveryId,claimedLease:t,completion:Promise.resolve()};n.completion=this.handleRequest(e,t,o,e=>{n.cancel=e}).catch(e=>this.observeDeliveryError(e)).finally(()=>{this.workers.delete(r)}),this.workers.set(r,n),await n.completion}async readOperationHistory(e){const t=this.getLease();if(!t)return{status:"unavailable"};try{return await this.channel.history({operationId:e.operationId,lease:t})}catch{return{status:"unavailable"}}}async loop(e){let t;(()=>{t||(t=setInterval(()=>{this.renewActive().catch(e=>this.observeDeliveryError(e))},this.options.renewIntervalMs??2e4),t.unref?.())})();try{for(;!e.aborted;){const t=this.getLease();if(!t){this.observeLeaseStarvation(),await delay(this.options.idleDelayMs??500,e);continue}let o;this.observeLeaseRestored();try{o=await this.channel.read({maxCount:this.options.readCount??32,blockMs:this.options.blockMs??5e3,lease:t,signal:e})}catch(t){if(e.aborted)return;this.observeDeliveryError(t),await delay(this.options.idleDelayMs??500,e);continue}for(const a of o){if(e.aborted)break;if(a.message.type===RUNTIME_MESSAGE_TYPES.cancel){await this.handleCancel(a,t).catch(e=>this.observeDeliveryError(e));continue}const o=a.message.channel_id;if(this.workers.has(o))continue;const r={deliveryId:a.deliveryId,claimedLease:t,completion:Promise.resolve()};r.completion=this.handleRequest(a,t,e,e=>{r.cancel=e}).catch(e=>this.observeDeliveryError(e)).finally(()=>{this.workers.delete(o)}),this.workers.set(o,r)}}}finally{t&&clearInterval(t),await Promise.allSettled([...this.workers.values()].map(e=>e.completion))}}observeDeliveryError(e){try{this.options.onDeliveryError?.(e)}catch{}}observeLeaseStarvation(){const e=Date.now();this.leaseStarvedSince??=e;const t=e-this.leaseStarvedSince;if(!(t<3e4||this.leaseStarvationReportedAt&&e-this.leaseStarvationReportedAt<3e4)){this.leaseStarvationReportedAt=e;try{this.options.onLeaseStarvation?.({starvedForMs:t,recovered:!1})}catch{}}}observeLeaseRestored(){const e=this.leaseStarvedSince;if(void 0===e)return;this.leaseStarvedSince=void 0;const t=this.leaseStarvationReportedAt;if(this.leaseStarvationReportedAt=0,t)try{this.options.onLeaseStarvation?.({starvedForMs:Date.now()-e,recovered:!0})}catch{}}observeRequestFailure(e,t,o){try{this.options.onRequestFailure?.({operationId:e,method:t,error:o})}catch{}}async renewActive(){const e=this.getLease();if(!e)return;const t=[];for(const o of this.workers.values())sameLeaseBinding(o.claimedLease,e)?t.push(o.deliveryId):o.cancel?.();if(!t.length)return;let o;try{o=await this.channel.renew({deliveryIds:t,lease:e})}catch(e){if(this.observeDeliveryError(e),this.renewTransportFailurePolicy.recordFailure()){const e=new Set(t);for(const t of this.workers.values())e.has(t.deliveryId)&&t.cancel?.()}return}if(this.renewTransportFailurePolicy.recordSuccess(),o.notPending.length){const e=new Set(o.notPending);for(const t of this.workers.values())e.has(t.deliveryId)&&t.cancel?.()}}async handleCancel(e,t){const o=validateRuntimeCancelEnvelope(e.message);if(!o.ok)return void await this.handlePoison(e,`invalid_cancel:${o.reason}`,t);const a=o.envelope.payload,r=await this.channel.history({operationId:a.operationId,lease:t});if("found"===r.status&&r.snapshot.terminal&&"final_message"===r.snapshot.terminalSource)return void await this.channel.acknowledge({deliveryIds:[e.deliveryId],lease:t});if("not_found"===r.status||"expired"===r.status)return void await this.channel.acknowledge({deliveryIds:[e.deliveryId],lease:t});const n=r.snapshot.request.payload;n.operationId===a.operationId&&n.requestMessageId===a.requestMessageId&&n.requestHash===a.requestHash&&n.dispatchEpoch===a.dispatchEpoch&&n.method===a.method?(await this.journal.observeCancellation({operationId:a.operationId,requestMessageId:a.requestMessageId,requestHash:a.requestHash,eventId:a.eventId}),this.workers.get(a.operationId)?.cancel?.(),await this.channel.acknowledge({deliveryIds:[e.deliveryId],lease:t})):await this.handlePoison(e,"cancel_history_mismatch",t)}async handleRequest(e,t,o,a){const r=validateRuntimeRequestEnvelope(e.message);if(!r.ok)return void await this.handlePoison(e,`invalid_request:${r.reason}`,t);const n=r.envelope.payload,i=e.executionGrant,s=createRuntimeAppendTimingRecorder("runtime-op",{operationId:n.operationId,method:n.method}),c=new AbortController;a(()=>c.abort());const d=async()=>{await this.channel.acknowledge({deliveryIds:[e.deliveryId],lease:this.currentLease(t)}),s.mark("ack")},l=await this.channel.history({operationId:n.operationId,lease:t});if(s.mark("history"),"not_found"===l.status||"expired"===l.status)return void await d();if(l.snapshot.terminal&&"final_message"===l.snapshot.terminalSource)return void await d();if(this.options.allowedMethods&&!this.options.allowedMethods.has(n.method))return await this.reject(n,"unsupported_method",t),void await d();if("deadline"===l.snapshot.terminalSource||Date.parse(n.executionDeadlineAt)<=Date.now()||!l.snapshot.started&&Date.parse(n.claimDeadlineAt)<=Date.now())return await this.reject(n,"execution_deadline_exceeded",t),void await d();const p=await this.journal.getCancellation(n.operationId);s.mark("journal-cancel-read");const u=l.snapshot.cancelRequested||null!==p;if(u&&"queued"===l.snapshot.status)return await this.reject(n,"cancelled_before_dispatch",t),void await d();if(n.instanceId!==t.instanceId||n.runtimeHandlerIdentity!==t.handlerIdentity||n.dispatchEpoch!==t.runtimeEpoch)return await this.reject(n,"authority_mismatch",t),void await d();const h=l.snapshot.request.payload;if(l.snapshot.operationId!==n.operationId||l.snapshot.requestMessageId!==n.requestMessageId||l.snapshot.requestHash!==n.requestHash||!semanticEqual(h,n))return void await this.handlePoison(e,"request_history_mismatch",t);const m=l.snapshot.started?.payload,I=void 0!==m&&m.operationId===n.operationId&&m.requestMessageId===n.requestMessageId&&m.requestHash===n.requestHash&&m.executionGrantHash===n.executionGrantHash&&m.handlerIdentity===t.handlerIdentity&&m.dispatchEpoch===t.runtimeEpoch&&m.method===n.method,E=await this.journal.get(n.operationId);s.mark("journal-prior");const v=await this.journal.acceptMessageRequest({operationId:n.operationId,command:n.command.name,paramsHash:n.paramsHash,runtimeEpoch:n.dispatchEpoch,requestMessageId:n.requestMessageId,requestHash:n.requestHash});s.mark("journal-accept");const f=I?E:v,R=decideMessageServiceRecovery(l.snapshot,n,f,I);if("already_terminal"===R)return void await d();if(!CORE_RECOVERY_DECISIONS.has(R))return await this.markOutcomeUnknownIfMutable(v),await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:failurePayload(n,new RuntimeCommandError("OUTCOME_UNKNOWN",`Types recovery policy requires ${R}; this runtime cannot safely replay Core`),(new Date).toISOString())}),void await d();if(await this.verifier.refresh(),s.mark("verifier-refresh"),!i)return I?await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:failurePayload(n,new RuntimeCommandError("OUTCOME_UNKNOWN","retained started proof has no live execution grant"),(new Date).toISOString())}):await this.reject(n,"invalid_execution_grant",t),void await d();this.verifier.verifyAndDecodeGrant(i)||await this.verifier.refresh(!0);const y=()=>c.abort();let _;o.addEventListener("abort",y,{once:!0});try{_=await verifyAndCreateMessageServiceCoreExecutionAttempt({request:n,executionGrant:i,runtimeEpoch:t.runtimeEpoch,lease:t,verifier:this.verifier,allowExpiredGrant:I,abortSignal:c.signal,resolvePorts:async()=>await this.ports.resolve({request:n,executionGrant:i,command:n.command,getLease:()=>this.currentLease(t),...this.journalLineage(),journalRecord:v,abortSignal:c.signal})})}catch(e){if(o.removeEventListener("abort",y),c.abort(),!(e instanceof RuntimeResourceResolutionError))throw e;if("transient"===e.kind)return;return I?(await this.markOutcomeUnknownIfMutable(v),await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:failurePayload(n,new RuntimeCommandError("OUTCOME_UNKNOWN","eager resources cannot be reconstructed after retained started proof"),(new Date).toISOString())})):await this.reject(n,"integrity_mismatch"===e.kind?"resource_integrity_mismatch":"resource_resolution_rejected",t),void await d()}if(!_.ok)return o.removeEventListener("abort",y),c.abort(),I?(await this.markOutcomeUnknownIfMutable(v),await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:failurePayload(n,new RuntimeCommandError("OUTCOME_UNKNOWN","execution grant cannot be revalidated after retained started proof"),(new Date).toISOString())})):await this.reject(n,"invalid_execution_grant",t),void await d();if(!u||"prepared"!==v.phase&&"started"!==v.phase||c.abort(),c.signal.aborted&&!I)return o.removeEventListener("abort",y),await this.reject(n,"cancelled_before_dispatch",t),void await d();s.mark("attempt"),I?this.currentLease(t):(await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),executionGrant:i,type:RUNTIME_MESSAGE_TYPES.started,payload:{...runtimeMessageBase(n),executionMode:"start",executionGrantHash:n.executionGrantHash,handlerIdentity:t.handlerIdentity,claimedAt:v.messageBinding?.acceptedAt??v.updatedAt}}),s.mark("append-started"));const w=this.dispatcher.dispatch(n.command,_.context);w.completion.catch(()=>{}),a(()=>{c.abort(),w.cancel()}),c.signal.aborted&&w.cancel();const M=this.forwardProgress(n,w.progress,t).catch(()=>{});let g,S=!1;try{if(("mcp/set"===n.method||"mcp/unset"===n.method)&&hasEffectReceiptHandoff(w)){const e=await w.effectCommitted;if(e){if(e.operationId!==n.operationId||e.method!==n.command.name)throw new RuntimeCommandError("OUTCOME_UNKNOWN","Core MCP receipt correlation mismatch");const o=runtimeMessageHash(RUNTIME_HASH_DOMAINS.coreResult,{method:n.method,result:e.result}),a={schemaVersion:1,operationId:n.operationId,method:n.method,coreResultRef:`sha256:${o}`,coreResultHash:o};g=runtimeMessageHash(RUNTIME_HASH_DOMAINS.effectRecord,a),S=!0,await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.effectCommitted,payload:{...runtimeMessageBase(n),effectRecord:a,effectRecordHash:g,committedAt:e.committedAt}}),await w.acknowledgeEffectReceipt({operationId:n.operationId,method:n.command.name,effectRecordHash:g})}}const o=await w.completion;await M,s.mark("core");const a=await this.journal.get(n.operationId);if(s.mark("journal-after-core"),!a||!isCommittedCorePhase(a.phase))throw new RuntimeCommandError("OUTCOME_UNKNOWN","Core completed without a committed local journal record");const r=a.updatedAt;let i,c;if("query"!==RUNTIME_INVOCATION_RECOVERY_CLASSES[n.method]){const e=isAgentProjectionMethod(n.method),c=w.getSnapshot().projection,l=a.agentProjectionIntent??a.agentProjectionPreparationFailure;if(e&&!l)throw new RuntimeCommandError("OUTCOME_UNKNOWN","agent effect committed without an atomic projection preparation record");if(!g){const e=l?.coreResultHash??runtimeMessageHash(RUNTIME_HASH_DOMAINS.coreResult,{method:n.method,result:o}),i=a.agentProjectionIntent?.projectionRevision??(methodRequiresProjectionRevision(n.method)?c?.revision??`${Math.max(0,a.revision)}`:void 0),d={schemaVersion:1,operationId:n.operationId,method:n.method,coreResultRef:`sha256:${e}`,coreResultHash:e,...i?{projectionRevision:i}:{}};g=runtimeMessageHash(RUNTIME_HASH_DOMAINS.effectRecord,d),S=!0,await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.effectCommitted,payload:{...runtimeMessageBase(n),effectRecord:d,effectRecordHash:g,committedAt:r}}),s.mark("append-effect")}let p=e?await awaitRuntimeProjection(w):c;if("session/set_model"===n.method&&"synced"!==p?.state&&(p=await this.projectSessionModelAfterEffect(n,_.context,a,p),s.mark("set-model-projection")),e&&a.agentProjectionIntent&&(!p||p.revision!==a.agentProjectionIntent.projectionRevision))throw new RuntimeCommandError("OUTCOME_UNKNOWN","agent projection receipt revision mismatch");if("pending"===p?.state)return void await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.projectionPending,payload:{...runtimeMessageBase(n),revision:p.revision}});if("synced"===p?.state&&await this.publishProjectionSynced(n,t,{...p,state:"synced"}),"blocked"===p?.state){await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.projectionBlocked,payload:{...runtimeMessageBase(n),revision:p.revision,errorCode:"PROJECTION_BLOCKED"}});const e=RUNTIME_ERROR_DESCRIPTORS.PROJECTION_BLOCKED;return await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:{...runtimeMessageBase(n),outcome:"projection_blocked",response:{jsonrpc:"2.0",id:n.request.id,error:{code:e.jsonRpcCode,message:"PROJECTION_BLOCKED",data:{code:"PROJECTION_BLOCKED",operationId:n.operationId,effectState:"committed",retryMode:e.retryMode}}},effectRecordHash:g,completedAt:r}}),void await d()}i=e?p?.platformAgentId:void 0}try{c=sanitizeRuntimeServiceResult(n.method,o,_.context,i)}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed Core result cannot be mapped safely",void 0,{cause:e})}const l=runtimeMessageHash(RUNTIME_HASH_DOMAINS.serviceResult,{method:n.method,result:c});S=!0;const p=await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:{...runtimeMessageBase(n),outcome:"succeeded",response:{jsonrpc:"2.0",id:n.request.id,result:c},serviceResultHash:l,...g?{effectRecordHash:g}:{},completedAt:r}});if(s.mark("append-final"),this.observeRequestTerminalAccepted(e.deliveryId,p.message),("mcp/set"===n.method||"mcp/unset"===n.method)&&hasEffectReceiptHandoff(w)&&"function"==typeof w.acknowledgeTerminalReceipt){if(!g)throw new RuntimeCommandError("OUTCOME_UNKNOWN","MCP terminal response lacks its committed effect hash");await w.acknowledgeTerminalReceipt({operationId:n.operationId,method:n.command.name,effectRecordHash:g,terminalMessageId:p.message.message_id})}await d(),this.observeRequestAcknowledged(e.deliveryId,p.message)}catch(e){const o=await this.journal.get(n.operationId);if(o&&isCommittedCorePhase(o.phase)&&S)throw e;const a=!o||!isCommittedCorePhase(o.phase)||e instanceof RuntimeCommandError&&"OUTCOME_UNKNOWN"===e.code?e:new RuntimeCommandError("OUTCOME_UNKNOWN","Core effect committed before terminal mapping",void 0,{cause:e});this.observeRequestFailure(n.operationId,n.method,a);const r=failurePayload(n,a,o?.updatedAt??(new Date).toISOString());await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:r}),s.mark("append-terminal-failure"),await d()}finally{s.finish(),c.abort(),o.removeEventListener("abort",y)}}async handlePoison(e,t,o){this.currentLease(o);(await this.poisonJournal.record({delivery:e,reason:durablePoisonReason(t),limit:this.options.poisonDeliveryLimit??3})).terminal&&await this.channel.acknowledge({deliveryIds:[e.deliveryId],lease:this.currentLease(o)})}observeRequestTerminalAccepted(e,t){try{this.options.onRequestTerminalAccepted?.({deliveryId:e,message:t})}catch{}}observeRequestAcknowledged(e,t){try{this.options.onRequestAcknowledged?.({deliveryId:e,message:t})}catch{}}async forwardProgress(e,t,o){for await(const a of t)await this.channel.append({operationId:e.operationId,lease:this.currentLease(o),type:RUNTIME_MESSAGE_TYPES.progress,payload:{...runtimeMessageBase(e),phase:a.phase,progress:a}})}async reject(e,t,o){await this.channel.append({operationId:e.operationId,lease:this.currentLease(o),type:RUNTIME_MESSAGE_TYPES.final,payload:prestartFailurePayload(e,t)})}async markOutcomeUnknownIfMutable(e){"prepared"!==e.phase&&"started"!==e.phase||await this.journal.transition({operationId:e.operationId,expectedRevision:e.revision,phase:"outcome_unknown",errorCode:"OUTCOME_UNKNOWN"})}async projectSessionModelAfterEffect(e,t,o,a){const r=Object.freeze({state:"pending",revision:a?.revision??`${Math.max(0,o.revision)}`}),n=e.command;if("session.setModel"!==n.name||"conversation"!==n.context.scope)return r;const i=t.sessionModelProjection;if(!i)return r;try{await i.project({conversationId:n.context.conversation.runtimeConversationUid,modelOverrideId:n.params.modelOverrideId});const e=Object.freeze({state:"synced",revision:r.revision});try{const t=await this.journal.get(o.operationId)??o;if("projection_committed"===t.phase&&"synced"===t.projectionReceipt?.snapshot.state)return Object.freeze({state:"synced",revision:t.projectionReceipt.snapshot.revision});await this.journal.transition({operationId:t.operationId,expectedRevision:t.revision,phase:"projection_committed",projectionSnapshot:e})}catch{}return e}catch(e){return this.observeDeliveryError(e),r}}async publishProjectionSynced(e,t,o){const a=this.currentLease(t),r=await this.channel.history({operationId:e.operationId,lease:a});if("found"===r.status&&"synced"===r.snapshot.projectionState)return;const n={...runtimeMessageBase(e),revision:o.revision};("found"!==r.status||"reserved"===r.snapshot.projectionState||"pending"!==r.snapshot.projectionState&&void 0===r.snapshot.projectionPending)&&await this.channel.append({operationId:e.operationId,lease:a,type:RUNTIME_MESSAGE_TYPES.projectionPending,payload:n}),await this.channel.append({operationId:e.operationId,lease:a,type:RUNTIME_MESSAGE_TYPES.projectionSynced,payload:{...n,...o.platformAgentId?{platformAgentId:o.platformAgentId}:{}}})}journalLineage(){return this.options.getJournalLineage?.()??{journalStoreId:this.options.journalStoreId,journalGeneration:this.options.journalGeneration}}currentLease(e){const t=this.getLease();if(!t||t.instanceId!==e.instanceId||t.leaseId!==e.leaseId||t.runtimeEpoch!==e.runtimeEpoch||t.handlerIdentity!==e.handlerIdentity||!Number.isFinite(Date.parse(t.leaseExpiresAt))||Date.parse(t.leaseExpiresAt)<=Date.now())throw new RuntimeCommandError("INSTANCE_EPOCH_MISMATCH","runtime message lease changed");return t}}function durablePoisonReason(e){const t=e.replace(/[^a-z0-9_:.-]+/gi,"_").replace(/^_+|_+$/g,"").slice(0,256);if(!t)throw new Error("poison reason is empty");return t}function isCommittedCorePhase(e){return"effect_committed"===e||"projection_committed"===e}const CORE_RECOVERY_DECISIONS=new Set(["execute","resume","replay_effect_committed","resume_projection","publish_committed_result","publish_projected_result","publish_terminal_result"]);function decideMessageServiceRecovery(e,t,o,a){const r=RUNTIME_INVOCATION_PARITY_ENTRIES.find(e=>e.acpMethod===t.method),n=e.terminal?"terminal":"blocked"===e.projectionState?"projection_blocked":"synced"===e.projectionState?"projection_synced":"pending"===e.projectionState?"projection_pending":e.effectCommitted?"runtime_committed":a?"running":"queued",i="failed"===o?.phase||"outcome_unknown"===o?.phase?"terminal":o?.phase,s=o&&o.runtimeEpoch===t.dispatchEpoch&&(void 0===o.messageBinding||o.messageBinding.requestMessageId===t.requestMessageId&&o.messageBinding.requestHash===t.requestHash)?"continuous":"discontinuous";return reduceRuntimeRecoveryPolicy({recoveryClass:r?.recoveryClass??RUNTIME_INVOCATION_RECOVERY_CLASSES[t.method],projectionRequired:"mcp/set"===t.method||"mcp/unset"===t.method||(r?.projectionRequired??!1),messageServicePhase:n,executionBoundaryCrossed:a,lineageContinuity:s,journalState:o?"available":"unavailable",...i?{journalPhase:i}:{}})}export function sanitizeRuntimeServiceResult(e,t,o,a){if("session/clear"===e)return serviceClearResult(t,o?.historyBoundary);if("session/set_model"===e)return serviceSetModelResult(t,o);if(!(e in SERVICE_CANONICAL_COMMAND_NAMES))return t;const r="cron/status"===e&&record(t)?{enabled:t.enabled,jobCount:t.jobCount,..."number"==typeof t.nextWakeAtMs?{nextWakeAtMs:t.nextWakeAtMs}:{}}:t;return mapCanonicalResultToService(e,r,{...a?{platformAgentId:a}:{},classifySkillOrigin:e=>e.bundled?{origin:"bundled",slug:e.slug}:{origin:"legacy_runtime",slug:e.slug},resolveMcpView:e=>({name:e.name,transport:e.transport,origin:"legacy_runtime",...void 0===e.connected?{}:{connected:e.connected},...void 0===e.connectionTimeoutMs?{}:{connectionTimeoutMs:e.connectionTimeoutMs}}),sanitizeDiagnostic:e=>/^[A-Z][A-Z0-9_]{0,63}$/.test(e)?e:"RUNTIME_EXECUTION_FAILED"})}function serviceClearResult(e,t){if(!record(e)||!0!==e.cleared||"string"!=typeof e.historyGeneration||!t||"message-service"!==t.kind)throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed clear result lacks its Message Service receipt");const o=t;if(!o.committedIntentId)throw new RuntimeCommandError("OUTCOME_UNKNOWN","Message Service clear receipt is unavailable");return{...e,clearIntentId:o.committedIntentId()}}function serviceSetModelResult(e,t){if(!record(e)||"string"!=typeof e.effectiveModelId||!t)throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed set_model result is invalid");const o=t.verifiedMessageGrant?.claims.command;if(!o||"session.setModel"!==o.name||"conversation"!==o.context.scope)throw new RuntimeCommandError("OUTCOME_UNKNOWN","set_model Service target receipt is unavailable");const a=o.params.modelOverrideId;return{conversationId:o.context.conversation.runtimeConversationUid,...null===a?{defaultModelId:e.effectiveModelId}:{},modelOverrideId:a,effectiveModelId:e.effectiveModelId,effectState:"committed",projectionState:"synced",operationId:t.operationId}}function isAgentProjectionMethod(e){return"agent/create"===e||"agent/update"===e||"agent/delete"===e||"agent/applyTemplate"===e}function methodRequiresProjectionRevision(e){return isAgentProjectionMethod(e)||"session/set_model"===e}function record(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}function sameLeaseBinding(e,t){return e.instanceId===t.instanceId&&e.leaseId===t.leaseId&&e.handlerIdentity===t.handlerIdentity&&e.runtimeEpoch===t.runtimeEpoch}function failurePayload(e,t,o){const a=t instanceof RuntimeCommandError?t.code:"RUNTIME_EXECUTION_FAILED",r=a in RUNTIME_ERROR_DESCRIPTORS?a:"RUNTIME_EXECUTION_FAILED",n="OUTCOME_UNKNOWN"===r||"INSTANCE_EPOCH_MISMATCH"===r?"outcome_unknown":"COMMAND_EXPIRED"===r?"expired":"OPERATION_CANCELLED"===r?"cancelled":"failed",i="outcome_unknown"===n?"OUTCOME_UNKNOWN":r,s=RUNTIME_ERROR_DESCRIPTORS[i],c="outcome_unknown"===n?"outcome_unknown":n;return{...runtimeMessageBase(e),outcome:n,response:{jsonrpc:"2.0",id:e.request.id,error:{code:s.jsonRpcCode,message:i,data:{code:i,operationId:e.operationId,effectState:c,retryMode:s.retryMode}}},completedAt:o}}function prestartFailurePayload(e,t){const o="invalid_execution_grant"===t?"INVALID_EXECUTION_GRANT":"unsupported_method"===t?"METHOD_NOT_SUPPORTED":"authority_mismatch"===t?"INSTANCE_EPOCH_MISMATCH":"execution_deadline_exceeded"===t?"COMMAND_EXPIRED":"cancelled_before_dispatch"===t?"OPERATION_CANCELLED":"resource_resolution_rejected"===t?"INVALID_INVOCATION":"RUNTIME_EXECUTION_FAILED",a=RUNTIME_ERROR_DESCRIPTORS[o in RUNTIME_ERROR_DESCRIPTORS?o:"RUNTIME_EXECUTION_FAILED"],r="COMMAND_EXPIRED"===o?"expired":"OPERATION_CANCELLED"===o?"cancelled":"failed";return{...runtimeMessageBase(e),outcome:r,response:{jsonrpc:"2.0",id:e.request.id,error:{code:a.jsonRpcCode,message:o,data:{code:o,operationId:e.operationId,effectState:r,retryMode:a.retryMode}}},completedAt:(new Date).toISOString()}}function abortable(e,t){return t?t.aborted?Promise.resolve():new Promise((o,a)=>{const r=()=>o();t.addEventListener("abort",r,{once:!0}),e.then(()=>{t.removeEventListener("abort",r),o()},e=>{t.removeEventListener("abort",r),a(e)})}):e}function delay(e,t){return new Promise(o=>{if(t?.aborted)return o();const a=()=>{clearTimeout(r),o()},r=setTimeout(()=>{t?.removeEventListener("abort",a),o()},e);t?.addEventListener("abort",a,{once:!0})})}
|
|
1
|
+
import{RUNTIME_ERROR_DESCRIPTORS,RUNTIME_HASH_DOMAINS,RUNTIME_INVOCATION_PARITY_ENTRIES,RUNTIME_INVOCATION_RECOVERY_CLASSES,SERVICE_CANONICAL_COMMAND_NAMES,mapCanonicalResultToService}from"@beeos-ai/beeos-types/runtime";import{reduceRuntimeRecoveryPolicy}from"@beeos-ai/beeos-types/runtime/internal";import{verifyAndCreateMessageServiceCoreExecutionAttempt}from"./core-execution-attempt-context.js";import{awaitRuntimeProjection,hasEffectReceiptHandoff,RuntimeCommandError}from"./runtime-command-dispatcher.js";import{createRuntimeAppendTimingRecorder}from"./runtime-append-timing.js";import{RUNTIME_MESSAGE_TYPES,runtimeMessageBase,runtimeMessageHash,semanticEqual,validateRuntimeCancelEnvelope,validateRuntimeRequestEnvelope}from"./runtime-message-channel-contract.js";import{RuntimeResourceResolutionError}from"./runtime-operation-resource-resolver.js";import{RuntimeTransportFailurePolicy}from"./runtime-transport-failure-policy.js";const leaseStarvationReportIntervalMs=3e4;export class MsRuntimeMessageChannelAdapter{dispatcher;channel;verifier;ports;journal;getLease;options;controller;running;externalDeliveryOwner;workers=new Map;poisonJournal;renewTransportFailurePolicy=new RuntimeTransportFailurePolicy;leaseStarvedSince;leaseStarvationReportedAt=0;receiptHistory=this;constructor(e,t,o,a,r,n,i){if(this.dispatcher=e,this.channel=t,this.verifier=o,this.ports=a,this.journal=r,this.getLease=n,this.options=i,!i.poisonJournal)throw new Error("durable poison journal is required");if(this.poisonJournal=i.poisonJournal,!Number.isSafeInteger(i.poisonDeliveryLimit??3)||(i.poisonDeliveryLimit??3)<=0)throw new Error("poison delivery limit must be a positive integer")}start(){if(this.externalDeliveryOwner)return void this.externalDeliveryOwner.start();if(this.running)return;const e=new AbortController;this.controller=e;const t=this.loop(e.signal).catch(t=>{e.signal.aborted||this.observeDeliveryError(t)}).finally(()=>{this.running===t&&(this.running=void 0)});this.running=t}async stop(e){this.controller?.abort();for(const e of this.workers.values())e.cancel?.();if(this.externalDeliveryOwner)return await this.externalDeliveryOwner.stop(e),void await Promise.allSettled([...this.workers.values()].map(e=>e.completion));this.running&&await abortable(this.running,e)}attachExternalDeliveryOwner(e){if(this.running||this.externalDeliveryOwner)throw new Error("runtime delivery owner is already attached");this.externalDeliveryOwner=e}async acceptDelivery(e,t,o){if(this.currentLease(t),e.message.type===RUNTIME_MESSAGE_TYPES.cancel)return void await this.handleCancel(e,t);const a=validateRuntimeRequestEnvelope(e.message),r=a.ok?a.envelope.payload.operationId:e.message.channel_id;if(this.workers.has(r))return;const n={deliveryId:e.deliveryId,claimedLease:t,completion:Promise.resolve()};n.completion=this.handleRequest(e,t,o,e=>{n.cancel=e}).catch(e=>this.observeDeliveryError(e)).finally(()=>{this.workers.delete(r)}),this.workers.set(r,n),await n.completion}async acceptPoisonDelivery(e,t,o){await this.handlePoison(e,t,o)}async readOperationHistory(e){const t=this.getLease();if(!t)return{status:"unavailable"};try{return await this.channel.history({operationId:e.operationId,lease:t})}catch{return{status:"unavailable"}}}async loop(e){let t;(()=>{t||(t=setInterval(()=>{this.renewActive().catch(e=>this.observeDeliveryError(e))},this.options.renewIntervalMs??2e4),t.unref?.())})();try{for(;!e.aborted;){const t=this.getLease();if(!t){this.observeLeaseStarvation(),await delay(this.options.idleDelayMs??500,e);continue}let o;this.observeLeaseRestored();try{o=await this.channel.read({maxCount:this.options.readCount??32,blockMs:this.options.blockMs??5e3,lease:t,signal:e})}catch(t){if(e.aborted)return;this.observeDeliveryError(t),await delay(this.options.idleDelayMs??500,e);continue}for(const a of o){if(e.aborted)break;if(a.message.type===RUNTIME_MESSAGE_TYPES.cancel){await this.handleCancel(a,t).catch(e=>this.observeDeliveryError(e));continue}const o=a.message.channel_id;if(this.workers.has(o))continue;const r={deliveryId:a.deliveryId,claimedLease:t,completion:Promise.resolve()};r.completion=this.handleRequest(a,t,e,e=>{r.cancel=e}).catch(e=>this.observeDeliveryError(e)).finally(()=>{this.workers.delete(o)}),this.workers.set(o,r)}}}finally{t&&clearInterval(t),await Promise.allSettled([...this.workers.values()].map(e=>e.completion))}}observeDeliveryError(e){try{this.options.onDeliveryError?.(e)}catch{}}observeLeaseStarvation(){const e=Date.now();this.leaseStarvedSince??=e;const t=e-this.leaseStarvedSince;if(!(t<3e4||this.leaseStarvationReportedAt&&e-this.leaseStarvationReportedAt<3e4)){this.leaseStarvationReportedAt=e;try{this.options.onLeaseStarvation?.({starvedForMs:t,recovered:!1})}catch{}}}observeLeaseRestored(){const e=this.leaseStarvedSince;if(void 0===e)return;this.leaseStarvedSince=void 0;const t=this.leaseStarvationReportedAt;if(this.leaseStarvationReportedAt=0,t)try{this.options.onLeaseStarvation?.({starvedForMs:Date.now()-e,recovered:!0})}catch{}}observeRequestFailure(e,t,o){try{this.options.onRequestFailure?.({operationId:e,method:t,error:o})}catch{}}async renewActive(){const e=this.getLease();if(!e)return;const t=[];for(const o of this.workers.values())sameLeaseBinding(o.claimedLease,e)?t.push(o.deliveryId):o.cancel?.();if(!t.length)return;let o;try{o=await this.channel.renew({deliveryIds:t,lease:e})}catch(e){if(this.observeDeliveryError(e),this.renewTransportFailurePolicy.recordFailure()){const e=new Set(t);for(const t of this.workers.values())e.has(t.deliveryId)&&t.cancel?.()}return}if(this.renewTransportFailurePolicy.recordSuccess(),o.notPending.length){const e=new Set(o.notPending);for(const t of this.workers.values())e.has(t.deliveryId)&&t.cancel?.()}}async handleCancel(e,t){const o=validateRuntimeCancelEnvelope(e.message);if(!o.ok)return void await this.handlePoison(e,`invalid_cancel:${o.reason}`,t);const a=o.envelope.payload,r=await this.channel.history({operationId:a.operationId,lease:t});if("found"===r.status&&r.snapshot.terminal&&"final_message"===r.snapshot.terminalSource)return void await this.channel.acknowledge({deliveryIds:[e.deliveryId],lease:t});if("not_found"===r.status||"expired"===r.status)return void await this.channel.acknowledge({deliveryIds:[e.deliveryId],lease:t});const n=r.snapshot.request.payload;n.operationId===a.operationId&&n.requestMessageId===a.requestMessageId&&n.requestHash===a.requestHash&&n.dispatchEpoch===a.dispatchEpoch&&n.method===a.method?(await this.journal.observeCancellation({operationId:a.operationId,requestMessageId:a.requestMessageId,requestHash:a.requestHash,eventId:a.eventId}),this.workers.get(a.operationId)?.cancel?.(),await this.channel.acknowledge({deliveryIds:[e.deliveryId],lease:t})):await this.handlePoison(e,"cancel_history_mismatch",t)}async handleRequest(e,t,o,a){const r=validateRuntimeRequestEnvelope(e.message);if(!r.ok)return void await this.handlePoison(e,`invalid_request:${r.reason}`,t);const n=r.envelope.payload,i=e.executionGrant,s=createRuntimeAppendTimingRecorder("runtime-op",{operationId:n.operationId,method:n.method}),c=new AbortController;a(()=>c.abort());const d=async()=>{await this.channel.acknowledge({deliveryIds:[e.deliveryId],lease:this.currentLease(t)}),s.mark("ack")},l=await this.channel.history({operationId:n.operationId,lease:t});if(s.mark("history"),"not_found"===l.status||"expired"===l.status)return void await d();if(l.snapshot.terminal&&"final_message"===l.snapshot.terminalSource)return void await d();if(this.options.allowedMethods&&!this.options.allowedMethods.has(n.method))return await this.reject(n,"unsupported_method",t),void await d();if("deadline"===l.snapshot.terminalSource||Date.parse(n.executionDeadlineAt)<=Date.now()||!l.snapshot.started&&Date.parse(n.claimDeadlineAt)<=Date.now())return await this.reject(n,"execution_deadline_exceeded",t),void await d();const p=await this.journal.getCancellation(n.operationId);s.mark("journal-cancel-read");const u=l.snapshot.cancelRequested||null!==p;if(u&&"queued"===l.snapshot.status)return await this.reject(n,"cancelled_before_dispatch",t),void await d();if(n.instanceId!==t.instanceId||n.runtimeHandlerIdentity!==t.handlerIdentity||n.dispatchEpoch!==t.runtimeEpoch)return await this.reject(n,"authority_mismatch",t),void await d();const h=l.snapshot.request.payload;if(l.snapshot.operationId!==n.operationId||l.snapshot.requestMessageId!==n.requestMessageId||l.snapshot.requestHash!==n.requestHash||!semanticEqual(h,n))return void await this.handlePoison(e,"request_history_mismatch",t);const m=l.snapshot.started?.payload,I=void 0!==m&&m.operationId===n.operationId&&m.requestMessageId===n.requestMessageId&&m.requestHash===n.requestHash&&m.executionGrantHash===n.executionGrantHash&&m.handlerIdentity===t.handlerIdentity&&m.dispatchEpoch===t.runtimeEpoch&&m.method===n.method,E=await this.journal.get(n.operationId);s.mark("journal-prior");const v=await this.journal.acceptMessageRequest({operationId:n.operationId,command:n.command.name,paramsHash:n.paramsHash,runtimeEpoch:n.dispatchEpoch,requestMessageId:n.requestMessageId,requestHash:n.requestHash});s.mark("journal-accept");const f=I?E:v,R=decideMessageServiceRecovery(l.snapshot,n,f,I);if("already_terminal"===R)return void await d();if(!CORE_RECOVERY_DECISIONS.has(R))return await this.markOutcomeUnknownIfMutable(v),await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:failurePayload(n,new RuntimeCommandError("OUTCOME_UNKNOWN",`Types recovery policy requires ${R}; this runtime cannot safely replay Core`),(new Date).toISOString())}),void await d();if(await this.verifier.refresh(),s.mark("verifier-refresh"),!i)return I?await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:failurePayload(n,new RuntimeCommandError("OUTCOME_UNKNOWN","retained started proof has no live execution grant"),(new Date).toISOString())}):await this.reject(n,"invalid_execution_grant",t),void await d();this.verifier.verifyAndDecodeGrant(i)||await this.verifier.refresh(!0);const y=()=>c.abort();let _;o.addEventListener("abort",y,{once:!0});try{_=await verifyAndCreateMessageServiceCoreExecutionAttempt({request:n,executionGrant:i,runtimeEpoch:t.runtimeEpoch,lease:t,verifier:this.verifier,allowExpiredGrant:I,abortSignal:c.signal,resolvePorts:async()=>await this.ports.resolve({request:n,executionGrant:i,command:n.command,getLease:()=>this.currentLease(t),...this.journalLineage(),journalRecord:v,abortSignal:c.signal})})}catch(e){if(o.removeEventListener("abort",y),c.abort(),!(e instanceof RuntimeResourceResolutionError))throw e;if("transient"===e.kind)return;return I?(await this.markOutcomeUnknownIfMutable(v),await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:failurePayload(n,new RuntimeCommandError("OUTCOME_UNKNOWN","eager resources cannot be reconstructed after retained started proof"),(new Date).toISOString())})):await this.reject(n,"integrity_mismatch"===e.kind?"resource_integrity_mismatch":"resource_resolution_rejected",t),void await d()}if(!_.ok)return o.removeEventListener("abort",y),c.abort(),I?(await this.markOutcomeUnknownIfMutable(v),await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:failurePayload(n,new RuntimeCommandError("OUTCOME_UNKNOWN","execution grant cannot be revalidated after retained started proof"),(new Date).toISOString())})):await this.reject(n,"invalid_execution_grant",t),void await d();if(!u||"prepared"!==v.phase&&"started"!==v.phase||c.abort(),c.signal.aborted&&!I)return o.removeEventListener("abort",y),await this.reject(n,"cancelled_before_dispatch",t),void await d();s.mark("attempt"),I?this.currentLease(t):(await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),executionGrant:i,type:RUNTIME_MESSAGE_TYPES.started,payload:{...runtimeMessageBase(n),executionMode:"start",executionGrantHash:n.executionGrantHash,handlerIdentity:t.handlerIdentity,claimedAt:v.messageBinding?.acceptedAt??v.updatedAt}}),s.mark("append-started"));const w=this.dispatcher.dispatch(n.command,_.context);w.completion.catch(()=>{}),a(()=>{c.abort(),w.cancel()}),c.signal.aborted&&w.cancel();const M=this.forwardProgress(n,w.progress,t).catch(()=>{});let g,S=!1;try{if(("mcp/set"===n.method||"mcp/unset"===n.method)&&hasEffectReceiptHandoff(w)){const e=await w.effectCommitted;if(e){if(e.operationId!==n.operationId||e.method!==n.command.name)throw new RuntimeCommandError("OUTCOME_UNKNOWN","Core MCP receipt correlation mismatch");const o=runtimeMessageHash(RUNTIME_HASH_DOMAINS.coreResult,{method:n.method,result:e.result}),a={schemaVersion:1,operationId:n.operationId,method:n.method,coreResultRef:`sha256:${o}`,coreResultHash:o};g=runtimeMessageHash(RUNTIME_HASH_DOMAINS.effectRecord,a),S=!0,await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.effectCommitted,payload:{...runtimeMessageBase(n),effectRecord:a,effectRecordHash:g,committedAt:e.committedAt}}),await w.acknowledgeEffectReceipt({operationId:n.operationId,method:n.command.name,effectRecordHash:g})}}const o=await w.completion;await M,s.mark("core");const a=await this.journal.get(n.operationId);if(s.mark("journal-after-core"),!a||!isCommittedCorePhase(a.phase))throw new RuntimeCommandError("OUTCOME_UNKNOWN","Core completed without a committed local journal record");const r=a.updatedAt;let i,c;if("query"!==RUNTIME_INVOCATION_RECOVERY_CLASSES[n.method]){const e=isAgentProjectionMethod(n.method),c=w.getSnapshot().projection,l=a.agentProjectionIntent??a.agentProjectionPreparationFailure;if(e&&!l)throw new RuntimeCommandError("OUTCOME_UNKNOWN","agent effect committed without an atomic projection preparation record");if(!g){const e=l?.coreResultHash??runtimeMessageHash(RUNTIME_HASH_DOMAINS.coreResult,{method:n.method,result:o}),i=a.agentProjectionIntent?.projectionRevision??(methodRequiresProjectionRevision(n.method)?c?.revision??`${Math.max(0,a.revision)}`:void 0),d={schemaVersion:1,operationId:n.operationId,method:n.method,coreResultRef:`sha256:${e}`,coreResultHash:e,...i?{projectionRevision:i}:{}};g=runtimeMessageHash(RUNTIME_HASH_DOMAINS.effectRecord,d),S=!0,await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.effectCommitted,payload:{...runtimeMessageBase(n),effectRecord:d,effectRecordHash:g,committedAt:r}}),s.mark("append-effect")}let p=e?await awaitRuntimeProjection(w):c;if("session/set_model"===n.method&&"synced"!==p?.state&&(p=await this.projectSessionModelAfterEffect(n,_.context,a,p),s.mark("set-model-projection")),e&&a.agentProjectionIntent&&(!p||p.revision!==a.agentProjectionIntent.projectionRevision))throw new RuntimeCommandError("OUTCOME_UNKNOWN","agent projection receipt revision mismatch");if("pending"===p?.state)return void await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.projectionPending,payload:{...runtimeMessageBase(n),revision:p.revision}});if("synced"===p?.state&&await this.publishProjectionSynced(n,t,{...p,state:"synced"}),"blocked"===p?.state){await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.projectionBlocked,payload:{...runtimeMessageBase(n),revision:p.revision,errorCode:"PROJECTION_BLOCKED"}});const e=RUNTIME_ERROR_DESCRIPTORS.PROJECTION_BLOCKED;return await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:{...runtimeMessageBase(n),outcome:"projection_blocked",response:{jsonrpc:"2.0",id:n.request.id,error:{code:e.jsonRpcCode,message:"PROJECTION_BLOCKED",data:{code:"PROJECTION_BLOCKED",operationId:n.operationId,effectState:"committed",retryMode:e.retryMode}}},effectRecordHash:g,completedAt:r}}),void await d()}i=e?p?.platformAgentId:void 0}try{c=sanitizeRuntimeServiceResult(n.method,o,_.context,i)}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed Core result cannot be mapped safely",void 0,{cause:e})}const l=runtimeMessageHash(RUNTIME_HASH_DOMAINS.serviceResult,{method:n.method,result:c});S=!0;const p=await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:{...runtimeMessageBase(n),outcome:"succeeded",response:{jsonrpc:"2.0",id:n.request.id,result:c},serviceResultHash:l,...g?{effectRecordHash:g}:{},completedAt:r}});if(s.mark("append-final"),this.observeRequestTerminalAccepted(e.deliveryId,p.message),("mcp/set"===n.method||"mcp/unset"===n.method)&&hasEffectReceiptHandoff(w)&&"function"==typeof w.acknowledgeTerminalReceipt){if(!g)throw new RuntimeCommandError("OUTCOME_UNKNOWN","MCP terminal response lacks its committed effect hash");await w.acknowledgeTerminalReceipt({operationId:n.operationId,method:n.command.name,effectRecordHash:g,terminalMessageId:p.message.message_id})}await d(),this.observeRequestAcknowledged(e.deliveryId,p.message)}catch(e){const o=await this.journal.get(n.operationId);if(o&&isCommittedCorePhase(o.phase)&&S)throw e;const a=!o||!isCommittedCorePhase(o.phase)||e instanceof RuntimeCommandError&&"OUTCOME_UNKNOWN"===e.code?e:new RuntimeCommandError("OUTCOME_UNKNOWN","Core effect committed before terminal mapping",void 0,{cause:e});this.observeRequestFailure(n.operationId,n.method,a);const r=failurePayload(n,a,o?.updatedAt??(new Date).toISOString());await this.channel.append({operationId:n.operationId,lease:this.currentLease(t),type:RUNTIME_MESSAGE_TYPES.final,payload:r}),s.mark("append-terminal-failure"),await d()}finally{s.finish(),c.abort(),o.removeEventListener("abort",y)}}async handlePoison(e,t,o){this.currentLease(o);(await this.poisonJournal.record({delivery:e,reason:durablePoisonReason(t),limit:this.options.poisonDeliveryLimit??3})).terminal&&await this.channel.acknowledge({deliveryIds:[e.deliveryId],lease:this.currentLease(o)})}observeRequestTerminalAccepted(e,t){try{this.options.onRequestTerminalAccepted?.({deliveryId:e,message:t})}catch{}}observeRequestAcknowledged(e,t){try{this.options.onRequestAcknowledged?.({deliveryId:e,message:t})}catch{}}async forwardProgress(e,t,o){for await(const a of t)await this.channel.append({operationId:e.operationId,lease:this.currentLease(o),type:RUNTIME_MESSAGE_TYPES.progress,payload:{...runtimeMessageBase(e),phase:a.phase,progress:a}})}async reject(e,t,o){await this.channel.append({operationId:e.operationId,lease:this.currentLease(o),type:RUNTIME_MESSAGE_TYPES.final,payload:prestartFailurePayload(e,t)})}async markOutcomeUnknownIfMutable(e){"prepared"!==e.phase&&"started"!==e.phase||await this.journal.transition({operationId:e.operationId,expectedRevision:e.revision,phase:"outcome_unknown",errorCode:"OUTCOME_UNKNOWN"})}async projectSessionModelAfterEffect(e,t,o,a){const r=Object.freeze({state:"pending",revision:a?.revision??`${Math.max(0,o.revision)}`}),n=e.command;if("session.setModel"!==n.name||"conversation"!==n.context.scope)return r;const i=t.sessionModelProjection;if(!i)return r;try{await i.project({conversationId:n.context.conversation.runtimeConversationUid,modelOverrideId:n.params.modelOverrideId});const e=Object.freeze({state:"synced",revision:r.revision});try{const t=await this.journal.get(o.operationId)??o;if("projection_committed"===t.phase&&"synced"===t.projectionReceipt?.snapshot.state)return Object.freeze({state:"synced",revision:t.projectionReceipt.snapshot.revision});await this.journal.transition({operationId:t.operationId,expectedRevision:t.revision,phase:"projection_committed",projectionSnapshot:e})}catch{}return e}catch(e){return this.observeDeliveryError(e),r}}async publishProjectionSynced(e,t,o){const a=this.currentLease(t),r=await this.channel.history({operationId:e.operationId,lease:a});if("found"===r.status&&"synced"===r.snapshot.projectionState)return;const n={...runtimeMessageBase(e),revision:o.revision};("found"!==r.status||"reserved"===r.snapshot.projectionState||"pending"!==r.snapshot.projectionState&&void 0===r.snapshot.projectionPending)&&await this.channel.append({operationId:e.operationId,lease:a,type:RUNTIME_MESSAGE_TYPES.projectionPending,payload:n}),await this.channel.append({operationId:e.operationId,lease:a,type:RUNTIME_MESSAGE_TYPES.projectionSynced,payload:{...n,...o.platformAgentId?{platformAgentId:o.platformAgentId}:{}}})}journalLineage(){return this.options.getJournalLineage?.()??{journalStoreId:this.options.journalStoreId,journalGeneration:this.options.journalGeneration}}currentLease(e){const t=this.getLease();if(!t||t.instanceId!==e.instanceId||t.leaseId!==e.leaseId||t.runtimeEpoch!==e.runtimeEpoch||t.handlerIdentity!==e.handlerIdentity||!Number.isFinite(Date.parse(t.leaseExpiresAt))||Date.parse(t.leaseExpiresAt)<=Date.now())throw new RuntimeCommandError("INSTANCE_EPOCH_MISMATCH","runtime message lease changed");return t}}function durablePoisonReason(e){const t=e.replace(/[^a-z0-9_:.-]+/gi,"_").replace(/^_+|_+$/g,"").slice(0,256);if(!t)throw new Error("poison reason is empty");return t}function isCommittedCorePhase(e){return"effect_committed"===e||"projection_committed"===e}const CORE_RECOVERY_DECISIONS=new Set(["execute","resume","replay_effect_committed","resume_projection","publish_committed_result","publish_projected_result","publish_terminal_result"]);function decideMessageServiceRecovery(e,t,o,a){const r=RUNTIME_INVOCATION_PARITY_ENTRIES.find(e=>e.acpMethod===t.method),n=e.terminal?"terminal":"blocked"===e.projectionState?"projection_blocked":"synced"===e.projectionState?"projection_synced":"pending"===e.projectionState?"projection_pending":e.effectCommitted?"runtime_committed":a?"running":"queued",i="failed"===o?.phase||"outcome_unknown"===o?.phase?"terminal":o?.phase,s=o&&o.runtimeEpoch===t.dispatchEpoch&&(void 0===o.messageBinding||o.messageBinding.requestMessageId===t.requestMessageId&&o.messageBinding.requestHash===t.requestHash)?"continuous":"discontinuous";return reduceRuntimeRecoveryPolicy({recoveryClass:r?.recoveryClass??RUNTIME_INVOCATION_RECOVERY_CLASSES[t.method],projectionRequired:"mcp/set"===t.method||"mcp/unset"===t.method||(r?.projectionRequired??!1),messageServicePhase:n,executionBoundaryCrossed:a,lineageContinuity:s,journalState:o?"available":"unavailable",...i?{journalPhase:i}:{}})}export function sanitizeRuntimeServiceResult(e,t,o,a){if("session/clear"===e)return serviceClearResult(t,o?.historyBoundary);if("session/set_model"===e)return serviceSetModelResult(t,o);if(!(e in SERVICE_CANONICAL_COMMAND_NAMES))return t;const r="cron/status"===e&&record(t)?{enabled:t.enabled,jobCount:t.jobCount,..."number"==typeof t.nextWakeAtMs?{nextWakeAtMs:t.nextWakeAtMs}:{}}:t;return mapCanonicalResultToService(e,r,{...a?{platformAgentId:a}:{},classifySkillOrigin:e=>e.bundled?{origin:"bundled",slug:e.slug}:{origin:"legacy_runtime",slug:e.slug},resolveMcpView:e=>({name:e.name,transport:e.transport,origin:"legacy_runtime",...void 0===e.connected?{}:{connected:e.connected},...void 0===e.connectionTimeoutMs?{}:{connectionTimeoutMs:e.connectionTimeoutMs}}),sanitizeDiagnostic:e=>/^[A-Z][A-Z0-9_]{0,63}$/.test(e)?e:"RUNTIME_EXECUTION_FAILED"})}function serviceClearResult(e,t){if(!record(e)||!0!==e.cleared||"string"!=typeof e.historyGeneration||!t||"message-service"!==t.kind)throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed clear result lacks its Message Service receipt");const o=t;if(!o.committedIntentId)throw new RuntimeCommandError("OUTCOME_UNKNOWN","Message Service clear receipt is unavailable");return{...e,clearIntentId:o.committedIntentId()}}function serviceSetModelResult(e,t){if(!record(e)||"string"!=typeof e.effectiveModelId||!t)throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed set_model result is invalid");const o=t.verifiedMessageGrant?.claims.command;if(!o||"session.setModel"!==o.name||"conversation"!==o.context.scope)throw new RuntimeCommandError("OUTCOME_UNKNOWN","set_model Service target receipt is unavailable");const a=o.params.modelOverrideId;return{conversationId:o.context.conversation.runtimeConversationUid,...null===a?{defaultModelId:e.effectiveModelId}:{},modelOverrideId:a,effectiveModelId:e.effectiveModelId,effectState:"committed",projectionState:"synced",operationId:t.operationId}}function isAgentProjectionMethod(e){return"agent/create"===e||"agent/update"===e||"agent/delete"===e||"agent/applyTemplate"===e}function methodRequiresProjectionRevision(e){return isAgentProjectionMethod(e)||"session/set_model"===e}function record(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}function sameLeaseBinding(e,t){return e.instanceId===t.instanceId&&e.leaseId===t.leaseId&&e.handlerIdentity===t.handlerIdentity&&e.runtimeEpoch===t.runtimeEpoch}function failurePayload(e,t,o){const a=t instanceof RuntimeCommandError?t.code:"RUNTIME_EXECUTION_FAILED",r=a in RUNTIME_ERROR_DESCRIPTORS?a:"RUNTIME_EXECUTION_FAILED",n="OUTCOME_UNKNOWN"===r||"INSTANCE_EPOCH_MISMATCH"===r?"outcome_unknown":"COMMAND_EXPIRED"===r?"expired":"OPERATION_CANCELLED"===r?"cancelled":"failed",i="outcome_unknown"===n?"OUTCOME_UNKNOWN":r,s=RUNTIME_ERROR_DESCRIPTORS[i],c="outcome_unknown"===n?"outcome_unknown":n;return{...runtimeMessageBase(e),outcome:n,response:{jsonrpc:"2.0",id:e.request.id,error:{code:s.jsonRpcCode,message:i,data:{code:i,operationId:e.operationId,effectState:c,retryMode:s.retryMode}}},completedAt:o}}function prestartFailurePayload(e,t){const o="invalid_execution_grant"===t?"INVALID_EXECUTION_GRANT":"unsupported_method"===t?"METHOD_NOT_SUPPORTED":"authority_mismatch"===t?"INSTANCE_EPOCH_MISMATCH":"execution_deadline_exceeded"===t?"COMMAND_EXPIRED":"cancelled_before_dispatch"===t?"OPERATION_CANCELLED":"resource_resolution_rejected"===t?"INVALID_INVOCATION":"RUNTIME_EXECUTION_FAILED",a=RUNTIME_ERROR_DESCRIPTORS[o in RUNTIME_ERROR_DESCRIPTORS?o:"RUNTIME_EXECUTION_FAILED"],r="COMMAND_EXPIRED"===o?"expired":"OPERATION_CANCELLED"===o?"cancelled":"failed";return{...runtimeMessageBase(e),outcome:r,response:{jsonrpc:"2.0",id:e.request.id,error:{code:a.jsonRpcCode,message:o,data:{code:o,operationId:e.operationId,effectState:r,retryMode:a.retryMode}}},completedAt:(new Date).toISOString()}}function abortable(e,t){return t?t.aborted?Promise.resolve():new Promise((o,a)=>{const r=()=>o();t.addEventListener("abort",r,{once:!0}),e.then(()=>{t.removeEventListener("abort",r),o()},e=>{t.removeEventListener("abort",r),a(e)})}):e}function delay(e,t){return new Promise(o=>{if(t?.aborted)return o();const a=()=>{clearTimeout(r),o()},r=setTimeout(()=>{t?.removeEventListener("abort",a),o()},e);t?.addEventListener("abort",a,{once:!0})})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{MsRuntimeMessageChannelAdapter}from"./ms-runtime-message-channel-adapter.js";import{decodeRuntimeAppendMessage,decodeRuntimeBrokerDelivery,decodeRuntimeOperationHistory,RuntimeMessageChannelProtocolError}from"./message-service-runtime-message-channel.js";export class MsRuntimeMessageChannelConsumerFactory{deps;constructor(e){this.deps=e}async create(e){let n;const s=new SdkRuntimeMessageChannel(()=>{if(!n)throw new Error("SDK runtime delivery consumer is not attached");return n}),r=new MsRuntimeMessageChannelAdapter(e.dispatcher,s,this.deps.verifier,this.deps.ports,this.deps.journal,()=>e.getLease(),{...this.deps.options,allowedMethods:this.deps.allowedMethods,journalStoreId:e.binding.journalStoreId,journalGeneration:e.binding.journalGeneration,...e.getBinding?{getJournalLineage:()=>{const n=e.getBinding();return{journalStoreId:n.journalStoreId,journalGeneration:n.journalGeneration}}}:{}});return n=this.deps.client.methods.consume({onDelivery:async(n,s)=>{const
|
|
1
|
+
import{MsRuntimeMessageChannelAdapter}from"./ms-runtime-message-channel-adapter.js";import{decodeRuntimeAppendMessage,decodeRuntimeBrokerDelivery,decodeRuntimeOperationHistory,RuntimeMessageChannelProtocolError}from"./message-service-runtime-message-channel.js";import{isCanonicalSessionNewDelivery,SessionNewRuntimeDeliveryBridge}from"./session-new-runtime-delivery-bridge.js";export class MsRuntimeMessageChannelConsumerFactory{deps;constructor(e){this.deps=e}async create(e){let n;const s=new SdkRuntimeMessageChannel(()=>{if(!n)throw new Error("SDK runtime delivery consumer is not attached");return n}),r=new MsRuntimeMessageChannelAdapter(e.dispatcher,s,this.deps.verifier,this.deps.ports,this.deps.journal,()=>e.getLease(),{...this.deps.options,allowedMethods:this.deps.allowedMethods,journalStoreId:e.binding.journalStoreId,journalGeneration:e.binding.journalGeneration,...e.getBinding?{getJournalLineage:()=>{const n=e.getBinding();return{journalStoreId:n.journalStoreId,journalGeneration:n.journalGeneration}}}:{}}),t=new SessionNewRuntimeDeliveryBridge({client:this.deps.client,consumer:()=>{if(!n)throw new Error("SDK runtime delivery consumer is not attached");return n},verifier:this.deps.verifier,getLease:()=>e.getLease(),createRuntimeSession:e.createRuntimeSession,poison:async(e,n,s)=>{await r.acceptPoisonDelivery(e,n,s)}});return n=this.deps.client.methods.consume({onDelivery:async(n,s)=>{const i=currentFencedLease(e,s.lease),o=decodeRuntimeBrokerDelivery(n);isCanonicalSessionNewDelivery(o)?await t.acceptDelivery(o,i,s.signal):await r.acceptDelivery(o,i,s.signal)},onError:this.deps.options.onDeliveryError,readCount:this.deps.options.readCount,blockMs:this.deps.options.blockMs,idleDelayMs:this.deps.options.idleDelayMs,renewIntervalMs:this.deps.options.renewIntervalMs}),r.attachExternalDeliveryOwner(n),r}}class SdkRuntimeMessageChannel{consumer;constructor(e){this.consumer=e}async read(){throw new Error("MessageClient owns runtime delivery reads")}async renew(){throw new Error("MessageClient owns runtime delivery renewal")}async acknowledge(e){assertLeaseAvailable(e.lease),await this.consumer().acknowledge(e.deliveryIds)}async history(e){assertLeaseAvailable(e.lease);const n=await this.consumer().history(e.operationId);return"found"!==n.status?n:{status:"found",snapshot:decodeRuntimeOperationHistory(n.snapshot,e.operationId)}}async append(e){assertLeaseAvailable(e.lease);const n=await this.consumer().append(e.operationId,e.type,e.payload,e.executionGrant);if("created"===n.outcome||"duplicate"===n.outcome)return{disposition:"created"===n.outcome?"created":"reused",message:decodeRuntimeAppendMessage(n.message,e)};if(n.history){const s=findReconciledMessage(decodeRuntimeOperationHistory(n.history,e.operationId),e);if(s)return{disposition:"reused",message:s}}throw new RuntimeMessageChannelProtocolError("runtime append outcome is unknown after history reconcile",503,"OUTCOME_UNKNOWN")}}function currentFencedLease(e,n){const s=e.getLease(),r=e.getBinding?.()??e.binding;if(!s||s.instanceId!==n.instanceId||s.handlerIdentity!==n.handlerIdentity||s.runtimeEpoch!==n.runtimeEpoch||s.leaseId!==n.leaseId||r.journalStoreId!==n.journalStoreId||r.journalGeneration!==n.journalGeneration)throw new Error("runtime delivery lease fence changed");if(Date.parse(s.leaseExpiresAt)<=Date.now())throw new Error("runtime delivery lease expired");return s}function assertLeaseAvailable(e){if(!Number.isFinite(Date.parse(e.leaseExpiresAt))||Date.parse(e.leaseExpiresAt)<=Date.now())throw new Error("runtime delivery lease expired")}function findReconciledMessage(e,n){for(let s=e.messages.length-1;s>=0;s-=1)try{return decodeRuntimeAppendMessage(e.messages[s],n)}catch{}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{}
|
|
1
|
+
export class RuntimeSessionNewRejectedError extends Error{constructor(e){super(e),this.name="RuntimeSessionNewRejectedError"}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{RUNTIME_ERROR_DESCRIPTORS,RUNTIME_HASH_DOMAINS}from"@beeos-ai/beeos-types/runtime";import{verifyAndCreateMessageServiceCoreExecutionAttempt}from"./core-execution-attempt-context.js";import{RuntimeSessionNewRejectedError}from"./runtime-rpc-consumer.js";import{RUNTIME_MESSAGE_TYPES,runtimeMessageHash}from"./runtime-message-channel-contract.js";const SESSION_NEW_METHOD="session/new",SESSION_NEW_COMMAND="session.create";export class SessionNewRuntimeDeliveryBridge{options;workers=new Map;constructor(e){this.options=e}async acceptDelivery(e,t,s){this.currentLease(t);const r=record(e.message.payload),n=string(r?.operationId)??e.message.channel_id,o=this.workers.get(n);if(o)return await o;const i=this.handleDelivery(e,t,s).finally(()=>this.workers.delete(n));this.workers.set(n,i),await i}async handleDelivery(e,t,s){const r=parseSessionNewRequest(e);if(!r.ok)return void await this.options.poison(e,`invalid_session_new:${r.reason}`,t);const n=r.request,o=this.options.consumer(),i=async()=>{this.currentLease(t),await o.acknowledge([e.deliveryId])},a=await o.history(n.operationId);if("found"!==a.status)return void await i();const d=parseSessionNewHistory(a.snapshot);if(!d.ok||d.request.operationId!==n.operationId||d.request.requestMessageId!==n.requestMessageId||d.request.requestHash!==n.requestHash)return void await this.options.poison(e,"session_new_history_mismatch",t);const c=d.request;if(d.terminal)return void await i();if(c.instanceId!==t.instanceId||c.runtimeHandlerIdentity!==t.handlerIdentity||c.dispatchEpoch!==t.runtimeEpoch)return await this.appendFailure(c,t,"INSTANCE_EPOCH_MISMATCH"),void await i();const u=Date.now();if("deadline"===d.terminalSource||Date.parse(c.executionDeadlineAt)<=u||!d.started&&Date.parse(c.claimDeadlineAt)<=u)return await this.appendFailure(c,t,"COMMAND_EXPIRED"),void await i();if(d.cancelRequested&&!d.started)return await this.appendFailure(c,t,"OPERATION_CANCELLED"),void await i();const p=e.executionGrant;if(!p)return await this.appendFailure(c,t,d.started?"OUTCOME_UNKNOWN":"INVALID_EXECUTION_GRANT"),void await i();await this.options.verifier.refresh(),this.options.verifier.verifyAndDecodeGrant(p)||await this.options.verifier.refresh(!0);const h=new AbortController,l=()=>h.abort();s.addEventListener("abort",l,{once:!0});try{const e=await verifyAndCreateMessageServiceCoreExecutionAttempt({request:c,executionGrant:p,runtimeEpoch:t.runtimeEpoch,lease:t,verifier:this.options.verifier,allowExpiredGrant:d.started,abortSignal:h.signal,resolvePorts:async()=>({resources:noSessionNewResources})});if(!e.ok)return await this.appendFailure(c,t,d.started?"OUTCOME_UNKNOWN":"INVALID_EXECUTION_GRANT"),void await i();if(s.aborted)throw new Error("session/new delivery owner stopped");d.started?this.currentLease(t):await this.append(c,t,RUNTIME_MESSAGE_TYPES.started,{...correlation(c),executionGrantHash:c.executionGrantHash,handlerIdentity:t.handlerIdentity,executionMode:"start",claimedAt:(new Date).toISOString()},p);const r=c.request.params.agentId;let n;try{n=await this.options.createRuntimeSession({operationId:c.operationId,platformAgentId:r,...optionalStringProperty(c.request.params,"cwd"),...optionalStringProperty(c.command.params,"title")},e.context)}catch(e){if(!(e instanceof RuntimeSessionNewRejectedError))throw e;return await this.appendFailure(c,t,"INVALID_INVOCATION"),void await i()}const o=c.instanceId,a=r.startsWith("agent:")?r:`agent:${r}`;let u;try{u=await this.options.client.conversations.create({agentId:r,participants:dedupe([o,a,c.callerIdentityId]),...optionalStringProperty(c.command.params,"title"),metadata:{source:"session/new",runtimeSessionId:n.sessionId,runtimeSessionKey:n.gatewaySessionKey,runtimeInstanceId:c.instanceId,runtimeEpoch:c.dispatchEpoch,platformAgentId:r},idempotencyKey:c.operationId})}catch(e){const s=httpStatus(e);if(void 0===s||s>=500||408===s||429===s)throw e;return await this.appendFailure(c,t,"INVALID_INVOCATION"),void await i()}const l={sessionId:n.sessionId,conversationId:u.id},I=runtimeMessageHash(RUNTIME_HASH_DOMAINS.serviceResult,{method:"session/new",result:l});await this.append(c,t,RUNTIME_MESSAGE_TYPES.final,{...correlation(c),outcome:"succeeded",response:{jsonrpc:"2.0",id:c.request.id,result:l},serviceResultHash:I,completedAt:(new Date).toISOString()}),await i()}finally{h.abort(),s.removeEventListener("abort",l)}}async appendFailure(e,t,s){const r="COMMAND_EXPIRED"===s?"expired":"OPERATION_CANCELLED"===s?"cancelled":"OUTCOME_UNKNOWN"===s||"INSTANCE_EPOCH_MISMATCH"===s?"outcome_unknown":"failed",n="outcome_unknown"===r?"OUTCOME_UNKNOWN":s,o=RUNTIME_ERROR_DESCRIPTORS[n];await this.append(e,t,RUNTIME_MESSAGE_TYPES.final,{...correlation(e),outcome:r,response:{jsonrpc:"2.0",id:e.request.id,error:{code:o.jsonRpcCode,message:n,data:{code:n,operationId:e.operationId,effectState:r,retryMode:o.retryMode}}},completedAt:(new Date).toISOString()})}async append(e,t,s,r,n){this.currentLease(t);const o=this.options.consumer(),i=await o.append(e.operationId,s,r,n);if("created"===i.outcome||"duplicate"===i.outcome)return;let a=i.history;if(void 0===a){const t=await o.history(e.operationId);"found"===t.status&&(a=t.snapshot)}if(!hasCorrelatedMessage(a,s,e))throw new Error(`session/new ${s} append outcome is unknown`)}currentLease(e){const t=this.options.getLease();if(!t||t.instanceId!==e.instanceId||t.leaseId!==e.leaseId||t.runtimeEpoch!==e.runtimeEpoch||t.handlerIdentity!==e.handlerIdentity)throw new Error("session/new runtime delivery lease fence changed");if(!Number.isFinite(Date.parse(t.leaseExpiresAt))||Date.parse(t.leaseExpiresAt)<=Date.now())throw new Error("session/new runtime delivery lease expired");return t}}export function isCanonicalSessionNewDelivery(e){return"session/new"===record(e.message.payload)?.method}function parseSessionNewRequest(e){const t=e.message,s=record(t.payload),r=record(s?.request),n=record(r?.params),o=record(s?.command),i=record(o?.context),a=void 0===o?.params?void 0:record(o.params),d=[s?.operationId,s?.requestMessageId,s?.requestHash,s?.executionGrantHash,s?.instanceId,s?.runtimeHandlerIdentity,s?.dispatchEpoch,s?.callerIdentityId,s?.claimDeadlineAt,s?.executionDeadlineAt];return 1===s?.schemaVersion&&"session/new"===s?.method&&d.every(nonempty)&&"2.0"===r?.jsonrpc&&"session/new"===r.method&&("string"==typeof r.id||"number"==typeof r.id)&&n&&nonempty(n.agentId)&&"session.create"===o?.name&&i&&"instance"===i.scope&&i.operationId===s.operationId&&i.runtimeInstanceUid===s.instanceId&&i.dispatchEpoch===s.dispatchEpoch&&(void 0===o.params||a)&&t.type===RUNTIME_MESSAGE_TYPES.request&&t.channel_id===s.operationId&&t.message_id===s.requestMessageId&&Number.isFinite(Date.parse(s.claimDeadlineAt))&&Number.isFinite(Date.parse(s.executionDeadlineAt))?{ok:!0,request:s}:{ok:!1,reason:"required session/new fields do not correlate"}}function parseSessionNewHistory(e){const t=record(e),s=parseSessionNewRequest({deliveryId:"retained",redelivered:!0,idleMs:0,message:record(t?.request)});if(!s.ok||t?.operationId!==s.request.operationId||t.requestMessageId!==s.request.requestMessageId||t.requestHash!==s.request.requestHash)return{ok:!1};const r=record(t.started),n=record(r?.payload),o=void 0!==r&&n?.operationId===s.request.operationId&&n.requestMessageId===s.request.requestMessageId&&n.requestHash===s.request.requestHash&&n.dispatchEpoch===s.request.dispatchEpoch&&"session/new"===n.method;return{ok:!0,request:s.request,terminal:!0===t.terminal,terminalSource:string(t.terminalSource)??"none",cancelRequested:!0===t.cancelRequested,started:o}}function correlation(e){return{schemaVersion:1,operationId:e.operationId,requestMessageId:e.requestMessageId,requestHash:e.requestHash,dispatchEpoch:e.dispatchEpoch,method:"session/new"}}function hasCorrelatedMessage(e,t,s){const r=record(e);return(Array.isArray(r?.messages)?r.messages:[]).some(e=>{const r=record(e),n=record(r?.payload);return r?.type===t&&n?.operationId===s.operationId&&n.requestMessageId===s.requestMessageId&&n.requestHash===s.requestHash&&n.dispatchEpoch===s.dispatchEpoch&&"session/new"===n.method})}function optionalStringProperty(e,t){const s=e?.[t];return"string"==typeof s&&s.length>0?{[t]:s}:{}}function dedupe(e){return[...new Set(e.filter(e=>e.length>0))]}function httpStatus(e){const t=record(e),s=t?.status;return"number"==typeof s?s:void 0}function record(e){return null===e||"object"!=typeof e||Array.isArray(e)?void 0:e}function string(e){return"string"==typeof e&&e.length>0?e:void 0}function nonempty(e){return"string"==typeof e&&e.length>0}const noSessionNewResources=Object.freeze({async readContent(){throw new Error("session/new does not accept content resources")},async readVerifiedArtifact(){throw new Error("session/new does not accept artifact resources")}});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beeos-claw",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.31",
|
|
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>",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@beeos-ai/beeos-types": "4.2.0",
|
|
65
65
|
"@beeos-ai/bridge-client": "^0.1.0",
|
|
66
|
-
"@beeos-ai/message-sdk": "2.0.
|
|
66
|
+
"@beeos-ai/message-sdk": "2.0.7",
|
|
67
67
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
68
68
|
"adm-zip": "^0.6.0",
|
|
69
69
|
"ws": "^8.18.0"
|