beeos-claw 0.6.55 → 0.6.57
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/bridge-core.js +1 -1
- package/dist/acp-gateway/mcp-native-projection-nudge.js +1 -0
- package/dist/acp-server.js +1 -1
- package/dist/im-inbound-handler.js +1 -1
- package/dist/im-runtime-dispatch.js +1 -1
- package/dist/index.js +1 -1
- package/dist/runtime/im-hot-path-deferral.js +1 -0
- package/dist/runtime/prompt-run-store.js +1 -1
- package/dist/runtime/runtime-command-dispatcher.js +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash,randomUUID}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{homedir}from"node:os";import path,{join,relative,resolve}from"node:path";import{RUNTIME_HASH_DOMAINS,RUNTIME_METHOD_PARITY_MANIFEST,runtimeHashPreimage}from"@beeos-ai/beeos-types/runtime";import{reduceRuntimeRecoveryPolicy}from"@beeos-ai/beeos-types/runtime/internal";import{assertTrustedCoreExecutionAttempt}from"./core-execution-attempt-context.js";import{InMemoryRuntimeCommandJournal,RuntimeCommandJournalConflictError,runtimeCommandIsReplayableQuery,runtimeCommandResultHash}from"./runtime-command-journal.js";import{RuntimeProjectionTransportError}from"./agent-projection-worker.js";const DEFAULT_AGENT_ID="main",AGENT_VALID_ID_RE=/^[a-z0-9][a-z0-9_-]{0,63}$/i,AGENT_INVALID_CHARS_RE=/[^a-z0-9_-]+/g;export function normalizeRuntimeAgentLocalKey(e){const t=(e??"").trim();return t?AGENT_VALID_ID_RE.test(t)?t.toLowerCase():t.toLowerCase().replace(AGENT_INVALID_CHARS_RE,"-").replace(/^-+/,"").replace(/-+$/,"").slice(0,64)||"main":"main"}export async function awaitRuntimeProjection(e){const t=e;return await(t.awaitProjection?.()??Promise.resolve(e.getSnapshot().projection))}export function hasEffectReceiptHandoff(e){const t=e;return t.effectCommitted instanceof Promise&&"function"==typeof t.acknowledgeEffectReceipt}export class RuntimeCommandError extends Error{code;param;constructor(e,t,r,i){super(t,i),this.code=e,this.param=r,this.name="RuntimeCommandError"}}const emptyProgress=async function*(){};function deferred(){let e;return{promise:new Promise(t=>{e=t}),resolve:e}}async function waitForEffectReceipt(e,t){if(!t)return await e;if(t.aborted)throw new RuntimeCommandError("OUTCOME_UNKNOWN","MCP effect receipt was not durably published before the Service attempt ended");await new Promise((r,i)=>{const n=()=>i(new RuntimeCommandError("OUTCOME_UNKNOWN","MCP effect receipt was not durably published before the Service attempt ended"));t.addEventListener("abort",n,{once:!0}),e.then(()=>{t.removeEventListener("abort",n),r()},e=>{t.removeEventListener("abort",n),i(e)})})}export class OpenClawRuntimeCommandDispatcher{deps;logger;getOpenclawHome;createAgentId;journal;capabilities;constructor(e){this.deps=e,this.logger=e.logger??{},this.getOpenclawHome=e.getOpenclawHome??(()=>process.env.OPENCLAW_HOME||join(homedir(),".openclaw")),this.createAgentId=e.createAgentId??(()=>`agent-${randomUUID().replace(/-/g,"").slice(0,12)}`),this.journal=e.journal??new InMemoryRuntimeCommandJournal,this.capabilities=e.capabilities}setCapabilities(e){this.capabilities=e}dispatch(e,t){const r=e;assertTrustedCoreExecutionAttempt(t,{operationId:r.context.operationId,runtimeEpoch:r.context.dispatchEpoch});let i,n,a,o="running";const s=deferred(),c=deferred();let m;const d="service"===t.origin&&("mcp.set"===r.name||"mcp.unset"===r.name),p=this.executeWithLease(r,t,(e,t)=>{o="committed",m={operationId:r.context.operationId,method:r.name,record:t},s.resolve({...m,result:e,committedAt:t.updatedAt})},async()=>{d?await waitForEffectReceipt(c.promise,t.abortSignal):"acp"!==t.origin||"mcp.set"!==r.name&&"mcp.unset"!==r.name||!m?.record.mcpDesiredStateCommit||(await this.journal.releaseMcpLiveEffect({operationId:r.context.operationId,source:"acp_local"}),await this.journal.promoteMcpDesiredStateActive({operationId:r.context.operationId,source:"acp_local"}))},d,e=>{i=e},e=>{n=e}).then(e=>(o="committed",e),e=>{throw o=e instanceof RuntimeCommandError&&("OUTCOME_UNKNOWN"===e.code||"INSTANCE_EPOCH_MISMATCH"===e.code)?"outcome_unknown":"failed",s.resolve(void 0),e});return{operationId:r.context.operationId,getSnapshot:()=>({effectState:o,...i?{projection:i}:{}}),completion:p,progress:emptyProgress(),effectCommitted:s.promise,acknowledgeEffectReceipt:async e=>{if(!m||e.operationId!==m.operationId||e.method!==m.method)throw new RuntimeCommandError("OUTCOME_UNKNOWN","MCP effect receipt does not match this operation");if(!/^[a-f0-9]{64}$/.test(e.effectRecordHash))throw new RuntimeCommandError("OUTCOME_UNKNOWN","MCP effect receipt hash is invalid");await this.journal.releaseMcpLiveEffect({operationId:e.operationId,source:"service",effectRecordHash:e.effectRecordHash}),c.resolve()},acknowledgeTerminalReceipt:async e=>{if(!(d&&m&&e.operationId===m.operationId&&e.method===m.method&&/^[a-f0-9]{64}$/.test(e.effectRecordHash)&&e.terminalMessageId))throw new RuntimeCommandError("OUTCOME_UNKNOWN","MCP terminal receipt does not match this operation");await this.journal.promoteMcpDesiredStateActive({operationId:e.operationId,source:"service",effectRecordHash:e.effectRecordHash,terminalMessageId:e.terminalMessageId});const a=await this.requireReleasedRecord(e.operationId);if(void 0===a.result)throw new RuntimeCommandError("OUTCOME_UNKNOWN","active MCP desired state lost its committed result");await this.afterCommittedEffect(r,a.result,a,t,e=>{i=e},e=>{n=e})},cancel:async()=>"running"===o?{status:"cancel_requested"===await(this.capabilities?.cancel?.(r.context.operationId))?"cancel_requested":"not_cancellable"}:{status:"already_terminal"},awaitProjection:async()=>n?(a??=n(),await a):i}}async executeWithLease(e,t,r,i,n,a,o){const s=await this.deps.leases.claim(e.context.operationId,e.context.dispatchEpoch);if(s.runtimeEpoch!==e.context.dispatchEpoch)throw await this.deps.leases.release(s),new RuntimeCommandError("INSTANCE_EPOCH_MISMATCH","runtime operation lease epoch mismatch");const c=this.deps.leases.startHeartbeat(s);try{let c;await this.recoverInterruptedCreates(e.context.operationId);try{c=await this.journal.prepare({operationId:e.context.operationId,command:e.name,paramsHash:e.context.paramsHash,runtimeEpoch:s.runtimeEpoch})}catch(e){if(e instanceof RuntimeCommandJournalConflictError)throw new RuntimeCommandError("OUTCOME_UNKNOWN",e.message,void 0,{cause:e});throw e}if(("effect_committed"===c.phase||"projection_committed"===c.phase)&&void 0!==c.result){if(r(c.result,c),await i(),c=await this.requireReleasedRecord(c.operationId),void 0===c.result)throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed result disappeared from command journal");return n||await this.afterCommittedEffect(e,c.result,c,t,a,o),c.result}if(("effect_committed"===c.phase||"projection_committed"===c.phase)&&"hash_only"===c.resultReceipt?.policy&&runtimeCommandIsReplayableQuery(e.name)){const n=await this.execute(e,s,t);if(runtimeCommandResultHash(n)!==c.resultReceipt.resultHash)throw new RuntimeCommandError("OUTCOME_UNKNOWN","redacted committed query result changed");return r(n,c),await i(),n}if(("effect_committed"===c.phase||"projection_committed"===c.phase)&&"hash_only"===c.resultReceipt?.policy){if(r(void 0,c),await i(),c=await this.requireReleasedRecord(c.operationId),!n){if(isRuntimeAgentMutation(e)&&(c.agentProjectionIntent||c.agentProjectionPreparationFailure)){const r=agentProjectionRecoveryResult(c.agentProjectionIntent??c.agentProjectionPreparationFailure);return await this.afterCommittedEffect(e,r,c,t,a,o),r}await this.runAfterEffect(e,void 0,c,t,a)}throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed mutation result is redacted")}if("effect_committed"===c.phase||"projection_committed"===c.phase)throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed result receipt is unavailable");if("outcome_unknown"===c.phase)throw new RuntimeCommandError("OUTCOME_UNKNOWN","previous execution outcome is unknown");if("started"===c.phase&&isRuntimeAgentMutation(e)){let n;try{n=await this.recoverStartedAgentMutation(e,s,t)}catch(e){throw await this.markJournalUnknown(c),e instanceof RuntimeCommandError?e:new RuntimeCommandError("OUTCOME_UNKNOWN",`agent desired-state recovery could not prove its effect: ${errorText(e)}`,void 0,{cause:e})}const m=this.deps.projection?await this.prepareAgentProjectionCommit(e,n,t):void 0,d=await this.journal.transition({operationId:c.operationId,expectedRevision:c.revision,phase:"effect_committed",result:n,...m?{agentProjection:m}:{}});return r(n,d),await i(),await this.afterCommittedEffect(e,n,d,t,a,o),this.scheduleJournalCompaction(),n}if("started"===c.phase&&"outcome_unknown"===this.recoveryDecision(e.name,c.phase))throw await this.markJournalUnknown(c),new RuntimeCommandError("OUTCOME_UNKNOWN","imperative action crossed its execution boundary");if("failed"===c.phase)throw new RuntimeCommandError("EXECUTION_FAILED","previous execution failed");"prepared"===c.phase&&(c=await this.journal.transition({operationId:c.operationId,expectedRevision:c.revision,phase:"started"}));let m=!1;try{const d=await this.execute(e,s,t);m=!0;const p=isRuntimeAgentMutation(e)&&this.deps.projection?await this.prepareAgentProjectionCommit(e,d,t):void 0;let u;try{const e=await this.requireReleasedRecord(c.operationId);u=await this.journal.transition({operationId:e.operationId,expectedRevision:e.revision,phase:"effect_committed",result:d,...p?{agentProjection:p}:{}})}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`effect completed before its journal commit: ${errorText(e)}`,void 0,{cause:e})}return r(d,u),await i(),u=await this.requireReleasedRecord(u.operationId),n||await this.afterCommittedEffect(e,d,u,t,a,o),this.scheduleJournalCompaction(),d}catch(t){if(m)throw t;const r=t instanceof RuntimeCommandError&&("OUTCOME_UNKNOWN"===t.code||"INSTANCE_EPOCH_MISMATCH"===t.code);if(r&&"clear-saga"===recoveryMetadata(e.name).recoveryClass)throw t;try{await this.journal.transition({operationId:c.operationId,expectedRevision:c.revision,phase:r?"outcome_unknown":"failed",errorCode:r?"OUTCOME_UNKNOWN":"EXECUTION_FAILED"})}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`command and journal outcome unknown: ${errorText(e)}`,void 0,{cause:t})}throw t}}finally{try{await c.stop(),await this.deps.leases.release(s)}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`runtime operation lease finalization unknown: ${errorText(e)}`,void 0,{cause:e})}}}scheduleJournalCompaction(){this.journal.compact().catch(e=>this.logger.error?.(`[runtime-journal] event=checkpoint_failed trigger=effect_committed error=${errorText(e)}`))}async execute(e,t,r){switch(e.name){case"agent.create":return await this.createAgent(e,t,r);case"agent.update":return await this.updateAgent(e);case"agent.delete":return await this.deleteAgent(e,t);case"agent.applyTemplate":return await this.applyTemplate(e,t,r)}if(!this.capabilities)throw new RuntimeCommandError("INVALID_PARAMS",`Unsupported runtime command: ${e.name}`);return await this.capabilities.execute(e,t,r)}async recoverStartedAgentMutation(e,t,r){if("agent.create"===e.name||"agent.applyTemplate"===e.name){let i=await this.bindCreateOperation(e,t,!1);if(i||(i=await this.findCreateRecoveryIdentity(e,!1),"allocated"===i.state&&void 0===i.createOperation?.paramsHash&&await this.bindCreateOperation(e,t,!1),i=await this.findCreateRecoveryIdentity(e)),"active"===i.state)return await this.recoverActiveCreateEffect(i);if(await this.runtimeAgentExists(i.observedRuntimeLocalKey??i.runtimeLocalKey)){const n={runtimeLocalKey:i.observedRuntimeLocalKey??i.runtimeLocalKey,workspacePath:join(this.getOpenclawHome(),`workspace-${i.runtimeLocalKey}`)};return"agent.create"===e.name?await this.completeCreatedAgent(e,t,r,n):await this.completeTemplateAgent(e,t,r,n)}return await this.execute(e,t,r)}const i=e.context.agent,n=await this.runtimeAgentExists(i.runtimeLocalKey);if("agent.delete"===e.name&&!n)return await this.deps.identities.commitDeleteTombstone(i.runtimeAgentUid,i.runtimeLocalKey,t),{runtimeAgentUid:i.runtimeAgentUid,runtimeLocalKey:i.runtimeLocalKey};if("agent.update"===e.name&&!n)throw new RuntimeCommandError("OUTCOME_UNKNOWN","update recovery target is absent");return await this.execute(e,t,r)}async runtimeAgentExists(e){const t=await this.requireGateway().request("agents.list",{});if(!Array.isArray(t?.agents))throw new RuntimeCommandError("OUTCOME_UNKNOWN","runtime agent directory query is incomplete");return t.agents.some(t=>null!==t&&"object"==typeof t&&(t.id===e||t.name===e))}async findCreateRecoveryIdentity(e,t=!0){const r={operationId:e.context.operationId,command:e.name,runtimeEpoch:e.context.dispatchEpoch,paramsHash:e.context.paramsHash,runtimeAgentUid:e.params.runtimeAgentUid},i=void 0!==this.deps.identities.findCreateOperation,n=i?await this.deps.identities.findCreateOperation(r):(await this.deps.identities.pendingAllocations()).filter(e=>e.operationId===r.operationId&&e.command===r.command&&e.runtimeEpoch===r.runtimeEpoch&&e.runtimeAgentUid===r.runtimeAgentUid);if(1!==n.length)throw new RuntimeCommandError("OUTCOME_UNKNOWN","create recovery identity binding is missing or ambiguous");const a=n[0];if(i&&(!a.createOperation||t&&a.createOperation.paramsHash!==r.paramsHash||a.createOperation.operationId!==r.operationId||a.createOperation.command!==r.command||a.createOperation.runtimeEpoch!==r.runtimeEpoch))throw new RuntimeCommandError("OUTCOME_UNKNOWN","create recovery identity hash binding conflicts");return a}async bindCreateOperation(e,t,r=!0){if(!this.deps.identities.findCreateOperation||!this.deps.identities.bindCreateOperation)return;const i={operationId:e.context.operationId,command:e.name,runtimeEpoch:e.context.dispatchEpoch,paramsHash:e.context.paramsHash,runtimeAgentUid:e.params.runtimeAgentUid};try{let n=await this.deps.identities.findCreateOperation(i);if(0===n.length){if(!r)throw new RuntimeCommandError("OUTCOME_UNKNOWN","create recovery identity binding is missing");if((await this.deps.identities.allocateCreate(t,e.name,e.params.runtimeAgentUid)).runtimeAgentUid!==e.params.runtimeAgentUid)throw new RuntimeCommandError("OUTCOME_UNKNOWN","create allocation UID does not match the canonical command");n=await this.deps.identities.findCreateOperation(i)}if(1!==n.length)throw new RuntimeCommandError("OUTCOME_UNKNOWN","create identity binding is missing or ambiguous");const a=n[0],o=await this.deps.identities.bindCreateOperation(a.runtimeAgentUid,a.runtimeLocalKey,{operationId:e.context.operationId,command:e.name,runtimeEpoch:e.context.dispatchEpoch,paramsHash:e.context.paramsHash});if(!o.createOperation||o.runtimeAgentUid!==e.params.runtimeAgentUid||o.createOperation.operationId!==i.operationId||o.createOperation.command!==i.command||o.createOperation.runtimeEpoch!==i.runtimeEpoch||o.createOperation.paramsHash!==i.paramsHash)throw new Error("create operation identity binding changed during compare-and-set");if("tombstoned"===o.state)throw new Error("create operation identity is tombstoned");return o}catch(e){if(e instanceof RuntimeCommandError)throw e;throw new RuntimeCommandError("OUTCOME_UNKNOWN",`create operation identity binding is corrupt: ${errorText(e)}`,void 0,{cause:e})}}async recoverActiveCreateEffect(e){const t=e.observedRuntimeLocalKey??e.runtimeLocalKey;if(!await this.runtimeAgentExists(t))throw new RuntimeCommandError("OUTCOME_UNKNOWN","active create identity is absent from the runtime directory");return{runtimeAgentUid:e.runtimeAgentUid,runtimeLocalKey:t,workspacePath:join(this.getOpenclawHome(),`workspace-${e.runtimeLocalKey}`)}}async markJournalUnknown(e){try{await this.journal.transition({operationId:e.operationId,expectedRevision:e.revision,phase:"outcome_unknown",errorCode:"OUTCOME_UNKNOWN"})}catch{}}async requireReleasedRecord(e){const t=await this.journal.get(e);if(!t)throw new RuntimeCommandError("OUTCOME_UNKNOWN","command journal record disappeared");return t}async afterCommittedEffect(e,t,r,i,n,a){if(!isRuntimeAgentMutation(e))return void await this.runAfterEffect(e,t,r,i,n);const o=await this.prepareAgentProjection(e,t,r,i,n);o&&(a(o),"acp"===i.origin&&o().catch(e=>this.logger.warn?.(`[runtime-core] deferred ACP agent projection failed: ${errorText(e)}`)))}async prepareAgentProjectionCommit(e,t,r){const i=agentProjectionRecoverySummary(e,t,r);try{const r=await this.deps.projection.prepareCommittedMutation({command:e,result:t,...i.expectedPlatformAgentId?{expectedPlatformAgentId:i.expectedPlatformAgentId}:{}});return Object.freeze({...r,...i})}catch(e){const t=!(e instanceof RuntimeProjectionTransportError)||e.retryable;return this.logger.warn?.(`[runtime-core] agent projection preparation ${t?"deferred":"blocked"}: ${errorText(e)}`),Object.freeze({...i,state:t?"pending":"blocked",errorKind:t?"snapshot_retryable":"snapshot_nonretryable"})}}async prepareAgentProjection(e,t,r,i,n){if("projection_committed"===r.phase)return n(r.projectionReceipt?.snapshot??Object.freeze({state:"synced",revision:`${Math.max(0,r.revision-1)}`})),r.agentProjectionIntent&&await this.compactAgentProjectionReference(r.agentProjectionIntent),void await this.runPostCommit(e,t);if("effect_committed"!==r.phase||!this.deps.projection)return;let a=r,o=a.agentProjectionIntent;const s=a.agentProjectionPreparationFailure;if(o&&"blocked"===a.agentProjectionTerminal?.state)return n(Object.freeze({state:"blocked",revision:a.agentProjectionTerminal.revision})),await this.compactAgentProjectionReference(o),void await this.runPostCommit(e,t);let c;return o&&n(Object.freeze({state:"pending",revision:o.projectionRevision})),async()=>(c??=(async()=>{if(!o){if(!s||"blocked"===s.state)return Object.freeze({state:"blocked",revision:`${Math.max(0,a.revision)}`});const t=await this.prepareAgentProjectionCommit(e,agentProjectionRecoveryResult(s),i);if(!isProjectionIntent(t))return"blocked"===t.state?Object.freeze({state:"blocked",revision:`${Math.max(0,a.revision)}`}):Object.freeze({state:"pending",revision:`${Math.max(0,a.revision)}`});o=t;try{a=await this.journal.recordAgentProjectionIntent({operationId:a.operationId,expectedRevision:a.revision,intent:o})}catch(e){return void this.logger.warn?.(`[runtime-core] agent projection reservation recovery deferred: ${errorText(e)}`)}n(Object.freeze({state:"pending",revision:o.projectionRevision}))}const r=Object.freeze({state:"pending",revision:o.projectionRevision});let c;try{c=await this.deps.projection.applyCommittedMutation(o)}catch(e){this.logger.warn?.(`[runtime-core] agent projection receipt deferred: ${errorText(e)}`),c=r}if(c.revision!==o.projectionRevision&&(c=Object.freeze({state:"blocked",revision:o.projectionRevision})),"synced"===c.state)try{a=await this.journal.transition({operationId:a.operationId,expectedRevision:a.revision,phase:"projection_committed",projectionSnapshot:c}),await this.compactAgentProjectionReference(o)}catch(e){this.logger.warn?.(`[runtime-core] projection phase commit deferred: ${errorText(e)}`),c=Object.freeze({state:"pending",revision:o.projectionRevision})}if("blocked"===c.state)try{a=await this.journal.recordAgentProjectionBlocked({operationId:a.operationId,expectedRevision:a.revision,revision:o.projectionRevision}),await this.compactAgentProjectionReference(o)}catch(e){this.logger.warn?.(`[runtime-core] blocked projection terminal commit deferred: ${errorText(e)}`),c=r}return"synced"===c.state&&c.platformAgentId&&"projection_committed"===a.phase&&this.reportTemplateOriginBestEffort(e,c.platformAgentId),n(c),await this.runPostCommit(e,t),c})(),await c)}async compactAgentProjectionReference(e){if(this.deps.projection)try{await this.deps.projection.compactCommittedMutation(e)}catch(e){this.logger.warn?.(`[runtime-core] projection reference compaction deferred: ${errorText(e)}`)}}reportTemplateOriginBestEffort(e,t){if("agent.applyTemplate"!==e.name||!this.deps.templateOriginReporter)return;const r=e.params.templateId;r&&this.deps.templateOriginReporter.report({platformAgentId:t,templateId:r}).catch(e=>{this.logger.warn?.(`[runtime-core] active template origin report failed, client fallback remains: ${errorText(e)}`)})}async runAfterEffect(e,t,r,i,n){if("projection_committed"===r.phase)return n(r.projectionReceipt?.snapshot??Object.freeze({state:"synced",revision:`${Math.max(0,r.revision-1)}`})),void await this.runPostCommit(e,t);const a="effect_committed"===r.phase&&await this.runProjection(e,t,i),o=!0===a?Object.freeze({state:"synced",revision:`${r.revision}`}):a&&"object"==typeof a?Object.freeze({...a,revision:`${r.revision}`}):"session.setModel"===e.name?Object.freeze({state:"pending",revision:`${r.revision}`}):void 0;if("synced"===o?.state)try{const e=o;await this.journal.transition({operationId:r.operationId,expectedRevision:r.revision,phase:"projection_committed",projectionSnapshot:e}),n(o)}catch(e){return this.logger.warn?.(`[runtime-core] projection phase commit deferred: ${errorText(e)}`),void n(Object.freeze({revision:o.revision,state:"pending"}))}else o&&n(o);await this.runPostCommit(e,t)}async runPostCommit(e,t){if(this.capabilities?.afterCommit)try{await this.capabilities.afterCommit(e,t)}catch(e){this.logger.warn?.(`[runtime-core] post-commit action failed: ${errorText(e)}`)}}async runProjection(e,t,r){if(!recoveryMetadata(e.name).projectionRequired)return!1;try{return!isRuntimeAgentMutation(e)&&(await(this.capabilities?.projectCommitted?.(e,t,r))??!1)}catch(e){return this.logger.warn?.(`[runtime-core] agent projection deferred: ${errorText(e)}`),!1}}recoveryDecision(e,t){const r=recoveryMetadata(e);return reduceRuntimeRecoveryPolicy({...r,messageServicePhase:"queued",executionBoundaryCrossed:"prepared"!==t,lineageContinuity:"continuous",journalState:"available",journalPhase:t})}requireGateway(){const e=this.deps.getGateway();if(!e?.isConnected)throw new RuntimeCommandError("GATEWAY_NOT_CONNECTED","Gateway not connected");return e}async createAgentShell(e,t,r,i,n,a){const o=this.requireGateway(),s=(await this.deps.identities.pendingAllocations()).find(t=>t.runtimeAgentUid===e),c=a??s?.runtimeLocalKey??this.createAgentId(),m=join(this.getOpenclawHome(),`workspace-${c}`);let d;try{d=await o.request("agents.create",{name:c,workspace:m,...n?{model:n}:{},...i?.emoji?{emoji:i.emoji}:{},...i?.avatar?{avatar:i.avatar}:{}})}catch(r){if(isDeterministicAgentsCreateParamsRejection(r)&&(void 0!==a||void 0!==s))try{await this.deps.identities.tombstone(e,c,t)}catch(e){this.logger.warn?.(`[runtime-core] rejected-create allocation cleanup deferred: ${errorText(e)}`)}throw r}const p=d?.agentId??c,u=d?.workspace??m;if(await this.deps.identities.observeEffectKey(e,c,p,t),p!==c)throw new RuntimeCommandError("OUTCOME_UNKNOWN",`Create agent outcome unknown: gateway changed reserved local key to ${p}`);try{await o.request("agents.update",{agentId:p,name:r})}catch(e){this.logger.warn?.(`[runtime-core] display-name update failed agent=${p}: ${errorText(e)}`)}return{runtimeLocalKey:p,workspacePath:u}}async createAgent(e,t,r){const i=e.params.name.trim();if(!i)throw new RuntimeCommandError("INVALID_PARAMS","Missing agent name");try{const n=await this.bindCreateOperation(e,t);if("active"===n?.state)return await this.recoverActiveCreateEffect(n);const a=await this.createAgentShell(e.params.runtimeAgentUid,t,i,e.params.identity,e.params.defaultModelId,n?.runtimeLocalKey);return await this.completeCreatedAgent(e,t,r,a)}catch(e){throw this.executionError("Create agent",e)}}async updateAgent(e){const{runtimeAgentUid:t,runtimeLocalKey:r}=e.context.agent;if(!r.trim())throw new RuntimeCommandError("MISSING_PARAM","Missing agentId","agentId");const i=e.params,n=i.name?.trim(),a=i.defaultModelId?.trim(),o=i.identity?.emoji?.trim(),s=i.identity?.avatar?.trim();if(!(n||a||o||s||void 0!==i.description||void 0!==i.version||void 0!==i.capabilities||void 0!==i.skills||void 0!==i.avatarUrl||void 0!==i.homepage||void 0!==i.status||void 0!==i.identity?.vibe))throw new RuntimeCommandError("INVALID_PARAMS","No updatable fields provided (name/model/identity)");try{return await this.deps.identities.requireActive(t,r),await this.requireGateway().request("agents.update",{agentId:r,...n?{name:n}:{},...a?{model:a}:{},...o?{emoji:o}:{},...s?{avatar:s}:{},...i.identity?.vibe?{vibe:i.identity.vibe}:{},...void 0!==i.description?{description:i.description}:{},...void 0!==i.version?{version:i.version}:{},...void 0!==i.capabilities?{capabilities:i.capabilities}:{},...void 0!==i.skills?{skills:i.skills}:{},...void 0!==i.avatarUrl?{avatarUrl:i.avatarUrl}:{},...void 0!==i.homepage?{homepage:i.homepage}:{},...void 0!==i.status?{status:i.status}:{}}),{runtimeAgentUid:t,runtimeLocalKey:r}}catch(e){throw this.executionError("Update agent",e)}}async deleteAgent(e,t){const{runtimeAgentUid:r,runtimeLocalKey:i}=e.context.agent;if(!i.trim())throw new RuntimeCommandError("MISSING_PARAM","Missing agentId","agentId");if("main"===normalizeRuntimeAgentLocalKey(i))throw new RuntimeCommandError("INVALID_PARAMS",'"main" cannot be deleted; delete the instance instead');try{if("tombstoned"===await this.deps.identities.requireDeleteTarget(r,i))return{runtimeAgentUid:r,runtimeLocalKey:i};if(!await this.runtimeAgentExists(i))return await this.deps.identities.commitDeleteTombstone(r,i,t),{runtimeAgentUid:r,runtimeLocalKey:i};const n=requireCommittedOpenClawDeleteAck(await this.requireGateway().request("agents.delete",{agentId:i,deleteFiles:e.params.deleteFiles??!0}),i);try{await this.deps.identities.commitDeleteTombstone(r,i,t)}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`Delete agent outcome unknown: identity tombstone failed: ${errorText(e)}`,void 0,{cause:e})}return{runtimeAgentUid:r,runtimeLocalKey:i,...void 0===n.removedBindings?{}:{removedBindings:n.removedBindings}}}catch(e){throw this.executionError("Delete agent",e)}}async applyTemplate(e,t,r){const i=e.params.name.trim();if(!i)throw new RuntimeCommandError("INVALID_PARAMS","Missing agent name");this.requireGateway();try{const n=await this.bindCreateOperation(e,t);if("active"===n?.state)return await this.recoverActiveCreateEffect(n);const a=await r.resources.readVerifiedArtifact(e.params.artifact),o=await this.createAgentShell(e.params.runtimeAgentUid,t,i,e.params.identity,e.params.defaultModelId,n?.runtimeLocalKey);return await this.completeTemplateAgent(e,t,r,o,a)}catch(e){throw this.executionError("Apply template",e)}}async completeCreatedAgent(e,t,r,i){for(const t of e.params.bootstrapFiles??[]){if("IDENTITY.md"===t.name){this.logger.warn?.("[runtime-core] agent.create ignoring IDENTITY.md; identity is structured");continue}const e=await r.resources.readContent(t.contentRef);try{await this.requireGateway().request("agents.files.set",{agentId:i.runtimeLocalKey,name:t.name,content:e})}catch(e){this.logger.warn?.(`[runtime-core] bootstrap write failed file=${t.name}: ${errorText(e)}`)}}try{await this.deps.identities.activate(e.params.runtimeAgentUid,i.runtimeLocalKey,t)}catch(r){throw await this.compensateCreatedAgent(e.params.runtimeAgentUid,i.runtimeLocalKey,t,r,"Create agent"),new RuntimeCommandError("EXECUTION_FAILED",`Create agent failed after compensation: ${errorText(r)}`)}return{runtimeAgentUid:e.params.runtimeAgentUid,runtimeLocalKey:i.runtimeLocalKey,workspacePath:i.workspacePath}}async completeTemplateAgent(e,t,r,i,n){const a=n??await r.resources.readVerifiedArtifact(e.params.artifact);try{for(const[e,t]of a.workspaceFiles){const r=resolve(i.workspacePath,e),n=relative(i.workspacePath,r);if(""===n||n.startsWith("..")||path.isAbsolute(n))throw new Error(`refusing to write outside workspace: ${e}`);await(this.deps.mkdirWorkspace??mkdir)(path.dirname(r),{recursive:!0}),await(this.deps.writeWorkspaceFile??writeFile)(r,t)}await this.deps.identities.activate(e.params.runtimeAgentUid,i.runtimeLocalKey,t)}catch(r){throw await this.compensateCreatedAgent(e.params.runtimeAgentUid,i.runtimeLocalKey,t,r,"Apply template"),new RuntimeCommandError("EXECUTION_FAILED",`Apply template failed after compensation: ${errorText(r)}`,void 0,{cause:r})}return{runtimeAgentUid:e.params.runtimeAgentUid,runtimeLocalKey:i.runtimeLocalKey,workspacePath:i.workspacePath}}executionError(e,t){return t instanceof RuntimeCommandError?t:(this.logger.error?.(`[runtime-core] ${e.toLowerCase()} failed: ${errorText(t)}`),new RuntimeCommandError("EXECUTION_FAILED",`${e} failed: ${errorText(t)}`,void 0,{cause:t}))}async compensateCreatedAgent(e,t,r,i,n){try{const i=this.requireGateway();requireCommittedOpenClawDeleteAck(await i.request("agents.delete",{agentId:t,deleteFiles:!0}),t),await this.deps.identities.tombstone(e,t,r)}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`${n} outcome unknown after ${errorText(i)}; compensation unproven: ${errorText(e)}`,void 0,{cause:e})}}async recoverInterruptedCreates(e){const t=await this.deps.identities.pendingAllocations();for(const r of t){if(r.operationId===e)continue;const t=await this.deps.leases.claimExpiredForRecovery(r.operationId);if(!t)continue;const i=this.deps.leases.startHeartbeat(t);try{await this.deps.identities.adoptRecoveryLease(r.runtimeAgentUid,r.runtimeLocalKey,t);const e=r.observedRuntimeLocalKey;if(!e){const e=r.createOperation?.operationId??r.operationId,i=await this.journal.get(e);if("failed"===i?.phase&&i.command===r.command&&!await this.runtimeAgentExists(r.runtimeLocalKey)){await this.deps.identities.tombstone(r.runtimeAgentUid,r.runtimeLocalKey,t);continue}throw new Error("no persisted gateway effect key; absence cannot be proven")}requireCommittedOpenClawDeleteAck(await this.requireGateway().request("agents.delete",{agentId:e,deleteFiles:!0}),e),await this.deps.identities.tombstone(r.runtimeAgentUid,r.runtimeLocalKey,t)}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`Interrupted ${r.command} recovery outcome unknown for operation ${r.operationId}: ${errorText(e)}`,void 0,{cause:e})}finally{let e;try{await i.stop()}catch(t){e=t}try{await this.deps.leases.release(t)}catch(t){e??=t}if(e)throw new RuntimeCommandError("OUTCOME_UNKNOWN",`Interrupted recovery lease finalization unknown: ${errorText(e)}`,void 0,{cause:e})}}}}function isRuntimeAgentMutation(e){return"agent.create"===e.name||"agent.update"===e.name||"agent.delete"===e.name||"agent.applyTemplate"===e.name}function servicePlatformAgentId(e){const t=e.verifiedMessageGrant?.claims;return"agent"===t?.scope?t.platformAgentId:void 0}function agentCoreResultHash(e,t){return createHash("sha256").update(runtimeHashPreimage(RUNTIME_HASH_DOMAINS.coreResult,{method:e.name.replace(".","/"),result:t})).digest("hex")}function agentProjectionRecoverySummary(e,t,r){const i="agent.update"===e.name||"agent.delete"===e.name?e.context.agent:createProjectionTarget(e,t),n=t;return Object.freeze({schemaVersion:1,operationId:e.context.operationId,method:e.name,runtimeEpoch:e.context.dispatchEpoch,runtimeAgentUid:i.runtimeAgentUid,runtimeLocalKey:i.runtimeLocalKey,coreResultHash:agentCoreResultHash(e,t),...servicePlatformAgentId(r)?{expectedPlatformAgentId:servicePlatformAgentId(r)}:{},..."agent.delete"===e.name&&Number.isSafeInteger(n?.removedBindings)?{removedBindings:n.removedBindings}:{}})}function createProjectionTarget(e,t){const r=t;if(!r||r.runtimeAgentUid!==e.params.runtimeAgentUid||"string"!=typeof r.runtimeLocalKey||!r.runtimeLocalKey)throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed agent effect lacks a recoverable local identity");return{runtimeAgentUid:r.runtimeAgentUid,runtimeLocalKey:r.runtimeLocalKey}}function agentProjectionRecoveryResult(e){return Object.freeze({runtimeAgentUid:e.runtimeAgentUid,runtimeLocalKey:e.runtimeLocalKey,...void 0===e.removedBindings?{}:{removedBindings:e.removedBindings}})}function isProjectionIntent(e){return"projectionRevision"in e}function recoveryMetadata(e){const t=RUNTIME_METHOD_PARITY_MANIFEST.filter(t=>t.serviceAllowed&&t.canonicalCommand===e),r=t[0]?.recoveryClass;return r?{recoveryClass:r,projectionRequired:"mcp.set"===e||"mcp.unset"===e||t.some(e=>!0===e.projectionRequired)}:{recoveryClass:"imperative-ambiguous",projectionRequired:!1}}export function isDeterministicAgentsCreateParamsRejection(e){return e instanceof Error&&/^invalid agents\.create params\b/.test(e.message)}export function requireCommittedOpenClawDeleteAck(e,t){if(!e||"object"!=typeof e)throw new Error("gateway delete lacks the committed target acknowledgement");const r=e,i=Object.keys(r).every(e=>"ok"===e||"agentId"===e||"removedBindings"===e),n=void 0===r.removedBindings||Number.isSafeInteger(r.removedBindings)&&r.removedBindings>=0;if(!i||!0!==r.ok||r.agentId!==t||!n)throw new Error("gateway delete lacks the committed target acknowledgement");return{ok:!0,agentId:t,...void 0===r.removedBindings?{}:{removedBindings:r.removedBindings}}}function errorText(e){return e instanceof Error?e.message:String(e)}
|
|
1
|
+
import{createHash,randomUUID}from"node:crypto";import{mkdir,writeFile}from"node:fs/promises";import{homedir}from"node:os";import path,{join,relative,resolve}from"node:path";import{RUNTIME_HASH_DOMAINS,RUNTIME_METHOD_PARITY_MANIFEST,runtimeHashPreimage}from"@beeos-ai/beeos-types/runtime";import{reduceRuntimeRecoveryPolicy}from"@beeos-ai/beeos-types/runtime/internal";import{assertTrustedCoreExecutionAttempt}from"./core-execution-attempt-context.js";import{InMemoryRuntimeCommandJournal,RuntimeCommandJournalConflictError,runtimeCommandIsReplayableQuery,runtimeCommandResultHash}from"./runtime-command-journal.js";import{RuntimeProjectionTransportError}from"./agent-projection-worker.js";import{ImHotPathAbortedError}from"./im-hot-path-deferral.js";const DEFAULT_AGENT_ID="main",AGENT_VALID_ID_RE=/^[a-z0-9][a-z0-9_-]{0,63}$/i,AGENT_INVALID_CHARS_RE=/[^a-z0-9_-]+/g;export function normalizeRuntimeAgentLocalKey(e){const t=(e??"").trim();return t?AGENT_VALID_ID_RE.test(t)?t.toLowerCase():t.toLowerCase().replace(AGENT_INVALID_CHARS_RE,"-").replace(/^-+/,"").replace(/-+$/,"").slice(0,64)||"main":"main"}export async function awaitRuntimeProjection(e){const t=e;return await(t.awaitProjection?.()??Promise.resolve(e.getSnapshot().projection))}export function hasEffectReceiptHandoff(e){const t=e;return t.effectCommitted instanceof Promise&&"function"==typeof t.acknowledgeEffectReceipt}export class RuntimeCommandError extends Error{code;param;constructor(e,t,r,i){super(t,i),this.code=e,this.param=r,this.name="RuntimeCommandError"}}const emptyProgress=async function*(){};function deferred(){let e;return{promise:new Promise(t=>{e=t}),resolve:e}}async function waitForEffectReceipt(e,t){if(!t)return await e;if(t.aborted)throw new RuntimeCommandError("OUTCOME_UNKNOWN","MCP effect receipt was not durably published before the Service attempt ended");await new Promise((r,i)=>{const a=()=>i(new RuntimeCommandError("OUTCOME_UNKNOWN","MCP effect receipt was not durably published before the Service attempt ended"));t.addEventListener("abort",a,{once:!0}),e.then(()=>{t.removeEventListener("abort",a),r()},e=>{t.removeEventListener("abort",a),i(e)})})}export class OpenClawRuntimeCommandDispatcher{deps;logger;getOpenclawHome;createAgentId;journal;capabilities;constructor(e){this.deps=e,this.logger=e.logger??{},this.getOpenclawHome=e.getOpenclawHome??(()=>process.env.OPENCLAW_HOME||join(homedir(),".openclaw")),this.createAgentId=e.createAgentId??(()=>`agent-${randomUUID().replace(/-/g,"").slice(0,12)}`),this.journal=e.journal??new InMemoryRuntimeCommandJournal,this.capabilities=e.capabilities}setCapabilities(e){this.capabilities=e}dispatch(e,t){const r=e;assertTrustedCoreExecutionAttempt(t,{operationId:r.context.operationId,runtimeEpoch:r.context.dispatchEpoch});let i,a,n,o="running";const s=deferred(),c=deferred();let m;const d="service"===t.origin&&("mcp.set"===r.name||"mcp.unset"===r.name),p=this.executeWithLease(r,t,(e,t)=>{o="committed",m={operationId:r.context.operationId,method:r.name,record:t},s.resolve({...m,result:e,committedAt:t.updatedAt})},async()=>{d?await waitForEffectReceipt(c.promise,t.abortSignal):"acp"!==t.origin||"mcp.set"!==r.name&&"mcp.unset"!==r.name||!m?.record.mcpDesiredStateCommit||(await this.journal.releaseMcpLiveEffect({operationId:r.context.operationId,source:"acp_local"}),await this.journal.promoteMcpDesiredStateActive({operationId:r.context.operationId,source:"acp_local"}))},d,e=>{i=e},e=>{a=e}).then(e=>(o="committed",e),e=>{throw o=e instanceof RuntimeCommandError&&("OUTCOME_UNKNOWN"===e.code||"INSTANCE_EPOCH_MISMATCH"===e.code)?"outcome_unknown":"failed",s.resolve(void 0),e});return{operationId:r.context.operationId,getSnapshot:()=>({effectState:o,...i?{projection:i}:{}}),completion:p,progress:emptyProgress(),effectCommitted:s.promise,acknowledgeEffectReceipt:async e=>{if(!m||e.operationId!==m.operationId||e.method!==m.method)throw new RuntimeCommandError("OUTCOME_UNKNOWN","MCP effect receipt does not match this operation");if(!/^[a-f0-9]{64}$/.test(e.effectRecordHash))throw new RuntimeCommandError("OUTCOME_UNKNOWN","MCP effect receipt hash is invalid");await this.journal.releaseMcpLiveEffect({operationId:e.operationId,source:"service",effectRecordHash:e.effectRecordHash}),c.resolve()},acknowledgeTerminalReceipt:async e=>{if(!(d&&m&&e.operationId===m.operationId&&e.method===m.method&&/^[a-f0-9]{64}$/.test(e.effectRecordHash)&&e.terminalMessageId))throw new RuntimeCommandError("OUTCOME_UNKNOWN","MCP terminal receipt does not match this operation");await this.journal.promoteMcpDesiredStateActive({operationId:e.operationId,source:"service",effectRecordHash:e.effectRecordHash,terminalMessageId:e.terminalMessageId});const n=await this.requireReleasedRecord(e.operationId);if(void 0===n.result)throw new RuntimeCommandError("OUTCOME_UNKNOWN","active MCP desired state lost its committed result");await this.afterCommittedEffect(r,n.result,n,t,e=>{i=e},e=>{a=e})},cancel:async()=>"running"===o?{status:"cancel_requested"===await(this.capabilities?.cancel?.(r.context.operationId))?"cancel_requested":"not_cancellable"}:{status:"already_terminal"},awaitProjection:async()=>a?(n??=a(),await n):i}}async executeWithLease(e,t,r,i,a,n,o){return await this.withExclusiveLifecycle(e,t.abortSignal,()=>this.executeClaimedLifecycle(e,t,r,i,a,n,o))}async executeClaimedLifecycle(e,t,r,i,a,n,o){const s=await this.deps.leases.claim(e.context.operationId,e.context.dispatchEpoch);if(s.runtimeEpoch!==e.context.dispatchEpoch)throw await this.deps.leases.release(s),new RuntimeCommandError("INSTANCE_EPOCH_MISMATCH","runtime operation lease epoch mismatch");const c=this.deps.leases.startHeartbeat(s);try{let c;await this.recoverInterruptedCreates(e.context.operationId);try{c=await this.journal.prepare({operationId:e.context.operationId,command:e.name,paramsHash:e.context.paramsHash,runtimeEpoch:s.runtimeEpoch})}catch(e){if(e instanceof RuntimeCommandJournalConflictError)throw new RuntimeCommandError("OUTCOME_UNKNOWN",e.message,void 0,{cause:e});throw e}if(("effect_committed"===c.phase||"projection_committed"===c.phase)&&void 0!==c.result){if(r(c.result,c),await i(),c=await this.requireReleasedRecord(c.operationId),void 0===c.result)throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed result disappeared from command journal");return a||await this.afterCommittedEffect(e,c.result,c,t,n,o),c.result}if(("effect_committed"===c.phase||"projection_committed"===c.phase)&&"hash_only"===c.resultReceipt?.policy&&runtimeCommandIsReplayableQuery(e.name)){const a=await this.execute(e,s,t);if(runtimeCommandResultHash(a)!==c.resultReceipt.resultHash)throw new RuntimeCommandError("OUTCOME_UNKNOWN","redacted committed query result changed");return r(a,c),await i(),a}if(("effect_committed"===c.phase||"projection_committed"===c.phase)&&"hash_only"===c.resultReceipt?.policy){if(r(void 0,c),await i(),c=await this.requireReleasedRecord(c.operationId),!a){if(isRuntimeAgentMutation(e)&&(c.agentProjectionIntent||c.agentProjectionPreparationFailure)){const r=agentProjectionRecoveryResult(c.agentProjectionIntent??c.agentProjectionPreparationFailure);return await this.afterCommittedEffect(e,r,c,t,n,o),r}await this.runAfterEffect(e,void 0,c,t,n)}throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed mutation result is redacted")}if("effect_committed"===c.phase||"projection_committed"===c.phase)throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed result receipt is unavailable");if("outcome_unknown"===c.phase)throw new RuntimeCommandError("OUTCOME_UNKNOWN","previous execution outcome is unknown");if("started"===c.phase&&isRuntimeAgentMutation(e)){let a;try{a=await this.recoverStartedAgentMutation(e,s,t)}catch(e){throw await this.markJournalUnknown(c),e instanceof RuntimeCommandError?e:new RuntimeCommandError("OUTCOME_UNKNOWN",`agent desired-state recovery could not prove its effect: ${errorText(e)}`,void 0,{cause:e})}const m=this.deps.projection?await this.prepareAgentProjectionCommit(e,a,t):void 0,d=await this.journal.transition({operationId:c.operationId,expectedRevision:c.revision,phase:"effect_committed",result:a,...m?{agentProjection:m}:{}});return r(a,d),await i(),await this.afterCommittedEffect(e,a,d,t,n,o),this.scheduleJournalCompaction(),a}if("started"===c.phase&&"outcome_unknown"===this.recoveryDecision(e.name,c.phase))throw await this.markJournalUnknown(c),new RuntimeCommandError("OUTCOME_UNKNOWN","imperative action crossed its execution boundary");if("failed"===c.phase)throw new RuntimeCommandError("EXECUTION_FAILED","previous execution failed");"prepared"===c.phase&&(c=await this.journal.transition({operationId:c.operationId,expectedRevision:c.revision,phase:"started"}));let m=!1;try{const d=await this.execute(e,s,t);m=!0;const p=isRuntimeAgentMutation(e)&&this.deps.projection?await this.prepareAgentProjectionCommit(e,d,t):void 0;let u;try{const e=await this.requireReleasedRecord(c.operationId);u=await this.journal.transition({operationId:e.operationId,expectedRevision:e.revision,phase:"effect_committed",result:d,...p?{agentProjection:p}:{}})}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`effect completed before its journal commit: ${errorText(e)}`,void 0,{cause:e})}return r(d,u),await i(),u=await this.requireReleasedRecord(u.operationId),a||await this.afterCommittedEffect(e,d,u,t,n,o),this.scheduleJournalCompaction(),d}catch(t){if(m)throw t;const r=t instanceof RuntimeCommandError&&("OUTCOME_UNKNOWN"===t.code||"INSTANCE_EPOCH_MISMATCH"===t.code);if(r&&"clear-saga"===recoveryMetadata(e.name).recoveryClass)throw t;try{await this.journal.transition({operationId:c.operationId,expectedRevision:c.revision,phase:r?"outcome_unknown":"failed",errorCode:r?"OUTCOME_UNKNOWN":"EXECUTION_FAILED"})}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`command and journal outcome unknown: ${errorText(e)}`,void 0,{cause:t})}throw t}}finally{try{await c.stop(),await this.deps.leases.release(s)}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`runtime operation lease finalization unknown: ${errorText(e)}`,void 0,{cause:e})}}}scheduleJournalCompaction(){this.journal.compact().catch(e=>this.logger.error?.(`[runtime-journal] event=checkpoint_failed trigger=effect_committed error=${errorText(e)}`))}async execute(e,t,r){switch(e.name){case"agent.create":return await this.createAgent(e,t,r);case"agent.update":return await this.updateAgent(e);case"agent.delete":return await this.deleteAgent(e,t);case"agent.applyTemplate":return await this.applyTemplate(e,t,r)}if(!this.capabilities)throw new RuntimeCommandError("INVALID_PARAMS",`Unsupported runtime command: ${e.name}`);return await this.capabilities.execute(e,t,r)}async recoverStartedAgentMutation(e,t,r){if("agent.create"===e.name||"agent.applyTemplate"===e.name){let i=await this.bindCreateOperation(e,t,!1);if(i||(i=await this.findCreateRecoveryIdentity(e,!1),"allocated"===i.state&&void 0===i.createOperation?.paramsHash&&await this.bindCreateOperation(e,t,!1),i=await this.findCreateRecoveryIdentity(e)),"active"===i.state)return await this.recoverActiveCreateEffect(i);if(await this.runtimeAgentExists(i.observedRuntimeLocalKey??i.runtimeLocalKey)){const a={runtimeLocalKey:i.observedRuntimeLocalKey??i.runtimeLocalKey,workspacePath:join(this.getOpenclawHome(),`workspace-${i.runtimeLocalKey}`)};return"agent.create"===e.name?await this.completeCreatedAgent(e,t,r,a):await this.completeTemplateAgent(e,t,r,a)}return await this.execute(e,t,r)}const i=e.context.agent,a=await this.runtimeAgentExists(i.runtimeLocalKey);if("agent.delete"===e.name&&!a)return await this.deps.identities.commitDeleteTombstone(i.runtimeAgentUid,i.runtimeLocalKey,t),{runtimeAgentUid:i.runtimeAgentUid,runtimeLocalKey:i.runtimeLocalKey};if("agent.update"===e.name&&!a)throw new RuntimeCommandError("OUTCOME_UNKNOWN","update recovery target is absent");return await this.execute(e,t,r)}async runtimeAgentExists(e){const t=await this.requireGateway().request("agents.list",{});if(!Array.isArray(t?.agents))throw new RuntimeCommandError("OUTCOME_UNKNOWN","runtime agent directory query is incomplete");return t.agents.some(t=>null!==t&&"object"==typeof t&&(t.id===e||t.name===e))}async findCreateRecoveryIdentity(e,t=!0){const r={operationId:e.context.operationId,command:e.name,runtimeEpoch:e.context.dispatchEpoch,paramsHash:e.context.paramsHash,runtimeAgentUid:e.params.runtimeAgentUid},i=void 0!==this.deps.identities.findCreateOperation,a=i?await this.deps.identities.findCreateOperation(r):(await this.deps.identities.pendingAllocations()).filter(e=>e.operationId===r.operationId&&e.command===r.command&&e.runtimeEpoch===r.runtimeEpoch&&e.runtimeAgentUid===r.runtimeAgentUid);if(1!==a.length)throw new RuntimeCommandError("OUTCOME_UNKNOWN","create recovery identity binding is missing or ambiguous");const n=a[0];if(i&&(!n.createOperation||t&&n.createOperation.paramsHash!==r.paramsHash||n.createOperation.operationId!==r.operationId||n.createOperation.command!==r.command||n.createOperation.runtimeEpoch!==r.runtimeEpoch))throw new RuntimeCommandError("OUTCOME_UNKNOWN","create recovery identity hash binding conflicts");return n}async bindCreateOperation(e,t,r=!0){if(!this.deps.identities.findCreateOperation||!this.deps.identities.bindCreateOperation)return;const i={operationId:e.context.operationId,command:e.name,runtimeEpoch:e.context.dispatchEpoch,paramsHash:e.context.paramsHash,runtimeAgentUid:e.params.runtimeAgentUid};try{let a=await this.deps.identities.findCreateOperation(i);if(0===a.length){if(!r)throw new RuntimeCommandError("OUTCOME_UNKNOWN","create recovery identity binding is missing");if((await this.deps.identities.allocateCreate(t,e.name,e.params.runtimeAgentUid)).runtimeAgentUid!==e.params.runtimeAgentUid)throw new RuntimeCommandError("OUTCOME_UNKNOWN","create allocation UID does not match the canonical command");a=await this.deps.identities.findCreateOperation(i)}if(1!==a.length)throw new RuntimeCommandError("OUTCOME_UNKNOWN","create identity binding is missing or ambiguous");const n=a[0],o=await this.deps.identities.bindCreateOperation(n.runtimeAgentUid,n.runtimeLocalKey,{operationId:e.context.operationId,command:e.name,runtimeEpoch:e.context.dispatchEpoch,paramsHash:e.context.paramsHash});if(!o.createOperation||o.runtimeAgentUid!==e.params.runtimeAgentUid||o.createOperation.operationId!==i.operationId||o.createOperation.command!==i.command||o.createOperation.runtimeEpoch!==i.runtimeEpoch||o.createOperation.paramsHash!==i.paramsHash)throw new Error("create operation identity binding changed during compare-and-set");if("tombstoned"===o.state)throw new Error("create operation identity is tombstoned");return o}catch(e){if(e instanceof RuntimeCommandError)throw e;throw new RuntimeCommandError("OUTCOME_UNKNOWN",`create operation identity binding is corrupt: ${errorText(e)}`,void 0,{cause:e})}}async recoverActiveCreateEffect(e){const t=e.observedRuntimeLocalKey??e.runtimeLocalKey;if(!await this.runtimeAgentExists(t))throw new RuntimeCommandError("OUTCOME_UNKNOWN","active create identity is absent from the runtime directory");return{runtimeAgentUid:e.runtimeAgentUid,runtimeLocalKey:t,workspacePath:join(this.getOpenclawHome(),`workspace-${e.runtimeLocalKey}`)}}async markJournalUnknown(e){try{await this.journal.transition({operationId:e.operationId,expectedRevision:e.revision,phase:"outcome_unknown",errorCode:"OUTCOME_UNKNOWN"})}catch{}}async requireReleasedRecord(e){const t=await this.journal.get(e);if(!t)throw new RuntimeCommandError("OUTCOME_UNKNOWN","command journal record disappeared");return t}async afterCommittedEffect(e,t,r,i,a,n){if(!isRuntimeAgentMutation(e))return void await this.runAfterEffect(e,t,r,i,a);const o=await this.prepareAgentProjection(e,t,r,i,a);o&&(n(o),"acp"===i.origin&&o().catch(e=>this.logger.warn?.(`[runtime-core] deferred ACP agent projection failed: ${errorText(e)}`)))}async prepareAgentProjectionCommit(e,t,r){const i=agentProjectionRecoverySummary(e,t,r);try{const r=await this.deps.projection.prepareCommittedMutation({command:e,result:t,...i.expectedPlatformAgentId?{expectedPlatformAgentId:i.expectedPlatformAgentId}:{}});return Object.freeze({...r,...i})}catch(e){const t=!(e instanceof RuntimeProjectionTransportError)||e.retryable;return this.logger.warn?.(`[runtime-core] agent projection preparation ${t?"deferred":"blocked"}: ${errorText(e)}`),Object.freeze({...i,state:t?"pending":"blocked",errorKind:t?"snapshot_retryable":"snapshot_nonretryable"})}}async prepareAgentProjection(e,t,r,i,a){if("projection_committed"===r.phase)return a(r.projectionReceipt?.snapshot??Object.freeze({state:"synced",revision:`${Math.max(0,r.revision-1)}`})),r.agentProjectionIntent&&await this.compactAgentProjectionReference(r.agentProjectionIntent),void await this.runPostCommit(e,t);if("effect_committed"!==r.phase||!this.deps.projection)return;let n=r,o=n.agentProjectionIntent;const s=n.agentProjectionPreparationFailure;if(o&&"blocked"===n.agentProjectionTerminal?.state)return a(Object.freeze({state:"blocked",revision:n.agentProjectionTerminal.revision})),await this.compactAgentProjectionReference(o),void await this.runPostCommit(e,t);let c;return o&&a(Object.freeze({state:"pending",revision:o.projectionRevision})),async()=>(c??=(async()=>{if(!o){if(!s||"blocked"===s.state)return Object.freeze({state:"blocked",revision:`${Math.max(0,n.revision)}`});const t=await this.prepareAgentProjectionCommit(e,agentProjectionRecoveryResult(s),i);if(!isProjectionIntent(t))return"blocked"===t.state?Object.freeze({state:"blocked",revision:`${Math.max(0,n.revision)}`}):Object.freeze({state:"pending",revision:`${Math.max(0,n.revision)}`});o=t;try{n=await this.journal.recordAgentProjectionIntent({operationId:n.operationId,expectedRevision:n.revision,intent:o})}catch(e){return void this.logger.warn?.(`[runtime-core] agent projection reservation recovery deferred: ${errorText(e)}`)}a(Object.freeze({state:"pending",revision:o.projectionRevision}))}const r=Object.freeze({state:"pending",revision:o.projectionRevision});let c;try{c=await this.deps.projection.applyCommittedMutation(o)}catch(e){this.logger.warn?.(`[runtime-core] agent projection receipt deferred: ${errorText(e)}`),c=r}if(c.revision!==o.projectionRevision&&(c=Object.freeze({state:"blocked",revision:o.projectionRevision})),"synced"===c.state)try{n=await this.journal.transition({operationId:n.operationId,expectedRevision:n.revision,phase:"projection_committed",projectionSnapshot:c}),await this.compactAgentProjectionReference(o)}catch(e){this.logger.warn?.(`[runtime-core] projection phase commit deferred: ${errorText(e)}`),c=Object.freeze({state:"pending",revision:o.projectionRevision})}if("blocked"===c.state)try{n=await this.journal.recordAgentProjectionBlocked({operationId:n.operationId,expectedRevision:n.revision,revision:o.projectionRevision}),await this.compactAgentProjectionReference(o)}catch(e){this.logger.warn?.(`[runtime-core] blocked projection terminal commit deferred: ${errorText(e)}`),c=r}return"synced"===c.state&&c.platformAgentId&&"projection_committed"===n.phase&&this.reportTemplateOriginBestEffort(e,c.platformAgentId),a(c),await this.runPostCommit(e,t),c})(),await c)}async compactAgentProjectionReference(e){if(this.deps.projection)try{await this.deps.projection.compactCommittedMutation(e)}catch(e){this.logger.warn?.(`[runtime-core] projection reference compaction deferred: ${errorText(e)}`)}}reportTemplateOriginBestEffort(e,t){if("agent.applyTemplate"!==e.name||!this.deps.templateOriginReporter)return;const r=e.params.templateId;r&&this.deps.templateOriginReporter.report({platformAgentId:t,templateId:r}).catch(e=>{this.logger.warn?.(`[runtime-core] active template origin report failed, client fallback remains: ${errorText(e)}`)})}async runAfterEffect(e,t,r,i,a){if("projection_committed"===r.phase)return a(r.projectionReceipt?.snapshot??Object.freeze({state:"synced",revision:`${Math.max(0,r.revision-1)}`})),void await this.runPostCommit(e,t);const n="effect_committed"===r.phase&&await this.runProjection(e,t,i),o=!0===n?Object.freeze({state:"synced",revision:`${r.revision}`}):n&&"object"==typeof n?Object.freeze({...n,revision:`${r.revision}`}):"session.setModel"===e.name?Object.freeze({state:"pending",revision:`${r.revision}`}):void 0;if("synced"===o?.state)try{const e=o;await this.journal.transition({operationId:r.operationId,expectedRevision:r.revision,phase:"projection_committed",projectionSnapshot:e}),a(o)}catch(e){return this.logger.warn?.(`[runtime-core] projection phase commit deferred: ${errorText(e)}`),void a(Object.freeze({revision:o.revision,state:"pending"}))}else o&&a(o);await this.runPostCommit(e,t)}async runPostCommit(e,t){if(this.capabilities?.afterCommit)try{await this.capabilities.afterCommit(e,t)}catch(e){this.logger.warn?.(`[runtime-core] post-commit action failed: ${errorText(e)}`)}}async runProjection(e,t,r){if(!recoveryMetadata(e.name).projectionRequired)return!1;try{return!isRuntimeAgentMutation(e)&&(await(this.capabilities?.projectCommitted?.(e,t,r))??!1)}catch(e){return this.logger.warn?.(`[runtime-core] agent projection deferred: ${errorText(e)}`),!1}}recoveryDecision(e,t){const r=recoveryMetadata(e);return reduceRuntimeRecoveryPolicy({...r,messageServicePhase:"queued",executionBoundaryCrossed:"prepared"!==t,lineageContinuity:"continuous",journalState:"available",journalPhase:t})}requireGateway(){const e=this.deps.getGateway();if(!e?.isConnected)throw new RuntimeCommandError("GATEWAY_NOT_CONNECTED","Gateway not connected");return e}exclusiveLifecycleReason(e){switch(e.name){case"agent.applyTemplate":return"applyTemplate";case"agent.create":return"createAgent";case"agent.delete":return"deleteAgent";case"agent.update":return"updateAgent";default:return}}async withExclusiveLifecycle(e,t,r){const i=this.exclusiveLifecycleReason(e);if(!i)return await r();if(this.deps.runExclusive)try{return await this.deps.runExclusive(i,r,t)}catch(e){if(e instanceof ImHotPathAbortedError)throw new RuntimeCommandError("INVALID_PARAMS",`${i} aborted while waiting for in-flight chat`);throw e}return await(this.deps.waitForChatIdle?.(i,t)),await r()}async createAgentShell(e,t,r,i,a,n){const o=this.requireGateway(),s=(await this.deps.identities.pendingAllocations()).find(t=>t.runtimeAgentUid===e),c=n??s?.runtimeLocalKey??this.createAgentId(),m=join(this.getOpenclawHome(),`workspace-${c}`);let d;try{d=await o.request("agents.create",{name:c,workspace:m,...a?{model:a}:{},...i?.emoji?{emoji:i.emoji}:{},...i?.avatar?{avatar:i.avatar}:{}})}catch(r){if(isDeterministicAgentsCreateParamsRejection(r)&&(void 0!==n||void 0!==s))try{await this.deps.identities.tombstone(e,c,t)}catch(e){this.logger.warn?.(`[runtime-core] rejected-create allocation cleanup deferred: ${errorText(e)}`)}throw r}const p=d?.agentId??c,u=d?.workspace??m;if(await this.deps.identities.observeEffectKey(e,c,p,t),p!==c)throw new RuntimeCommandError("OUTCOME_UNKNOWN",`Create agent outcome unknown: gateway changed reserved local key to ${p}`);try{await o.request("agents.update",{agentId:p,name:r})}catch(e){this.logger.warn?.(`[runtime-core] display-name update failed agent=${p}: ${errorText(e)}`)}return{runtimeLocalKey:p,workspacePath:u}}async createAgent(e,t,r){const i=e.params.name.trim();if(!i)throw new RuntimeCommandError("INVALID_PARAMS","Missing agent name");try{const a=await this.bindCreateOperation(e,t);if("active"===a?.state)return await this.recoverActiveCreateEffect(a);const n=await this.createAgentShell(e.params.runtimeAgentUid,t,i,e.params.identity,e.params.defaultModelId,a?.runtimeLocalKey);return await this.completeCreatedAgent(e,t,r,n)}catch(e){throw this.executionError("Create agent",e)}}async updateAgent(e){const{runtimeAgentUid:t,runtimeLocalKey:r}=e.context.agent;if(!r.trim())throw new RuntimeCommandError("MISSING_PARAM","Missing agentId","agentId");const i=e.params,a=i.name?.trim(),n=i.defaultModelId?.trim(),o=i.identity?.emoji?.trim(),s=i.identity?.avatar?.trim();if(!(a||n||o||s||void 0!==i.description||void 0!==i.version||void 0!==i.capabilities||void 0!==i.skills||void 0!==i.avatarUrl||void 0!==i.homepage||void 0!==i.status||void 0!==i.identity?.vibe))throw new RuntimeCommandError("INVALID_PARAMS","No updatable fields provided (name/model/identity)");try{return await this.deps.identities.requireActive(t,r),await this.requireGateway().request("agents.update",{agentId:r,...a?{name:a}:{},...n?{model:n}:{},...o?{emoji:o}:{},...s?{avatar:s}:{},...i.identity?.vibe?{vibe:i.identity.vibe}:{},...void 0!==i.description?{description:i.description}:{},...void 0!==i.version?{version:i.version}:{},...void 0!==i.capabilities?{capabilities:i.capabilities}:{},...void 0!==i.skills?{skills:i.skills}:{},...void 0!==i.avatarUrl?{avatarUrl:i.avatarUrl}:{},...void 0!==i.homepage?{homepage:i.homepage}:{},...void 0!==i.status?{status:i.status}:{}}),{runtimeAgentUid:t,runtimeLocalKey:r}}catch(e){throw this.executionError("Update agent",e)}}async deleteAgent(e,t){const{runtimeAgentUid:r,runtimeLocalKey:i}=e.context.agent;if(!i.trim())throw new RuntimeCommandError("MISSING_PARAM","Missing agentId","agentId");if("main"===normalizeRuntimeAgentLocalKey(i))throw new RuntimeCommandError("INVALID_PARAMS",'"main" cannot be deleted; delete the instance instead');try{if("tombstoned"===await this.deps.identities.requireDeleteTarget(r,i))return{runtimeAgentUid:r,runtimeLocalKey:i};if(!await this.runtimeAgentExists(i))return await this.deps.identities.commitDeleteTombstone(r,i,t),{runtimeAgentUid:r,runtimeLocalKey:i};const a=requireCommittedOpenClawDeleteAck(await this.requireGateway().request("agents.delete",{agentId:i,deleteFiles:e.params.deleteFiles??!0}),i);try{await this.deps.identities.commitDeleteTombstone(r,i,t)}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`Delete agent outcome unknown: identity tombstone failed: ${errorText(e)}`,void 0,{cause:e})}return{runtimeAgentUid:r,runtimeLocalKey:i,...void 0===a.removedBindings?{}:{removedBindings:a.removedBindings}}}catch(e){throw this.executionError("Delete agent",e)}}async applyTemplate(e,t,r){const i=e.params.name.trim();if(!i)throw new RuntimeCommandError("INVALID_PARAMS","Missing agent name");this.requireGateway();try{const a=await this.bindCreateOperation(e,t);if("active"===a?.state)return await this.recoverActiveCreateEffect(a);const n=await r.resources.readVerifiedArtifact(e.params.artifact),o=await this.createAgentShell(e.params.runtimeAgentUid,t,i,e.params.identity,e.params.defaultModelId,a?.runtimeLocalKey);return await this.completeTemplateAgent(e,t,r,o,n)}catch(e){throw this.executionError("Apply template",e)}}async completeCreatedAgent(e,t,r,i){for(const t of e.params.bootstrapFiles??[]){if("IDENTITY.md"===t.name){this.logger.warn?.("[runtime-core] agent.create ignoring IDENTITY.md; identity is structured");continue}const e=await r.resources.readContent(t.contentRef);try{await this.requireGateway().request("agents.files.set",{agentId:i.runtimeLocalKey,name:t.name,content:e})}catch(e){this.logger.warn?.(`[runtime-core] bootstrap write failed file=${t.name}: ${errorText(e)}`)}}try{await this.deps.identities.activate(e.params.runtimeAgentUid,i.runtimeLocalKey,t)}catch(r){throw await this.compensateCreatedAgent(e.params.runtimeAgentUid,i.runtimeLocalKey,t,r,"Create agent"),new RuntimeCommandError("EXECUTION_FAILED",`Create agent failed after compensation: ${errorText(r)}`)}return await this.prepareAgentToolCatalog(i.runtimeLocalKey),{runtimeAgentUid:e.params.runtimeAgentUid,runtimeLocalKey:i.runtimeLocalKey,workspacePath:i.workspacePath}}async completeTemplateAgent(e,t,r,i,a){const n=a??await r.resources.readVerifiedArtifact(e.params.artifact);try{for(const[e,t]of n.workspaceFiles){const r=resolve(i.workspacePath,e),a=relative(i.workspacePath,r);if(""===a||a.startsWith("..")||path.isAbsolute(a))throw new Error(`refusing to write outside workspace: ${e}`);await(this.deps.mkdirWorkspace??mkdir)(path.dirname(r),{recursive:!0}),await(this.deps.writeWorkspaceFile??writeFile)(r,t)}await this.deps.identities.activate(e.params.runtimeAgentUid,i.runtimeLocalKey,t)}catch(r){throw await this.compensateCreatedAgent(e.params.runtimeAgentUid,i.runtimeLocalKey,t,r,"Apply template"),new RuntimeCommandError("EXECUTION_FAILED",`Apply template failed after compensation: ${errorText(r)}`,void 0,{cause:r})}return await this.prepareAgentToolCatalog(i.runtimeLocalKey),{runtimeAgentUid:e.params.runtimeAgentUid,runtimeLocalKey:i.runtimeLocalKey,workspacePath:i.workspacePath}}async prepareAgentToolCatalog(e){const t=Date.now();try{await this.requireGateway().request("tools.catalog",{agentId:e}),this.logger.info?.(`[runtime-core] prepared agent tool catalog agent=${e} elapsed_ms=${Date.now()-t}`)}catch(t){this.logger.warn?.(`[runtime-core] agent tool catalog prepare failed agent=${e}: ${errorText(t)}`)}}executionError(e,t){return t instanceof RuntimeCommandError?t:(this.logger.error?.(`[runtime-core] ${e.toLowerCase()} failed: ${errorText(t)}`),new RuntimeCommandError("EXECUTION_FAILED",`${e} failed: ${errorText(t)}`,void 0,{cause:t}))}async compensateCreatedAgent(e,t,r,i,a){try{const i=this.requireGateway();requireCommittedOpenClawDeleteAck(await i.request("agents.delete",{agentId:t,deleteFiles:!0}),t),await this.deps.identities.tombstone(e,t,r)}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`${a} outcome unknown after ${errorText(i)}; compensation unproven: ${errorText(e)}`,void 0,{cause:e})}}async recoverInterruptedCreates(e){const t=await this.deps.identities.pendingAllocations();for(const r of t){if(r.operationId===e)continue;const t=await this.deps.leases.claimExpiredForRecovery(r.operationId);if(!t)continue;const i=this.deps.leases.startHeartbeat(t);try{await this.deps.identities.adoptRecoveryLease(r.runtimeAgentUid,r.runtimeLocalKey,t);const e=r.observedRuntimeLocalKey;if(!e){const e=r.createOperation?.operationId??r.operationId,i=await this.journal.get(e);if("failed"===i?.phase&&i.command===r.command&&!await this.runtimeAgentExists(r.runtimeLocalKey)){await this.deps.identities.tombstone(r.runtimeAgentUid,r.runtimeLocalKey,t);continue}throw new Error("no persisted gateway effect key; absence cannot be proven")}requireCommittedOpenClawDeleteAck(await this.requireGateway().request("agents.delete",{agentId:e,deleteFiles:!0}),e),await this.deps.identities.tombstone(r.runtimeAgentUid,r.runtimeLocalKey,t)}catch(e){throw new RuntimeCommandError("OUTCOME_UNKNOWN",`Interrupted ${r.command} recovery outcome unknown for operation ${r.operationId}: ${errorText(e)}`,void 0,{cause:e})}finally{let e;try{await i.stop()}catch(t){e=t}try{await this.deps.leases.release(t)}catch(t){e??=t}if(e)throw new RuntimeCommandError("OUTCOME_UNKNOWN",`Interrupted recovery lease finalization unknown: ${errorText(e)}`,void 0,{cause:e})}}}}function isRuntimeAgentMutation(e){return"agent.create"===e.name||"agent.update"===e.name||"agent.delete"===e.name||"agent.applyTemplate"===e.name}function servicePlatformAgentId(e){const t=e.verifiedMessageGrant?.claims;return"agent"===t?.scope?t.platformAgentId:void 0}function agentCoreResultHash(e,t){return createHash("sha256").update(runtimeHashPreimage(RUNTIME_HASH_DOMAINS.coreResult,{method:e.name.replace(".","/"),result:t})).digest("hex")}function agentProjectionRecoverySummary(e,t,r){const i="agent.update"===e.name||"agent.delete"===e.name?e.context.agent:createProjectionTarget(e,t),a=t;return Object.freeze({schemaVersion:1,operationId:e.context.operationId,method:e.name,runtimeEpoch:e.context.dispatchEpoch,runtimeAgentUid:i.runtimeAgentUid,runtimeLocalKey:i.runtimeLocalKey,coreResultHash:agentCoreResultHash(e,t),...servicePlatformAgentId(r)?{expectedPlatformAgentId:servicePlatformAgentId(r)}:{},..."agent.delete"===e.name&&Number.isSafeInteger(a?.removedBindings)?{removedBindings:a.removedBindings}:{}})}function createProjectionTarget(e,t){const r=t;if(!r||r.runtimeAgentUid!==e.params.runtimeAgentUid||"string"!=typeof r.runtimeLocalKey||!r.runtimeLocalKey)throw new RuntimeCommandError("OUTCOME_UNKNOWN","committed agent effect lacks a recoverable local identity");return{runtimeAgentUid:r.runtimeAgentUid,runtimeLocalKey:r.runtimeLocalKey}}function agentProjectionRecoveryResult(e){return Object.freeze({runtimeAgentUid:e.runtimeAgentUid,runtimeLocalKey:e.runtimeLocalKey,...void 0===e.removedBindings?{}:{removedBindings:e.removedBindings}})}function isProjectionIntent(e){return"projectionRevision"in e}function recoveryMetadata(e){const t=RUNTIME_METHOD_PARITY_MANIFEST.filter(t=>t.serviceAllowed&&t.canonicalCommand===e),r=t[0]?.recoveryClass;return r?{recoveryClass:r,projectionRequired:"mcp.set"===e||"mcp.unset"===e||t.some(e=>!0===e.projectionRequired)}:{recoveryClass:"imperative-ambiguous",projectionRequired:!1}}export function isDeterministicAgentsCreateParamsRejection(e){return e instanceof Error&&/^invalid agents\.create params\b/.test(e.message)}export function requireCommittedOpenClawDeleteAck(e,t){if(!e||"object"!=typeof e)throw new Error("gateway delete lacks the committed target acknowledgement");const r=e,i=Object.keys(r).every(e=>"ok"===e||"agentId"===e||"removedBindings"===e),a=void 0===r.removedBindings||Number.isSafeInteger(r.removedBindings)&&r.removedBindings>=0;if(!i||!0!==r.ok||r.agentId!==t||!a)throw new Error("gateway delete lacks the committed target acknowledgement");return{ok:!0,agentId:t,...void 0===r.removedBindings?{}:{removedBindings:r.removedBindings}}}function errorText(e){return e instanceof Error?e.message:String(e)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beeos-claw",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.57",
|
|
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>",
|
|
@@ -87,5 +87,5 @@
|
|
|
87
87
|
"fast-uri": ">=3.1.4",
|
|
88
88
|
"brace-expansion": ">=5.0.9"
|
|
89
89
|
},
|
|
90
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "bcdc0116e7bd8ef98e2febaaa0f6e5b0d6874e81"
|
|
91
91
|
}
|