shennian 0.2.117 → 0.2.119

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.
@@ -51,13 +51,13 @@
51
51
  },
52
52
  {
53
53
  "file": "src/agents/cursor.js",
54
- "beforeBytes": 8582,
55
- "afterBytes": 3829
54
+ "beforeBytes": 9147,
55
+ "afterBytes": 4197
56
56
  },
57
57
  {
58
58
  "file": "src/agents/custom.js",
59
- "beforeBytes": 10037,
60
- "afterBytes": 5064
59
+ "beforeBytes": 10627,
60
+ "afterBytes": 5463
61
61
  },
62
62
  {
63
63
  "file": "src/agents/detect.js",
@@ -71,8 +71,8 @@
71
71
  },
72
72
  {
73
73
  "file": "src/agents/gemini.js",
74
- "beforeBytes": 5657,
75
- "afterBytes": 2848
74
+ "beforeBytes": 6230,
75
+ "afterBytes": 3224
76
76
  },
77
77
  {
78
78
  "file": "src/agents/manager.js",
@@ -116,13 +116,13 @@
116
116
  },
117
117
  {
118
118
  "file": "src/agents/openclaw.js",
119
- "beforeBytes": 10365,
120
- "afterBytes": 4588
119
+ "beforeBytes": 10951,
120
+ "afterBytes": 4987
121
121
  },
122
122
  {
123
123
  "file": "src/agents/opencode.js",
124
- "beforeBytes": 7660,
125
- "afterBytes": 4001
124
+ "beforeBytes": 8238,
125
+ "afterBytes": 4391
126
126
  },
127
127
  {
128
128
  "file": "src/agents/pi-context.js",
@@ -136,8 +136,8 @@
136
136
  },
137
137
  {
138
138
  "file": "src/agents/platform-instructions.js",
139
- "beforeBytes": 2735,
140
- "afterBytes": 1589
139
+ "beforeBytes": 3342,
140
+ "afterBytes": 1913
141
141
  },
142
142
  {
143
143
  "file": "src/channels/base.js",
@@ -521,8 +521,8 @@
521
521
  },
522
522
  {
523
523
  "file": "src/manager/runtime.js",
524
- "beforeBytes": 60524,
525
- "afterBytes": 31029
524
+ "beforeBytes": 62555,
525
+ "afterBytes": 32116
526
526
  },
