shennian 0.2.126 → 0.2.127
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/publish-build-manifest.json +8 -8
- package/dist/src/agents/pi-context.d.ts +1 -1
- package/dist/src/agents/pi-context.js +7 -7
- package/dist/src/agents/pi.js +13 -10
- package/dist/src/channels/wechat-channel/observer.js +6 -6
- package/dist/src/channels/wechat-channel/runner.d.ts +1 -0
- package/dist/src/channels/wechat-channel/runner.js +1 -1
- package/package.json +1 -1
|
@@ -126,13 +126,13 @@
|
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
"file": "src/agents/pi-context.js",
|
|
129
|
-
"beforeBytes":
|
|
130
|
-
"afterBytes":
|
|
129
|
+
"beforeBytes": 8247,
|
|
130
|
+
"afterBytes": 4981
|
|
131
131
|
},
|
|
132
132
|
{
|
|
133
133
|
"file": "src/agents/pi.js",
|
|
134
|
-
"beforeBytes":
|
|
135
|
-
"afterBytes":
|
|
134
|
+
"beforeBytes": 31585,
|
|
135
|
+
"afterBytes": 14905
|
|
136
136
|
},
|
|
137
137
|
{
|
|
138
138
|
"file": "src/agents/platform-instructions.js",
|
|
@@ -261,8 +261,8 @@
|
|
|
261
261
|
},
|
|
262
262
|
{
|
|
263
263
|
"file": "src/channels/wechat-channel/observer.js",
|
|
264
|
-
"beforeBytes":
|
|
265
|
-
"afterBytes":
|
|
264
|
+
"beforeBytes": 109318,
|
|
265
|
+
"afterBytes": 49637
|
|
266
266
|
},
|
|
267
267
|
{
|
|
268
268
|
"file": "src/channels/wechat-channel/outbound-ledger.js",
|
|
@@ -286,8 +286,8 @@
|
|
|
286
286
|
},
|
|
287
287
|
{
|
|
288
288
|
"file": "src/channels/wechat-channel/runner.js",
|
|
289
|
-
"beforeBytes":
|
|
290
|
-
"afterBytes":
|
|
289
|
+
"beforeBytes": 16883,
|
|
290
|
+
"afterBytes": 8066
|
|
291
291
|
},
|
|
292
292
|
{
|
|
293
293
|
"file": "src/channels/wechat-channel/runtime.js",
|
|
@@ -8,7 +8,7 @@ type ShellCommandSpec = {
|
|
|
8
8
|
};
|
|
9
9
|
export declare function buildShellCommandSpec(command: string, platform?: NodeJS.Platform): ShellCommandSpec;
|
|
10
10
|
export declare function createPiModel(modelId?: string, overrides?: Partial<Pick<Model<'openai-completions'>, 'baseUrl' | 'provider' | 'compat'>>): Model<'openai-completions'>;
|
|
11
|
-
export declare const SYSTEM_PROMPT = "\u4F60\u662F\u795E\u5FF5\u5185\u7F6E\u7F16\u7A0B\u52A9\u624B\uFF0C\u8FD0\u884C\u5728\u7528\u6237\u672C\u5730\u673A\u5668\u4E0A\u3002\n\u4F60\u53EF\u4EE5\u8BFB\u5199\u6587\u4EF6\u3001\u6267\u884C shell \u547D\u4EE4\u3001\u5E2E\u52A9\u7528\u6237\u5B8C\u6210\u7F16\u7A0B\u548C\u7CFB\u7EDF\u7BA1\u7406\u4EFB\u52A1\u3002\n\u5DE5\u4F5C\u76EE\u5F55\u5DF2\u8BBE\u7F6E\uFF0C\u64CD\u4F5C\u6587\u4EF6\u65F6\u4F7F\u7528\u76F8\u5BF9\u8DEF\u5F84\u6216\u7EDD\u5BF9\u8DEF\u5F84\u5747\u53EF\u3002\n\u5F53\u524D shell \u4F1A\u968F\u64CD\u4F5C\u7CFB\u7EDF\u9009\u62E9\uFF1AWindows \u4F7F\u7528 PowerShell\uFF0CmacOS/Linux \u4F7F\u7528 bash\u3002Windows \u4E0B\u9700\u8981\u771F\u5B9E curl \u65F6\u4F7F\u7528 curl.exe\uFF0C\u907F\u514D PowerShell \u7684 curl \u522B\u540D\u3002\n\u4FDD\u6301\u56DE\u590D\u7B80\u6D01\u3001\u51C6\u786E\uFF0C\u4E2D\u6587\u56DE\u590D\u3002";
|
|
11
|
+
export declare const SYSTEM_PROMPT = "\u4F60\u662F\u795E\u5FF5\u5185\u7F6E\u7F16\u7A0B\u52A9\u624B\uFF0C\u8FD0\u884C\u5728\u7528\u6237\u672C\u5730\u673A\u5668\u4E0A\u3002\n\u4F60\u53EF\u4EE5\u8BFB\u5199\u6587\u4EF6\u3001\u6267\u884C shell \u547D\u4EE4\u3001\u5E2E\u52A9\u7528\u6237\u5B8C\u6210\u7F16\u7A0B\u548C\u7CFB\u7EDF\u7BA1\u7406\u4EFB\u52A1\u3002\n\u5DE5\u4F5C\u76EE\u5F55\u5DF2\u8BBE\u7F6E\uFF0C\u64CD\u4F5C\u6587\u4EF6\u65F6\u4F7F\u7528\u76F8\u5BF9\u8DEF\u5F84\u6216\u7EDD\u5BF9\u8DEF\u5F84\u5747\u53EF\u3002\n\u5F53\u524D shell \u4F1A\u968F\u64CD\u4F5C\u7CFB\u7EDF\u9009\u62E9\uFF1AWindows \u4F7F\u7528 PowerShell\uFF0CmacOS/Linux \u4F7F\u7528 bash\u3002Windows \u4E0B\u9700\u8981\u771F\u5B9E curl \u65F6\u4F7F\u7528 curl.exe\uFF0C\u67E5\u627E\u547D\u4EE4\u4F4D\u7F6E\u4F7F\u7528 where.exe\uFF0C\u907F\u514D PowerShell \u7684 curl / where \u522B\u540D\u3002\n\u4FDD\u6301\u56DE\u590D\u7B80\u6D01\u3001\u51C6\u786E\uFF0C\u4E2D\u6587\u56DE\u590D\u3002";
|
|
12
12
|
export declare function findAgentsMd(startDir: string): string | null;
|
|
13
13
|
export declare function loadAgentsMdInstructions(workDir: string): string | null;
|
|
14
14
|
export declare const CONTEXT_TOKEN_THRESHOLD = 90000;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import a from"node:fs";import l from"node:path";import{resolveShennianPath as x}from"../config/index.js";import{resolveWindowsPowerShellPath as S}from"../windows-shell.js";const d="qwen3.6-plus";function b(e,t=process.platform){return t==="win32"?{file:S(),args:["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command",e],shell:"powershell"}:{file:a.existsSync("/bin/bash")?"/bin/bash":"bash",args:["-c",e],shell:"bash"}}function E(e=d,t={}){return{id:e,name:e,api:"openai-completions",provider:t.provider??"shennian-proxy",baseUrl:t.baseUrl??"",reasoning:!1,input:["text","image"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:128e3,maxTokens:8192,...t.compat?{compat:t.compat}:{}}}const P=`\u4F60\u662F\u795E\u5FF5\u5185\u7F6E\u7F16\u7A0B\u52A9\u624B\uFF0C\u8FD0\u884C\u5728\u7528\u6237\u672C\u5730\u673A\u5668\u4E0A\u3002
|
|
2
2
|
\u4F60\u53EF\u4EE5\u8BFB\u5199\u6587\u4EF6\u3001\u6267\u884C shell \u547D\u4EE4\u3001\u5E2E\u52A9\u7528\u6237\u5B8C\u6210\u7F16\u7A0B\u548C\u7CFB\u7EDF\u7BA1\u7406\u4EFB\u52A1\u3002
|
|
3
3
|
\u5DE5\u4F5C\u76EE\u5F55\u5DF2\u8BBE\u7F6E\uFF0C\u64CD\u4F5C\u6587\u4EF6\u65F6\u4F7F\u7528\u76F8\u5BF9\u8DEF\u5F84\u6216\u7EDD\u5BF9\u8DEF\u5F84\u5747\u53EF\u3002
|
|
4
|
-
\u5F53\u524D shell \u4F1A\u968F\u64CD\u4F5C\u7CFB\u7EDF\u9009\u62E9\uFF1AWindows \u4F7F\u7528 PowerShell\uFF0CmacOS/Linux \u4F7F\u7528 bash\u3002Windows \u4E0B\u9700\u8981\u771F\u5B9E curl \u65F6\u4F7F\u7528 curl.exe\uFF0C\u907F\u514D PowerShell \u7684 curl \u522B\u540D\u3002
|
|
5
|
-
\u4FDD\u6301\u56DE\u590D\u7B80\u6D01\u3001\u51C6\u786E\uFF0C\u4E2D\u6587\u56DE\u590D\u3002`,
|
|
4
|
+
\u5F53\u524D shell \u4F1A\u968F\u64CD\u4F5C\u7CFB\u7EDF\u9009\u62E9\uFF1AWindows \u4F7F\u7528 PowerShell\uFF0CmacOS/Linux \u4F7F\u7528 bash\u3002Windows \u4E0B\u9700\u8981\u771F\u5B9E curl \u65F6\u4F7F\u7528 curl.exe\uFF0C\u67E5\u627E\u547D\u4EE4\u4F4D\u7F6E\u4F7F\u7528 where.exe\uFF0C\u907F\u514D PowerShell \u7684 curl / where \u522B\u540D\u3002
|
|
5
|
+
\u4FDD\u6301\u56DE\u590D\u7B80\u6D01\u3001\u51C6\u786E\uFF0C\u4E2D\u6587\u56DE\u590D\u3002`,y=24e3;function N(e){let t=l.resolve(e||process.cwd());try{const n=a.existsSync(t)?a.statSync(t):null;n&&!n.isDirectory()&&(t=l.dirname(t))}catch{}for(;;){const n=l.join(t,"AGENTS.md");if(a.existsSync(n))return n;const o=l.dirname(t);if(o===t)return null;t=o}}function $(e){const t=N(e);if(!t)return null;try{const n=a.readFileSync(t,"utf-8").trim();if(!n)return null;const o=n.length>y?`${n.slice(0,y)}
|
|
6
6
|
|
|
7
7
|
...\uFF08AGENTS.md \u5DF2\u622A\u65AD\uFF09`:n;return`# AGENTS.md instructions for ${l.dirname(t)}
|
|
8
8
|
|
|
9
|
-
${o}`}catch{return null}}const k=9e4,C=6,A=
|
|
10
|
-
`)}function G(e){return JSON.parse(JSON.stringify(e))}function F(e){return l.join(A,e)}function T(e){if(!e||typeof e!="object")return null;const t=e;if(t.type==="text"&&typeof t.text=="string")return t.text;if(t.type==="thinking"&&typeof t.thinking=="string")return`[thinking] ${t.thinking}`;if(t.type==="toolCall"){const n=typeof t.name=="string"?t.name:typeof t.toolName=="string"?t.toolName:"tool",o=t.arguments??t.args??{};return`[toolCall] ${n}(${JSON.stringify(o).slice(0,300)})`}return t.type==="image"&&typeof t.mimeType=="string"?`[image] ${t.mimeType}`:null}function W(e,t){const n=[];for(const r of t){const c=String(r.role??"unknown"),i=Array.isArray(r.content)?r.content:[];for(const p of i){const
|
|
11
|
-
`).trim()||e?.trim()||null;return s?s.length>2e3?s.slice(s.length-2e3):s:null}function v(e,t){const n=Math.min(e.length,t.length);for(let o=0;o<n;o++)if(JSON.stringify(e[o])!==JSON.stringify(t[o]))return o;return n}async function U(e,t,n){const o=await fetch(`${e}/api/stream`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:E("qwen-plus"),context:{messages:[{role:"user",content:[{type:"text",text:n}]}]},options:{temperature:.3,maxTokens:500}})});if(!o.ok||!o.body)return null;const s=o.body.getReader(),r=new TextDecoder,c=[];let i="";for(;;){const{done:p,value:
|
|
12
|
-
`);i=m.pop()??"";for(const g of m){if(!g.startsWith("data: "))continue;const
|
|
9
|
+
${o}`}catch{return null}}const k=9e4,C=6,A=x("sessions"),L="summary.json",j="snapshot.json",R="messages.jsonl",D="pi-context.json";function I(e){let t=0;for(const n of e)t+=JSON.stringify(n).length;return Math.ceil(t/3)}function J(e){const t=[];for(const n of e){const o=n,s=String(o.role??"unknown");if(Array.isArray(o.content)){for(const r of o.content)if(r.type==="text"&&typeof r.text=="string")t.push(`[${s}] ${r.text.slice(0,500)}`);else if(r.type==="toolCall"){const c=typeof r.name=="string"?r.name:typeof r.toolName=="string"?r.toolName:"tool",i=r.arguments??r.args??{};t.push(`[${s}] tool:${c}(${JSON.stringify(i).slice(0,200)})`)}}}return t.join(`
|
|
10
|
+
`)}function G(e){return JSON.parse(JSON.stringify(e))}function F(e){return l.join(A,e)}function T(e){if(!e||typeof e!="object")return null;const t=e;if(t.type==="text"&&typeof t.text=="string")return t.text;if(t.type==="thinking"&&typeof t.thinking=="string")return`[thinking] ${t.thinking}`;if(t.type==="toolCall"){const n=typeof t.name=="string"?t.name:typeof t.toolName=="string"?t.toolName:"tool",o=t.arguments??t.args??{};return`[toolCall] ${n}(${JSON.stringify(o).slice(0,300)})`}return t.type==="image"&&typeof t.mimeType=="string"?`[image] ${t.mimeType}`:null}function W(e,t){const n=[];for(const r of t){const c=String(r.role??"unknown"),i=Array.isArray(r.content)?r.content:[];for(const p of i){const u=T(p);u&&n.push(`[${c}] ${u}`)}}const s=n.slice(-8).join(`
|
|
11
|
+
`).trim()||e?.trim()||null;return s?s.length>2e3?s.slice(s.length-2e3):s:null}function v(e,t){const n=Math.min(e.length,t.length);for(let o=0;o<n;o++)if(JSON.stringify(e[o])!==JSON.stringify(t[o]))return o;return n}async function U(e,t,n){const o=await fetch(`${e}/api/stream`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:E("qwen-plus"),context:{messages:[{role:"user",content:[{type:"text",text:n}]}]},options:{temperature:.3,maxTokens:500}})});if(!o.ok||!o.body)return null;const s=o.body.getReader(),r=new TextDecoder,c=[];let i="";for(;;){const{done:p,value:u}=await s.read();if(p)break;i+=r.decode(u,{stream:!0});const m=i.split(`
|
|
12
|
+
`);i=m.pop()??"";for(const g of m){if(!g.startsWith("data: "))continue;const h=g.slice(6).trim();if(!h)continue;const f=JSON.parse(h);f.type==="text_delta"&&typeof f.delta=="string"&&c.push(f.delta)}}return c.join("").trim()||null}export{k as CONTEXT_TOKEN_THRESHOLD,C as KEEP_RECENT_MESSAGES,D as LEGACY_SUMMARY_FILENAME,R as MESSAGES_FILENAME,d as PI_DEFAULT_MODEL_ID,j as SNAPSHOT_FILENAME,L as SUMMARY_FILENAME,P as SYSTEM_PROMPT,W as buildRollingSummary,b as buildShellCommandSpec,G as cloneMessages,E as createPiModel,I as estimateTokens,N as findAgentsMd,F as getSessionDir,$ as loadAgentsMdInstructions,v as longestCommonPrefixLength,J as messagesToText,U as requestProxySummary};
|
package/dist/src/agents/pi.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import{randomUUID as
|
|
2
|
-
|
|
1
|
+
import{randomUUID as b}from"node:crypto";import l from"node:fs";import g from"node:path";import{execFile as _}from"node:child_process";import{promisify as A}from"node:util";import{Agent as T,streamProxy as I}from"@mariozechner/pi-agent-core";import{streamOpenAICompletions as j}from"@mariozechner/pi-ai/openai-completions";import{Type as p}from"@sinclair/typebox";import{AgentAdapter as D,registerAgent as $}from"./adapter.js";import{buildExternalChannelInstructions as F}from"./external-channel-instructions.js";import{loadConfig as L}from"../config/index.js";import{getManagedAgentProviderConfig as O}from"./config-status.js";import{SERVERS as N}from"../region.js";import{buildAgentProcessEnv as q}from"../agent-env.js";import{buildRollingSummary as E,buildShellCommandSpec as P,cloneMessages as S,CONTEXT_TOKEN_THRESHOLD as v,createPiModel as M,estimateTokens as w,getSessionDir as z,KEEP_RECENT_MESSAGES as k,LEGACY_SUMMARY_FILENAME as R,loadAgentsMdInstructions as U,longestCommonPrefixLength as B,MESSAGES_FILENAME as K,messagesToText as G,PI_DEFAULT_MODEL_ID as J,requestProxySummary as H,SNAPSHOT_FILENAME as Y,SYSTEM_PROMPT as W,SUMMARY_FILENAME as V}from"./pi-context.js";import{buildShellCommandSpec as Mt}from"./pi-context.js";const X=A(_),Q="https://dashscope.aliyuncs.com/compatible-mode/v1";function y(o,t){return g.resolve(o,t)}async function Z(o,t,e,s){const n=P(t),{stdout:i,stderr:a}=await X(n.file,n.args,{cwd:o,env:q(e),timeout:3e4,signal:s,maxBuffer:1024*1024,windowsHide:!0});return{stdout:i,stderr:a,shell:n.shell}}function C(o){return typeof o=="string"?o:Buffer.isBuffer(o)?o.toString("utf8"):""}function tt(o){if(!o||typeof o!="object")return String(o);const t=o,e=[t.message||String(o)],s=C(t.stdout).trim(),n=C(t.stderr).trim();return s&&e.push(`---stdout---
|
|
2
|
+
${s}`),n&&e.push(`---stderr---
|
|
3
|
+
${n}`),t.code!==void 0&&e.push(`exitCode: ${String(t.code)}`),t.signal&&e.push(`signal: ${t.signal}`),e.join(`
|
|
4
|
+
`)}function et(o,t={}){return[{name:"read_file",label:"\u8BFB\u53D6\u6587\u4EF6",description:"Read the full content of a file at the given path.",parameters:p.Object({path:p.String({description:"Absolute or relative file path"})}),async execute(e,{path:s}){let n="";try{return n=y(o,s),{content:[{type:"text",text:l.readFileSync(n,"utf-8")}],details:{path:n}}}catch(i){return{content:[{type:"text",text:`Error: ${i instanceof Error?i.message:String(i)}`}],details:{path:n}}}}},{name:"write_file",label:"\u5199\u5165\u6587\u4EF6",description:"Write content to a file, creating it or overwriting if it exists.",parameters:p.Object({path:p.String({description:"Absolute or relative file path"}),content:p.String({description:"File content to write"})}),async execute(e,{path:s,content:n}){let i="";try{return i=y(o,s),l.mkdirSync(g.dirname(i),{recursive:!0}),l.writeFileSync(i,n,"utf-8"),{content:[{type:"text",text:`Written ${n.length} bytes to ${i}`}],details:{path:i}}}catch(a){return{content:[{type:"text",text:`Error: ${a instanceof Error?a.message:String(a)}`}],details:{path:i}}}}},{name:"list_directory",label:"\u5217\u51FA\u76EE\u5F55",description:"List files and directories at the given path.",parameters:p.Object({path:p.String({description:"Directory path to list",default:"."})}),async execute(e,{path:s}){let n="";try{return n=y(o,s),{content:[{type:"text",text:l.readdirSync(n,{withFileTypes:!0}).map(h=>`${h.isDirectory()?"d":"f"} ${h.name}`).join(`
|
|
5
|
+
`)||"(empty)"}],details:{path:n}}}catch(i){return{content:[{type:"text",text:`Error: ${i instanceof Error?i.message:String(i)}`}],details:{path:n}}}}},{name:"bash",label:"\u6267\u884C\u547D\u4EE4",description:"Execute a shell command in the working directory. Uses PowerShell on Windows and bash on macOS/Linux. Timeout: 30s.",parameters:p.Object({command:p.String({description:"Shell command to execute"})}),async execute(e,{command:s},n){try{const{stdout:i,stderr:a,shell:h}=await Z(o,s,t,n);return{content:[{type:"text",text:[i,a].filter(Boolean).join(`
|
|
3
6
|
---stderr---
|
|
4
|
-
`)||"(no output)"}],details:{command:
|
|
7
|
+
`)||"(no output)"}],details:{command:s,shell:h}}}catch(i){return{content:[{type:"text",text:`Error: ${tt(i)}`}],details:{command:s,shell:P(s).shell}}}}},{name:"read_image",label:"\u8BFB\u53D6\u56FE\u7247",description:"Read an image file and return its content for visual analysis. Supports png, jpg, jpeg, gif, webp. Max 10 MB.",parameters:p.Object({path:p.String({description:"Absolute or relative path to the image file"})}),async execute(e,{path:s}){let n;try{n=y(o,s)}catch(r){return{content:[{type:"text",text:`Error: ${r instanceof Error?r.message:String(r)}`}],details:{path:s}}}const i=g.extname(n).toLowerCase().slice(1),h={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp"}[i];if(!h)return{content:[{type:"text",text:`Error: unsupported image type ".${i}". Supported: png, jpg, jpeg, gif, webp`}],details:{path:n}};try{const r=l.statSync(n);return r.size>10*1024*1024?{content:[{type:"text",text:`Error: image too large (${(r.size/1024/1024).toFixed(1)} MB, max 10 MB)`}],details:{path:n}}:{content:[{type:"image",data:l.readFileSync(n).toString("base64"),mimeType:h}],details:{path:n,mimeType:h,size:r.size}}}catch(r){return{content:[{type:"text",text:`Error: ${r instanceof Error?r.message:String(r)}`}],details:{path:n}}}}}]}class st extends D{type="pi";agent=null;sessionId=null;workDir=null;seq=0;runId="";emittedLengths=new Map;terminalState="open";authToken=null;proxyUrl=null;providerConfig;sessionDir=null;messagesPath=null;snapshotPath=null;summaryPath=null;cachedSummary=null;restoredMessages=[];compressing=!1;lastSummaryMsgCount=0;pendingBaseMessages=[];finalizePromise=Promise.resolve();sendGeneration=0;externalChannel=null;shennianSessionId=null;extraEnv={};pendingSendStart=null;configure(t){this.shennianSessionId=t.sessionId??null,this.externalChannel=t.externalChannel??null,this.extraEnv=t.env??{}}async start(t,e,s){this.sessionId=t,this.workDir=e,this.seq=0,this.sessionDir=z(t),this.messagesPath=g.join(this.sessionDir,K),this.snapshotPath=g.join(this.sessionDir,Y),this.summaryPath=g.join(this.sessionDir,V),this.loadSnapshot(),this.loadSummary()}async send(t,e){const s=++this.sendGeneration,n=this.agent&&this.terminalState==="open"?S(this.pendingBaseMessages):null;n&&(this.agent?.abort(),this.agent=null,this.restoredMessages=n,this.finalizePromise=Promise.resolve());const i=L(),a=i.machineToken??i.accessToken;if(!a){this.emit("agentEvent",{state:"error",runId:this.runId,seq:++this.seq,message:"\u672A\u914D\u5BF9\uFF0C\u8BF7\u5148\u8FD0\u884C shennian \u5B8C\u6210\u673A\u5668\u914D\u5BF9"});return}this.authToken=a,this.proxyUrl=(i.serverUrl??N.cn.url).replace(/\/$/,"");const h=O("pi"),r=i.apiKeys?.dashscope?.trim();this.providerConfig=h??(r?{agent:"pi",token:r,updatedAt:""}:void 0),this.runId=b(),this.seq=0,this.emittedLengths.clear(),this.terminalState="open",this.agent||this.initAgent(),await this.finalizePromise.catch(()=>{}),this.agent?.setModel(M(e??J)),this.pendingBaseMessages=S(this.agent?.state.messages??[]);const d=this.runId,m=new Promise((c,u)=>{this.pendingSendStart={runId:d,resolve:c,reject:u}});this.emit("agentEvent",{state:"init",runId:d,seq:++this.seq}),this.agent.prompt(t).then(async()=>{s===this.sendGeneration&&(this.resolvePendingSendStart(d),await this.finalizePromise.catch(()=>{}))}).catch(c=>{if(s!==this.sendGeneration||(this.rejectPendingSendStart(d,c),this.terminalState!=="open"))return;this.terminalState="error";const u=c instanceof Error?c.message:String(c);u.includes("429")||u.includes("daily_quota_exceeded")||u.includes("nian_quota_exceeded")?this.emit("agentEvent",{state:"error",runId:d,seq:++this.seq,message:"Nian \u4ECA\u65E5\u989D\u5EA6\u5DF2\u7528\u5B8C\uFF0C\u6B21\u65E5\u81EA\u52A8\u6062\u590D\u3002"}):this.emit("agentEvent",{state:"error",runId:d,seq:++this.seq,message:u})}),await m}initAgent(){const t=this.workDir??process.cwd(),e=et(t,this.extraEnv),s=U(t),n=new T({initialState:{systemPrompt:[W,s,`\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${t}`,F(this.externalChannel,t,this.shennianSessionId??void 0)].filter(Boolean).join(`
|
|
5
8
|
|
|
6
|
-
`),model:M(),tools:e},streamFn:(
|
|
7
|
-
${this.cachedSummary}`}],timestamp:Date.now()}),
|
|
8
|
-
${
|
|
9
|
-
${this.cachedSummary}`}],timestamp:Date.now()},...
|
|
10
|
-
...(\u5DF2\u622A\u65AD)`:e;return await
|
|
9
|
+
`),model:M(),tools:e},streamFn:(i,a,h)=>{const r=this.providerConfig;return r?.token?j(M(i.id,{provider:"dashscope",baseUrl:r.baseUrl||Q,compat:{supportsDeveloperRole:!1,supportsStore:!1,supportsReasoningEffort:!1,maxTokensField:"max_tokens",thinkingFormat:"qwen"}}),a,{...h,apiKey:r.token}):I(i,a,{...h,authToken:this.authToken,proxyUrl:this.proxyUrl})},transformContext:i=>this.compressContext(i)});this.agent=n,this.restoredMessages.length>0?n.replaceMessages(S(this.restoredMessages)):this.cachedSummary&&(n.appendMessage({role:"user",content:[{type:"text",text:`[\u4E4B\u524D\u7684\u5BF9\u8BDD\u6458\u8981]
|
|
10
|
+
${this.cachedSummary}`}],timestamp:Date.now()}),n.appendMessage({role:"assistant",content:[{type:"text",text:"\u597D\u7684\uFF0C\u6211\u5DF2\u4E86\u89E3\u4E4B\u524D\u7684\u5BF9\u8BDD\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u7EE7\u7EED\u3002"}],timestamp:Date.now()})),n.subscribe(i=>{if(this.agent!==n||this.terminalState!=="open")return;const a=++this.seq,h=this.runId;switch(i.type){case"agent_start":this.resolvePendingSendStart(h),this.emit("agentEvent",{state:"start",runId:h,seq:a});break;case"message_update":{const r=i.message;if(r.role!=="assistant")break;const d=r.content??[];for(let m=0;m<d.length;m++){const c=d[m];if(c.type==="text"&&c.text){const u=`text:${m}`,f=this.emittedLengths.get(u)??0;if(c.text.length>f){const x=c.text.slice(f);this.emittedLengths.set(u,c.text.length),this.emit("agentEvent",{state:"delta",runId:h,seq:a,text:x})}}else if(c.type==="thinking"&&c.thinking){const u=`thinking:${m}`,f=this.emittedLengths.get(u)??0;if(c.thinking.length>f){const x=c.thinking.slice(f);this.emittedLengths.set(u,c.thinking.length),this.emit("agentEvent",{state:"delta",runId:h,seq:a,text:x,thinking:!0})}}}break}case"tool_execution_start":this.emit("agentEvent",{state:"tool-call",runId:h,seq:a,name:i.toolName,args:i.args});break;case"tool_execution_end":this.emit("agentEvent",{state:"tool-result",runId:h,seq:a,name:i.toolName,result:typeof i.result=="string"?i.result:JSON.stringify(i.result)});break;case"agent_end":{this.terminalState="final";const r=i.messages,m=[...r].reverse().find(c=>c.role==="assistant")?.usage;this.emit("agentEvent",{state:"final",runId:h,seq:a,usage:m?{inputTokens:m.input??0,outputTokens:m.output??0}:void 0}),this.finalizePromise=this.finalizeTurn(r);break}}})}async compressAndReplace(){if(!this.agent||this.compressing)return;const t=this.agent.state.messages;if(w(t)<v)return;const s=this.splitMessages(t);if(!s)return;const n=await this.generateSummary(s.toCompress);if(!n)return;this.cachedSummary=n,this.lastSummaryMsgCount+=s.toCompress.length;const i=[{role:"user",content:[{type:"text",text:`[\u5386\u53F2\u5BF9\u8BDD\u6458\u8981]
|
|
11
|
+
${n}`}],timestamp:Date.now()},{role:"assistant",content:[{type:"text",text:"\u597D\u7684\uFF0C\u6211\u5DF2\u4E86\u89E3\u4E0A\u4E0B\u6587\u3002"}],timestamp:Date.now()},...s.toKeep];this.agent.replaceMessages(i)}async compressContext(t){if(w(t)<v||!this.cachedSummary)return t;const s=this.splitMessages(t);return s?[{role:"user",content:[{type:"text",text:`[\u5386\u53F2\u5BF9\u8BDD\u6458\u8981]
|
|
12
|
+
${this.cachedSummary}`}],timestamp:Date.now()},...s.toKeep]:t}splitMessages(t){const e=t.filter(n=>n.role!=="system");if(e.length<=k)return null;let s=e.length-k;for(;s>0&&e[s].role==="toolResult";)s--;return s<=0?null:{toCompress:e.slice(0,s),toKeep:e.slice(s)}}async generateSummary(t){if(!this.authToken||!this.proxyUrl||this.compressing)return this.cachedSummary;this.compressing=!0;try{const e=G(t);if(e.length<100)return null;const s=e.length>1e4?e.slice(0,1e4)+`
|
|
13
|
+
...(\u5DF2\u622A\u65AD)`:e;return await H(this.proxyUrl,this.authToken,`\u8BF7\u5C06\u4EE5\u4E0B\u5BF9\u8BDD\u5386\u53F2\u538B\u7F29\u4E3A\u7B80\u6D01\u6458\u8981\uFF0C\u4FDD\u7559\u5173\u952E\u4FE1\u606F\uFF1A\u8BA8\u8BBA\u7684\u6587\u4EF6\u548C\u76EE\u5F55\u3001\u505A\u51FA\u7684\u6280\u672F\u51B3\u5B9A\u3001\u5F53\u524D\u4EFB\u52A1\u8FDB\u5EA6\u3001\u672A\u5B8C\u6210\u7684\u5DE5\u4F5C\u3002\u6458\u8981\u63A7\u5236\u5728 300 \u5B57\u4EE5\u5185\u3002
|
|
11
14
|
|
|
12
|
-
${
|
|
15
|
+
${s}`)}catch{return this.cachedSummary}finally{this.compressing=!1}}loadSnapshot(){if(this.snapshotPath)try{const t=l.readFileSync(this.snapshotPath,"utf-8"),e=JSON.parse(t);this.restoredMessages=Array.isArray(e.messages)?e.messages:[],this.cachedSummary=e.summary??this.cachedSummary,this.lastSummaryMsgCount=e.summarizedCount??this.lastSummaryMsgCount}catch{this.restoredMessages=[]}}loadSummary(){if(this.summaryPath)try{const t=l.readFileSync(this.summaryPath,"utf-8"),e=JSON.parse(t);this.cachedSummary=e.summary??null,this.lastSummaryMsgCount=e.summarizedCount??0}catch{if(!this.sessionDir)return;try{const t=g.join(this.sessionDir,R),e=l.readFileSync(t,"utf-8"),s=JSON.parse(e);this.cachedSummary=s.summary??null,this.lastSummaryMsgCount=s.summarizedCount??0}catch{}}}saveSummary(t){if(this.summaryPath)try{l.mkdirSync(g.dirname(this.summaryPath),{recursive:!0});const e=E(this.cachedSummary,t);this.cachedSummary=e,l.writeFileSync(this.summaryPath,JSON.stringify({version:1,summary:e,summarizedCount:this.lastSummaryMsgCount,updatedAt:Date.now()},null,2))}catch{}}saveSnapshot(t){if(!(!this.snapshotPath||!this.sessionId||!this.workDir))try{l.mkdirSync(g.dirname(this.snapshotPath),{recursive:!0}),l.writeFileSync(this.snapshotPath,JSON.stringify({version:1,sessionId:this.sessionId,workDir:this.workDir,summary:this.cachedSummary,summarizedCount:this.lastSummaryMsgCount,messages:t,updatedAt:Date.now()},null,2)),this.restoredMessages=S(t)}catch{}}appendMessagesLog(t){if(!(!this.messagesPath||t.length===0))try{l.mkdirSync(g.dirname(this.messagesPath),{recursive:!0});const e=t.map(s=>JSON.stringify(s)).join(`
|
|
13
16
|
`)+`
|
|
14
|
-
`;
|
|
17
|
+
`;l.appendFileSync(this.messagesPath,e,"utf-8")}catch{}}getTurnMessages(t){const e=B(this.pendingBaseMessages,t);return S(t.slice(e))}async finalizeTurn(t){const e=S(t),s=this.getTurnMessages(e);this.appendMessagesLog(s),await this.compressAndReplace();const n=this.agent?S(this.agent.state.messages):e;this.cachedSummary||(this.cachedSummary=E(null,e)),this.saveSummary(n),this.saveSnapshot(n)}async resume(t){this.loadSnapshot(),this.loadSummary(),this.agent&&this.restoredMessages.length>0&&this.agent.replaceMessages(S(this.restoredMessages))}async stop(){if(this.rejectPendingSendStart(this.runId,new Error("Pi run stopped before dispatch completed")),await this.finalizePromise.catch(()=>{}),this.agent){const t=S(this.agent.state.messages??[]);this.saveSummary(t),this.saveSnapshot(t)}this.agent?.abort(),this.agent=null}resolvePendingSendStart(t){if(!this.pendingSendStart||this.pendingSendStart.runId!==t)return;const{resolve:e}=this.pendingSendStart;this.pendingSendStart=null,e()}rejectPendingSendStart(t,e){if(!this.pendingSendStart||this.pendingSendStart.runId!==t)return;const{reject:s}=this.pendingSendStart;this.pendingSendStart=null,s(e)}}$("pi",()=>new st);export{st as PiAdapter,Mt as buildShellCommandSpec};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
`,"utf8")}catch{}}function rt(e){if(!e||typeof e!="object")return null;const t=e,n=typeof t.windowId=="string"?t.windowId:"",r=typeof t.boundsKey=="string"?t.boundsKey:"";if(!r)return null;const i=ie(t.messageInputPoint??t.point),o=ie(t.searchInputPoint);return{windowId:n,boundsKey:r,messageInputPoint:i,searchInputPoint:o,...typeof t.updatedAt=="string"?{updatedAt:t.updatedAt}:{}}}function ie(e){if(!e||typeof e!="object")return null;const t=e,n=Number(t.x),r=Number(t.y);return!Number.isFinite(n)||!Number.isFinite(r)?null:{x:Math.round(n),y:Math.round(r),coordinateSpace:"screen"}}function oe(e){const t=e.bounds;return[Math.round(Number(t?.x??0)),Math.round(Number(t?.y??0)),Math.round(Number(t?.width??0)),Math.round(Number(t?.height??0))].join(",")}function R(e,t,n,r="message-input"){const i=Number(e?.x),o=Number(e?.y),s=Number(e?.width),a=Number(e?.height);if(![i,o,s,a].every(Number.isFinite)||s<=0||a<=0)return null;const c=e?.coordinateSpace==="screen"?{x:i,y:o,width:s,height:a,coordinateSpace:"screen"}:{x:i/999*t.width,y:o/999*t.height,width:s/999*t.width,height:a/999*t.height,coordinateSpace:"screenshotPixel"},l=it(c,t,n,r);return l?{x:Math.round(l.x),y:Math.round(l.y),coordinateSpace:"screen"}:null}function it(e,t,n,r="message-input"){const i=r==="message-input"?.28:.55,o=ot({x:e.x+e.width*.54,y:e.y+e.height*i,coordinateSpace:e.coordinateSpace},t,n);return o?{x:o.x,y:o.y,coordinateSpace:"screen"}:null}function ot(e,t,n){if(![e.x,e.y].every(Number.isFinite))return null;if(e.coordinateSpace==="screen"||!n.bounds)return{x:e.x,y:e.y};const r=t.width&&n.bounds.width?t.width/n.bounds.width:1,i=t.height&&n.bounds.height?t.height/n.bounds.height:r,o=Math.max(0,(t.width-n.bounds.width*r)/2),s=Math.max(0,(t.height-n.bounds.height*i)/2);return{x:n.bounds.x+(e.x-o)/r,y:n.bounds.y+(e.y-s)/i}}async function ae(e){if(!e.api.classifyWindow)throw new Error("wechat_window_classifier_unavailable");const t=await e.helper.request("windows.list",{},e.traceId);m(t,"windows.list");const n=(t.result?.windows??[]).filter(H).filter(s=>s.visible!==!1&&s.minimized!==!0&&!!s.windowId),r=ct(n.length?n:[e.fallback],e.fallback);if(!r.length)throw new Error("wechat_window_not_found");const i=[];for(const s of r)try{const a=await F(e.helper,s.windowId,e.traceId,s.bounds),c=await e.api.classifyWindow(e.runtime,e.binding,{screenshot:{mimeType:a.mimeType,dataBase64:a.dataBase64,width:a.width,height:a.height,windowId:s.windowId},traceId:e.traceId});i.push({window:s,classification:c,screenshot:a,score:dt(c,e.requireTargetConversation===!0)})}catch(a){if(at(a))throw a;i.push({window:s,classification:null,errorSummary:a instanceof Error?a.message:String(a||"window classification failed"),score:-1})}const o=i.filter(s=>s.score>0).sort((s,a)=>a.score-s.score)[0];if(!o){const s=i.map(a=>({windowId:a.window.windowId,appName:a.window.appName,title:a.window.title,score:a.score,errorSummary:a.errorSummary,classification:a.classification?{windowKind:a.classification.windowKind,reasonCode:a.classification.reasonCode,confidence:a.classification.confidence,conversationTitle:a.classification.conversationTitle,isTargetConversation:a.classification.isTargetConversation}:null}));throw new Error(`wechat_chat_main_window_not_found: ${JSON.stringify(s)}`)}return o.screenshot&&tt({helper:e.helper,runtime:e.runtime,binding:e.binding,workDir:e.workDir,traceId:e.traceId,window:o.window,classification:o.classification,screenshot:o.screenshot}),o.window}async function Pn(e,t,n){if(e.runtime.policy.platform!=="win32")return;const r=t.filter(i=>{if(i.window.windowId===n.window.windowId||!i.window.windowId)return!1;const o=i.classification?.windowKind;return o==="chat_main"||o==="login"});if(r.length!==0)for(const i of r)try{await e.helper.request("windows.closeWindow",{windowId:i.window.windowId},e.traceId)}catch{}}function at(e){const t=st(e);return t==="insufficient_credits"||t==="entitlement_required"||t==="manual_review_required"||t==="wechat_channel_network_failed"||t==="wechat_channel_invalid_response"}function st(e){if(e instanceof Ae||e&&typeof e=="object"&&typeof e.reasonCode=="string")return e.reasonCode.trim().toLowerCase();const t=e instanceof Error?e.message:String(e||"");return/classify-window (?:network )?failed:\s*([a-z][a-z0-9_]*)/i.exec(t)?.[1]?.trim().toLowerCase()||""}function ct(e,t){const n=[],r=i=>{i?.windowId&&(n.some(o=>o.windowId===i.windowId)||n.push(i))};r(e.find(i=>i.windowId===t.windowId));for(const i of e)r(i);return n}function dt(e,t){if(!e||e.windowKind!=="chat_main")return 0;const n=Number(e.confidence??0);return t&&e.isTargetConversation!==!0?0:100+(e.isTargetConversation?50:0)+Math.round(Math.max(0,Math.min(1,n))*100)}function lt(e,t,n){if(!t)return{helper:e,withLease:async(a,c,l)=>await l(e)};let r=null;const i=a=>{t.onEvent?.({...a,at:new Date().toISOString()})},o=async(a,c,l={})=>{if(r){const u=await e.request("automation.lease.status",{},n),d=u.result??{},f=u.ok&&d.interrupted?se(d.interruptReason):u.ok?void 0:u.errorCode||"user_activity_unknown";if(i({phase:"lease-status",stage:a,action:c,ok:u.ok===!0&&!d.interrupted,...f?{reasonCode:f}:{}}),!u.ok)throw new N({reasonCode:u.errorCode||"user_activity_unknown",stage:a,action:c});if(d.active===!1||d.leaseId!==r||!d.interrupted)return;throw new N({reasonCode:se(d.interruptReason),stage:a,action:c})}const w=Date.now()+wt(t.preflightIdleSettleTimeoutMs);for(;;){const u=await e.request("activity.snapshot",{},n);if(!u.ok)throw i({phase:"snapshot",stage:a,action:c,ok:!1,reasonCode:u.errorCode||"user_activity_unknown"}),new N({reasonCode:u.errorCode||"user_activity_unknown",stage:a,action:c});const d=He({snapshot:Ge(u.result),stage:a,policy:t.policy});if(i({phase:"snapshot",stage:a,action:c,ok:d.ok,...d.ok?{}:{reasonCode:d.reasonCode,waitMs:d.waitMs}}),d.ok)return;const f=new N({reasonCode:d.reasonCode,stage:a,action:c});if(!l.settle)throw f;const X=w-Date.now();if(X<=0)throw f;await G(Math.max(50,Math.min(d.waitMs,X)))}},s={request:async(a,c,l)=>{const w=ut(a);w&&await o(w.stage,`${a}:before`);const u=await e.request(a,c,l);return w&&u.ok&&await o(w.stage,`${a}:after`),u}};return{helper:s,async withLease(a,c,l){if(await Lt(e,n),await o(a,`${c}:preflight`,{settle:!0}),t.useAutomationLease===!1)return await l(s);const w=await e.request("automation.lease.acquire",{owner:"wechat-channel",purpose:`observe:${c}`,ttlMs:12e4},n);if(r=typeof w.result?.leaseId=="string"?w.result.leaseId:null,i({phase:"lease-acquire",stage:a,action:c,ok:w.ok===!0,...w.ok?{}:{reasonCode:w.errorCode||"user_activity_unknown"}}),!w.ok)throw r=null,new N({reasonCode:w.errorCode||"user_activity_unknown",stage:a,action:c});try{const u=await l(s);return await o(a,`${c}:complete`),u}finally{const u=r;if(r=null,u){const d=await e.request("automation.lease.release",{leaseId:u},n).catch(f=>({ok:!1,errorCode:"automation_lease_release_failed",errorSummary:f instanceof Error?f.message:String(f)}));i({phase:"lease-release",stage:a,action:c,ok:d.ok===!0,...d.ok?{}:{reasonCode:d.errorCode||"automation_lease_release_failed"}})}}}}}function ut(e){return e==="windows.ensureReady"||e==="windows.focus"||e==="wechat.searchConversation"?{stage:"open_conversation"}:e==="keyboard.shortcut"||e==="mouse.click"||e==="mouse.rightClick"||e==="mouse.scroll"||e==="clipboard.snapshot"||e==="clipboard.readAttachment"||e==="menu.pickItem"?{stage:"dangerous_action"}:null}function se(e){return e==="recent_mouse_activity"||e==="recent_mouse_click"||e==="recent_scroll_activity"||e==="recent_keyboard_activity"||e==="frontmost_app_changed"?e:"user_activity_unknown"}function wt(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:Je}function ce(e){return e.observePipeline==="edge-structure"?!0:e.observePipeline==="server-observe"?!1:!!e.api.structureWindow}async function z(e){const t=await _e(e),n=await e.api.observe(e.runtime,e.binding,{screenshots:[{captureIndex:0,mimeType:t.mimeType,dataBase64:t.dataBase64,width:t.width,height:t.height}],edgeOcrBlocks:e.ocr.blocks??[],visibleConversationFingerprints:e.ocr.visibleConversationFingerprints??[],localLedgerTailAnchors:e.localLedgerTailAnchors??[],traceId:e.traceId}),r=await he({helper:e.helper,runtime:e.runtime,binding:e.binding,messages:n.observedMessages??[],workDir:e.workDir,attachmentsDir:e.attachmentsDir,window:e.window,screenshot:t,windowId:e.window.windowId,traceId:e.traceId,mediaAnchorText:e.mediaAnchorText});return Be(r,Ee({ocr:e.ocr,screenshot:t,binding:e.binding,anchors:e.localOutboundEchoAnchors??[]}))}async function de(e){if(!e.api.structureWindow)throw new Error("wechat_structure_window_unavailable");const t=await _e(e);let n;try{n=await e.api.structureWindow(e.runtime,e.binding,{screenshots:[{captureIndex:0,mimeType:t.mimeType,dataBase64:t.dataBase64,width:t.width,height:t.height}],edgeOcrBlocks:e.ocr.blocks??[],visibleConversationFingerprints:e.ocr.visibleConversationFingerprints??[],localLedgerTailAnchors:e.localLedgerTailAnchors??[],traceId:e.traceId})}catch(c){if(ht(c))return z(e);throw c}const r=Ct(n.structuredMessages??n.observedMessages??[]),i=await ft({...e,messages:r,screenshot:t}),o=await he({helper:e.helper,runtime:e.runtime,binding:e.binding,messages:i.messages,workDir:e.workDir,attachmentsDir:e.attachmentsDir,window:e.window,screenshot:t,windowId:e.window.windowId,traceId:e.traceId,mediaAnchorText:e.mediaAnchorText}),s=Be(o,Ee({ocr:e.ocr,screenshot:t,binding:e.binding,anchors:e.localOutboundEchoAnchors??[]}));return e.localLedger?De({ledger:e.localLedger,bindingId:e.binding.bindingId,observedMessages:s,baselineOnly:e.baselineOnly,vectorReferences:i.vectorReferences}).newMessages:s}function ht(e){return e instanceof Error&&/\bedge_runtime_disabled\b/.test(e.message)}async function ft(e){const t=mt(e.messages);if(!t.length)return{messages:e.messages,vectorReferences:[]};const n=e.api.embedVisual?await gt({...e,seedBlocks:t}):t.filter(s=>h(s.vectorBase64)||h(s.signature));if(!n.length)return{messages:e.messages,vectorReferences:[]};const r=e.vectorStorePath??Oe(e.workDir||process.cwd(),e.runtime.runtimeId),i=Ke(r,e.runtime.runtimeId),o=ze({store:i,bindingId:e.binding.bindingId,blocks:n});return o.length?($e(r,i),{messages:vt(e.messages,o),vectorReferences:o}):{messages:e.messages,vectorReferences:[]}}function mt(e){const t=[];for(const n of e)for(const[r,i]of(n.visualBlocks??[]).entries()){const o=h(i.blockId)||`${n.stableMessageKey}:visual-${r}`,s=h(i.blockKind)||n.kind||"visual";t.push({...i,stableMessageKey:n.stableMessageKey,blockId:o,blockKind:s,...i.bbox!==void 0?{bbox:i.bbox}:n.bbox!==void 0?{bbox:n.bbox}:{}})}return t}async function bt(e){if(!e.api.embedVisual)return[];const t=await e.api.embedVisual(e.runtime,e.binding,{screenshots:[{captureIndex:0,mimeType:e.screenshot.mimeType,dataBase64:e.screenshot.dataBase64,width:e.screenshot.width,height:e.screenshot.height}],visualBlocks:e.seedBlocks,traceId:e.traceId});return xt(t.visualBlocks??t.embeddedBlocks??[],e.seedBlocks)}async function gt(e){try{return await bt(e)}catch(t){if(yt(t))throw t;return[]}}function yt(e){return!e||typeof e!="object"?!1:e.reasonCode==="insufficient_credits"?!0:e instanceof Error&&/\binsufficient_credits\b/.test(e.message)}function xt(e,t){return e.map((n,r)=>{const i=t[r];return{...n,stableMessageKey:h(n.stableMessageKey)||h(i?.stableMessageKey),blockId:h(n.blockId)||h(i?.blockId),blockKind:h(n.blockKind)||h(i?.blockKind)||"visual",...n.bbox!==void 0?{bbox:n.bbox}:i?.bbox!==void 0?{bbox:i.bbox}:{}}}).filter(n=>h(n.stableMessageKey)&&h(n.blockId))}function vt(e,t){const n=new Map;for(const r of t){const i=n.get(r.stableMessageKey)??[];i.push(r),n.set(r.stableMessageKey,i)}return e.map(r=>{const i=n.get(r.stableMessageKey);return i?.length?{...r,visualBlocks:pt(r,i)}:r})}function pt(e,t){const r=(e.visualBlocks??[]).map((o,s)=>{const a=h(o.blockId)||`${e.stableMessageKey}:visual-${s}`,c=t.find(l=>l.blockId===a);return c?le(c,o):ue(o)}),i=new Set(r.map(o=>o.blockId));for(const o of t)i.has(o.blockId)||r.push(le(o));return r}function le(e,t){return{...t?ue(t):{},stableMessageKey:e.stableMessageKey,blockId:e.blockId,blockKind:e.blockKind,vectorStoreKey:e.vectorStoreKey,model:e.model,...e.modelVersion!==void 0?{modelVersion:e.modelVersion}:{},dims:e.dims,...e.signature?{signature:e.signature}:{},...e.bbox!==void 0?{bbox:e.bbox}:{}}}function ue(e){const{vectorBase64:t,...n}=e;return n}function Ct(e){return e.map((t,n)=>It(t,n)).filter(t=>t!=null)}function It(e,t){if(!b(e))return null;const n=Ve(e.kind),r=St(e.senderRole),i=g(e.normalizedText),o=g(e.anchorText)??i??g(e.textExcerpt),s=h(e.stableMessageKey)||_t({message:e,index:t,senderRole:r,kind:n,anchorText:o});return{stableMessageKey:s,senderRole:r,...g(e.senderName)!==null?{senderName:g(e.senderName)}:{},kind:n,...i!==null?{normalizedText:i}:{},...o!==null?{anchorText:o}:{},...I(e,"anchorMetadata")?{anchorMetadata:e.anchorMetadata}:{},...I(e,"neighborContext")?{neighborContext:e.neighborContext}:{},...g(e.textExcerpt)!==null?{textExcerpt:g(e.textExcerpt)}:{},...I(e,"bbox")?{bbox:e.bbox}:{},...I(e,"mediaMetadata")?{mediaMetadata:kt(e.mediaMetadata)}:{},...typeof e.isBaseline=="boolean"?{isBaseline:e.isBaseline}:{},...g(e.deliveryStatus)!==null?{deliveryStatus:g(e.deliveryStatus)??void 0}:{},...g(e.observedAt)!==null?{observedAt:g(e.observedAt)??void 0}:{},...Array.isArray(e.visualBlocks)?{visualBlocks:e.visualBlocks}:{},...o?{}:{anchorText:s}}}function _t(e){const t=b(e.message.bbox)?JSON.stringify(e.message.bbox):"";return`structured-window:${[e.index,e.senderRole,e.kind,e.anchorText||h(e.message.textExcerpt)||"",t].join(":").slice(0,180)}`}function kt(e){if(!b(e))return e;const t={...e};return I(t,"availability")&&(t.availability=Z(t.availability)),b(t.attachment)&&(t.attachment=we(t.attachment)),Array.isArray(t.attachments)&&(t.attachments=t.attachments.map(n=>b(n)?we(n):n)),t}function we(e){const t={...e};return I(t,"availability")&&(t.availability=Z(t.availability)),t}function St(e){return e==="self"||e==="contact"||e==="system"||e==="unknown"?e:"unknown"}async function he(e){if(e.binding.downloadMedia===!1)return e.messages;const t=e.messages.map((o,s)=>Wt(o,e.screenshot,e.window,Pt(e.messages,s))).filter((o,s)=>Mt(e.messages,s,e.mediaAnchorText)).filter(o=>o!=null);if(!t.length)return e.messages;const n=e.attachmentsDir??Fe(e.workDir||process.cwd(),e.runtime.runtimeId,e.binding.bindingId),r=await Le({helper:e.helper,candidates:t,attachmentsDir:n,screenshot:e.screenshot,windowId:e.windowId,window:e.window,traceId:e.traceId,platform:e.runtime.policy.platform,stabilityCheck:async()=>{const o=await M({helper:e.helper,window:e.window,binding:e.binding,traceId:e.traceId});return o.ok?{ok:!0}:{ok:!1,reasonCode:o.reason}}});if(!r.length)return e.messages;const i=new Map(r.map(o=>[o.messageKey,o]));return e.messages.map(o=>{const s=i.get(o.stableMessageKey);return s?{...o,mediaMetadata:Rt(o.mediaMetadata,s.attachment,s.reasonCode,s.attemptReasonCodes,s.resolveTrace)}:o})}function Mt(e,t,n){const r=me(n);if(!r)return!0;const i=Nt(r),o=e.map((s,a)=>me(Bt(s)).includes(r)?a:-1).filter(s=>s>=0);if(!o.length)return t===Tt(e,i);for(const s of o)if(t>=s&&t<=s+8||t===s-1&&!e.slice(s+1,Math.min(e.length,s+9)).some(fe))return!0;return!1}function Nt(e){return e.includes("video")||e.includes("vide0")?"video":e.includes("image")||e.includes("photo")||e.includes("ph0t0")||e.includes("picture")?"image":e.includes("file")||e.includes("document")?"file":null}function Tt(e,t=null){for(let n=e.length-1;n>=0;n-=1)if(fe(e[n]))return Et(e[n],t)?n:-1;return-1}function fe(e){if(!e)return!1;const t=String(e.kind||"").toLowerCase(),n=b(e.mediaMetadata)?e.mediaMetadata:{},r=b(n.attachment)?n.attachment:{};return be(t,n,r)}function Et(e,t){if(!e||!t)return!0;const n=String(e.kind||"").toLowerCase(),r=b(e.mediaMetadata)?e.mediaMetadata:{},i=b(r.attachment)?r.attachment:{},o=String(i.type||"").toLowerCase(),s=String(i.mimeType||"").toLowerCase(),a=String(i.name||i.localPath||e.anchorText||e.textExcerpt||"").toLowerCase();return t==="video"?n.includes("video")||o==="video"||s.startsWith("video/")||/\.(mp4|mov|m4v|avi|mkv|webm)$/i.test(a):t==="image"?/image|photo|picture/.test(n)||o==="image"||s.startsWith("image/")||/\.(png|jpe?g|gif|webp|heic|tiff?|bmp)$/i.test(a):/file|document/.test(n)||o==="file"||!/image|photo|picture|video/.test(n)&&o!=="image"&&o!=="video"&&!s.startsWith("image/")&&!s.startsWith("video/")}function Bt(e){if(!e)return"";const t=e;return[e.normalizedText,e.anchorText,e.textExcerpt,t.text].map(n=>String(n||"")).join(`
|
|
3
|
-
`)}function
|
|
4
|
-
`)||null}function Wt(e,t,n,r){const i=String(e.kind||"").toLowerCase(),o=b(e.mediaMetadata)?e.mediaMetadata:{},s=b(o.attachment)?o.attachment:{},a=h(s.availability)||h(o.availability),c=h(s.localPath)||h(o.localPath);if(a==="edge-local"&&c||!be(i,o,s))return null;const l=A(e.bbox)??A(o.bbox)??A(o.downloadActionBbox),w=A(o.downloadActionBbox),u=ge(l,t,n),d=Ft(l,t,n),f=ge(w,t,n);return{messageKey:e.stableMessageKey,kind:h(s.type)||h(s.kind)||h(o.messageType)||i,fileName:h(s.name)||h(s.fileName)||h(o.fileName)||null,mimeType:h(s.mimeType)||h(o.mimeType)||null,size:_(s.size)??_(o.size),mediaStatus:At(o,s),observedAt:e.observedAt??null,contextText:r??e.normalizedText??e.anchorText??e.textExcerpt??null,...u?{bbox:u}:{},...d?{screenshotBbox:d}:{},...f?{downloadActionBbox:f}:{}}}function Rt(e,t,n,r,i){const o=b(e)?{...e}:{};return{...o,availability:b(t)?t.availability:o.availability,mediaStatus:b(t)&&t.availability==="edge-local"?"downloaded":o.mediaStatus,attachment:t,edgeResolveReasonCode:n,...r?.length?{edgeResolveAttempts:r}:{},...i?{edgeResolveTrace:i}:{}}}function At(e,t){const n=h(e.mediaStatus);if(n==="not_downloaded")return"not_downloaded";if(n==="loading"||n==="downloading"||n==="in_progress")return"loading";if(n==="downloaded"||n==="available")return"available";const r=h(t.availability)||h(e.availability);return r==="pending-download"?"not_downloaded":r==="metadata-only"?"metadata_only":n||null}function be(e,t,n){const r=`${e} ${h(t.messageType)} ${h(n.type)} ${h(n.kind)}`.toLowerCase();return/image|photo|video|file|document/.test(r)}function A(e){if(!b(e))return null;const t=_(e.x),n=_(e.y),r=_(e.width),i=_(e.height);return t==null||n==null||r==null||i==null?null:{x:t,y:n,width:r,height:i,...typeof e.coordinateSpace=="string"?{coordinateSpace:e.coordinateSpace}:{}}}function ge(e,t,n){if(!e)return null;if(e.coordinateSpace==="screen")return e;const r=K(e,t,n);if(!r)return e;const i=n.bounds;if(!i?.width||!i?.height)return{...e,x:r.x-e.width/2,y:r.y-e.height/2,coordinateSpace:"screen"};const o=i.width/t.width,s=i.height/t.height,a=r.x,c=r.y;return{x:a-e.width*o/2,y:c-e.height*s/2,width:e.width*o,height:e.height*s,coordinateSpace:"screen"}}function Ft(e,t,n){if(!e)return null;if(e.coordinateSpace!=="screen")return{...e,coordinateSpace:"screenshotPixel"};const r=n.bounds;if(!r?.width||!r?.height)return null;const i=t.width/r.width,o=t.height/r.height;return{x:(e.x-r.x)*i,y:(e.y-r.y)*o,width:e.width*i,height:e.height*o,coordinateSpace:"screenshotPixel"}}function b(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function I(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function h(e){return typeof e=="string"?e.trim():""}function g(e){return h(e)||null}function _(e){const t=Number(e);return Number.isFinite(t)?t:null}async function Wn(e,t){await xe(e,t)}async function Lt(e,t){await ye(e,t)}async function ye(e,t){const n=await e.request("permissions.check",{},t);m(n,"permissions.check");const r=n.result??{};if(Kt(r.platform)){const i=await Dt(e,r,t);if(i==="screen-recording")throw new Error("permission_screen_recording_missing");if(i==="accessibility")throw new Error("permission_accessibility_missing");if(i==="input-monitoring")throw new Error("permission_input_monitoring_missing");if(r.automation===!1)throw new Error("permission_automation_missing")}return r}async function xe(e,t,n={}){const r=await ye(e,t),i=String(r.platform??"").toLowerCase();if(r.wechatRunning===!1)throw new Error("wechat_not_running");if(Vt(r))throw new Error("windows_visible_desktop_unavailable");if(r.dpiMappingAvailable===!1||r.displayTopologySupported===!1)throw new Error("dpi_mapping_failed");if(r.wechatMainWindowResponsive===!1)throw new Error("wechat_window_unresponsive");if(r.wechatWindowAvailable===!1&&i!=="win32"&&n.allowUnavailableWindow!==!0)throw new Error("wechat_window_unavailable");return r}async function Dt(e,t,n){const r=Ot(t);if(!r||process.platform!=="darwin")return r;const i=$t(r);try{await e.request(i,{},n)}catch{}return r}function Ot(e){return e.screenRecording===!1?"screen-recording":e.accessibility===!1?"accessibility":e.inputMonitoring===!1?"input-monitoring":null}function Kt(e){const t=String(e||"").toLowerCase();return t?t.includes("darwin")||t.includes("mac"):!0}function $t(e){return e==="screen-recording"?"permissions.requestScreenRecording":e==="accessibility"?"permissions.requestAccessibility":"permissions.requestInputMonitoring"}async function zt(e,t,n={}){const i=(n.foreground??"required")!=="background",o=await xe(e,t,{allowUnavailableWindow:i});if(String(o.platform??"").toLowerCase()==="win32"){const c=await e.request("windows.ensureReady",{activate:i,allowRecovery:!1,allowLaunch:!1},t);m(c,"windows.ensureReady");const l=c.result;if(!l?.windowId)throw new Error("helper_invalid_response: windows.ensureReady missing WeChat window data");return l}const s=await e.request("windows.ensureReady",{restore:i,focus:i},t);m(s,"windows.ensureReady");const a=s.result;if(!a?.windowId)throw new Error("helper_invalid_response: windows.ensureReady missing WeChat window data");return a}function Vt(e){return e.windowsVisibleDesktopAvailable===!1||e.rdpVisibleDesktopAvailable===!1||e.desktopSessionVisible===!1||e.screenLocked===!0||e.rdpDisconnected===!0}function ve(e){const t=e.filter(H),n=t.filter(i=>i.visible!==!1&&i.minimized!==!0);return(n.length?n:t)[0]??null}async function Rn(e,t){let n=await e.request("windows.list",{},t);m(n,"windows.list");let r=n.result?.windows??[],i=ve(r);if(!i)throw new Error("wechat_window_not_found");const o=await e.request("windows.focus",{windowId:i.windowId},t);return m(o,"windows.focus"),await Ce(e,i,t)}async function pe(e,t,n){if(!t.windowId)throw new Error("wechat_window_not_found");const r=await e.request("windows.focus",{windowId:t.windowId},n);return m(r,"windows.focus"),t}async function qt(e,t){const n=await e.request("windows.list",{},t);m(n,"windows.list");const r=n.result?.windows??[],i=ve(r);if(!i)throw new Error("wechat_window_not_found");const o=await e.request("windows.focus",{windowId:i.windowId},t);return m(o,"windows.focus"),await Ce(e,i,t)}async function Ce(e,t,n){let r;try{r=await e.request("windows.list",{},n)}catch{return t}if(!r.ok)return t;const i=(r.result?.windows??[]).filter(H);return i.find(o=>o.windowId===t.windowId)??i[0]??t}async function V(e){const{capture:t,ocr:n}=e.observation??await k(e),r=E({capture:t,ocr:n,window:e.window});if(r)return{opened:!1,reason:r};const i=je({visibleItems:en(n,t,e.allowOcrTitleRows!==!1),targets:[{bindingId:e.binding.bindingId,conversationDisplayName:e.binding.conversationDisplayName}]})[0];if(!i)return{opened:!1,reason:"conversation_not_visible"};const o=gn(i.item.bbox,t,e.window);if(!o)return{opened:!1,reason:"conversation_bbox_missing"};const s=await e.helper.request("mouse.click",{x:o.x,y:o.y,coordinateSpace:"screen",windowId:e.window.windowId},e.traceId);return m(s,"mouse.click"),{opened:!0,reason:i.reason}}async function q(e){let t={opened:!1,reason:"conversation_not_opened"};for(let r=0;r<Ue;r+=1){if(t=await jt(e),t.opened||t.reason!=="conversation_title_not_confirmed")return t;await S(e,"open-retry",`retry:${r}`)}const n=await Ie(e);return n.opened?{opened:!0,reason:`${n.reason}:final-visible-recovery`}:t}async function jt(e){const t=await k(e),n=E({capture:t.capture,ocr:t.ocr,window:e.window});if(n)return{opened:!1,reason:n};let r=!1;if(O(t.ocr,t.capture,e.binding.conversationDisplayName))return e.settleToBottom===!0&&await T({helper:e.helper,window:e.window,traceId:e.traceId,observation:t}),{opened:!0,reason:"current-conversation-title-confirmed"};if(!r){const u=await V({...e,observation:t});if(u.opened){if(await S(e,"open-click-settle","visible-initial"),(await M(e)).ok)return{opened:!0,reason:u.reason};const f=await Ie(e);if(f.opened)return f}}const i=await Jt(e,t.capture);if(!i.ok)return{opened:!1,reason:i.reason};const o=await e.helper.request("wechat.searchConversation",{conversationName:e.binding.conversationDisplayName,windowId:e.window.windowId,waitMs:e.searchDelayMs??L(e,"search-input-settle","search-input"),searchPoint:i.point},e.traceId);m(o,"wechat.searchConversation");const s=await Ht(e);if(s.opened){await S(e,"open-click-settle","search-result-click");const u=await M(e);return u.ok?(e.settleToBottom===!0&&await T({helper:e.helper,window:e.window,traceId:e.traceId}),{opened:!0,reason:s.reason}):{opened:!1,reason:u.reason}}let a=s.observation;const c=y(e.binding.conversationDisplayName)&&s.reason==="search_result_not_visible";if(!y(e.binding.conversationDisplayName)){await Qt(e.helper,e.traceId),await S(e,"open-click-settle","search-return");const u=await M(e);if(u.ok)return e.settleToBottom===!0&&await T({helper:e.helper,window:e.window,traceId:e.traceId}),{opened:!0,reason:u.reason};const d=await e.helper.request("wechat.searchConversation",{conversationName:e.binding.conversationDisplayName,windowId:e.window.windowId,waitMs:e.searchDelayMs??L(e,"search-input-settle","search-input-retry-after-return"),searchPoint:i.point},e.traceId);m(d,"wechat.searchConversation"),a=void 0}const l=await V({...e,...a?{observation:a}:{},allowOcrTitleRows:!c});if(!l.opened)return l;await S(e,"open-click-settle","visible-final");const w=await M(e);return w.ok?(e.settleToBottom===!0&&await T({helper:e.helper,window:e.window,traceId:e.traceId}),{opened:!0,reason:l.reason}):{opened:!1,reason:w.reason}}async function Ie(e){const t=await V(e);if(!t.opened)return t;await S(e,"open-click-settle","visible-retry");const n=await M(e);return n.ok?(e.settleToBottom===!0&&await T({helper:e.helper,window:e.window,traceId:e.traceId}),{opened:!0,reason:`${t.reason}:retry-visible-title-confirmed`}):{opened:!1,reason:n.reason}}async function Ht(e){let t;const n=e.searchDelayMs===0?0:L(e,"search-result-probe","search-result-probe"),r=y(e.binding.conversationDisplayName)?Ye:1;for(let i=0;i<r;i+=1){i>0&&n>0&&await G(n);const o=await Gt(e);t=o;const{capture:s,ocr:a}=o,c=E({capture:s,ocr:a,window:e.window});if(c)return{opened:!1,reason:c,observation:o};const l=rn(a,s,e.binding.conversationDisplayName);if(!l){if(on(a)||an(a,e.binding.conversationDisplayName))break;continue}const w=K(l.bbox,s,Ut(s,e.window));if(!w)return{opened:!1,reason:"search_result_bbox_missing",observation:o};const u=await e.helper.request("mouse.click",{x:w.x,y:w.y,coordinateSpace:"screen",windowId:e.window.windowId},e.traceId);return m(u,"mouse.click"),{opened:!0,reason:l.reason,observation:o}}return{opened:!1,reason:"search_result_not_visible",observation:t}}async function Gt(e){if(e.window.bounds&&y(e.binding.conversationDisplayName)){const t=await e.helper.request("screen.capture",{bounds:e.window.bounds},e.traceId);if(t.ok&&t.result?.dataBase64&&t.result.width&&t.result.height){const n={...t.result,windowId:e.window.windowId,bounds:t.result.bounds??e.window.bounds},r=await ke(e.helper,n,e.traceId);return{capture:n,ocr:r}}t.errorCode&&t.errorCode!=="helper_unknown_command"&&t.errorCode!=="helper_command_unsupported"&&m(t,"screen.capture")}return k(e)}function Ut(e,t){return e.bounds?{...t,bounds:e.bounds}:t}async function k(e){let{capture:t,ocr:n}=await j(e.helper,e.window.windowId,e.traceId,e.window.bounds);return await Yt({helper:e.helper,window:e.window,capture:t,ocr:n,traceId:e.traceId})&&(await Q("preview-dismiss-settle",`${e.traceId||""}:${e.window.windowId}:preview-dismiss`),{capture:t,ocr:n}=await j(e.helper,e.window.windowId,e.traceId,e.window.bounds)),{capture:t,ocr:n}}async function Yt(e){const t=Xt(e.ocr,e.capture,e.window);if(!t)return!1;for(const n of[async()=>e.helper.request("keyboard.shortcut",{key:"escape",modifiers:[]},e.traceId),async()=>e.helper.request("mouse.click",{x:t.x,y:t.y,coordinateSpace:"screen",windowId:e.window.windowId},e.traceId)])if((await n()).ok)return!0;return!1}function Xt(e,t,n){const r=e.blocks??[],i=r.find(c=>{const l=String(c.text||""),w=c.bbox;if(!w)return!1;const u=Number(w.x),d=Number(w.y);return Number.isFinite(u)&&Number.isFinite(d)&&d>t.height*.06&&d<t.height*.22&&u>t.width*.3&&/查看原视频|查看原图|原视频|原图|视频|图片|图像/.test(l)});if(!i)return null;const o=i.bbox,s=Number(o?.y);if(!Number.isFinite(s))return null;const a=r.filter(c=>{const l=String(c.text||"").trim(),w=c.bbox;if(!w||l!=="\xD7")return!1;const u=Number(w.x),d=Number(w.y);return Number.isFinite(u)&&Number.isFinite(d)&&u>t.width*.55&&u<t.width*.9&&Math.abs(d-s)<t.height*.08}).sort((c,l)=>Number(l.bbox?.x??0)-Number(c.bbox?.x??0))[0];return K(a?.bbox,t,n)}async function Jt(e,t){if(!e.runtime||!e.api?.classifyWindow)return{ok:!1,reason:"wechat_search_input_detector_unavailable"};try{return{ok:!0,point:await nt({runtime:e.runtime,binding:e.binding,helper:e.helper,api:e.api,workDir:e.workDir,traceId:e.traceId,window:e.window,...t.dataBase64?{screenshot:t}:{}})}}catch(n){return{ok:!1,reason:n instanceof Error?n.message:"wechat_search_input_not_found"}}}async function F(e,t,n,r){const i=await e.request("windows.capture",{windowId:t,scope:"full-window",...r?{bounds:r}:{}},n);m(i,"windows.capture");const o=i.result;if(!o?.dataBase64||!o.mimeType||!o.width||!o.height)throw new Error("helper_invalid_response: windows.capture missing screenshot data");return o}async function _e(e){return e.capture.dataBase64?e.capture:F(e.helper,e.window.windowId,e.traceId,e.window.bounds)}async function j(e,t,n,r){const i=await e.request("windows.captureAndOcr",{windowId:t,scope:"full-window",...r?{bounds:r}:{}},n);if(i.ok&&i.result?.capture&&i.result?.ocr)return{capture:i.result.capture,ocr:i.result.ocr};!i.ok&&i.errorCode&&i.errorCode!=="helper_unknown_command"&&i.errorCode!=="helper_command_unsupported"&&m(i,"windows.captureAndOcr");const o=await F(e,t,n,r),s=await ke(e,o,n);return{capture:o,ocr:s}}async function ke(e,t,n){const r=await e.request("ocr.recognize",{mimeType:t.mimeType,dataBase64:t.dataBase64,width:t.width,height:t.height},n);return m(r,"ocr.recognize"),r.result??{}}function m(e,t){if(!e.ok)throw new Error(`${e.errorCode||"helper_command_failed"}: ${e.errorSummary||t}`)}function H(e){const t=String(e.appName||"").toLowerCase();return t==="wechat"||t==="weixin"||t==="\u5FAE\u4FE1"}function G(e){return new Promise(t=>setTimeout(t,e))}function L(e,t,n){return e.searchDelayMs===0?0:qe(t,Zt(e,n))}async function S(e,t,n){const r=L(e,t,n);r>0&&await G(r)}function Zt(e,t){return`${e.traceId||""}:${e.binding.conversationDisplayName}:${t}`}async function Qt(e,t){const n=await e.request("keyboard.shortcut",{key:"return",modifiers:[]},t);m(n,"keyboard.shortcut")}async function T(e){if(!e.window.bounds)return;const t=e.observation,n=yn(t?.ocr,t?.capture,e.window);if(n){const r=await e.helper.request("mouse.click",{x:n.x,y:n.y,coordinateSpace:"screen",windowId:e.window.windowId},e.traceId);m(r,"mouse.click"),await Q("jump-latest-settle",`${e.traceId||""}:${e.window.windowId}:jump-latest`)}}async function M(e){const{capture:t,ocr:n}=await j(e.helper,e.window.windowId,e.traceId,e.window.bounds),r=E({capture:t,ocr:n,window:e.window});return r?{ok:!1,reason:r}:O(n,t,e.binding.conversationDisplayName)?{ok:!0,reason:"target-conversation-title-confirmed"}:{ok:!1,reason:"conversation_title_not_confirmed"}}function E(e){const n=(e.ocr.blocks??[]).map(r=>cn(r.text)).filter(Boolean).join("");return/(扫码登录|仅传输文件|重新登录|为了安全|安全验证|登录微信|微信登录|该账号已登录|帐号已登录|账号已登录|当前账号已登录|当前帐号已登录|已登录|进入微信|進入微信)/u.test(n)?Xe:null}function en(e,t,n=!0){const r=n?tn(e.blocks??[],t):[];return r.length?r:e.visibleConversationFingerprints??[]}function tn(e,t){const n=e.map(i=>Se(i)).filter(i=>!!i).filter(i=>i.text.length>=2).filter(i=>i.x>t.width*.08&&i.x<t.width*.38).filter(i=>i.y>t.height*.06&&i.y<t.height*.96).filter(i=>!Me(i.text)),r=new Set;return n.filter(i=>!nn(i,n,t)).sort((i,o)=>i.y-o.y||i.x-o.x).map(i=>{const o=i.text.trim();return{title:o,bbox:{x:Math.max(0,i.x-24),y:Math.max(0,i.y-Math.max(24,i.height)),width:Math.max(120,t.width*.3),height:Math.max(48,i.height+40),coordinateSpace:"screenshotPixel"},fingerprint:o.toLowerCase()}}).filter(i=>{const o=B(i.title);return!o||r.has(o)?!1:(r.add(o),!0)})}function Se(e){const t=e.bbox,n=String(e.text||"").normalize("NFKC").trim(),r=Number(t?.x),i=Number(t?.y),o=Number(t?.width),s=Number(t?.height);return!n||![r,i,o,s].every(Number.isFinite)?null:{text:n,x:r,y:i,width:o,height:s}}function nn(e,t,n){const r=Math.max(36,Math.min(64,n.height*.058));return t.some(i=>i!==e&&i.y<e.y&&e.y-i.y<=r&&Math.abs(i.x-e.x)<=16&&i.height>=e.height*.85)}function Me(e){const t=p(e);return/^(搜索|微信|通讯录|收藏|设置|search)$/iu.test(t)||D(t)||sn(t)||/^包含[::]?/u.test(t)||/搜索网络结果/u.test(t)}function rn(e,t,n){const r=(e.blocks??[]).map(a=>Se(a)).filter(a=>!!a),i=r.filter(a=>D(p(a.text))).sort((a,c)=>a.y-c.y||a.x-c.x),o=["\u7FA4\u804A","GroupChats","\u8054\u7CFB\u4EBA","Contacts"];for(const a of o){const c=i.findIndex(d=>p(d.text)===a);if(c<0)continue;const l=i[c],w=i[c+1]?.y??Number.POSITIVE_INFINITY,u=r.filter(d=>d.y>l.y&&d.y<w).filter(d=>d.x<t.width*.7).filter(d=>d.text.length>=2).filter(d=>!D(p(d.text))).filter(d=>!Te(d,r)).filter(d=>Y(d.text,n)).sort((d,f)=>d.y-f.y||d.x-f.x)[0];if(u)return{bbox:Ne(u,t),reason:"search-result-title"}}const s=r.filter(a=>a.y>t.height*.12&&a.y<t.height*.82).filter(a=>a.x>t.width*.08&&a.x<t.width*.45).filter(a=>a.text.length>=2).filter(a=>!Me(a.text)).filter(a=>!Te(a,r)).filter(a=>Y(a.text,n)).sort((a,c)=>a.y-c.y||a.x-c.x)[0];return y(n)?null:s?{bbox:Ne(s,t),reason:"search-result-title"}:null}function Ne(e,t){return{x:Math.max(0,e.x-24),y:Math.max(0,e.y-12),width:Math.max(e.width+t.width*.18,160),height:Math.max(e.height+28,44),coordinateSpace:"screenshotPixel"}}function D(e){return/^(群聊|联系人|聊天记录|公众号|小程序|GroupChats|Contacts|ChatHistory|OfficialAccounts|MiniPrograms)$/u.test(e)}function on(e){return(e.blocks??[]).some(t=>D(p(t.text)))}function an(e,t){return(e.visibleConversationFingerprints??[]).some(n=>Y(n.title,t))}function p(e){return String(e||"").normalize("NFKC").replace(/[^\p{L}\p{N}_-]/gu,"").trim()}function Te(e,t){return/^包含[::]?/u.test(e.text.trim())?!0:t.some(n=>n!==e&&Math.abs(n.y-e.y)<=Math.max(18,e.height)&&n.x<e.x&&/^包含[::]?/u.test(n.text.trim()))}function sn(e){const t=String(e||"").trim();return!!(/^(星期[一二三四五六日天]|周[一二三四五六日天])\s*\d{1,2}:\d{2}$/u.test(t)||/^\d{1,2}:\d{2}(?::\d{2})?$/u.test(t)||/^\d{4}[-/.年]\d{1,2}(?:[-/.月]\d{1,2}日?)?$/u.test(t)||/^\d{1,2}[-/.月]\d{1,2}日?$/u.test(t))}function cn(e){return String(e||"").normalize("NFKC").replace(/\s+/g,"").trim()}function O(e,t,n){const r=y(n)?B(n):$(n);return r?(e.blocks??[]).some(i=>{const o=y(n)?B(i.text):$(i.text);if(!o||!Pe(o,r))return!1;const s=i.bbox;if(!s)return!1;const a=Number(s.x),c=Number(s.y);if(!Number.isFinite(a)||!Number.isFinite(c))return!1;const l=a>t.width*.32&&a<t.width*.78&&c<t.height*.16,w=a<t.width*.18&&c<t.height*.12;return l||w}):!1}function U(e){if(O(e.ocr,e.capture,e.binding.conversationDisplayName))return!1;const t=(e.ocr.blocks??[]).map(a=>String(a.text||"").normalize("NFKC").replace(/\s+/g," ").trim()).filter(Boolean),n=t.join(`
|
|
1
|
+
import W from"node:fs";import J from"node:path";import{WeChatChannelApiError as Fe}from"./client.js";import{defaultWeChatChannelAttachmentDir as De,resolveVisibleWeChatChannelMedia as Le}from"./media-resolver.js";import{updateWeChatChannelBindingLedger as Oe}from"./ledger.js";import{defaultWeChatChannelVectorStorePath as Ke,loadWeChatChannelVectorStore as $e,saveWeChatChannelVectorStore as Ve,upsertWeChatChannelVectorReferences as ze}from"./vector-store.js";import{normalizeWeChatChannelAttachmentAvailability as Z,normalizeWeChatChannelMessageKind as qe}from"./core/schema.js";import{waitForWeChatChannelPacing as Q,weChatChannelPacingDelayMs as je}from"./pacing.js";import{matchWeChatConversationFingerprints as He}from"./fingerprint.js";import{normalizeWeChatAnchorText as v,weChatTextSimilarity as ee}from"./anchor.js";import{decideWeChatChannelActivityGate as Ge,normalizeWeChatChannelActivitySnapshot as Ue}from"./human-coordination.js";const Ye=3,Xe=5,Je="wechat_login_required",Ze=5500;class N extends Error{reasonCode;stage;action;constructor(t){super(`user_active:${t.reasonCode}:${t.stage}:${t.action}`),this.name="WeChatChannelUserActivityAbort",this.reasonCode=t.reasonCode,this.stage=t.stage,this.action=t.action}}async function Pn(e){return await lt(e.helper,e.activityGuard,e.traceId).withLease("observe","observe-binding",async n=>Qe({...e,helper:n}))}async function Qe(e){const t=e.foregroundMode??"required";let n=await et(e,{foregroundMode:t});if(t!=="background"&&(n=await Ce(e.helper,n,e.traceId)),t==="background"){const{capture:s,ocr:a}=await k({helper:e.helper,window:n,traceId:e.traceId}),c=E({capture:s,ocr:a,window:n});if(c)throw new Error(c);if(!O(a,s,e.binding.conversationDisplayName))throw new Error("conversation_not_visible_background");if(Y({capture:s,ocr:a,binding:e.binding}))throw new Error("wechat_window_obstructed_background");return e.onObservationEvidence?.({window:n,capture:s,ocr:a}),de(e)?le({...e,window:n,capture:s,ocr:a}):z({...e,window:n,capture:s,ocr:a})}const r=await j({helper:e.helper,window:n,binding:e.binding,runtime:e.runtime,api:e.api,workDir:e.workDir,traceId:e.traceId});if(!r.opened){const s=await se({...e,fallback:n,requireTargetConversation:!1,force:!0});if(s.windowId!==n.windowId){n=await Ce(e.helper,s,e.traceId);const a=await j({helper:e.helper,window:n,binding:e.binding,runtime:e.runtime,api:e.api,workDir:e.workDir,traceId:e.traceId});if(!a.opened)throw new Error(a.reason||r.reason||"conversation_not_opened")}else throw new Error(r.reason||"conversation_not_opened")}let{capture:i,ocr:o}=await k({helper:e.helper,window:n,traceId:e.traceId});if(Y({capture:i,ocr:o,binding:e.binding})){n=await qt(e.helper,e.traceId);const s=await j({helper:e.helper,window:n,binding:e.binding,runtime:e.runtime,api:e.api,workDir:e.workDir,traceId:e.traceId});if(!s.opened)throw new Error(s.reason||"wechat_window_obstructed");if({capture:i,ocr:o}=await k({helper:e.helper,window:n,traceId:e.traceId}),Y({capture:i,ocr:o,binding:e.binding}))throw new Error("wechat_window_obstructed")}return e.onObservationEvidence?.({window:n,capture:i,ocr:o}),de(e)?le({...e,window:n,capture:i,ocr:o}):z({...e,window:n,capture:i,ocr:o})}async function et(e,t={}){const n=t.foregroundMode??e.foregroundMode??"required",r=await Vt(e.helper,e.traceId,{foreground:n});return n==="background"?r:se({...e,fallback:r,requireTargetConversation:!1,force:t.forceVision})}const x=new Map;function tt(){return process.env.SHENNIAN_WECHAT_VISION_LAYOUT_REUSE!=="0"}function te(e){if(!tt()||!e.classification||e.classification.windowKind!=="chat_main")return;const t=e.window.windowId;if(!t)return;const n=ae(e.window),r=A(e.classification.layout?.messageInputRect,e.screenshot,e.window,"message-input"),i=A(e.classification.layout?.searchInputRect,e.screenshot,e.window,"search-input");if(!r&&!i)return;const o={windowId:t,boundsKey:n,messageInputPoint:r,searchInputPoint:i,updatedAt:new Date().toISOString()},s=`${e.runtime.runtimeId}:${e.binding.bindingId}:${t}`,a=`${e.runtime.runtimeId}:window:${t}:${n}`;x.set(s,o),x.set(a,o),R(e,s,o),R(e,a,o)}async function Wn(e){const t=await ne(e,"messageInputPoint");if(!t.messageInputPoint)throw new Error("wechat_message_input_not_found:vision_rect_missing");return t.messageInputPoint}async function nt(e){const t=await ne(e,"searchInputPoint");if(!t.searchInputPoint)throw new Error("wechat_search_input_not_found:vision_rect_missing");return t.searchInputPoint}async function ne(e,t){const n=t==="searchInputPoint"?"wechat_search_input":"wechat_message_input";if(!e.api.classifyWindow)throw new Error(`${n}_detector_unavailable`);const r=e.window.windowId,i=ae(e.window),o=`${e.runtime.runtimeId}:${e.binding.bindingId}:${r||"unknown"}`,s=`${e.runtime.runtimeId}:window:${r||"unknown"}:${i}`,a=x.get(o)??x.get(s)??ie(e,o)??ie(e,s);if(a&&a.windowId===r&&a.boundsKey===i&&(!t||a[t]))return x.set(o,a),x.set(s,a),a;const c=e.screenshot??await T(e.helper,r,e.traceId,e.window.bounds),l=await e.api.classifyWindow(e.runtime,e.binding,{screenshot:{mimeType:c.mimeType,dataBase64:c.dataBase64,width:c.width,height:c.height,windowId:r},traceId:e.traceId});if(l.windowKind!=="chat_main")throw new Error(`${n}_not_found:${l.windowKind||"unknown_window"}`);const w=A(l.layout?.messageInputRect,c,e.window,"message-input"),u=A(l.layout?.searchInputRect,c,e.window,"search-input"),d={windowId:r||"",boundsKey:i,messageInputPoint:w,searchInputPoint:u,updatedAt:new Date().toISOString()};return x.set(o,d),x.set(s,d),R(e,o,d),R(e,s,d),d}function re(e){const t=e.workDir;return t?J.join(t,"wechat-channel",e.runtime.runtimeId,"vision-layout-point-cache.json"):null}function ie(e,t){const n=re(e);if(!n)return null;try{const r=JSON.parse(W.readFileSync(n,"utf8"));return rt(r[t])}catch{return null}}function R(e,t,n){const r=re(e);if(r)try{let i={};try{i=JSON.parse(W.readFileSync(r,"utf8"))}catch{i={}}i[t]=n,W.mkdirSync(J.dirname(r),{recursive:!0}),W.writeFileSync(r,`${JSON.stringify(i,null,2)}
|
|
2
|
+
`,"utf8")}catch{}}function rt(e){if(!e||typeof e!="object")return null;const t=e,n=typeof t.windowId=="string"?t.windowId:"",r=typeof t.boundsKey=="string"?t.boundsKey:"";if(!r)return null;const i=oe(t.messageInputPoint??t.point),o=oe(t.searchInputPoint);return{windowId:n,boundsKey:r,messageInputPoint:i,searchInputPoint:o,...typeof t.updatedAt=="string"?{updatedAt:t.updatedAt}:{}}}function oe(e){if(!e||typeof e!="object")return null;const t=e,n=Number(t.x),r=Number(t.y);return!Number.isFinite(n)||!Number.isFinite(r)?null:{x:Math.round(n),y:Math.round(r),coordinateSpace:"screen"}}function ae(e){const t=e.bounds;return[Math.round(Number(t?.x??0)),Math.round(Number(t?.y??0)),Math.round(Number(t?.width??0)),Math.round(Number(t?.height??0))].join(",")}function A(e,t,n,r="message-input"){const i=Number(e?.x),o=Number(e?.y),s=Number(e?.width),a=Number(e?.height);if(![i,o,s,a].every(Number.isFinite)||s<=0||a<=0)return null;const c=e?.coordinateSpace==="screen"?{x:i,y:o,width:s,height:a,coordinateSpace:"screen"}:{x:i/999*t.width,y:o/999*t.height,width:s/999*t.width,height:a/999*t.height,coordinateSpace:"screenshotPixel"},l=it(c,t,n,r);return l?{x:Math.round(l.x),y:Math.round(l.y),coordinateSpace:"screen"}:null}function it(e,t,n,r="message-input"){const i=r==="message-input"?.28:.55,o=ot({x:e.x+e.width*.54,y:e.y+e.height*i,coordinateSpace:e.coordinateSpace},t,n);return o?{x:o.x,y:o.y,coordinateSpace:"screen"}:null}function ot(e,t,n){if(![e.x,e.y].every(Number.isFinite))return null;if(e.coordinateSpace==="screen"||!n.bounds)return{x:e.x,y:e.y};const r=t.width&&n.bounds.width?t.width/n.bounds.width:1,i=t.height&&n.bounds.height?t.height/n.bounds.height:r,o=Math.max(0,(t.width-n.bounds.width*r)/2),s=Math.max(0,(t.height-n.bounds.height*i)/2);return{x:n.bounds.x+(e.x-o)/r,y:n.bounds.y+(e.y-s)/i}}async function se(e){if(!e.api.classifyWindow)throw new Error("wechat_window_classifier_unavailable");const t=await e.helper.request("windows.list",{},e.traceId);m(t,"windows.list");const n=(t.result?.windows??[]).filter(G).filter(s=>s.visible!==!1&&s.minimized!==!0&&!!s.windowId),r=ct(n.length?n:[e.fallback],e.fallback);if(!r.length)throw new Error("wechat_window_not_found");const i=[];for(const s of r)try{const a=await T(e.helper,s.windowId,e.traceId,s.bounds),c=await e.api.classifyWindow(e.runtime,e.binding,{screenshot:{mimeType:a.mimeType,dataBase64:a.dataBase64,width:a.width,height:a.height,windowId:s.windowId},traceId:e.traceId});i.push({window:s,classification:c,screenshot:a,score:dt(c,e.requireTargetConversation===!0)})}catch(a){if(at(a))throw a;i.push({window:s,classification:null,errorSummary:a instanceof Error?a.message:String(a||"window classification failed"),score:-1})}const o=i.filter(s=>s.score>0).sort((s,a)=>a.score-s.score)[0];if(!o){const s=i.map(a=>({windowId:a.window.windowId,appName:a.window.appName,title:a.window.title,score:a.score,errorSummary:a.errorSummary,classification:a.classification?{windowKind:a.classification.windowKind,reasonCode:a.classification.reasonCode,confidence:a.classification.confidence,conversationTitle:a.classification.conversationTitle,isTargetConversation:a.classification.isTargetConversation}:null}));throw new Error(`wechat_chat_main_window_not_found: ${JSON.stringify(s)}`)}return o.screenshot&&te({helper:e.helper,runtime:e.runtime,binding:e.binding,workDir:e.workDir,traceId:e.traceId,window:o.window,classification:o.classification,screenshot:o.screenshot}),o.window}async function Rn(e,t,n){if(e.runtime.policy.platform!=="win32")return;const r=t.filter(i=>{if(i.window.windowId===n.window.windowId||!i.window.windowId)return!1;const o=i.classification?.windowKind;return o==="chat_main"||o==="login"});if(r.length!==0)for(const i of r)try{await e.helper.request("windows.closeWindow",{windowId:i.window.windowId},e.traceId)}catch{}}function at(e){const t=st(e);return t==="insufficient_credits"||t==="entitlement_required"||t==="manual_review_required"||t==="wechat_channel_network_failed"||t==="wechat_channel_invalid_response"}function st(e){if(e instanceof Fe||e&&typeof e=="object"&&typeof e.reasonCode=="string")return e.reasonCode.trim().toLowerCase();const t=e instanceof Error?e.message:String(e||"");return/classify-window (?:network )?failed:\s*([a-z][a-z0-9_]*)/i.exec(t)?.[1]?.trim().toLowerCase()||""}function ct(e,t){const n=[],r=i=>{i?.windowId&&(n.some(o=>o.windowId===i.windowId)||n.push(i))};r(e.find(i=>i.windowId===t.windowId));for(const i of e)r(i);return n}function dt(e,t){if(!e||e.windowKind!=="chat_main")return 0;const n=Number(e.confidence??0);return t&&e.isTargetConversation!==!0?0:100+(e.isTargetConversation?50:0)+Math.round(Math.max(0,Math.min(1,n))*100)}function lt(e,t,n){if(!t)return{helper:e,withLease:async(a,c,l)=>await l(e)};let r=null;const i=a=>{t.onEvent?.({...a,at:new Date().toISOString()})},o=async(a,c,l={})=>{if(r){const u=await e.request("automation.lease.status",{},n),d=u.result??{},f=u.ok&&d.interrupted?ce(d.interruptReason):u.ok?void 0:u.errorCode||"user_activity_unknown";if(i({phase:"lease-status",stage:a,action:c,ok:u.ok===!0&&!d.interrupted,...f?{reasonCode:f}:{}}),!u.ok)throw new N({reasonCode:u.errorCode||"user_activity_unknown",stage:a,action:c});if(d.active===!1||d.leaseId!==r||!d.interrupted)return;throw new N({reasonCode:ce(d.interruptReason),stage:a,action:c})}const w=Date.now()+wt(t.preflightIdleSettleTimeoutMs);for(;;){const u=await e.request("activity.snapshot",{},n);if(!u.ok)throw i({phase:"snapshot",stage:a,action:c,ok:!1,reasonCode:u.errorCode||"user_activity_unknown"}),new N({reasonCode:u.errorCode||"user_activity_unknown",stage:a,action:c});const d=Ge({snapshot:Ue(u.result),stage:a,policy:t.policy});if(i({phase:"snapshot",stage:a,action:c,ok:d.ok,...d.ok?{}:{reasonCode:d.reasonCode,waitMs:d.waitMs}}),d.ok)return;const f=new N({reasonCode:d.reasonCode,stage:a,action:c});if(!l.settle)throw f;const X=w-Date.now();if(X<=0)throw f;await U(Math.max(50,Math.min(d.waitMs,X)))}},s={request:async(a,c,l)=>{const w=ut(a);w&&await o(w.stage,`${a}:before`);const u=await e.request(a,c,l);return w&&u.ok&&await o(w.stage,`${a}:after`),u}};return{helper:s,async withLease(a,c,l){if(await Dt(e,n),await o(a,`${c}:preflight`,{settle:!0}),t.useAutomationLease===!1)return await l(s);const w=await e.request("automation.lease.acquire",{owner:"wechat-channel",purpose:`observe:${c}`,ttlMs:12e4},n);if(r=typeof w.result?.leaseId=="string"?w.result.leaseId:null,i({phase:"lease-acquire",stage:a,action:c,ok:w.ok===!0,...w.ok?{}:{reasonCode:w.errorCode||"user_activity_unknown"}}),!w.ok)throw r=null,new N({reasonCode:w.errorCode||"user_activity_unknown",stage:a,action:c});try{const u=await l(s);return await o(a,`${c}:complete`),u}finally{const u=r;if(r=null,u){const d=await e.request("automation.lease.release",{leaseId:u},n).catch(f=>({ok:!1,errorCode:"automation_lease_release_failed",errorSummary:f instanceof Error?f.message:String(f)}));i({phase:"lease-release",stage:a,action:c,ok:d.ok===!0,...d.ok?{}:{reasonCode:d.errorCode||"automation_lease_release_failed"}})}}}}}function ut(e){return e==="windows.ensureReady"||e==="windows.focus"||e==="wechat.searchConversation"?{stage:"open_conversation"}:e==="keyboard.shortcut"||e==="mouse.click"||e==="mouse.rightClick"||e==="mouse.scroll"||e==="clipboard.snapshot"||e==="clipboard.readAttachment"||e==="menu.pickItem"?{stage:"dangerous_action"}:null}function ce(e){return e==="recent_mouse_activity"||e==="recent_mouse_click"||e==="recent_scroll_activity"||e==="recent_keyboard_activity"||e==="frontmost_app_changed"?e:"user_activity_unknown"}function wt(e){return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:Ze}function de(e){return e.observePipeline==="edge-structure"?!0:e.observePipeline==="server-observe"?!1:!!e.api.structureWindow}async function z(e){const t=await ke(e),n=await e.api.observe(e.runtime,e.binding,{screenshots:[{captureIndex:0,mimeType:t.mimeType,dataBase64:t.dataBase64,width:t.width,height:t.height}],edgeOcrBlocks:e.ocr.blocks??[],visibleConversationFingerprints:e.ocr.visibleConversationFingerprints??[],localLedgerTailAnchors:e.localLedgerTailAnchors??[],traceId:e.traceId}),r=await fe({helper:e.helper,runtime:e.runtime,binding:e.binding,messages:n.observedMessages??[],workDir:e.workDir,attachmentsDir:e.attachmentsDir,window:e.window,screenshot:t,windowId:e.window.windowId,traceId:e.traceId,mediaAnchorText:e.mediaAnchorText});return Pe(r,Ee({ocr:e.ocr,screenshot:t,binding:e.binding,anchors:e.localOutboundEchoAnchors??[]}))}async function le(e){if(!e.api.structureWindow)throw new Error("wechat_structure_window_unavailable");const t=await ke(e);let n;try{n=await e.api.structureWindow(e.runtime,e.binding,{screenshots:[{captureIndex:0,mimeType:t.mimeType,dataBase64:t.dataBase64,width:t.width,height:t.height}],edgeOcrBlocks:e.ocr.blocks??[],visibleConversationFingerprints:e.ocr.visibleConversationFingerprints??[],localLedgerTailAnchors:e.localLedgerTailAnchors??[],traceId:e.traceId})}catch(c){if(ht(c))return z(e);throw c}const r=Ct(n.structuredMessages??n.observedMessages??[]),i=await ft({...e,messages:r,screenshot:t}),o=await fe({helper:e.helper,runtime:e.runtime,binding:e.binding,messages:i.messages,workDir:e.workDir,attachmentsDir:e.attachmentsDir,window:e.window,screenshot:t,windowId:e.window.windowId,traceId:e.traceId,mediaAnchorText:e.mediaAnchorText}),s=Pe(o,Ee({ocr:e.ocr,screenshot:t,binding:e.binding,anchors:e.localOutboundEchoAnchors??[]}));return e.localLedger?Oe({ledger:e.localLedger,bindingId:e.binding.bindingId,observedMessages:s,baselineOnly:e.baselineOnly,vectorReferences:i.vectorReferences}).newMessages:s}function ht(e){return e instanceof Error&&/\bedge_runtime_disabled\b/.test(e.message)}async function ft(e){const t=mt(e.messages);if(!t.length)return{messages:e.messages,vectorReferences:[]};const n=e.api.embedVisual?await gt({...e,seedBlocks:t}):t.filter(s=>h(s.vectorBase64)||h(s.signature));if(!n.length)return{messages:e.messages,vectorReferences:[]};const r=e.vectorStorePath??Ke(e.workDir||process.cwd(),e.runtime.runtimeId),i=$e(r,e.runtime.runtimeId),o=ze({store:i,bindingId:e.binding.bindingId,blocks:n});return o.length?(Ve(r,i),{messages:vt(e.messages,o),vectorReferences:o}):{messages:e.messages,vectorReferences:[]}}function mt(e){const t=[];for(const n of e)for(const[r,i]of(n.visualBlocks??[]).entries()){const o=h(i.blockId)||`${n.stableMessageKey}:visual-${r}`,s=h(i.blockKind)||n.kind||"visual";t.push({...i,stableMessageKey:n.stableMessageKey,blockId:o,blockKind:s,...i.bbox!==void 0?{bbox:i.bbox}:n.bbox!==void 0?{bbox:n.bbox}:{}})}return t}async function bt(e){if(!e.api.embedVisual)return[];const t=await e.api.embedVisual(e.runtime,e.binding,{screenshots:[{captureIndex:0,mimeType:e.screenshot.mimeType,dataBase64:e.screenshot.dataBase64,width:e.screenshot.width,height:e.screenshot.height}],visualBlocks:e.seedBlocks,traceId:e.traceId});return xt(t.visualBlocks??t.embeddedBlocks??[],e.seedBlocks)}async function gt(e){try{return await bt(e)}catch(t){if(yt(t))throw t;return[]}}function yt(e){return!e||typeof e!="object"?!1:e.reasonCode==="insufficient_credits"?!0:e instanceof Error&&/\binsufficient_credits\b/.test(e.message)}function xt(e,t){return e.map((n,r)=>{const i=t[r];return{...n,stableMessageKey:h(n.stableMessageKey)||h(i?.stableMessageKey),blockId:h(n.blockId)||h(i?.blockId),blockKind:h(n.blockKind)||h(i?.blockKind)||"visual",...n.bbox!==void 0?{bbox:n.bbox}:i?.bbox!==void 0?{bbox:i.bbox}:{}}}).filter(n=>h(n.stableMessageKey)&&h(n.blockId))}function vt(e,t){const n=new Map;for(const r of t){const i=n.get(r.stableMessageKey)??[];i.push(r),n.set(r.stableMessageKey,i)}return e.map(r=>{const i=n.get(r.stableMessageKey);return i?.length?{...r,visualBlocks:pt(r,i)}:r})}function pt(e,t){const r=(e.visualBlocks??[]).map((o,s)=>{const a=h(o.blockId)||`${e.stableMessageKey}:visual-${s}`,c=t.find(l=>l.blockId===a);return c?ue(c,o):we(o)}),i=new Set(r.map(o=>o.blockId));for(const o of t)i.has(o.blockId)||r.push(ue(o));return r}function ue(e,t){return{...t?we(t):{},stableMessageKey:e.stableMessageKey,blockId:e.blockId,blockKind:e.blockKind,vectorStoreKey:e.vectorStoreKey,model:e.model,...e.modelVersion!==void 0?{modelVersion:e.modelVersion}:{},dims:e.dims,...e.signature?{signature:e.signature}:{},...e.bbox!==void 0?{bbox:e.bbox}:{}}}function we(e){const{vectorBase64:t,...n}=e;return n}function Ct(e){return e.map((t,n)=>It(t,n)).filter(t=>t!=null)}function It(e,t){if(!b(e))return null;const n=qe(e.kind),r=St(e.senderRole),i=g(e.normalizedText),o=g(e.anchorText)??i??g(e.textExcerpt),s=h(e.stableMessageKey)||_t({message:e,index:t,senderRole:r,kind:n,anchorText:o});return{stableMessageKey:s,senderRole:r,...g(e.senderName)!==null?{senderName:g(e.senderName)}:{},kind:n,...i!==null?{normalizedText:i}:{},...o!==null?{anchorText:o}:{},...I(e,"anchorMetadata")?{anchorMetadata:e.anchorMetadata}:{},...I(e,"neighborContext")?{neighborContext:e.neighborContext}:{},...g(e.textExcerpt)!==null?{textExcerpt:g(e.textExcerpt)}:{},...I(e,"bbox")?{bbox:e.bbox}:{},...I(e,"mediaMetadata")?{mediaMetadata:kt(e.mediaMetadata)}:{},...typeof e.isBaseline=="boolean"?{isBaseline:e.isBaseline}:{},...g(e.deliveryStatus)!==null?{deliveryStatus:g(e.deliveryStatus)??void 0}:{},...g(e.observedAt)!==null?{observedAt:g(e.observedAt)??void 0}:{},...Array.isArray(e.visualBlocks)?{visualBlocks:e.visualBlocks}:{},...o?{}:{anchorText:s}}}function _t(e){const t=b(e.message.bbox)?JSON.stringify(e.message.bbox):"";return`structured-window:${[e.index,e.senderRole,e.kind,e.anchorText||h(e.message.textExcerpt)||"",t].join(":").slice(0,180)}`}function kt(e){if(!b(e))return e;const t={...e};return I(t,"availability")&&(t.availability=Z(t.availability)),b(t.attachment)&&(t.attachment=he(t.attachment)),Array.isArray(t.attachments)&&(t.attachments=t.attachments.map(n=>b(n)?he(n):n)),t}function he(e){const t={...e};return I(t,"availability")&&(t.availability=Z(t.availability)),t}function St(e){return e==="self"||e==="contact"||e==="system"||e==="unknown"?e:"unknown"}async function fe(e){if(e.binding.downloadMedia===!1)return e.messages;const t=e.messages.map((o,s)=>Wt(o,e.screenshot,e.window,Pt(e.messages,s))).filter((o,s)=>Mt(e.messages,s,e.mediaAnchorText)).filter(o=>o!=null);if(!t.length)return e.messages;const n=e.attachmentsDir??De(e.workDir||process.cwd(),e.runtime.runtimeId,e.binding.bindingId),r=await Le({helper:e.helper,candidates:t,attachmentsDir:n,screenshot:e.screenshot,windowId:e.windowId,window:e.window,traceId:e.traceId,platform:e.runtime.policy.platform,stabilityCheck:async()=>{const o=await M({helper:e.helper,window:e.window,binding:e.binding,traceId:e.traceId});return o.ok?{ok:!0}:{ok:!1,reasonCode:o.reason}}});if(!r.length)return e.messages;const i=new Map(r.map(o=>[o.messageKey,o]));return e.messages.map(o=>{const s=i.get(o.stableMessageKey);return s?{...o,mediaMetadata:Rt(o.mediaMetadata,s.attachment,s.reasonCode,s.attemptReasonCodes,s.resolveTrace)}:o})}function Mt(e,t,n){const r=be(n);if(!r)return!0;const i=Nt(r),o=e.map((s,a)=>be(Et(s)).includes(r)?a:-1).filter(s=>s>=0);if(!o.length)return t===Tt(e,i);for(const s of o)if(t>=s&&t<=s+8||t===s-1&&!e.slice(s+1,Math.min(e.length,s+9)).some(me))return!0;return!1}function Nt(e){return e.includes("video")||e.includes("vide0")?"video":e.includes("image")||e.includes("photo")||e.includes("ph0t0")||e.includes("picture")?"image":e.includes("file")||e.includes("document")?"file":null}function Tt(e,t=null){for(let n=e.length-1;n>=0;n-=1)if(me(e[n]))return Bt(e[n],t)?n:-1;return-1}function me(e){if(!e)return!1;const t=String(e.kind||"").toLowerCase(),n=b(e.mediaMetadata)?e.mediaMetadata:{},r=b(n.attachment)?n.attachment:{};return ge(t,n,r)}function Bt(e,t){if(!e||!t)return!0;const n=String(e.kind||"").toLowerCase(),r=b(e.mediaMetadata)?e.mediaMetadata:{},i=b(r.attachment)?r.attachment:{},o=String(i.type||"").toLowerCase(),s=String(i.mimeType||"").toLowerCase(),a=String(i.name||i.localPath||e.anchorText||e.textExcerpt||"").toLowerCase();return t==="video"?n.includes("video")||o==="video"||s.startsWith("video/")||/\.(mp4|mov|m4v|avi|mkv|webm)$/i.test(a):t==="image"?/image|photo|picture/.test(n)||o==="image"||s.startsWith("image/")||/\.(png|jpe?g|gif|webp|heic|tiff?|bmp)$/i.test(a):/file|document/.test(n)||o==="file"||!/image|photo|picture|video/.test(n)&&o!=="image"&&o!=="video"&&!s.startsWith("image/")&&!s.startsWith("video/")}function Et(e){if(!e)return"";const t=e;return[e.normalizedText,e.anchorText,e.textExcerpt,t.text].map(n=>String(n||"")).join(`
|
|
3
|
+
`)}function be(e){return String(e||"").normalize("NFKC").replace(/[o]/giu,"0").replace(/[^\p{L}\p{N}]/gu,"").toLowerCase()}function Pt(e,t){return[e[t-1],e[t],e[t+1]].map(r=>r&&(r.normalizedText||r.anchorText||r.textExcerpt)||"").map(r=>String(r||"").trim()).filter(Boolean).join(`
|
|
4
|
+
`)||null}function Wt(e,t,n,r){const i=String(e.kind||"").toLowerCase(),o=b(e.mediaMetadata)?e.mediaMetadata:{},s=b(o.attachment)?o.attachment:{},a=h(s.availability)||h(o.availability),c=h(s.localPath)||h(o.localPath);if(a==="edge-local"&&c||!ge(i,o,s))return null;const l=F(e.bbox)??F(o.bbox)??F(o.downloadActionBbox),w=F(o.downloadActionBbox),u=ye(l,t,n),d=Ft(l,t,n),f=ye(w,t,n);return{messageKey:e.stableMessageKey,kind:h(s.type)||h(s.kind)||h(o.messageType)||i,fileName:h(s.name)||h(s.fileName)||h(o.fileName)||null,mimeType:h(s.mimeType)||h(o.mimeType)||null,size:_(s.size)??_(o.size),mediaStatus:At(o,s),observedAt:e.observedAt??null,contextText:r??e.normalizedText??e.anchorText??e.textExcerpt??null,...u?{bbox:u}:{},...d?{screenshotBbox:d}:{},...f?{downloadActionBbox:f}:{}}}function Rt(e,t,n,r,i){const o=b(e)?{...e}:{};return{...o,availability:b(t)?t.availability:o.availability,mediaStatus:b(t)&&t.availability==="edge-local"?"downloaded":o.mediaStatus,attachment:t,edgeResolveReasonCode:n,...r?.length?{edgeResolveAttempts:r}:{},...i?{edgeResolveTrace:i}:{}}}function At(e,t){const n=h(e.mediaStatus);if(n==="not_downloaded")return"not_downloaded";if(n==="loading"||n==="downloading"||n==="in_progress")return"loading";if(n==="downloaded"||n==="available")return"available";const r=h(t.availability)||h(e.availability);return r==="pending-download"?"not_downloaded":r==="metadata-only"?"metadata_only":n||null}function ge(e,t,n){const r=`${e} ${h(t.messageType)} ${h(n.type)} ${h(n.kind)}`.toLowerCase();return/image|photo|video|file|document/.test(r)}function F(e){if(!b(e))return null;const t=_(e.x),n=_(e.y),r=_(e.width),i=_(e.height);return t==null||n==null||r==null||i==null?null:{x:t,y:n,width:r,height:i,...typeof e.coordinateSpace=="string"?{coordinateSpace:e.coordinateSpace}:{}}}function ye(e,t,n){if(!e)return null;if(e.coordinateSpace==="screen")return e;const r=K(e,t,n);if(!r)return e;const i=n.bounds;if(!i?.width||!i?.height)return{...e,x:r.x-e.width/2,y:r.y-e.height/2,coordinateSpace:"screen"};const o=i.width/t.width,s=i.height/t.height,a=r.x,c=r.y;return{x:a-e.width*o/2,y:c-e.height*s/2,width:e.width*o,height:e.height*s,coordinateSpace:"screen"}}function Ft(e,t,n){if(!e)return null;if(e.coordinateSpace!=="screen")return{...e,coordinateSpace:"screenshotPixel"};const r=n.bounds;if(!r?.width||!r?.height)return null;const i=t.width/r.width,o=t.height/r.height;return{x:(e.x-r.x)*i,y:(e.y-r.y)*o,width:e.width*i,height:e.height*o,coordinateSpace:"screenshotPixel"}}function b(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function I(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function h(e){return typeof e=="string"?e.trim():""}function g(e){return h(e)||null}function _(e){const t=Number(e);return Number.isFinite(t)?t:null}async function An(e,t){await ve(e,t)}async function Dt(e,t){await xe(e,t)}async function xe(e,t){const n=await e.request("permissions.check",{},t);m(n,"permissions.check");const r=n.result??{};if(Kt(r.platform)){const i=await Lt(e,r,t);if(i==="screen-recording")throw new Error("permission_screen_recording_missing");if(i==="accessibility")throw new Error("permission_accessibility_missing");if(i==="input-monitoring")throw new Error("permission_input_monitoring_missing");if(r.automation===!1)throw new Error("permission_automation_missing")}return r}async function ve(e,t,n={}){const r=await xe(e,t),i=String(r.platform??"").toLowerCase();if(r.wechatRunning===!1)throw new Error("wechat_not_running");if(zt(r))throw new Error("windows_visible_desktop_unavailable");if(r.dpiMappingAvailable===!1||r.displayTopologySupported===!1)throw new Error("dpi_mapping_failed");if(r.wechatMainWindowResponsive===!1)throw new Error("wechat_window_unresponsive");if(r.wechatWindowAvailable===!1&&i!=="win32"&&n.allowUnavailableWindow!==!0)throw new Error("wechat_window_unavailable");return r}async function Lt(e,t,n){const r=Ot(t);if(!r||process.platform!=="darwin")return r;const i=$t(r);try{await e.request(i,{},n)}catch{}return r}function Ot(e){return e.screenRecording===!1?"screen-recording":e.accessibility===!1?"accessibility":e.inputMonitoring===!1?"input-monitoring":null}function Kt(e){const t=String(e||"").toLowerCase();return t?t.includes("darwin")||t.includes("mac"):!0}function $t(e){return e==="screen-recording"?"permissions.requestScreenRecording":e==="accessibility"?"permissions.requestAccessibility":"permissions.requestInputMonitoring"}async function Vt(e,t,n={}){const i=(n.foreground??"required")!=="background",o=await ve(e,t,{allowUnavailableWindow:i});if(String(o.platform??"").toLowerCase()==="win32"){const c=await e.request("windows.ensureReady",{activate:i,allowRecovery:!1,allowLaunch:!1},t);m(c,"windows.ensureReady");const l=c.result;if(!l?.windowId)throw new Error("helper_invalid_response: windows.ensureReady missing WeChat window data");return l}const s=await e.request("windows.ensureReady",{restore:i,focus:i},t);m(s,"windows.ensureReady");const a=s.result;if(!a?.windowId)throw new Error("helper_invalid_response: windows.ensureReady missing WeChat window data");return a}function zt(e){return e.windowsVisibleDesktopAvailable===!1||e.rdpVisibleDesktopAvailable===!1||e.desktopSessionVisible===!1||e.screenLocked===!0||e.rdpDisconnected===!0}function pe(e){const t=e.filter(G),n=t.filter(i=>i.visible!==!1&&i.minimized!==!0);return(n.length?n:t)[0]??null}async function Fn(e,t){let n=await e.request("windows.list",{},t);m(n,"windows.list");let r=n.result?.windows??[],i=pe(r);if(!i)throw new Error("wechat_window_not_found");const o=await e.request("windows.focus",{windowId:i.windowId},t);return m(o,"windows.focus"),await Ie(e,i,t)}async function Ce(e,t,n){if(!t.windowId)throw new Error("wechat_window_not_found");const r=await e.request("windows.focus",{windowId:t.windowId},n);return m(r,"windows.focus"),t}async function qt(e,t){const n=await e.request("windows.list",{},t);m(n,"windows.list");const r=n.result?.windows??[],i=pe(r);if(!i)throw new Error("wechat_window_not_found");const o=await e.request("windows.focus",{windowId:i.windowId},t);return m(o,"windows.focus"),await Ie(e,i,t)}async function Ie(e,t,n){let r;try{r=await e.request("windows.list",{},n)}catch{return t}if(!r.ok)return t;const i=(r.result?.windows??[]).filter(G);return i.find(o=>o.windowId===t.windowId)??i[0]??t}async function q(e){const{capture:t,ocr:n}=e.observation??await k(e),r=E({capture:t,ocr:n,window:e.window});if(r)return{opened:!1,reason:r};const i=He({visibleItems:nn(n,t,e.allowOcrTitleRows!==!1),targets:[{bindingId:e.binding.bindingId,conversationDisplayName:e.binding.conversationDisplayName}]})[0];if(!i)return{opened:!1,reason:"conversation_not_visible"};const o=xn(i.item.bbox,t,e.window);if(!o)return{opened:!1,reason:"conversation_bbox_missing"};const s=await e.helper.request("mouse.click",{x:o.x,y:o.y,coordinateSpace:"screen",windowId:e.window.windowId},e.traceId);return m(s,"mouse.click"),{opened:!0,reason:i.reason}}async function j(e){let t={opened:!1,reason:"conversation_not_opened"};for(let r=0;r<Ye;r+=1){if(t=await jt(e),t.opened||t.reason!=="conversation_title_not_confirmed")return t;await S(e,"open-retry",`retry:${r}`)}const n=await _e(e);return n.opened?{opened:!0,reason:`${n.reason}:final-visible-recovery`}:t}async function jt(e){const t=await k(e),n=E({capture:t.capture,ocr:t.ocr,window:e.window});if(n)return{opened:!1,reason:n};let r=!1;if(O(t.ocr,t.capture,e.binding.conversationDisplayName))return e.settleToBottom===!0&&await B({helper:e.helper,window:e.window,traceId:e.traceId,observation:t}),{opened:!0,reason:"current-conversation-title-confirmed"};if(!r){const u=await q({...e,observation:t});if(u.opened){if(await S(e,"open-click-settle","visible-initial"),(await M(e)).ok)return{opened:!0,reason:u.reason};const f=await _e(e);if(f.opened)return f}}const i=await Jt(e,t.capture);if(!i.ok)return{opened:!1,reason:i.reason};const o=await e.helper.request("wechat.searchConversation",{conversationName:e.binding.conversationDisplayName,windowId:e.window.windowId,waitMs:e.searchDelayMs??D(e,"search-input-settle","search-input"),searchPoint:i.point},e.traceId);m(o,"wechat.searchConversation");const s=await Ht(e);if(s.opened){await S(e,"open-click-settle","search-result-click");const u=await M(e);return u.ok?(e.settleToBottom===!0&&await B({helper:e.helper,window:e.window,traceId:e.traceId}),{opened:!0,reason:s.reason}):{opened:!1,reason:u.reason}}let a=s.observation;const c=y(e.binding.conversationDisplayName)&&s.reason==="search_result_not_visible";if(!y(e.binding.conversationDisplayName)){await Qt(e.helper,e.traceId),await S(e,"open-click-settle","search-return");const u=await M(e);if(u.ok)return e.settleToBottom===!0&&await B({helper:e.helper,window:e.window,traceId:e.traceId}),{opened:!0,reason:u.reason};const d=await e.helper.request("wechat.searchConversation",{conversationName:e.binding.conversationDisplayName,windowId:e.window.windowId,waitMs:e.searchDelayMs??D(e,"search-input-settle","search-input-retry-after-return"),searchPoint:i.point},e.traceId);m(d,"wechat.searchConversation"),a=void 0}const l=await q({...e,...a?{observation:a}:{},allowOcrTitleRows:!c});if(!l.opened)return l;await S(e,"open-click-settle","visible-final");const w=await M(e);return w.ok?(e.settleToBottom===!0&&await B({helper:e.helper,window:e.window,traceId:e.traceId}),{opened:!0,reason:l.reason}):{opened:!1,reason:w.reason}}async function _e(e){const t=await q(e);if(!t.opened)return t;await S(e,"open-click-settle","visible-retry");const n=await M(e);return n.ok?(e.settleToBottom===!0&&await B({helper:e.helper,window:e.window,traceId:e.traceId}),{opened:!0,reason:`${t.reason}:retry-visible-title-confirmed`}):{opened:!1,reason:n.reason}}async function Ht(e){let t;const n=e.searchDelayMs===0?0:D(e,"search-result-probe","search-result-probe"),r=y(e.binding.conversationDisplayName)?Xe:1;for(let i=0;i<r;i+=1){i>0&&n>0&&await U(n);const o=await Gt(e);t=o;const{capture:s,ocr:a}=o,c=E({capture:s,ocr:a,window:e.window});if(c)return{opened:!1,reason:c,observation:o};const l=an(a,s,e.binding.conversationDisplayName);if(!l){if(sn(a)||cn(a,e.binding.conversationDisplayName))break;continue}const w=K(l.bbox,s,Ut(s,e.window));if(!w)return{opened:!1,reason:"search_result_bbox_missing",observation:o};const u=await e.helper.request("mouse.click",{x:w.x,y:w.y,coordinateSpace:"screen",windowId:e.window.windowId},e.traceId);return m(u,"mouse.click"),{opened:!0,reason:l.reason,observation:o}}return{opened:!1,reason:"search_result_not_visible",observation:t}}async function Gt(e){if(e.window.bounds&&y(e.binding.conversationDisplayName)){const t=await e.helper.request("screen.capture",{bounds:e.window.bounds},e.traceId);if(t.ok&&t.result?.dataBase64&&t.result.width&&t.result.height){const n={...t.result,windowId:e.window.windowId,bounds:t.result.bounds??e.window.bounds},r=await Se(e.helper,n,e.traceId);return{capture:n,ocr:r}}t.errorCode&&t.errorCode!=="helper_unknown_command"&&t.errorCode!=="helper_command_unsupported"&&m(t,"screen.capture")}return k(e)}function Ut(e,t){return e.bounds?{...t,bounds:e.bounds}:t}async function k(e){let{capture:t,ocr:n}=await H(e.helper,e.window.windowId,e.traceId,e.window.bounds);return await Yt({helper:e.helper,window:e.window,capture:t,ocr:n,traceId:e.traceId})&&(await Q("preview-dismiss-settle",`${e.traceId||""}:${e.window.windowId}:preview-dismiss`),{capture:t,ocr:n}=await H(e.helper,e.window.windowId,e.traceId,e.window.bounds)),{capture:t,ocr:n}}async function Yt(e){const t=Xt(e.ocr,e.capture,e.window);if(!t)return!1;for(const n of[async()=>e.helper.request("keyboard.shortcut",{key:"escape",modifiers:[]},e.traceId),async()=>e.helper.request("mouse.click",{x:t.x,y:t.y,coordinateSpace:"screen",windowId:e.window.windowId},e.traceId)])if((await n()).ok)return!0;return!1}function Xt(e,t,n){const r=e.blocks??[],i=r.find(c=>{const l=String(c.text||""),w=c.bbox;if(!w)return!1;const u=Number(w.x),d=Number(w.y);return Number.isFinite(u)&&Number.isFinite(d)&&d>t.height*.06&&d<t.height*.22&&u>t.width*.3&&/查看原视频|查看原图|原视频|原图|视频|图片|图像/.test(l)});if(!i)return null;const o=i.bbox,s=Number(o?.y);if(!Number.isFinite(s))return null;const a=r.filter(c=>{const l=String(c.text||"").trim(),w=c.bbox;if(!w||l!=="\xD7")return!1;const u=Number(w.x),d=Number(w.y);return Number.isFinite(u)&&Number.isFinite(d)&&u>t.width*.55&&u<t.width*.9&&Math.abs(d-s)<t.height*.08}).sort((c,l)=>Number(l.bbox?.x??0)-Number(c.bbox?.x??0))[0];return K(a?.bbox,t,n)}async function Jt(e,t){if(!e.runtime||!e.api?.classifyWindow)return{ok:!1,reason:"wechat_search_input_detector_unavailable"};try{return{ok:!0,point:await nt({runtime:e.runtime,binding:e.binding,helper:e.helper,api:e.api,workDir:e.workDir,traceId:e.traceId,window:e.window,...t.dataBase64?{screenshot:t}:{}})}}catch(n){return{ok:!1,reason:n instanceof Error?n.message:"wechat_search_input_not_found"}}}async function T(e,t,n,r){const i=await e.request("windows.capture",{windowId:t,scope:"full-window",...r?{bounds:r}:{}},n);m(i,"windows.capture");const o=i.result;if(!o?.dataBase64||!o.mimeType||!o.width||!o.height)throw new Error("helper_invalid_response: windows.capture missing screenshot data");return o}async function ke(e){return e.capture.dataBase64?e.capture:T(e.helper,e.window.windowId,e.traceId,e.window.bounds)}async function H(e,t,n,r){const i=await e.request("windows.captureAndOcr",{windowId:t,scope:"full-window",...r?{bounds:r}:{}},n);if(i.ok&&i.result?.capture&&i.result?.ocr)return{capture:i.result.capture,ocr:i.result.ocr};!i.ok&&i.errorCode&&i.errorCode!=="helper_unknown_command"&&i.errorCode!=="helper_command_unsupported"&&m(i,"windows.captureAndOcr");const o=await T(e,t,n,r),s=await Se(e,o,n);return{capture:o,ocr:s}}async function Se(e,t,n){const r=await e.request("ocr.recognize",{mimeType:t.mimeType,dataBase64:t.dataBase64,width:t.width,height:t.height},n);return m(r,"ocr.recognize"),r.result??{}}function m(e,t){if(!e.ok)throw new Error(`${e.errorCode||"helper_command_failed"}: ${e.errorSummary||t}`)}function G(e){const t=String(e.appName||"").toLowerCase();return t==="wechat"||t==="weixin"||t==="\u5FAE\u4FE1"}function U(e){return new Promise(t=>setTimeout(t,e))}function D(e,t,n){return e.searchDelayMs===0?0:je(t,Zt(e,n))}async function S(e,t,n){const r=D(e,t,n);r>0&&await U(r)}function Zt(e,t){return`${e.traceId||""}:${e.binding.conversationDisplayName}:${t}`}async function Qt(e,t){const n=await e.request("keyboard.shortcut",{key:"return",modifiers:[]},t);m(n,"keyboard.shortcut")}async function B(e){if(!e.window.bounds)return;const t=e.observation,n=vn(t?.ocr,t?.capture,e.window);if(n){const r=await e.helper.request("mouse.click",{x:n.x,y:n.y,coordinateSpace:"screen",windowId:e.window.windowId},e.traceId);m(r,"mouse.click"),await Q("jump-latest-settle",`${e.traceId||""}:${e.window.windowId}:jump-latest`)}}async function M(e){const{capture:t,ocr:n}=await H(e.helper,e.window.windowId,e.traceId,e.window.bounds),r=E({capture:t,ocr:n,window:e.window});return r?{ok:!1,reason:r}:O(n,t,e.binding.conversationDisplayName)?{ok:!0,reason:"target-conversation-title-confirmed"}:!en(n)&&await tn({...e,capture:t})?{ok:!0,reason:"target-conversation-title-confirmed-by-vision"}:{ok:!1,reason:"conversation_title_not_confirmed"}}function en(e){return(e.blocks??[]).length>0?!0:String(e.text??"").trim().length>0}async function tn(e){if(!e.runtime||!e.api?.classifyWindow)return!1;try{const t=e.capture.dataBase64?e.capture:await T(e.helper,e.window.windowId,e.traceId,e.window.bounds),n=await e.api.classifyWindow(e.runtime,e.binding,{screenshot:{mimeType:t.mimeType,dataBase64:t.dataBase64,width:t.width,height:t.height,windowId:e.window.windowId},traceId:e.traceId});return n.windowKind!=="chat_main"||!(n.isTargetConversation===!0||$(n.conversationTitle,e.binding.conversationDisplayName))?!1:(te({helper:e.helper,runtime:e.runtime,binding:e.binding,workDir:e.workDir,traceId:e.traceId,window:e.window,classification:n,screenshot:t}),!0)}catch{return!1}}function E(e){const n=(e.ocr.blocks??[]).map(r=>ln(r.text)).filter(Boolean).join("");return/(扫码登录|仅传输文件|重新登录|为了安全|安全验证|登录微信|微信登录|该账号已登录|帐号已登录|账号已登录|当前账号已登录|当前帐号已登录|已登录|进入微信|進入微信)/u.test(n)?Je:null}function nn(e,t,n=!0){const r=n?rn(e.blocks??[],t):[];return r.length?r:e.visibleConversationFingerprints??[]}function rn(e,t){const n=e.map(i=>Me(i)).filter(i=>!!i).filter(i=>i.text.length>=2).filter(i=>i.x>t.width*.08&&i.x<t.width*.38).filter(i=>i.y>t.height*.06&&i.y<t.height*.96).filter(i=>!Ne(i.text)),r=new Set;return n.filter(i=>!on(i,n,t)).sort((i,o)=>i.y-o.y||i.x-o.x).map(i=>{const o=i.text.trim();return{title:o,bbox:{x:Math.max(0,i.x-24),y:Math.max(0,i.y-Math.max(24,i.height)),width:Math.max(120,t.width*.3),height:Math.max(48,i.height+40),coordinateSpace:"screenshotPixel"},fingerprint:o.toLowerCase()}}).filter(i=>{const o=P(i.title);return!o||r.has(o)?!1:(r.add(o),!0)})}function Me(e){const t=e.bbox,n=String(e.text||"").normalize("NFKC").trim(),r=Number(t?.x),i=Number(t?.y),o=Number(t?.width),s=Number(t?.height);return!n||![r,i,o,s].every(Number.isFinite)?null:{text:n,x:r,y:i,width:o,height:s}}function on(e,t,n){const r=Math.max(36,Math.min(64,n.height*.058));return t.some(i=>i!==e&&i.y<e.y&&e.y-i.y<=r&&Math.abs(i.x-e.x)<=16&&i.height>=e.height*.85)}function Ne(e){const t=p(e);return/^(搜索|微信|通讯录|收藏|设置|search)$/iu.test(t)||L(t)||dn(t)||/^包含[::]?/u.test(t)||/搜索网络结果/u.test(t)}function an(e,t,n){const r=(e.blocks??[]).map(a=>Me(a)).filter(a=>!!a),i=r.filter(a=>L(p(a.text))).sort((a,c)=>a.y-c.y||a.x-c.x),o=["\u7FA4\u804A","GroupChats","\u8054\u7CFB\u4EBA","Contacts"];for(const a of o){const c=i.findIndex(d=>p(d.text)===a);if(c<0)continue;const l=i[c],w=i[c+1]?.y??Number.POSITIVE_INFINITY,u=r.filter(d=>d.y>l.y&&d.y<w).filter(d=>d.x<t.width*.7).filter(d=>d.text.length>=2).filter(d=>!L(p(d.text))).filter(d=>!Be(d,r)).filter(d=>$(d.text,n)).sort((d,f)=>d.y-f.y||d.x-f.x)[0];if(u)return{bbox:Te(u,t),reason:"search-result-title"}}const s=r.filter(a=>a.y>t.height*.12&&a.y<t.height*.82).filter(a=>a.x>t.width*.08&&a.x<t.width*.45).filter(a=>a.text.length>=2).filter(a=>!Ne(a.text)).filter(a=>!Be(a,r)).filter(a=>$(a.text,n)).sort((a,c)=>a.y-c.y||a.x-c.x)[0];return y(n)?null:s?{bbox:Te(s,t),reason:"search-result-title"}:null}function Te(e,t){return{x:Math.max(0,e.x-24),y:Math.max(0,e.y-12),width:Math.max(e.width+t.width*.18,160),height:Math.max(e.height+28,44),coordinateSpace:"screenshotPixel"}}function L(e){return/^(群聊|联系人|聊天记录|公众号|小程序|GroupChats|Contacts|ChatHistory|OfficialAccounts|MiniPrograms)$/u.test(e)}function sn(e){return(e.blocks??[]).some(t=>L(p(t.text)))}function cn(e,t){return(e.visibleConversationFingerprints??[]).some(n=>$(n.title,t))}function p(e){return String(e||"").normalize("NFKC").replace(/[^\p{L}\p{N}_-]/gu,"").trim()}function Be(e,t){return/^包含[::]?/u.test(e.text.trim())?!0:t.some(n=>n!==e&&Math.abs(n.y-e.y)<=Math.max(18,e.height)&&n.x<e.x&&/^包含[::]?/u.test(n.text.trim()))}function dn(e){const t=String(e||"").trim();return!!(/^(星期[一二三四五六日天]|周[一二三四五六日天])\s*\d{1,2}:\d{2}$/u.test(t)||/^\d{1,2}:\d{2}(?::\d{2})?$/u.test(t)||/^\d{4}[-/.年]\d{1,2}(?:[-/.月]\d{1,2}日?)?$/u.test(t)||/^\d{1,2}[-/.月]\d{1,2}日?$/u.test(t))}function ln(e){return String(e||"").normalize("NFKC").replace(/\s+/g,"").trim()}function O(e,t,n){const r=y(n)?P(n):V(n);return r?(e.blocks??[]).some(i=>{const o=y(n)?P(i.text):V(i.text);if(!o||!We(o,r))return!1;const s=i.bbox;if(!s)return!1;const a=Number(s.x),c=Number(s.y);if(!Number.isFinite(a)||!Number.isFinite(c))return!1;const l=a>t.width*.32&&a<t.width*.78&&c<t.height*.16,w=a<t.width*.18&&c<t.height*.12;return l||w}):!1}function Y(e){if(O(e.ocr,e.capture,e.binding.conversationDisplayName))return!1;const t=(e.ocr.blocks??[]).map(a=>String(a.text||"").normalize("NFKC").replace(/\s+/g," ").trim()).filter(Boolean),n=t.join(`
|
|
5
5
|
`),i=[{pattern:/UTF-?8/iu,source:n},{pattern:/Unix\s*\(LF\)/iu,source:n},{pattern:/纯文本/u,source:n},{pattern:/\d+\s*个字符/u,source:n},{pattern:/\bH1\b/u,source:n},{pattern:/^查看$/u,source:t}].reduce((a,c)=>{const l=Array.isArray(c.source)?c.source.some(w=>c.pattern.test(w)):c.pattern.test(c.source);return a+(l?1:0)},0);if(i>=2)return!0;const o=(e.ocr.blocks??[]).filter(a=>Number(a.bbox?.y)<e.capture.height*.14).map(a=>String(a.text||"")).join(`
|
|
6
|
-
`);return/\.(txt|md|rtf|docx?|pdf)\b/i.test(o)&&i>=1||/\.(png|jpe?g|gif|webp|bmp|heic|mp4|mov|m4v|avi|mkv|webm)\b/i.test(o)&&
|
|
7
|
-
`);if(/\b\d+\s*x\s*\d+\b/i.test(r)&&/\b\d+(\.\d+)?\s*(B|KB|MB|GB)\b/i.test(r)||/\b100%\b/.test(r)&&n.length<=20)return!0;const i=n.filter(o=>!/^(□|×|\+|…|\.\.\.|100%|\d+|发送)$/u.test(o));return e.width>600&&e.height>500&&i.length<=6}function Ee(e){const t=e.anchors.map(o=>({...o,normalized:v(o.expectedEchoAnchor)})).filter(o=>o.normalized);if(!t.length)return[];const n=[],r=new Set,i=
|
|
6
|
+
`);return/\.(txt|md|rtf|docx?|pdf)\b/i.test(o)&&i>=1||/\.(png|jpe?g|gif|webp|bmp|heic|mp4|mov|m4v|avi|mkv|webm)\b/i.test(o)&&un(e.capture,e.ocr)?!0:((e.ocr.visibleConversationFingerprints??[]).some(a=>{const c=y(e.binding.conversationDisplayName)?P(a.title):V(a.title),l=y(e.binding.conversationDisplayName)?P(e.binding.conversationDisplayName):V(e.binding.conversationDisplayName);return!!(c&&l&&We(c,l))}),!1)}function un(e,t){const n=(t.blocks??[]).map(o=>String(o.text||"").normalize("NFKC").trim()).filter(Boolean),r=n.join(`
|
|
7
|
+
`);if(/\b\d+\s*x\s*\d+\b/i.test(r)&&/\b\d+(\.\d+)?\s*(B|KB|MB|GB)\b/i.test(r)||/\b100%\b/.test(r)&&n.length<=20)return!0;const i=n.filter(o=>!/^(□|×|\+|…|\.\.\.|100%|\d+|发送)$/u.test(o));return e.width>600&&e.height>500&&i.length<=6}function Ee(e){const t=e.anchors.map(o=>({...o,normalized:v(o.expectedEchoAnchor)})).filter(o=>o.normalized);if(!t.length)return[];const n=[],r=new Set,i=wn(e.ocr,e.screenshot).sort((o,s)=>v(s.text).length-v(o.text).length);for(const o of i){const s=v(o.text);if(!s)continue;const a=t.find(l=>hn(l.normalized,s));if(!a)continue;const c=`local-outbound-echo:${e.binding.bindingId}:${a.idempotencyKey||a.replyId||a.normalized}`;r.has(c)||(r.add(c),n.push({stableMessageKey:c,senderRole:"self",kind:"text",normalizedText:s,anchorText:s,textExcerpt:o.text.trim(),bbox:o.bbox??null,observedAt:new Date().toISOString(),deliveryStatus:"suppressed"}))}return n}function wn(e,t){const n=(e.blocks??[]).filter(i=>yn(i,t)&&v(i.text)).sort((i,o)=>C(i.bbox,"y")-C(o.bbox,"y")),r=n.map(i=>({text:String(i.text||"").trim(),bbox:i.bbox}));for(let i=0;i<n.length;i+=1){const o=[n[i]];for(let s=i+1;s<n.length&&o.length<5;s+=1){const a=n[s];if(!fn(o[o.length-1],a,t))break;o.push(a),r.push({text:mn(o.map(c=>String(c.text||"").trim())),bbox:gn(o.map(c=>c.bbox))})}}return r}function hn(e,t){if(!e||!t)return!1;if(ee(e,t)>=.88)return!0;const n=e.replace(/\s+/g,""),r=t.replace(/\s+/g,"");return r.length>=8&&n.includes(r)}function fn(e,t,n){const r=C(e.bbox,"x"),i=C(e.bbox,"y"),o=C(e.bbox,"height"),s=C(t.bbox,"x"),a=C(t.bbox,"y");if(![r,i,o,s,a].every(Number.isFinite)||r<n.width*.5||s<n.width*.5)return!1;const c=a-(i+o);return c>=-8&&c<=Math.max(64,n.height*.04)&&Math.abs(s-r)<=120}function mn(e){return e.reduce((t,n)=>t?n?`${t}${bn(t,n)?" ":""}${n}`:t:n,"")}function bn(e,t){return/[A-Za-z0-9]$/u.test(e)&&/^[A-Za-z0-9]/u.test(t)}function gn(e){const t=e.filter(c=>!!c);if(!t.length)return;const n=t.map(c=>Number(c.x)).filter(Number.isFinite),r=t.map(c=>Number(c.y)).filter(Number.isFinite),i=t.map(c=>Number(c.x)+Number(c.width)).filter(Number.isFinite),o=t.map(c=>Number(c.y)+Number(c.height)).filter(Number.isFinite);if(!n.length||!r.length||!i.length||!o.length)return t[0];const s=Math.min(...n),a=Math.min(...r);return{x:s,y:a,width:Math.max(...i)-s,height:Math.max(...o)-a,coordinateSpace:t.find(c=>c.coordinateSpace)?.coordinateSpace}}function C(e,t){const n=Number(e?.[t]);return Number.isFinite(n)?n:Number.NaN}function Pe(e,t){if(!t.length)return e;const n=[...e];for(const r of t){const i=v(r.anchorText||r.normalizedText||r.textExcerpt);n.some(s=>{if(s.senderRole!=="self")return!1;const a=v(s.anchorText||s.normalizedText||s.textExcerpt);return a&&i&&ee(a,i)>=.9})||n.push(r)}return n}function yn(e,t){const n=e.bbox;if(!n)return!1;const r=Number(n.x),i=Number(n.y);return!Number.isFinite(r)||!Number.isFinite(i)?!1:r>t.width*.34&&r<t.width*.96&&i>t.height*.12&&i<t.height*.86}function xn(e,t,n){if(!e||typeof e!="object")return null;const r=e,i=Number(r.x),o=Number(r.y),s=Number(r.width),a=Number(r.height);if(![i,o,s,a].every(Number.isFinite))return null;const c=typeof r.coordinateSpace=="string"?r.coordinateSpace:void 0,l=t.width&&n.bounds?.width?t.width/n.bounds.width:1,w=t.height&&n.bounds?.height?t.height/n.bounds.height:l,u={x:i+Math.min(s*.35,110*l),y:o+Math.min(a-8*w,Math.max(18*w,a/2))};if(c==="screen"||!n.bounds)return u;const d=Math.max(0,(t.width-n.bounds.width*l)/2),f=Math.max(0,(t.height-n.bounds.height*w)/2);return{x:n.bounds.x+(u.x-d)/l,y:n.bounds.y+(u.y-f)/w}}function K(e,t,n){if(!e||typeof e!="object")return null;const r=e,i=Number(r.x),o=Number(r.y),s=Number(r.width),a=Number(r.height);if(![i,o,s,a].every(Number.isFinite))return null;const c=typeof r.coordinateSpace=="string"?r.coordinateSpace:void 0,l={x:i+s/2,y:o+a/2};if(c==="screen"||!n.bounds)return l;const w=t.width&&n.bounds.width?t.width/n.bounds.width:1,u=t.height&&n.bounds.height?t.height/n.bounds.height:w,d=Math.max(0,(t.width-n.bounds.width*w)/2),f=Math.max(0,(t.height-n.bounds.height*u)/2);return{x:n.bounds.x+(l.x-d)/w,y:n.bounds.y+(l.y-f)/u}}function vn(e,t,n){if(!e?.blocks?.length||!t)return null;const r=e.blocks.find(i=>{const o=String(i.text||"").trim(),s=i.bbox;if(!s||!o)return!1;const a=Number(s.x),c=Number(s.y);return!Number.isFinite(a)||!Number.isFinite(c)||!/跳转到最新消息|回到最新消息|jump\s+to\s+latest/i.test(o)?!1:a>t.width*.55&&c>t.height*.45&&c<t.height*.92});return K(r?.bbox,t,n)}function We(e,t){return y(t)?Ae(e,t):e===t||e.includes(t)||t.includes(e)}function $(e,t){if(y(t))return Ae(e,t);const n=Re(p(e)),r=Re(p(t));return!n||!r?!1:n===r?!0:n.replace(/\d+$/u,"")===r}function Re(e){return e.toLowerCase().replace(/[l1]/g,"i")}function V(e){return String(e||"").normalize("NFKC").replace(/[((]\d+[))]/g,"").replace(/\s+/g,"").replace(/[l1]/gi,"i").toLowerCase().trim()}function P(e){return String(e||"").normalize("NFKC").replace(/[((]\d+[))]/g,"").replace(/\s+/g,"").trim()}function y(e){const t=String(e||"").trim();return/^[A-Z0-9_-]{1,6}$/.test(t)&&/[A-Z]/.test(t)}function Ae(e,t){const n=String(e||"").normalize("NFKC").replace(/[((]\d+[))]/g,"").replace(/\s+/g,"").trim(),r=String(t||"").normalize("NFKC").replace(/[((]\d+[))]/g,"").replace(/\s+/g,"").trim();return!!(n&&r&&(n===r||n.replace(/\d+$/u,"")===r))}export{N as WeChatChannelUserActivityAbort,H as captureAndRecognizeWeChatWindow,T as captureWeChatWindow,Wn as detectWeChatMessageInputPointByServerVision,nt as detectWeChatSearchInputPointByServerVision,Dt as ensureHelperPermissionPreflight,An as ensureHelperPreflight,Vt as ensureWeChatWindowReady,qt as focusExistingWeChatWindow,Ce as focusKnownWeChatWindow,Fn as focusWeChatWindow,Pn as observeWeChatChannelBindingViaHelper,j as openConversationBySearch,q as openConversationInVisibleList,Se as recognizeWeChatScreenshot,et as selectWeChatWindowForBinding};
|
|
@@ -39,4 +39,5 @@ export declare class WeChatChannelProductRunner {
|
|
|
39
39
|
private shouldSkipObserveForUnchangedFingerprint;
|
|
40
40
|
}
|
|
41
41
|
export declare function createWeChatChannelProductRunner(options: WeChatChannelProductRunnerOptions): WeChatChannelProductRunner;
|
|
42
|
+
export declare function resolveWeChatOutboundBindingForConversation(runtime: WeChatChannelRuntime, conversationName: string): WeChatChannelBindingConfig;
|
|
42
43
|
export declare function buildLocalLedgerTailAnchors(ledgerPath: string, runtimeId: string, bindingId: string, limit?: number): Array<Record<string, unknown>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import u from"node:path";import h from"node:fs";import{createWeChatChannelApiClient as m}from"./client.js";import{WeChatChannelHelperClient as
|
|
1
|
+
import u from"node:path";import h from"node:fs";import{createWeChatChannelApiClient as m}from"./client.js";import{WeChatChannelHelperClient as g}from"./helper-client.js";import{resolveWeChatChannelHelperAsset as W,WECHAT_CHANNEL_HELPER_VERSION as S}from"./helper-assets.js";import{requiredWindowsWeChatChannelHelperCapabilitiesForProfile as c}from"./helper-protocol.js";import{captureWeChatWindow as I,detectWeChatMessageInputPointByServerVision as P,focusKnownWeChatWindow as w,observeWeChatChannelBindingViaHelper as A,openConversationBySearch as D,recognizeWeChatScreenshot as O,selectWeChatWindowForBinding as C}from"./observer.js";import{WeChatChannelScheduler as F}from"./scheduler.js";import{loadWeChatChannelLedger as M}from"./ledger.js";import{buildWeChatConversationFingerprint as _,matchWeChatConversationFingerprints as T}from"./fingerprint.js";import{WeChatChannelOutboundSender as x}from"./outbound-sender.js";import{SerialWeChatAutomationLane as N}from"./automation-lane.js";import{decideWeChatChannelActivityGate as L,nextWeChatChannelActivityRetryAt as H,normalizeWeChatChannelActivitySnapshot as R}from"./human-coordination.js";const E=120*1e3;class q{options;scheduler;helper;helperStarted=!1;lane;constructor(e){this.options=e;const n=e.api??m();this.helper=e.helper??G(e),this.lane=e.lane??new N,this.scheduler=new F({runtime:e.runtime,workDir:e.workDir,api:n,ledgerPath:e.ledgerPath,outboundLedgerPath:e.outboundLedgerPath,onInboundMessages:e.onInboundMessages,activityGate:{canObserve:async(a,t)=>{if(e.runtime.foregroundPolicy==="work")return{ok:!0};const o=await this.helper.request("activity.snapshot",{});if(!o.ok)return{ok:!1,reasonCode:"user_activity_unknown",nextAttemptAt:new Date(t.getTime()+5e3)};const i=L({snapshot:R(o.result),stage:"observe"});return i.ok?{ok:!0}:{ok:!1,reasonCode:i.reasonCode,nextAttemptAt:H(t,i.waitMs)}}},shouldSkipObserve:(a,t)=>this.shouldSkipObserveForUnchangedFingerprint(a,t.foregroundMode),outboundSender:new x({helper:this.helper,platform:e.runtime.policy.platform,activityGatePolicy:e.runtime.foregroundPolicy==="work"?{mouseMovedThresholdMs:0,mouseClickThresholdMs:0,scrollWheelThresholdMs:0,keyDownThresholdMs:0}:void 0,takeoverCheck:e.runtime.foregroundPolicy!=="work",openConversation:async a=>{const t=B(e.runtime,a),o=await C({runtime:e.runtime,binding:t,helper:this.helper,api:n,workDir:e.workDir}),i=await w(this.helper,o),s=await D({helper:this.helper,window:i,settleToBottom:!1,binding:t,runtime:e.runtime,api:n,workDir:e.workDir});if(!s.opened)return{...s,windowId:i.windowId,inputPoint:null};const l=await P({runtime:e.runtime,binding:t,helper:this.helper,api:n,workDir:e.workDir,window:i});return{...s,windowId:i.windowId,inputPoint:l}}}),observeBinding:(a,t)=>A({runtime:e.runtime,binding:a,helper:this.helper,api:n,workDir:e.workDir,localLedgerTailAnchors:U(e.ledgerPath??z(e.workDir,e.runtime.runtimeId),e.runtime.runtimeId,a.bindingId),localOutboundEchoAnchors:t?.localOutboundEchoAnchors,foregroundMode:t?.foregroundMode,onObservationEvidence:({ocr:o})=>{j({statePath:v(e.workDir,e.runtime.runtimeId),runtimeId:e.runtime.runtimeId,binding:a,ocr:o})}})})}async start(){return this.lane.run("wechat.runner.start",async()=>{await this.ensureHelperStarted(),await this.scheduler.start()})}async tick(e){return this.lane.run("wechat.runner.tick",async()=>(await this.ensureHelperStarted(),this.scheduler.tick(e)))}async stop(){return this.lane.run("wechat.runner.stop",async()=>{await this.scheduler.stop(),this.helperStarted&&this.helper.stop&&await this.helper.stop(),this.helperStarted=!1})}async ensureHelperStarted(){this.helperStarted||(this.helper.start&&await this.helper.start(),this.helperStarted=!0)}async shouldSkipObserveForUnchangedFingerprint(e,n="required"){if(this.options.runtime.policy.platform!=="darwin"&&this.options.runtime.policy.platform!=="win32")return{skip:!1};const a=v(this.options.workDir,this.options.runtime.runtimeId),t=f(a,this.options.runtime.runtimeId).bindings[e.bindingId];if(!t?.fingerprint)return{skip:!1};if(K(t))return{skip:!1};try{const o=this.options.api??m(),i=await C({runtime:this.options.runtime,binding:e,helper:this.helper,api:o,workDir:this.options.workDir},{foregroundMode:n}),s=n==="background"?i:await w(this.helper,i),l=await I(this.helper,s.windowId,void 0,s.bounds),k=await O(this.helper,l),d=y({binding:e,ocr:k,prior:t});return!d?.fingerprint||d.fingerprint!==t.fingerprint?{skip:!1}:{skip:!0,reasonCode:"conversation_fingerprint_unchanged",fingerprint:d.fingerprint}}catch{return{skip:!1}}}}function le(r){return new q(r)}function B(r,e){const n=p(e),a=r.bindings.find(t=>t.enabled!==!1&&t.allowReply!==!1&&p(t.conversationDisplayName)===n)??r.bindings.find(t=>t.enabled!==!1&&p(t.conversationDisplayName)===n);return a||{bindingId:`outbound:${e}`,sessionId:"outbound",conversationDisplayName:e,enabled:!0,allowReply:!0,downloadMedia:!0}}function p(r){return String(r??"").normalize("NFKC").replace(/\s+/g," ").trim()}function U(r,e,n,a=3){return(M(r,e).bindings[n]?.recent??[]).slice(-a).map(i=>({stableMessageKey:i.stableMessageKey,senderRole:i.senderRole,kind:i.kind,anchorText:i.anchorText??i.normalizedText??i.textExcerpt??null,anchorMetadata:i.anchorMetadata??null}))}function G(r){if(r.helperClientOptions)return new g({...r.helperClientOptions,requiredCapabilities:r.helperClientOptions.requiredCapabilities??b(r.runtime),guardUnsafeWindowsCommands:r.helperClientOptions.guardUnsafeWindowsCommands??r.runtime.policy.platform==="win32",skipUserActivityGuard:r.helperClientOptions.skipUserActivityGuard??r.runtime.foregroundPolicy==="work",cleanupWindowsOverlays:r.helperClientOptions.cleanupWindowsOverlays??r.runtime.policy.platform==="win32",requestLogger:r.helperClientOptions.requestLogger??r.helperRequestLogger});const e=W();if(!e.ok)throw new Error(`${e.reasonCode}: ${e.message}`);return new g({helperPath:e.helperPath,expectedHelperVersion:e.version||S,requiredCapabilities:b(r.runtime),guardUnsafeWindowsCommands:r.runtime.policy.platform==="win32",skipUserActivityGuard:r.runtime.foregroundPolicy==="work",cleanupWindowsOverlays:r.runtime.policy.platform==="win32",requestLogger:r.helperRequestLogger})}function b(r){if(r.policy.platform==="win32")return r.bindings.some(e=>e.enabled!==!1&&e.allowReply!==!1)?c("send"):r.bindings.some(e=>e.enabled!==!1&&e.downloadMedia!==!1)?c("download"):c("observe")}function z(r,e){return u.join(r,"wechat-channel",`${e}.ledger.json`)}function v(r,e){return u.join(r,"wechat-channel",`${V(e)}.conversation-fingerprints.json`)}function f(r,e){try{const n=JSON.parse(h.readFileSync(r,"utf8"));if(n?.version===1&&n.runtimeId===e&&n.bindings&&typeof n.bindings=="object")return n}catch{}return{version:1,runtimeId:e,bindings:{}}}function $(r,e){h.mkdirSync(u.dirname(r),{recursive:!0}),h.writeFileSync(r,JSON.stringify(e,null,2))}function j(r){const e=y({binding:r.binding,ocr:r.ocr,prior:f(r.statePath,r.runtimeId).bindings[r.binding.bindingId]});if(!e?.fingerprint)return;const n=f(r.statePath,r.runtimeId);n.bindings[r.binding.bindingId]={bindingId:r.binding.bindingId,fingerprint:e.fingerprint,title:e.item.title??null,preview:e.item.preview??null,timeText:e.item.timeText??null,unreadText:e.item.unreadText??null,observedAt:new Date().toISOString()},$(r.statePath,n)}function K(r){const e=Date.parse(r.observedAt||"");return Number.isFinite(e)?Date.now()-e>=E:!0}function y(r){const e=r.ocr.visibleConversationFingerprints??[],n=T({visibleItems:e,targets:[{bindingId:r.binding.bindingId,conversationDisplayName:r.binding.conversationDisplayName,lastConversationFingerprint:r.prior?.fingerprint,lastPreview:r.prior?.preview??void 0}]})[0];if(!n)return null;const a=_(n.item);return a?{item:n.item,fingerprint:a,reason:n.reason}:null}function V(r){return String(r||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"_").replace(/^_+|_+$/g,"")||"wechat-channel-runtime"}export{E as WECHAT_CHANNEL_UNCHANGED_FINGERPRINT_MAX_SKIP_MS,q as WeChatChannelProductRunner,U as buildLocalLedgerTailAnchors,le as createWeChatChannelProductRunner,B as resolveWeChatOutboundBindingForConversation};
|