shennian 0.3.34 → 0.3.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/publish-build-manifest.json +12 -7
- package/dist/src/agents/codex.d.ts +2 -0
- package/dist/src/agents/codex.js +7 -7
- package/dist/src/native-fusion/parser-common.js +4 -4
- package/dist/src/session/handlers/chat.js +2 -2
- package/dist/src/session/tool-summary.d.ts +1 -0
- package/dist/src/session/tool-summary.js +1 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"jsMinified": true,
|
|
4
4
|
"minifier": "esbuild",
|
|
5
|
-
"fileCount":
|
|
5
|
+
"fileCount": 130,
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"file": "bin/shennian.js",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
"file": "src/agents/codex.js",
|
|
34
|
-
"beforeBytes":
|
|
35
|
-
"afterBytes":
|
|
34
|
+
"beforeBytes": 43923,
|
|
35
|
+
"afterBytes": 22006
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
"file": "src/agents/command-spec.js",
|
|
@@ -356,8 +356,8 @@
|
|
|
356
356
|
},
|
|
357
357
|
{
|
|
358
358
|
"file": "src/native-fusion/parser-common.js",
|
|
359
|
-
"beforeBytes":
|
|
360
|
-
"afterBytes":
|
|
359
|
+
"beforeBytes": 7754,
|
|
360
|
+
"afterBytes": 3606
|
|
361
361
|
},
|
|
362
362
|
{
|
|
363
363
|
"file": "src/native-fusion/parsers.js",
|
|
@@ -566,8 +566,8 @@
|
|
|
566
566
|
},
|
|
567
567
|
{
|
|
568
568
|
"file": "src/session/handlers/chat.js",
|
|
569
|
-
"beforeBytes":
|
|
570
|
-
"afterBytes":
|
|
569
|
+
"beforeBytes": 29613,
|
|
570
|
+
"afterBytes": 12377
|
|
571
571
|
},
|
|
572
572
|
{
|
|
573
573
|
"file": "src/session/handlers/control.js",
|
|
@@ -624,6 +624,11 @@
|
|
|
624
624
|
"beforeBytes": 3925,
|
|
625
625
|
"afterBytes": 1918
|
|
626
626
|
},
|
|
627
|
+
{
|
|
628
|
+
"file": "src/session/tool-summary.js",
|
|
629
|
+
"beforeBytes": 1401,
|
|
630
|
+
"afterBytes": 731
|
|
631
|
+
},
|
|
627
632
|
{
|
|
628
633
|
"file": "src/session/types.js",
|
|
629
634
|
"beforeBytes": 159,
|
|
@@ -3,6 +3,8 @@ import type { ChatAttachmentMeta, ExternalChannelSessionStatus } from '@shennian
|
|
|
3
3
|
import type { SessionRunPhase } from '@shennian/wire';
|
|
4
4
|
export { isCodexUnsupportedEffortError, isMissingCodexRolloutError, normalizeCodexModelId, normalizeCodexReasoningEffort, } from './codex-utils.js';
|
|
5
5
|
export declare function isCodexActiveWriterError(error: unknown): boolean;
|
|
6
|
+
export declare function isCodexPaginatedHistoryUnsupportedError(error: unknown): boolean;
|
|
7
|
+
export declare function isCodexExcludeTurnsUnsupportedError(error: unknown): boolean;
|
|
6
8
|
export declare function buildCodexQueuedText(text: string, attachments?: ChatAttachmentMeta[]): string;
|
|
7
9
|
export declare function buildCodexQueueArgs(threadId: string, text: string, attachments?: ChatAttachmentMeta[]): string[];
|
|
8
10
|
export declare class CodexAdapter extends AgentAdapter {
|
package/dist/src/agents/codex.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import{spawnSync as C}from"node:child_process";import{createInterface as
|
|
2
|
-
`)}function
|
|
3
|
-
`)}function
|
|
4
|
-
${p}`.trim();if(
|
|
5
|
-
`,p=>{p&&(clearTimeout(u),this.pendingRequests.delete(i),
|
|
1
|
+
import{spawnSync as C}from"node:child_process";import{createInterface as I}from"node:readline";import{randomUUID as _}from"node:crypto";import A from"node:path";import{AgentAdapter as R,registerAgent as P}from"./adapter.js";import{resolveBuiltinCommand as g,spawnAgentCommand as v}from"./command-spec.js";import{buildAgentProcessEnv as x}from"../agent-env.js";import{ensurePlatformInstructionsFile as q}from"./platform-instructions.js";import{CODEX_APP_SERVER_CLIENT_INFO as O,extractAppServerErrorMessage as $,formatCodexErrorMessage as b,formatTransientCodexStatus as L,isCodexCollabAgentItem as F,isCodexCollabAgentToolName as f,isCodexLegacyCollabAgentItem as M,isCodexUnsupportedEffortError as U,isMissingCodexRolloutError as N,isTransientCodexErrorMessage as D,looksLikeCodexInteractiveAuthPrompt as W,looksLikeFatalCodexStderr as z,makeThreadTitle as B,normalizeCodexModelId as S,normalizeCodexReasoningEffort as G,normalizeCodexStderr as T,normalizeTerminalText as J,safeStringify as w,stripGitDirectiveArtifacts as H}from"./codex-utils.js";import{isCodexUnsupportedEffortError as me,isMissingCodexRolloutError as fe,normalizeCodexModelId as ge,normalizeCodexReasoningEffort as ve}from"./codex-utils.js";function V(a){const e=a instanceof Error?a.message:String(a);return/already has an active writer|thread-store conflict/i.test(e)}function Q(a){const e=a instanceof Error?a.message:String(a);return/paginated(?:_threads|\s+(?:thread\s+)?history)?.*(?:not supported|unsupported|unavailable)/i.test(e)||/(?:not supported|unsupported|unavailable).*paginated(?:_threads|\s+(?:thread\s+)?history)?/i.test(e)}function K(a){const e=a instanceof Error?a.message:String(a);return/unknown field [`'"]?excludeTurns/i.test(e)||/excludeTurns.*(?:not supported|unsupported|unavailable)/i.test(e)}function X(a,e){const t=e?.flatMap(r=>Y(r)).filter(r=>!/^https?:\/\//i.test(r.path)).filter(r=>r.path);return{type:"text",text:j(a,e),text_elements:[],...t?.length?{local_images:t}:{}}}function Y(a){if(a.kind==="image")return a.previewData?[{path:a.path,data:a.previewData,mimeType:a.mimeType}]:[{path:a.path}];if(a.mimeType.startsWith("video/")){const e=Z(a.path);return e?[{path:e}]:[]}return[]}function Z(a){if(!a||/^https?:\/\//i.test(a))return null;const e=A.extname(a),s=`${e?a.slice(0,-e.length):a}.preview.png`;return C("ffmpeg",["-y","-ss","0","-i",a,"-frames:v","1","-vf","scale=320:-1",s],{stdio:"ignore",timeout:15e3}).status===0?s:null}function j(a,e){const t=e?.filter(i=>i.kind!=="image").filter(i=>i.path&&!/^https?:\/\//i.test(i.path));if(!t?.length||t.every(i=>a.includes(i.path)))return a;const r=t.map((i,n)=>{const o=i.name||`attachment-${n+1}`,l=i.mimeType?` (${i.mimeType})`:"";return`[${k(o)}${l}](<${i.path}>)`});return[a,"",...r].join(`
|
|
2
|
+
`)}function ee(a,e){const t=e?.filter(r=>r.path&&!/^https?:\/\//i.test(r.path)&&!a.includes(r.path));if(!t?.length)return a;const s=t.map((r,i)=>{const n=k(r.name||`attachment-${i+1}`);return r.kind==="image"?``:`[${n}](<${r.path}>)`});return[a,"",...s].join(`
|
|
3
|
+
`)}function te(a,e,t){return["queue","--thread",a,"--message",ee(e,t)]}function k(a){return a.replace(/[[\]\\]/g,"\\$&")}class se extends R{options;type="codex";process=null;workDir=null;seq=0;runId="";pendingUsage;agentSessionId=null;hasEmittedText=!1;textTail="";terminalState="open";forceCloseTimer=null;stderrBuf="";rpcSeq=1;pendingRequests=new Map;appServerReady=null;appServerStartupError=null;activeTurnId=null;namedThread=!1;deltaItemIds=new Set;lastTransientStatus="";agentSystemPrompt="";constructor(e={}){super(),this.options=e}externalChannel=null;shennianSessionId=null;extraEnv={};configure(e){this.shennianSessionId=e.sessionId??null,this.externalChannel=e.externalChannel??null,this.extraEnv=e.env??{}}async start(e,t,s){this.workDir=t,this.seq=0,s&&(this.agentSessionId=s)}async send(e,t,s,r,i){this.activeTurnId&&(await this.interruptActiveTurn().catch(()=>{}),await this.killProcess());const n=S(t),o=G(s),l=i?.trim()??"";l!==this.agentSystemPrompt&&(this.agentSystemPrompt=l,this.process&&await this.killProcess()),this.runId=_(),this.seq=0,this.resetRunState();try{await this.ensureAppServer(n)}catch(c){if(!this.agentSessionId||!V(c))throw c;return{deliveryMode:"external_owner_queue",queuedSubmissionId:await this.enqueueForExternalOwner(this.agentSessionId,e,r)}}const u=this.agentSessionId;if(!u)throw new Error("codex app-server did not create a thread");this.emitEvent({state:"start",agentSessionId:u}),this.namedThread||(await this.sendRpc("thread/name/set",{threadId:u,name:B(e)}).catch(()=>{}),this.namedThread=!0);const p=await this.startTurnWithRecovery(u,e,n,o,r);return this.activeTurnId=p.turn?.id??null,{deliveryMode:"direct"}}async enqueueForExternalOwner(e,t,s){const r=g("codex");if(!r)throw new Error('Command "codex" not found. Is OpenAI Codex CLI installed?');const i=te(e,t,s),n=v(r,i,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:x({NO_COLOR:"1",...this.extraEnv})});return await new Promise((o,l)=>{let u="",p="",c=!1;const h=(d,m)=>{c||(c=!0,clearTimeout(y),d?l(d):o(m))},y=setTimeout(()=>{n.kill("SIGTERM"),h(new Error("Codex Desktop message queue timed out"))},6e4);y.unref?.(),n.stdout?.on("data",d=>{u+=d.toString()}),n.stderr?.on("data",d=>{p+=d.toString()}),n.once("error",d=>h(d)),n.once("close",d=>{const m=`${u}
|
|
4
|
+
${p}`.trim();if(d!==0){h(new Error(m||`codex queue exited with code ${d??"unknown"}`));return}const E=m.match(/Queued message\s+([^\s]+)\s+for thread/i)?.[1];h(void 0,E)})})}async resume(e){await this.killProcess(),this.agentSessionId=e,this.namedThread=!0,this.resetTextState()}async setTitle(e,t,s){const r=e.trim(),i=t.replace(/\s+/g," ").trim();!r||!i||(this.agentSessionId=r,s?.trim()&&(this.workDir=s),await this.ensureAppServer(),await this.sendRpc("thread/name/set",{threadId:r,name:i}),this.namedThread=!0)}async stop(){await this.interruptActiveTurn().catch(()=>{}),await this.killProcess()}async getStatus(){const e=this.agentSessionId,t=this.activeTurnId;if(!e||!this.process)return{active:!1,runId:t,runPhase:null,canStop:!1};let s=null;try{s=(await this.sendRpc("thread/read",{threadId:e,includeTurns:!1},5e3)).thread?.status??null}catch{}const r=s?.type==="active"||!!t;return{active:r,runId:t,runPhase:r?this.mapThreadStatusToRunPhase(s):null,canStop:!!(r&&t&&this.process)}}spawnCodex(e){const t=g("codex");if(!t){this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?'));return}const s=v(t,e,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:x(this.extraEnv)});this.process=s,I({input:s.stdout}).on("line",n=>{if(n.trim())try{const o=JSON.parse(n);this.handleStreamEvent(o)}catch{this.emitEvent({state:"delta",text:n})}});let i="";s.stderr?.on("data",n=>{i+=n.toString()}),s.on("close",n=>{this.process===s&&(this.process=null,this.clearForceCloseTimer(),this.handleProcessClose(n,i))}),s.on("error",n=>{this.process===s&&(this.process=null,n.code==="ENOENT"?this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?')):this.emit("error",n))})}spawnAppServer(){const e=g("codex");if(!e){this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?'));return}const t=["app-server","--listen","stdio://"],s=this.options.modelInstructionsFile??q(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,this.agentSystemPrompt);s&&t.push("-c",`model_instructions_file=${JSON.stringify(s)}`);const r=v(e,t,{cwd:this.workDir??void 0,stdio:["pipe","pipe","pipe"],env:x({NO_COLOR:"1",...this.extraEnv})});this.process=r,this.stderrBuf="",this.appServerStartupError=null,I({input:r.stdout}).on("line",n=>{if(!n.trim())return;let o;try{o=JSON.parse(n)}catch{this.handleAppServerNonJsonStdout(n);return}this.handleAppServerMessage(o)}),r.stderr?.on("data",n=>{this.stderrBuf+=n.toString()}),r.on("close",n=>{if(this.process!==r)return;const o=this.activeTurnId!=null;this.process=null,this.appServerReady=null,this.activeTurnId=null,this.rejectAllPending(new Error(T(this.stderrBuf)||`codex app-server exited with code ${n}`)),this.terminalState==="open"&&o&&this.handleProcessClose(n,this.stderrBuf)}),r.on("error",n=>{this.process===r&&(this.process=null,this.rejectAllPending(n),n.code==="ENOENT"?this.emit("error",new Error('Command "codex" not found. Is OpenAI Codex CLI installed?')):this.emit("error",n))})}async ensureAppServer(e){return this.appServerReady?this.appServerReady:(this.spawnAppServer(),this.appServerReady=this.initializeAppServer(e).catch(async t=>{throw this.appServerReady=null,await this.killProcess(),t}),this.appServerReady)}async initializeAppServer(e){const t=S(e);if(await this.sendRpc("initialize",{clientInfo:O,capabilities:{experimentalApi:!0}}),this.agentSessionId){const n={threadId:this.agentSessionId,cwd:this.workDir,approvalPolicy:"never",sandbox:"danger-full-access",persistExtendedHistory:!0,...this.options.hidden?{threadSource:"subagent"}:{},...t?{model:t}:{}};let o;try{o=await this.sendRpc("thread/resume",{...n,excludeTurns:!0})}catch(l){if(!K(l))throw l;o=await this.sendRpc("thread/resume",n)}this.agentSessionId=o.thread?.id??this.agentSessionId,this.namedThread=!!o.thread?.name;return}const s={cwd:this.workDir,approvalPolicy:"never",sandbox:"danger-full-access",serviceName:"Shennian",threadSource:this.options.hidden?"subagent":"user",experimentalRawEvents:!1,persistExtendedHistory:!0,...t?{model:t}:{}};let r;if(this.options.hidden)r=await this.sendRpc("thread/start",s);else try{r=await this.sendRpc("thread/start",{...s,historyMode:"paginated"})}catch(n){throw Q(n)?new Error("\u5F53\u524D Codex CLI \u4E0D\u652F\u6301\u521B\u5EFA\u53EF\u5728 Codex Desktop \u4E2D\u7EE7\u7EED\u7684\u65B0\u4F1A\u8BDD\uFF0C\u8BF7\u624B\u52A8\u5347\u7EA7 Codex CLI \u540E\u91CD\u8BD5\u3002\u795E\u5FF5\u4E0D\u4F1A\u81EA\u52A8\u5347\u7EA7\uFF0C\u4E5F\u4E0D\u4F1A\u964D\u7EA7\u521B\u5EFA\u4E0D\u53EF\u89C1\u7684 legacy \u4F1A\u8BDD\u3002",{cause:n}):n}const i=r.thread?.id;if(!i)throw new Error("codex app-server thread/start returned no thread id");this.agentSessionId=i,this.namedThread=!!r.thread?.name}async startTurnWithRecovery(e,t,s,r,i){try{return await this.startTurn(e,t,s,r,i)}catch(n){if(!N(n))throw n;return await this.killProcess(),await this.ensureAppServer(s),await this.startTurn(e,t,s,r,i)}}async startTurn(e,t,s,r,i){try{return await this.sendRpc("turn/start",{threadId:e,input:[X(t,i)],approvalPolicy:"never",sandboxPolicy:{type:"dangerFullAccess"},...s?{model:s}:{},...r?{effort:r}:{}})}catch(n){throw r&&U(n)?new Error(`Codex app-server does not accept reasoning effort "${r}" for this turn. Refresh models or upgrade Codex CLI, then retry.`,{cause:n}):n}}async interruptActiveTurn(){const e=this.agentSessionId,t=this.activeTurnId;!e||!t||!this.process||(await this.sendRpc("turn/interrupt",{threadId:e,turnId:t},5e3),this.activeTurnId=null)}sendRpc(e,t,s=6e4){if(this.appServerStartupError)return Promise.reject(this.appServerStartupError);const r=this.process;if(!r?.stdin)return Promise.reject(new Error("codex app-server is not running"));const i=this.rpcSeq++,n=JSON.stringify({id:i,method:e,params:t});return new Promise((o,l)=>{const u=setTimeout(()=>{this.pendingRequests.delete(i),l(new Error(`codex app-server request timed out: ${e}`))},s);this.pendingRequests.set(i,{resolve:o,reject:l,timer:u}),r.stdin.write(`${n}
|
|
5
|
+
`,p=>{p&&(clearTimeout(u),this.pendingRequests.delete(i),l(p))})})}handleAppServerMessage(e){if(e.id!=null){const s=this.pendingRequests.get(e.id);s&&(clearTimeout(s.timer),this.pendingRequests.delete(e.id),e.error?s.reject(new Error(e.error.message||`codex app-server error ${e.error.code??""}`.trim())):s.resolve(e.result))}if(!e.method)return;const t=e.params??{};switch(e.method){case"turn/started":{const s=typeof t.turn=="object"&&t.turn!==null?t.turn:null,r=typeof s?.id=="string"?s.id:null;r&&(this.activeTurnId=r);break}case"thread/status/changed":{const s=typeof t.threadId=="string"?t.threadId:"";if(s&&this.agentSessionId&&s!==this.agentSessionId)break;const r=typeof t.status=="object"&&t.status!==null?t.status:null;r?.type==="active"&&this.emitEvent({state:"heartbeat",runPhase:this.mapThreadStatusToRunPhase(r)});break}case"item/agentMessage/delta":{const s=typeof t.itemId=="string"?t.itemId:"";s&&this.deltaItemIds.add(s),typeof t.delta=="string"&&this.emitText(t.delta);break}case"item/completed":this.handleAppServerCompletedItem(t);break;case"thread/tokenUsage/updated":this.handleAppServerUsage(t);break;case"turn/completed":{const s=typeof t.turn=="object"&&t.turn!==null?t.turn:null,r=typeof s?.id=="string"?s.id:null;(!this.activeTurnId||r===this.activeTurnId)&&(this.activeTurnId=null,this.emitFinalIfOpen());break}case"error":{const s=$(t);if(D(s)){this.emitTransientStatus(s);return}this.emitErrorIfOpen(s);break}}}mapThreadStatusToRunPhase(e){const t=e?.type==="active"&&Array.isArray(e.activeFlags)?e.activeFlags:[];return t.includes("waitingOnApproval")?"waiting_approval":t.includes("waitingOnUserInput")?"waiting_user_input":"thinking"}handleAppServerNonJsonStdout(e){const t=J(e);W(t)&&this.failAppServerStartup(new Error("Codex \u672A\u767B\u5F55\u3002\u8BF7\u5148\u5728\u8FD9\u53F0\u7535\u8111\u7684\u7EC8\u7AEF\u8FD0\u884C `codex`\uFF0C\u6309\u63D0\u793A\u5B8C\u6210 ChatGPT \u767B\u5F55\u6216\u914D\u7F6E API key\uFF0C\u7136\u540E\u518D\u56DE\u5230\u795E\u5FF5\u53D1\u9001\u6D88\u606F\u3002"))}failAppServerStartup(e){this.appServerStartupError||(this.appServerStartupError=e,this.rejectAllPending(e),this.process?.kill("SIGTERM"))}handleAppServerCompletedItem(e){const t=typeof e.item=="object"&&e.item!==null?e.item:null;if(!(!t||typeof t.type!="string")&&!F(t))switch(t.type){case"agentMessage":{const s=typeof t.id=="string"?t.id:"";if(s&&this.deltaItemIds.has(s))return;typeof t.text=="string"&&this.emitText(t.text,"block");break}case"commandExecution":{const s=typeof t.command=="string"?t.command:"",r=typeof t.aggregatedOutput=="string"?t.aggregatedOutput:"";s&&this.emitEvent({state:"tool-call",name:"command_execution",args:{command:s}}),this.emitEvent({state:"tool-result",name:"command_execution",result:[r,t.exitCode!=null?`
|
|
6
6
|
(exit ${t.exitCode})`:""].join("").trim()});break}case"mcpToolCall":case"dynamicToolCall":{const s=typeof t.tool=="string"?t.tool:t.type;if(f(s))return;const r=typeof t.arguments=="object"&&t.arguments!==null?t.arguments:{};this.emitEvent({state:"tool-call",name:s,args:r}),this.emitEvent({state:"tool-result",name:s,result:w(t.error??t.result??t.contentItems??"")});break}case"fileChange":break;case"approvalRequest":case"approval_request":case"permissionRequest":case"permission_request":case"userInputRequired":case"user_input_required":{this.emitApprovalPending(t);break}}}handleAppServerUsage(e){const t=typeof e.tokenUsage=="object"&&e.tokenUsage!==null?e.tokenUsage:null,s=typeof t?.last=="object"&&t.last!==null?t.last:null,r=typeof t?.total=="object"&&t.total!==null?t.total:null,i=s??r;if(!i)return;const n=typeof i.inputTokens=="number"?i.inputTokens:void 0,o=typeof i.outputTokens=="number"?i.outputTokens:void 0;(n!=null||o!=null)&&(this.pendingUsage={inputTokens:n??0,outputTokens:o??0})}handleCodexItemLine(e){const t=e.item;if(t?.type&&!M(t))switch(t.type){case"agent_message":case"reasoning":{e.type==="item.completed"&&t.text&&this.emitText(t.text,"block");break}case"command_execution":{if(e.type==="item.started"&&t.command&&this.emitEvent({state:"tool-call",name:"command_execution",args:{command:t.command}}),e.type==="item.completed"){const s=[t.aggregated_output??"",t.exit_code!=null?`
|
|
7
7
|
(exit ${t.exit_code})`:""];this.emitEvent({state:"tool-result",name:"command_execution",result:s.join("").trim()||String(t.status??"")})}break}case"mcp_tool_call":{if(t.tool&&f(t.tool))return;if(e.type==="item.started"&&this.emitEvent({state:"tool-call",name:t.tool??"mcp_tool",args:{server:t.server,...t.arguments&&typeof t.arguments=="object"?t.arguments:{}}}),e.type==="item.completed"){const s=t.error&&typeof t.error=="object"?t.error.message:void 0;this.emitEvent({state:"tool-result",name:t.tool??"mcp_tool",result:s??w(t.result)})}break}case"file_change":break;case"web_search":{e.type==="item.completed"&&t.query&&this.emitText(`[web_search] ${t.query}`,"block");break}case"todo_list":{if(e.type==="item.completed"&&t.items?.length){const s=t.items.map(r=>`- [${r.completed?"x":" "}] ${r.text}`).join(`
|
|
8
|
-
`);this.emitText(s,"block")}break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{(e.type==="item.started"||e.type==="item.completed")&&this.emitApprovalPending(t);break}case"error":{e.type==="item.completed"&&t.message&&this.emitEvent({state:"error",message:t.message});break}default:break}}handleStreamEvent(e){const t=e.type??e.event;switch(t?.startsWith("item.")&&this.handleCodexItemLine(e),t){case"turn.completed":{const r=e.usage;if(r){const i=r.input_tokens??r.prompt_tokens,n=r.output_tokens??r.completion_tokens;(i!=null||n!=null)&&(this.pendingUsage={inputTokens:i??0,outputTokens:n??0})}this.emitFinalIfOpen();return}case"turn.failed":{const r=typeof e.error=="object"&&e.error?.message?e.error.message:typeof e.error=="string"?e.error:"turn failed";this.emitErrorIfOpen(r);return}case"error":{const r=typeof e.message=="string"?e.message:"";if(r.includes("Reconnecting"))return;this.emitErrorIfOpen(r||(typeof e.error=="string"?e.error:"stream error"));return}case"thread.started":{const r=e.thread_id??e.session_id??e.id;typeof r=="string"&&r&&(this.agentSessionId=r,this.emitEvent({state:"start",agentSessionId:this.agentSessionId}));return}case"turn.started":return}if(t?.startsWith("item."))return;switch(e.type??e.event){case"message":case"text":case"content":{const r=e.content??e.text;r&&this.emitText(r);break}case"function_call":case"tool_call":{if(this.isApprovalLikeName(e.name)){this.emitApprovalPending(e);break}if(e.name&&f(e.name))return;this.emitEvent({state:"tool-call",name:e.name,args:e.arguments??e.input});break}case"function_call_output":case"tool_result":{if(e.name&&f(e.name))return;this.emitEvent({state:"tool-result",name:e.name,result:e.output??e.result});break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{this.emitApprovalPending(e);break}case"error":break;case"done":case"completed":{e.usage&&(this.pendingUsage={inputTokens:e.usage.prompt_tokens??e.usage.input_tokens??0,outputTokens:e.usage.completion_tokens??e.usage.output_tokens??0}),this.emitFinalIfOpen();break}}}emitEvent(e){if(this.terminalState!=="open"&&e.state!=="final"&&e.state!=="error"&&e.state!=="aborted")return;const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}isApprovalLikeName(e){return typeof e!="string"?!1:/approval|permission|confirm|user[_-]?input|request[_-]?user/i.test(e)}emitApprovalPending(e){const t=typeof e.command=="string"?e.command:"",s=typeof e.title=="string"&&e.title.trim()?e.title:"\u9700\u8981\u7528\u6237\u786E\u8BA4",r=typeof e.prompt=="string"?e.prompt:typeof e.reason=="string"?e.reason:typeof e.message=="string"?e.message:t?`Codex \u8BF7\u6C42\u6267\u884C\u547D\u4EE4\uFF1A${t}`:"Codex \u6B63\u5728\u7B49\u5F85\u7528\u6237\u786E\u8BA4\u540E\u7EE7\u7EED\u3002";this.emitEvent({state:"approval-pending",approval:{title:s,content:r,source:"codex",actionHint:"\u5F53\u524D\u795E\u5FF5\u6682\u4E0D\u652F\u6301\u8FDC\u7A0B\u786E\u8BA4\uFF0C\u8BF7\u56DE\u5230\u8FD0\u884C Codex \u7684\u7535\u8111/\u7EC8\u7AEF\u5B8C\u6210\u786E\u8BA4\u3002"}})}async killProcess(){const e=this.process;if(this.appServerReady=null,this.activeTurnId=null,!e){this.rejectAllPending(new Error("codex app-server stopped"));return}this.process=null,this.clearForceCloseTimer(),e.kill("SIGTERM"),await new Promise(t=>{e.on("close",t),setTimeout(()=>{e.kill("SIGKILL"),t()},3e3)}),this.rejectAllPending(new Error("codex app-server stopped"))}rejectAllPending(e){for(const[t,s]of this.pendingRequests.entries())clearTimeout(s.timer),s.reject(e),this.pendingRequests.delete(t)}handleProcessClose(e,t){const s=T(t);if(e!==0&&e!==null){const r=s||`codex exited with code ${e}`;this.emitErrorIfOpen(r)}else z(s)?this.emitErrorIfOpen(s):this.emitFinalIfOpen();this.pendingUsage=void 0}emitFinalIfOpen(){this.terminalState==="open"&&(this.terminalState="final",this.emitEvent({state:"final",usage:this.pendingUsage,agentSessionId:this.agentSessionId??void 0}),this.killProcess().catch(()=>{}))}emitErrorIfOpen(e){this.terminalState==="open"&&(this.terminalState="error",this.emitEvent({state:"error",message:b(e)}),this.scheduleProcessClose())}resetRunState(){this.pendingUsage=void 0,this.terminalState="open",this.deltaItemIds.clear(),this.lastTransientStatus="",this.clearForceCloseTimer(),this.resetTextState()}emitTransientStatus(e){const t=
|
|
8
|
+
`);this.emitText(s,"block")}break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{(e.type==="item.started"||e.type==="item.completed")&&this.emitApprovalPending(t);break}case"error":{e.type==="item.completed"&&t.message&&this.emitEvent({state:"error",message:t.message});break}default:break}}handleStreamEvent(e){const t=e.type??e.event;switch(t?.startsWith("item.")&&this.handleCodexItemLine(e),t){case"turn.completed":{const r=e.usage;if(r){const i=r.input_tokens??r.prompt_tokens,n=r.output_tokens??r.completion_tokens;(i!=null||n!=null)&&(this.pendingUsage={inputTokens:i??0,outputTokens:n??0})}this.emitFinalIfOpen();return}case"turn.failed":{const r=typeof e.error=="object"&&e.error?.message?e.error.message:typeof e.error=="string"?e.error:"turn failed";this.emitErrorIfOpen(r);return}case"error":{const r=typeof e.message=="string"?e.message:"";if(r.includes("Reconnecting"))return;this.emitErrorIfOpen(r||(typeof e.error=="string"?e.error:"stream error"));return}case"thread.started":{const r=e.thread_id??e.session_id??e.id;typeof r=="string"&&r&&(this.agentSessionId=r,this.emitEvent({state:"start",agentSessionId:this.agentSessionId}));return}case"turn.started":return}if(t?.startsWith("item."))return;switch(e.type??e.event){case"message":case"text":case"content":{const r=e.content??e.text;r&&this.emitText(r);break}case"function_call":case"tool_call":{if(this.isApprovalLikeName(e.name)){this.emitApprovalPending(e);break}if(e.name&&f(e.name))return;this.emitEvent({state:"tool-call",name:e.name,args:e.arguments??e.input});break}case"function_call_output":case"tool_result":{if(e.name&&f(e.name))return;this.emitEvent({state:"tool-result",name:e.name,result:e.output??e.result});break}case"approval_request":case"approvalRequest":case"permission_request":case"permissionRequest":case"user_input_required":case"userInputRequired":{this.emitApprovalPending(e);break}case"error":break;case"done":case"completed":{e.usage&&(this.pendingUsage={inputTokens:e.usage.prompt_tokens??e.usage.input_tokens??0,outputTokens:e.usage.completion_tokens??e.usage.output_tokens??0}),this.emitFinalIfOpen();break}}}emitEvent(e){if(this.terminalState!=="open"&&e.state!=="final"&&e.state!=="error"&&e.state!=="aborted")return;const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}isApprovalLikeName(e){return typeof e!="string"?!1:/approval|permission|confirm|user[_-]?input|request[_-]?user/i.test(e)}emitApprovalPending(e){const t=typeof e.command=="string"?e.command:"",s=typeof e.title=="string"&&e.title.trim()?e.title:"\u9700\u8981\u7528\u6237\u786E\u8BA4",r=typeof e.prompt=="string"?e.prompt:typeof e.reason=="string"?e.reason:typeof e.message=="string"?e.message:t?`Codex \u8BF7\u6C42\u6267\u884C\u547D\u4EE4\uFF1A${t}`:"Codex \u6B63\u5728\u7B49\u5F85\u7528\u6237\u786E\u8BA4\u540E\u7EE7\u7EED\u3002";this.emitEvent({state:"approval-pending",approval:{title:s,content:r,source:"codex",actionHint:"\u5F53\u524D\u795E\u5FF5\u6682\u4E0D\u652F\u6301\u8FDC\u7A0B\u786E\u8BA4\uFF0C\u8BF7\u56DE\u5230\u8FD0\u884C Codex \u7684\u7535\u8111/\u7EC8\u7AEF\u5B8C\u6210\u786E\u8BA4\u3002"}})}async killProcess(){const e=this.process;if(this.appServerReady=null,this.activeTurnId=null,!e){this.rejectAllPending(new Error("codex app-server stopped"));return}this.process=null,this.clearForceCloseTimer(),e.kill("SIGTERM"),await new Promise(t=>{e.on("close",t),setTimeout(()=>{e.kill("SIGKILL"),t()},3e3)}),this.rejectAllPending(new Error("codex app-server stopped"))}rejectAllPending(e){for(const[t,s]of this.pendingRequests.entries())clearTimeout(s.timer),s.reject(e),this.pendingRequests.delete(t)}handleProcessClose(e,t){const s=T(t);if(e!==0&&e!==null){const r=s||`codex exited with code ${e}`;this.emitErrorIfOpen(r)}else z(s)?this.emitErrorIfOpen(s):this.emitFinalIfOpen();this.pendingUsage=void 0}emitFinalIfOpen(){this.terminalState==="open"&&(this.terminalState="final",this.emitEvent({state:"final",usage:this.pendingUsage,agentSessionId:this.agentSessionId??void 0}),this.killProcess().catch(()=>{}))}emitErrorIfOpen(e){this.terminalState==="open"&&(this.terminalState="error",this.emitEvent({state:"error",message:b(e)}),this.scheduleProcessClose())}resetRunState(){this.pendingUsage=void 0,this.terminalState="open",this.deltaItemIds.clear(),this.lastTransientStatus="",this.clearForceCloseTimer(),this.resetTextState()}emitTransientStatus(e){const t=L(e);!t||t===this.lastTransientStatus||this.terminalState!=="open"||(this.lastTransientStatus=t,this.emitEvent({state:"delta",text:`${t}
|
|
9
9
|
`,thinking:!0}))}resetTextState(){this.hasEmittedText=!1,this.textTail=""}emitText(e,t="delta"){if(!e)return;let s=H(e);s&&(t==="block"&&this.hasEmittedText&&!s.startsWith(`
|
|
10
10
|
`)&&(this.textTail.endsWith(`
|
|
11
11
|
`)?s=`
|
|
@@ -13,4 +13,4 @@ ${s}`:this.textTail.endsWith(`
|
|
|
13
13
|
|
|
14
14
|
`)||(s=`
|
|
15
15
|
|
|
16
|
-
${s}`)),this.hasEmittedText=!0,this.textTail=(this.textTail+s).slice(-4),this.emitEvent({state:"delta",text:s}))}scheduleProcessClose(){const e=this.process;!e||this.forceCloseTimer||(this.forceCloseTimer=setTimeout(()=>{this.forceCloseTimer=null,this.process===e&&(e.kill("SIGTERM"),setTimeout(()=>{this.process===e&&e.kill("SIGKILL")},1e3))},250))}clearForceCloseTimer(){this.forceCloseTimer&&(clearTimeout(this.forceCloseTimer),this.forceCloseTimer=null)}}P("codex",()=>new
|
|
16
|
+
${s}`)),this.hasEmittedText=!0,this.textTail=(this.textTail+s).slice(-4),this.emitEvent({state:"delta",text:s}))}scheduleProcessClose(){const e=this.process;!e||this.forceCloseTimer||(this.forceCloseTimer=setTimeout(()=>{this.forceCloseTimer=null,this.process===e&&(e.kill("SIGTERM"),setTimeout(()=>{this.process===e&&e.kill("SIGKILL")},1e3))},250))}clearForceCloseTimer(){this.forceCloseTimer&&(clearTimeout(this.forceCloseTimer),this.forceCloseTimer=null)}}P("codex",()=>new se);export{se as CodexAdapter,te as buildCodexQueueArgs,ee as buildCodexQueuedText,V as isCodexActiveWriterError,K as isCodexExcludeTurnsUnsupportedError,Q as isCodexPaginatedHistoryUnsupportedError,me as isCodexUnsupportedEffortError,fe as isMissingCodexRolloutError,ge as normalizeCodexModelId,ve as normalizeCodexReasoningEffort};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createHash as N}from"node:crypto";import
|
|
2
|
-
`).trim())}const
|
|
3
|
-
`).replace(/\n+$/g,""):""}function
|
|
4
|
-
`).trim()}function
|
|
1
|
+
import{createHash as N}from"node:crypto";import m from"node:fs";import C from"node:os";import n from"node:path";import{buildToolArgsSummary as E}from"../session/tool-summary.js";const h=64*1024*1024,x=["/root/.claude-mem/observer-session"],I=x.map(D);function R(e){return w(e.replace(/\r\n/g,`
|
|
2
|
+
`).trim())}const _=/^\s*::git-[a-z-]+\{[^\n]*\}\s*$/gm;function w(e){if(!e)return"";if(!/(^|\n)\s*::git-[a-z-]+\{[^\n]*\}\s*(?=\n|$)/.test(e))return e;const r=e.replace(_,"");return r.trim()?r.replace(/[ \t]+\n/g,`
|
|
3
|
+
`).replace(/\n+$/g,""):""}function v(e){if(typeof e!="string")return null;const t=Date.parse(e);return Number.isFinite(t)?t:null}function F(e){try{const t=JSON.parse(e);return typeof t=="object"&&t!==null?t:null}catch{return null}}function G(e,t,r){const s=m.statSync(e).size;if(t>=s)return s;const y=m.openSync(e,"r");try{const S=Buffer.allocUnsafe(262144);let l=t,p=t,o=Buffer.alloc(0),f=!1;for(;l<s;){const g=m.readSync(y,S,0,Math.min(262144,s-l),l);if(g<=0)break;l+=g;let c=S.subarray(0,g);o.length>0&&(c=Buffer.concat([o,c]),o=Buffer.alloc(0));let u=0;for(;u<c.length;){const a=c.indexOf(10,u);if(a<0)break;const d=c.subarray(u,a),T=p;p+=a-u+1,u=a+1,!f&&d.length>0&&d.length<=h&&r(d.toString("utf8"),T),f=!1}if(u<c.length){const a=c.subarray(u);f||a.length>h?(f=!0,p+=a.length,o=Buffer.alloc(0)):o=Buffer.from(a)}}return!f&&o.length>0&&o.length<=h&&r(o.toString("utf8"),p),s}finally{m.closeSync(y)}}function M(e){return typeof e.cwd=="string"&&e.cwd.trim()?e.cwd:null}function U(e){return n.basename(n.dirname(e))==="subagents"}function b(e){const t=n.resolve(e);return process.platform==="win32"?t.toLowerCase():t}function z(e,t){const r=b(e),i=b(t);return r===i||r.startsWith(i+n.sep)}function D(e){return n.resolve(e).replace(/\//g,"-")}function V(e){return x.some(t=>z(e,t))}function O(e){return I.includes(e)}function H(e){const t=n.join(C.homedir(),".claude","projects"),r=n.relative(t,e);if(!r||r.startsWith("..")||n.isAbsolute(r))return!1;const[i]=r.split(n.sep);return i?O(i):!1}function W(e,t){return`${e}:${t}`}function K(e,t,r){return`${N("sha1").update(e).digest("hex").slice(0,16)}:${t}:${r}`}function X(e){if(e==null)return"";if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function Y(e){return e.replace(/\r\n/g,`
|
|
4
|
+
`).trim()}function q(e){if(typeof e!="string")return e;const t=e.trim();if(!t)return"";try{return JSON.parse(t)}catch{return e}}function Q(e,t,r){const i=E(t),s={v:1,type:"tool",name:e,status:r!==void 0?"completed":"running",resultOmitted:!0,...i!==void 0?{argsSummary:i}:{}};return JSON.stringify(s)}function k(e){return e.replace(/[[\]\\]/g,"\\$&")}function A(e,t="Generated image"){return``}function Z(e){const t=n.basename(e)||"generated-image.png";return JSON.stringify({v:1,type:"image",content:A(e,t),attachments:[{path:e,name:t,mimeType:"image/png",kind:"image"}]})}function ee(e){const t=n.extname(e).toLowerCase();return t===".png"?"image/png":t===".jpg"||t===".jpeg"?"image/jpeg":t===".webp"?"image/webp":t===".gif"?"image/gif":"application/octet-stream"}export{Z as buildImagePayload,A as buildMarkdownImageRef,Q as buildToolPayload,D as encodeClaudeProjectDir,k as escapeMarkdownLabel,ee as inferMimeType,U as isClaudeSubagentTranscript,z as isSameOrChildPath,W as makeCursor,K as makeEventKey,b as normalizePathForCompare,R as normalizeText,Y as normalizeToolText,q as parseStructuredString,M as readClaudeEventCwd,G as readJsonlLines,v as readTimestamp,F as safeParse,X as safeStringify,O as shouldIgnoreClaudeProjectDir,H as shouldIgnoreClaudeTranscriptPath,V as shouldIgnoreNativeScanPath};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import F from"node:os";import{createAgent as Q}from"../../agents/adapter.js";import{buildApprovalPendingPayload as Y,buildUserMessagePayload as V}from"@shennian/wire";import{reportLog as T}from"../../log-reporter.js";import{lookupClaudeTranscriptCwd as G}from"../../native-fusion/parsers.js";import{appendMessage as x,recordSession as O}from"../store.js";import{mergeProjectedSessions as X}from"../projection.js";import{buildManagedAgentEnv as Z}from"../../agents/config-status.js";import{materializeRemoteChatAttachments as ee}from"../remote-attachments.js";function
|
|
2
|
-
`),s=t>0?Math.min(t,80):Math.min(e.length,80);return e.slice(0,s)}function ae(e,t,s={}){if(e.state==="tool-call"||e.state==="tool-result"){const a={runId:e.runId,sourceSeq:e.seq};return{state:e.state,runId:e.runId,seq:e.seq,sessionId:t,detailRef:a,...e.name?{name:e.name}:{},...e.source?{source:e.source}:{},...e.agentSessionId?{agentSessionId:e.agentSessionId}:{},...s}}return{...e,sessionId:t,...s}}const se=3e4;function re(e){return e.state==="heartbeat"?e.runPhase??null:e.state==="tool-call"||e.state==="tool-result"?"tool_running":e.state==="approval-pending"?"waiting_approval":e.state==="delta"?e.thinking?"thinking":"streaming_text":e.state==="init"||e.state==="start"?"thinking":null}function oe(e,t){return`Agent send failed: ${t instanceof Error?t.message:String(t)}`}function W(e,t){return e!=="manager"?e:t==="claude"?"claude":"codex"}function L(e,t,s){e.client.sendEvent({type:"event",event:"session.message",payload:{sessionId:t.sessionId,message:t,session:{id:t.sessionId,agentType:s.agentType,agentSessionId:s.agentSessionId??null,modelId:s.modelId??null,workDir:s.workDir,status:"active",externalChannel:null}}})}function de(e,t){O({sessionId:t.sessionId,agentType:t.agentType,workDir:t.workDir,agentSessionId:t.agentSessionId??null,modelId:t.modelId??null}),e.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:t.sessionId,agentType:t.agentType,agentSessionId:t.agentSessionId??null,modelId:t.modelId??null,workDir:t.workDir,status:"active",externalChannel:null}}})}function H(e){return Z(e)}function U(e,t,s){return{}}function j(e,t,s,a,d,l){e.configure?.({sessionId:t,externalChannel:a??null,env:{...H(s),...U(t,a,d),...l?{SHENNIAN_ROOM_REGISTRY_KEY:l}:{}}})}function ie(e,t,s){if(e!=="claude"||!s)return t;const a=t.trim();return!!a&&a.startsWith("-")&&!a.includes("/")?G(s)??t:t}function le(e,t,s,a){let d=null;function l(n,r={}){e.client.sendAgentEvent({type:"event",event:"agent",payload:ae(n,t,r),seq:n.seq,id:`agent-evt-${n.runId}-${n.seq}`})}function g(n){n?.heartbeatTimer&&(clearInterval(n.heartbeatTimer),n.heartbeatTimer=null)}function i(n){if(!n.currentRunId||!n.currentRunPhase)return;const r=n.heartbeatSeq++;e.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:t,runId:n.currentRunId,seq:r,runPhase:n.currentRunPhase},seq:r,id:`agent-heartbeat-${n.currentRunId}-${r}-${Date.now()}`})}function f(n){!n||n.heartbeatTimer||(n.heartbeatTimer=setInterval(()=>{i(n)},se),n.heartbeatTimer.unref?.())}function y(n){const r=n?.pendingTextEvent;!n||!r||!r.text||(l({state:"delta",runId:r.runId,seq:r.seq,text:r.text,thinking:r.thinking||void 0}),n.pendingTextEvent=null)}a.on("agentEvent",n=>{const r=e.sessions.get(t),S=re(n),w=n.state==="final"||n.state==="error"||n.state==="aborted";if(r&&(r.nextEventSeq=n.seq+1,w||(r.currentRunId=n.runId),!w&&S&&(r.currentRunPhase=S,f(r)),n.agentSessionId&&(r.agentSessionId=n.agentSessionId)),e.managerRuntime?.noteAgentEvent(t,n),n.state==="delta"&&n.thinking)return;n.state!=="delta"&&T({level:"info",sessionId:t,wsEvent:`agent.${n.state}`,wsDirection:"out",metadata:{runId:n.runId,seq:n.seq,agentType:s}}),n.state==="delta"&&n.text&&!n.thinking?x(t,{id:`agent-${n.runId}-${n.seq}`,sessionId:t,role:"agent",ts:Date.now(),payload:n.text}):n.state==="tool-call"||n.state==="tool-result"?x(t,{id:`agent-${n.runId}-${n.seq}`,sessionId:t,role:"agent",ts:Date.now(),payload:JSON.stringify({v:1,type:n.state==="tool-call"?"tool_use":"tool_result",name:n.name,status:n.state==="tool-call"?"running":"completed",detailRef:{runId:n.runId,sourceSeq:n.seq},args:n.args,result:n.result})}):n.state==="approval-pending"?x(t,{id:`agent-${n.runId||"run"}-${n.seq}`,sessionId:t,role:"agent",ts:Date.now(),payload:Y(n.approval)}):(n.state==="error"||n.state==="aborted")&&n.message&&x(t,{id:`agent-${n.runId||"run"}-${n.seq}`,sessionId:t,role:"agent",ts:Date.now(),payload:n.message});const I=`${t}:${n.runId}`;if(n.state==="delta"&&!n.thinking&&n.text&&e.runTextAcc.set(I,(e.runTextAcc.get(I)??"")+n.text),n.agentSessionId&&n.agentSessionId!==d&&(d=n.agentSessionId,e.nativeFusion?.noteManagedSourceSession(t,W(s,n.source),n.agentSessionId),r&&O({sessionId:t,agentType:s,workDir:r.workDir,agentSessionId:n.agentSessionId}),e.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:t,agentType:s,agentSessionId:n.agentSessionId}}})),n.state==="delta"){const m=n.text??"";if(!m)return;r?.pendingTextEvent&&r.pendingTextEvent.runId!==n.runId&&y(r),r&&!r.pendingTextEvent&&(r.pendingTextEvent={runId:n.runId,seq:n.seq,text:"",thinking:!1}),r?.pendingTextEvent&&(r.pendingTextEvent.text+=m,r.pendingTextEvent.seq=n.seq);return}let R={};if(n.state==="final"){y(r);const m=e.runTextAcc.get(I)??"";m&&(R={messageSummary:ne(m)}),e.runTextAcc.delete(I)}else n.state==="error"||n.state==="aborted"?(y(r),e.runTextAcc.delete(I)):(n.state==="tool-call"||n.state==="tool-result"||n.state==="approval-pending")&&y(r);w&&r?.currentRunId===n.runId&&(r.currentRunId=null,r.currentRunPhase=null,r.nextEventSeq=0,g(r),e.chatQueue?.noteTerminal(t)),l(n,R)}),a.on("error",n=>{console.error(`[chat.send] adapter error sessionId=${t} agentType=${s}: ${n.message}`),e.sessions.delete(t),e.chatQueue?.noteTerminal(t),e.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:t,message:n.message,runId:"",seq:0}})})}function ce(e,t){if(e.processedReqIds.add(t),e.processedReqIds.size>1e3){const s=e.processedReqIds.values().next().value;e.processedReqIds.delete(s)}}async function P(e){e.heartbeatTimer&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=null),e.adapter.removeAllListeners(),await e.adapter.stop().catch(()=>{})}function B(e,t,s,a,d,l,g){return g?e.send(t,s,a,d,l,g):l?.trim()?e.send(t,s,a,d,l):d?.length?e.send(t,s,a,d):a?e.send(t,s,a):e.send(t,s)}async function ue(e,t,s,a,d,l,g){e.evictIdleSessions();const i=Q(s);if(!i)throw new Error(`Unsupported agent: ${s}`);j(i,t,s,l,g),await i.start(t,a,d);const f={adapter:i,workDir:a,agentType:s,agentSessionId:d??null,lastActiveAt:Date.now(),currentRunId:null,currentRunPhase:null,nextEventSeq:0,heartbeatSeq:0,heartbeatTimer:null,pendingTextEvent:null,externalChannel:l??null,externalReplyTarget:g??null,externalChannelEnv:{...H(s),...U(t,l,g)}};return e.sessions.set(t,f),le(e,t,s,i),f}function ge(e,t){const s=e.sessions.get(t),a=s?.currentRunId;if(!s||!a)return;const d=s.nextEventSeq;e.runTextAcc.delete(`${t}:${a}`),s.pendingTextEvent=null,s.currentRunId=null,s.currentRunPhase=null,s.nextEventSeq=0,s.heartbeatTimer&&(clearInterval(s.heartbeatTimer),s.heartbeatTimer=null),e.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"aborted",sessionId:t,runId:a,seq:d},seq:d,id:`agent-evt-${a}-${d}`}),e.chatQueue?.noteTerminal(t)}async function xe(e,t,s){if(e.processedReqIds.has(t.id)){e.client.sendRes({type:"res",id:t.id,ok:!0});return}ce(e,t.id);const{sessionId:a,text:d,agentType:l,workDir:g,agentSessionId:i,modelId:f,systemPrompt:y,managerDefaultWorkerAgentType:n,managerDefaultWorkerModelId:r,reasoningEffort:S,clientMessageId:w,sessionListProjection:I,waitForDispatch:R,responseId:m,roomContextRegistryKey:$,suppressExternalOwnerEcho:J}=t.params,A=m||t.id;X(I);const b=null,M="";if(!a||!d){e.processedReqIds.delete(t.id),e.client.sendRes({type:"res",id:A,ok:!1,error:"sessionId and text are required"});return}const u=l;u==="manager"&&e.managerRuntime?.setManagerWorkerDefaults(a,n??null,r??null);const q=(u==="claude"||u==="codex"||u==="workbuddy")&&typeof S=="string"&&S.trim()?S.trim():void 0,E=e.resolvePath(ie(u,g||F.homedir(),i)||F.homedir()),D=E,_=te(t.params.attachments),p=_?.length?await ee({text:d,attachments:_,workDir:E}):{text:d,attachments:_,localized:!1};let o=e.sessions.get(a);if(o){if(o.lastActiveAt=Date.now(),o.agentType!==u||o.workDir!==E||JSON.stringify(o.externalChannel??null)!==JSON.stringify(b??null)){e.sessions.delete(a);try{await P(o)}catch{e.processedReqIds.delete(t.id)}o=void 0}else if(i&&o.agentSessionId!==i)try{await o.adapter.resume(i),o.agentSessionId=i}catch{e.sessions.delete(a);try{await P(o)}catch{e.processedReqIds.delete(t.id)}o=void 0}}if(!o)try{o=await ue(e,a,u,E,i,b,M)}catch(c){const h=c instanceof Error&&c.message.startsWith("Unsupported agent:")?c.message:`Failed to start ${l}: ${c instanceof Error?c.message:String(c)}`;console.error(`[chat.send] start failed reqId=${t.id} sessionId=${a} agentType=${l} workDir=${E} agentSessionId=${i??""}: ${h}`),e.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:a,message:h,runId:"",seq:0}}),e.processedReqIds.delete(t.id),e.client.sendRes({type:"res",id:A,ok:!1,error:h});return}$&&/^[a-f0-9]{64}$/.test($)&&j(o.adapter,a,u,b,M,$);const C={id:w??`user-${t.id}`,sessionId:a,role:"user",ts:Date.now(),payload:V(p.text,p.attachments)};T({level:"info",sessionId:a,wsEvent:"chat.send.start",metadata:{reqId:t.id,agentType:u,modelId:f,reasoningEffort:q}});const z=c=>{de(e,{sessionId:a,agentType:u,workDir:D,agentSessionId:o.agentSessionId??i??null,modelId:f}),o.currentRunId||(o.nextEventSeq=0),e.nativeFusion?.registerManagedSend({sessionId:a,agentType:u,sourceAgentType:W(u,f),canonicalMessageId:w??null,sourceSessionKey:o.agentSessionId??i??null,text:p.text,managedEchoPolicy:c?.deliveryMode==="external_owner_queue"&&!J?"import_following":"suppress_following"}),x(a,C),L(e,C,{agentType:u,workDir:D,agentSessionId:o.agentSessionId??i??null,modelId:f})},v=async(c,h)=>{const k=oe(u,c);console.error(`[chat.send] send failed reqId=${t.id} sessionId=${a} agentType=${l} workDir=${E} agentSessionId=${o.agentSessionId??i??""}: ${k}`),e.sessions.delete(a);try{await P(o)}catch{}if(e.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:a,message:k,runId:"",seq:0}}),!h){const N={id:`agent-error-${t.id}-${Date.now()}`,sessionId:a,role:"agent",ts:Date.now(),payload:k};x(a,N),L(e,N,{agentType:u,workDir:D,agentSessionId:o.agentSessionId??i??null,modelId:f})}h&&(e.processedReqIds.delete(t.id),e.client.sendRes({type:"res",id:A,ok:!1,error:k}))};if(R){let c;try{const h=p.attachments;c=await B(o.adapter,p.text,f,q,h,y,s),T({level:"info",sessionId:a,wsEvent:"chat.send.done",metadata:{reqId:t.id}})}catch(h){await v(h,!0);return}z(c??void 0),e.client.sendRes({type:"res",id:A,ok:!0,...p.localized||c?.deliveryMode==="external_owner_queue"?{payload:{...p.localized?{localizedAttachments:!0}:{},...c?.deliveryMode==="external_owner_queue"?{queued:!0,deliveryMode:c.deliveryMode,queuedSubmissionId:c.queuedSubmissionId}:{}}}:{}}),T({level:"info",sessionId:a,wsEvent:"chat.send.res",metadata:{reqId:t.id,ok:!0}});return}z(),e.client.sendRes({type:"res",id:A,ok:!0,...p.localized?{payload:{localizedAttachments:!0}}:{}}),T({level:"info",sessionId:a,wsEvent:"chat.send.res",metadata:{reqId:t.id,ok:!0}});const K=p.attachments;B(o.adapter,p.text,f,q,K,y,s).then(()=>{T({level:"info",sessionId:a,wsEvent:"chat.send.done",metadata:{reqId:t.id}})}).catch(c=>{v(c,!1)})}async function Ae(e,t){const{sessionId:s}=t.params,a=e.sessions.get(s);if(a){try{await a.adapter.stop()}catch{}ge(e,s),e.activityPublisher?.publish(s,null)}e.client.sendRes({type:"res",id:t.id,ok:!0})}export{Ae as handleChatAbort,xe as handleChatSend,de as sendSessionUpdateEvent};
|
|
1
|
+
import F from"node:os";import{createAgent as Q}from"../../agents/adapter.js";import{buildApprovalPendingPayload as Y,buildUserMessagePayload as V}from"@shennian/wire";import{reportLog as T}from"../../log-reporter.js";import{lookupClaudeTranscriptCwd as G}from"../../native-fusion/parsers.js";import{appendMessage as x,recordSession as O}from"../store.js";import{mergeProjectedSessions as X}from"../projection.js";import{buildManagedAgentEnv as Z}from"../../agents/config-status.js";import{materializeRemoteChatAttachments as ee}from"../remote-attachments.js";import{buildToolArgsSummary as te}from"../tool-summary.js";function ne(e){if(!Array.isArray(e))return;const t=e.map(r=>{if(!r||typeof r!="object")return null;const a=r,o=typeof a.path=="string"?a.path:"",l=typeof a.name=="string"?a.name:"",g=typeof a.mimeType=="string"?a.mimeType:"";if(!o||!l||!g)return null;const i=typeof a.previewData=="string"&&a.previewData.trim()?a.previewData.trim():void 0;return{path:o,name:l,mimeType:g,kind:g.startsWith("image/")?"image":"file",...i?{previewData:i}:{}}}).filter(r=>r!=null);return t.length?t:void 0}function ae(e){const t=e.indexOf(`
|
|
2
|
+
`),r=t>0?Math.min(t,80):Math.min(e.length,80);return e.slice(0,r)}function re(e,t,r={}){if(e.state==="tool-call"||e.state==="tool-result"){const a={runId:e.runId,sourceSeq:e.seq},o=te(e.args);return{state:e.state,runId:e.runId,seq:e.seq,sessionId:t,detailRef:a,...e.name?{name:e.name}:{},...o!==void 0?{argsSummary:o}:{},...e.source?{source:e.source}:{},...e.agentSessionId?{agentSessionId:e.agentSessionId}:{},...r}}return{...e,sessionId:t,...r}}const se=3e4;function oe(e){return e.state==="heartbeat"?e.runPhase??null:e.state==="tool-call"||e.state==="tool-result"?"tool_running":e.state==="approval-pending"?"waiting_approval":e.state==="delta"?e.thinking?"thinking":"streaming_text":e.state==="init"||e.state==="start"?"thinking":null}function de(e,t){return`Agent send failed: ${t instanceof Error?t.message:String(t)}`}function W(e,t){return e!=="manager"?e:t==="claude"?"claude":"codex"}function L(e,t,r){e.client.sendEvent({type:"event",event:"session.message",payload:{sessionId:t.sessionId,message:t,session:{id:t.sessionId,agentType:r.agentType,agentSessionId:r.agentSessionId??null,modelId:r.modelId??null,workDir:r.workDir,status:"active",externalChannel:null}}})}function ie(e,t){O({sessionId:t.sessionId,agentType:t.agentType,workDir:t.workDir,agentSessionId:t.agentSessionId??null,modelId:t.modelId??null}),e.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:t.sessionId,agentType:t.agentType,agentSessionId:t.agentSessionId??null,modelId:t.modelId??null,workDir:t.workDir,status:"active",externalChannel:null}}})}function H(e){return Z(e)}function U(e,t,r){return{}}function j(e,t,r,a,o,l){e.configure?.({sessionId:t,externalChannel:a??null,env:{...H(r),...U(t,a,o),...l?{SHENNIAN_ROOM_REGISTRY_KEY:l}:{}}})}function le(e,t,r){if(e!=="claude"||!r)return t;const a=t.trim();return!!a&&a.startsWith("-")&&!a.includes("/")?G(r)??t:t}function ce(e,t,r,a){let o=null;function l(n,s={}){e.client.sendAgentEvent({type:"event",event:"agent",payload:re(n,t,s),seq:n.seq,id:`agent-evt-${n.runId}-${n.seq}`})}function g(n){n?.heartbeatTimer&&(clearInterval(n.heartbeatTimer),n.heartbeatTimer=null)}function i(n){if(!n.currentRunId||!n.currentRunPhase)return;const s=n.heartbeatSeq++;e.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:t,runId:n.currentRunId,seq:s,runPhase:n.currentRunPhase},seq:s,id:`agent-heartbeat-${n.currentRunId}-${s}-${Date.now()}`})}function f(n){!n||n.heartbeatTimer||(n.heartbeatTimer=setInterval(()=>{i(n)},se),n.heartbeatTimer.unref?.())}function y(n){const s=n?.pendingTextEvent;!n||!s||!s.text||(l({state:"delta",runId:s.runId,seq:s.seq,text:s.text,thinking:s.thinking||void 0}),n.pendingTextEvent=null)}a.on("agentEvent",n=>{const s=e.sessions.get(t),S=oe(n),w=n.state==="final"||n.state==="error"||n.state==="aborted";if(s&&(s.nextEventSeq=n.seq+1,w||(s.currentRunId=n.runId),!w&&S&&(s.currentRunPhase=S,f(s)),n.agentSessionId&&(s.agentSessionId=n.agentSessionId)),e.managerRuntime?.noteAgentEvent(t,n),n.state==="delta"&&n.thinking)return;n.state!=="delta"&&T({level:"info",sessionId:t,wsEvent:`agent.${n.state}`,wsDirection:"out",metadata:{runId:n.runId,seq:n.seq,agentType:r}}),n.state==="delta"&&n.text&&!n.thinking?x(t,{id:`agent-${n.runId}-${n.seq}`,sessionId:t,role:"agent",ts:Date.now(),payload:n.text}):n.state==="tool-call"||n.state==="tool-result"?x(t,{id:`agent-${n.runId}-${n.seq}`,sessionId:t,role:"agent",ts:Date.now(),payload:JSON.stringify({v:1,type:n.state==="tool-call"?"tool_use":"tool_result",name:n.name,status:n.state==="tool-call"?"running":"completed",detailRef:{runId:n.runId,sourceSeq:n.seq},args:n.args,result:n.result})}):n.state==="approval-pending"?x(t,{id:`agent-${n.runId||"run"}-${n.seq}`,sessionId:t,role:"agent",ts:Date.now(),payload:Y(n.approval)}):(n.state==="error"||n.state==="aborted")&&n.message&&x(t,{id:`agent-${n.runId||"run"}-${n.seq}`,sessionId:t,role:"agent",ts:Date.now(),payload:n.message});const m=`${t}:${n.runId}`;if(n.state==="delta"&&!n.thinking&&n.text&&e.runTextAcc.set(m,(e.runTextAcc.get(m)??"")+n.text),n.agentSessionId&&n.agentSessionId!==o&&(o=n.agentSessionId,e.nativeFusion?.noteManagedSourceSession(t,W(r,n.source),n.agentSessionId),s&&O({sessionId:t,agentType:r,workDir:s.workDir,agentSessionId:n.agentSessionId}),e.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:t,agentType:r,agentSessionId:n.agentSessionId}}})),n.state==="delta"){const I=n.text??"";if(!I)return;s?.pendingTextEvent&&s.pendingTextEvent.runId!==n.runId&&y(s),s&&!s.pendingTextEvent&&(s.pendingTextEvent={runId:n.runId,seq:n.seq,text:"",thinking:!1}),s?.pendingTextEvent&&(s.pendingTextEvent.text+=I,s.pendingTextEvent.seq=n.seq);return}let R={};if(n.state==="final"){y(s);const I=e.runTextAcc.get(m)??"";I&&(R={messageSummary:ae(I)}),e.runTextAcc.delete(m)}else n.state==="error"||n.state==="aborted"?(y(s),e.runTextAcc.delete(m)):(n.state==="tool-call"||n.state==="tool-result"||n.state==="approval-pending")&&y(s);w&&s?.currentRunId===n.runId&&(s.currentRunId=null,s.currentRunPhase=null,s.nextEventSeq=0,g(s),e.chatQueue?.noteTerminal(t)),l(n,R)}),a.on("error",n=>{console.error(`[chat.send] adapter error sessionId=${t} agentType=${r}: ${n.message}`),e.sessions.delete(t),e.chatQueue?.noteTerminal(t),e.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:t,message:n.message,runId:"",seq:0}})})}function ue(e,t){if(e.processedReqIds.add(t),e.processedReqIds.size>1e3){const r=e.processedReqIds.values().next().value;e.processedReqIds.delete(r)}}async function P(e){e.heartbeatTimer&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=null),e.adapter.removeAllListeners(),await e.adapter.stop().catch(()=>{})}function B(e,t,r,a,o,l,g){return g?e.send(t,r,a,o,l,g):l?.trim()?e.send(t,r,a,o,l):o?.length?e.send(t,r,a,o):a?e.send(t,r,a):e.send(t,r)}async function ge(e,t,r,a,o,l,g){e.evictIdleSessions();const i=Q(r);if(!i)throw new Error(`Unsupported agent: ${r}`);j(i,t,r,l,g),await i.start(t,a,o);const f={adapter:i,workDir:a,agentType:r,agentSessionId:o??null,lastActiveAt:Date.now(),currentRunId:null,currentRunPhase:null,nextEventSeq:0,heartbeatSeq:0,heartbeatTimer:null,pendingTextEvent:null,externalChannel:l??null,externalReplyTarget:g??null,externalChannelEnv:{...H(r),...U(t,l,g)}};return e.sessions.set(t,f),ce(e,t,r,i),f}function fe(e,t){const r=e.sessions.get(t),a=r?.currentRunId;if(!r||!a)return;const o=r.nextEventSeq;e.runTextAcc.delete(`${t}:${a}`),r.pendingTextEvent=null,r.currentRunId=null,r.currentRunPhase=null,r.nextEventSeq=0,r.heartbeatTimer&&(clearInterval(r.heartbeatTimer),r.heartbeatTimer=null),e.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"aborted",sessionId:t,runId:a,seq:o},seq:o,id:`agent-evt-${a}-${o}`}),e.chatQueue?.noteTerminal(t)}async function Re(e,t,r){if(e.processedReqIds.has(t.id)){e.client.sendRes({type:"res",id:t.id,ok:!0});return}ue(e,t.id);const{sessionId:a,text:o,agentType:l,workDir:g,agentSessionId:i,modelId:f,systemPrompt:y,managerDefaultWorkerAgentType:n,managerDefaultWorkerModelId:s,reasoningEffort:S,clientMessageId:w,sessionListProjection:m,waitForDispatch:R,responseId:I,roomContextRegistryKey:$,suppressExternalOwnerEcho:J}=t.params,A=I||t.id;X(m);const b=null,M="";if(!a||!o){e.processedReqIds.delete(t.id),e.client.sendRes({type:"res",id:A,ok:!1,error:"sessionId and text are required"});return}const u=l;u==="manager"&&e.managerRuntime?.setManagerWorkerDefaults(a,n??null,s??null);const q=(u==="claude"||u==="codex"||u==="workbuddy")&&typeof S=="string"&&S.trim()?S.trim():void 0,E=e.resolvePath(le(u,g||F.homedir(),i)||F.homedir()),D=E,_=ne(t.params.attachments),p=_?.length?await ee({text:o,attachments:_,workDir:E}):{text:o,attachments:_,localized:!1};let d=e.sessions.get(a);if(d){if(d.lastActiveAt=Date.now(),d.agentType!==u||d.workDir!==E||JSON.stringify(d.externalChannel??null)!==JSON.stringify(b??null)){e.sessions.delete(a);try{await P(d)}catch{e.processedReqIds.delete(t.id)}d=void 0}else if(i&&d.agentSessionId!==i)try{await d.adapter.resume(i),d.agentSessionId=i}catch{e.sessions.delete(a);try{await P(d)}catch{e.processedReqIds.delete(t.id)}d=void 0}}if(!d)try{d=await ge(e,a,u,E,i,b,M)}catch(c){const h=c instanceof Error&&c.message.startsWith("Unsupported agent:")?c.message:`Failed to start ${l}: ${c instanceof Error?c.message:String(c)}`;console.error(`[chat.send] start failed reqId=${t.id} sessionId=${a} agentType=${l} workDir=${E} agentSessionId=${i??""}: ${h}`),e.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:a,message:h,runId:"",seq:0}}),e.processedReqIds.delete(t.id),e.client.sendRes({type:"res",id:A,ok:!1,error:h});return}$&&/^[a-f0-9]{64}$/.test($)&&j(d.adapter,a,u,b,M,$);const C={id:w??`user-${t.id}`,sessionId:a,role:"user",ts:Date.now(),payload:V(p.text,p.attachments)};T({level:"info",sessionId:a,wsEvent:"chat.send.start",metadata:{reqId:t.id,agentType:u,modelId:f,reasoningEffort:q}});const z=c=>{ie(e,{sessionId:a,agentType:u,workDir:D,agentSessionId:d.agentSessionId??i??null,modelId:f}),d.currentRunId||(d.nextEventSeq=0),e.nativeFusion?.registerManagedSend({sessionId:a,agentType:u,sourceAgentType:W(u,f),canonicalMessageId:w??null,sourceSessionKey:d.agentSessionId??i??null,text:p.text,managedEchoPolicy:c?.deliveryMode==="external_owner_queue"&&!J?"import_following":"suppress_following"}),x(a,C),L(e,C,{agentType:u,workDir:D,agentSessionId:d.agentSessionId??i??null,modelId:f})},N=async(c,h)=>{const k=de(u,c);console.error(`[chat.send] send failed reqId=${t.id} sessionId=${a} agentType=${l} workDir=${E} agentSessionId=${d.agentSessionId??i??""}: ${k}`),e.sessions.delete(a);try{await P(d)}catch{}if(e.client.sendEvent({type:"event",event:"agent",payload:{state:"error",sessionId:a,message:k,runId:"",seq:0}}),!h){const v={id:`agent-error-${t.id}-${Date.now()}`,sessionId:a,role:"agent",ts:Date.now(),payload:k};x(a,v),L(e,v,{agentType:u,workDir:D,agentSessionId:d.agentSessionId??i??null,modelId:f})}h&&(e.processedReqIds.delete(t.id),e.client.sendRes({type:"res",id:A,ok:!1,error:k}))};if(R){let c;try{const h=p.attachments;c=await B(d.adapter,p.text,f,q,h,y,r),T({level:"info",sessionId:a,wsEvent:"chat.send.done",metadata:{reqId:t.id}})}catch(h){await N(h,!0);return}z(c??void 0),e.client.sendRes({type:"res",id:A,ok:!0,...p.localized||c?.deliveryMode==="external_owner_queue"?{payload:{...p.localized?{localizedAttachments:!0}:{},...c?.deliveryMode==="external_owner_queue"?{queued:!0,deliveryMode:c.deliveryMode,queuedSubmissionId:c.queuedSubmissionId}:{}}}:{}}),T({level:"info",sessionId:a,wsEvent:"chat.send.res",metadata:{reqId:t.id,ok:!0}});return}z(),e.client.sendRes({type:"res",id:A,ok:!0,...p.localized?{payload:{localizedAttachments:!0}}:{}}),T({level:"info",sessionId:a,wsEvent:"chat.send.res",metadata:{reqId:t.id,ok:!0}});const K=p.attachments;B(d.adapter,p.text,f,q,K,y,r).then(()=>{T({level:"info",sessionId:a,wsEvent:"chat.send.done",metadata:{reqId:t.id}})}).catch(c=>{N(c,!1)})}async function ke(e,t){const{sessionId:r}=t.params,a=e.sessions.get(r);if(a){try{await a.adapter.stop()}catch{}fe(e,r),e.activityPublisher?.publish(r,null)}e.client.sendRes({type:"res",id:t.id,ok:!0})}export{ke as handleChatAbort,Re as handleChatSend,ie as sendSessionUpdateEvent};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function buildToolArgsSummary(value: unknown): unknown;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const o=240;function c(t){if(t==null)return;if(!t||typeof t!="object"||Array.isArray(t))return r(t);const n={};for(const[i,e]of Object.entries(t))if(!(e==null||e==="")&&(n[i]=r(e),Object.keys(n).length===2))break;return Object.keys(n).length?n:void 0}function r(t){if(typeof t=="string")return s(t)?"[SYSTEM CONTEXT REDACTED]":t.replace(/\s+/g," ").trim().slice(0,240);const n=JSON.stringify(t);return String(n??t).replace(/\s+/g," ").slice(0,240)}function s(t){const n=t.trim();return/^<environment_context>[\s\S]*<\/environment_context>$/i.test(n)||/^# AGENTS\.md instructions for [^\n]+[\s\S]*<INSTRUCTIONS>[\s\S]*<\/INSTRUCTIONS>/i.test(n)||/^<turn_aborted>[\s\S]*<\/turn_aborted>$/i.test(n)}export{c as buildToolArgsSummary};
|