beeos-claw 0.6.79 → 0.6.80
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/README.md +45 -10
- package/dist/runtime/im-reply-sink.js +1 -1
- package/dist/tool-activity.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -55,6 +55,16 @@ conversion belongs to the channel adapter; ownership and routing never do.
|
|
|
55
55
|
Run-domain completion is a separate lifecycle port invoked once alongside
|
|
56
56
|
terminal fan-out, so neither channel adapter owns session cleanup.
|
|
57
57
|
|
|
58
|
+
For interactive Message Service replies, `before_message_write` commits the
|
|
59
|
+
assistant text and tool order. `onPartialReply` is a temporary preview for the
|
|
60
|
+
current assistant message. Once that message is committed, later partial
|
|
61
|
+
callbacks are ignored until `onAssistantMessageStart` opens the next message.
|
|
62
|
+
This prevents a delayed preview from appending the committed answer twice;
|
|
63
|
+
terminal body replacement cannot retract text already sent through UHP.
|
|
64
|
+
Identical text in two distinct assistant messages remains valid and is kept.
|
|
65
|
+
The sink tests cover a commit followed by a late preview, repeated commit
|
|
66
|
+
hooks, terminal delivery, and identical text after the next message starts.
|
|
67
|
+
|
|
58
68
|
The channel plan is created only when run ownership is known:
|
|
59
69
|
|
|
60
70
|
| Run ownership | Output plan |
|
|
@@ -221,9 +231,9 @@ Each `tool_use` includes a server-generated activity:
|
|
|
221
231
|
Clients translate `kind` into localized wording and use `subject` only when
|
|
222
232
|
present. Supported kinds are `search`, `page`, `read`, `save`, `command`, `other`,
|
|
223
233
|
`find_design_tools`, `find_tools`, `check_rendering`, `list_chinese_fonts`,
|
|
224
|
-
`list_fonts`, `list_files`, `install`, `run_script`, `generate_poster`,
|
|
225
|
-
`generate_image`. Actions describe the invocation, not
|
|
226
|
-
command can contain multiple actions; unknown shell syntax falls back to
|
|
234
|
+
`list_fonts`, `list_files`, `install`, `run_script`, `generate_poster`,
|
|
235
|
+
`generate_image`, and `generate_document`. Actions describe the invocation, not
|
|
236
|
+
its success. A compound command can contain multiple actions; unknown shell syntax falls back to
|
|
227
237
|
`command` for the whole invocation. Standard `/bin`, `/usr/bin`, and
|
|
228
238
|
`/usr/local/bin` executable paths use the same rules as bare names. Script
|
|
229
239
|
execution shows the script basename without guessing what it produces.
|
|
@@ -238,14 +248,38 @@ Headless `google-chrome` screenshots of local HTML or SVG to PNG use `generate_i
|
|
|
238
248
|
with the output basename. Only known rendering flags are accepted; filenames
|
|
239
249
|
never imply `generate_poster`.
|
|
240
250
|
`identify` with one ordinary local PNG/JPEG/WebP/GIF path shows `read` and its basename.
|
|
241
|
-
`write`/`edit` calls show `save` with the file basename.
|
|
251
|
+
`write`/`edit` calls show `save` with the file basename. `render_ui` shows
|
|
252
|
+
`generate_document`; its optional subject comes only from the schema's `title`
|
|
253
|
+
field. A missing or invalid title leaves the subject absent so clients use
|
|
254
|
+
“生成文档” (Generate document). HTML, surface IDs, and component content never
|
|
255
|
+
supply a title. Unknown tools use `other`.
|
|
242
256
|
|
|
243
257
|
`src/tool-activity.ts` reads actual tool names and arguments, including bounded
|
|
244
|
-
`tool_call` wrappers. It ignores `
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
258
|
+
`tool_call` wrappers. It ignores `tasktitle`, incoming `activity`, and `title`
|
|
259
|
+
except for the explicit `render_ui.title` field. Subjects are limited to search
|
|
260
|
+
queries, URL hostnames, file basenames, document titles, and allowlisted package
|
|
261
|
+
names. Raw commands, inline code, HTML bodies, URL credentials/query strings,
|
|
262
|
+
and full local paths are not activity subjects.
|
|
263
|
+
|
|
264
|
+
The optional `activity.details` array supplies facts for expanding one action
|
|
265
|
+
row. It contains at most five `{ "kind": ..., "value": ... }` objects:
|
|
266
|
+
|
|
267
|
+
| Detail kind | Source |
|
|
268
|
+
| --- | --- |
|
|
269
|
+
| `query` | Search tool's actual `query` |
|
|
270
|
+
| `website` | HTTP(S) fetch URL hostname only |
|
|
271
|
+
| `file` | Basename from an allowed file operation or recognized script/render command |
|
|
272
|
+
| `document_title` | `render_ui.title` only |
|
|
273
|
+
|
|
274
|
+
For example, a search for `深圳 天气` includes
|
|
275
|
+
`"details": [{ "kind": "query", "value": "深圳 天气" }]`.
|
|
276
|
+
Values share the subject limit of 180 Unicode characters plus an ellipsis when
|
|
277
|
+
truncated; control characters become spaces. Empty values are omitted. If no
|
|
278
|
+
allowed facts exist, `details` is absent. This is an additive version 1 field.
|
|
279
|
+
Clients display these facts as plain text and never parse arguments, HTML,
|
|
280
|
+
commands, or outputs to construct details. Unknown operations can show status
|
|
281
|
+
alone. The classifier never executes commands and does not alter approval
|
|
282
|
+
requirements.
|
|
249
283
|
|
|
250
284
|
Tool results and lifecycle events correlate by the explicit canonical call ID.
|
|
251
285
|
Early results wait for that exact card; anonymous summaries are ignored even
|
|
@@ -265,7 +299,8 @@ Acceptance coverage lives in `message-client-types.test.ts`,
|
|
|
265
299
|
`runtime/im-reply-sink.test.ts`, `runtime/tool-result-observation-router.test.ts`, and
|
|
266
300
|
`runtime/message-service-run-output-channel.test.ts`: compound command actions,
|
|
267
301
|
misleading titles and prompts, secret-bearing shell/URL arguments, wrapped
|
|
268
|
-
calls,
|
|
302
|
+
calls, allowed detail fields and bounds, document titles and missing-title
|
|
303
|
+
fallbacks, delayed anonymous approval errors, early results for a different ID,
|
|
269
304
|
approval waiting versus terminal updates, and structured native failures without
|
|
270
305
|
inferring errors from output text.
|
|
271
306
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{toMessagePart}from"../message-client-types.js";import{isUploadArtifactToolName,resolveToolArtifactLinks}from"../upload/tool-artifact-enrichment.js";import{sessionWorkspaceDir,takeFinalizeAttachments}from"../upload/delivery-ledger.js";import{resolveRuntimeToolArguments,resolveRuntimeToolCallId,resolveRuntimeToolName}from"./tool-envelope-metadata.js";import{extractSearchSources,mergeSearchSource,searchSourceProvider}from"./search-source-extractor.js";import{isRenderUiToolName,staticHtmlProjectionOf,staticHtmlResultOf}from"../canvas/static-html-result.js";import{logChatLatency}from"../chat-latency.js";const STREAMING_SNAPSHOT_PUBLISH_INTERVAL_MS=200,isNonEmptyString=e=>"string"==typeof e&&e.length>0,isPlainRecord=e=>"object"==typeof e&&null!==e&&!Array.isArray(e);function pickRawResultFromPayload(e){if(void 0!==e.rawResult)return e.rawResult;if(void 0!==e.result)return e.result;if(void 0!==e.details)return e.details;if(void 0!==e.toolResult)return e.toolResult;if(isPlainRecord(e.channelData)){const t=e.channelData;if(void 0!==t.rawResult)return t.rawResult;if(void 0!==t.result)return t.result;if(void 0!==t.details)return t.details}}function asToolParams(e){if(e&&"object"==typeof e&&!Array.isArray(e))return e}const summarizeObservedToolError=e=>{if(null==e)return;if("string"==typeof e)return e.slice(0,180);if("object"!=typeof e)return String(e).slice(0,180);const t=e;for(const e of["error","message","blockReason","details","text"]){const r=t[e];if("string"==typeof r&&r.trim())return r.slice(0,180);if(isPlainRecord(r)&&"string"==typeof r.message&&r.message.trim())return r.message.slice(0,180)}try{const t=JSON.stringify(e);return t?t.slice(0,180):void 0}catch{return}},observedToolResultText=e=>{if(!isPlainRecord(e)||!Array.isArray(e.content))return;const t=e.content.filter(e=>isPlainRecord(e)&&"text"===e.type&&"string"==typeof e.text).map(e=>e.text.trim()).filter(Boolean);return t.length>0?t.join("\n"):void 0};export function createImReplySink(e){const t=e.startedAtMs??Date.now();let r=!1;const s=new Map,o=new Set,a={text:""};let n="",i="",l=!1,d=!1;const u=new Set;let m;const c={receivedSnapshotCount:0,streamingPublishCount:0,terminalPublishCount:0},g=[];let p;const f=new Map,h=[],b=new Map,v=new Map;let y,_=0,I=1;const S=(e,t={})=>({schema_version:1,seq:e,...t}),x=new Set,R=new Set,w=t=>{t!==a.text&&(t.startsWith(a.text)?e.stream.appendBody(t.slice(a.text.length)):e.stream.setBody(t),a.text=t)},P=e=>{void 0===e.publishTimer&&(e.publishTimer=setTimeout(()=>{e.publishTimer=void 0,te("body_preview_flush",()=>{m===e&&(e=>{a.text!==e.targetBody&&(w(e.targetBody),e.streamingPublishCount+=1)})(e)})},200))},k=e=>{const t=m;t?(void 0!==t.publishTimer&&(clearTimeout(t.publishTimer),t.publishTimer=void 0),t.targetBody=e,a.text!==e&&(w(e),t.terminalPublishCount+=1),c.receivedSnapshotCount+=t.receivedSnapshotCount,c.streamingPublishCount+=t.streamingPublishCount,c.terminalPublishCount+=t.terminalPublishCount,m=void 0):w(e)},q=t=>{if(void 0!==t.partIndex)return;const r=_,s=I;e.stream.addPart(toMessagePart({type:"text",text:t.text,state:"done",_seq:s,data:S(s)})),t.partIndex=r,_+=1,I+=1},T=()=>{if(!d){d=!0;for(const e of g)q(e)}},$=e=>{const t={text:e};g.push(t),d&&q(t)},E=(t,r)=>{for(const s of t){const t=v.get(s.url);if(t){const r=mergeSearchSource(t,s);if(r.title===t.title&&r.snippet===t.snippet)continue;const o={...r,partIndex:t.partIndex,displaySeq:t.displaySeq,toolUseId:t.toolUseId};e.stream.replacePart(t.partIndex,toMessagePart({type:"source",url:o.url,...o.title?{title:o.title}:{},...o.snippet?{snippet:o.snippet}:{},tool_use_id:o.toolUseId,_seq:o.displaySeq,data:S(o.displaySeq)})),v.set(s.url,o);continue}const o={...s,partIndex:_,displaySeq:I,toolUseId:r};e.stream.addPart(toMessagePart({type:"source",url:s.url,...s.title?{title:s.title}:{},...s.snippet?{snippet:s.snippet}:{},tool_use_id:r,_seq:o.displaySeq,data:S(o.displaySeq)})),v.set(s.url,o),_+=1,I+=1,Y.source+=1}},C=(e,t,r,s)=>toMessagePart({type:"thinking",text:t,state:r,_seq:e.displaySeq,_started_at_ms:e.startedAtMs,...void 0!==s?{_duration_ms:s}:{},data:S(e.displaySeq,{started_at_ms:e.startedAtMs,...void 0!==s?{duration_ms:s}:{}})}),M=t=>{T();const r={partIndex:_,displaySeq:I,text:t,publishedText:t,receivedSnapshotCount:1,streamingPublishCount:1,startedAtMs:Date.now(),startedAtMonotonicMs:performance.now()};return e.stream.addPart(C(r,t,"streaming")),_+=1,I+=1,p=r,r},A=t=>{void 0===t.publishTimer&&(t.publishTimer=setTimeout(()=>{t.publishTimer=void 0,te("reasoning_snapshot_flush",()=>{p===t&&(t=>{t.publishedText!==t.text&&(e.stream.replacePart(t.partIndex,C(t,t.text,"streaming")),t.publishedText=t.text,t.streamingPublishCount+=1)})(t)})},200))},O=()=>{const r=p;if(!r)return;void 0!==r.publishTimer&&(clearTimeout(r.publishTimer),r.publishTimer=void 0);const s=Math.max(0,Math.round(performance.now()-r.startedAtMonotonicMs));e.stream.replacePart(r.partIndex,C(r,r.text,"done",s)),p=void 0,logChatLatency(e.logger,"claw.reasoning.settled",e.requestId,t,{reasoning_duration_ms:s,reasoning_chars:r.text.length,reasoning_snapshot_count:r.receivedSnapshotCount,reasoning_streaming_publish_count:r.streamingPublishCount,reasoning_coalesced_snapshot_count:Math.max(0,r.receivedSnapshotCount-r.streamingPublishCount),reasoning_publish_interval_ms:200})},F=e=>{const t=h.indexOf(e);t>=0&&h.splice(t,1)},N=e=>null!=e&&("object"!=typeof e||(Array.isArray(e)?e.length>0:Object.keys(e).length>0)),U=e=>{let t=b.get(e);return t||(t={},b.set(e,t)),t},j=(t,r,s)=>{const o="tool"===t.name&&"tool"!==r?r:t.name,a=!N(t.arguments)&&N(s)?s:t.arguments;o===t.name&&a===t.arguments||(e.stream.replacePart(t.partIndex,toMessagePart({type:"tool_use",id:t.id,name:t.htmlPresentation?.name??o,arguments:t.htmlPresentation?.arguments??a,state:t.state,_seq:t.displaySeq,data:S(t.displaySeq)})),t.name=o,t.arguments=a)},L=(t,r,s,o)=>{const a=f.get(t);if(a)return j(a,r,s),o&&!h.includes(t)&&"streaming"===a.state&&h.push(t),a;T();const n=b.get(t),i="tool"!==r?r:n?.name&&"tool"!==n.name?n.name:r,l=N(s)?s:n?.arguments??s,d=((t,r,s)=>{const o=_,a=I;return e.stream.addPart(toMessagePart({type:"tool_use",id:t,name:r,arguments:s,state:"streaming",_seq:a,data:S(a)})),_+=1,I+=1,{partIndex:o,displaySeq:a}})(t,i,l),u={id:t,name:i,arguments:l,partIndex:d.partIndex,displaySeq:d.displaySeq,state:"streaming",itemEventObserved:!0===n?.itemEventObserved,toolStartObserved:!0===n?.toolStartObserved};return f.set(t,u),(o||u.toolStartObserved||u.itemEventObserved)&&(h.includes(t)||"streaming"!==u.state||h.push(t)),n&&Q(u,n),b.delete(t),u},B=(e,t)=>{const r=(e=>f.get(e))(e);if(r)return void 0===t.name&&void 0===t.arguments||j(r,t.name??r.name,t.arguments??r.arguments),t.toolStartObserved&&(r.toolStartObserved=!0),t.itemEventObserved&&(r.itemEventObserved=!0),(t.pending||t.toolStartObserved||t.itemEventObserved)&&!h.includes(r.id)&&"streaming"===r.state&&h.push(r.id),r;const s=U(e);void 0!==t.name&&(s.name=t.name),void 0!==t.arguments&&(s.arguments=t.arguments),t.toolStartObserved&&(s.toolStartObserved=!0),t.itemEventObserved&&(s.itemEventObserved=!0)},H=t=>{"done"!==t.state&&(e.stream.replacePart(t.partIndex,toMessagePart({type:"tool_use",id:t.id,name:t.htmlPresentation?.name??t.name,arguments:t.htmlPresentation?.arguments??t.arguments,state:"done",_seq:t.displaySeq,data:S(t.displaySeq)})),t.state="done")},z=e=>{if(null===e||"object"!=typeof e)return JSON.stringify(e)??String(e);if(Array.isArray(e))return`[${e.map(z).join(",")}]`;return`{${Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${z(t)}`).join(",")}}`},D=(t,r,s)=>{const o=`${s?"1":"0"}:${z(r)}`;if(t.progressSignature===o)return;const a=toMessagePart({type:"custom",kind:"tool_progress",data:{tool_use_id:t.id,content:r,...s?{is_error:!0}:{}}});if(void 0===t.progressPartIndex){const r=_;return e.stream.addPart(a),t.progressPartIndex=r,t.progressSignature=o,void(_+=1)}e.stream.replacePart(t.progressPartIndex,a),t.progressSignature=o},Q=(e,t)=>{if(t.progress?.length)for(const r of t.progress)D(e,r.content,r.isError);t.observedResult&&(D(e,t.observedResult.content,t.observedResult.isError),e.observedResult=t.observedResult,"tool_call"!==e.name&&!isRenderUiToolName(e.name)||t.observedResult.isError||V(e,{text:t.observedResult.content,isError:t.observedResult.isError,rawResult:t.observedResult.rawResult})),(t.progress?.length||t.observedResult)&&(H(e),F(e.id)),!t.observedResult&&t.htmlPayload&&V(e,t.htmlPayload),t.sources?.length&&E(t.sources,e.id)},W=e=>[...new Set([e.mediaUrl,...e.mediaUrls??[]].filter(e=>isNonEmptyString(e)).map(e=>e.trim()).filter(Boolean))],J=(e,t=[])=>{const r=[...new Set([...W(e),...t])];return isNonEmptyString(e.text)&&r.length>0?{text:e.text,media_urls:r}:isNonEmptyString(e.text)?e.text:1===r.length?r[0]:r.length>1?{media_urls:r}:!0===e.isError?"Tool execution failed.":""},K=t=>{for(const r of t)e.stream.addPart(toMessagePart({type:"resource_link",uri:r.uri,name:r.name,...r.mimeType?{mimeType:r.mimeType}:{}})),_+=1},G=t=>{x.add(t);const r=()=>{x.delete(t)};e.onCallbackFailure?t.then(r,r):t.finally(r)},V=(t,r)=>{const s=t.observedResult,o=s?.isError??!0===r.isError,a=s?.rawResult??pickRawResultFromPayload(r),n=o?void 0:staticHtmlProjectionOf(t.name,t.arguments,a);if(t.durableUploadFilesEmitted&&(!n||t.staticHtmlResultEmitted))return;e.logger.info?.(`[im-sink] schedule tool artifact enrichment requestId=${e.requestId} toolUseId=${t.id} name=${t.name}`);const i=(async()=>{let s=[];try{s=await resolveToolArtifactLinks({toolCallId:t.id,toolName:t.name,rawResult:a,rawText:"string"==typeof r.text?r.text:void 0,params:asToolParams(t.arguments),cwd:sessionWorkspaceDir(e.sessionKey),payloadMediaUrls:W(r)})}catch(r){const s=r instanceof Error?r.message:String(r);if(e.logger.warn?.(`[im-sink] resolveToolArtifactLinks failed requestId=${e.requestId} toolUseId=${t.id} error=${s}`),e.onCallbackFailure?.(r),e.onCallbackFailure)throw r;return}if(n&&!s.some(e=>e.uri===n.result.artifact.uri)){const e=n.result.artifact;s.push({uri:e.uri,name:e.title,mimeType:e.mimeType})}0!==s.length?(e.logger.info?.(`[im-sink] tool artifact enrichment resolved ${s.length} link(s) requestId=${e.requestId} toolUseId=${t.id}`),await new Promise((o,a)=>{const i=e.callbackQueue.enqueueSync(()=>{try{if(e.abortSignal.aborted||e.stream.isTerminated)return;const o=s.map(e=>e.uri);t.artifactMediaUrls=o;const a=t.observedResult;D(t,J(a?{text:a.content,isError:a.isError}:r,o),a?.isError??!0===r.isError),((t,r,s,o)=>{const a=r.length>0&&!t.durableUploadFilesEmitted,n=!s&&void 0!==o&&!t.staticHtmlResultEmitted;(a||n)&&(n&&(t.htmlPresentation={name:"render_ui",arguments:o.arguments},e.stream.replacePart(t.partIndex,toMessagePart({type:"tool_use",id:t.id,...t.htmlPresentation,state:t.state,_seq:t.displaySeq,data:S(t.displaySeq)}))),e.stream.appendToolResult(t.id,[...n?[{type:"text",text:JSON.stringify(o.result)}]:[],...a?r.map(e=>({type:"resource_link",uri:e.uri,name:e.name,...e.mimeType?{mimeType:e.mimeType}:{}})):[]],s),_+=1,n&&(t.staticHtmlResultEmitted=!0),a&&(t.durableUploadFilesEmitted=!0,K(r)))})(t,s,a?.isError??!0===r.isError,n)}catch(r){const s=r instanceof Error?r.message:String(r);e.logger.warn?.(`[im-sink] tool artifact enrichment apply failed requestId=${e.requestId} toolUseId=${t.id} error=${s}`),e.onCallbackFailure?.(r),e.onCallbackFailure&&a(r)}finally{o()}});!1===i&&e.onCallbackFailure&&e.callbackQueue.waitForIdle().then(o,a)})):e.logger.debug?.(`[im-sink] tool artifact enrichment found no links requestId=${e.requestId} toolUseId=${t.id} name=${t.name}`)})().catch(r=>{const s=r instanceof Error?r.message:String(r);if(e.logger.warn?.(`[im-sink] tool artifact enrichment failed requestId=${e.requestId} toolUseId=${t.id} error=${s}`),e.onCallbackFailure?.(r),e.onCallbackFailure)throw r});G(i)},X=(e,t,r)=>B(e,{name:t,arguments:r}),Y={tool:0,block:0,final:0,source:0};let Z,ee=!1;const te=(t,r)=>{e.callbackQueue.enqueueSync(()=>{if((t=>e.abortSignal.aborted?(e.logger.debug?.(`[im-sink] ${t} ignored after abort requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId}`),!1):e.stream.isTerminated?(e.logger.debug?.(`[im-sink] ${t} ignored after stream_terminated requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId}`),!1):!ee||(e.logger.debug?.(`[im-sink] ${t} ignored after mark_complete requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId}`),!1))(t))try{r()}catch(r){const s=r instanceof Error?r.message:String(r);e.logger.warn?.(`[im-sink] ${t} mapping failed requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId} error=${s}`),e.onCallbackFailure?.(r)}})},re={sendToolResult:t=>(te("tool_progress",()=>{const r=resolveRuntimeToolCallId(t),s=resolveRuntimeToolName(t),o=resolveRuntimeToolArguments(t),a=J(t),n=!0===t.isError;let i;if(r){if(i=X(r,s,o),!i){const e=U(r);if(s&&(e.name=s),N(o)&&(e.arguments=o),e.progress=[...e.progress??[],{content:a,isError:n}],"tool_call"===s||isRenderUiToolName(s??"")){const r=pickRawResultFromPayload(t);(n||void 0!==r)&&(e.htmlPayload=!n&&staticHtmlResultOf(r)?t:void 0)}return void(Y.tool+=1)}i&&(Y.tool+=1,i.observedResult||D(i,a,n),H(i),F(i.id),V(i,t))}else e.logger.debug?.(`[im-sink] unattributed tool progress ignored requestId=${e.requestId} channel=${e.channelId} tool=${s??"unknown"} pending=${h.length}`)}),!0),sendBlockReply:e=>(te("block_reply",()=>{Y.block+=1,isNonEmptyString(e.text)&&(Z=!0!==e.isError?void 0:e.text)}),!0),sendFinalReply:t=>(te("final_reply",()=>{var r;(Y.final+=1,!0!==t.isError)?((t=>{const r=W(t).filter(e=>!R.has(e));if(0===r.length)return;for(const e of r)R.add(e);const s=(async()=>{let t=[];try{t=await resolveToolArtifactLinks({toolCallId:`final:${e.runId??e.requestId}`,toolName:"final_reply_media",payloadMediaUrls:r})}catch(t){for(const e of r)R.delete(e);if(e.logger.warn?.(`[im-sink] final media enrichment failed requestId=${e.requestId} error=${t instanceof Error?t.message:String(t)}`),e.onCallbackFailure?.(t),e.onCallbackFailure)throw t;return}if(0!==t.length)await new Promise((r,s)=>{!1===e.callbackQueue.enqueueSync(()=>{try{if(e.abortSignal.aborted||e.stream.isTerminated)return;K(t)}catch(t){e.logger.warn?.(`[im-sink] final media enrichment apply failed requestId=${e.requestId} error=${t instanceof Error?t.message:String(t)}`),e.onCallbackFailure?.(t),e.onCallbackFailure&&s(t)}finally{r()}})&&e.onCallbackFailure&&e.callbackQueue.waitForIdle().then(r,s)});else for(const e of r)R.delete(e)})();G(s)})(t),isNonEmptyString(t.text)&&(Z=void 0,l||(r=t.text,i="",n+=r,k(n),$(r),l=!0))):Z=t.text}),!0),waitForIdle:async()=>{for(let t=0;(e.onCallbackFailure||t<16)&&(await e.callbackQueue.waitForIdle(),0!==x.size);t++)e.onCallbackFailure?await Promise.all([...x]):await Promise.allSettled([...x]);await e.callbackQueue.waitForIdle();const t=takeFinalizeAttachments(e.sessionKey);t.length>0&&!e.abortSignal.aborted&&!e.stream.isTerminated&&K(t)},getQueuedCounts:()=>({tool:Y.tool,block:Y.block,final:Y.final}),getAccumulatedBody:()=>a.text,getTerminalErrorText:()=>Z,markComplete:r=>{O(),b.size>0&&e.logger.debug?.(`[im-sink] dropping uncommitted lifecycle tool signals requestId=${e.requestId} buffered=${b.size}`),i="",k(n),c.receivedSnapshotCount>0&&logChatLatency(e.logger,"claw.text_preview.settled",e.requestId,t,{text_preview_snapshot_count:c.receivedSnapshotCount,text_preview_streaming_publish_count:c.streamingPublishCount,text_preview_terminal_publish_count:c.terminalPublishCount,text_preview_coalesced_snapshot_count:Math.max(0,c.receivedSnapshotCount-c.streamingPublishCount-c.terminalPublishCount),text_preview_publish_interval_ms:200});for(const t of f.values())try{"success"===r&&isUploadArtifactToolName(t.name)&&!t.durableUploadFilesEmitted&&V(t,{toolCallId:t.id,toolName:t.name}),"success"===r&&H(t),F(t.id)}catch(r){const s=r instanceof Error?r.message:String(r);e.logger.warn?.(`[im-sink] tool finalization failed requestId=${e.requestId} toolUseId=${t.id} error=${s}`)}b.clear(),ee=!0}},se={...e.runId?{runId:e.runId}:{},abortSignal:e.abortSignal,disableBlockStreaming:!0,onAgentRunStart:r=>{e.onAgentRunStart?.(r),logChatLatency(e.logger,"claw.runtime.run_started",e.requestId,t),e.logger.info?.(`[im-sink] run_start requestId=${e.requestId} runId=${r} channel=${e.channelId} in_reply_to=${e.inboundMessageId} origin=${e.origin??"im"}`)},onPartialReply:s=>{te("partial",()=>{"string"==typeof s.text&&(!r&&s.text.length>0&&(r=!0,logChatLatency(e.logger,"claw.model.first_delta",e.requestId,t)),i=s.text,(e=>{const t=m;if(!t){if(a.text===e)return;return w(e),void(m={targetBody:e,receivedSnapshotCount:1,streamingPublishCount:1,terminalPublishCount:0})}t.targetBody!==e&&(t.targetBody=e,t.receivedSnapshotCount+=1,P(t))})(n+i))})},onReasoningStream:e=>{te("reasoning",()=>{if(!isNonEmptyString(e.text))return;const t=e.text,r=p??M(t);t!==r.text&&(r.text.startsWith(t)||(t.startsWith(r.text)?(r.text=t,r.receivedSnapshotCount+=1,A(r)):(O(),M(t))))})},onReasoningEnd:()=>{te("reasoning_end",()=>{O()})},onAssistantMessageStart:()=>{te("assistant_message_start",()=>{i="",l=!1,k(n),e.logger.debug?.(`[im-sink] assistant_message_start requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId}`)})},onToolStart:r=>{te("tool_start",()=>{const o="string"==typeof r.phase?r.phase:"start",a=resolveRuntimeToolName(r)??"tool",n=resolveRuntimeToolCallId(r),i=resolveRuntimeToolArguments(r);"update"!==o?(n&&s.set(n,Date.now()),logChatLatency(e.logger,"claw.tool.start",e.requestId,t,{tool:a}),n&&B(n,{name:a,arguments:i,toolStartObserved:!0,pending:!0})):n&&B(n,{name:a,arguments:i,pending:!0})})},onItemEvent:e=>{te("item_event",()=>{const t="string"==typeof e.kind?e.kind.toLowerCase():"";if(t&&"tool"!==t)return;"string"==typeof e.phase&&e.phase.toLowerCase();const r=resolveRuntimeToolCallId(e)??("string"==typeof e.itemId&&e.itemId.trim()?e.itemId.trim():void 0),s=resolveRuntimeToolName(e)??("string"==typeof e.title&&e.title.trim()?e.title.trim():void 0);r&&s&&B(r,{name:s,itemEventObserved:!0,pending:!0})})}},oe={add(t){if(e.stream.isTerminated)return;const r=_;return e.stream.addPart(t),_+=1,r}},ae={add:e=>oe.add(e),replace:(t,r)=>!e.stream.isTerminated&&(e.stream.replacePart(t,r),!0)};return{dispatcher:re,replyOptions:se,commitAssistantMessage:t=>{te("assistant_message_commit",()=>{if(u.has(t.key))return;u.add(t.key),l=!0,Z=void 0,i="";const r=t.segments.filter(e=>"text"===e.type).map(e=>e.text).join("");n+=r,k(n);for(const e of t.segments)"text"!==e.type?L(e.id,e.name,e.arguments,!0):$(e.text);if(void 0!==t.executedModel||void 0!==y){const r=toMessagePart({type:"custom",kind:"execution_model",data:{executed_model:t.executedModel??""}});void 0===y?(e.stream.addPart(r),y=_++):e.stream.replacePart(y,r)}})},observeToolResult:r=>{te("tool_result_observation",()=>{const a=r.toolCallId.trim(),n=r.toolName.trim();if(!a||!n)return;const i=!o.has(a);if(i){o.add(a);const i=s.get(a);logChatLatency(e.logger,"claw.tool.result",e.requestId,t,{tool:n,tool_elapsed_ms:void 0===i?void 0:Math.max(0,Date.now()-i),outcome:r.isError?"error":"success",...r.isError?{error:summarizeObservedToolError(r.rawResult)??"error"}:{}})}if(e.persistObservedToolResults&&i){const e=observedToolResultText(r.rawResult)??("tool_call"===n||isRenderUiToolName(n)?"":void 0);if(void 0!==e){const t=X(a,n);if(t)D(t,J({text:e,isError:r.isError},t.artifactMediaUrls),r.isError),t.observedResult={content:e,isError:r.isError,rawResult:r.rawResult},H(t),F(t.id),"tool_call"!==t.name&&!isRenderUiToolName(t.name)||r.isError||V(t,{text:e,isError:r.isError,rawResult:r.rawResult});else{const t=U(a);t.name??=n,t.observedResult={content:e,isError:r.isError,rawResult:r.rawResult}}}}const l=searchSourceProvider(r.rawResult)??"unknown";let d=0;try{const t=extractSearchSources({toolName:n,rawResult:r.rawResult,isError:r.isError});if(d=t.length,0===d)return;const s=X(a,n);if(s)E(t,s.id);else{const e=U(a);e.name??=n,e.sources=((e,t)=>{if(!e?.length&&!t?.length)return;const r=[],s=new Map;for(const o of[...e??[],...t??[]]){const e=s.get(o.url);void 0===e?(s.set(o.url,r.length),r.push(o)):r[e]=mergeSearchSource(r[e],o)}return r})(e.sources,t)}e.logger.debug?.(`[im-sink] search source projection requestId=${e.requestId} tool=${n} provider=${l} source_count=${d}`)}catch{e.logger.warn?.(`[im-sink] search source projection ignored requestId=${e.requestId} tool=${n} provider=${l} source_count=${d}`)}})},getSourceCount:()=>Y.source,approvalParts:oe,questionParts:ae}}
|
|
1
|
+
import{toMessagePart}from"../message-client-types.js";import{isUploadArtifactToolName,resolveToolArtifactLinks}from"../upload/tool-artifact-enrichment.js";import{sessionWorkspaceDir,takeFinalizeAttachments}from"../upload/delivery-ledger.js";import{resolveRuntimeToolArguments,resolveRuntimeToolCallId,resolveRuntimeToolName}from"./tool-envelope-metadata.js";import{extractSearchSources,mergeSearchSource,searchSourceProvider}from"./search-source-extractor.js";import{isRenderUiToolName,staticHtmlProjectionOf,staticHtmlResultOf}from"../canvas/static-html-result.js";import{logChatLatency}from"../chat-latency.js";const STREAMING_SNAPSHOT_PUBLISH_INTERVAL_MS=200,isNonEmptyString=e=>"string"==typeof e&&e.length>0,isPlainRecord=e=>"object"==typeof e&&null!==e&&!Array.isArray(e);function pickRawResultFromPayload(e){if(void 0!==e.rawResult)return e.rawResult;if(void 0!==e.result)return e.result;if(void 0!==e.details)return e.details;if(void 0!==e.toolResult)return e.toolResult;if(isPlainRecord(e.channelData)){const t=e.channelData;if(void 0!==t.rawResult)return t.rawResult;if(void 0!==t.result)return t.result;if(void 0!==t.details)return t.details}}function asToolParams(e){if(e&&"object"==typeof e&&!Array.isArray(e))return e}const summarizeObservedToolError=e=>{if(null==e)return;if("string"==typeof e)return e.slice(0,180);if("object"!=typeof e)return String(e).slice(0,180);const t=e;for(const e of["error","message","blockReason","details","text"]){const r=t[e];if("string"==typeof r&&r.trim())return r.slice(0,180);if(isPlainRecord(r)&&"string"==typeof r.message&&r.message.trim())return r.message.slice(0,180)}try{const t=JSON.stringify(e);return t?t.slice(0,180):void 0}catch{return}},observedToolResultText=e=>{if(!isPlainRecord(e)||!Array.isArray(e.content))return;const t=e.content.filter(e=>isPlainRecord(e)&&"text"===e.type&&"string"==typeof e.text).map(e=>e.text.trim()).filter(Boolean);return t.length>0?t.join("\n"):void 0};export function createImReplySink(e){const t=e.startedAtMs??Date.now();let r=!1;const s=new Map,o=new Set,a={text:""};let n="",i="",l=!1,d=!1;const u=new Set;let m;const c={receivedSnapshotCount:0,streamingPublishCount:0,terminalPublishCount:0},g=[];let p;const f=new Map,h=[],b=new Map,v=new Map;let y,_=0,I=1;const S=(e,t={})=>({schema_version:1,seq:e,...t}),x=new Set,R=new Set,w=t=>{t!==a.text&&(t.startsWith(a.text)?e.stream.appendBody(t.slice(a.text.length)):e.stream.setBody(t),a.text=t)},P=e=>{void 0===e.publishTimer&&(e.publishTimer=setTimeout(()=>{e.publishTimer=void 0,te("body_preview_flush",()=>{m===e&&(e=>{a.text!==e.targetBody&&(w(e.targetBody),e.streamingPublishCount+=1)})(e)})},200))},k=e=>{const t=m;t?(void 0!==t.publishTimer&&(clearTimeout(t.publishTimer),t.publishTimer=void 0),t.targetBody=e,a.text!==e&&(w(e),t.terminalPublishCount+=1),c.receivedSnapshotCount+=t.receivedSnapshotCount,c.streamingPublishCount+=t.streamingPublishCount,c.terminalPublishCount+=t.terminalPublishCount,m=void 0):w(e)},q=t=>{if(void 0!==t.partIndex)return;const r=_,s=I;e.stream.addPart(toMessagePart({type:"text",text:t.text,state:"done",_seq:s,data:S(s)})),t.partIndex=r,_+=1,I+=1},T=()=>{if(!d){d=!0;for(const e of g)q(e)}},$=e=>{const t={text:e};g.push(t),d&&q(t)},E=(t,r)=>{for(const s of t){const t=v.get(s.url);if(t){const r=mergeSearchSource(t,s);if(r.title===t.title&&r.snippet===t.snippet)continue;const o={...r,partIndex:t.partIndex,displaySeq:t.displaySeq,toolUseId:t.toolUseId};e.stream.replacePart(t.partIndex,toMessagePart({type:"source",url:o.url,...o.title?{title:o.title}:{},...o.snippet?{snippet:o.snippet}:{},tool_use_id:o.toolUseId,_seq:o.displaySeq,data:S(o.displaySeq)})),v.set(s.url,o);continue}const o={...s,partIndex:_,displaySeq:I,toolUseId:r};e.stream.addPart(toMessagePart({type:"source",url:s.url,...s.title?{title:s.title}:{},...s.snippet?{snippet:s.snippet}:{},tool_use_id:r,_seq:o.displaySeq,data:S(o.displaySeq)})),v.set(s.url,o),_+=1,I+=1,Y.source+=1}},C=(e,t,r,s)=>toMessagePart({type:"thinking",text:t,state:r,_seq:e.displaySeq,_started_at_ms:e.startedAtMs,...void 0!==s?{_duration_ms:s}:{},data:S(e.displaySeq,{started_at_ms:e.startedAtMs,...void 0!==s?{duration_ms:s}:{}})}),M=t=>{T();const r={partIndex:_,displaySeq:I,text:t,publishedText:t,receivedSnapshotCount:1,streamingPublishCount:1,startedAtMs:Date.now(),startedAtMonotonicMs:performance.now()};return e.stream.addPart(C(r,t,"streaming")),_+=1,I+=1,p=r,r},A=t=>{void 0===t.publishTimer&&(t.publishTimer=setTimeout(()=>{t.publishTimer=void 0,te("reasoning_snapshot_flush",()=>{p===t&&(t=>{t.publishedText!==t.text&&(e.stream.replacePart(t.partIndex,C(t,t.text,"streaming")),t.publishedText=t.text,t.streamingPublishCount+=1)})(t)})},200))},O=()=>{const r=p;if(!r)return;void 0!==r.publishTimer&&(clearTimeout(r.publishTimer),r.publishTimer=void 0);const s=Math.max(0,Math.round(performance.now()-r.startedAtMonotonicMs));e.stream.replacePart(r.partIndex,C(r,r.text,"done",s)),p=void 0,logChatLatency(e.logger,"claw.reasoning.settled",e.requestId,t,{reasoning_duration_ms:s,reasoning_chars:r.text.length,reasoning_snapshot_count:r.receivedSnapshotCount,reasoning_streaming_publish_count:r.streamingPublishCount,reasoning_coalesced_snapshot_count:Math.max(0,r.receivedSnapshotCount-r.streamingPublishCount),reasoning_publish_interval_ms:200})},F=e=>{const t=h.indexOf(e);t>=0&&h.splice(t,1)},N=e=>null!=e&&("object"!=typeof e||(Array.isArray(e)?e.length>0:Object.keys(e).length>0)),U=e=>{let t=b.get(e);return t||(t={},b.set(e,t)),t},j=(t,r,s)=>{const o="tool"===t.name&&"tool"!==r?r:t.name,a=!N(t.arguments)&&N(s)?s:t.arguments;o===t.name&&a===t.arguments||(e.stream.replacePart(t.partIndex,toMessagePart({type:"tool_use",id:t.id,name:t.htmlPresentation?.name??o,arguments:t.htmlPresentation?.arguments??a,state:t.state,_seq:t.displaySeq,data:S(t.displaySeq)})),t.name=o,t.arguments=a)},L=(t,r,s,o)=>{const a=f.get(t);if(a)return j(a,r,s),o&&!h.includes(t)&&"streaming"===a.state&&h.push(t),a;T();const n=b.get(t),i="tool"!==r?r:n?.name&&"tool"!==n.name?n.name:r,l=N(s)?s:n?.arguments??s,d=((t,r,s)=>{const o=_,a=I;return e.stream.addPart(toMessagePart({type:"tool_use",id:t,name:r,arguments:s,state:"streaming",_seq:a,data:S(a)})),_+=1,I+=1,{partIndex:o,displaySeq:a}})(t,i,l),u={id:t,name:i,arguments:l,partIndex:d.partIndex,displaySeq:d.displaySeq,state:"streaming",itemEventObserved:!0===n?.itemEventObserved,toolStartObserved:!0===n?.toolStartObserved};return f.set(t,u),(o||u.toolStartObserved||u.itemEventObserved)&&(h.includes(t)||"streaming"!==u.state||h.push(t)),n&&Q(u,n),b.delete(t),u},B=(e,t)=>{const r=(e=>f.get(e))(e);if(r)return void 0===t.name&&void 0===t.arguments||j(r,t.name??r.name,t.arguments??r.arguments),t.toolStartObserved&&(r.toolStartObserved=!0),t.itemEventObserved&&(r.itemEventObserved=!0),(t.pending||t.toolStartObserved||t.itemEventObserved)&&!h.includes(r.id)&&"streaming"===r.state&&h.push(r.id),r;const s=U(e);void 0!==t.name&&(s.name=t.name),void 0!==t.arguments&&(s.arguments=t.arguments),t.toolStartObserved&&(s.toolStartObserved=!0),t.itemEventObserved&&(s.itemEventObserved=!0)},H=t=>{"done"!==t.state&&(e.stream.replacePart(t.partIndex,toMessagePart({type:"tool_use",id:t.id,name:t.htmlPresentation?.name??t.name,arguments:t.htmlPresentation?.arguments??t.arguments,state:"done",_seq:t.displaySeq,data:S(t.displaySeq)})),t.state="done")},z=e=>{if(null===e||"object"!=typeof e)return JSON.stringify(e)??String(e);if(Array.isArray(e))return`[${e.map(z).join(",")}]`;return`{${Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${z(t)}`).join(",")}}`},D=(t,r,s)=>{const o=`${s?"1":"0"}:${z(r)}`;if(t.progressSignature===o)return;const a=toMessagePart({type:"custom",kind:"tool_progress",data:{tool_use_id:t.id,content:r,...s?{is_error:!0}:{}}});if(void 0===t.progressPartIndex){const r=_;return e.stream.addPart(a),t.progressPartIndex=r,t.progressSignature=o,void(_+=1)}e.stream.replacePart(t.progressPartIndex,a),t.progressSignature=o},Q=(e,t)=>{if(t.progress?.length)for(const r of t.progress)D(e,r.content,r.isError);t.observedResult&&(D(e,t.observedResult.content,t.observedResult.isError),e.observedResult=t.observedResult,"tool_call"!==e.name&&!isRenderUiToolName(e.name)||t.observedResult.isError||V(e,{text:t.observedResult.content,isError:t.observedResult.isError,rawResult:t.observedResult.rawResult})),(t.progress?.length||t.observedResult)&&(H(e),F(e.id)),!t.observedResult&&t.htmlPayload&&V(e,t.htmlPayload),t.sources?.length&&E(t.sources,e.id)},W=e=>[...new Set([e.mediaUrl,...e.mediaUrls??[]].filter(e=>isNonEmptyString(e)).map(e=>e.trim()).filter(Boolean))],J=(e,t=[])=>{const r=[...new Set([...W(e),...t])];return isNonEmptyString(e.text)&&r.length>0?{text:e.text,media_urls:r}:isNonEmptyString(e.text)?e.text:1===r.length?r[0]:r.length>1?{media_urls:r}:!0===e.isError?"Tool execution failed.":""},K=t=>{for(const r of t)e.stream.addPart(toMessagePart({type:"resource_link",uri:r.uri,name:r.name,...r.mimeType?{mimeType:r.mimeType}:{}})),_+=1},G=t=>{x.add(t);const r=()=>{x.delete(t)};e.onCallbackFailure?t.then(r,r):t.finally(r)},V=(t,r)=>{const s=t.observedResult,o=s?.isError??!0===r.isError,a=s?.rawResult??pickRawResultFromPayload(r),n=o?void 0:staticHtmlProjectionOf(t.name,t.arguments,a);if(t.durableUploadFilesEmitted&&(!n||t.staticHtmlResultEmitted))return;e.logger.info?.(`[im-sink] schedule tool artifact enrichment requestId=${e.requestId} toolUseId=${t.id} name=${t.name}`);const i=(async()=>{let s=[];try{s=await resolveToolArtifactLinks({toolCallId:t.id,toolName:t.name,rawResult:a,rawText:"string"==typeof r.text?r.text:void 0,params:asToolParams(t.arguments),cwd:sessionWorkspaceDir(e.sessionKey),payloadMediaUrls:W(r)})}catch(r){const s=r instanceof Error?r.message:String(r);if(e.logger.warn?.(`[im-sink] resolveToolArtifactLinks failed requestId=${e.requestId} toolUseId=${t.id} error=${s}`),e.onCallbackFailure?.(r),e.onCallbackFailure)throw r;return}if(n&&!s.some(e=>e.uri===n.result.artifact.uri)){const e=n.result.artifact;s.push({uri:e.uri,name:e.title,mimeType:e.mimeType})}0!==s.length?(e.logger.info?.(`[im-sink] tool artifact enrichment resolved ${s.length} link(s) requestId=${e.requestId} toolUseId=${t.id}`),await new Promise((o,a)=>{const i=e.callbackQueue.enqueueSync(()=>{try{if(e.abortSignal.aborted||e.stream.isTerminated)return;const o=s.map(e=>e.uri);t.artifactMediaUrls=o;const a=t.observedResult;D(t,J(a?{text:a.content,isError:a.isError}:r,o),a?.isError??!0===r.isError),((t,r,s,o)=>{const a=r.length>0&&!t.durableUploadFilesEmitted,n=!s&&void 0!==o&&!t.staticHtmlResultEmitted;(a||n)&&(n&&(t.htmlPresentation={name:"render_ui",arguments:o.arguments},e.stream.replacePart(t.partIndex,toMessagePart({type:"tool_use",id:t.id,...t.htmlPresentation,state:t.state,_seq:t.displaySeq,data:S(t.displaySeq)}))),e.stream.appendToolResult(t.id,[...n?[{type:"text",text:JSON.stringify(o.result)}]:[],...a?r.map(e=>({type:"resource_link",uri:e.uri,name:e.name,...e.mimeType?{mimeType:e.mimeType}:{}})):[]],s),_+=1,n&&(t.staticHtmlResultEmitted=!0),a&&(t.durableUploadFilesEmitted=!0,K(r)))})(t,s,a?.isError??!0===r.isError,n)}catch(r){const s=r instanceof Error?r.message:String(r);e.logger.warn?.(`[im-sink] tool artifact enrichment apply failed requestId=${e.requestId} toolUseId=${t.id} error=${s}`),e.onCallbackFailure?.(r),e.onCallbackFailure&&a(r)}finally{o()}});!1===i&&e.onCallbackFailure&&e.callbackQueue.waitForIdle().then(o,a)})):e.logger.debug?.(`[im-sink] tool artifact enrichment found no links requestId=${e.requestId} toolUseId=${t.id} name=${t.name}`)})().catch(r=>{const s=r instanceof Error?r.message:String(r);if(e.logger.warn?.(`[im-sink] tool artifact enrichment failed requestId=${e.requestId} toolUseId=${t.id} error=${s}`),e.onCallbackFailure?.(r),e.onCallbackFailure)throw r});G(i)},X=(e,t,r)=>B(e,{name:t,arguments:r}),Y={tool:0,block:0,final:0,source:0};let Z,ee=!1;const te=(t,r)=>{e.callbackQueue.enqueueSync(()=>{if((t=>e.abortSignal.aborted?(e.logger.debug?.(`[im-sink] ${t} ignored after abort requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId}`),!1):e.stream.isTerminated?(e.logger.debug?.(`[im-sink] ${t} ignored after stream_terminated requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId}`),!1):!ee||(e.logger.debug?.(`[im-sink] ${t} ignored after mark_complete requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId}`),!1))(t))try{r()}catch(r){const s=r instanceof Error?r.message:String(r);e.logger.warn?.(`[im-sink] ${t} mapping failed requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId} error=${s}`),e.onCallbackFailure?.(r)}})},re={sendToolResult:t=>(te("tool_progress",()=>{const r=resolveRuntimeToolCallId(t),s=resolveRuntimeToolName(t),o=resolveRuntimeToolArguments(t),a=J(t),n=!0===t.isError;let i;if(r){if(i=X(r,s,o),!i){const e=U(r);if(s&&(e.name=s),N(o)&&(e.arguments=o),e.progress=[...e.progress??[],{content:a,isError:n}],"tool_call"===s||isRenderUiToolName(s??"")){const r=pickRawResultFromPayload(t);(n||void 0!==r)&&(e.htmlPayload=!n&&staticHtmlResultOf(r)?t:void 0)}return void(Y.tool+=1)}i&&(Y.tool+=1,i.observedResult||D(i,a,n),H(i),F(i.id),V(i,t))}else e.logger.debug?.(`[im-sink] unattributed tool progress ignored requestId=${e.requestId} channel=${e.channelId} tool=${s??"unknown"} pending=${h.length}`)}),!0),sendBlockReply:e=>(te("block_reply",()=>{Y.block+=1,isNonEmptyString(e.text)&&(Z=!0!==e.isError?void 0:e.text)}),!0),sendFinalReply:t=>(te("final_reply",()=>{var r;(Y.final+=1,!0!==t.isError)?((t=>{const r=W(t).filter(e=>!R.has(e));if(0===r.length)return;for(const e of r)R.add(e);const s=(async()=>{let t=[];try{t=await resolveToolArtifactLinks({toolCallId:`final:${e.runId??e.requestId}`,toolName:"final_reply_media",payloadMediaUrls:r})}catch(t){for(const e of r)R.delete(e);if(e.logger.warn?.(`[im-sink] final media enrichment failed requestId=${e.requestId} error=${t instanceof Error?t.message:String(t)}`),e.onCallbackFailure?.(t),e.onCallbackFailure)throw t;return}if(0!==t.length)await new Promise((r,s)=>{!1===e.callbackQueue.enqueueSync(()=>{try{if(e.abortSignal.aborted||e.stream.isTerminated)return;K(t)}catch(t){e.logger.warn?.(`[im-sink] final media enrichment apply failed requestId=${e.requestId} error=${t instanceof Error?t.message:String(t)}`),e.onCallbackFailure?.(t),e.onCallbackFailure&&s(t)}finally{r()}})&&e.onCallbackFailure&&e.callbackQueue.waitForIdle().then(r,s)});else for(const e of r)R.delete(e)})();G(s)})(t),isNonEmptyString(t.text)&&(Z=void 0,l||(r=t.text,i="",n+=r,k(n),$(r),l=!0))):Z=t.text}),!0),waitForIdle:async()=>{for(let t=0;(e.onCallbackFailure||t<16)&&(await e.callbackQueue.waitForIdle(),0!==x.size);t++)e.onCallbackFailure?await Promise.all([...x]):await Promise.allSettled([...x]);await e.callbackQueue.waitForIdle();const t=takeFinalizeAttachments(e.sessionKey);t.length>0&&!e.abortSignal.aborted&&!e.stream.isTerminated&&K(t)},getQueuedCounts:()=>({tool:Y.tool,block:Y.block,final:Y.final}),getAccumulatedBody:()=>a.text,getTerminalErrorText:()=>Z,markComplete:r=>{O(),b.size>0&&e.logger.debug?.(`[im-sink] dropping uncommitted lifecycle tool signals requestId=${e.requestId} buffered=${b.size}`),i="",k(n),c.receivedSnapshotCount>0&&logChatLatency(e.logger,"claw.text_preview.settled",e.requestId,t,{text_preview_snapshot_count:c.receivedSnapshotCount,text_preview_streaming_publish_count:c.streamingPublishCount,text_preview_terminal_publish_count:c.terminalPublishCount,text_preview_coalesced_snapshot_count:Math.max(0,c.receivedSnapshotCount-c.streamingPublishCount-c.terminalPublishCount),text_preview_publish_interval_ms:200});for(const t of f.values())try{"success"===r&&isUploadArtifactToolName(t.name)&&!t.durableUploadFilesEmitted&&V(t,{toolCallId:t.id,toolName:t.name}),"success"===r&&H(t),F(t.id)}catch(r){const s=r instanceof Error?r.message:String(r);e.logger.warn?.(`[im-sink] tool finalization failed requestId=${e.requestId} toolUseId=${t.id} error=${s}`)}b.clear(),ee=!0}},se={...e.runId?{runId:e.runId}:{},abortSignal:e.abortSignal,disableBlockStreaming:!0,onAgentRunStart:r=>{e.onAgentRunStart?.(r),logChatLatency(e.logger,"claw.runtime.run_started",e.requestId,t),e.logger.info?.(`[im-sink] run_start requestId=${e.requestId} runId=${r} channel=${e.channelId} in_reply_to=${e.inboundMessageId} origin=${e.origin??"im"}`)},onPartialReply:s=>{te("partial",()=>{l||"string"==typeof s.text&&(!r&&s.text.length>0&&(r=!0,logChatLatency(e.logger,"claw.model.first_delta",e.requestId,t)),i=s.text,(e=>{const t=m;if(!t){if(a.text===e)return;return w(e),void(m={targetBody:e,receivedSnapshotCount:1,streamingPublishCount:1,terminalPublishCount:0})}t.targetBody!==e&&(t.targetBody=e,t.receivedSnapshotCount+=1,P(t))})(n+i))})},onReasoningStream:e=>{te("reasoning",()=>{if(!isNonEmptyString(e.text))return;const t=e.text,r=p??M(t);t!==r.text&&(r.text.startsWith(t)||(t.startsWith(r.text)?(r.text=t,r.receivedSnapshotCount+=1,A(r)):(O(),M(t))))})},onReasoningEnd:()=>{te("reasoning_end",()=>{O()})},onAssistantMessageStart:()=>{te("assistant_message_start",()=>{i="",l=!1,k(n),e.logger.debug?.(`[im-sink] assistant_message_start requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId}`)})},onToolStart:r=>{te("tool_start",()=>{const o="string"==typeof r.phase?r.phase:"start",a=resolveRuntimeToolName(r)??"tool",n=resolveRuntimeToolCallId(r),i=resolveRuntimeToolArguments(r);"update"!==o?(n&&s.set(n,Date.now()),logChatLatency(e.logger,"claw.tool.start",e.requestId,t,{tool:a}),n&&B(n,{name:a,arguments:i,toolStartObserved:!0,pending:!0})):n&&B(n,{name:a,arguments:i,pending:!0})})},onItemEvent:e=>{te("item_event",()=>{const t="string"==typeof e.kind?e.kind.toLowerCase():"";if(t&&"tool"!==t)return;"string"==typeof e.phase&&e.phase.toLowerCase();const r=resolveRuntimeToolCallId(e)??("string"==typeof e.itemId&&e.itemId.trim()?e.itemId.trim():void 0),s=resolveRuntimeToolName(e)??("string"==typeof e.title&&e.title.trim()?e.title.trim():void 0);r&&s&&B(r,{name:s,itemEventObserved:!0,pending:!0})})}},oe={add(t){if(e.stream.isTerminated)return;const r=_;return e.stream.addPart(t),_+=1,r}},ae={add:e=>oe.add(e),replace:(t,r)=>!e.stream.isTerminated&&(e.stream.replacePart(t,r),!0)};return{dispatcher:re,replyOptions:se,commitAssistantMessage:t=>{te("assistant_message_commit",()=>{if(u.has(t.key))return;u.add(t.key),l=!0,Z=void 0,i="";const r=t.segments.filter(e=>"text"===e.type).map(e=>e.text).join("");n+=r,k(n);for(const e of t.segments)"text"!==e.type?L(e.id,e.name,e.arguments,!0):$(e.text);if(void 0!==t.executedModel||void 0!==y){const r=toMessagePart({type:"custom",kind:"execution_model",data:{executed_model:t.executedModel??""}});void 0===y?(e.stream.addPart(r),y=_++):e.stream.replacePart(y,r)}})},observeToolResult:r=>{te("tool_result_observation",()=>{const a=r.toolCallId.trim(),n=r.toolName.trim();if(!a||!n)return;const i=!o.has(a);if(i){o.add(a);const i=s.get(a);logChatLatency(e.logger,"claw.tool.result",e.requestId,t,{tool:n,tool_elapsed_ms:void 0===i?void 0:Math.max(0,Date.now()-i),outcome:r.isError?"error":"success",...r.isError?{error:summarizeObservedToolError(r.rawResult)??"error"}:{}})}if(e.persistObservedToolResults&&i){const e=observedToolResultText(r.rawResult)??("tool_call"===n||isRenderUiToolName(n)?"":void 0);if(void 0!==e){const t=X(a,n);if(t)D(t,J({text:e,isError:r.isError},t.artifactMediaUrls),r.isError),t.observedResult={content:e,isError:r.isError,rawResult:r.rawResult},H(t),F(t.id),"tool_call"!==t.name&&!isRenderUiToolName(t.name)||r.isError||V(t,{text:e,isError:r.isError,rawResult:r.rawResult});else{const t=U(a);t.name??=n,t.observedResult={content:e,isError:r.isError,rawResult:r.rawResult}}}}const l=searchSourceProvider(r.rawResult)??"unknown";let d=0;try{const t=extractSearchSources({toolName:n,rawResult:r.rawResult,isError:r.isError});if(d=t.length,0===d)return;const s=X(a,n);if(s)E(t,s.id);else{const e=U(a);e.name??=n,e.sources=((e,t)=>{if(!e?.length&&!t?.length)return;const r=[],s=new Map;for(const o of[...e??[],...t??[]]){const e=s.get(o.url);void 0===e?(s.set(o.url,r.length),r.push(o)):r[e]=mergeSearchSource(r[e],o)}return r})(e.sources,t)}e.logger.debug?.(`[im-sink] search source projection requestId=${e.requestId} tool=${n} provider=${l} source_count=${d}`)}catch{e.logger.warn?.(`[im-sink] search source projection ignored requestId=${e.requestId} tool=${n} provider=${l} source_count=${d}`)}})},getSourceCount:()=>Y.source,approvalParts:oe,questionParts:ae}}
|
package/dist/tool-activity.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const record=e=>{if("string"==typeof e&&e.length<=65536)try{e=JSON.parse(e)}catch{return{}}return null===e||"object"!=typeof e||Array.isArray(e)?{}:e},text=e=>"string"==typeof e?e:"",short=e=>{const t=e.replace(/[\u0000-\u001f\u007f]/g," ").trim(),n=Array.from(t);return n.length<=180?t:`${n.slice(0,180).join("")}…`},action=(e,t="")=>{const n=short(t);return n?{kind:e,subject:n}:{kind:e}},filename=e=>text(e).replaceAll("\\","/").split("/").at(-1)??"",toolName=e=>text(e).split(":").at(-1)??"";export function toolActivity(e,t){let n,s=toolName(e),i=record(t);for(let e=0;e<3&&"tool_call"===s;e++)s=toolName(i.id??i.name),i=record(i.args??i.arguments??i.input);switch(s){case"exec":case"exec_command":n=commandActions(text(i.command??i.cmd));break;case"beeos_search":case"web_search":case"search_web":n=[action("search",text(i.query))];break;case"beeos_fetch":case"web_fetch":{let e="";try{const t=new URL(text(i.url));"https:"!==t.protocol&&"http:"!==t.protocol||(e=t.hostname)}catch{}n=[action("page",e)];break}case"read":case"read_file":n=[action("read",filename(i.fileName??i.file_path??i.path))];break;case"write":case"edit":case"write_file":case"edit_file":case"beeos_upload_file":n=Array.isArray(i.paths)&&i.paths.length>0?i.paths.slice(0,5).map(e=>action("save",filename(e))):[action("save",filename(i.fileName??i.file_path??i.path))];break;case"tool_search":{const e=Array.isArray(i.queries)?i.queries:[],t=e.length>0&&e.every(e=>{const t=text(record(e).query).toLowerCase();return/\b(image|poster|graphic)\b/.test(t)&&/\b(generate|create|design)\b/.test(t)&&!/\b(not|never|without)\b/.test(t)});n=[action(t?"find_design_tools":"find_tools")];break}case"image_generate":{const e=text(i.prompt).trim(),t=/^(?:制作|生成|设计)[^不无非。!?\n]{0,60}海报[。!!]?$/i.test(e)||/^(?:create|generate|design) (?:a |an )?poster[.!]?$/i.test(e);n=[action(t?"generate_poster":"generate_image")];break}default:n=[action("other")]}return{schema_version:1,source:"tool_arguments",actions:n}}function commandActions(e){const t=[action("command")];if(!e||e.length>8192)return t;if(/^(?:\/(?:usr\/(?:local\/)?)?bin\/)?python3[ \t]+-c[ \t]+(["'])import PIL; print\(PIL\.__version__\)\1$/.test(e.trim()))return[action("check_rendering")];if(/[$`\\(){}<>]/.test(e))return t;const n=/"[^"\n]*"|'[^'\n]*'|&&|\|\||[;|\n]|[^\s"';|&]+/g,s=[],i=[];let r=[],a=0,c="";for(const o of e.matchAll(n)){const n=e.slice(a,o.index);if(n.trim())return t;const l=o[0],h=[";","|","&&","||","\n"].includes(l);if(!h&&r.length>0&&0===n.length)return t;if(a=o.index+l.length,h){if(!r.length)return t;s.push(r),i.push(c),r=[],c=l}else r.push(l.startsWith('"')||l.startsWith("'")?l.slice(1,-1):l)}if(e.slice(a).trim()||!r.length&&["&&","||","|"].includes(c))return t;r.length&&(s.push(r),i.push(c));const o=[],l=new Set(["rsvg-convert","inkscape","chromium","chromium-browser","google-chrome","convert","magick","python3"]);let h=!1;for(const[e,n]of s.entries()){const s=h&&"|"===i[e];h=!1;const[r,...a]=n,c=r.replace(/^\/(?:usr\/(?:local\/)?)?bin\/([A-Za-z0-9_.-]+)$/,"$1");let u;if("echo"!==c||1!==a.length||!["---","DONE"].includes(a[0])){if("which"===c&&a.length>0&&a.every(e=>l.has(e))||"command"===c&&2===a.length&&"-v"===a[0]&&l.has(a[1])||"convert"===c&&1===a.length&&"-version"===a[0])u=action("check_rendering");else if("google-chrome"===c&&chromeScreenshot(a))u=action("generate_image",filename(a.find(e=>e.startsWith("--screenshot=")).slice(13)));else if("identify"===c&&1===a.length&&/^(?:[A-Za-z0-9_./-]+\/)?[A-Za-z0-9_-][A-Za-z0-9_.-]*\.(?:png|jpe?g|webp|gif)$/.test(a[0]))u=action("read",filename(a[0]));else if("fc-list"===c&&(0===a.length||":lang=zh"===a[0]&&a.slice(1).every(e=>["family","style","fullname"].includes(e))))u=action(0===a.length?"list_fonts":"list_chinese_fonts"),h=!0;else{if("sort"===c&&s&&1===a.length&&"-u"===a[0]){h=!0;continue}if("ls"===c&&a.filter(e=>!e.startsWith("-")).length<=1&&a.every(e=>!e.startsWith("-")||/^-[lah]+$/.test(e)))u=action("list_files");else{if("head"===c&&1===a.length&&/^-\d+$/.test(a[0])&&o.length>0&&"|"===i[e]){h=s;continue}{const e="python3"===c&&"-m"===a[0]&&"pip"===a[1]?["pip",...a.slice(2)]:"uv"===c&&"pip"===a[0]?a:[c,...a];if("pip"!==e[0]&&"pip3"!==e[0]||"install"!==e[1]){if(!["python","python3","node"].includes(c)||1!==a.length||!/^(?:[A-Za-z0-9_./-]+\/)?[A-Za-z0-9_-][A-Za-z0-9_.-]*\.(?:py|js|mjs)$/.test(a[0]))return t;u=action("run_script",filename(a[0]))}else{const n=e.slice(2).filter(e=>!["--quiet","-q","--upgrade","-U","--user","--no-cache-dir"].includes(e));if(!n.length||n.length>6||n.some(e=>!/^[A-Za-z0-9][A-Za-z0-9_.-]{0,79}(?:==[A-Za-z0-9_.-]{1,40})?$/.test(e)))return t;u=action("install",n.join(", "))}}}}o.some(e=>e.kind===u.kind&&e.subject===u.subject)||o.push(u)}}return o.length?o:t}function chromeScreenshot(e){const t=e.map(e=>e.startsWith("--")?e.split("=",1)[0]:"input");return new Set(t).size===t.length&&e.includes("--headless=new")&&t.includes("--screenshot")&&t.includes("input")&&e.every(e=>["--headless=new","--no-sandbox","--disable-gpu","--hide-scrollbars"].includes(e)||/^--force-device-scale-factor=[1-4]$/.test(e)||/^--window-size=[1-9]\d{0,3},[1-9]\d{0,3}$/.test(e)||/^--screenshot=(?:[A-Za-z0-9_./-]+\/)?[A-Za-z0-9_-][A-Za-z0-9_.-]*\.png$/.test(e)||/^file:\/\/\/[A-Za-z0-9_./-]+\.(?:html?|svg)$/.test(e))}
|
|
1
|
+
const detailKinds={search:"query",page:"website",read:"file",save:"file",run_script:"file",generate_image:"file",generate_document:"document_title"},record=e=>{if("string"==typeof e&&e.length<=65536)try{e=JSON.parse(e)}catch{return{}}return null===e||"object"!=typeof e||Array.isArray(e)?{}:e},text=e=>"string"==typeof e?e:"",short=e=>{const t=e.replace(/[\u0000-\u001f\u007f]/g," ").trim(),n=Array.from(t);return n.length<=180?t:`${n.slice(0,180).join("")}…`},action=(e,t="")=>{const n=short(t);return n?{kind:e,subject:n}:{kind:e}},filename=e=>text(e).replaceAll("\\","/").split("/").at(-1)??"",toolName=e=>text(e).split(":").at(-1)??"";export function toolActivity(e,t){let n,s=toolName(e),i=record(t);for(let e=0;e<3&&"tool_call"===s;e++)s=toolName(i.id??i.name),i=record(i.args??i.arguments??i.input);switch(s){case"exec":case"exec_command":n=commandActions(text(i.command??i.cmd));break;case"beeos_search":case"web_search":case"search_web":n=[action("search",text(i.query))];break;case"beeos_fetch":case"web_fetch":{let e="";try{const t=new URL(text(i.url));"https:"!==t.protocol&&"http:"!==t.protocol||(e=t.hostname)}catch{}n=[action("page",e)];break}case"read":case"read_file":n=[action("read",filename(i.fileName??i.file_path??i.path))];break;case"write":case"edit":case"write_file":case"edit_file":case"beeos_upload_file":n=Array.isArray(i.paths)&&i.paths.length>0?i.paths.slice(0,5).map(e=>action("save",filename(e))):[action("save",filename(i.fileName??i.file_path??i.path))];break;case"render_ui":n=[action("generate_document",text(i.title))];break;case"tool_search":{const e=Array.isArray(i.queries)?i.queries:[],t=e.length>0&&e.every(e=>{const t=text(record(e).query).toLowerCase();return/\b(image|poster|graphic)\b/.test(t)&&/\b(generate|create|design)\b/.test(t)&&!/\b(not|never|without)\b/.test(t)});n=[action(t?"find_design_tools":"find_tools")];break}case"image_generate":{const e=text(i.prompt).trim(),t=/^(?:制作|生成|设计)[^不无非。!?\n]{0,60}海报[。!!]?$/i.test(e)||/^(?:create|generate|design) (?:a |an )?poster[.!]?$/i.test(e);n=[action(t?"generate_poster":"generate_image")];break}default:n=[action("other")]}const r=[];for(const e of n){const t=detailKinds[e.kind];if(t&&e.subject&&r.push({kind:t,value:e.subject}),5===r.length)break}return{schema_version:1,source:"tool_arguments",actions:n,...r.length?{details:r}:{}}}function commandActions(e){const t=[action("command")];if(!e||e.length>8192)return t;if(/^(?:\/(?:usr\/(?:local\/)?)?bin\/)?python3[ \t]+-c[ \t]+(["'])import PIL; print\(PIL\.__version__\)\1$/.test(e.trim()))return[action("check_rendering")];if(/[$`\\(){}<>]/.test(e))return t;const n=/"[^"\n]*"|'[^'\n]*'|&&|\|\||[;|\n]|[^\s"';|&]+/g,s=[],i=[];let r=[],a=0,c="";for(const o of e.matchAll(n)){const n=e.slice(a,o.index);if(n.trim())return t;const l=o[0],h=[";","|","&&","||","\n"].includes(l);if(!h&&r.length>0&&0===n.length)return t;if(a=o.index+l.length,h){if(!r.length)return t;s.push(r),i.push(c),r=[],c=l}else r.push(l.startsWith('"')||l.startsWith("'")?l.slice(1,-1):l)}if(e.slice(a).trim()||!r.length&&["&&","||","|"].includes(c))return t;r.length&&(s.push(r),i.push(c));const o=[],l=new Set(["rsvg-convert","inkscape","chromium","chromium-browser","google-chrome","convert","magick","python3"]);let h=!1;for(const[e,n]of s.entries()){const s=h&&"|"===i[e];h=!1;const[r,...a]=n,c=r.replace(/^\/(?:usr\/(?:local\/)?)?bin\/([A-Za-z0-9_.-]+)$/,"$1");let u;if("echo"!==c||1!==a.length||!["---","DONE"].includes(a[0])){if("which"===c&&a.length>0&&a.every(e=>l.has(e))||"command"===c&&2===a.length&&"-v"===a[0]&&l.has(a[1])||"convert"===c&&1===a.length&&"-version"===a[0])u=action("check_rendering");else if("google-chrome"===c&&chromeScreenshot(a))u=action("generate_image",filename(a.find(e=>e.startsWith("--screenshot=")).slice(13)));else if("identify"===c&&1===a.length&&/^(?:[A-Za-z0-9_./-]+\/)?[A-Za-z0-9_-][A-Za-z0-9_.-]*\.(?:png|jpe?g|webp|gif)$/.test(a[0]))u=action("read",filename(a[0]));else if("fc-list"===c&&(0===a.length||":lang=zh"===a[0]&&a.slice(1).every(e=>["family","style","fullname"].includes(e))))u=action(0===a.length?"list_fonts":"list_chinese_fonts"),h=!0;else{if("sort"===c&&s&&1===a.length&&"-u"===a[0]){h=!0;continue}if("ls"===c&&a.filter(e=>!e.startsWith("-")).length<=1&&a.every(e=>!e.startsWith("-")||/^-[lah]+$/.test(e)))u=action("list_files");else{if("head"===c&&1===a.length&&/^-\d+$/.test(a[0])&&o.length>0&&"|"===i[e]){h=s;continue}{const e="python3"===c&&"-m"===a[0]&&"pip"===a[1]?["pip",...a.slice(2)]:"uv"===c&&"pip"===a[0]?a:[c,...a];if("pip"!==e[0]&&"pip3"!==e[0]||"install"!==e[1]){if(!["python","python3","node"].includes(c)||1!==a.length||!/^(?:[A-Za-z0-9_./-]+\/)?[A-Za-z0-9_-][A-Za-z0-9_.-]*\.(?:py|js|mjs)$/.test(a[0]))return t;u=action("run_script",filename(a[0]))}else{const n=e.slice(2).filter(e=>!["--quiet","-q","--upgrade","-U","--user","--no-cache-dir"].includes(e));if(!n.length||n.length>6||n.some(e=>!/^[A-Za-z0-9][A-Za-z0-9_.-]{0,79}(?:==[A-Za-z0-9_.-]{1,40})?$/.test(e)))return t;u=action("install",n.join(", "))}}}}o.some(e=>e.kind===u.kind&&e.subject===u.subject)||o.push(u)}}return o.length?o:t}function chromeScreenshot(e){const t=e.map(e=>e.startsWith("--")?e.split("=",1)[0]:"input");return new Set(t).size===t.length&&e.includes("--headless=new")&&t.includes("--screenshot")&&t.includes("input")&&e.every(e=>["--headless=new","--no-sandbox","--disable-gpu","--hide-scrollbars"].includes(e)||/^--force-device-scale-factor=[1-4]$/.test(e)||/^--window-size=[1-9]\d{0,3},[1-9]\d{0,3}$/.test(e)||/^--screenshot=(?:[A-Za-z0-9_./-]+\/)?[A-Za-z0-9_-][A-Za-z0-9_.-]*\.png$/.test(e)||/^file:\/\/\/[A-Za-z0-9_./-]+\.(?:html?|svg)$/.test(e))}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beeos-claw",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.80",
|
|
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>",
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
"brace-expansion": ">=5.0.9",
|
|
91
91
|
"@beeos-ai/beeos-types": "$@beeos-ai/beeos-types"
|
|
92
92
|
},
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "87d681df5019200469c840e01ed7ecbce29e6b81"
|
|
94
94
|
}
|