beeos-claw 0.5.84 → 0.5.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{randomUUID}from"node:crypto";import{RuntimeCommandError}from"./runtime-command-dispatcher.js";import{ClearConversationUseCase}from"./conversation-clear-use-case.js";import{AROUTER_PROVIDER_ID}from"../media/arouter-config.js";export class RuntimeSessionControlService{clearRuntime;fallback;activeRuns;constructor(e,t,n){this.clearRuntime=e,this.fallback=t,this.activeRuns=n}async execute(e,t,n){const o=e;if("session.clear"===o.name){if(!n.historyBoundary)throw new RuntimeCommandError("INVALID_PARAMS",`${n.origin} clear attempt lacks its history boundary`);const e=o.context.conversation;return await new ClearConversationUseCase(n.historyBoundary,this.clearRuntime).execute({operationId:o.context.operationId,conversationId:e.runtimeConversationUid,runtimeSessionKey:e.runtimeSessionKey,runtimeEpoch:o.context.dispatchEpoch})}if("session.cancel"===o.name){if(!this.activeRuns)throw new RuntimeCommandError("INVALID_PARAMS","session.cancel active-run authority is not configured");const e=o;return await this.activeRuns.cancelExact({runtimeConversationUid:e.context.conversation.runtimeConversationUid,runtimeSessionKey:e.context.conversation.runtimeSessionKey,historyGeneration:e.context.historyGeneration,targetMessageId:e.params.targetMessageId}),{}}if(!this.fallback)throw new Error(`session command delegate is not configured: ${o.name}`);return await this.fallback.execute(o,t,n)}}export class OpenClawSessionMetadataService{metadata;constructor(e){this.metadata="function"==typeof e?new OpenClawGatewaySessionMetadataPort(e):e}async execute(e){const t=e,n=t.context.conversation.runtimeSessionKey;switch(t.name){case"session.load":return await this.metadata.load(n);case"session.rename":{const e=t.params.title.slice(0,64);return await this.metadata.rename(n,e)}case"session.delete":return await this.metadata.delete(n);case"session.setMode":{const e=t.params.mode;return await this.metadata.setMode(n,e)}case"session.setModel":{const e=t.params.modelOverrideId;if(null!==e&&("string"!=typeof e||0===e.length||e.trim()!==e))throw new RuntimeCommandError("INVALID_PARAMS","modelOverrideId must be a non-empty string or null");const o=null===e?await this.metadata.resolveAgentDefaultModel(n):void 0;if(null===e&&!o)throw new RuntimeCommandError("AGENT_DEFAULT_MODEL_NOT_CONFIGURED","agent default model is not configured");return await this.metadata.setModel(n,e,o??void 0)}}throw new RuntimeCommandError("INVALID_PARAMS","unsupported session metadata command")}async projectCommitted(e,t){if("session.setModel"===e.name){if(!this.metadata.projectCommittedSetModel)throw new Error("session metadata projection is unavailable");await this.metadata.projectCommittedSetModel(e.context.conversation.runtimeSessionKey,t)}}}export class OpenClawGatewaySessionMetadataPort{getGateway;projectModel;constructor(e,t){this.getGateway=e,this.projectModel=t}async load(e){return await this.gateway().request("sessions.resolve",{sessionKey:e}),{loaded:!0}}async rename(e,t){return await this.gateway().request("sessions.patch",{key:e,label:t}),{title:t}}async delete(e){return await this.gateway().request("sessions.delete",{key:e}),{deleted:!0}}async setMode(e,t){const n="verbose"===t||"detailed"===t?{verboseLevel:"full"}:"reasoning"===t||"thinking"===t?{reasoningLevel:"stream"}:"concise"===t||"default"===t?{verboseLevel:"default"}:null;if(!n)throw new RuntimeCommandError("INVALID_PARAMS",`unsupported session mode: ${t}`);if(!isAuthoritativeSetModeAck(await this.gateway().request("sessions.patch",{key:e,...n}),e,n))throw new RuntimeCommandError("OUTCOME_UNKNOWN","sessions.patch did not acknowledge the exact target and effective mode");return{mode:t}}async resolveAgentDefaultModel(e){const t=runtimeAgentId(e),n=await this.gateway().request("agents.list",{}),o=n?.agents?.find(e=>e.id===t),r=o?.defaultModel??o?.model;if("string"!=typeof r||!r.trim()||r.trim()!==r)return null;const s=toPlatformModelId(r),a=s.indexOf("/");return{modelId:s,...a>0?{modelProvider:s.slice(0,a)}:{}}}async setModel(e,t,n){const o=null===t?null:toOpenClawSessionModel(t),r=await this.gateway().request("sessions.patch",{key:e,model:o}),s=r?.resolved?.model;if("string"!=typeof s||0===s.length||s.trim()!==s)throw new RuntimeCommandError("OUTCOME_UNKNOWN","sessions.patch did not acknowledge the effective model override");const a=toPlatformModelId(s);if(null===t&&(!n||a!==n.modelId))throw new RuntimeCommandError("OUTCOME_UNKNOWN","sessions.patch effective model does not match the prevalidated agent default");if(null!==t&&a!==t&&s!==o)throw new RuntimeCommandError("OUTCOME_UNKNOWN","sessions.patch effective model does not match the requested override");return{...null===t?{}:{modelOverrideId:t},effectiveModelId:a,...r?.resolved?.modelProvider?{modelProvider:r.resolved.modelProvider}:{}}}async projectCommittedSetModel(e,t){if(!this.projectModel)throw new Error("session metadata projection is unavailable");await this.projectModel(e,t)}gateway(){const e=this.getGateway();if(!e?.isConnected)throw new RuntimeCommandError("GATEWAY_NOT_CONNECTED","Gateway not connected");return e}}function runtimeAgentId(e){const t=e.split(":");return"agent"===t[0]&&t[1]?.trim()?t[1]:"main"}function toOpenClawSessionModel(e){return e.startsWith(`${AROUTER_PROVIDER_ID}/`)?e:`${AROUTER_PROVIDER_ID}/${e}`}function toPlatformModelId(e){const t=`${AROUTER_PROVIDER_ID}/`;return e.startsWith(t)?e.slice(t.length):e}function isAuthoritativeSetModeAck(e,t,n){if(!e||"object"!=typeof e||Array.isArray(e))return!1;const o=e;if(!0!==o.ok||o.key!==t||!o.entry||"object"!=typeof o.entry||Array.isArray(o.entry))return!1;const r=o.entry;return"verboseLevel"in n?r.verboseLevel===n.verboseLevel:r.reasoningLevel===n.reasoningLevel}export class LocalConversationHistoryBoundary{onCommit;kind="local";intents=new Map;convergence=new Map;generations=new Map;constructor(e){this.onCommit=e}currentGeneration(e){return String(this.generations.get(e)??0n)}async prepare(e){const t=this.intents.get(e.operationId);if(t)return t;const n=(new Date).toISOString(),o=this.generations.get(e.conversationId)??0n,r={intentId:randomUUID(),operationId:e.operationId,conversationId:e.conversationId,state:"prepared",runtimeEpoch:e.runtimeEpoch,fromGeneration:String(o),toGeneration:String(o+1n),boundaryOffset:"0",version:"1",createdAt:n,updatedAt:n};return this.intents.set(e.operationId,r),r}async markResetting(e,t){return this.assertState(e,"prepared"),this.convergence.set(e.operationId,t),this.transition(e,"resetting")}async loadRunConvergence(e){const t=this.convergence.get(e.operationId);if(!t)throw new Error("local clear convergence receipt missing");return t}async markResetDone(e){return this.assertState(e,"resetting"),this.transition(e,"reset_done")}async commit(e){return this.assertState(e,"reset_done"),await(this.onCommit?.(e.conversationId)),this.generations.set(e.conversationId,BigInt(e.toGeneration)),this.transition(e,"committed")}async abortPrepared(e){this.assertState(e,"prepared"),this.transition(e,"aborted")}transition(e,t){const n={...e,state:t,version:String(BigInt(e.version)+1n),updatedAt:(new Date).toISOString()};return this.intents.set(e.operationId,n),n}assertState(e,t){const n=this.intents.get(e.operationId);if(!n||n.version!==e.version||n.state!==t)throw new Error(`local clear transition fenced: expected ${t}`)}}
1
+ import{randomUUID}from"node:crypto";import{RuntimeCommandError}from"./runtime-command-dispatcher.js";import{ClearConversationUseCase}from"./conversation-clear-use-case.js";import{AROUTER_PROVIDER_ID}from"../media/arouter-config.js";export class RuntimeSessionControlService{clearRuntime;fallback;activeRuns;constructor(e,t,n){this.clearRuntime=e,this.fallback=t,this.activeRuns=n}async execute(e,t,n){const o=e;if("session.clear"===o.name){if(!n.historyBoundary)throw new RuntimeCommandError("INVALID_PARAMS",`${n.origin} clear attempt lacks its history boundary`);const e=o.context.conversation;return await new ClearConversationUseCase(n.historyBoundary,this.clearRuntime).execute({operationId:o.context.operationId,conversationId:e.runtimeConversationUid,runtimeSessionKey:e.runtimeSessionKey,runtimeEpoch:o.context.dispatchEpoch})}if("session.cancel"===o.name){if(!this.activeRuns)throw new RuntimeCommandError("INVALID_PARAMS","session.cancel active-run authority is not configured");const e=o;return await this.activeRuns.cancelExact({runtimeConversationUid:e.context.conversation.runtimeConversationUid,runtimeSessionKey:e.context.conversation.runtimeSessionKey,historyGeneration:e.context.historyGeneration,targetMessageId:e.params.targetMessageId}),{}}if(!this.fallback)throw new Error(`session command delegate is not configured: ${o.name}`);return await this.fallback.execute(o,t,n)}async projectCommitted(e,t,n){return await(this.fallback?.projectCommitted?.(e,t,n))}}export class OpenClawSessionMetadataService{metadata;constructor(e){this.metadata="function"==typeof e?new OpenClawGatewaySessionMetadataPort(e):e}async execute(e){const t=e,n=t.context.conversation.runtimeSessionKey;switch(t.name){case"session.load":return await this.metadata.load(n);case"session.rename":{const e=t.params.title.slice(0,64);return await this.metadata.rename(n,e)}case"session.delete":return await this.metadata.delete(n);case"session.setMode":{const e=t.params.mode;return await this.metadata.setMode(n,e)}case"session.setModel":{const e=t.params.modelOverrideId;if(null!==e&&("string"!=typeof e||0===e.length||e.trim()!==e))throw new RuntimeCommandError("INVALID_PARAMS","modelOverrideId must be a non-empty string or null");const o=null===e?await this.metadata.resolveAgentDefaultModel(n):void 0;if(null===e&&!o)throw new RuntimeCommandError("AGENT_DEFAULT_MODEL_NOT_CONFIGURED","agent default model is not configured");return await this.metadata.setModel(n,e,o??void 0)}}throw new RuntimeCommandError("INVALID_PARAMS","unsupported session metadata command")}async projectCommitted(e,t){if("session.setModel"===e.name){if(!this.metadata.projectCommittedSetModel)throw new Error("session metadata projection is unavailable");await this.metadata.projectCommittedSetModel(e.context.conversation.runtimeSessionKey,t)}}}export class OpenClawGatewaySessionMetadataPort{getGateway;projectModel;constructor(e,t){this.getGateway=e,this.projectModel=t}async load(e){return await this.gateway().request("sessions.resolve",{sessionKey:e}),{loaded:!0}}async rename(e,t){return await this.gateway().request("sessions.patch",{key:e,label:t}),{title:t}}async delete(e){return await this.gateway().request("sessions.delete",{key:e}),{deleted:!0}}async setMode(e,t){const n="verbose"===t||"detailed"===t?{verboseLevel:"full"}:"reasoning"===t||"thinking"===t?{reasoningLevel:"stream"}:"concise"===t||"default"===t?{verboseLevel:"default"}:null;if(!n)throw new RuntimeCommandError("INVALID_PARAMS",`unsupported session mode: ${t}`);if(!isAuthoritativeSetModeAck(await this.gateway().request("sessions.patch",{key:e,...n}),e,n))throw new RuntimeCommandError("OUTCOME_UNKNOWN","sessions.patch did not acknowledge the exact target and effective mode");return{mode:t}}async resolveAgentDefaultModel(e){const t=runtimeAgentId(e),n=await this.gateway().request("agents.list",{}),o=n?.agents?.find(e=>e.id===t),r=o?.defaultModel??o?.model;if("string"!=typeof r||!r.trim()||r.trim()!==r)return null;const s=toPlatformModelId(r),a=s.indexOf("/");return{modelId:s,...a>0?{modelProvider:s.slice(0,a)}:{}}}async setModel(e,t,n){const o=null===t?null:toOpenClawSessionModel(t),r=await this.gateway().request("sessions.patch",{key:e,model:o}),s=r?.resolved?.model;if("string"!=typeof s||0===s.length||s.trim()!==s)throw new RuntimeCommandError("OUTCOME_UNKNOWN","sessions.patch did not acknowledge the effective model override");const a=toPlatformModelId(s);if(null===t&&(!n||a!==n.modelId))throw new RuntimeCommandError("OUTCOME_UNKNOWN","sessions.patch effective model does not match the prevalidated agent default");if(null!==t&&a!==t&&s!==o)throw new RuntimeCommandError("OUTCOME_UNKNOWN","sessions.patch effective model does not match the requested override");return{...null===t?{}:{modelOverrideId:t},effectiveModelId:a,...r?.resolved?.modelProvider?{modelProvider:r.resolved.modelProvider}:{}}}async projectCommittedSetModel(e,t){if(!this.projectModel)throw new Error("session metadata projection is unavailable");await this.projectModel(e,t)}gateway(){const e=this.getGateway();if(!e?.isConnected)throw new RuntimeCommandError("GATEWAY_NOT_CONNECTED","Gateway not connected");return e}}function runtimeAgentId(e){const t=e.split(":");return"agent"===t[0]&&t[1]?.trim()?t[1]:"main"}function toOpenClawSessionModel(e){return e.startsWith(`${AROUTER_PROVIDER_ID}/`)?e:`${AROUTER_PROVIDER_ID}/${e}`}function toPlatformModelId(e){const t=`${AROUTER_PROVIDER_ID}/`;return e.startsWith(t)?e.slice(t.length):e}function isAuthoritativeSetModeAck(e,t,n){if(!e||"object"!=typeof e||Array.isArray(e))return!1;const o=e;if(!0!==o.ok||o.key!==t||!o.entry||"object"!=typeof o.entry||Array.isArray(o.entry))return!1;const r=o.entry;return"verboseLevel"in n?r.verboseLevel===n.verboseLevel:r.reasoningLevel===n.reasoningLevel}export class LocalConversationHistoryBoundary{onCommit;kind="local";intents=new Map;convergence=new Map;generations=new Map;constructor(e){this.onCommit=e}currentGeneration(e){return String(this.generations.get(e)??0n)}async prepare(e){const t=this.intents.get(e.operationId);if(t)return t;const n=(new Date).toISOString(),o=this.generations.get(e.conversationId)??0n,r={intentId:randomUUID(),operationId:e.operationId,conversationId:e.conversationId,state:"prepared",runtimeEpoch:e.runtimeEpoch,fromGeneration:String(o),toGeneration:String(o+1n),boundaryOffset:"0",version:"1",createdAt:n,updatedAt:n};return this.intents.set(e.operationId,r),r}async markResetting(e,t){return this.assertState(e,"prepared"),this.convergence.set(e.operationId,t),this.transition(e,"resetting")}async loadRunConvergence(e){const t=this.convergence.get(e.operationId);if(!t)throw new Error("local clear convergence receipt missing");return t}async markResetDone(e){return this.assertState(e,"resetting"),this.transition(e,"reset_done")}async commit(e){return this.assertState(e,"reset_done"),await(this.onCommit?.(e.conversationId)),this.generations.set(e.conversationId,BigInt(e.toGeneration)),this.transition(e,"committed")}async abortPrepared(e){this.assertState(e,"prepared"),this.transition(e,"aborted")}transition(e,t){const n={...e,state:t,version:String(BigInt(e.version)+1n),updatedAt:(new Date).toISOString()};return this.intents.set(e.operationId,n),n}assertState(e,t){const n=this.intents.get(e.operationId);if(!n||n.version!==e.version||n.state!==t)throw new Error(`local clear transition fenced: expected ${t}`)}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beeos-claw",
3
- "version": "0.5.84",
3
+ "version": "0.5.85",
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>",