beeos-claw 0.5.83 → 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
|
-
const TITLE_SYSTEM_PROMPT='You are a conversation title generator. Your task is to generate a concise, human-readable title summarizing the topic of the user\'s question together with the assistant\'s answer.\n\n### Rules:\n- Length: 3-6 words in English, or 6-20 characters in Chinese (up to 24 if needed to keep all key domain terms intact).\n- Language: Match the user\'s input language exactly. Mixed zh/en input → use the dominant language.\n- Extract the core topic (noun-centric) of the Q&A exchange, not the action verb.\n- Use the assistant\'s answer to disambiguate or enrich the topic when the question alone is vague (e.g. "帮我看下" + an answer about x402 → "x402 支付集成").\n- No punctuation, no quotation marks, no emojis, no markdown.\n- No prefix like "Title:" or "Here is". Output the title only.\n- Avoid generic words: "help", "question", "chat", "problem", "task".\n- If both the question and answer are too vague to summarize, return "新会话" (for zh) or "New Conversation" (for en).\n\n### Input Format:\nThe user message will contain both the question and the assistant\'s answer, delimited like this:\n[User Question]\n...question text...\n\n[Assistant Answer]\n...answer text (may be truncated with "..." in the middle)...\n\n### Output Format:\nRespond ONLY with valid JSON, no other text:\n{"title": "<your title here>"}\n\n### Examples:\nInput:\n[User Question]\n帮我写一个关于BeeOS设备接入的PRD\n\n[Assistant Answer]\n好的,这是 BeeOS 设备接入 PRD 的草稿:1. 目标 ...\nOutput: {"title": "BeeOS 设备接入 PRD"}\n\nInput:\n[User Question]\n帮我看下\n\n[Assistant Answer]\n你说的 x402 支付协议是一个基于 HTTP 402 的链上支付标准 ...\nOutput: {"title": "x402 支付协议解析"}\n\nInput:\n[User Question]\nWhat\'s the best way to integrate x402 payment protocol?\n\n[Assistant Answer]\nYou have three options: 1. Use the official SDK ...\nOutput: {"title": "x402 Payment Integration"}\n\nInput:\n[User Question]\nhi\n\n[Assistant Answer]\nHello! How can I help you today?\nOutput: {"title": "New Conversation"}',TITLE_TEMPLATES=[{match:["今日日报","日报"],zh:"今日工作日报",en:"Daily Work Log"},{match:["周报","周报总结","本周周报"],zh:"本周工作周报",en:"Weekly Work Report"},{match:["月报","月度汇报","月度总结"],zh:"本月工作月报",en:"Monthly Work Report"},{match:["工作日志","日志"],zh:"工作日志整理",en:"Work Log Review"},{match:["晨会","今日晨会"],zh:"今日晨会纪要",en:"Daily Standup Notes"},{match:["复盘","今日复盘"],zh:"今日工作复盘",en:"Daily Retrospective"}];export function isPlaceholderTitle(t){if(!t)return!0;const e=t.trim();
|
|
1
|
+
const TITLE_SYSTEM_PROMPT='You are a conversation title generator. Your task is to generate a concise, human-readable title summarizing the topic of the user\'s question together with the assistant\'s answer.\n\n### Rules:\n- Length: 3-6 words in English, or 6-20 characters in Chinese (up to 24 if needed to keep all key domain terms intact).\n- Language: Match the user\'s input language exactly. Mixed zh/en input → use the dominant language.\n- Extract the core topic (noun-centric) of the Q&A exchange, not the action verb.\n- Use the assistant\'s answer to disambiguate or enrich the topic when the question alone is vague (e.g. "帮我看下" + an answer about x402 → "x402 支付集成").\n- No punctuation, no quotation marks, no emojis, no markdown.\n- No prefix like "Title:" or "Here is". Output the title only.\n- Avoid generic words: "help", "question", "chat", "problem", "task".\n- If both the question and answer are too vague to summarize, return "新会话" (for zh) or "New Conversation" (for en).\n\n### Input Format:\nThe user message will contain both the question and the assistant\'s answer, delimited like this:\n[User Question]\n...question text...\n\n[Assistant Answer]\n...answer text (may be truncated with "..." in the middle)...\n\n### Output Format:\nRespond ONLY with valid JSON, no other text:\n{"title": "<your title here>"}\n\n### Examples:\nInput:\n[User Question]\n帮我写一个关于BeeOS设备接入的PRD\n\n[Assistant Answer]\n好的,这是 BeeOS 设备接入 PRD 的草稿:1. 目标 ...\nOutput: {"title": "BeeOS 设备接入 PRD"}\n\nInput:\n[User Question]\n帮我看下\n\n[Assistant Answer]\n你说的 x402 支付协议是一个基于 HTTP 402 的链上支付标准 ...\nOutput: {"title": "x402 支付协议解析"}\n\nInput:\n[User Question]\nWhat\'s the best way to integrate x402 payment protocol?\n\n[Assistant Answer]\nYou have three options: 1. Use the official SDK ...\nOutput: {"title": "x402 Payment Integration"}\n\nInput:\n[User Question]\nhi\n\n[Assistant Answer]\nHello! How can I help you today?\nOutput: {"title": "New Conversation"}',TITLE_TEMPLATES=[{match:["今日日报","日报"],zh:"今日工作日报",en:"Daily Work Log"},{match:["周报","周报总结","本周周报"],zh:"本周工作周报",en:"Weekly Work Report"},{match:["月报","月度汇报","月度总结"],zh:"本月工作月报",en:"Monthly Work Report"},{match:["工作日志","日志"],zh:"工作日志整理",en:"Work Log Review"},{match:["晨会","今日晨会"],zh:"今日晨会纪要",en:"Daily Standup Notes"},{match:["复盘","今日复盘"],zh:"今日工作复盘",en:"Daily Retrospective"}],PLACEHOLDER_TITLES=new Set(["new chat","new conversation","新会话","新對話","新しいチャット","새 채팅","แชตใหม่"]);export function isPlaceholderTitle(t){if(!t)return!0;const e=t.trim();return!e||(!!PLACEHOLDER_TITLES.has(e.toLowerCase())||(!!/^[0-9a-f]{6,12}\s*\(20\d{2}/i.test(e)||(!!/^Sender\s*\(untrusted/i.test(e)||!!/^Conversation\s+info\s*\(untrusted/i.test(e))))}export function isGuardMessage(t){const e=t.trim();return[...e].length<3||[...e].every(t=>/[\p{P}\p{S}\s]/u.test(t))}export function matchTitleTemplate(t){const e=t.trim().toLowerCase();for(const n of TITLE_TEMPLATES)if(n.match.some(t=>t.toLowerCase()===e))return/[\u4e00-\u9fff]/.test(t)?n.zh:n.en}function truncateQuestionForTitle(t){return t.length>2e3?t.slice(0,1500):t}function truncateAnswerForTitle(t){return t.length<=1e3?t:`${t.slice(0,500)}\n...\n${t.slice(-500)}`}export async function generateTitleFromQA(t,e,n,o="title-gen"){if(isGuardMessage(t))return void n?.info?.(`[${o}] SKIP guard message`);const i=matchTitleTemplate(t);if(i)return n?.info?.(`[${o}] template title="${i}"`),i;const r=(process.env.AROUTER_BASE_URL||"").replace(/\/$/,""),s=process.env.AROUTER_API_KEY||"";if(!r||!s)return void n?.info?.(`[${o}] SKIP: no AROUTER env vars`);const a=`[User Question]\n${truncateQuestionForTitle(t)}\n\n[Assistant Answer]\n${truncateAnswerForTitle(e)}`;n?.info?.(`[${o}] CALLING LLM q="${t.slice(0,60)}" aLen=${e.length}`);try{const t=await fetch(`${r}/v1/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify({model:"openai/gpt-4o-mini",max_tokens:32,temperature:.3,messages:[{role:"system",content:TITLE_SYSTEM_PROMPT},{role:"user",content:a}]})});if(!t.ok){const e=await t.text().catch(()=>"");return void n?.info?.(`[${o}] FAILED status=${t.status} body=${e.slice(0,300)}`)}const e=await t.json(),i=e.choices?.[0]?.message?.content?.trim();if(!i)return;const c=i.replace(/^```json\s*/,"").replace(/```$/,"").trim();let u;try{u=JSON.parse(c).title?.trim()??""}catch{return void n?.debug?.(`[${o}] JSON parse failed: ${c}`)}return!u||isPlaceholderTitle(u)?void n?.info?.(`[${o}] discarded placeholder/empty title="${u}"`):(n?.info?.(`[${o}] OK title="${u}"`),u)}catch(t){return void n?.info?.(`[${o}] ERROR: ${t instanceof Error?t.message:t}`)}}function unwrapConversation(t){const e=t.data&&"object"==typeof t.data?t.data:t,n="string"==typeof e.owner_identity_id&&e.owner_identity_id||"string"==typeof e.ownerIdentityId&&e.ownerIdentityId||void 0;return{title:"string"==typeof e.title?e.title:void 0,ownerIdentityId:n}}export async function patchMsConversationTitle(t,e,n,o){await t.request("PATCH",`/api/v1/control/conversations/${encodeURIComponent(e)}`,{ownerIdentityId:n,title:o})}export async function maybeRenameImConversationTitle(t){const{client:e,conversationId:n,question:o,answer:i,logger:r}=t,s=`im-title-gen conv=${n}`;if(!n||!o.trim()||!i.trim())return void r?.debug?.(`[${s}] SKIP missing conversation/q/a`);let a,c;try{const t=unwrapConversation(await e.request("GET",`/api/v2/conversations/${encodeURIComponent(n)}`)??{});a=t.title,c=t.ownerIdentityId}catch(t){return void r?.info?.(`[${s}] GET conversation failed: ${t instanceof Error?t.message:t}`)}if(!isPlaceholderTitle(a))return void r?.debug?.(`[${s}] SKIP non-placeholder title="${a}"`);if(!c)return void r?.info?.(`[${s}] SKIP: no owner_identity_id on conversation`);const u=await generateTitleFromQA(o,i,r,s);if(u)try{return await patchMsConversationTitle(e,n,c,u),r?.info?.(`[${s}] PATCH MS title OK title="${u}"`),u}catch(t){return void r?.info?.(`[${s}] PATCH MS title FAILED: ${t instanceof Error?t.message:t}`)}}
|
|
@@ -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.
|
|
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>",
|