527
527
  {
528
528
  "file": "src/native-fusion/config.js",
@@ -1,4 +1,5 @@
1
1
  import { AgentAdapter } from './adapter.js';
2
+ import type { ExternalChannelSessionStatus } from '@shennian/wire';
2
3
  export declare class CursorAdapter extends AgentAdapter {
3
4
  readonly type: "cursor";
4
5
  private process;
@@ -7,6 +8,14 @@ export declare class CursorAdapter extends AgentAdapter {
7
8
  private seq;
8
9
  private runId;
9
10
  private emittedText;
11
+ private externalChannel;
12
+ private shennianSessionId;
13
+ private extraEnv;
14
+ configure(options: {
15
+ sessionId?: string;
16
+ externalChannel?: ExternalChannelSessionStatus | null;
17
+ env?: NodeJS.ProcessEnv;
18
+ }): void;
10
19
  start(_sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
11
20
  send(text: string, modelId?: string): Promise<void>;
12
21
  resume(agentSessionId: string): Promise<void>;
@@ -1 +1 @@
1
- import{createInterface as o}from"node:readline";import{randomUUID as a}from"node:crypto";import{AgentAdapter as h,registerAgent as l}from"./adapter.js";import{resolveBuiltinCommand as u,spawnResolvedCommand as c}from"./command-spec.js";import{buildAgentProcessEnv as d}from"../agent-env.js";class m extends h{type="cursor";process=null;chatId=null;workDir=null;seq=0;runId="";emittedText="";async start(t,s,e){this.workDir=s,this.seq=0,e&&(this.chatId=e)}async send(t,s){await this.killProcess(),this.runId=a(),this.resetRunState();const e=["-p",t,"--output-format","stream-json","--stream-partial-output","--trust"];s&&e.push("--model",s),this.chatId&&e.push("--continue"),this.spawnAndParse(e)}async resume(t){await this.killProcess(),this.chatId=t,this.runId=a(),this.resetRunState(),this.spawnAndParse(["--resume",t,"--output-format","stream-json","--stream-partial-output","--trust"])}async stop(){await this.killProcess()}spawnAndParse(t){const s=u("cursor");if(!s){this.emit("error",new Error('Cursor Agent CLI not found. Expected "agent" or "cursor agent".'));return}const e=c(s,t,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:d()});this.process=e,o({input:e.stdout}).on("line",i=>{if(i.trim())try{const r=JSON.parse(i);this.handleStreamEvent(r)}catch{this.emitEvent({state:"delta",text:i})}});let n="";e.stderr?.on("data",i=>{n+=i.toString()}),e.on("close",i=>{if(this.process===e&&(this.process=null,i!==0&&i!==null)){const r=n.trim()||`cursor agent exited with code ${i}`;this.emitEvent({state:"error",message:r})}}),e.on("error",i=>{this.process===e&&(this.process=null,i.code==="ENOENT"?this.emit("error",new Error('Command "cursor" not found. Is Cursor CLI installed?')):this.emit("error",i))})}handleStreamEvent(t){switch(t.session_id&&!this.chatId&&(this.chatId=t.session_id),t.chat_id&&!this.chatId&&(this.chatId=t.chat_id),t.type??t.event){case"system":break;case"assistant":{if(t.message?.content){if(!this.isLiveAssistantDelta(t))break;for(const e of t.message.content)e.type==="text"&&e.text?this.emitTextDelta(e.text):e.type==="thinking"&&e.thinking?this.emitEvent({state:"delta",text:e.thinking,thinking:!0}):e.type==="tool_use"&&this.emitEvent({state:"tool-call",name:e.name,args:e.input});break}(t.delta??t.text)&&this.emitEvent({state:"delta",text:t.delta??t.text});break}case"user":break;case"result":{if(t.subtype==="success"||!t.is_error){this.emitFinalResultDelta(t.result);const e=t.usage;this.emitEvent({state:"final",agentSessionId:this.chatId??void 0,usage:e?{inputTokens:e.inputTokens??e.input_tokens??0,outputTokens:e.outputTokens??e.output_tokens??0}:void 0})}else this.emitEvent({state:"error",message:t.result??t.error??"unknown error"});break}case"error":{this.emitEvent({state:"error",message:t.error??"unknown error"});break}case"text":case"delta":case"content":{const e=t.delta??t.text;e&&this.emitEvent({state:"delta",text:e});break}case"done":{this.emitEvent({state:"final",agentSessionId:this.chatId??void 0});break}default:t.done?this.emitEvent({state:"final",agentSessionId:this.chatId??void 0}):(t.delta??t.text)&&this.emitEvent({state:"delta",text:t.delta??t.text})}}emitEvent(t){const s={...t,runId:this.runId,seq:this.seq++};this.emit("agentEvent",s)}async killProcess(){const t=this.process;t&&(this.process=null,t.kill("SIGTERM"),await new Promise(s=>{t.on("close",s),setTimeout(()=>{t.kill("SIGKILL"),s()},3e3)}))}resetRunState(){this.seq=0,this.emittedText=""}isLiveAssistantDelta(t){return t.timestamp_ms!=null&&!t.model_call_id}emitTextDelta(t){t&&(this.emittedText+=t,this.emitEvent({state:"delta",text:t}))}emitFinalResultDelta(t){if(!t)return;if(!this.emittedText){this.emitTextDelta(t);return}if(!t.startsWith(this.emittedText))return;const s=t.slice(this.emittedText.length);s&&this.emitTextDelta(s)}}l("cursor",()=>new m);export{m as CursorAdapter};
1
+ import{createInterface as l}from"node:readline";import{randomUUID as o}from"node:crypto";import{AgentAdapter as h,registerAgent as u}from"./adapter.js";import{resolveBuiltinCommand as d,spawnResolvedCommand as c}from"./command-spec.js";import{buildAgentProcessEnv as m}from"../agent-env.js";import{buildInlineChannelPreamble as p}from"./platform-instructions.js";class f extends h{type="cursor";process=null;chatId=null;workDir=null;seq=0;runId="";emittedText="";externalChannel=null;shennianSessionId=null;extraEnv={};configure(t){this.shennianSessionId=t.sessionId??null,this.externalChannel=t.externalChannel??null,this.extraEnv=t.env??{}}async start(t,s,e){this.workDir=s,this.seq=0,e&&(this.chatId=e)}async send(t,s){await this.killProcess(),this.runId=o(),this.resetRunState();const n=["-p",this.chatId?t:`${p(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0)}${t}`,"--output-format","stream-json","--stream-partial-output","--trust"];s&&n.push("--model",s),this.chatId&&n.push("--continue"),this.spawnAndParse(n)}async resume(t){await this.killProcess(),this.chatId=t,this.runId=o(),this.resetRunState(),this.spawnAndParse(["--resume",t,"--output-format","stream-json","--stream-partial-output","--trust"])}async stop(){await this.killProcess()}spawnAndParse(t){const s=d("cursor");if(!s){this.emit("error",new Error('Cursor Agent CLI not found. Expected "agent" or "cursor agent".'));return}const e=c(s,t,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:m(this.extraEnv)});this.process=e,l({input:e.stdout}).on("line",i=>{if(i.trim())try{const r=JSON.parse(i);this.handleStreamEvent(r)}catch{this.emitEvent({state:"delta",text:i})}});let a="";e.stderr?.on("data",i=>{a+=i.toString()}),e.on("close",i=>{if(this.process===e&&(this.process=null,i!==0&&i!==null)){const r=a.trim()||`cursor agent exited with code ${i}`;this.emitEvent({state:"error",message:r})}}),e.on("error",i=>{this.process===e&&(this.process=null,i.code==="ENOENT"?this.emit("error",new Error('Command "cursor" not found. Is Cursor CLI installed?')):this.emit("error",i))})}handleStreamEvent(t){switch(t.session_id&&!this.chatId&&(this.chatId=t.session_id),t.chat_id&&!this.chatId&&(this.chatId=t.chat_id),t.type??t.event){case"system":break;case"assistant":{if(t.message?.content){if(!this.isLiveAssistantDelta(t))break;for(const e of t.message.content)e.type==="text"&&e.text?this.emitTextDelta(e.text):e.type==="thinking"&&e.thinking?this.emitEvent({state:"delta",text:e.thinking,thinking:!0}):e.type==="tool_use"&&this.emitEvent({state:"tool-call",name:e.name,args:e.input});break}(t.delta??t.text)&&this.emitEvent({state:"delta",text:t.delta??t.text});break}case"user":break;case"result":{if(t.subtype==="success"||!t.is_error){this.emitFinalResultDelta(t.result);const e=t.usage;this.emitEvent({state:"final",agentSessionId:this.chatId??void 0,usage:e?{inputTokens:e.inputTokens??e.input_tokens??0,outputTokens:e.outputTokens??e.output_tokens??0}:void 0})}else this.emitEvent({state:"error",message:t.result??t.error??"unknown error"});break}case"error":{this.emitEvent({state:"error",message:t.error??"unknown error"});break}case"text":case"delta":case"content":{const e=t.delta??t.text;e&&this.emitEvent({state:"delta",text:e});break}case"done":{this.emitEvent({state:"final",agentSessionId:this.chatId??void 0});break}default:t.done?this.emitEvent({state:"final",agentSessionId:this.chatId??void 0}):(t.delta??t.text)&&this.emitEvent({state:"delta",text:t.delta??t.text})}}emitEvent(t){const s={...t,runId:this.runId,seq:this.seq++};this.emit("agentEvent",s)}async killProcess(){const t=this.process;t&&(this.process=null,t.kill("SIGTERM"),await new Promise(s=>{t.on("close",s),setTimeout(()=>{t.kill("SIGKILL"),s()},3e3)}))}resetRunState(){this.seq=0,this.emittedText=""}isLiveAssistantDelta(t){return t.timestamp_ms!=null&&!t.model_call_id}emitTextDelta(t){t&&(this.emittedText+=t,this.emitEvent({state:"delta",text:t}))}emitFinalResultDelta(t){if(!t)return;if(!this.emittedText){this.emitTextDelta(t);return}if(!t.startsWith(this.emittedText))return;const s=t.slice(this.emittedText.length);s&&this.emitTextDelta(s)}}u("cursor",()=>new f);export{f as CursorAdapter};
@@ -1,5 +1,5 @@
1
1
  import { AgentAdapter } from './adapter.js';
2
- import type { CustomAgentType } from '@shennian/wire';
2
+ import type { CustomAgentType, ExternalChannelSessionStatus } from '@shennian/wire';
3
3
  import type { CustomAgentEntry } from '../config/index.js';
4
4
  export declare class CustomAgentAdapter extends AgentAdapter {
5
5
  readonly type: CustomAgentType;
@@ -11,12 +11,20 @@ export declare class CustomAgentAdapter extends AgentAdapter {
11
11
  private workDir;
12
12
  private runId;
13
13
  private seq;
14
+ private externalChannel;
15
+ private shennianSessionId;
16
+ private extraEnv;
14
17
  private stdioProcess;
15
18
  private spawnProcess;
16
19
  private dispatchGuard;
17
20
  private dispatchObservedEvent;
18
21
  constructor(name: string, entry: CustomAgentEntry);
19
22
  start(sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
23
+ configure(options: {
24
+ sessionId?: string;
25
+ externalChannel?: ExternalChannelSessionStatus | null;
26
+ env?: NodeJS.ProcessEnv;
27
+ }): void;
20
28
  send(text: string, modelId?: string): Promise<void>;
21
29
  resume(agentSessionId: string): Promise<void>;
22
30
  stop(): Promise<void>;
@@ -1,4 +1,4 @@
1
- import{createInterface as d}from"node:readline";import{randomUUID as a}from"node:crypto";import{AgentAdapter as p,registerAgent as l}from"./adapter.js";import{spawnCommandString as c}from"./command-spec.js";import{buildAgentProcessEnv as h}from"../agent-env.js";const m=3e3;class u extends p{type;command;mode;proactive;sessionId=null;agentSessionId=null;workDir=null;runId="";seq=0;stdioProcess=null;spawnProcess=null;dispatchGuard=null;dispatchObservedEvent=!1;constructor(s,t){super(),this.type=`custom:${s}`,this.command=t.command,this.mode=t.caps.mode,this.proactive=t.caps.proactive??!1}async start(s,t,r){this.sessionId=s,this.workDir=t,this.seq=0,r&&(this.agentSessionId=r),this.mode==="stdio"&&await this.startStdioProcess()}async send(s,t){this.runId=a(),this.seq=0,this.mode==="stdio"?await this.sendStdio(s,t):await this.runSpawn(s,t)}async resume(s){if(this.mode==="stdio"){const t=JSON.stringify({method:"resume",id:a(),params:{sessionId:this.sessionId,agentSessionId:s}});this.stdioProcess?.stdin?.write(t+`
2
- `)}}async stop(){this.mode==="stdio"?await this.stopStdioProcess():await this.killSpawnProcess()}async runSpawn(s,t){await this.killSpawnProcess();const r=this.startDispatchGuard();this.dispatchObservedEvent=!1;const i=["/run","--workdir",this.workDir??process.cwd()];this.sessionId&&i.push("--session",this.sessionId),this.agentSessionId&&i.push("--resume",this.agentSessionId),t&&i.push("--model",t);const e=c(this.command,i,{cwd:this.workDir??void 0,stdio:["pipe","pipe","pipe"],env:h()});this.spawnProcess=e,this.attachOutputHandlers(e,()=>{this.spawnProcess===e&&(this.spawnProcess=null)}),e.stdin?.once("error",o=>this.rejectDispatch(o)),e.stdin?.write(s),e.stdin?.end(),await r.promise}async killSpawnProcess(){const s=this.spawnProcess;s&&(this.spawnProcess=null,s.kill("SIGTERM"),await new Promise(t=>{s.on("close",t),setTimeout(()=>{s.kill("SIGKILL"),t()},3e3)}))}async startStdioProcess(){const s=c(this.command,["/start","--workdir",this.workDir??process.cwd()],{cwd:this.workDir??void 0,stdio:["pipe","pipe","pipe"],env:h()});this.stdioProcess=s,this.attachOutputHandlers(s,()=>{this.stdioProcess===s&&(this.stdioProcess=null,this.emit("error",new Error("Custom agent process exited unexpectedly")))})}async sendStdio(s,t){this.stdioProcess||await this.startStdioProcess();const r=this.startDispatchGuard();this.dispatchObservedEvent=!1;const i=JSON.stringify({method:"send",id:a(),params:{sessionId:this.sessionId,text:s,modelId:t}});this.stdioProcess?.stdin?.once("error",e=>this.rejectDispatch(e)),this.stdioProcess?.stdin?.write(i+`
3
- `),await r.promise}async stopStdioProcess(){const s=this.stdioProcess;if(!s)return;const t=JSON.stringify({method:"stop",id:a()});s.stdin?.write(t+`
4
- `),await new Promise(r=>{const i=setTimeout(()=>{s.kill("SIGTERM"),setTimeout(()=>{s.kill("SIGKILL"),r()},3e3)},5e3);s.on("close",()=>{clearTimeout(i),r()})}),this.stdioProcess=null}attachOutputHandlers(s,t){d({input:s.stdout}).on("line",e=>{if(e.trim())try{const o=JSON.parse(e);this.handleProtocolEvent(o)}catch{}});let i="";s.stderr?.on("data",e=>{i+=e.toString()}),s.on("close",e=>{if(t(),e!==0&&e!==null){const o=i.trim()||`Agent exited with code ${e}`;this.rejectDispatch(new Error(o)),this.emitEvent({state:"error",message:o})}else this.dispatchObservedEvent?this.acceptDispatch():this.rejectDispatch(new Error("Custom agent exited without protocol events"))}),s.on("error",e=>{t(),this.rejectDispatch(e),this.emit("error",e)})}handleProtocolEvent(s){const{state:t}=s;if(t)switch(this.dispatchObservedEvent=!0,t){case"delta":this.acceptDispatch(),this.emitEvent({state:"delta",text:s.text??"",thinking:s.thinking});break;case"final":this.acceptDispatch(),s.agentSessionId&&(this.agentSessionId=s.agentSessionId),this.emitEvent({state:"final",usage:s.usage,agentSessionId:this.agentSessionId??void 0});break;case"error":this.rejectDispatch(new Error(s.message??"unknown error")),this.emitEvent({state:"error",message:s.message??"unknown error"});break;case"tool-call":this.acceptDispatch(),this.emitEvent({state:"tool-call",name:s.name??"",args:s.args});break;case"tool-result":this.acceptDispatch(),this.emitEvent({state:"tool-result",name:s.name??"",result:s.result??""});break;case"notify":this.acceptDispatch(),this.emitEvent({state:"notify",text:s.text??"",title:s.title,source:s.source});break}}startDispatchGuard(){this.acceptDispatch();let s;const t=new Promise((r,i)=>{s={settled:!1,timer:setTimeout(()=>this.acceptDispatch(s),m),resolve:r,reject:i,promise:Promise.resolve()}});return s.promise=t,this.dispatchGuard=s,s}acceptDispatch(s=this.dispatchGuard){!s||s.settled||(s.settled=!0,clearTimeout(s.timer),this.dispatchGuard===s&&(this.dispatchGuard=null),s.resolve())}rejectDispatch(s,t=this.dispatchGuard){!t||t.settled||(t.settled=!0,clearTimeout(t.timer),this.dispatchGuard===t&&(this.dispatchGuard=null),t.reject(s))}emitEvent(s){const t={...s,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}}function D(n,s){const t=`custom:${n}`;l(t,()=>new u(n,s))}export{u as CustomAgentAdapter,D as registerCustomAgent};
1
+ import{createInterface as d}from"node:readline";import{randomUUID as o}from"node:crypto";import{AgentAdapter as l,registerAgent as p}from"./adapter.js";import{spawnCommandString as c}from"./command-spec.js";import{buildAgentProcessEnv as h}from"../agent-env.js";import{buildInlineChannelPreamble as m}from"./platform-instructions.js";const u=3e3;class w extends l{type;command;mode;proactive;sessionId=null;agentSessionId=null;workDir=null;runId="";seq=0;externalChannel=null;shennianSessionId=null;extraEnv={};stdioProcess=null;spawnProcess=null;dispatchGuard=null;dispatchObservedEvent=!1;constructor(s,t){super(),this.type=`custom:${s}`,this.command=t.command,this.mode=t.caps.mode,this.proactive=t.caps.proactive??!1}async start(s,t,i){this.sessionId=s,this.workDir=t,this.seq=0,i&&(this.agentSessionId=i),this.mode==="stdio"&&await this.startStdioProcess()}configure(s){this.shennianSessionId=s.sessionId??null,this.externalChannel=s.externalChannel??null,this.extraEnv=s.env??{}}async send(s,t){this.runId=o(),this.seq=0;const i=this.agentSessionId?s:`${m(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0)}${s}`;this.mode==="stdio"?await this.sendStdio(i,t):await this.runSpawn(i,t)}async resume(s){if(this.mode==="stdio"){const t=JSON.stringify({method:"resume",id:o(),params:{sessionId:this.sessionId,agentSessionId:s}});this.stdioProcess?.stdin?.write(t+`
2
+ `)}}async stop(){this.mode==="stdio"?await this.stopStdioProcess():await this.killSpawnProcess()}async runSpawn(s,t){await this.killSpawnProcess();const i=this.startDispatchGuard();this.dispatchObservedEvent=!1;const r=["/run","--workdir",this.workDir??process.cwd()];this.sessionId&&r.push("--session",this.sessionId),this.agentSessionId&&r.push("--resume",this.agentSessionId),t&&r.push("--model",t);const e=c(this.command,r,{cwd:this.workDir??void 0,stdio:["pipe","pipe","pipe"],env:h(this.extraEnv)});this.spawnProcess=e,this.attachOutputHandlers(e,()=>{this.spawnProcess===e&&(this.spawnProcess=null)}),e.stdin?.once("error",n=>this.rejectDispatch(n)),e.stdin?.write(s),e.stdin?.end(),await i.promise}async killSpawnProcess(){const s=this.spawnProcess;s&&(this.spawnProcess=null,s.kill("SIGTERM"),await new Promise(t=>{s.on("close",t),setTimeout(()=>{s.kill("SIGKILL"),t()},3e3)}))}async startStdioProcess(){const s=c(this.command,["/start","--workdir",this.workDir??process.cwd()],{cwd:this.workDir??void 0,stdio:["pipe","pipe","pipe"],env:h(this.extraEnv)});this.stdioProcess=s,this.attachOutputHandlers(s,()=>{this.stdioProcess===s&&(this.stdioProcess=null,this.emit("error",new Error("Custom agent process exited unexpectedly")))})}async sendStdio(s,t){this.stdioProcess||await this.startStdioProcess();const i=this.startDispatchGuard();this.dispatchObservedEvent=!1;const r=JSON.stringify({method:"send",id:o(),params:{sessionId:this.sessionId,text:s,modelId:t}});this.stdioProcess?.stdin?.once("error",e=>this.rejectDispatch(e)),this.stdioProcess?.stdin?.write(r+`
3
+ `),await i.promise}async stopStdioProcess(){const s=this.stdioProcess;if(!s)return;const t=JSON.stringify({method:"stop",id:o()});s.stdin?.write(t+`
4
+ `),await new Promise(i=>{const r=setTimeout(()=>{s.kill("SIGTERM"),setTimeout(()=>{s.kill("SIGKILL"),i()},3e3)},5e3);s.on("close",()=>{clearTimeout(r),i()})}),this.stdioProcess=null}attachOutputHandlers(s,t){d({input:s.stdout}).on("line",e=>{if(e.trim())try{const n=JSON.parse(e);this.handleProtocolEvent(n)}catch{}});let r="";s.stderr?.on("data",e=>{r+=e.toString()}),s.on("close",e=>{if(t(),e!==0&&e!==null){const n=r.trim()||`Agent exited with code ${e}`;this.rejectDispatch(new Error(n)),this.emitEvent({state:"error",message:n})}else this.dispatchObservedEvent?this.acceptDispatch():this.rejectDispatch(new Error("Custom agent exited without protocol events"))}),s.on("error",e=>{t(),this.rejectDispatch(e),this.emit("error",e)})}handleProtocolEvent(s){const{state:t}=s;if(t)switch(this.dispatchObservedEvent=!0,t){case"delta":this.acceptDispatch(),this.emitEvent({state:"delta",text:s.text??"",thinking:s.thinking});break;case"final":this.acceptDispatch(),s.agentSessionId&&(this.agentSessionId=s.agentSessionId),this.emitEvent({state:"final",usage:s.usage,agentSessionId:this.agentSessionId??void 0});break;case"error":this.rejectDispatch(new Error(s.message??"unknown error")),this.emitEvent({state:"error",message:s.message??"unknown error"});break;case"tool-call":this.acceptDispatch(),this.emitEvent({state:"tool-call",name:s.name??"",args:s.args});break;case"tool-result":this.acceptDispatch(),this.emitEvent({state:"tool-result",name:s.name??"",result:s.result??""});break;case"notify":this.acceptDispatch(),this.emitEvent({state:"notify",text:s.text??"",title:s.title,source:s.source});break}}startDispatchGuard(){this.acceptDispatch();let s;const t=new Promise((i,r)=>{s={settled:!1,timer:setTimeout(()=>this.acceptDispatch(s),u),resolve:i,reject:r,promise:Promise.resolve()}});return s.promise=t,this.dispatchGuard=s,s}acceptDispatch(s=this.dispatchGuard){!s||s.settled||(s.settled=!0,clearTimeout(s.timer),this.dispatchGuard===s&&(this.dispatchGuard=null),s.resolve())}rejectDispatch(s,t=this.dispatchGuard){!t||t.settled||(t.settled=!0,clearTimeout(t.timer),this.dispatchGuard===t&&(this.dispatchGuard=null),t.reject(s))}emitEvent(s){const t={...s,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}}function E(a,s){const t=`custom:${a}`;p(t,()=>new w(a,s))}export{w as CustomAgentAdapter,E as registerCustomAgent};
@@ -1,4 +1,5 @@
1
1
  import { AgentAdapter } from './adapter.js';
2
+ import type { ExternalChannelSessionStatus } from '@shennian/wire';
2
3
  export declare class GeminiAdapter extends AgentAdapter {
3
4
  readonly type: "gemini";
4
5
  private process;
@@ -6,6 +7,14 @@ export declare class GeminiAdapter extends AgentAdapter {
6
7
  private workDir;
7
8
  private seq;
8
9
  private runId;
10
+ private externalChannel;
11
+ private shennianSessionId;
12
+ private extraEnv;
13
+ configure(options: {
14
+ sessionId?: string;
15
+ externalChannel?: ExternalChannelSessionStatus | null;
16
+ env?: NodeJS.ProcessEnv;
17
+ }): void;
9
18
  start(_sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
10
19
  send(text: string, modelId?: string): Promise<void>;
11
20
  resume(agentSessionId: string): Promise<void>;
@@ -1 +1 @@
1
- import{createInterface as m}from"node:readline";import{randomUUID as u}from"node:crypto";import{AgentAdapter as d,registerAgent as p}from"./adapter.js";import{resolveBuiltinCommand as c,spawnResolvedCommand as l}from"./command-spec.js";import{buildAgentProcessEnv as h}from"../agent-env.js";function r(s){return typeof s=="number"&&Number.isFinite(s)?s:void 0}function f(s){if(!s)return;const e=r(s.input_tokens)??r(s.prompt_tokens)??r(s.inputTokens)??r(s.promptTokenCount),t=r(s.output_tokens)??r(s.completion_tokens)??r(s.outputTokens)??r(s.candidatesTokenCount)??r(s.responseTokenCount);if(!(e===void 0&&t===void 0))return{inputTokens:e??0,outputTokens:t??0}}class g extends d{type="gemini";process=null;agentSessionId=null;workDir=null;seq=0;runId="";async start(e,t,n){this.workDir=t,this.seq=0,n&&(this.agentSessionId=n)}async send(e,t){await this.killProcess(),this.runId=u(),this.seq=0;const n=["-p",e,"--output-format","stream-json"];t&&n.push("-m",t),this.agentSessionId&&n.push("--resume",this.agentSessionId),this.spawnAndParse(n)}async resume(e){await this.killProcess(),this.agentSessionId=e,this.runId=u(),this.seq=0,this.spawnAndParse(["--resume",e,"--output-format","stream-json"])}async stop(){await this.killProcess()}spawnAndParse(e){const t=c("gemini");if(!t){this.emit("error",new Error('Command "gemini" not found. Is Gemini CLI installed?'));return}const n=l(t,e,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:h()});this.process=n,m({input:n.stdout}).on("line",i=>{if(i.trim())try{const o=JSON.parse(i);this.handleStreamEvent(o)}catch{this.emitEvent({state:"delta",text:i})}});let a="";n.stderr?.on("data",i=>{a+=i.toString()}),n.on("close",i=>{if(this.process===n&&(this.process=null,i!==0&&i!==null)){const o=a.trim()||`gemini exited with code ${i}`;this.emitEvent({state:"error",message:o})}}),n.on("error",i=>{this.process===n&&(this.process=null,i.code==="ENOENT"?this.emit("error",new Error('Command "gemini" not found. Is Gemini CLI installed?')):this.emit("error",i))})}handleStreamEvent(e){switch(e.type){case"init":{e.session_id&&(this.agentSessionId=e.session_id);break}case"message":{e.role==="assistant"&&e.content&&this.emitEvent({state:"delta",text:e.content});break}case"result":{if(e.status==="success")this.emitEvent({state:"final",agentSessionId:this.agentSessionId??void 0,usage:f(e.stats)});else if(e.status==="error"){const t=typeof e.error=="string"&&e.error||typeof e.message=="string"&&e.message||"gemini result error";this.emitEvent({state:"error",message:t})}break}default:break}}emitEvent(e){const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}async killProcess(){const e=this.process;e&&(this.process=null,e.kill("SIGTERM"),await new Promise(t=>{e.on("close",t),setTimeout(()=>{e.kill("SIGKILL"),t()},3e3)}))}}p("gemini",()=>new g);export{g as GeminiAdapter};
1
+ import{createInterface as m}from"node:readline";import{randomUUID as l}from"node:crypto";import{AgentAdapter as d,registerAgent as h}from"./adapter.js";import{resolveBuiltinCommand as c,spawnResolvedCommand as p}from"./command-spec.js";import{buildAgentProcessEnv as f}from"../agent-env.js";import{buildInlineChannelPreamble as g}from"./platform-instructions.js";function r(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function I(t){if(!t)return;const e=r(t.input_tokens)??r(t.prompt_tokens)??r(t.inputTokens)??r(t.promptTokenCount),n=r(t.output_tokens)??r(t.completion_tokens)??r(t.outputTokens)??r(t.candidatesTokenCount)??r(t.responseTokenCount);if(!(e===void 0&&n===void 0))return{inputTokens:e??0,outputTokens:n??0}}class k extends d{type="gemini";process=null;agentSessionId=null;workDir=null;seq=0;runId="";externalChannel=null;shennianSessionId=null;extraEnv={};configure(e){this.shennianSessionId=e.sessionId??null,this.externalChannel=e.externalChannel??null,this.extraEnv=e.env??{}}async start(e,n,i){this.workDir=n,this.seq=0,i&&(this.agentSessionId=i)}async send(e,n){await this.killProcess(),this.runId=l(),this.seq=0;const o=["-p",this.agentSessionId?e:`${g(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0)}${e}`,"--output-format","stream-json"];n&&o.push("-m",n),this.agentSessionId&&o.push("--resume",this.agentSessionId),this.spawnAndParse(o)}async resume(e){await this.killProcess(),this.agentSessionId=e,this.runId=l(),this.seq=0,this.spawnAndParse(["--resume",e,"--output-format","stream-json"])}async stop(){await this.killProcess()}spawnAndParse(e){const n=c("gemini");if(!n){this.emit("error",new Error('Command "gemini" not found. Is Gemini CLI installed?'));return}const i=p(n,e,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:f(this.extraEnv)});this.process=i,m({input:i.stdout}).on("line",s=>{if(s.trim())try{const a=JSON.parse(s);this.handleStreamEvent(a)}catch{this.emitEvent({state:"delta",text:s})}});let u="";i.stderr?.on("data",s=>{u+=s.toString()}),i.on("close",s=>{if(this.process===i&&(this.process=null,s!==0&&s!==null)){const a=u.trim()||`gemini exited with code ${s}`;this.emitEvent({state:"error",message:a})}}),i.on("error",s=>{this.process===i&&(this.process=null,s.code==="ENOENT"?this.emit("error",new Error('Command "gemini" not found. Is Gemini CLI installed?')):this.emit("error",s))})}handleStreamEvent(e){switch(e.type){case"init":{e.session_id&&(this.agentSessionId=e.session_id);break}case"message":{e.role==="assistant"&&e.content&&this.emitEvent({state:"delta",text:e.content});break}case"result":{if(e.status==="success")this.emitEvent({state:"final",agentSessionId:this.agentSessionId??void 0,usage:I(e.stats)});else if(e.status==="error"){const n=typeof e.error=="string"&&e.error||typeof e.message=="string"&&e.message||"gemini result error";this.emitEvent({state:"error",message:n})}break}default:break}}emitEvent(e){const n={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",n)}async killProcess(){const e=this.process;e&&(this.process=null,e.kill("SIGTERM"),await new Promise(n=>{e.on("close",n),setTimeout(()=>{e.kill("SIGKILL"),n()},3e3)}))}}h("gemini",()=>new k);export{k as GeminiAdapter};
@@ -1,4 +1,5 @@
1
1
  import { AgentAdapter } from './adapter.js';
2
+ import type { ExternalChannelSessionStatus } from '@shennian/wire';
2
3
  export declare class OpenClawAdapter extends AgentAdapter {
3
4
  readonly type: "openclaw";
4
5
  private process;
@@ -9,6 +10,14 @@ export declare class OpenClawAdapter extends AgentAdapter {
9
10
  private workDir;
10
11
  private seq;
11
12
  private runId;
13
+ private externalChannel;
14
+ private shennianSessionId;
15
+ private extraEnv;
16
+ configure(options: {
17
+ sessionId?: string;
18
+ externalChannel?: ExternalChannelSessionStatus | null;
19
+ env?: NodeJS.ProcessEnv;
20
+ }): void;
12
21
  start(sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
13
22
  send(text: string, modelId?: string): Promise<void>;
14
23
  resume(agentSessionId: string): Promise<void>;
@@ -1,2 +1,2 @@
1
- import{randomUUID as g}from"node:crypto";import{AgentAdapter as E}from"./adapter.js";import{resolveBuiltinCommand as h,spawnResolvedCommand as w}from"./command-spec.js";import{buildAgentProcessEnv as y}from"../agent-env.js";function x(n){if(n==null)return"";if(typeof n=="string")return n;if(typeof n=="object"){const t=n;if(Array.isArray(t.payloads)){const o=[];for(const s of t.payloads)if(s&&typeof s=="object"){const r=s.text;typeof r=="string"&&o.push(r)}if(o.join("").trim())return o.join(`
2
- `)}const e=t.response??t.message??t.text??t.output??t.content??t.result;if(typeof e=="string"&&e.trim())return e}return""}function k(n){if(n==null||typeof n!="object")return;const t=n,s=t.meta?.agentMeta?.sessionId??t.sessionId??t.session_id;return typeof s=="string"&&s?s:void 0}function C(n){if(n==null||typeof n!="object")return;const t=n,s=t.meta?.agentMeta?.usage??t.usage;if(!s||typeof s!="object")return;const r=s,c=r.input??r.inputTokens??r.input_tokens,i=r.output??r.outputTokens??r.output_tokens;if(!(typeof c!="number"&&typeof i!="number"))return{inputTokens:typeof c=="number"?c:0,outputTokens:typeof i=="number"?i:0}}function I(n){if(n==null||typeof n!="object")return;const t=n,e=t.error??t.err??t.errorMessage;if(typeof e=="string"&&e.trim())return e}class j extends E{type="openclaw";process=null;sessionId=null;agentSessionId=null;currentModelId=null;workDir=null;seq=0;runId="";async start(t,e,o){this.sessionId=t,this.workDir=e,this.seq=0,o&&(this.agentSessionId=o)}async send(t,e){await this.killProcess(),this.runId=g(),this.seq=0;const o=this.agentSessionId??this.sessionId;if(!o){this.emitEvent({state:"error",message:"openclaw: session not started"});return}if(e&&e!==this.currentModelId){const s=await this.runAgentCommand(["--message",`/model ${e}`,"--session-id",o]);if(!s.ok){this.emitEvent({state:"error",message:s.error??"openclaw model switch failed"});return}this.currentModelId=e}this.spawnAgent(["--message",t,"--session-id",o])}async resume(t){await this.killProcess(),this.agentSessionId=t,this.runId=g(),this.seq=0,this.spawnAgent(["--message","\u200B","--session-id",t])}async stop(){await this.killProcess()}spawnAgent(t){const e=h("openclaw");if(!e){this.emit("error",new Error('Command "openclaw" not found. Is OpenClaw CLI installed?'));return}const o=["agent","--local","--json",...t],s=w(e,o,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:y()});this.process=s;let r="";s.stdout?.on("data",i=>{r+=i.toString()});let c="";s.stderr?.on("data",i=>{c+=i.toString()}),s.on("close",i=>{if(this.process!==s)return;if(this.process=null,i!==0&&i!==null){const f=c.trim()||`openclaw exited with code ${i}`;this.emitEvent({state:"error",message:f});return}const a=r.trim();if(!a){const f=c.trim()||"openclaw returned empty stdout";this.emitEvent({state:"error",message:f});return}let u;try{u=JSON.parse(a)}catch{this.emitEvent({state:"error",message:`openclaw stdout is not valid JSON: ${a.slice(0,200)}`});return}const l=u;if(l.ok===!1||l.success===!1){this.emitEvent({state:"error",message:I(u)??"openclaw request failed"});return}const p=k(u);p&&(this.agentSessionId=p);const m=x(u);m&&this.emitEvent({state:"delta",text:m});const S=C(u);this.emitEvent({state:"final",agentSessionId:this.agentSessionId??void 0,usage:S})}),s.on("error",i=>{this.process===s&&(this.process=null,i.code==="ENOENT"?this.emit("error",new Error('Command "openclaw" not found. Is OpenClaw CLI installed?')):this.emit("error",i))})}async runAgentCommand(t){return new Promise(e=>{const o=h("openclaw");if(!o){e({ok:!1,error:'Command "openclaw" not found. Is OpenClaw CLI installed?'});return}const s=["agent","--local","--json",...t],r=w(o,s,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:y()});let c="",i="";r.stdout?.on("data",a=>{c+=a.toString()}),r.stderr?.on("data",a=>{i+=a.toString()}),r.on("close",a=>{if(a!==0&&a!==null){e({ok:!1,error:i.trim()||`openclaw exited with code ${a}`});return}const u=c.trim();if(!u){e({ok:!0});return}try{const l=JSON.parse(u);if(l.ok===!1||l.success===!1){e({ok:!1,error:I(l)??"openclaw request failed"});return}const d=k(l);d&&(this.agentSessionId=d),e({ok:!0,parsed:l})}catch{e({ok:!1,error:`openclaw stdout is not valid JSON: ${u.slice(0,200)}`})}}),r.on("error",a=>{e({ok:!1,error:a instanceof Error?a.message:String(a)})})})}emitEvent(t){const e={...t,runId:this.runId,seq:this.seq++};this.emit("agentEvent",e)}async killProcess(){const t=this.process;t&&(this.process=null,t.kill("SIGTERM"),await new Promise(e=>{t.on("close",e),setTimeout(()=>{t.kill("SIGKILL"),e()},3e3)}))}}export{j as OpenClawAdapter};
1
+ import{randomUUID as h}from"node:crypto";import{AgentAdapter as E}from"./adapter.js";import{resolveBuiltinCommand as g,spawnResolvedCommand as w}from"./command-spec.js";import{buildAgentProcessEnv as I}from"../agent-env.js";import{buildInlineChannelPreamble as x}from"./platform-instructions.js";function C(o){if(o==null)return"";if(typeof o=="string")return o;if(typeof o=="object"){const t=o;if(Array.isArray(t.payloads)){const r=[];for(const n of t.payloads)if(n&&typeof n=="object"){const s=n.text;typeof s=="string"&&r.push(s)}if(r.join("").trim())return r.join(`
2
+ `)}const e=t.response??t.message??t.text??t.output??t.content??t.result;if(typeof e=="string"&&e.trim())return e}return""}function k(o){if(o==null||typeof o!="object")return;const t=o,n=t.meta?.agentMeta?.sessionId??t.sessionId??t.session_id;return typeof n=="string"&&n?n:void 0}function v(o){if(o==null||typeof o!="object")return;const t=o,n=t.meta?.agentMeta?.usage??t.usage;if(!n||typeof n!="object")return;const s=n,u=s.input??s.inputTokens??s.input_tokens,i=s.output??s.outputTokens??s.output_tokens;if(!(typeof u!="number"&&typeof i!="number"))return{inputTokens:typeof u=="number"?u:0,outputTokens:typeof i=="number"?i:0}}function y(o){if(o==null||typeof o!="object")return;const t=o,e=t.error??t.err??t.errorMessage;if(typeof e=="string"&&e.trim())return e}class O extends E{type="openclaw";process=null;sessionId=null;agentSessionId=null;currentModelId=null;workDir=null;seq=0;runId="";externalChannel=null;shennianSessionId=null;extraEnv={};configure(t){this.shennianSessionId=t.sessionId??null,this.externalChannel=t.externalChannel??null,this.extraEnv=t.env??{}}async start(t,e,r){this.sessionId=t,this.workDir=e,this.seq=0,r&&(this.agentSessionId=r)}async send(t,e){await this.killProcess(),this.runId=h(),this.seq=0;const r=this.agentSessionId??this.sessionId;if(!r){this.emitEvent({state:"error",message:"openclaw: session not started"});return}if(e&&e!==this.currentModelId){const s=await this.runAgentCommand(["--message",`/model ${e}`,"--session-id",r]);if(!s.ok){this.emitEvent({state:"error",message:s.error??"openclaw model switch failed"});return}this.currentModelId=e}const n=this.agentSessionId?t:`${x(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0)}${t}`;this.spawnAgent(["--message",n,"--session-id",r])}async resume(t){await this.killProcess(),this.agentSessionId=t,this.runId=h(),this.seq=0,this.spawnAgent(["--message","\u200B","--session-id",t])}async stop(){await this.killProcess()}spawnAgent(t){const e=g("openclaw");if(!e){this.emit("error",new Error('Command "openclaw" not found. Is OpenClaw CLI installed?'));return}const r=["agent","--local","--json",...t],n=w(e,r,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:I(this.extraEnv)});this.process=n;let s="";n.stdout?.on("data",i=>{s+=i.toString()});let u="";n.stderr?.on("data",i=>{u+=i.toString()}),n.on("close",i=>{if(this.process!==n)return;if(this.process=null,i!==0&&i!==null){const f=u.trim()||`openclaw exited with code ${i}`;this.emitEvent({state:"error",message:f});return}const a=s.trim();if(!a){const f=u.trim()||"openclaw returned empty stdout";this.emitEvent({state:"error",message:f});return}let c;try{c=JSON.parse(a)}catch{this.emitEvent({state:"error",message:`openclaw stdout is not valid JSON: ${a.slice(0,200)}`});return}const l=c;if(l.ok===!1||l.success===!1){this.emitEvent({state:"error",message:y(c)??"openclaw request failed"});return}const p=k(c);p&&(this.agentSessionId=p);const m=C(c);m&&this.emitEvent({state:"delta",text:m});const S=v(c);this.emitEvent({state:"final",agentSessionId:this.agentSessionId??void 0,usage:S})}),n.on("error",i=>{this.process===n&&(this.process=null,i.code==="ENOENT"?this.emit("error",new Error('Command "openclaw" not found. Is OpenClaw CLI installed?')):this.emit("error",i))})}async runAgentCommand(t){return new Promise(e=>{const r=g("openclaw");if(!r){e({ok:!1,error:'Command "openclaw" not found. Is OpenClaw CLI installed?'});return}const n=["agent","--local","--json",...t],s=w(r,n,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:I(this.extraEnv)});let u="",i="";s.stdout?.on("data",a=>{u+=a.toString()}),s.stderr?.on("data",a=>{i+=a.toString()}),s.on("close",a=>{if(a!==0&&a!==null){e({ok:!1,error:i.trim()||`openclaw exited with code ${a}`});return}const c=u.trim();if(!c){e({ok:!0});return}try{const l=JSON.parse(c);if(l.ok===!1||l.success===!1){e({ok:!1,error:y(l)??"openclaw request failed"});return}const d=k(l);d&&(this.agentSessionId=d),e({ok:!0,parsed:l})}catch{e({ok:!1,error:`openclaw stdout is not valid JSON: ${c.slice(0,200)}`})}}),s.on("error",a=>{e({ok:!1,error:a instanceof Error?a.message:String(a)})})})}emitEvent(t){const e={...t,runId:this.runId,seq:this.seq++};this.emit("agentEvent",e)}async killProcess(){const t=this.process;t&&(this.process=null,t.kill("SIGTERM"),await new Promise(e=>{t.on("close",e),setTimeout(()=>{t.kill("SIGKILL"),e()},3e3)}))}}export{O as OpenClawAdapter};
@@ -1,4 +1,5 @@
1
1
  import { AgentAdapter } from './adapter.js';
2
+ import type { ExternalChannelSessionStatus } from '@shennian/wire';
2
3
  export declare class OpenCodeAdapter extends AgentAdapter {
3
4
  readonly type: "opencode";
4
5
  private process;
@@ -7,6 +8,14 @@ export declare class OpenCodeAdapter extends AgentAdapter {
7
8
  private seq;
8
9
  private runId;
9
10
  private terminalState;
11
+ private externalChannel;
12
+ private shennianSessionId;
13
+ private extraEnv;
14
+ configure(options: {
15
+ sessionId?: string;
16
+ externalChannel?: ExternalChannelSessionStatus | null;
17
+ env?: NodeJS.ProcessEnv;
18
+ }): void;
10
19
  start(_sessionId: string, workDir: string, agentSessionId?: string | null): Promise<void>;
11
20
  send(text: string, modelId?: string): Promise<void>;
12
21
  resume(agentSessionId: string): Promise<void>;
@@ -1 +1 @@
1
- import{createInterface as l}from"node:readline";import{randomUUID as a}from"node:crypto";import{AgentAdapter as d,registerAgent as f}from"./adapter.js";import{resolveBuiltinCommand as m,spawnAgentCommand as h}from"./command-spec.js";import{buildAgentProcessEnv as c}from"../agent-env.js";function g(s){if(!s)return;const t=s.input,e=s.output;if(!(typeof t!="number"&&typeof e!="number"))return{inputTokens:typeof t=="number"?t:0,outputTokens:typeof e=="number"?e:0}}function p(s){if(s==null)return"";if(typeof s=="string")return s;try{return JSON.stringify(s)}catch{return String(s)}}function u(s){if(!s)return"opencode request failed";if(typeof s=="string")return s;if(typeof s!="object")return String(s);const t=s;return typeof t.message=="string"?t.message:typeof t.name=="string"?t.name:"data"in t?u(t.data):p(s)||"opencode request failed"}class I extends d{type="opencode";process=null;agentSessionId=null;workDir=null;seq=0;runId="";terminalState="closed";async start(t,e,n){this.workDir=e,n&&(this.agentSessionId=n),this.resetRunState()}async send(t,e){await this.killProcess(),this.runId=a(),this.resetRunState();const n=["run","--format","json","--dangerously-skip-permissions","--dir",this.workDir??process.cwd()];this.agentSessionId&&n.push("--session",this.agentSessionId),e&&n.push("--model",e),n.push(t),this.spawnAndParse(n)}async resume(t){await this.killProcess(),this.agentSessionId=t,this.runId=a(),this.resetRunState(),this.emitEvent({state:"start",agentSessionId:t}),this.emitFinalIfOpen({state:"final",agentSessionId:t})}async stop(){await this.killProcess()}resetRunState(){this.seq=0,this.terminalState="open"}spawnAndParse(t){const e=m("opencode");if(!e){this.emit("error",new Error('Command "opencode" not found. Install it with "npm i -g opencode-ai@latest".'));return}const n=h(e,t,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:c({NO_COLOR:"1"})});this.process=n,l({input:n.stdout}).on("line",r=>{if(r.trim())try{const i=JSON.parse(r);this.handleStreamEvent(i)}catch{this.emitEvent({state:"delta",text:r})}});let o="";n.stderr?.on("data",r=>{o+=r.toString()}),n.on("close",r=>{if(this.process!==n||(this.process=null,this.terminalState!=="open"))return;const i=o.trim();if(r!==0&&r!==null){this.emitErrorIfOpen({state:"error",message:i||`opencode exited with code ${r}`});return}this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0})}),n.on("error",r=>{this.process===n&&(this.process=null,r.code==="ENOENT"?this.emit("error",new Error('Command "opencode" not found. Install it with "npm i -g opencode-ai@latest".')):this.emit("error",r))})}handleStreamEvent(t){t.sessionID&&t.sessionID!==this.agentSessionId&&(this.agentSessionId=t.sessionID,this.emitEvent({state:"start",agentSessionId:t.sessionID}));const e=t.part;if(t.type==="text"&&e?.text){this.emitEvent({state:"delta",text:e.text});return}if(t.type==="reasoning"&&e?.text){this.emitEvent({state:"delta",text:e.text,thinking:!0});return}if(t.type==="tool_use"&&e?.type==="tool"){e.state?.status==="completed"||e.state?.status==="error"?this.emitEvent({state:"tool-result",name:e.tool??"tool",result:e.state.status==="error"?e.state.error??"tool failed":p(e.state?.output)}):this.emitEvent({state:"tool-call",name:e.tool??"tool",args:e.state?.input??{}});return}if(t.type==="error"){this.emitErrorIfOpen({state:"error",message:u(t.error)});return}t.type==="step_finish"&&this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??t.sessionID,usage:g(e?.tokens)})}emitEvent(t){const e={...t,runId:this.runId,seq:this.seq++};this.emit("agentEvent",e)}emitFinalIfOpen(t){this.terminalState==="open"&&(this.terminalState="closed",this.emitEvent(t))}emitErrorIfOpen(t){this.terminalState==="open"&&(this.terminalState="closed",this.emitEvent(t))}async killProcess(){const t=this.process;t&&(this.process=null,t.kill("SIGTERM"),await new Promise(e=>{t.on("close",e),setTimeout(()=>{t.kill("SIGKILL"),e()},3e3)}))}}f("opencode",()=>new I);export{I as OpenCodeAdapter};
1
+ import{createInterface as h}from"node:readline";import{randomUUID as l}from"node:crypto";import{AgentAdapter as d,registerAgent as f}from"./adapter.js";import{resolveBuiltinCommand as m,spawnAgentCommand as c}from"./command-spec.js";import{buildAgentProcessEnv as g}from"../agent-env.js";import{buildInlineChannelPreamble as I}from"./platform-instructions.js";function S(s){if(!s)return;const t=s.input,e=s.output;if(!(typeof t!="number"&&typeof e!="number"))return{inputTokens:typeof t=="number"?t:0,outputTokens:typeof e=="number"?e:0}}function u(s){if(s==null)return"";if(typeof s=="string")return s;try{return JSON.stringify(s)}catch{return String(s)}}function p(s){if(!s)return"opencode request failed";if(typeof s=="string")return s;if(typeof s!="object")return String(s);const t=s;return typeof t.message=="string"?t.message:typeof t.name=="string"?t.name:"data"in t?p(t.data):u(s)||"opencode request failed"}class y extends d{type="opencode";process=null;agentSessionId=null;workDir=null;seq=0;runId="";terminalState="closed";externalChannel=null;shennianSessionId=null;extraEnv={};configure(t){this.shennianSessionId=t.sessionId??null,this.externalChannel=t.externalChannel??null,this.extraEnv=t.env??{}}async start(t,e,n){this.workDir=e,n&&(this.agentSessionId=n),this.resetRunState()}async send(t,e){await this.killProcess(),this.runId=l(),this.resetRunState();const n=["run","--format","json","--dangerously-skip-permissions","--dir",this.workDir??process.cwd()];this.agentSessionId&&n.push("--session",this.agentSessionId),e&&n.push("--model",e);const o=this.agentSessionId?t:`${I(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0)}${t}`;n.push(o),this.spawnAndParse(n)}async resume(t){await this.killProcess(),this.agentSessionId=t,this.runId=l(),this.resetRunState(),this.emitEvent({state:"start",agentSessionId:t}),this.emitFinalIfOpen({state:"final",agentSessionId:t})}async stop(){await this.killProcess()}resetRunState(){this.seq=0,this.terminalState="open"}spawnAndParse(t){const e=m("opencode");if(!e){this.emit("error",new Error('Command "opencode" not found. Install it with "npm i -g opencode-ai@latest".'));return}const n=c(e,t,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:g({NO_COLOR:"1",...this.extraEnv})});this.process=n,h({input:n.stdout}).on("line",i=>{if(i.trim())try{const r=JSON.parse(i);this.handleStreamEvent(r)}catch{this.emitEvent({state:"delta",text:i})}});let a="";n.stderr?.on("data",i=>{a+=i.toString()}),n.on("close",i=>{if(this.process!==n||(this.process=null,this.terminalState!=="open"))return;const r=a.trim();if(i!==0&&i!==null){this.emitErrorIfOpen({state:"error",message:r||`opencode exited with code ${i}`});return}this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??void 0})}),n.on("error",i=>{this.process===n&&(this.process=null,i.code==="ENOENT"?this.emit("error",new Error('Command "opencode" not found. Install it with "npm i -g opencode-ai@latest".')):this.emit("error",i))})}handleStreamEvent(t){t.sessionID&&t.sessionID!==this.agentSessionId&&(this.agentSessionId=t.sessionID,this.emitEvent({state:"start",agentSessionId:t.sessionID}));const e=t.part;if(t.type==="text"&&e?.text){this.emitEvent({state:"delta",text:e.text});return}if(t.type==="reasoning"&&e?.text){this.emitEvent({state:"delta",text:e.text,thinking:!0});return}if(t.type==="tool_use"&&e?.type==="tool"){e.state?.status==="completed"||e.state?.status==="error"?this.emitEvent({state:"tool-result",name:e.tool??"tool",result:e.state.status==="error"?e.state.error??"tool failed":u(e.state?.output)}):this.emitEvent({state:"tool-call",name:e.tool??"tool",args:e.state?.input??{}});return}if(t.type==="error"){this.emitErrorIfOpen({state:"error",message:p(t.error)});return}t.type==="step_finish"&&this.emitFinalIfOpen({state:"final",agentSessionId:this.agentSessionId??t.sessionID,usage:S(e?.tokens)})}emitEvent(t){const e={...t,runId:this.runId,seq:this.seq++};this.emit("agentEvent",e)}emitFinalIfOpen(t){this.terminalState==="open"&&(this.terminalState="closed",this.emitEvent(t))}emitErrorIfOpen(t){this.terminalState==="open"&&(this.terminalState="closed",this.emitEvent(t))}async killProcess(){const t=this.process;t&&(this.process=null,t.kill("SIGTERM"),await new Promise(e=>{t.on("close",e),setTimeout(()=>{t.kill("SIGKILL"),e()},3e3)}))}}f("opencode",()=>new y);export{y as OpenCodeAdapter};
@@ -1,4 +1,5 @@
1
1
  import type { ExternalChannelSessionStatus } from '@shennian/wire';
2
2
  export declare const PLATFORM_OUTPUT_INSTRUCTIONS = "## Shennian Output Instructions\n\nWhen you mention a local file that the user may want to open in Shennian, format it as a Markdown link using the exact local path:\n\n- Use [filename.ext](</absolute/path/to/filename.ext>) for absolute Unix, macOS, or Windows paths.\n- Use [filename.ext](<relative/path/to/filename.ext>) for paths relative to the current working directory.\n- Do not use file:// URLs for local files.\n- Do not put user-openable file paths only inside code blocks.\n- Keep normal http:// and https:// links unchanged.";
3
3
  export declare function buildPlatformInstructions(workDir: string, externalChannel?: ExternalChannelSessionStatus | null, sessionId?: string): string;
4
+ export declare function buildInlineChannelPreamble(workDir: string, externalChannel?: ExternalChannelSessionStatus | null, sessionId?: string): string;
4
5
  export declare function ensurePlatformInstructionsFile(workDir: string, externalChannel?: ExternalChannelSessionStatus | null, sessionId?: string): string;
@@ -1,4 +1,4 @@
1
- import s from"node:fs";import a from"node:path";import{createHash as c}from"node:crypto";import{resolveShennianPath as l}from"../config/index.js";import{buildExternalChannelInstructions as u}from"./external-channel-instructions.js";import{buildInstalledSkillInstructions as f}from"../skills/registry.js";const h=`## Shennian Output Instructions
1
+ import a from"node:fs";import i from"node:path";import{createHash as c}from"node:crypto";import{resolveShennianPath as u}from"../config/index.js";import{buildExternalChannelInstructions as l}from"./external-channel-instructions.js";import{buildInstalledSkillInstructions as f}from"../skills/registry.js";const h=`## Shennian Output Instructions
2
2
 
3
3
  When you mention a local file that the user may want to open in Shennian, format it as a Markdown link using the exact local path:
4
4
 
@@ -6,11 +6,17 @@ When you mention a local file that the user may want to open in Shennian, format
6
6
  - Use [filename.ext](<relative/path/to/filename.ext>) for paths relative to the current working directory.
7
7
  - Do not use file:// URLs for local files.
8
8
  - Do not put user-openable file paths only inside code blocks.
9
- - Keep normal http:// and https:// links unchanged.`;function m(n){const e=a.join(n,"AGENTS.md");try{return s.readFileSync(e,"utf8").trim()}catch{return""}}function p(n,e,o){const r=m(n),t=u(e,a.resolve(n),o),i=f();return`${["# Shennian Agent Instructions",r?`## Project Instructions
9
+ - Keep normal http:// and https:// links unchanged.`;function m(n){const t=i.join(n,"AGENTS.md");try{return a.readFileSync(t,"utf8").trim()}catch{return""}}function p(n,t,r){const o=m(n),e=l(t,i.resolve(n),r),s=f();return`${["# Shennian Agent Instructions",o?`## Project Instructions
10
10
 
11
- ${r}`:"",h,i,t?`## External Message Channel Instructions
11
+ ${o}`:"",h,s,e?`## External Message Channel Instructions
12
12
 
13
- ${t}`:""].filter(Boolean).join(`
13
+ ${e}`:""].filter(Boolean).join(`
14
14
 
15
15
  `)}
16
- `}function b(n,e,o){const r=c("sha256").update(`${a.resolve(n)}:${o??""}:${JSON.stringify(e??null)}`).digest("hex").slice(0,16),t=l("runtime","agent-instructions",`${r}.md`),i=p(n,e,o);s.mkdirSync(a.dirname(t),{recursive:!0});try{if(s.readFileSync(t,"utf8")===i)return t}catch{}return s.writeFileSync(t,i),t}export{h as PLATFORM_OUTPUT_INSTRUCTIONS,p as buildPlatformInstructions,b as ensurePlatformInstructionsFile};
16
+ `}function b(n,t,r){const o=l(t,i.resolve(n),r);return o?`# \u795E\u5FF5\u5916\u90E8\u6D88\u606F\u901A\u9053\u8BF4\u660E\uFF08\u7CFB\u7EDF\u6307\u4EE4\uFF0C\u975E\u7528\u6237\u8F93\u5165\uFF0C\u8BF7\u9075\u5FAA\u540E\u518D\u56DE\u5E94\u4E0B\u65B9\u7528\u6237\u6D88\u606F\uFF09
17
+
18
+ ${o}
19
+
20
+ ---
21
+
22
+ `:""}function $(n,t,r){const o=c("sha256").update(`${i.resolve(n)}:${r??""}:${JSON.stringify(t??null)}`).digest("hex").slice(0,16),e=u("runtime","agent-instructions",`${o}.md`),s=p(n,t,r);a.mkdirSync(i.dirname(e),{recursive:!0});try{if(a.readFileSync(e,"utf8")===s)return e}catch{}return a.writeFileSync(e,s),e}export{h as PLATFORM_OUTPUT_INSTRUCTIONS,b as buildInlineChannelPreamble,p as buildPlatformInstructions,$ as ensurePlatformInstructionsFile};
@@ -56,6 +56,7 @@ export declare class ManagerRuntimeService {
56
56
  private handleIpc;
57
57
  private dispatchChatSend;
58
58
  private dispatchChatEnqueue;
59
+ private tryDirectWeChatRpaReply;
59
60
  private sendManagedWeComReply;
60
61
  private wakeManagerForWorker;
61
62
  private handleExternalMessage;
@@ -1,24 +1,24 @@
1
- import K from"node:http";import{randomBytes as G,randomUUID as p}from"node:crypto";import k from"node:fs";import N from"node:os";import y from"node:path";import{AVAILABLE_BUILTIN_AGENT_TYPES as H,extractPayloadText as j,formatExternalConversationText as z,formatExternalMessageLine as J,formatExternalAttachmentReference as Y,isAgentHiddenPayload as V,isToolPayload as Q}from"@shennian/wire";import{ManagerRegistry as X}from"./registry.js";import{readMessages as Z}from"../session/store.js";import{ChannelRuntime as ee}from"../channels/runtime.js";import{splitExternalReplyText as te}from"../channels/reply-split.js";import{resolveShennianPath as ne}from"../config/index.js";import{buildExternalChannelInstructions as re}from"../agents/external-channel-instructions.js";import{readDirectWeChatLatestOnce as ae,sendDirectWeChatMessageOnce as se}from"../commands/wechat.js";import{createWeChatAutomationLane as ie}from"../channels/wechat-channel/automation-lane.js";const C=Number(process.env.SHENNIAN_MANAGER_IPC_BODY_MAX_BYTES||2*1024*1024),A=12*6e4;let P=null;function qe(r){P=r}function Fe(){return P}function S(r){return y.resolve(r||N.homedir())}function u(r,e,a){r.writeHead(e,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify(a))}function oe(r){return/^agent-(.+)-\d+$/.exec(r)?.[1]??null}function le(r){return r==="manager"?!1:r.startsWith("custom:")?!0:H.includes(r)}function ce(r){const e=/^agent-.+-(\d+)$/.exec(r);if(!e)return null;const a=Number(e[1]);return Number.isInteger(a)&&a>=0?a:null}function D(r){return r.replace(/\r\n/g,`
2
- `).trim()}function de(r){try{const e=JSON.parse(r),a=e.type==="tool_result"||e.result?"tool_result":"tool_call",n=e.name||"tool",t=typeof e.result=="string"?e.result.replace(/\s+/g," ").trim():"",i=t.length>220?`${t.slice(0,220)}...`:t;return i?`[${a}] ${n}: ${i}`:`[${a}] ${n}`}catch{return"[tool]"}}function W(r){if(!r||typeof r!="object")return;const e=r,a=String(e.kind||""),n=String(e.name||""),t=String(e.mimeType||""),i=String(e.dataBase64||""),o=String(e.localPath||""),s=String(e.url||""),c=Number(e.size||0);if(i)throw new Error("Manager IPC external attachments must use localPath or url; dataBase64 is not accepted");if(!(a!=="image"&&a!=="video"&&a!=="file")&&!(!n||!t||!Number.isFinite(c)||c<0)&&!(!o&&!s))return{kind:a,name:n,mimeType:t,size:c,...o?{localPath:o}:{},...s?{url:s}:{}}}function v(r){const e=r.binding&&typeof r.binding=="object"&&!Array.isArray(r.binding)?r.binding:{},a=String(e.sessionId||r.managerSessionId||"").trim(),n=String(e.channelId||"").trim(),t=String(e.conversationId||"").trim(),i=String(e.conversationName||r.conversation||"").trim(),o=String(e.workDir||r.workDir||"").trim();if(!a)throw new Error("WeChat tool sessionId is required");if(!n)throw new Error("WeChat tool channelId is required");if(!t)throw new Error("WeChat tool conversationId is required");if(!i)throw new Error("WeChat tool conversationName is required");if(!o)throw new Error("WeChat tool workDir is required");return{sessionId:a,channelId:n,conversationId:t,conversationName:i,workDir:o}}function ue(r,e){const a=[...r].sort((d,l)=>d.ts-l.ts),n=[];let t=null,i=null,o=null,s="";const c=()=>{if(!t)return;const d=s.trim();d&&n.push({...t,id:`${t.id}-compact`,payload:d}),t=null,i=null,o=null,s=""};for(const d of a){if(V(d.payload)){c();continue}if(d.role==="user"){c(),n.push(d);continue}if(Q(d.payload)){c(),n.push({...d,payload:de(d.payload)});continue}const l=j(d.payload);if(!l.trim())continue;const h=oe(d.id),g=ce(d.id);t&&t.role===d.role&&i===h&&h&&g!==null&&o!==null&&g===o+1?(s+=l,t.ts=d.ts,o=g):(c(),t=d,i=h,o=g,s=l)}return c(),n.slice(-e).sort((d,l)=>l.ts-d.ts)}async function he(r){const e=[];let a=0;for await(const t of r){const i=Buffer.from(t);if(a+=i.byteLength,Number.isFinite(C)&&C>0&&a>C)throw new Error(`Manager IPC request body is too large. Max: ${C} bytes.`);e.push(i)}const n=Buffer.concat(e).toString("utf-8");return n?JSON.parse(n):{}}function w(r,e,a,n){r.client.sendRes({type:"res",id:e,ok:a,...a?{payload:n}:{error:String(n.error||"unknown error")}})}function $(r){return/binding not found|unknown method|not supported|relay is not connected|no external channel/i.test(r)}function _(){return ge()?y.join(N.tmpdir(),"shennian-vitest-runtime",String(process.pid),"manager-ipc.json"):ne("runtime","manager-ipc.json")}function ge(){return(process.env.VITEST==="true"||!!process.env.VITEST_WORKER_ID)&&!process.env.SHENNIAN_HOME?.trim()}class Le{opts;registry=new X;channelRuntime;server=null;ipcUrl=null;ipcToken=G(24).toString("hex");healthTimer=null;startPromise=null;workerTextAcc=new Map;weChatAutomationLane;constructor(e){this.opts=e,this.weChatAutomationLane=e.weChatAutomationLane??ie(),this.channelRuntime=e.channelRuntime??new ee((a,n)=>{this.handleExternalMessage(a,n)},a=>this.registry.createReplyTarget(a).replyTarget,{createWeChatRpaProductRunner:e.createWeChatRpaProductRunner,weChatAutomationLane:this.weChatAutomationLane})}async start(){return this.startPromise?this.startPromise:(this.startPromise=this.doStart(),this.startPromise)}async doStart(){if(this.server)return;this.server=K.createServer((a,n)=>{this.handleIpc(a,n)}),this.server.requestTimeout=A,this.server.timeout=A,this.server.keepAliveTimeout=A,this.server.headersTimeout=A+5e3,await new Promise((a,n)=>{this.server.once("error",n),this.server.listen(0,"127.0.0.1",()=>a())});const e=this.server.address();typeof e=="object"&&e&&(this.ipcUrl=`http://127.0.0.1:${e.port}`,this.writeIpcRuntimeFile()),this.server.unref(),await this.channelRuntime.start(),this.broadcastConfiguredChannelStatuses(),this.healthTimer=setInterval(()=>this.scanWorkerHealth(),6e4),this.healthTimer.unref()}async ready(){await this.start()}async stop(){this.healthTimer&&clearInterval(this.healthTimer),this.healthTimer=null,await this.channelRuntime.stop(),await new Promise(e=>{if(!this.server)return e();this.server.close(()=>e())}),this.server=null,this.ipcUrl=null,this.removeIpcRuntimeFile()}writeIpcRuntimeFile(){if(this.ipcUrl)try{const e=_();k.mkdirSync(y.dirname(e),{recursive:!0}),k.writeFileSync(e,JSON.stringify({url:this.ipcUrl,token:this.ipcToken,pid:process.pid,updatedAt:new Date().toISOString()},null,2),{mode:384}),k.chmodSync(e,384)}catch{}}removeIpcRuntimeFile(){try{const e=_(),a=JSON.parse(k.readFileSync(e,"utf-8"));(a.url===this.ipcUrl||a.token===this.ipcToken)&&k.unlinkSync(e)}catch{}}getInjectedEnv(e,a,n,t){return this.ipcUrl?{SHENNIAN_MANAGER_SESSION_ID:e,SHENNIAN_MANAGER_AGENT_SESSION_ID:a??"",SHENNIAN_MANAGER_WORKDIR:S(n),SHENNIAN_MANAGER_MODEL:t,SHENNIAN_MANAGER_IPC_URL:this.ipcUrl,SHENNIAN_MANAGER_IPC_TOKEN:this.ipcToken}:{}}registerManager(e){this.registry.upsertManager({...e,workDir:S(e.workDir),machineId:process.env.SHENNIAN_MACHINE_ID??null})}setManagerWorkerDefaults(e,a,n){const t=this.registry.getManager(e);t&&this.registry.upsertManager({...t,defaultWorkerAgentType:a??null,defaultWorkerModelId:n??null})}getManagerWorkerDefaults(e){const a=this.registry.getManager(e);return{agentType:a?.defaultWorkerAgentType??null,modelId:a?.defaultWorkerModelId??null}}noteManagerAgentSession(e,a,n,t){this.registry.upsertManager({sessionId:e,agentSessionId:a,workDir:S(n),machineId:process.env.SHENNIAN_MACHINE_ID??null,modelId:t})}noteAgentEvent(e,a){if(!this.findWorker(e))return;const t={lastActivityAt:new Date().toISOString(),runId:a.runId};a.agentSessionId&&(t.agentSessionId=a.agentSessionId);const i=`${e}:${a.runId}`;if(a.state==="delta"&&a.text&&!a.thinking){const s=(this.workerTextAcc.get(i)??"")+a.text;this.workerTextAcc.set(i,s);const c=D(s);c&&(t.summary=c.length>160?`${c.slice(0,160)}...`:c)}if(a.state==="final"||a.state==="error"||a.state==="aborted"){t.status=a.state;const s=D(this.workerTextAcc.get(i)??"");s&&(t.summary=s.length>240?`${s.slice(0,240)}...`:s),this.workerTextAcc.delete(i)}else a.state==="start"&&(t.status="running");const o=this.registry.updateWorker(e,t);o&&(a.state==="final"||a.state==="error"||a.state==="aborted")&&this.wakeManagerForWorker(o.managedBy,o,a.state,a.message)}findWorker(e){return this.registry.load().workers[e]}async handleAppReq(e){const a=this.opts.getRuntime(),n=e.params??{};try{const t=String(n.managerSessionId||n.sessionId||"");if(!t)throw new Error("sessionId is required");const i=this.registry.getManager(t),o=e.method==="session.wechat-rpa.channel.get"||e.method==="manager.wechat-rpa.channel.get",s=e.method==="session.wechat-rpa.channel.upsert"||e.method==="manager.wechat-rpa.channel.upsert",c=e.method==="session.wechat-rpa.channel.sync"||e.method==="manager.wechat-rpa.channel.sync",d=e.method==="session.wechat-rpa.outbound.cancel"||e.method==="manager.wechat-rpa.outbound.cancel";if(e.method==="manager.channel.get"){w(a,e.id,!0,{channel:this.channelRuntime.getManagerChannel(t,"websocket",{includeSecret:!0})});return}if(e.method==="manager.channel.upsert"){const l=await this.channelRuntime.upsertManagerChannel({id:String(n.id||`websocket:${t}`),managerSessionId:t,sessionId:t,workDir:String(n.workDir||i?.workDir||""),type:"websocket",name:typeof n.name=="string"?n.name:void 0,agentType:typeof n.agentType=="string"?n.agentType:void 0,agentSessionId:typeof n.agentSessionId=="string"?n.agentSessionId:null,modelId:typeof n.modelId=="string"?n.modelId:null,enabled:!!n.enabled,wsUrl:typeof n.wsUrl=="string"?n.wsUrl:void 0,token:typeof n.token=="string"?n.token:void 0,canReply:n.canReply===void 0?void 0:!!n.canReply,systemPrompt:typeof n.systemPrompt=="string"?n.systemPrompt:void 0});this.broadcastManagerChannelStatus(t),w(a,e.id,!0,{channel:l});return}if(o){w(a,e.id,!0,{channel:this.channelRuntime.getManagerChannel(t,"wechat-rpa",{includeSecret:!0})});return}if(s){const l=await this.channelRuntime.upsertManagerWeChatRpaChannel({id:String(n.id||`wechat-rpa:${t}`),managerSessionId:t,sessionId:t,workDir:S(String(n.workDir||i?.workDir||"")),name:typeof n.name=="string"?n.name:void 0,agentType:typeof n.agentType=="string"?n.agentType:void 0,agentSessionId:typeof n.agentSessionId=="string"?n.agentSessionId:null,modelId:typeof n.modelId=="string"?n.modelId:null,enabled:!!n.enabled,groups:B(n.groups),canReply:n.canReply===void 0?void 0:!!n.canReply,systemPrompt:typeof n.systemPrompt=="string"?n.systemPrompt:void 0,source:q(n.source),pollIntervalMs:m(n.pollIntervalMs),recentLimit:m(n.recentLimit),idleSeconds:m(n.idleSeconds),forceForeground:n.forceForeground===void 0?void 0:!!n.forceForeground,noRestore:n.noRestore===void 0?void 0:!!n.noRestore,downloadAttachments:n.downloadAttachments===void 0?void 0:!!n.downloadAttachments,downloadAttachmentsDir:typeof n.downloadAttachmentsDir=="string"?n.downloadAttachmentsDir:void 0,selfNickname:typeof n.selfNickname=="string"?n.selfNickname:void 0,selfTriggerMarker:typeof n.selfTriggerMarker=="string"?n.selfTriggerMarker:void 0,deferInitialPoll:n.deferInitialPoll===void 0?void 0:!!n.deferInitialPoll,privacyConsentAccepted:n.privacyConsentAccepted===void 0?void 0:!!n.privacyConsentAccepted,flowScriptPath:typeof n.flowScriptPath=="string"?n.flowScriptPath:void 0});this.broadcastManagerChannelStatus(t),w(a,e.id,!0,{channel:l});return}if(c){const l=await this.channelRuntime.syncManagerWeChatRpaChannel(t);this.broadcastManagerChannelStatus(t),w(a,e.id,!0,l);return}if(d){const l=await this.channelRuntime.cancelManagerWeChatRpaOutbound({managerSessionId:t,idempotencyKey:typeof n.idempotencyKey=="string"?n.idempotencyKey:null,replyId:typeof n.replyId=="string"?n.replyId:null,reason:typeof n.reason=="string"?n.reason:"user_cancelled"});this.broadcastManagerChannelStatus(t),w(a,e.id,!0,l);return}throw new Error(`Unsupported manager app method: ${e.method}`)}catch(t){w(a,e.id,!1,{error:t instanceof Error?t.message:String(t)})}}broadcastConfiguredChannelStatuses(){for(const e of this.channelRuntime.listManagerChannelStatuses())this.broadcastManagerChannelStatus(e.managerSessionId)}broadcastManagerChannelStatus(e){const a=this.opts.getRuntime();if(!a.client?.sendEvent)return;const n=this.registry.getManager(e),t=this.channelRuntime.getManagerChannelStatus(e),i=this.channelRuntime.getManagerChannel(e,"wechat-rpa")??this.channelRuntime.getManagerChannel(e,"websocket");a.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:e,agentType:n?"manager":i?.agentType,agentSessionId:n?.agentSessionId??i?.agentSessionId??null,modelId:n?.modelId??i?.modelId??null,workDir:n?.workDir??i?.workDir,externalChannel:t}}})}async handleIpc(e,a){if(e.headers.authorization!==`Bearer ${this.ipcToken}`){u(a,401,{ok:!1,error:"Unauthorized"});return}try{const n=new URL(e.url??"/","http://127.0.0.1"),t=await he(e),i=String(t.managerSessionId||e.headers["x-shennian-manager-session-id"]||"");if(!i)throw new Error("managerSessionId is required");const o=this.registry.getManager(i);if(n.pathname==="/sessions/list"){if(!o)throw new Error("Manager runtime is not registered");const s=new Set(this.opts.getRuntime().sessions.keys());u(a,200,{ok:!0,sessions:this.registry.listWorkers(i,{runningSessionIds:s})});return}if(n.pathname==="/sessions/start"){if(!o)throw new Error("Manager runtime is not registered");const s=String(t.agentType||t.agent||o.defaultWorkerAgentType||"codex");if(!le(s))throw new Error(`Unsupported manager worker agent: ${s}`);const c=S(String(t.workDir||o.workDir));if(c!==o.workDir)throw new Error("Manager can only start workers in the same workDir");const d=String(t.message||"");if(!d)throw new Error("message is required");const l=this.registry.addWorker({managerSessionId:i,agentType:s,workDir:c,summary:d.slice(0,120)}),h=String(t.modelId||(s===o.defaultWorkerAgentType?o.defaultWorkerModelId??"":""));await this.dispatchChatSend(l.sessionId,s,c,d,null,h),u(a,200,{ok:!0,session:l});return}if(n.pathname==="/sessions/send"){const s=String(t.sessionId||""),c=String(t.message||""),d=t.enqueue===void 0?!0:!!t.enqueue,l=this.registry.getWorkerForManager(i,s);if(!l)throw new Error("Worker not found in this manager scope");const h=String(t.modelId||(l.agentType===o?.defaultWorkerAgentType?o.defaultWorkerModelId??"":""));d?await this.dispatchChatEnqueue(l.sessionId,l.agentType,l.workDir,c,l.agentSessionId??null,h):await this.dispatchChatSend(l.sessionId,l.agentType,l.workDir,c,l.agentSessionId??null,h),u(a,200,{ok:!0});return}if(n.pathname==="/sessions/queue"){const s=String(t.sessionId||"");if(!this.registry.getWorkerForManager(i,s))throw new Error("Worker not found in this manager scope");const d=this.opts.getRuntime().chatQueue?.getSnapshot(s);u(a,200,{ok:!0,queue:d});return}if(n.pathname==="/sessions/queue/edit"){const s=String(t.sessionId||"");if(!this.registry.getWorkerForManager(i,s))throw new Error("Worker not found in this manager scope");await this.opts.dispatchReq({type:"req",id:`manager-queue-edit-${p()}`,method:"chat.queue.edit",params:{sessionId:s,queueMessageId:String(t.queueMessageId||t.messageId||""),text:String(t.message||t.text||"")}}),u(a,200,{ok:!0,queue:this.opts.getRuntime().chatQueue?.getSnapshot(s)});return}if(n.pathname==="/sessions/queue/delete"){const s=String(t.sessionId||"");if(!this.registry.getWorkerForManager(i,s))throw new Error("Worker not found in this manager scope");await this.opts.dispatchReq({type:"req",id:`manager-queue-delete-${p()}`,method:"chat.queue.delete",params:{sessionId:s,queueMessageId:String(t.queueMessageId||t.messageId||"")}}),u(a,200,{ok:!0,queue:this.opts.getRuntime().chatQueue?.getSnapshot(s)});return}if(n.pathname==="/sessions/stop"||n.pathname==="/sessions/terminate"){const s=String(t.sessionId||"");if(!this.registry.getWorkerForManager(i,s))throw new Error("Worker not found in this manager scope");await this.opts.dispatchReq({type:"req",id:`manager-abort-${p()}`,method:"chat.abort",params:{sessionId:s}}),this.registry.updateWorker(s,{status:"aborted"}),u(a,200,{ok:!0});return}if(n.pathname==="/sessions/read"){const s=String(t.sessionId||""),c=Number(t.limit||200);if(!this.registry.getWorkerForManager(i,s))throw new Error("Worker not found in this manager scope");const l=Z(s,{limit:Math.max(c*20,c)});u(a,200,{ok:!0,messages:ue(l,c),rawMessageCount:l.length});return}if(n.pathname==="/memory/path"){if(!o)throw new Error("Manager runtime is not registered");u(a,200,{ok:!0,path:y.join(o.workDir,".shennian")});return}if(n.pathname==="/external/reply"){const s=typeof t.replyTarget=="string"?this.registry.getReplyTarget(t.replyTarget):this.registry.getLatestReplyTargetForManager(i),c=String(t.text||""),d=W(t.attachment),l=String(t.idempotencyKey||p()),h=String(t.channelId||""),g=String(t.conversationId||""),M=!s&&(!h||!g)?await this.channelRuntime.getDefaultReplyTarget(i).catch(()=>null):null,R=s?.channelId||h||M?.channelId||"",E=s?.conversationId||g||M?.conversationId||"";if(R&&this.channelRuntime.getChannelById(R)){if(!E)throw new Error("No external channel target is available for this Manager");const f=await this.channelRuntime.reply({managerSessionId:i,channelId:R,conversationId:E,messageId:s?.messageId??void 0,text:c,attachment:d,idempotencyKey:l});u(a,f.ok?200:400,f);return}let I;try{I=await this.sendManagedWeComReply({managerSessionId:i,text:c,attachment:d,idempotencyKey:l})}catch(f){const x=f instanceof Error?f.message:String(f);if(!$(x))throw f;I={ok:!1,error:x}}if(I.ok){u(a,200,{ok:!0,payload:I.payload});return}if(!$(I.error||"")||!R||!E){u(a,400,{ok:!1,error:I.error||"External send failed"});return}u(a,400,{ok:!1,error:`No local external channel is configured for ${R}`});return}if(n.pathname==="/channel/get"){u(a,200,{ok:!0,channel:this.channelRuntime.getManagerChannel(i,"websocket")});return}if(n.pathname==="/channel/upsert"){if(!o)throw new Error("Manager runtime is not registered");const s=await this.channelRuntime.upsertManagerChannel({id:String(t.id||`websocket:${i}`),managerSessionId:i,workDir:o.workDir,type:"websocket",name:typeof t.name=="string"?t.name:void 0,enabled:!!t.enabled,wsUrl:typeof t.wsUrl=="string"?t.wsUrl:void 0,token:typeof t.token=="string"?t.token:void 0,canReply:t.canReply===void 0?void 0:!!t.canReply,systemPrompt:typeof t.systemPrompt=="string"?t.systemPrompt:void 0});this.registry.upsertManager({...o,status:o.status}),this.broadcastManagerChannelStatus(i),u(a,200,{ok:!0,channel:s});return}if(n.pathname==="/wechat-rpa/tool/read"){const s=v(t),c=m(t.limit)??10,d=typeof t.traceId=="string"?t.traceId:void 0;let l;try{l=await this.weChatAutomationLane.run(`wechat-tool:read:${s.channelId}`,()=>ae(s,{conversation:s.conversationName,workDir:s.workDir,sessionId:s.sessionId,limit:c,recentLimit:c,download:t.download==="never"?"never":"auto",traceId:d,timeoutMs:m(t.timeoutMs)}))}catch(h){u(a,400,{ok:!1,...U(h,d)});return}u(a,200,{ok:!0,messages:l.messages,outDir:l.outDir,helperTracePath:l.helperTracePath,activityGuardPath:l.activityGuardPath});return}if(n.pathname==="/wechat-rpa/tool/send"){const s=v(t),c=String(t.text||""),d=W(t.attachment),l=typeof t.traceId=="string"?t.traceId:void 0;let h;try{h=await this.weChatAutomationLane.run(`wechat-tool:send:${s.channelId}`,()=>se(s,{conversation:s.conversationName,workDir:s.workDir,sessionId:s.sessionId,text:c,attachment:d,traceId:l,timeoutMs:m(t.timeoutMs)}))}catch(g){u(a,400,{ok:!1,...U(g,l)});return}u(a,200,{ok:!0,...h});return}if(n.pathname==="/wechat-rpa/channel/get"){u(a,200,{ok:!0,channel:this.channelRuntime.getManagerChannel(i,"wechat-rpa",{includeSecret:!0})});return}if(n.pathname==="/wechat-rpa/channel/upsert"){const s=S(String(t.workDir||o?.workDir||""));if(!s)throw new Error("workDir is required");const c=await this.channelRuntime.upsertManagerWeChatRpaChannel({id:String(t.id||`wechat-rpa:${i}`),managerSessionId:i,sessionId:i,workDir:s,name:typeof t.name=="string"?t.name:void 0,agentType:typeof t.agentType=="string"?t.agentType:void 0,agentSessionId:typeof t.agentSessionId=="string"?t.agentSessionId:null,modelId:typeof t.modelId=="string"?t.modelId:null,enabled:!!t.enabled,groups:B(t.groups),canReply:t.canReply===void 0?void 0:!!t.canReply,systemPrompt:typeof t.systemPrompt=="string"?t.systemPrompt:void 0,source:q(t.source),pollIntervalMs:m(t.pollIntervalMs),recentLimit:m(t.recentLimit),idleSeconds:m(t.idleSeconds),forceForeground:t.forceForeground===void 0?void 0:!!t.forceForeground,noRestore:t.noRestore===void 0?void 0:!!t.noRestore,downloadAttachments:t.downloadAttachments===void 0?void 0:!!t.downloadAttachments,downloadAttachmentsDir:typeof t.downloadAttachmentsDir=="string"?t.downloadAttachmentsDir:void 0,selfNickname:typeof t.selfNickname=="string"?t.selfNickname:void 0,selfTriggerMarker:typeof t.selfTriggerMarker=="string"?t.selfTriggerMarker:void 0,deferInitialPoll:t.deferInitialPoll===void 0?void 0:!!t.deferInitialPoll,privacyConsentAccepted:t.privacyConsentAccepted===void 0?void 0:!!t.privacyConsentAccepted,flowScriptPath:typeof t.flowScriptPath=="string"?t.flowScriptPath:void 0});o&&this.registry.upsertManager({...o,status:o.status}),this.broadcastManagerChannelStatus(i),u(a,200,{ok:!0,channel:c});return}if(n.pathname==="/wechat-rpa/channel/sync"){const{channel:s,messages:c}=await this.channelRuntime.syncManagerWeChatRpaChannel(i);this.broadcastManagerChannelStatus(i),u(a,200,{ok:!0,channel:s,messages:c});return}if(n.pathname==="/wechat-rpa/outbound/cancel"){const s=await this.channelRuntime.cancelManagerWeChatRpaOutbound({managerSessionId:i,idempotencyKey:typeof t.idempotencyKey=="string"?t.idempotencyKey:null,replyId:typeof t.replyId=="string"?t.replyId:null,reason:typeof t.reason=="string"?t.reason:"user_cancelled"});this.broadcastManagerChannelStatus(i),u(a,200,{ok:!0,...s});return}u(a,404,{ok:!1,error:`Unknown manager IPC path: ${n.pathname}`})}catch(n){u(a,400,{ok:!1,error:n instanceof Error?n.message:String(n)})}}async dispatchChatSend(e,a,n,t,i,o){await this.opts.dispatchReq({type:"req",id:`manager-send-${p()}`,method:"chat.send",params:{sessionId:e,text:t,agentType:a,workDir:n,agentSessionId:i,modelId:o}})}async dispatchChatEnqueue(e,a,n,t,i,o){await this.opts.dispatchReq({type:"req",id:`manager-enqueue-${p()}`,method:"chat.enqueue",params:{sessionId:e,text:t,agentType:a,workDir:n,agentSessionId:i,modelId:o}})}async sendManagedWeComReply(e){const a=te(e.text);if(!a.length&&!e.attachment)return{ok:!1,error:"text or attachment is required"};const n=this.opts.getRuntime().client;if(!n||typeof n.sendReq!="function")return{ok:!1,error:"Relay is not connected"};const t=[];for(const[i,o]of a.entries()){const s=await n.sendReq({type:"req",id:`external-send-${p()}`,method:"external.send",params:{managerSessionId:e.managerSessionId,text:o,idempotencyKey:a.length>1?`${e.idempotencyKey}:${i+1}`:e.idempotencyKey}});if(!s.ok)return{ok:!1,error:s.error||"External send failed"};t.push(s.payload)}if(e.attachment){const i=await n.sendReq({type:"req",id:`external-send-${p()}`,method:"external.send",params:{managerSessionId:e.managerSessionId,attachment:e.attachment,idempotencyKey:a.length?`${e.idempotencyKey}:attachment`:e.idempotencyKey}});if(!i.ok)return{ok:!1,error:i.error||"External send failed"};t.push(i.payload)}return{ok:!0,payload:t.length===1?t[0]:t}}wakeManagerForWorker(e,a,n,t){const i=this.registry.getManager(e);if(!i)return;const o=`\u4F60\u7BA1\u7406\u7684 worker \u5DF2\u7ED3\u675F\u3002
1
+ import G from"node:http";import{randomBytes as j,randomUUID as m}from"node:crypto";import k from"node:fs";import D from"node:os";import y from"node:path";import{AVAILABLE_BUILTIN_AGENT_TYPES as z,extractPayloadText as J,formatExternalConversationText as Y,formatExternalMessageLine as V,formatExternalAttachmentReference as Q,isAgentHiddenPayload as X,isToolPayload as Z}from"@shennian/wire";import{ManagerRegistry as ee}from"./registry.js";import{readMessages as te}from"../session/store.js";import{ChannelRuntime as ne}from"../channels/runtime.js";import{splitExternalReplyText as re}from"../channels/reply-split.js";import{loadConfig as ae,resolveShennianPath as se}from"../config/index.js";import{weChatChannelConversationId as ie}from"../channels/wechat-rpa/product-channel.js";import{buildExternalChannelInstructions as oe}from"../agents/external-channel-instructions.js";import{readDirectWeChatLatestOnce as ce,sendDirectWeChatMessageOnce as P}from"../commands/wechat.js";import{createWeChatAutomationLane as le}from"../channels/wechat-channel/automation-lane.js";const C=Number(process.env.SHENNIAN_MANAGER_IPC_BODY_MAX_BYTES||2*1024*1024),A=12*6e4;let v=null;function Ue(r){v=r}function He(){return v}function S(r){return y.resolve(r||D.homedir())}function u(r,e,a){r.writeHead(e,{"content-type":"application/json; charset=utf-8"}),r.end(JSON.stringify(a))}function de(r){return/^agent-(.+)-\d+$/.exec(r)?.[1]??null}function ue(r){return r==="manager"?!1:r.startsWith("custom:")?!0:z.includes(r)}function he(r){const e=/^agent-.+-(\d+)$/.exec(r);if(!e)return null;const a=Number(e[1]);return Number.isInteger(a)&&a>=0?a:null}function W(r){return r.replace(/\r\n/g,`
2
+ `).trim()}function ge(r){try{const e=JSON.parse(r),a=e.type==="tool_result"||e.result?"tool_result":"tool_call",n=e.name||"tool",t=typeof e.result=="string"?e.result.replace(/\s+/g," ").trim():"",s=t.length>220?`${t.slice(0,220)}...`:t;return s?`[${a}] ${n}: ${s}`:`[${a}] ${n}`}catch{return"[tool]"}}function $(r){if(!r||typeof r!="object")return;const e=r,a=String(e.kind||""),n=String(e.name||""),t=String(e.mimeType||""),s=String(e.dataBase64||""),o=String(e.localPath||""),i=String(e.url||""),c=Number(e.size||0);if(s)throw new Error("Manager IPC external attachments must use localPath or url; dataBase64 is not accepted");if(!(a!=="image"&&a!=="video"&&a!=="file")&&!(!n||!t||!Number.isFinite(c)||c<0)&&!(!o&&!i))return{kind:a,name:n,mimeType:t,size:c,...o?{localPath:o}:{},...i?{url:i}:{}}}function _(r){const e=r.binding&&typeof r.binding=="object"&&!Array.isArray(r.binding)?r.binding:{},a=String(e.sessionId||r.managerSessionId||"").trim(),n=String(e.channelId||"").trim(),t=String(e.conversationId||"").trim(),s=String(e.conversationName||r.conversation||"").trim(),o=String(e.workDir||r.workDir||"").trim();if(!a)throw new Error("WeChat tool sessionId is required");if(!n)throw new Error("WeChat tool channelId is required");if(!t)throw new Error("WeChat tool conversationId is required");if(!s)throw new Error("WeChat tool conversationName is required");if(!o)throw new Error("WeChat tool workDir is required");return{sessionId:a,channelId:n,conversationId:t,conversationName:s,workDir:o}}function me(r,e){const a=[...r].sort((d,l)=>d.ts-l.ts),n=[];let t=null,s=null,o=null,i="";const c=()=>{if(!t)return;const d=i.trim();d&&n.push({...t,id:`${t.id}-compact`,payload:d}),t=null,s=null,o=null,i=""};for(const d of a){if(X(d.payload)){c();continue}if(d.role==="user"){c(),n.push(d);continue}if(Z(d.payload)){c(),n.push({...d,payload:ge(d.payload)});continue}const l=J(d.payload);if(!l.trim())continue;const h=de(d.id),g=he(d.id);t&&t.role===d.role&&s===h&&h&&g!==null&&o!==null&&g===o+1?(i+=l,t.ts=d.ts,o=g):(c(),t=d,s=h,o=g,i=l)}return c(),n.slice(-e).sort((d,l)=>l.ts-d.ts)}async function pe(r){const e=[];let a=0;for await(const t of r){const s=Buffer.from(t);if(a+=s.byteLength,Number.isFinite(C)&&C>0&&a>C)throw new Error(`Manager IPC request body is too large. Max: ${C} bytes.`);e.push(s)}const n=Buffer.concat(e).toString("utf-8");return n?JSON.parse(n):{}}function w(r,e,a,n){r.client.sendRes({type:"res",id:e,ok:a,...a?{payload:n}:{error:String(n.error||"unknown error")}})}function B(r){return/binding not found|unknown method|not supported|relay is not connected|no external channel/i.test(r)}function q(){return fe()?y.join(D.tmpdir(),"shennian-vitest-runtime",String(process.pid),"manager-ipc.json"):se("runtime","manager-ipc.json")}function fe(){return(process.env.VITEST==="true"||!!process.env.VITEST_WORKER_ID)&&!process.env.SHENNIAN_HOME?.trim()}class Ke{opts;registry=new ee;channelRuntime;server=null;ipcUrl=null;ipcToken=j(24).toString("hex");healthTimer=null;startPromise=null;workerTextAcc=new Map;weChatAutomationLane;constructor(e){this.opts=e,this.weChatAutomationLane=e.weChatAutomationLane??le(),this.channelRuntime=e.channelRuntime??new ne((a,n)=>{this.handleExternalMessage(a,n)},a=>this.registry.createReplyTarget(a).replyTarget,{createWeChatRpaProductRunner:e.createWeChatRpaProductRunner,weChatAutomationLane:this.weChatAutomationLane})}async start(){return this.startPromise?this.startPromise:(this.startPromise=this.doStart(),this.startPromise)}async doStart(){if(this.server)return;this.server=G.createServer((a,n)=>{this.handleIpc(a,n)}),this.server.requestTimeout=A,this.server.timeout=A,this.server.keepAliveTimeout=A,this.server.headersTimeout=A+5e3,await new Promise((a,n)=>{this.server.once("error",n),this.server.listen(0,"127.0.0.1",()=>a())});const e=this.server.address();typeof e=="object"&&e&&(this.ipcUrl=`http://127.0.0.1:${e.port}`,this.writeIpcRuntimeFile()),this.server.unref(),await this.channelRuntime.start(),this.broadcastConfiguredChannelStatuses(),this.healthTimer=setInterval(()=>this.scanWorkerHealth(),6e4),this.healthTimer.unref()}async ready(){await this.start()}async stop(){this.healthTimer&&clearInterval(this.healthTimer),this.healthTimer=null,await this.channelRuntime.stop(),await new Promise(e=>{if(!this.server)return e();this.server.close(()=>e())}),this.server=null,this.ipcUrl=null,this.removeIpcRuntimeFile()}writeIpcRuntimeFile(){if(this.ipcUrl)try{const e=q();k.mkdirSync(y.dirname(e),{recursive:!0}),k.writeFileSync(e,JSON.stringify({url:this.ipcUrl,token:this.ipcToken,pid:process.pid,updatedAt:new Date().toISOString()},null,2),{mode:384}),k.chmodSync(e,384)}catch{}}removeIpcRuntimeFile(){try{const e=q(),a=JSON.parse(k.readFileSync(e,"utf-8"));(a.url===this.ipcUrl||a.token===this.ipcToken)&&k.unlinkSync(e)}catch{}}getInjectedEnv(e,a,n,t){return this.ipcUrl?{SHENNIAN_MANAGER_SESSION_ID:e,SHENNIAN_MANAGER_AGENT_SESSION_ID:a??"",SHENNIAN_MANAGER_WORKDIR:S(n),SHENNIAN_MANAGER_MODEL:t,SHENNIAN_MANAGER_IPC_URL:this.ipcUrl,SHENNIAN_MANAGER_IPC_TOKEN:this.ipcToken}:{}}registerManager(e){this.registry.upsertManager({...e,workDir:S(e.workDir),machineId:process.env.SHENNIAN_MACHINE_ID??null})}setManagerWorkerDefaults(e,a,n){const t=this.registry.getManager(e);t&&this.registry.upsertManager({...t,defaultWorkerAgentType:a??null,defaultWorkerModelId:n??null})}getManagerWorkerDefaults(e){const a=this.registry.getManager(e);return{agentType:a?.defaultWorkerAgentType??null,modelId:a?.defaultWorkerModelId??null}}noteManagerAgentSession(e,a,n,t){this.registry.upsertManager({sessionId:e,agentSessionId:a,workDir:S(n),machineId:process.env.SHENNIAN_MACHINE_ID??null,modelId:t})}noteAgentEvent(e,a){if(!this.findWorker(e))return;const t={lastActivityAt:new Date().toISOString(),runId:a.runId};a.agentSessionId&&(t.agentSessionId=a.agentSessionId);const s=`${e}:${a.runId}`;if(a.state==="delta"&&a.text&&!a.thinking){const i=(this.workerTextAcc.get(s)??"")+a.text;this.workerTextAcc.set(s,i);const c=W(i);c&&(t.summary=c.length>160?`${c.slice(0,160)}...`:c)}if(a.state==="final"||a.state==="error"||a.state==="aborted"){t.status=a.state;const i=W(this.workerTextAcc.get(s)??"");i&&(t.summary=i.length>240?`${i.slice(0,240)}...`:i),this.workerTextAcc.delete(s)}else a.state==="start"&&(t.status="running");const o=this.registry.updateWorker(e,t);o&&(a.state==="final"||a.state==="error"||a.state==="aborted")&&this.wakeManagerForWorker(o.managedBy,o,a.state,a.message)}findWorker(e){return this.registry.load().workers[e]}async handleAppReq(e){const a=this.opts.getRuntime(),n=e.params??{};try{const t=String(n.managerSessionId||n.sessionId||"");if(!t)throw new Error("sessionId is required");const s=this.registry.getManager(t),o=e.method==="session.wechat-rpa.channel.get"||e.method==="manager.wechat-rpa.channel.get",i=e.method==="session.wechat-rpa.channel.upsert"||e.method==="manager.wechat-rpa.channel.upsert",c=e.method==="session.wechat-rpa.channel.sync"||e.method==="manager.wechat-rpa.channel.sync",d=e.method==="session.wechat-rpa.outbound.cancel"||e.method==="manager.wechat-rpa.outbound.cancel";if(e.method==="manager.channel.get"){w(a,e.id,!0,{channel:this.channelRuntime.getManagerChannel(t,"websocket",{includeSecret:!0})});return}if(e.method==="manager.channel.upsert"){const l=await this.channelRuntime.upsertManagerChannel({id:String(n.id||`websocket:${t}`),managerSessionId:t,sessionId:t,workDir:String(n.workDir||s?.workDir||""),type:"websocket",name:typeof n.name=="string"?n.name:void 0,agentType:typeof n.agentType=="string"?n.agentType:void 0,agentSessionId:typeof n.agentSessionId=="string"?n.agentSessionId:null,modelId:typeof n.modelId=="string"?n.modelId:null,enabled:!!n.enabled,wsUrl:typeof n.wsUrl=="string"?n.wsUrl:void 0,token:typeof n.token=="string"?n.token:void 0,canReply:n.canReply===void 0?void 0:!!n.canReply,systemPrompt:typeof n.systemPrompt=="string"?n.systemPrompt:void 0});this.broadcastManagerChannelStatus(t),w(a,e.id,!0,{channel:l});return}if(o){w(a,e.id,!0,{channel:this.channelRuntime.getManagerChannel(t,"wechat-rpa",{includeSecret:!0})});return}if(i){const l=await this.channelRuntime.upsertManagerWeChatRpaChannel({id:String(n.id||`wechat-rpa:${t}`),managerSessionId:t,sessionId:t,workDir:S(String(n.workDir||s?.workDir||"")),name:typeof n.name=="string"?n.name:void 0,agentType:typeof n.agentType=="string"?n.agentType:void 0,agentSessionId:typeof n.agentSessionId=="string"?n.agentSessionId:null,modelId:typeof n.modelId=="string"?n.modelId:null,enabled:!!n.enabled,groups:L(n.groups),canReply:n.canReply===void 0?void 0:!!n.canReply,systemPrompt:typeof n.systemPrompt=="string"?n.systemPrompt:void 0,source:F(n.source),pollIntervalMs:p(n.pollIntervalMs),recentLimit:p(n.recentLimit),idleSeconds:p(n.idleSeconds),forceForeground:n.forceForeground===void 0?void 0:!!n.forceForeground,noRestore:n.noRestore===void 0?void 0:!!n.noRestore,downloadAttachments:n.downloadAttachments===void 0?void 0:!!n.downloadAttachments,downloadAttachmentsDir:typeof n.downloadAttachmentsDir=="string"?n.downloadAttachmentsDir:void 0,selfNickname:typeof n.selfNickname=="string"?n.selfNickname:void 0,selfTriggerMarker:typeof n.selfTriggerMarker=="string"?n.selfTriggerMarker:void 0,deferInitialPoll:n.deferInitialPoll===void 0?void 0:!!n.deferInitialPoll,privacyConsentAccepted:n.privacyConsentAccepted===void 0?void 0:!!n.privacyConsentAccepted,flowScriptPath:typeof n.flowScriptPath=="string"?n.flowScriptPath:void 0});this.broadcastManagerChannelStatus(t),w(a,e.id,!0,{channel:l});return}if(c){const l=await this.channelRuntime.syncManagerWeChatRpaChannel(t);this.broadcastManagerChannelStatus(t),w(a,e.id,!0,l);return}if(d){const l=await this.channelRuntime.cancelManagerWeChatRpaOutbound({managerSessionId:t,idempotencyKey:typeof n.idempotencyKey=="string"?n.idempotencyKey:null,replyId:typeof n.replyId=="string"?n.replyId:null,reason:typeof n.reason=="string"?n.reason:"user_cancelled"});this.broadcastManagerChannelStatus(t),w(a,e.id,!0,l);return}throw new Error(`Unsupported manager app method: ${e.method}`)}catch(t){w(a,e.id,!1,{error:t instanceof Error?t.message:String(t)})}}broadcastConfiguredChannelStatuses(){for(const e of this.channelRuntime.listManagerChannelStatuses())this.broadcastManagerChannelStatus(e.managerSessionId)}broadcastManagerChannelStatus(e){const a=this.opts.getRuntime();if(!a.client?.sendEvent)return;const n=this.registry.getManager(e),t=this.channelRuntime.getManagerChannelStatus(e),s=this.channelRuntime.getManagerChannel(e,"wechat-rpa")??this.channelRuntime.getManagerChannel(e,"websocket");a.client.sendEvent({type:"event",event:"session.update",payload:{session:{id:e,agentType:n?"manager":s?.agentType,agentSessionId:n?.agentSessionId??s?.agentSessionId??null,modelId:n?.modelId??s?.modelId??null,workDir:n?.workDir??s?.workDir,externalChannel:t}}})}async handleIpc(e,a){if(e.headers.authorization!==`Bearer ${this.ipcToken}`){u(a,401,{ok:!1,error:"Unauthorized"});return}try{const n=new URL(e.url??"/","http://127.0.0.1"),t=await pe(e),s=String(t.managerSessionId||e.headers["x-shennian-manager-session-id"]||"");if(!s)throw new Error("managerSessionId is required");const o=this.registry.getManager(s);if(n.pathname==="/sessions/list"){if(!o)throw new Error("Manager runtime is not registered");const i=new Set(this.opts.getRuntime().sessions.keys());u(a,200,{ok:!0,sessions:this.registry.listWorkers(s,{runningSessionIds:i})});return}if(n.pathname==="/sessions/start"){if(!o)throw new Error("Manager runtime is not registered");const i=String(t.agentType||t.agent||o.defaultWorkerAgentType||"codex");if(!ue(i))throw new Error(`Unsupported manager worker agent: ${i}`);const c=S(String(t.workDir||o.workDir));if(c!==o.workDir)throw new Error("Manager can only start workers in the same workDir");const d=String(t.message||"");if(!d)throw new Error("message is required");const l=this.registry.addWorker({managerSessionId:s,agentType:i,workDir:c,summary:d.slice(0,120)}),h=String(t.modelId||(i===o.defaultWorkerAgentType?o.defaultWorkerModelId??"":""));await this.dispatchChatSend(l.sessionId,i,c,d,null,h),u(a,200,{ok:!0,session:l});return}if(n.pathname==="/sessions/send"){const i=String(t.sessionId||""),c=String(t.message||""),d=t.enqueue===void 0?!0:!!t.enqueue,l=this.registry.getWorkerForManager(s,i);if(!l)throw new Error("Worker not found in this manager scope");const h=String(t.modelId||(l.agentType===o?.defaultWorkerAgentType?o.defaultWorkerModelId??"":""));d?await this.dispatchChatEnqueue(l.sessionId,l.agentType,l.workDir,c,l.agentSessionId??null,h):await this.dispatchChatSend(l.sessionId,l.agentType,l.workDir,c,l.agentSessionId??null,h),u(a,200,{ok:!0});return}if(n.pathname==="/sessions/queue"){const i=String(t.sessionId||"");if(!this.registry.getWorkerForManager(s,i))throw new Error("Worker not found in this manager scope");const d=this.opts.getRuntime().chatQueue?.getSnapshot(i);u(a,200,{ok:!0,queue:d});return}if(n.pathname==="/sessions/queue/edit"){const i=String(t.sessionId||"");if(!this.registry.getWorkerForManager(s,i))throw new Error("Worker not found in this manager scope");await this.opts.dispatchReq({type:"req",id:`manager-queue-edit-${m()}`,method:"chat.queue.edit",params:{sessionId:i,queueMessageId:String(t.queueMessageId||t.messageId||""),text:String(t.message||t.text||"")}}),u(a,200,{ok:!0,queue:this.opts.getRuntime().chatQueue?.getSnapshot(i)});return}if(n.pathname==="/sessions/queue/delete"){const i=String(t.sessionId||"");if(!this.registry.getWorkerForManager(s,i))throw new Error("Worker not found in this manager scope");await this.opts.dispatchReq({type:"req",id:`manager-queue-delete-${m()}`,method:"chat.queue.delete",params:{sessionId:i,queueMessageId:String(t.queueMessageId||t.messageId||"")}}),u(a,200,{ok:!0,queue:this.opts.getRuntime().chatQueue?.getSnapshot(i)});return}if(n.pathname==="/sessions/stop"||n.pathname==="/sessions/terminate"){const i=String(t.sessionId||"");if(!this.registry.getWorkerForManager(s,i))throw new Error("Worker not found in this manager scope");await this.opts.dispatchReq({type:"req",id:`manager-abort-${m()}`,method:"chat.abort",params:{sessionId:i}}),this.registry.updateWorker(i,{status:"aborted"}),u(a,200,{ok:!0});return}if(n.pathname==="/sessions/read"){const i=String(t.sessionId||""),c=Number(t.limit||200);if(!this.registry.getWorkerForManager(s,i))throw new Error("Worker not found in this manager scope");const l=te(i,{limit:Math.max(c*20,c)});u(a,200,{ok:!0,messages:me(l,c),rawMessageCount:l.length});return}if(n.pathname==="/memory/path"){if(!o)throw new Error("Manager runtime is not registered");u(a,200,{ok:!0,path:y.join(o.workDir,".shennian")});return}if(n.pathname==="/external/reply"){const i=typeof t.replyTarget=="string"?this.registry.getReplyTarget(t.replyTarget):this.registry.getLatestReplyTargetForManager(s),c=String(t.text||""),d=$(t.attachment),l=String(t.idempotencyKey||m()),h=String(t.channelId||""),g=String(t.conversationId||""),R=!i&&(!h||!g)?await this.channelRuntime.getDefaultReplyTarget(s).catch(()=>null):null,M=i?.channelId||h||R?.channelId||"",T=i?.conversationId||g||R?.conversationId||"";if(M&&this.channelRuntime.getChannelById(M)){if(!T)throw new Error("No external channel target is available for this Manager");const f=await this.channelRuntime.reply({managerSessionId:s,channelId:M,conversationId:T,messageId:i?.messageId??void 0,text:c,attachment:d,idempotencyKey:l});u(a,f.ok?200:400,f);return}const b=await this.tryDirectWeChatRpaReply(s,c,d);if(b){u(a,b.ok?200:400,b);return}let I;try{I=await this.sendManagedWeComReply({managerSessionId:s,text:c,attachment:d,idempotencyKey:l})}catch(f){const N=f instanceof Error?f.message:String(f);if(!B(N))throw f;I={ok:!1,error:N}}if(I.ok){u(a,200,{ok:!0,payload:I.payload});return}if(!B(I.error||"")||!M||!T){u(a,400,{ok:!1,error:I.error||"External send failed"});return}u(a,400,{ok:!1,error:`No local external channel is configured for ${M}`});return}if(n.pathname==="/channel/get"){u(a,200,{ok:!0,channel:this.channelRuntime.getManagerChannel(s,"websocket")});return}if(n.pathname==="/channel/upsert"){if(!o)throw new Error("Manager runtime is not registered");const i=await this.channelRuntime.upsertManagerChannel({id:String(t.id||`websocket:${s}`),managerSessionId:s,workDir:o.workDir,type:"websocket",name:typeof t.name=="string"?t.name:void 0,enabled:!!t.enabled,wsUrl:typeof t.wsUrl=="string"?t.wsUrl:void 0,token:typeof t.token=="string"?t.token:void 0,canReply:t.canReply===void 0?void 0:!!t.canReply,systemPrompt:typeof t.systemPrompt=="string"?t.systemPrompt:void 0});this.registry.upsertManager({...o,status:o.status}),this.broadcastManagerChannelStatus(s),u(a,200,{ok:!0,channel:i});return}if(n.pathname==="/wechat-rpa/tool/read"){const i=_(t),c=p(t.limit)??10,d=typeof t.traceId=="string"?t.traceId:void 0;let l;try{l=await this.weChatAutomationLane.run(`wechat-tool:read:${i.channelId}`,()=>ce(i,{conversation:i.conversationName,workDir:i.workDir,sessionId:i.sessionId,limit:c,recentLimit:c,download:t.download==="never"?"never":"auto",traceId:d,timeoutMs:p(t.timeoutMs)}))}catch(h){u(a,400,{ok:!1,...K(h,d)});return}u(a,200,{ok:!0,messages:l.messages,outDir:l.outDir,helperTracePath:l.helperTracePath,activityGuardPath:l.activityGuardPath});return}if(n.pathname==="/wechat-rpa/tool/send"){const i=_(t),c=String(t.text||""),d=$(t.attachment),l=typeof t.traceId=="string"?t.traceId:void 0;let h;try{h=await this.weChatAutomationLane.run(`wechat-tool:send:${i.channelId}`,()=>P(i,{conversation:i.conversationName,workDir:i.workDir,sessionId:i.sessionId,text:c,attachment:d,traceId:l,timeoutMs:p(t.timeoutMs)}))}catch(g){u(a,400,{ok:!1,...K(g,l)});return}u(a,200,{ok:!0,...h});return}if(n.pathname==="/wechat-rpa/channel/get"){u(a,200,{ok:!0,channel:this.channelRuntime.getManagerChannel(s,"wechat-rpa",{includeSecret:!0})});return}if(n.pathname==="/wechat-rpa/channel/upsert"){const i=S(String(t.workDir||o?.workDir||""));if(!i)throw new Error("workDir is required");const c=await this.channelRuntime.upsertManagerWeChatRpaChannel({id:String(t.id||`wechat-rpa:${s}`),managerSessionId:s,sessionId:s,workDir:i,name:typeof t.name=="string"?t.name:void 0,agentType:typeof t.agentType=="string"?t.agentType:void 0,agentSessionId:typeof t.agentSessionId=="string"?t.agentSessionId:null,modelId:typeof t.modelId=="string"?t.modelId:null,enabled:!!t.enabled,groups:L(t.groups),canReply:t.canReply===void 0?void 0:!!t.canReply,systemPrompt:typeof t.systemPrompt=="string"?t.systemPrompt:void 0,source:F(t.source),pollIntervalMs:p(t.pollIntervalMs),recentLimit:p(t.recentLimit),idleSeconds:p(t.idleSeconds),forceForeground:t.forceForeground===void 0?void 0:!!t.forceForeground,noRestore:t.noRestore===void 0?void 0:!!t.noRestore,downloadAttachments:t.downloadAttachments===void 0?void 0:!!t.downloadAttachments,downloadAttachmentsDir:typeof t.downloadAttachmentsDir=="string"?t.downloadAttachmentsDir:void 0,selfNickname:typeof t.selfNickname=="string"?t.selfNickname:void 0,selfTriggerMarker:typeof t.selfTriggerMarker=="string"?t.selfTriggerMarker:void 0,deferInitialPoll:t.deferInitialPoll===void 0?void 0:!!t.deferInitialPoll,privacyConsentAccepted:t.privacyConsentAccepted===void 0?void 0:!!t.privacyConsentAccepted,flowScriptPath:typeof t.flowScriptPath=="string"?t.flowScriptPath:void 0});o&&this.registry.upsertManager({...o,status:o.status}),this.broadcastManagerChannelStatus(s),u(a,200,{ok:!0,channel:c});return}if(n.pathname==="/wechat-rpa/channel/sync"){const{channel:i,messages:c}=await this.channelRuntime.syncManagerWeChatRpaChannel(s);this.broadcastManagerChannelStatus(s),u(a,200,{ok:!0,channel:i,messages:c});return}if(n.pathname==="/wechat-rpa/outbound/cancel"){const i=await this.channelRuntime.cancelManagerWeChatRpaOutbound({managerSessionId:s,idempotencyKey:typeof t.idempotencyKey=="string"?t.idempotencyKey:null,replyId:typeof t.replyId=="string"?t.replyId:null,reason:typeof t.reason=="string"?t.reason:"user_cancelled"});this.broadcastManagerChannelStatus(s),u(a,200,{ok:!0,...i});return}u(a,404,{ok:!1,error:`Unknown manager IPC path: ${n.pathname}`})}catch(n){u(a,400,{ok:!1,error:n instanceof Error?n.message:String(n)})}}async dispatchChatSend(e,a,n,t,s,o){await this.opts.dispatchReq({type:"req",id:`manager-send-${m()}`,method:"chat.send",params:{sessionId:e,text:t,agentType:a,workDir:n,agentSessionId:s,modelId:o}})}async dispatchChatEnqueue(e,a,n,t,s,o){await this.opts.dispatchReq({type:"req",id:`manager-enqueue-${m()}`,method:"chat.enqueue",params:{sessionId:e,text:t,agentType:a,workDir:n,agentSessionId:s,modelId:o}})}async tryDirectWeChatRpaReply(e,a,n){const t=this.opts.getRuntime().sessions.get(e),s=t?.externalChannel;if(!s||s.type!=="wechat-rpa"||!s.channelId||!s.name)return null;const o=process.env.SHENNIAN_MACHINE_ID||ae().machineId||"";if(s.machineId&&o&&s.machineId!==o)return{ok:!1,error:`WeChat \u7ED1\u5B9A\u5C5E\u4E8E\u5176\u4ED6\u673A\u5668 (${s.machineId})\uFF0C\u8BF7\u5728\u7ED1\u5B9A\u673A\u5668\u4E0A\u53D1\u9001\u3002`};if(!a.trim()&&!n)return{ok:!1,error:"text or attachment is required"};const i=t?.workDir||process.cwd(),c={sessionId:e,channelId:s.channelId,conversationId:ie(s.name),conversationName:s.name,workDir:i};try{return{ok:!0,payload:await this.weChatAutomationLane.run(`wechat-tool:send:${c.channelId}`,()=>P(c,{conversation:c.conversationName,workDir:c.workDir,sessionId:c.sessionId,text:a,attachment:n}))}}catch(d){return{ok:!1,error:d instanceof Error?d.message:String(d)}}}async sendManagedWeComReply(e){const a=re(e.text);if(!a.length&&!e.attachment)return{ok:!1,error:"text or attachment is required"};const n=this.opts.getRuntime().client;if(!n||typeof n.sendReq!="function")return{ok:!1,error:"Relay is not connected"};const t=[];for(const[s,o]of a.entries()){const i=await n.sendReq({type:"req",id:`external-send-${m()}`,method:"external.send",params:{managerSessionId:e.managerSessionId,text:o,idempotencyKey:a.length>1?`${e.idempotencyKey}:${s+1}`:e.idempotencyKey}});if(!i.ok)return{ok:!1,error:i.error||"External send failed"};t.push(i.payload)}if(e.attachment){const s=await n.sendReq({type:"req",id:`external-send-${m()}`,method:"external.send",params:{managerSessionId:e.managerSessionId,attachment:e.attachment,idempotencyKey:a.length?`${e.idempotencyKey}:attachment`:e.idempotencyKey}});if(!s.ok)return{ok:!1,error:s.error||"External send failed"};t.push(s.payload)}return{ok:!0,payload:t.length===1?t[0]:t}}wakeManagerForWorker(e,a,n,t){const s=this.registry.getManager(e);if(!s)return;const o=`\u4F60\u7BA1\u7406\u7684 worker \u5DF2\u7ED3\u675F\u3002
3
3
 
4
4
  Worker: ${a.sessionId}
5
5
  \u72B6\u6001\uFF1A${n}
6
6
  \u6700\u7EC8\u7ED3\u679C\uFF1A
7
7
  ${t||a.summary||"(\u65E0\u53EF\u89C1\u6458\u8981)"}
8
8
 
9
- \u8BF7\u51B3\u5B9A\u4E0B\u4E00\u6B65\uFF1A\u7EE7\u7EED\u7B49\u5F85\u3001\u521B\u5EFA/\u6307\u6D3E worker\u3001\u505C\u6B62 worker\u3001\u8BE2\u95EE\u7528\u6237\uFF0C\u6216\u5411\u7528\u6237\u6C47\u62A5\u3002`;this.interruptAndResumeManager(i,o,n==="final"?"worker.final":`worker.${n}`)}handleExternalMessage(e,a){const n=this.channelRuntime.getChannelById(a.channelId)??this.channelRuntime.getManagerChannel(e,a.channelType),t=this.channelRuntime.getChannelStatusById(a.channelId)??this.channelRuntime.getManagerChannelStatus(e),i=this.registry.getManager(e),o=n?.agentType||(i?"manager":"codex"),s=n?.workDir||i?.workDir||process.cwd(),c=n?.agentSessionId??i?.agentSessionId??null,d=n?.modelId||i?.modelId||"",l=pe(a.attachments,a.channelType),h=fe(a);this.dispatchExternalMessage({sessionId:e,agentType:o,workDir:s,agentSessionId:c,modelId:d,text:h,attachments:l,externalChannel:Ie(t),replyTarget:a.replyTarget})}async dispatchExternalMessage(e){await this.opts.dispatchReq({type:"req",id:`external-enqueue-${p()}`,method:"chat.enqueue",params:{sessionId:e.sessionId,text:e.text,agentType:e.agentType,workDir:e.workDir,agentSessionId:e.agentSessionId,modelId:e.modelId,origin:"external",attachments:e.attachments,externalChannel:e.externalChannel??null,replyTarget:e.replyTarget}})}scanWorkerHealth(){const e=Date.now(),a=this.registry.load();for(const n of Object.values(a.workers)){if(n.status!=="running")continue;const t=e-Date.parse(n.createdAt);if(t<10*6e4)continue;const i=n.healthNotifiedAt?Date.parse(n.healthNotifiedAt):0;if(i&&e-i<10*6e4)continue;const o=a.managers[n.managedBy];if(!o)continue;const s=Math.max(0,Math.floor((e-Date.parse(n.lastActivityAt))/6e4)),c=`Worker ${n.sessionId} \u5DF2\u8FD0\u884C ${Math.floor(t/6e4)} \u5206\u949F\uFF0C\u5C1A\u672A\u7ED3\u675F\u3002
9
+ \u8BF7\u51B3\u5B9A\u4E0B\u4E00\u6B65\uFF1A\u7EE7\u7EED\u7B49\u5F85\u3001\u521B\u5EFA/\u6307\u6D3E worker\u3001\u505C\u6B62 worker\u3001\u8BE2\u95EE\u7528\u6237\uFF0C\u6216\u5411\u7528\u6237\u6C47\u62A5\u3002`;this.interruptAndResumeManager(s,o,n==="final"?"worker.final":`worker.${n}`)}handleExternalMessage(e,a){const n=this.channelRuntime.getChannelById(a.channelId)??this.channelRuntime.getManagerChannel(e,a.channelType),t=this.channelRuntime.getChannelStatusById(a.channelId)??this.channelRuntime.getManagerChannelStatus(e),s=this.registry.getManager(e),o=n?.agentType||(s?"manager":"codex"),i=n?.workDir||s?.workDir||process.cwd(),c=n?.agentSessionId??s?.agentSessionId??null,d=n?.modelId||s?.modelId||"",l=ye(a.attachments,a.channelType),h=Ie(a);this.dispatchExternalMessage({sessionId:e,agentType:o,workDir:i,agentSessionId:c,modelId:d,text:h,attachments:l,externalChannel:Re(t),replyTarget:a.replyTarget})}async dispatchExternalMessage(e){await this.opts.dispatchReq({type:"req",id:`external-enqueue-${m()}`,method:"chat.enqueue",params:{sessionId:e.sessionId,text:e.text,agentType:e.agentType,workDir:e.workDir,agentSessionId:e.agentSessionId,modelId:e.modelId,origin:"external",attachments:e.attachments,externalChannel:e.externalChannel??null,replyTarget:e.replyTarget}})}scanWorkerHealth(){const e=Date.now(),a=this.registry.load();for(const n of Object.values(a.workers)){if(n.status!=="running")continue;const t=e-Date.parse(n.createdAt);if(t<10*6e4)continue;const s=n.healthNotifiedAt?Date.parse(n.healthNotifiedAt):0;if(s&&e-s<10*6e4)continue;const o=a.managers[n.managedBy];if(!o)continue;const i=Math.max(0,Math.floor((e-Date.parse(n.lastActivityAt))/6e4)),c=`Worker ${n.sessionId} \u5DF2\u8FD0\u884C ${Math.floor(t/6e4)} \u5206\u949F\uFF0C\u5C1A\u672A\u7ED3\u675F\u3002
10
10
 
11
11
  \u5F53\u524D\u53EF\u89C1\u8FDB\u5C55\uFF1A
12
12
  - \u6700\u8FD1\u6587\u672C\u6458\u8981\uFF1A${n.summary||"(\u65E0\u53EF\u89C1\u6458\u8981)"}
13
13
  - \u6700\u8FD1\u6D3B\u52A8\u65F6\u95F4\uFF1A${n.lastActivityAt}
14
- - \u6700\u8FD1 ${s} \u5206\u949F\u6CA1\u6709\u65B0\u6D3B\u52A8\u3002
14
+ - \u6700\u8FD1 ${i} \u5206\u949F\u6CA1\u6709\u65B0\u6D3B\u52A8\u3002
15
15
 
16
- \u8BF7\u51B3\u5B9A\u662F\u5426\u7EE7\u7EED\u7B49\u5F85\u3001\u8BE2\u95EE\u7528\u6237\u3001\u505C\u6B62 worker\u3001\u6216\u521B\u5EFA\u5176\u4ED6 worker \u534F\u52A9\u3002`;this.registry.updateWorker(n.sessionId,{healthNotifiedAt:new Date(e).toISOString(),lastHealthSummary:c}),o.status==="idle"&&this.dispatchChatSend(o.sessionId,"manager",o.workDir,c,o.agentSessionId,o.modelId)}}async interruptAndResumeManager(e,a,n){this.opts.getRuntime().sessions.get(e.sessionId)?.currentRunId&&(this.registry.upsertManager({...e,status:"interrupting"}),await this.opts.dispatchReq({type:"req",id:`manager-interrupt-${p()}`,method:"chat.abort",params:{sessionId:e.sessionId}}));const o=n?`\u4E8B\u4EF6\u7C7B\u578B\uFF1A${n}
16
+ \u8BF7\u51B3\u5B9A\u662F\u5426\u7EE7\u7EED\u7B49\u5F85\u3001\u8BE2\u95EE\u7528\u6237\u3001\u505C\u6B62 worker\u3001\u6216\u521B\u5EFA\u5176\u4ED6 worker \u534F\u52A9\u3002`;this.registry.updateWorker(n.sessionId,{healthNotifiedAt:new Date(e).toISOString(),lastHealthSummary:c}),o.status==="idle"&&this.dispatchChatSend(o.sessionId,"manager",o.workDir,c,o.agentSessionId,o.modelId)}}async interruptAndResumeManager(e,a,n){this.opts.getRuntime().sessions.get(e.sessionId)?.currentRunId&&(this.registry.upsertManager({...e,status:"interrupting"}),await this.opts.dispatchReq({type:"req",id:`manager-interrupt-${m()}`,method:"chat.abort",params:{sessionId:e.sessionId}}));const o=n?`\u4E8B\u4EF6\u7C7B\u578B\uFF1A${n}
17
17
 
18
- ${a}`:a;await this.dispatchChatSend(e.sessionId,"manager",e.workDir,o,e.agentSessionId,e.modelId)}bindManagerAdapterEvents(e,a){a.on("agentEvent",n=>{if(n.state==="start"&&n.agentSessionId){const t=this.registry.getManager(e);t&&this.noteManagerAgentSession(e,n.agentSessionId,t.workDir,t.modelId)}n.state==="start"&&this.updateManagerStatus(e,"running"),(n.state==="final"||n.state==="error"||n.state==="aborted")&&this.updateManagerStatus(e,"idle")})}updateManagerStatus(e,a){const n=this.registry.getManager(e);n&&this.registry.upsertManager({...n,status:a})}getExternalChannelStatus(e){return this.channelRuntime.getManagerChannelStatus(e)}getManagerExternalChannelSystemPrompt(e){return this.channelRuntime.listManagerExternalChannels(e).map(a=>re(a,void 0,e,"manager")).join(`
18
+ ${a}`:a;await this.dispatchChatSend(e.sessionId,"manager",e.workDir,o,e.agentSessionId,e.modelId)}bindManagerAdapterEvents(e,a){a.on("agentEvent",n=>{if(n.state==="start"&&n.agentSessionId){const t=this.registry.getManager(e);t&&this.noteManagerAgentSession(e,n.agentSessionId,t.workDir,t.modelId)}n.state==="start"&&this.updateManagerStatus(e,"running"),(n.state==="final"||n.state==="error"||n.state==="aborted")&&this.updateManagerStatus(e,"idle")})}updateManagerStatus(e,a){const n=this.registry.getManager(e);n&&this.registry.upsertManager({...n,status:a})}getExternalChannelStatus(e){return this.channelRuntime.getManagerChannelStatus(e)}getManagerExternalChannelSystemPrompt(e){return this.channelRuntime.listManagerExternalChannels(e).map(a=>oe(a,void 0,e,"manager")).join(`
19
19
 
20
- `).trim()}}function B(r){return Array.isArray(r)?r.map(e=>({name:String(e?.name||"").trim()})).filter(e=>e.name):[]}function q(r){return r==="wechat-channel"||r==="macos-flow"||r==="macos-probe"||r==="windows-visual-flow"||r==="wechat-rpa-lab"||r==="fixture-jsonl"?r:void 0}function pe(r,e){const a=r.map(n=>F(n,e)).filter(n=>n!=null);return a.length?a:void 0}function me(r,e,a,n){const t=e||"",i=new Set;return r.map((s,c)=>{const d=F(s,n),l=Y({type:s.type,name:d?.name||s.name,path:d?.path,mimeType:d?.mimeType||s.mimeType,availability:s.availability,providerError:s.providerError||we(s)},c),h=d?.path||"";if(h){const M=`${l}
21
- ${h}`;return i.has(M)||t.includes(h)?"":(i.add(M),`${a}: ${l}`)}const g=l;return i.has(g)?"":(i.add(g),`${a}: ${l}`)}).filter(s=>!t.includes(s)).join(`
22
- `)}function fe(r){const a=(r.channelType==="wechat-rpa"?ye(r.sender.name):r.sender.name||r.sender.id)||(r.channelType==="wechat-rpa"?"\u5BF9\u65B9":r.sender.id)||"\u5BF9\u65B9",n=me(r.attachments,r.text,a,r.channelType),i=[r.text?J({senderName:a,senderId:r.sender.id,text:r.text}):n?"":`${a}:`,n].filter(Boolean).join(`
23
- `);return[z({conversationName:r.conversationName||r.conversationId,messages:[]}),i].filter(Boolean).join(`
24
- `)}function ye(r){const e=r?.trim()||"";return!e||/^(contact|self|system|unknown)$/i.test(e)||/^wechat-sender:/i.test(e)?"":e}function we(r){return!r.localPath||r.availability&&r.availability!=="edge-local"||b(r.localPath)?"":"edge-local-unavailable"}function F(r,e){return r.localPath&&ke(r,e)&&b(r.localPath)?{path:r.localPath,name:r.name||y.basename(r.localPath)||"attachment",mimeType:r.mimeType||O(r)}:r.url&&Se(r)?{path:r.url,name:r.name||r.url.split("/").filter(Boolean).at(-1)||"attachment",mimeType:r.mimeType||O(r)}:r.thumbnailPath&&!L(r,e)&&b(r.thumbnailPath)?{path:r.thumbnailPath,name:r.name?`${r.name}-preview.png`:y.basename(r.thumbnailPath)||"preview.png",mimeType:"image/png"}:null}function Ie(r){return r?r.type!=="wechat-rpa"?r:{configured:r.configured,connected:r.connected,type:r.type,channelId:r.channelId,name:r.name,canReply:r.canReply,systemPrompt:r.systemPrompt,wechatRpaSource:r.wechatRpaSource,wechatRpaGroups:r.wechatRpaGroups,pollIntervalMs:r.pollIntervalMs,recentLimit:r.recentLimit,idleSeconds:r.idleSeconds,forceForeground:r.forceForeground,noRestore:r.noRestore,downloadAttachments:r.downloadAttachments,selfNickname:r.selfNickname,wechatRpaPrivacyConsentAccepted:r.wechatRpaPrivacyConsentAccepted,wechatRpaServerDecisionAvailable:r.wechatRpaServerDecisionAvailable,wechatRpaPreflightChecks:r.wechatRpaPreflightChecks,wechatRpaRuntimeState:r.wechatRpaRuntimeState,wechatRpaLastMessageAt:r.wechatRpaLastMessageAt,wechatRpaPendingReplyCount:r.wechatRpaPendingReplyCount,wechatRpaLastError:r.wechatRpaLastError}:null}function ke(r,e){return r.providerError||r.availability&&r.availability!=="edge-local"?!1:L(r,e)?r.materializationKind==="original-file"&&r.isOriginal===!0&&r.mimeKindMatches===!0&&!Me(r.localPath):!0}function Se(r){return!r.providerError&&(!r.availability||r.availability==="server-url")}function L(r,e){if(e!=="wechat-rpa")return!1;const a=String(r.type||"").toLowerCase();return a==="file"||a==="video"||a==="video-file"}function Me(r){const e=String(r||"").replace(/\\/g,"/"),a=y.basename(e).toLowerCase();return/(^|\/)\.uploads(\/|$)/.test(e)||/(^|-)preview([-.]|$)/i.test(a)}function b(r){try{return k.statSync(r).isFile()}catch{return!1}}function O(r){return r.type==="image"?"image/*":r.type==="video"?"video/*":r.type==="audio"?"audio/*":"application/octet-stream"}function m(r){const e=Number(r);return Number.isFinite(e)?e:void 0}function U(r,e){const a=T(r,"reasonCode")||Re(r),n=T(r,"outDir"),t=T(r,"helperTracePath"),i=T(r,"activityGuardPath");return{error:r instanceof Error?r.message:String(r||a),reasonCode:a,...n?{outDir:n}:{},...t?{helperTracePath:t}:{},...i?{activityGuardPath:i}:{},...e?{traceId:e}:{}}}function T(r,e){if(!r||typeof r!="object")return"";const a=r[e];return typeof a=="string"&&a.trim()?a.trim():""}function Re(r){const e=r instanceof Error?r.message:String(r||"");return/^([a-z][a-z0-9_]*)(?::|\b)/i.exec(e.trim())?.[1]||"wechat_tool_failed"}export{Le as ManagerRuntimeService,Fe as getManagerRuntimeService,qe as setManagerRuntimeService};
20
+ `).trim()}}function L(r){return Array.isArray(r)?r.map(e=>({name:String(e?.name||"").trim()})).filter(e=>e.name):[]}function F(r){return r==="wechat-channel"||r==="macos-flow"||r==="macos-probe"||r==="windows-visual-flow"||r==="wechat-rpa-lab"||r==="fixture-jsonl"?r:void 0}function ye(r,e){const a=r.map(n=>O(n,e)).filter(n=>n!=null);return a.length?a:void 0}function we(r,e,a,n){const t=e||"",s=new Set;return r.map((i,c)=>{const d=O(i,n),l=Q({type:i.type,name:d?.name||i.name,path:d?.path,mimeType:d?.mimeType||i.mimeType,availability:i.availability,providerError:i.providerError||Se(i)},c),h=d?.path||"";if(h){const R=`${l}
21
+ ${h}`;return s.has(R)||t.includes(h)?"":(s.add(R),`${a}: ${l}`)}const g=l;return s.has(g)?"":(s.add(g),`${a}: ${l}`)}).filter(i=>!t.includes(i)).join(`
22
+ `)}function Ie(r){const a=(r.channelType==="wechat-rpa"?ke(r.sender.name):r.sender.name||r.sender.id)||(r.channelType==="wechat-rpa"?"\u5BF9\u65B9":r.sender.id)||"\u5BF9\u65B9",n=we(r.attachments,r.text,a,r.channelType),s=[r.text?V({senderName:a,senderId:r.sender.id,text:r.text}):n?"":`${a}:`,n].filter(Boolean).join(`
23
+ `);return[Y({conversationName:r.conversationName||r.conversationId,messages:[]}),s].filter(Boolean).join(`
24
+ `)}function ke(r){const e=r?.trim()||"";return!e||/^(contact|self|system|unknown)$/i.test(e)||/^wechat-sender:/i.test(e)?"":e}function Se(r){return!r.localPath||r.availability&&r.availability!=="edge-local"||x(r.localPath)?"":"edge-local-unavailable"}function O(r,e){return r.localPath&&Me(r,e)&&x(r.localPath)?{path:r.localPath,name:r.name||y.basename(r.localPath)||"attachment",mimeType:r.mimeType||H(r)}:r.url&&Ce(r)?{path:r.url,name:r.name||r.url.split("/").filter(Boolean).at(-1)||"attachment",mimeType:r.mimeType||H(r)}:r.thumbnailPath&&!U(r,e)&&x(r.thumbnailPath)?{path:r.thumbnailPath,name:r.name?`${r.name}-preview.png`:y.basename(r.thumbnailPath)||"preview.png",mimeType:"image/png"}:null}function Re(r){return r?r.type!=="wechat-rpa"?r:{configured:r.configured,connected:r.connected,type:r.type,channelId:r.channelId,name:r.name,canReply:r.canReply,systemPrompt:r.systemPrompt,wechatRpaSource:r.wechatRpaSource,wechatRpaGroups:r.wechatRpaGroups,pollIntervalMs:r.pollIntervalMs,recentLimit:r.recentLimit,idleSeconds:r.idleSeconds,forceForeground:r.forceForeground,noRestore:r.noRestore,downloadAttachments:r.downloadAttachments,selfNickname:r.selfNickname,wechatRpaPrivacyConsentAccepted:r.wechatRpaPrivacyConsentAccepted,wechatRpaServerDecisionAvailable:r.wechatRpaServerDecisionAvailable,wechatRpaPreflightChecks:r.wechatRpaPreflightChecks,wechatRpaRuntimeState:r.wechatRpaRuntimeState,wechatRpaLastMessageAt:r.wechatRpaLastMessageAt,wechatRpaPendingReplyCount:r.wechatRpaPendingReplyCount,wechatRpaLastError:r.wechatRpaLastError}:null}function Me(r,e){return r.providerError||r.availability&&r.availability!=="edge-local"?!1:U(r,e)?r.materializationKind==="original-file"&&r.isOriginal===!0&&r.mimeKindMatches===!0&&!Ae(r.localPath):!0}function Ce(r){return!r.providerError&&(!r.availability||r.availability==="server-url")}function U(r,e){if(e!=="wechat-rpa")return!1;const a=String(r.type||"").toLowerCase();return a==="file"||a==="video"||a==="video-file"}function Ae(r){const e=String(r||"").replace(/\\/g,"/"),a=y.basename(e).toLowerCase();return/(^|\/)\.uploads(\/|$)/.test(e)||/(^|-)preview([-.]|$)/i.test(a)}function x(r){try{return k.statSync(r).isFile()}catch{return!1}}function H(r){return r.type==="image"?"image/*":r.type==="video"?"video/*":r.type==="audio"?"audio/*":"application/octet-stream"}function p(r){const e=Number(r);return Number.isFinite(e)?e:void 0}function K(r,e){const a=E(r,"reasonCode")||Ee(r),n=E(r,"outDir"),t=E(r,"helperTracePath"),s=E(r,"activityGuardPath");return{error:r instanceof Error?r.message:String(r||a),reasonCode:a,...n?{outDir:n}:{},...t?{helperTracePath:t}:{},...s?{activityGuardPath:s}:{},...e?{traceId:e}:{}}}function E(r,e){if(!r||typeof r!="object")return"";const a=r[e];return typeof a=="string"&&a.trim()?a.trim():""}function Ee(r){const e=r instanceof Error?r.message:String(r||"");return/^([a-z][a-z0-9_]*)(?::|\b)/i.exec(e.trim())?.[1]||"wechat_tool_failed"}export{Ke as ManagerRuntimeService,He as getManagerRuntimeService,Ue as setManagerRuntimeService};
@@ -65,6 +65,7 @@ export type ExternalChannelSessionStatus = {
65
65
  connected: boolean;
66
66
  type?: string | null;
67
67
  channelId?: string | null;
68
+ machineId?: string | null;
68
69
  name?: string | null;
69
70
  canReply?: boolean | null;
70
71
  systemPrompt?: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAElE,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,IAAI,GAAG,SAAS,CAAA;AACpH,MAAM,MAAM,eAAe,GAAG,UAAU,MAAM,EAAE,CAAA;AAChD,MAAM,MAAM,SAAS,GAAG,gBAAgB,GAAG,eAAe,CAAA;AAE1D,eAAO,MAAM,4BAA4B,uBAA8D,CAAA;AACvG,eAAO,MAAM,6BAA6B,+EAAsH,CAAA;AAIhK,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,yBAAyB,CAAC,EAAE,KAAK,CAAC;QAChC,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAC,CAAA;IACF,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAA;AAE5E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,6EAA6E;IAC7E,MAAM,EAAE,iBAAiB,CAAA;IACzB,mDAAmD;IACnD,MAAM,CAAC,EAAE,KAAK,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAA;IACpE,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,wEAAwE;IACxE,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAC5B,CAAA;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,gBAAgB,CAEpF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,SAAS,CAEtE;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,CAWhF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,CAapF;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,cAAc,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,oBAAoB,CAAA;AAExH,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,eAAe,CAAA;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,qFAAqF;IACrF,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,4BAA4B,GAAG;IACzC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAA;IAChD,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,eAAe,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAChC,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAC1B,mBAAmB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACpC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,qBAAqB,CAAC,EAAE,cAAc,GAAG,SAAS,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,IAAI,CAAA;IACnG,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1C,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1C,uBAAuB,CAAC,EAAE,+BAA+B,EAAE,GAAG,IAAI,CAAA;IAClE,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,yBAAyB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,4BAA4B,CAAC,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAA;IAC5D,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,4BAA4B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5C,8BAA8B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9C,8BAA8B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9C,0BAA0B,CAAC,EAAE;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,GAAG,IAAI,CAAA;IACR,wBAAwB,CAAC,EAAE,uBAAuB,EAAE,GAAG,IAAI,CAAA;IAC3D,gCAAgC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACjD,+BAA+B,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CACjD,CAAA;AAED,MAAM,MAAM,+BAA+B,GAAG;IAC5C,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,kBAAkB,GAAG,MAAM,CAAA;IAC1D,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,GAAG,UAAU,CAAA;IAClE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAC9B,IAAI,GACJ,UAAU,GACV,sBAAsB,GACtB,qBAAqB,GACrB,0BAA0B,GAC1B,6BAA6B,GAC7B,uBAAuB,GACvB,yBAAyB,GACzB,kBAAkB,GAClB,qCAAqC,GACrC,kCAAkC,GAClC,+BAA+B,GAC/B,oBAAoB,GACpB,2BAA2B,GAC3B,4BAA4B,GAC5B,wBAAwB,GACxB,oCAAoC,GACpC,yBAAyB,GACzB,qBAAqB,GACrB,eAAe,GACf,SAAS,CAAA;AAEb,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,sBAAsB,CAAA;IAC5B,EAAE,EAAE,OAAO,CAAA;IACX,QAAQ,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,UAAU,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAA;IAC3C,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,6BAA6B,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IAChD,2BAA2B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAA;IACzC,OAAO,EAAE,MAAM,CAAA;IACf,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACnC,QAAQ,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAA;IACzC,eAAe,CAAC,EAAE,4BAA4B,GAAG,IAAI,CAAA;CACtD,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,WAAW,EACT,IAAI,GACJ,WAAW,GACX,QAAQ,GACR,WAAW,GACX,gBAAgB,GAChB,SAAS,GACT,+BAA+B,GAC/B,6BAA6B,GAC7B,OAAO,GACP,QAAQ,GACR,SAAS,GACT,oBAAoB,GACpB,gBAAgB,GAChB,WAAW,GACX,WAAW,GACX,WAAW,GACX,aAAa,GACb,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,WAAW,GACX,sBAAsB,GACtB,UAAU,GACV,iBAAiB,CACpB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6BAA6B,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IAChD,2BAA2B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3C,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,qBAAqB,CAAC,EAAE,qBAAqB,EAAE,CAAA;IAC/C,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3F,eAAe,CAAC,EAAE,4BAA4B,GAAG,IAAI,CAAA;IACrD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3F,eAAe,CAAC,EAAE,4BAA4B,GAAG,IAAI,CAAA;IACrD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,iBAAiB,EAAE,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,KAAK,GAAG,UAAU,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC5F,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAC5D,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.2.117",
3
+ "version": "0.2.119",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {