beeos-claw 0.6.54-staging.0 → 0.6.54-staging.2
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{toMessagePart}from"../message-client-types.js";import{resolveToolArtifactLinks}from"../upload/tool-artifact-enrichment.js";import{resolveRuntimeToolArguments,resolveRuntimeToolCallId,resolveRuntimeToolName}from"./tool-envelope-metadata.js";import{extractSearchSources,mergeSearchSource,searchSourceProvider}from"./search-source-extractor.js";const 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}}export function createImReplySink(e){const t={text:""};let r="",n="",s=!1,o=!1;const a=new Set,i=[];let l,d="",u="";const m=new Map,g=new Map,c=[],p=[],f=new Map,v=new Map;let y=0,h=1;const I=new Set,b=r=>{r!==t.text&&(r.startsWith(t.text)?e.stream.appendBody(r.slice(t.text.length)):e.stream.setBody(r),t.text=r)},S=t=>{if(void 0!==t.partIndex)return;const r=y,n=h;e.stream.addPart(toMessagePart({type:"text",text:t.text,state:"done",_seq:n})),t.partIndex=r,y+=1,h+=1},$=e=>{const t={text:e};i.push(t),o&&S(t)},q=t=>{for(const r of t){const t=v.get(r.url);if(t){const n=mergeSearchSource(t,r);if(n.title===t.title&&n.snippet===t.snippet)continue;const s={...n,partIndex:t.partIndex,displaySeq:t.displaySeq};e.stream.replacePart(t.partIndex,toMessagePart({type:"source",url:s.url,...s.title?{title:s.title}:{},...s.snippet?{snippet:s.snippet}:{},_seq:s.displaySeq})),v.set(r.url,s);continue}const n={...r,partIndex:y,displaySeq:h};e.stream.addPart(toMessagePart({type:"source",url:r.url,...r.title?{title:r.title}:{},...r.snippet?{snippet:r.snippet}:{},_seq:n.displaySeq})),v.set(r.url,n),y+=1,h+=1,D.source+=1}},x=e=>{const t=c.indexOf(e);t>=0&&c.splice(t,1)},k=e=>{const t=e?c.filter(t=>m.get(t)?.name===e):c;return 1===t.length?t[0]:void 0},_=e=>{const t=p.map((e,t)=>({hint:e,index:t})).filter(({hint:t})=>!e||t.name===e);if(1!==t.length)return;const[{hint:r,index:n}]=t;return p.splice(n,1),r},E=(e,t)=>{if(g.set(e,t),e===t)return;const r=f.get(e);if(!r)return;const n=O(t);P(n,r),f.delete(e);const s=m.get(t);s&&(F(s,n),f.delete(t))},R=e=>g.get(e)??e,w=e=>null!=e&&("object"!=typeof e||(Array.isArray(e)?e.length>0:Object.keys(e).length>0)),O=e=>{let t=f.get(e);return t||(t={},f.set(e,t)),t},T=(e,t)=>{if(!e?.length&&!t?.length)return;const r=[],n=new Map;for(const s of[...e??[],...t??[]]){const e=n.get(s.url);void 0===e?(n.set(s.url,r.length),r.push(s)):r[e]=mergeSearchSource(r[e],s)}return r},P=(e,t)=>{e.name??=t.name,e.arguments??=t.arguments,t.toolStartObserved&&(e.toolStartObserved=!0),t.itemEventObserved&&(e.itemEventObserved=!0),t.progress?.length&&(e.progress=[...e.progress??[],...t.progress]),e.sources=T(e.sources,t.sources)},M=(t,r,n)=>{const s="tool"===t.name&&"tool"!==r?r:t.name,o=!w(t.arguments)&&w(n)?n:t.arguments;s===t.name&&o===t.arguments||(e.stream.replacePart(t.partIndex,toMessagePart({type:"tool_use",id:t.id,name:s,arguments:o,state:t.state,_seq:t.displaySeq})),t.name=s,t.arguments=o)},A=(t,r,n,s)=>{const a=m.get(t);if(a)return M(a,r,n),s&&!c.includes(t)&&"streaming"===a.state&&c.push(t),a;(()=>{if(!o){o=!0;for(const e of i)S(e)}})();const l=f.get(t),d="tool"!==r?r:l?.name&&"tool"!==l.name?l.name:r,u=w(n)?n:l?.arguments??n,g=((t,r,n)=>{const s=y,o=h;return e.stream.addPart(toMessagePart({type:"tool_use",id:t,name:r,arguments:n,state:"streaming",_seq:o})),y+=1,h+=1,{partIndex:s,displaySeq:o}})(t,d,u),p={id:t,name:d,arguments:u,partIndex:g.partIndex,displaySeq:g.displaySeq,state:"streaming",itemEventObserved:!0===l?.itemEventObserved,toolStartObserved:!0===l?.toolStartObserved};return m.set(t,p),(s||p.toolStartObserved||p.itemEventObserved)&&(c.includes(t)||"streaming"!==p.state||c.push(t)),l&&F(p,l),f.delete(t),p},N=(e,t)=>{const r=(e=>{const t=g.get(e);return t?m.get(t):m.get(e)})(e);if(r)return void 0===t.name&&void 0===t.arguments||M(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)&&!c.includes(r.id)&&"streaming"===r.state&&c.push(r.id),r;const n=O(e);void 0!==t.name&&(n.name=t.name),void 0!==t.arguments&&(n.arguments=t.arguments),t.toolStartObserved&&(n.toolStartObserved=!0),t.itemEventObserved&&(n.itemEventObserved=!0)},j=t=>{"done"!==t.state&&(e.stream.replacePart(t.partIndex,toMessagePart({type:"tool_use",id:t.id,name:t.name,arguments:t.arguments,state:"done",_seq:t.displaySeq})),t.state="done")},U=e=>{if(null===e||"object"!=typeof e)return JSON.stringify(e)??String(e);if(Array.isArray(e))return`[${e.map(U).join(",")}]`;return`{${Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${U(t)}`).join(",")}}`},C=(t,r,n)=>{const s=`${n?"1":"0"}:${U(r)}`;if(t.progressSignature===s)return;const o=toMessagePart({type:"custom",kind:"tool_progress",data:{tool_use_id:t.id,content:r,...n?{is_error:!0}:{}}});if(void 0===t.progressPartIndex){const r=y;return e.stream.addPart(o),t.progressPartIndex=r,t.progressSignature=s,void(y+=1)}e.stream.replacePart(t.progressPartIndex,o),t.progressSignature=s},F=(e,t)=>{if(t.progress?.length){for(const r of t.progress)C(e,r.content,r.isError);j(e),x(e.id)}t.sources?.length&&q(t.sources)},B=e=>[e.mediaUrl,...e.mediaUrls??[]].filter(e=>isNonEmptyString(e)),L=(e,t=[])=>{const r=[...new Set([...B(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.":""},Q=(t,r)=>{if(t.durableUploadFilesEmitted)return;e.logger.info?.(`[im-sink] schedule tool artifact enrichment requestId=${e.requestId} toolUseId=${t.id} name=${t.name}`);const n=pickRawResultFromPayload(r),s=(async()=>{let s=[];try{s=await resolveToolArtifactLinks({toolCallId:t.id,toolName:t.name,rawResult:n,rawText:"string"==typeof r.text?r.text:void 0,payloadMediaUrls:B(r)})}catch(r){const n=r instanceof Error?r.message:String(r);return void e.logger.warn?.(`[im-sink] resolveToolArtifactLinks failed requestId=${e.requestId} toolUseId=${t.id} error=${n}`)}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(n=>{e.callbackQueue.enqueueSync(()=>{try{if(e.abortSignal.aborted||e.stream.isTerminated)return;const n=s.map(e=>e.uri);C(t,L(r,n),!0===r.isError),((t,r,n)=>{if(0!==r.length&&!t.durableUploadFilesEmitted){t.durableUploadFilesEmitted=!0,e.stream.appendToolResult(t.id,r.map(e=>({type:"resource_link",uri:e.uri,name:e.name,...e.mimeType?{mimeType:e.mimeType}:{}})),n),y+=1;for(const t of r)e.stream.addPart(toMessagePart({type:"resource_link",uri:t.uri,name:t.name,...t.mimeType?{mimeType:t.mimeType}:{}})),y+=1}})(t,s,!0===r.isError)}catch(r){const n=r instanceof Error?r.message:String(r);e.logger.warn?.(`[im-sink] tool artifact enrichment apply failed requestId=${e.requestId} toolUseId=${t.id} error=${n}`)}finally{n()}})})):e.logger.debug?.(`[im-sink] tool artifact enrichment found no links requestId=${e.requestId} toolUseId=${t.id} name=${t.name}`)})().catch(r=>{const n=r instanceof Error?r.message:String(r);e.logger.warn?.(`[im-sink] tool artifact enrichment failed requestId=${e.requestId} toolUseId=${t.id} error=${n}`)});I.add(s),s.finally(()=>{I.delete(s)})},z=(e,t,r)=>{const n=g.get(e);if(n)return N(n,{name:t,arguments:r});const s=N(e,{name:t,arguments:r});if(s)return s;const o=k(t);if(o)return E(e,o),N(o,{name:t,arguments:r});N(e,{name:t,arguments:r})},W=(e,t)=>{const r=g.get(e);if(r)return N(r,{name:t,itemEventObserved:!0,pending:!0});const n=N(e,{name:t,itemEventObserved:!0,pending:!0});if(n)return n;const s=(e=>{const t=c.filter(t=>{const r=m.get(t);return!(void 0===r||e&&r.name!==e||r.itemEventObserved)});return 1===t.length?t[0]:void 0})(t);if(s)return E(e,s),N(s,{name:t,itemEventObserved:!0,pending:!0});const o=_(t);N(e,{name:t,arguments:o?.arguments,itemEventObserved:!0,pending:!0})},D={tool:0,block:0,final:0,source:0};let J,G=!1;const H=(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):!G||(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 n=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=${n}`)}})};return{dispatcher:{sendToolResult:t=>(H("tool_progress",()=>{const r=resolveRuntimeToolCallId(t),n=resolveRuntimeToolName(t),s=resolveRuntimeToolArguments(t),o=L(t),a=!0===t.isError;let i;if(r){if(i=z(r,n,s),!i){const e=O(r);return n&&(e.name=n),w(s)&&(e.arguments=s),e.progress=[...e.progress??[],{content:o,isError:a}],void(D.tool+=1)}}else{const t=n?k(n):k();if(!t)return _(n),void e.logger.debug?.(`[im-sink] unattributed tool progress ignored requestId=${e.requestId} channel=${e.channelId} tool=${n??"unknown"} pending=${c.length}`);i=N(t,{name:n,arguments:s})}i&&(D.tool+=1,C(i,o,a),j(i),x(i.id),Q(i,t))}),!0),sendBlockReply:e=>(H("block_reply",()=>{D.block+=1,isNonEmptyString(e.text)&&(J=!0!==e.isError?void 0:e.text)}),!0),sendFinalReply:e=>(H("final_reply",()=>{var t;(D.final+=1,isNonEmptyString(e.text))&&(!0!==e.isError?(J=void 0,s||(t=e.text,n="",r+=t,b(r),$(t),s=!0)):J=e.text)}),!0),waitForIdle:async()=>{for(let t=0;t<16;t++){if(await e.callbackQueue.waitForIdle(),0===I.size)return;await Promise.allSettled([...I])}await e.callbackQueue.waitForIdle()},getQueuedCounts:()=>({tool:D.tool,block:D.block,final:D.final}),getAccumulatedBody:()=>t.text,getTerminalErrorText:()=>J,markComplete:t=>{(p.length>0||f.size>0)&&e.logger.debug?.(`[im-sink] dropping uncommitted lifecycle tool signals requestId=${e.requestId} legacy_hints=${p.length} buffered=${f.size}`),n="",b(r);for(const r of m.values())try{"success"===t&&j(r),x(r.id)}catch(t){const n=t instanceof Error?t.message:String(t);e.logger.warn?.(`[im-sink] tool finalization failed requestId=${e.requestId} toolUseId=${r.id} error=${n}`)}p.length=0,f.clear(),G=!0}},replyOptions:{...e.runId?{runId:e.runId}:{},abortSignal:e.abortSignal,disableBlockStreaming:!0,onAgentRunStart:t=>{e.onAgentRunStart?.(t),e.logger.info?.(`[im-sink] run_start requestId=${e.requestId} runId=${t} channel=${e.channelId} in_reply_to=${e.inboundMessageId} origin=${e.origin??"im"}`)},onPartialReply:e=>{H("partial",()=>{"string"==typeof e.text&&(n=e.text,b(r+n))})},onReasoningStream:t=>{H("reasoning",()=>{if(!isNonEmptyString(t.text))return;if(!l&&(l=e.openReasoningStream?.(),!l))return;const r=t.text;""===u&&""!==d&&(l.appendBody("\n"),d+="\n"),r!==u&&(r.startsWith(u)?(l.appendBody(r.slice(u.length)),u=r):u.startsWith(r)||(l.setBody(d+r),u=r))})},onReasoningEnd:()=>{H("reasoning_end",()=>{var t;""!==u&&(t=u,e.stream.appendThinking(t,"done"),y+=1,d+=u,u="")})},onAssistantMessageStart:()=>{H("assistant_message_start",()=>{n="",s=!1,b(r),e.logger.debug?.(`[im-sink] assistant_message_start requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId}`)})},onToolStart:t=>{H("tool_start",()=>{const r="string"==typeof t.phase?t.phase:"start",n=resolveRuntimeToolName(t)??"tool",s=resolveRuntimeToolCallId(t),o=resolveRuntimeToolArguments(t);if("update"===r)return void(s&&N(R(s),{name:n,arguments:o,pending:!0}));if(s){N(s,{name:n,arguments:o,toolStartObserved:!0,pending:!0});const e=k(n);return void(e&&e!==s&&!g.has(s)&&(E(s,e),N(e,{name:n,arguments:o,toolStartObserved:!0,pending:!0})))}const a=(i=n,c.map(e=>m.get(e)).filter(e=>void 0!==e&&(!i||e.name===i)&&e.itemEventObserved));var i;if(1===a.length)return void N(a[0].id,{name:n,arguments:o,toolStartObserved:!0,pending:!0});if(a.length>1)return void e.logger.debug?.(`[im-sink] ambiguous id-less tool start ignored requestId=${e.requestId} channel=${e.channelId} tool=${n} candidates=${a.length}`);const l=[...f.entries()].filter(([,e])=>!e.name||e.name===n||"tool"===e.name);1!==l.length?p.push({name:n,arguments:o}):N(l[0][0],{name:n,arguments:o,toolStartObserved:!0,pending:!0})})},onItemEvent:e=>{H("item_event",()=>{const t="string"==typeof e.kind?e.kind.toLowerCase():"";if(t&&"tool"!==t)return;const r="string"==typeof e.phase?e.phase.toLowerCase():"update",n=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);n&&s&&("update"!==r?W(n,s):N(R(n),{name:s,itemEventObserved:!0,pending:!0}))})}},commitAssistantMessage:e=>{H("assistant_message_commit",()=>{if(a.has(e.key))return;a.add(e.key),s=!0,J=void 0,n="";const t=e.segments.filter(e=>"text"===e.type).map(e=>e.text).join("");r+=t,b(r);for(const t of e.segments)"text"!==t.type?A(t.id,t.name,t.arguments,!0):$(t.text)})},observeToolResult:t=>{H("tool_result_observation",()=>{const r=t.toolCallId.trim(),n=t.toolName.trim();if(!r||!n)return;const s=searchSourceProvider(t.rawResult)??"unknown";let o=0;try{const a=extractSearchSources({toolName:n,rawResult:t.rawResult,isError:t.isError});if(o=a.length,0===o)return;if(z(r,n))q(a);else{const e=O(R(r));e.name??=n,e.sources=T(e.sources,a)}e.logger.debug?.(`[im-sink] search source projection requestId=${e.requestId} tool=${n} provider=${s} source_count=${o}`)}catch{e.logger.warn?.(`[im-sink] search source projection ignored requestId=${e.requestId} tool=${n} provider=${s} source_count=${o}`)}})},getSourceCount:()=>D.source}}
|
|
1
|
+
import{toMessagePart}from"../message-client-types.js";import{resolveToolArtifactLinks}from"../upload/tool-artifact-enrichment.js";import{resolveRuntimeToolArguments,resolveRuntimeToolCallId,resolveRuntimeToolName}from"./tool-envelope-metadata.js";import{extractSearchSources,mergeSearchSource,searchSourceProvider}from"./search-source-extractor.js";const 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}}export function createImReplySink(e){const t={text:""};let r="",n="",s=!1,o=!1;const a=new Set,i=[];let l,d="",u="";const m=new Map,g=new Map,c=[],p=[],f=new Map,v=new Map;let y=0,I=1;const h=new Set,b=r=>{r!==t.text&&(r.startsWith(t.text)?e.stream.appendBody(r.slice(t.text.length)):e.stream.setBody(r),t.text=r)},S=t=>{if(void 0!==t.partIndex)return;const r=y,n=I;e.stream.addPart(toMessagePart({type:"text",text:t.text,state:"done",_seq:n})),t.partIndex=r,y+=1,I+=1},$=e=>{const t={text:e};i.push(t),o&&S(t)},q=(t,r)=>{for(const n of t){const t=v.get(n.url);if(t){const r=mergeSearchSource(t,n);if(r.title===t.title&&r.snippet===t.snippet)continue;const s={...r,partIndex:t.partIndex,displaySeq:t.displaySeq,toolUseId:t.toolUseId};e.stream.replacePart(t.partIndex,toMessagePart({type:"source",url:s.url,...s.title?{title:s.title}:{},...s.snippet?{snippet:s.snippet}:{},tool_use_id:s.toolUseId,_seq:s.displaySeq})),v.set(n.url,s);continue}const s={...n,partIndex:y,displaySeq:I,toolUseId:r};e.stream.addPart(toMessagePart({type:"source",url:n.url,...n.title?{title:n.title}:{},...n.snippet?{snippet:n.snippet}:{},tool_use_id:r,_seq:s.displaySeq})),v.set(n.url,s),y+=1,I+=1,D.source+=1}},x=e=>{const t=c.indexOf(e);t>=0&&c.splice(t,1)},_=e=>{const t=e?c.filter(t=>m.get(t)?.name===e):c;return 1===t.length?t[0]:void 0},k=e=>{const t=p.map((e,t)=>({hint:e,index:t})).filter(({hint:t})=>!e||t.name===e);if(1!==t.length)return;const[{hint:r,index:n}]=t;return p.splice(n,1),r},E=(e,t)=>{if(g.set(e,t),e===t)return;const r=f.get(e);if(!r)return;const n=O(t);P(n,r),f.delete(e);const s=m.get(t);s&&(F(s,n),f.delete(t))},R=e=>g.get(e)??e,w=e=>null!=e&&("object"!=typeof e||(Array.isArray(e)?e.length>0:Object.keys(e).length>0)),O=e=>{let t=f.get(e);return t||(t={},f.set(e,t)),t},T=(e,t)=>{if(!e?.length&&!t?.length)return;const r=[],n=new Map;for(const s of[...e??[],...t??[]]){const e=n.get(s.url);void 0===e?(n.set(s.url,r.length),r.push(s)):r[e]=mergeSearchSource(r[e],s)}return r},P=(e,t)=>{e.name??=t.name,e.arguments??=t.arguments,t.toolStartObserved&&(e.toolStartObserved=!0),t.itemEventObserved&&(e.itemEventObserved=!0),t.progress?.length&&(e.progress=[...e.progress??[],...t.progress]),e.sources=T(e.sources,t.sources)},M=(t,r,n)=>{const s="tool"===t.name&&"tool"!==r?r:t.name,o=!w(t.arguments)&&w(n)?n:t.arguments;s===t.name&&o===t.arguments||(e.stream.replacePart(t.partIndex,toMessagePart({type:"tool_use",id:t.id,name:s,arguments:o,state:t.state,_seq:t.displaySeq})),t.name=s,t.arguments=o)},A=(t,r,n,s)=>{const a=m.get(t);if(a)return M(a,r,n),s&&!c.includes(t)&&"streaming"===a.state&&c.push(t),a;(()=>{if(!o){o=!0;for(const e of i)S(e)}})();const l=f.get(t),d="tool"!==r?r:l?.name&&"tool"!==l.name?l.name:r,u=w(n)?n:l?.arguments??n,g=((t,r,n)=>{const s=y,o=I;return e.stream.addPart(toMessagePart({type:"tool_use",id:t,name:r,arguments:n,state:"streaming",_seq:o})),y+=1,I+=1,{partIndex:s,displaySeq:o}})(t,d,u),p={id:t,name:d,arguments:u,partIndex:g.partIndex,displaySeq:g.displaySeq,state:"streaming",itemEventObserved:!0===l?.itemEventObserved,toolStartObserved:!0===l?.toolStartObserved};return m.set(t,p),(s||p.toolStartObserved||p.itemEventObserved)&&(c.includes(t)||"streaming"!==p.state||c.push(t)),l&&F(p,l),f.delete(t),p},U=(e,t)=>{const r=(e=>{const t=g.get(e);return t?m.get(t):m.get(e)})(e);if(r)return void 0===t.name&&void 0===t.arguments||M(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)&&!c.includes(r.id)&&"streaming"===r.state&&c.push(r.id),r;const n=O(e);void 0!==t.name&&(n.name=t.name),void 0!==t.arguments&&(n.arguments=t.arguments),t.toolStartObserved&&(n.toolStartObserved=!0),t.itemEventObserved&&(n.itemEventObserved=!0)},N=t=>{"done"!==t.state&&(e.stream.replacePart(t.partIndex,toMessagePart({type:"tool_use",id:t.id,name:t.name,arguments:t.arguments,state:"done",_seq:t.displaySeq})),t.state="done")},j=e=>{if(null===e||"object"!=typeof e)return JSON.stringify(e)??String(e);if(Array.isArray(e))return`[${e.map(j).join(",")}]`;return`{${Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${j(t)}`).join(",")}}`},C=(t,r,n)=>{const s=`${n?"1":"0"}:${j(r)}`;if(t.progressSignature===s)return;const o=toMessagePart({type:"custom",kind:"tool_progress",data:{tool_use_id:t.id,content:r,...n?{is_error:!0}:{}}});if(void 0===t.progressPartIndex){const r=y;return e.stream.addPart(o),t.progressPartIndex=r,t.progressSignature=s,void(y+=1)}e.stream.replacePart(t.progressPartIndex,o),t.progressSignature=s},F=(e,t)=>{if(t.progress?.length){for(const r of t.progress)C(e,r.content,r.isError);N(e),x(e.id)}t.sources?.length&&q(t.sources,e.id)},B=e=>[e.mediaUrl,...e.mediaUrls??[]].filter(e=>isNonEmptyString(e)),L=(e,t=[])=>{const r=[...new Set([...B(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.":""},Q=(t,r)=>{if(t.durableUploadFilesEmitted)return;e.logger.info?.(`[im-sink] schedule tool artifact enrichment requestId=${e.requestId} toolUseId=${t.id} name=${t.name}`);const n=pickRawResultFromPayload(r),s=(async()=>{let s=[];try{s=await resolveToolArtifactLinks({toolCallId:t.id,toolName:t.name,rawResult:n,rawText:"string"==typeof r.text?r.text:void 0,payloadMediaUrls:B(r)})}catch(r){const n=r instanceof Error?r.message:String(r);return void e.logger.warn?.(`[im-sink] resolveToolArtifactLinks failed requestId=${e.requestId} toolUseId=${t.id} error=${n}`)}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(n=>{e.callbackQueue.enqueueSync(()=>{try{if(e.abortSignal.aborted||e.stream.isTerminated)return;const n=s.map(e=>e.uri);C(t,L(r,n),!0===r.isError),((t,r,n)=>{if(0!==r.length&&!t.durableUploadFilesEmitted){t.durableUploadFilesEmitted=!0,e.stream.appendToolResult(t.id,r.map(e=>({type:"resource_link",uri:e.uri,name:e.name,...e.mimeType?{mimeType:e.mimeType}:{}})),n),y+=1;for(const t of r)e.stream.addPart(toMessagePart({type:"resource_link",uri:t.uri,name:t.name,...t.mimeType?{mimeType:t.mimeType}:{}})),y+=1}})(t,s,!0===r.isError)}catch(r){const n=r instanceof Error?r.message:String(r);e.logger.warn?.(`[im-sink] tool artifact enrichment apply failed requestId=${e.requestId} toolUseId=${t.id} error=${n}`)}finally{n()}})})):e.logger.debug?.(`[im-sink] tool artifact enrichment found no links requestId=${e.requestId} toolUseId=${t.id} name=${t.name}`)})().catch(r=>{const n=r instanceof Error?r.message:String(r);e.logger.warn?.(`[im-sink] tool artifact enrichment failed requestId=${e.requestId} toolUseId=${t.id} error=${n}`)});h.add(s),s.finally(()=>{h.delete(s)})},z=(e,t,r)=>{const n=g.get(e);if(n)return U(n,{name:t,arguments:r});const s=U(e,{name:t,arguments:r});if(s)return s;const o=_(t);if(o)return E(e,o),U(o,{name:t,arguments:r});U(e,{name:t,arguments:r})},W=(e,t)=>{const r=g.get(e);if(r)return U(r,{name:t,itemEventObserved:!0,pending:!0});const n=U(e,{name:t,itemEventObserved:!0,pending:!0});if(n)return n;const s=(e=>{const t=c.filter(t=>{const r=m.get(t);return!(void 0===r||e&&r.name!==e||r.itemEventObserved)});return 1===t.length?t[0]:void 0})(t);if(s)return E(e,s),U(s,{name:t,itemEventObserved:!0,pending:!0});const o=k(t);U(e,{name:t,arguments:o?.arguments,itemEventObserved:!0,pending:!0})},D={tool:0,block:0,final:0,source:0};let J,G=!1;const H=(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):!G||(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 n=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=${n}`)}})};return{dispatcher:{sendToolResult:t=>(H("tool_progress",()=>{const r=resolveRuntimeToolCallId(t),n=resolveRuntimeToolName(t),s=resolveRuntimeToolArguments(t),o=L(t),a=!0===t.isError;let i;if(r){if(i=z(r,n,s),!i){const e=O(r);return n&&(e.name=n),w(s)&&(e.arguments=s),e.progress=[...e.progress??[],{content:o,isError:a}],void(D.tool+=1)}}else{const t=n?_(n):_();if(!t)return k(n),void e.logger.debug?.(`[im-sink] unattributed tool progress ignored requestId=${e.requestId} channel=${e.channelId} tool=${n??"unknown"} pending=${c.length}`);i=U(t,{name:n,arguments:s})}i&&(D.tool+=1,C(i,o,a),N(i),x(i.id),Q(i,t))}),!0),sendBlockReply:e=>(H("block_reply",()=>{D.block+=1,isNonEmptyString(e.text)&&(J=!0!==e.isError?void 0:e.text)}),!0),sendFinalReply:e=>(H("final_reply",()=>{var t;(D.final+=1,isNonEmptyString(e.text))&&(!0!==e.isError?(J=void 0,s||(t=e.text,n="",r+=t,b(r),$(t),s=!0)):J=e.text)}),!0),waitForIdle:async()=>{for(let t=0;t<16;t++){if(await e.callbackQueue.waitForIdle(),0===h.size)return;await Promise.allSettled([...h])}await e.callbackQueue.waitForIdle()},getQueuedCounts:()=>({tool:D.tool,block:D.block,final:D.final}),getAccumulatedBody:()=>t.text,getTerminalErrorText:()=>J,markComplete:t=>{(p.length>0||f.size>0)&&e.logger.debug?.(`[im-sink] dropping uncommitted lifecycle tool signals requestId=${e.requestId} legacy_hints=${p.length} buffered=${f.size}`),n="",b(r);for(const r of m.values())try{"success"===t&&N(r),x(r.id)}catch(t){const n=t instanceof Error?t.message:String(t);e.logger.warn?.(`[im-sink] tool finalization failed requestId=${e.requestId} toolUseId=${r.id} error=${n}`)}p.length=0,f.clear(),G=!0}},replyOptions:{...e.runId?{runId:e.runId}:{},abortSignal:e.abortSignal,disableBlockStreaming:!0,onAgentRunStart:t=>{e.onAgentRunStart?.(t),e.logger.info?.(`[im-sink] run_start requestId=${e.requestId} runId=${t} channel=${e.channelId} in_reply_to=${e.inboundMessageId} origin=${e.origin??"im"}`)},onPartialReply:e=>{H("partial",()=>{"string"==typeof e.text&&(n=e.text,b(r+n))})},onReasoningStream:t=>{H("reasoning",()=>{if(!isNonEmptyString(t.text))return;if(!l&&(l=e.openReasoningStream?.(),!l))return;const r=t.text;""===u&&""!==d&&(l.appendBody("\n"),d+="\n"),r!==u&&(r.startsWith(u)?(l.appendBody(r.slice(u.length)),u=r):u.startsWith(r)||(l.setBody(d+r),u=r))})},onReasoningEnd:()=>{H("reasoning_end",()=>{var t;""!==u&&(t=u,e.stream.appendThinking(t,"done"),y+=1,d+=u,u="")})},onAssistantMessageStart:()=>{H("assistant_message_start",()=>{n="",s=!1,b(r),e.logger.debug?.(`[im-sink] assistant_message_start requestId=${e.requestId} channel=${e.channelId} in_reply_to=${e.inboundMessageId}`)})},onToolStart:t=>{H("tool_start",()=>{const r="string"==typeof t.phase?t.phase:"start",n=resolveRuntimeToolName(t)??"tool",s=resolveRuntimeToolCallId(t),o=resolveRuntimeToolArguments(t);if("update"===r)return void(s&&U(R(s),{name:n,arguments:o,pending:!0}));if(s){U(s,{name:n,arguments:o,toolStartObserved:!0,pending:!0});const e=_(n);return void(e&&e!==s&&!g.has(s)&&(E(s,e),U(e,{name:n,arguments:o,toolStartObserved:!0,pending:!0})))}const a=(i=n,c.map(e=>m.get(e)).filter(e=>void 0!==e&&(!i||e.name===i)&&e.itemEventObserved));var i;if(1===a.length)return void U(a[0].id,{name:n,arguments:o,toolStartObserved:!0,pending:!0});if(a.length>1)return void e.logger.debug?.(`[im-sink] ambiguous id-less tool start ignored requestId=${e.requestId} channel=${e.channelId} tool=${n} candidates=${a.length}`);const l=[...f.entries()].filter(([,e])=>!e.name||e.name===n||"tool"===e.name);1!==l.length?p.push({name:n,arguments:o}):U(l[0][0],{name:n,arguments:o,toolStartObserved:!0,pending:!0})})},onItemEvent:e=>{H("item_event",()=>{const t="string"==typeof e.kind?e.kind.toLowerCase():"";if(t&&"tool"!==t)return;const r="string"==typeof e.phase?e.phase.toLowerCase():"update",n=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);n&&s&&("update"!==r?W(n,s):U(R(n),{name:s,itemEventObserved:!0,pending:!0}))})}},commitAssistantMessage:e=>{H("assistant_message_commit",()=>{if(a.has(e.key))return;a.add(e.key),s=!0,J=void 0,n="";const t=e.segments.filter(e=>"text"===e.type).map(e=>e.text).join("");r+=t,b(r);for(const t of e.segments)"text"!==t.type?A(t.id,t.name,t.arguments,!0):$(t.text)})},observeToolResult:t=>{H("tool_result_observation",()=>{const r=t.toolCallId.trim(),n=t.toolName.trim();if(!r||!n)return;const s=searchSourceProvider(t.rawResult)??"unknown";let o=0;try{const a=extractSearchSources({toolName:n,rawResult:t.rawResult,isError:t.isError});if(o=a.length,0===o)return;const i=z(r,n);if(i)q(a,i.id);else{const e=O(R(r));e.name??=n,e.sources=T(e.sources,a)}e.logger.debug?.(`[im-sink] search source projection requestId=${e.requestId} tool=${n} provider=${s} source_count=${o}`)}catch{e.logger.warn?.(`[im-sink] search source projection ignored requestId=${e.requestId} tool=${n} provider=${s} source_count=${o}`)}})},getSourceCount:()=>D.source}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dedupeMessageServiceArtifacts,extractMessageToolCaption,messageServiceFileParts,messageServiceRunMessageId,sanitizeMessageServiceText}from"./message-service-output-format.js";import{toMessagePart}from"../message-client-types.js";import{extractSearchSources,mergeSearchSource,searchSourceProvider}from"./search-source-extractor.js";export class MessageServiceRunOutputChannel{deps;id="message_service";runs=new Map;constructor(e){this.deps=e}open(e){if(!e.conversationId)throw new Error(`Message Service run has no conversation: ${e.runId}`);this.runs.set(e.runId,{assistantText:"",reasoningText:"",artifacts:[],artifactUris:new Set,tools:[],toolsById:new Map,sourcesByUrl:new Map})}project(e,t){const r=this.state(e.runId);try{switch(t.type){case"assistant_delta":this.projectAssistantDelta(e,r,t.content);break;case"thought_chunk":this.projectThoughtDelta(e,r,t.content);break;case"tool_call":this.projectToolStart(e,r,t);break;case"tool_call_update":this.projectToolUpdate(e,r,t)}}catch(t){throw this.reportProjectionFailure(e,t,"project"),t}}async terminal(e,t,r){const s=this.state(e.runId);try{const o=dedupeMessageServiceArtifacts(s.artifacts);let n,a=sanitizeMessageServiceText(s.assistantText)||sanitizeMessageServiceText(s.caption);r.expectedUploadArtifacts&&0===o.length?(a="The generated attachment could not be delivered.",n="attachment_delivery_failed"):"failed"===t.kind&&(a||=t.message,n="interrupted"===t.mode?t.errorCode:"error");const i="failed"===r.persistenceReconciliation||"timed_out"===r.persistenceReconciliation;!i||a||0!==o.length||0!==s.tools.length||s.reasoningText||"complete"!==t.kind||(a="The response could not be delivered.",n=`persistence_reconciliation_${r.persistenceReconciliation}`),i&&this.deps.writeObs({component:"message-service-run-output",domain:"lifecycle",name:"timed_out"===r.persistenceReconciliation?"run_output.reconciliation_timeout":"run_output.reconciliation_failed",severity:"warn",payload:{conversationId:e.conversationId,runId:e.runId,status:r.persistenceReconciliation}});if(!(Boolean(a)||o.length>0||s.tools.length>0||Boolean(s.reasoningText))&&"complete"===t.kind)return;const c=this.stream(e,s);if(a!==s.assistantText&&c.setBody(a),this.finishReasoning(s),this.finishTools(s),"cancelled"===t.kind)await c.cancel({stopReason:"user_stop"});else if(n)await c.fail({stopReason:n});else{const e="complete"===t.kind?t.stopReason:"end_turn";await c.finalize({stopReason:e})}this.deps.writeObs({component:"message-service-run-output",domain:"lifecycle",name:n?"run_output.failed":"run_output.completed",severity:n?"warn":"info",payload:{conversationId:e.conversationId,runId:e.runId,textLen:a.length,artifactCount:o.length,toolCount:s.tools.length,sourceCount:s.sourcesByUrl.size}})}catch(t){throw this.reportProjectionFailure(e,t,"terminal"),t}finally{this.runs.delete(e.runId)}}projectAssistantDelta(e,t,r){const s=asRecord(r);if(!s)return;if("text"===s.type&&"string"==typeof s.text)return t.assistantText+=s.text,void this.stream(e,t).appendBody(s.text);const o=artifactFromBlock(s);o&&this.projectArtifact(e,t,o)}projectThoughtDelta(e,t,r){const s=asRecord(r);if("text"!==s?.type||"string"!=typeof s.text)return;t.reasoningText+=s.text;const o=this.stream(e,t),n=toMessagePart({type:"thinking",text:t.reasoningText,state:"streaming"});void 0===t.reasoningPartIndex?(t.reasoningPartIndex=o.parts.length,o.addPart(n)):o.replacePart(t.reasoningPartIndex,n)}projectToolStart(e,t,r){const s={id:String(r.toolCallId),name:r.name??r.title,arguments:r.rawInput??parseArguments(r.arguments),isError:!1,completed:!1};t.tools.push(s),t.toolsById.set(s.id,s),this.upsertToolUse(e,t,s);const o=extractMessageToolCaption(s.name,s.arguments);o&&(t.caption=o)}projectToolUpdate(e,t,r){const s=String(r.toolCallId);let o=t.toolsById.get(s);o||(o={id:s,name:r.name??r.title??"tool",arguments:{},isError:!1,completed:!1},t.tools.push(o),t.toolsById.set(s,o));const n=r.name??r.title;"tool"===o.name&&n&&(o.name=n),o.result=r.result??r.content??r.rawOutput??r.output??r.text,o.isError="failed"===r.status,o.completed=!0,this.upsertToolUse(e,t,o),this.upsertToolProgress(e,t,o),this.projectSearchSources(e,t,o.name,r.rawOutput,r.result,o.isError);for(const s of r.content??[]){const r=asRecord(asRecord(s)?.content),o=r?artifactFromBlock(r):void 0;o&&this.projectArtifact(e,t,o)}}upsertToolUse(e,t,r){const s=this.stream(e,t),o=toMessagePart({type:"tool_use",id:r.id,name:r.name,arguments:r.arguments,state:r.completed?"done":"streaming"});void 0===r.usePartIndex?(r.usePartIndex=s.parts.length,s.addPart(o)):s.replacePart(r.usePartIndex,o)}upsertToolProgress(e,t,r){if(void 0===r.result)return;const s=this.stream(e,t),o=toMessagePart({type:"custom",kind:"tool_progress",data:{tool_use_id:r.id,content:r.result,...r.isError?{is_error:!0}:{}}});void 0===r.progressPartIndex?(r.progressPartIndex=s.parts.length,s.addPart(o)):s.replacePart(r.progressPartIndex,o)}projectArtifact(e,t,r){const s=dedupeMessageServiceArtifacts([r])[0];if(!s||t.artifactUris.has(s.uri))return;t.artifactUris.add(s.uri),t.artifacts.push(s);const[o]=messageServiceFileParts([s]);o&&this.stream(e,t).addPart(o)}projectSearchSources(e,t,r,s,o,n){let
|
|
1
|
+
import{dedupeMessageServiceArtifacts,extractMessageToolCaption,messageServiceFileParts,messageServiceRunMessageId,sanitizeMessageServiceText}from"./message-service-output-format.js";import{toMessagePart}from"../message-client-types.js";import{extractSearchSources,mergeSearchSource,searchSourceProvider}from"./search-source-extractor.js";export class MessageServiceRunOutputChannel{deps;id="message_service";runs=new Map;constructor(e){this.deps=e}open(e){if(!e.conversationId)throw new Error(`Message Service run has no conversation: ${e.runId}`);this.runs.set(e.runId,{assistantText:"",reasoningText:"",artifacts:[],artifactUris:new Set,tools:[],toolsById:new Map,sourcesByUrl:new Map})}project(e,t){const r=this.state(e.runId);try{switch(t.type){case"assistant_delta":this.projectAssistantDelta(e,r,t.content);break;case"thought_chunk":this.projectThoughtDelta(e,r,t.content);break;case"tool_call":this.projectToolStart(e,r,t);break;case"tool_call_update":this.projectToolUpdate(e,r,t)}}catch(t){throw this.reportProjectionFailure(e,t,"project"),t}}async terminal(e,t,r){const s=this.state(e.runId);try{const o=dedupeMessageServiceArtifacts(s.artifacts);let n,a=sanitizeMessageServiceText(s.assistantText)||sanitizeMessageServiceText(s.caption);r.expectedUploadArtifacts&&0===o.length?(a="The generated attachment could not be delivered.",n="attachment_delivery_failed"):"failed"===t.kind&&(a||=t.message,n="interrupted"===t.mode?t.errorCode:"error");const i="failed"===r.persistenceReconciliation||"timed_out"===r.persistenceReconciliation;!i||a||0!==o.length||0!==s.tools.length||s.reasoningText||"complete"!==t.kind||(a="The response could not be delivered.",n=`persistence_reconciliation_${r.persistenceReconciliation}`),i&&this.deps.writeObs({component:"message-service-run-output",domain:"lifecycle",name:"timed_out"===r.persistenceReconciliation?"run_output.reconciliation_timeout":"run_output.reconciliation_failed",severity:"warn",payload:{conversationId:e.conversationId,runId:e.runId,status:r.persistenceReconciliation}});if(!(Boolean(a)||o.length>0||s.tools.length>0||Boolean(s.reasoningText))&&"complete"===t.kind)return;const c=this.stream(e,s);if(a!==s.assistantText&&c.setBody(a),this.finishReasoning(s),this.finishTools(s),"cancelled"===t.kind)await c.cancel({stopReason:"user_stop"});else if(n)await c.fail({stopReason:n});else{const e="complete"===t.kind?t.stopReason:"end_turn";await c.finalize({stopReason:e})}this.deps.writeObs({component:"message-service-run-output",domain:"lifecycle",name:n?"run_output.failed":"run_output.completed",severity:n?"warn":"info",payload:{conversationId:e.conversationId,runId:e.runId,textLen:a.length,artifactCount:o.length,toolCount:s.tools.length,sourceCount:s.sourcesByUrl.size}})}catch(t){throw this.reportProjectionFailure(e,t,"terminal"),t}finally{this.runs.delete(e.runId)}}projectAssistantDelta(e,t,r){const s=asRecord(r);if(!s)return;if("text"===s.type&&"string"==typeof s.text)return t.assistantText+=s.text,void this.stream(e,t).appendBody(s.text);const o=artifactFromBlock(s);o&&this.projectArtifact(e,t,o)}projectThoughtDelta(e,t,r){const s=asRecord(r);if("text"!==s?.type||"string"!=typeof s.text)return;t.reasoningText+=s.text;const o=this.stream(e,t),n=toMessagePart({type:"thinking",text:t.reasoningText,state:"streaming"});void 0===t.reasoningPartIndex?(t.reasoningPartIndex=o.parts.length,o.addPart(n)):o.replacePart(t.reasoningPartIndex,n)}projectToolStart(e,t,r){const s={id:String(r.toolCallId),name:r.name??r.title,arguments:r.rawInput??parseArguments(r.arguments),isError:!1,completed:!1};t.tools.push(s),t.toolsById.set(s.id,s),this.upsertToolUse(e,t,s);const o=extractMessageToolCaption(s.name,s.arguments);o&&(t.caption=o)}projectToolUpdate(e,t,r){const s=String(r.toolCallId);let o=t.toolsById.get(s);o||(o={id:s,name:r.name??r.title??"tool",arguments:{},isError:!1,completed:!1},t.tools.push(o),t.toolsById.set(s,o));const n=r.name??r.title;"tool"===o.name&&n&&(o.name=n),o.result=r.result??r.content??r.rawOutput??r.output??r.text,o.isError="failed"===r.status,o.completed=!0,this.upsertToolUse(e,t,o),this.upsertToolProgress(e,t,o),this.projectSearchSources(e,t,o.id,o.name,r.rawOutput,r.result,o.isError);for(const s of r.content??[]){const r=asRecord(asRecord(s)?.content),o=r?artifactFromBlock(r):void 0;o&&this.projectArtifact(e,t,o)}}upsertToolUse(e,t,r){const s=this.stream(e,t),o=toMessagePart({type:"tool_use",id:r.id,name:r.name,arguments:r.arguments,state:r.completed?"done":"streaming"});void 0===r.usePartIndex?(r.usePartIndex=s.parts.length,s.addPart(o)):s.replacePart(r.usePartIndex,o)}upsertToolProgress(e,t,r){if(void 0===r.result)return;const s=this.stream(e,t),o=toMessagePart({type:"custom",kind:"tool_progress",data:{tool_use_id:r.id,content:r.result,...r.isError?{is_error:!0}:{}}});void 0===r.progressPartIndex?(r.progressPartIndex=s.parts.length,s.addPart(o)):s.replacePart(r.progressPartIndex,o)}projectArtifact(e,t,r){const s=dedupeMessageServiceArtifacts([r])[0];if(!s||t.artifactUris.has(s.uri))return;t.artifactUris.add(s.uri),t.artifacts.push(s);const[o]=messageServiceFileParts([s]);o&&this.stream(e,t).addPart(o)}projectSearchSources(e,t,r,s,o,n,a){let i=o,c=0;try{let u=extractSearchSources({toolName:s,rawResult:i,isError:a});0===u.length&&void 0!==n&&n!==o&&(i=n,u=extractSearchSources({toolName:s,rawResult:i,isError:a}));const l=searchSourceProvider(i)??"unknown";if(c=u.length,0===c)return;const p=this.stream(e,t);for(const e of u){const s=t.sourcesByUrl.get(e.url);if(s){const r=mergeSearchSource(s.source,e);if(r.title===s.source.title&&r.snippet===s.source.snippet)continue;p.replacePart(s.partIndex,toMessagePart({type:"source",url:r.url,...r.title?{title:r.title}:{},...r.snippet?{snippet:r.snippet}:{},tool_use_id:s.toolUseId})),t.sourcesByUrl.set(e.url,{source:r,partIndex:s.partIndex,toolUseId:s.toolUseId});continue}const o=p.parts.length;p.addPart(toMessagePart({type:"source",url:e.url,...e.title?{title:e.title}:{},...e.snippet?{snippet:e.snippet}:{},tool_use_id:r})),t.sourcesByUrl.set(e.url,{source:e,partIndex:o,toolUseId:r})}this.deps.logger.debug?.(`[message-service-run-output] search source projection run=${e.runId} tool=${s} provider=${l} source_count=${c}`)}catch{const t=searchSourceProvider(i)??"unknown";this.deps.logger.warn?.(`[message-service-run-output] search source projection ignored run=${e.runId} tool=${s} provider=${t} source_count=${c}`)}}finishReasoning(e){e.stream&&void 0!==e.reasoningPartIndex&&e.stream.replacePart(e.reasoningPartIndex,toMessagePart({type:"thinking",text:e.reasoningText,state:"done"}))}finishTools(e){if(e.stream)for(const t of e.tools)void 0!==t.usePartIndex&&(t.completed||e.stream.replacePart(t.usePartIndex,toMessagePart({type:"tool_use",id:t.id,name:t.name,arguments:t.arguments,state:"done"})))}stream(e,t){if(t.stream)return t.stream;const r=this.deps.getClient();if(!r)throw new Error(`Message Service client unavailable: ${e.runId}`);const s=messageServiceRunMessageId(e.runId);return t.stream=r.messages.startStream({conversationId:e.conversationId,clientMessageId:s,idempotencyKey:s,type:"agent_reply",content:{run_id:e.runId},...e.replyTo?{replyTo:e.replyTo}:{}}),t.stream}reportProjectionFailure(e,t,r){const s=t instanceof Error?t.message:String(t);this.deps.logger.warn?.(`[message-service-run-output] ${r} failed run=${e.runId}: ${s}`),this.deps.writeObs({component:"message-service-run-output",domain:"lifecycle",name:"run_output.failed",severity:"warn",summary:s,payload:{conversationId:e.conversationId,runId:e.runId,phase:r}})}state(e){const t=this.runs.get(e);if(!t)throw new Error(`Message Service run output is not open: ${e}`);return t}}function asRecord(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:void 0}function parseArguments(e){if(!e)return{};try{return JSON.parse(e)}catch{return e}}function artifactFromBlock(e){if("resource_link"!==e.type&&"file"!==e.type)return;const t="string"==typeof e.uri?e.uri:"string"==typeof e.url?e.url:void 0;return t?{uri:t,..."string"==typeof e.name?{name:e.name}:{},..."string"==typeof e.mimeType?{mimeType:e.mimeType}:"string"==typeof e.mime_type?{mimeType:e.mime_type}:{}}:void 0}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const SEARCH_TOOL_NAMES=new Set(["web_search","x_search"]),EXTERNAL_WEB_SEARCH_CONTENT_RE=/^<<<EXTERNAL_UNTRUSTED_CONTENT id="([a-f0-9]{16})">>>\nSource: Web Search\n---\n([\s\S]*)\n<<<END_EXTERNAL_UNTRUSTED_CONTENT id="\1">>>$/u,isRecord=r=>"object"==typeof r&&null!==r&&!Array.isArray(r),cleanField=r=>{if("string"!=typeof r)return;const e=r.trim();if(!e)return;const t=e.match(EXTERNAL_WEB_SEARCH_CONTENT_RE);return(t?.[2]??e).trim()||void 0},normalizeUrl=r=>{if("string"!=typeof r)return;const e=r.trim();if(e)try{const r=new URL(e);if("http:"!==r.protocol&&"https:"!==r.protocol)return;if(r.username||r.password)return;return r.hash="",r.toString()}catch{return}},hasSourceCollections=r=>Array.isArray(r.results)||Array.isArray(r.citations)||Array.isArray(r.sources),sourcePayload=r=>{if(!isRecord(r))return;if(hasSourceCollections(r))return r;const e=isRecord(r.details)?r.details:void 0;return e&&hasSourceCollections(e)?e:void 0};export const searchSourceProvider=r=>{const e=sourcePayload(r)?.provider;if("string"!=typeof e)return;const t=e.trim().toLowerCase();return/^[a-z0-9][a-z0-9._-]{0,63}$/u.test(t)?t:void 0};const sourceFromRecord=(r,e)=>{const t=normalizeUrl(r.url);if(!t)return;const o=cleanField(r.title);let i=e.includeSnippet?cleanField(r.description):void 0;if(!i&&e.includeSnippet&&Array.isArray(r.snippets)){const e=r.snippets.map(cleanField).filter(r=>Boolean(r));e.length>0&&(i=e.join("\n"))}return{url:t,...o?{title:o}:{},...i?{snippet:i}:{}}},sourceFromCitation=r=>{if("string"==typeof r){const e=normalizeUrl(r);return e?{url:e}:void 0}return isRecord(r)?sourceFromRecord(r,{includeSnippet:!1}):void 0};export const mergeSearchSource=(r,e)=>({url:r.url,...r.title||e.title?{title:r.title??e.title}:{},...r.snippet||e.snippet?{snippet:r.snippet??e.snippet}:{}});export const extractSearchSources=r=>{const e=r.toolName.trim().toLowerCase();if(r.isError||!SEARCH_TOOL_NAMES.has(e))return[];const t=sourcePayload(r.rawResult);if(!t)return[];const o=[],i=new Map,s=r=>{if(!r)return;const e=i.get(r.url);if(void 0===e)return i.set(r.url,o.length),void o.push(r);o[e]=mergeSearchSource(o[e],r)};if("web_search"===e&&Array.isArray(t.results))for(const r of t.results)isRecord(r)&&s(sourceFromRecord(r,{includeSnippet:!0}));if(Array.isArray(t.citations))for(const r of t.citations)s(sourceFromCitation(r));if("web_search"===e&&Array.isArray(t.sources))for(const r of t.sources)s(sourceFromCitation(r));return o};
|
|
1
|
+
const SEARCH_TOOL_NAMES=new Set(["web_search","x_search","beeos_search"]),EXTERNAL_WEB_SEARCH_CONTENT_RE=/^<<<EXTERNAL_UNTRUSTED_CONTENT id="([a-f0-9]{16})">>>\nSource: Web Search\n---\n([\s\S]*)\n<<<END_EXTERNAL_UNTRUSTED_CONTENT id="\1">>>$/u,isRecord=r=>"object"==typeof r&&null!==r&&!Array.isArray(r),cleanField=r=>{if("string"!=typeof r)return;const e=r.trim();if(!e)return;const t=e.match(EXTERNAL_WEB_SEARCH_CONTENT_RE);return(t?.[2]??e).trim()||void 0},normalizeUrl=r=>{if("string"!=typeof r)return;const e=r.trim();if(e)try{const r=new URL(e);if("http:"!==r.protocol&&"https:"!==r.protocol)return;if(r.username||r.password)return;return r.hash="",r.toString()}catch{return}},hasSourceCollections=r=>Array.isArray(r.results)||Array.isArray(r.citations)||Array.isArray(r.sources),sourcePayload=r=>{if(!isRecord(r))return;if(hasSourceCollections(r))return r;const e=isRecord(r.details)?r.details:void 0;return e&&hasSourceCollections(e)?e:void 0};export const searchSourceProvider=r=>{const e=sourcePayload(r)?.provider;if("string"!=typeof e)return;const t=e.trim().toLowerCase();return/^[a-z0-9][a-z0-9._-]{0,63}$/u.test(t)?t:void 0};const sourceFromRecord=(r,e)=>{const t=normalizeUrl(r.url);if(!t)return;const o=cleanField(r.title);let i=e.includeSnippet?cleanField(r.snippet)??cleanField(r.description):void 0;if(!i&&e.includeSnippet&&Array.isArray(r.snippets)){const e=r.snippets.map(cleanField).filter(r=>Boolean(r));e.length>0&&(i=e.join("\n"))}return{url:t,...o?{title:o}:{},...i?{snippet:i}:{}}},sourceFromCitation=r=>{if("string"==typeof r){const e=normalizeUrl(r);return e?{url:e}:void 0}return isRecord(r)?sourceFromRecord(r,{includeSnippet:!1}):void 0};export const mergeSearchSource=(r,e)=>({url:r.url,...r.title||e.title?{title:r.title??e.title}:{},...r.snippet||e.snippet?{snippet:r.snippet??e.snippet}:{}});export const extractSearchSources=r=>{const e=r.toolName.trim().toLowerCase();if(r.isError||!SEARCH_TOOL_NAMES.has(e))return[];const t=sourcePayload(r.rawResult);if(!t)return[];const o=[],i=new Map,s=r=>{if(!r)return;const e=i.get(r.url);if(void 0===e)return i.set(r.url,o.length),void o.push(r);o[e]=mergeSearchSource(o[e],r)};if(("web_search"===e||"beeos_search"===e)&&Array.isArray(t.results))for(const r of t.results)isRecord(r)&&s(sourceFromRecord(r,{includeSnippet:!0}));if(Array.isArray(t.citations))for(const r of t.citations)s(sourceFromCitation(r));if("web_search"===e&&Array.isArray(t.sources))for(const r of t.sources)s(sourceFromCitation(r));return o};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beeos-claw",
|
|
3
|
-
"version": "0.6.54-staging.
|
|
3
|
+
"version": "0.6.54-staging.2",
|
|
4
4
|
"description": "OpenClaw plugin that bridges the BeeOS platform with the local OpenClaw Gateway, providing file transfer, ACP bridge, and observability.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "BeeOS <dev@beeos.ai>",
|
|
@@ -87,5 +87,5 @@
|
|
|
87
87
|
"fast-uri": ">=3.1.4",
|
|
88
88
|
"brace-expansion": ">=5.0.9"
|
|
89
89
|
},
|
|
90
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "60ca592d77474708ec4c75b7e0e68b444f5b6d61"
|
|
91
91
|
}
|