diff --git a/lib/index.js b/lib/index.js index e507709..72ac9c7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -338,7 +338,7 @@ ${s.join(` ${i.appendMessage}`:dt(e);return await this.#D(t,a).catch(()=>{}),e}async#V(t,o,i,e){if(e?.code==="turn-stopped"){await this.#Ge(o,i),e?.batchInputMessage&&await this.#D(t.message.chat_id,e.batchInputMessage).catch(()=>{});return}if(this.#S?.aborted){await this.#Ge(o,i);return}let a=Eo(e)??go(e),A=this.#Z(e,{logLabel:"message handling",logLevel:"error",userMessage:a,reason:vi(e)?.reason});await this.#Ae(o,i,"ERROR");let r=e?.batchInputMessage?`${dt(A)} -${e.batchInputMessage}`:dt(A);await this.#D(t.message.chat_id,r).catch(()=>{})}async waitForIdle(){for(;;){let t=[...this.#a.values(),...[...this.#c.values()].flatMap(o=>o.queue?[o.queue]:[]),...this.#n,...this.#g,...this.#l,...this.#J.values(),...[...this.#P.values()].map(o=>o.promise)];if(t.length===0||(await Promise.allSettled(t),this.#a.size===0&&this.#n.size===0&&this.#g.size===0&&this.#l.size===0&&this.#J.size===0&&this.#P.size===0&&![...this.#c.values()].some(o=>o.queue)))return}}#j(){let t=AbortSignal.timeout(this.#G);return this.#S?AbortSignal.any([this.#S,t]):t}#ee(t){return this.#c.has(t)||this.#Q.hasPending(t)}async#Fe(t,o,i,e,a){if(this.#S?.throwIfAborted(),this.#r.hasSeen(o))return;await this.#r.markSeen(o),this.#C.lastMessageAt=new Date().toISOString(),this.#C.messagesReceived+=1;let A=await a(CA(e.content)??"",this.#t,this.#r,i,{signal:this.#S,hasImages:qt(e),hasFiles:Gt(e),pendingInteraction:this.#ee(i),control:{owner:this,key:i}});A?.stopped&&await Promise.allSettled([this.#me(i),this.#Q.closeRoute(i)]);for(let r of A?.messages??[A?.message])r&&await this.#D(t.message.chat_id,r);this.#C.lastError=null}async#Se(t,o,{alreadyRecorded:i=!1}={}){this.#S?.throwIfAborted();let e=t.message.message_id;if(!i){if(this.#r.hasSeen(e))return;await this.#r.markSeen(e),this.#C.lastMessageAt=new Date().toISOString(),this.#C.messagesReceived+=1}let a=Pk(t,this.#e),A=a.content,r=qt(a),s=Gt(a),g=t.message.message_type==="text"&&!r&&!s?A:null;if(!A&&!r&&!s){await this.#D(t.message.chat_id,D("\u76EE\u524D\u652F\u6301\u6587\u5B57\u3001\u56FE\u7247\u548C\u6587\u4EF6\u6D88\u606F\u3002"));return}if(g!==null&&P_e.test(g)){await this.#De(t,g);return}if(g==="/help"){await this.#D(t.message.chat_id,Fz());return}if(v_e.test(g)){await this.#X(o,t.message.chat_id);return}if(g==="/new"){if(this.#a.has(o)||this.#ee(o)){await this.#D(t.message.chat_id,D("\u5F53\u524D\u4EFB\u52A1\u4ECD\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148\u505C\u6B62\u4EFB\u52A1\u6216\u7B49\u5F85\u4EFB\u52A1\u5B8C\u6210\u540E\u518D\u5F00\u542F\u65B0\u4F1A\u8BDD\u3002"));return}await this.#r.clearSession(o),await this.#D(t.message.chat_id,D("\u5DF2\u5F00\u542F\u5168\u65B0 Harness \u4F1A\u8BDD\u3002")),await this.#X(o,t.message.chat_id);return}if(g==="/status"){await this.#Xe(o,t.message.chat_id);return}if(g==="/compact"){let f=await si(g,this.#t,this.#r,o,{signal:this.#S});f&&await this.#D(t.message.chat_id,f.message);return}if(L_e.test(g)){let f=g.slice(12).trim()||null;await this.#ge({chatId:t.message.chat_id,key:o},f,0);return}if(U_e.test(g)){await this.#be({chatId:t.message.chat_id,key:o});return}if(qz.test(g)){let f=(qz.exec(g)?.[1]??"").trim()||null;await this.#he(o,t.message.chat_id,f);return}if(zz.test(g)){let f=(zz.exec(g)?.[1]??"").trim()||null;await this.#Ee(o,t.message.chat_id,f);return}if(F_e.test(g)){await this.#Ce(o,t.message.chat_id);return}if(Wz.test(g)){let Q=Wz.exec(g)[1]?.toLowerCase();if(Q!=="on"&&Q!=="off"){await this.#D(t.message.chat_id,D("\u7528\u6CD5\uFF1A/archived on\uFF08\u5305\u542B\u5F52\u6863\u4F1A\u8BDD\uFF09\u6216 /archived off\uFF08\u9690\u85CF\u5F52\u6863\u4F1A\u8BDD\uFF09"));return}typeof this.#r?.setIncludeArchivedSessions=="function"&&await this.#r.setIncludeArchivedSessions(Q==="on"),await this.#D(t.message.chat_id,Q==="on"?D("\u5DF2\u5F00\u542F\uFF1A\u4F1A\u8BDD\u5217\u8868\u5305\u542B\u5F52\u6863\u4F1A\u8BDD\u3002"):D("\u5DF2\u5173\u95ED\uFF1A\u4F1A\u8BDD\u5217\u8868\u9690\u85CF\u5F52\u6863\u4F1A\u8BDD\u3002"));return}if(H_e.test(g)){let f=this.#Je(o);if(f){await this.#qe(f,Number(g),{chatId:t.message.chat_id,key:o,event:t});return}}let c=g===null?null:await Io(A,this.#t,o);if(c){for(let f of c.messages??[c.message])await this.#D(t.message.chat_id,f);return}let I=g===null?null:await si(g,this.#t,this.#r,o,{signal:this.#S});if(I){await this.#D(t.message.chat_id,I.message);return}this.#w.info?.(`[dsh-feishu] processing ${t.message.chat_type} message ${e}`);let d=t.batchSubmission??null,B=!1;try{let{receipt:f,artifactSendErrors:Q,textDeliveryErrors:y=0}=await this.#IA(t,o,a,{onAskComplete:d?()=>{B=this.#i.complete(o,d.token).completed}:void 0});return this.#C.messagesReplied+=1,this.#C.lastReplyAt=new Date().toISOString(),this.#C.lastError=null,y===0&&Q===0&&oo(this.#C),f}catch(f){if(d&&!B){if(f?.code==="turn-stopped")throw this.#i.complete(o,d.token),f;let Q=this.#i.fail(o,d.token);if(Q.retained){let y=new Error(f?.message??String(f),{cause:f});throw y.code=f?.code,y.providerCode=f?.providerCode,y.method=f?.method,Number.isInteger(f?.status)&&(y.status=f.status),y.batchInputMessage=Q.message,y}}throw f}finally{await this.#me(o),await this.#Q.closeRoute(o)}}async#De(t,o){if(t?.message?.chat_type!=="p2p"){await this.#D(t.message.chat_id,D("\u4E3A\u907F\u514D\u6388\u6743\u94FE\u63A5\u66B4\u9732\uFF0C\u8BF7\u79C1\u804A\u673A\u5668\u4EBA\u53D1\u9001 /repair\u3002"));return}let i=oTe(t);if(!i){await this.#D(t.message.chat_id,D("\u65E0\u6CD5\u8BC6\u522B\u5F53\u524D\u53D1\u9001\u8005\uFF0C\u672A\u53D1\u8D77\u4FEE\u590D\u3002"));return}if(!this.#v){await this.#D(t.message.chat_id,D("\u5F53\u524D Host \u7248\u672C\u6682\u4E0D\u652F\u6301\u804A\u5929\u5185\u4FEE\u590D\uFF0C\u8BF7\u5148\u66F4\u65B0\u63D2\u4EF6\u3002"));return}let e=G_e.exec(o);if(!e){await this.#D(t.message.chat_id,D("\u7528\u6CD5\uFF1A/repair\u3001/repair qr\u3001/repair status\u3001/repair cancel \u6216 /repair verify"));return}let a=e[1]?.toLowerCase()??"start",A=t.message.chat_id;if(a==="start"){await this.#Le({actorOpenId:i,chatId:A});return}let r=this.#T;if(!r){await this.#D(A,D("\u5F53\u524D Runtime \u6CA1\u6709\u53EF\u6062\u590D\u7684\u4FEE\u590D\u4EFB\u52A1\u8BB0\u5F55\uFF08\u673A\u5668\u4EBA\u53EF\u80FD\u521A\u5B8C\u6210\u5BC6\u94A5\u66F4\u65B0\u5E76\u91CD\u542F\uFF09\u3002\u672C\u547D\u4EE4\u4E0D\u4F1A\u542F\u52A8\u65B0\u7684\u6388\u6743\uFF1B\u8BF7\u67E5\u770B\u673A\u5668\u4EBA\u53D1\u9001\u7684\u9A8C\u8BC1\u7ED3\u679C\uFF0C\u786E\u8BA4\u4E0A\u4E00\u6B21\u4EFB\u52A1\u5DF2\u7ED3\u675F\u540E\u518D\u53D1\u9001 /repair\u3002"));return}if(r.actorOpenId!==i){await this.#D(A,D("\u53E6\u4E00\u4F4D\u7528\u6237\u6B63\u5728\u4FEE\u590D\u8BE5\u673A\u5668\u4EBA\uFF0C\u672C\u6B21\u4E0D\u4F1A\u663E\u793A\u5176\u6388\u6743\u4FE1\u606F\u3002"));return}if(a==="cancel"){let g;try{let c=await this.#v.cancel(this.#se(r));g=NC(c,{botId:this.#_}),r.snapshot=g}catch{await this.#D(A,D("\u6682\u65F6\u65E0\u6CD5\u53D6\u6D88\u4FEE\u590D\u4EFB\u52A1\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));return}g.state==="cancelled"&&(r.stopped=!0,this.#F+=1),await this.#D(A,this.#re(g));return}let s;try{s=await this.#le(r)}catch{await this.#D(A,D("\u6682\u65F6\u65E0\u6CD5\u67E5\u8BE2\u4FEE\u590D\u72B6\u6001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));return}if(a==="qr"){if(!Lk.has(s.state)||!r.verificationUrl){await this.#D(A,this.#re(s,{verificationFocused:!0}));return}await this.#xe(A,r.verificationUrl,s);return}await this.#D(A,this.#re(s,{verificationFocused:a==="verify"}))}#se(t){return{botId:this.#_,attemptId:t.attemptId,actorOpenId:t.actorOpenId,chatId:t.chatId}}async#Le({actorOpenId:t,chatId:o}){let i=this.#T,e=!1;if(i&&Lk.has(i.snapshot.state)){if(i.actorOpenId!==t){await this.#D(o,D("\u53E6\u4E00\u4F4D\u7528\u6237\u6B63\u5728\u4FEE\u590D\u8BE5\u673A\u5668\u4EBA\uFF0C\u672C\u6B21\u4E0D\u4F1A\u663E\u793A\u5176\u6388\u6743\u4FE1\u606F\u3002"));return}let r;try{r=await this.#le(i)}catch{await this.#D(o,D("\u6682\u65F6\u65E0\u6CD5\u67E5\u8BE2\u4FEE\u590D\u72B6\u6001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));return}if(r.state==="saving"){await this.#D(o,this.#re(r));return}if(eV.has(r.state)){let s;try{s=NC(await this.#v.cancel(this.#se(i)),{botId:this.#_}),i.snapshot=s}catch{await this.#D(o,D("\u6682\u65F6\u65E0\u6CD5\u53D6\u6D88\u65E7\u4FEE\u590D\u4EFB\u52A1\uFF0C\u672A\u751F\u6210\u65B0\u94FE\u63A5\uFF1B\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));return}if(!Vy.has(s.state)){await this.#D(o,this.#re(s));return}i.stopped=!0,this.#F+=1,e=s.state==="cancelled"}else Vy.has(r.state)&&(i.stopped=!0,this.#F+=1)}let a;try{a=NC(await this.#v.start({botId:this.#_,actorOpenId:t,chatId:o}),{botId:this.#_}),a=await this.#Ue(a,{actorOpenId:t,chatId:o})}catch{await this.#D(o,D("\u4FEE\u590D\u6D41\u7A0B\u6682\u65F6\u5931\u8D25\uFF0C\u73B0\u6709\u673A\u5668\u4EBA\u8FDE\u63A5\u4E0D\u53D7\u5F71\u54CD\uFF1B\u8BF7\u7A0D\u540E\u53D1\u9001 /repair \u91CD\u8BD5\u3002"));return}let A={attemptId:a.attemptId,actorOpenId:t,chatId:o,snapshot:a,verificationUrl:null,stopped:!1,announcedSaving:!1,announcedTerminal:!1};if(this.#T=A,a.verificationUrl)try{A.verificationUrl=$z(a.verificationUrl,this.#R)}catch{A.stopped=!0,await this.#v.cancel(this.#se(A)).catch(()=>{}),await this.#D(o,D("\u98DE\u4E66\u8FD4\u56DE\u4E86\u65E0\u6CD5\u5B89\u5168\u9A8C\u8BC1\u7684\u6388\u6743\u94FE\u63A5\uFF0C\u5DF2\u4E2D\u6B62\u672C\u6B21\u4FEE\u590D\u3002"));return}if(Vy.has(a.state)){A.announcedTerminal=!0,a.state!=="succeeded"&&await this.#D(o,this.#re(a));return}if(!A.verificationUrl){A.stopped=!0,await this.#D(o,D("\u98DE\u4E66\u672A\u8FD4\u56DE\u6388\u6743\u94FE\u63A5\uFF0C\u5DF2\u4E2D\u6B62\u672C\u6B21\u4FEE\u590D\u3002"));return}await this.#Ke(o,A.verificationUrl,a,{restarted:e}),this.#He(A)}async#Ue(t,o){let i=t,e=Date.now()+this.#U;for(;!i.verificationUrl&&Lk.has(i.state);){if(Date.now()>=e)throw new Error("Feishu repair link timed out");await Xz(Math.min(100,this.#O),this.#S),i=NC(await this.#v.status({botId:this.#_,attemptId:i.attemptId,actorOpenId:o.actorOpenId,chatId:o.chatId}),{botId:this.#_})}return i}async#le(t){let o=NC(await this.#v.status(this.#se(t)),{botId:this.#_});if(o.attemptId!==t.attemptId)throw new Error("Feishu repair attempt changed unexpectedly");return t.snapshot=o,o.verificationUrl&&(t.verificationUrl=$z(o.verificationUrl,this.#R)),o}#He(t){let o=++this.#F;(async()=>{for(;!t.stopped&&this.#T===t&&this.#F===o&&!this.#S?.aborted;){let i=Math.max(250,Math.min(1e4,t.snapshot.pollIntervalMs??this.#O));if(await Xz(i,this.#S),t.stopped||this.#T!==t||this.#F!==o)return;let e=await this.#le(t);if(e.state==="saving"&&!t.announcedSaving&&(t.announcedSaving=!0,await this.#D(t.chatId,D("\u6388\u6743\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u53D1\u9001\u5E76\u7B49\u5F85\u6D4B\u8BD5\u6309\u94AE\u56DE\u8C03\uFF1B\u6536\u5230\u771F\u5B9E\u56DE\u8C03\u540E\u624D\u4F1A\u5B8C\u6210\u3002"))),Vy.has(e.state)){t.stopped=!0,e.state!=="succeeded"&&!t.announcedTerminal&&(t.announcedTerminal=!0,await this.#D(t.chatId,this.#re(e)));return}}})().catch(async()=>{this.#S?.aborted||t.stopped||this.#T!==t||(t.stopped=!0,this.#w.warn?.("[dsh-feishu] callback repair status monitoring failed"),await this.#D(t.chatId,D("\u4FEE\u590D\u72B6\u6001\u67E5\u8BE2\u4E2D\u65AD\uFF0C\u73B0\u6709\u673A\u5668\u4EBA\u8FDE\u63A5\u4E0D\u53D7\u5F71\u54CD\uFF1B\u53D1\u9001 /repair status \u91CD\u8BD5\u67E5\u8BE2\u3002")).catch(()=>{}))})}async#Ke(t,o,i,{restarted:e=!1}={}){let a=i.remainingSeconds??(i.expiresAt?Math.max(0,Math.ceil((i.expiresAt-Date.now())/1e3)):null),A=a===null?D("\u94FE\u63A5\u4E3A\u77ED\u671F\u6709\u6548"):D("\u94FE\u63A5\u7EA6 {minutes} \u5206\u949F\u540E\u8FC7\u671F",{minutes:Math.max(1,Math.ceil(a/60))});await this.#D(t,[e?D("\u65E7\u6388\u6743\u94FE\u63A5\u5DF2\u4F5C\u5E9F\uFF0C\u5DF2\u751F\u6210\u65B0\u7684\u4FEE\u590D\u94FE\u63A5\u3002"):D("\u{1F527} \u51C6\u5907\u8865\u5168\u6743\u9650\u4E0E\u56DE\u8C03\u3002"),D("\u672C\u6B21\u6700\u591A\u589E\u91CF\u6DFB\u52A0\u4E09\u9879\uFF1A\u5361\u7247\u56DE\u8C03 card.action.trigger\uFF1B\u98DE\u4E66\u663E\u793A\u4E3A\u201C\u83B7\u53D6\u5355\u804A\u3001\u7FA4\u7EC4\u6D88\u606F\u201D\u7684\u79DF\u6237\u6743\u9650 im:message:readonly\uFF08\u7528\u4E8E\u8BFB\u53D6\u7528\u6237\u6D88\u606F\u4E2D\u7684\u56FE\u7247\u6216\u6587\u4EF6\uFF09\uFF1B\u4EE5\u53CA im:resource\uFF08\u7528\u4E8E\u4E0A\u4F20\u673A\u5668\u4EBA\u53D1\u9001\u7684\u56FE\u7247\u6216\u6587\u4EF6\uFF09\u3002\u786E\u8BA4\u9875\u53EA\u4F1A\u663E\u793A\u5F53\u524D\u7F3A\u5C11\u7684\u9879\uFF1B\u82E5\u51FA\u73B0\u4E0A\u8FF0\u8303\u56F4\u4E4B\u5916\u7684\u914D\u7F6E\uFF0C\u8BF7\u53D6\u6D88\u3002"),"",D("\u5F53\u524D\u8BBE\u5907\u76F4\u63A5\u6253\u5F00\uFF1A"),o,"",D("\u82E5\u8981\u7528\u53E6\u4E00\u53F0\u8BBE\u5907\u626B\u7801\uFF0C\u53D1\u9001 /repair qr\u3002{expiry}\u3002",{expiry:A})].join(` +${e.batchInputMessage}`:dt(A);await this.#D(t.message.chat_id,r).catch(()=>{})}async waitForIdle(){for(;;){let t=[...this.#a.values(),...[...this.#c.values()].flatMap(o=>o.queue?[o.queue]:[]),...this.#n,...this.#g,...this.#l,...this.#J.values(),...[...this.#P.values()].map(o=>o.promise)];if(t.length===0||(await Promise.allSettled(t),this.#a.size===0&&this.#n.size===0&&this.#g.size===0&&this.#l.size===0&&this.#J.size===0&&this.#P.size===0&&![...this.#c.values()].some(o=>o.queue)))return}}#j(){let t=AbortSignal.timeout(this.#G);return this.#S?AbortSignal.any([this.#S,t]):t}#ee(t){return this.#c.has(t)||this.#Q.hasPending(t)}async#Fe(t,o,i,e,a){if(this.#S?.throwIfAborted(),this.#r.hasSeen(o))return;await this.#r.markSeen(o),this.#C.lastMessageAt=new Date().toISOString(),this.#C.messagesReceived+=1;let A=await a(CA(e.content)??"",this.#t,this.#r,i,{signal:this.#S,hasImages:qt(e),hasFiles:Gt(e),pendingInteraction:this.#ee(i),control:{owner:this,key:i}});A?.stopped&&await Promise.allSettled([this.#me(i),this.#Q.closeRoute(i)]);for(let r of A?.messages??[A?.message])r&&await this.#D(t.message.chat_id,r);this.#C.lastError=null}async#Se(t,o,{alreadyRecorded:i=!1}={}){this.#S?.throwIfAborted();let e=t.message.message_id;if(!i){if(this.#r.hasSeen(e))return;await this.#r.markSeen(e),this.#C.lastMessageAt=new Date().toISOString(),this.#C.messagesReceived+=1}let a=Pk(t,this.#e),A=a.content,r=qt(a),s=Gt(a),g=!r&&!s&&A?A.trim():null;if(!A&&!r&&!s){await this.#D(t.message.chat_id,D("\u76EE\u524D\u652F\u6301\u6587\u5B57\u3001\u56FE\u7247\u548C\u6587\u4EF6\u6D88\u606F\u3002"));return}if(g!==null&&P_e.test(g)){await this.#De(t,g);return}if(g==="/help"){await this.#D(t.message.chat_id,Fz());return}if(v_e.test(g)){await this.#X(o,t.message.chat_id);return}if(g==="/new"){if(this.#a.has(o)||this.#ee(o)){await this.#D(t.message.chat_id,D("\u5F53\u524D\u4EFB\u52A1\u4ECD\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148\u505C\u6B62\u4EFB\u52A1\u6216\u7B49\u5F85\u4EFB\u52A1\u5B8C\u6210\u540E\u518D\u5F00\u542F\u65B0\u4F1A\u8BDD\u3002"));return}await this.#r.clearSession(o),await this.#D(t.message.chat_id,D("\u5DF2\u5F00\u542F\u5168\u65B0 Harness \u4F1A\u8BDD\u3002")),await this.#X(o,t.message.chat_id);return}if(g==="/status"){await this.#Xe(o,t.message.chat_id);return}if(g==="/compact"){let f=await si(g,this.#t,this.#r,o,{signal:this.#S});f&&await this.#D(t.message.chat_id,f.message);return}if(L_e.test(g)){let f=g.slice(12).trim()||null;await this.#ge({chatId:t.message.chat_id,key:o},f,0);return}if(U_e.test(g)){await this.#be({chatId:t.message.chat_id,key:o});return}if(qz.test(g)){let f=(qz.exec(g)?.[1]??"").trim()||null;await this.#he(o,t.message.chat_id,f);return}if(zz.test(g)){let f=(zz.exec(g)?.[1]??"").trim()||null;await this.#Ee(o,t.message.chat_id,f);return}if(F_e.test(g)){await this.#Ce(o,t.message.chat_id);return}if(Wz.test(g)){let Q=Wz.exec(g)[1]?.toLowerCase();if(Q!=="on"&&Q!=="off"){await this.#D(t.message.chat_id,D("\u7528\u6CD5\uFF1A/archived on\uFF08\u5305\u542B\u5F52\u6863\u4F1A\u8BDD\uFF09\u6216 /archived off\uFF08\u9690\u85CF\u5F52\u6863\u4F1A\u8BDD\uFF09"));return}typeof this.#r?.setIncludeArchivedSessions=="function"&&await this.#r.setIncludeArchivedSessions(Q==="on"),await this.#D(t.message.chat_id,Q==="on"?D("\u5DF2\u5F00\u542F\uFF1A\u4F1A\u8BDD\u5217\u8868\u5305\u542B\u5F52\u6863\u4F1A\u8BDD\u3002"):D("\u5DF2\u5173\u95ED\uFF1A\u4F1A\u8BDD\u5217\u8868\u9690\u85CF\u5F52\u6863\u4F1A\u8BDD\u3002"));return}if(H_e.test(g)){let f=this.#Je(o);if(f){await this.#qe(f,Number(g),{chatId:t.message.chat_id,key:o,event:t});return}}let c=g===null?null:await Io(A,this.#t,o);if(c){for(let f of c.messages??[c.message])await this.#D(t.message.chat_id,f);return}let I=g===null?null:await si(g,this.#t,this.#r,o,{signal:this.#S});if(I){await this.#D(t.message.chat_id,I.message);return}this.#w.info?.(`[dsh-feishu] processing ${t.message.chat_type} message ${e}`);let d=t.batchSubmission??null,B=!1;try{let{receipt:f,artifactSendErrors:Q,textDeliveryErrors:y=0}=await this.#IA(t,o,a,{onAskComplete:d?()=>{B=this.#i.complete(o,d.token).completed}:void 0});return this.#C.messagesReplied+=1,this.#C.lastReplyAt=new Date().toISOString(),this.#C.lastError=null,y===0&&Q===0&&oo(this.#C),f}catch(f){if(d&&!B){if(f?.code==="turn-stopped")throw this.#i.complete(o,d.token),f;let Q=this.#i.fail(o,d.token);if(Q.retained){let y=new Error(f?.message??String(f),{cause:f});throw y.code=f?.code,y.providerCode=f?.providerCode,y.method=f?.method,Number.isInteger(f?.status)&&(y.status=f.status),y.batchInputMessage=Q.message,y}}throw f}finally{await this.#me(o),await this.#Q.closeRoute(o)}}async#De(t,o){if(t?.message?.chat_type!=="p2p"){await this.#D(t.message.chat_id,D("\u4E3A\u907F\u514D\u6388\u6743\u94FE\u63A5\u66B4\u9732\uFF0C\u8BF7\u79C1\u804A\u673A\u5668\u4EBA\u53D1\u9001 /repair\u3002"));return}let i=oTe(t);if(!i){await this.#D(t.message.chat_id,D("\u65E0\u6CD5\u8BC6\u522B\u5F53\u524D\u53D1\u9001\u8005\uFF0C\u672A\u53D1\u8D77\u4FEE\u590D\u3002"));return}if(!this.#v){await this.#D(t.message.chat_id,D("\u5F53\u524D Host \u7248\u672C\u6682\u4E0D\u652F\u6301\u804A\u5929\u5185\u4FEE\u590D\uFF0C\u8BF7\u5148\u66F4\u65B0\u63D2\u4EF6\u3002"));return}let e=G_e.exec(o);if(!e){await this.#D(t.message.chat_id,D("\u7528\u6CD5\uFF1A/repair\u3001/repair qr\u3001/repair status\u3001/repair cancel \u6216 /repair verify"));return}let a=e[1]?.toLowerCase()??"start",A=t.message.chat_id;if(a==="start"){await this.#Le({actorOpenId:i,chatId:A});return}let r=this.#T;if(!r){await this.#D(A,D("\u5F53\u524D Runtime \u6CA1\u6709\u53EF\u6062\u590D\u7684\u4FEE\u590D\u4EFB\u52A1\u8BB0\u5F55\uFF08\u673A\u5668\u4EBA\u53EF\u80FD\u521A\u5B8C\u6210\u5BC6\u94A5\u66F4\u65B0\u5E76\u91CD\u542F\uFF09\u3002\u672C\u547D\u4EE4\u4E0D\u4F1A\u542F\u52A8\u65B0\u7684\u6388\u6743\uFF1B\u8BF7\u67E5\u770B\u673A\u5668\u4EBA\u53D1\u9001\u7684\u9A8C\u8BC1\u7ED3\u679C\uFF0C\u786E\u8BA4\u4E0A\u4E00\u6B21\u4EFB\u52A1\u5DF2\u7ED3\u675F\u540E\u518D\u53D1\u9001 /repair\u3002"));return}if(r.actorOpenId!==i){await this.#D(A,D("\u53E6\u4E00\u4F4D\u7528\u6237\u6B63\u5728\u4FEE\u590D\u8BE5\u673A\u5668\u4EBA\uFF0C\u672C\u6B21\u4E0D\u4F1A\u663E\u793A\u5176\u6388\u6743\u4FE1\u606F\u3002"));return}if(a==="cancel"){let g;try{let c=await this.#v.cancel(this.#se(r));g=NC(c,{botId:this.#_}),r.snapshot=g}catch{await this.#D(A,D("\u6682\u65F6\u65E0\u6CD5\u53D6\u6D88\u4FEE\u590D\u4EFB\u52A1\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));return}g.state==="cancelled"&&(r.stopped=!0,this.#F+=1),await this.#D(A,this.#re(g));return}let s;try{s=await this.#le(r)}catch{await this.#D(A,D("\u6682\u65F6\u65E0\u6CD5\u67E5\u8BE2\u4FEE\u590D\u72B6\u6001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));return}if(a==="qr"){if(!Lk.has(s.state)||!r.verificationUrl){await this.#D(A,this.#re(s,{verificationFocused:!0}));return}await this.#xe(A,r.verificationUrl,s);return}await this.#D(A,this.#re(s,{verificationFocused:a==="verify"}))}#se(t){return{botId:this.#_,attemptId:t.attemptId,actorOpenId:t.actorOpenId,chatId:t.chatId}}async#Le({actorOpenId:t,chatId:o}){let i=this.#T,e=!1;if(i&&Lk.has(i.snapshot.state)){if(i.actorOpenId!==t){await this.#D(o,D("\u53E6\u4E00\u4F4D\u7528\u6237\u6B63\u5728\u4FEE\u590D\u8BE5\u673A\u5668\u4EBA\uFF0C\u672C\u6B21\u4E0D\u4F1A\u663E\u793A\u5176\u6388\u6743\u4FE1\u606F\u3002"));return}let r;try{r=await this.#le(i)}catch{await this.#D(o,D("\u6682\u65F6\u65E0\u6CD5\u67E5\u8BE2\u4FEE\u590D\u72B6\u6001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));return}if(r.state==="saving"){await this.#D(o,this.#re(r));return}if(eV.has(r.state)){let s;try{s=NC(await this.#v.cancel(this.#se(i)),{botId:this.#_}),i.snapshot=s}catch{await this.#D(o,D("\u6682\u65F6\u65E0\u6CD5\u53D6\u6D88\u65E7\u4FEE\u590D\u4EFB\u52A1\uFF0C\u672A\u751F\u6210\u65B0\u94FE\u63A5\uFF1B\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));return}if(!Vy.has(s.state)){await this.#D(o,this.#re(s));return}i.stopped=!0,this.#F+=1,e=s.state==="cancelled"}else Vy.has(r.state)&&(i.stopped=!0,this.#F+=1)}let a;try{a=NC(await this.#v.start({botId:this.#_,actorOpenId:t,chatId:o}),{botId:this.#_}),a=await this.#Ue(a,{actorOpenId:t,chatId:o})}catch{await this.#D(o,D("\u4FEE\u590D\u6D41\u7A0B\u6682\u65F6\u5931\u8D25\uFF0C\u73B0\u6709\u673A\u5668\u4EBA\u8FDE\u63A5\u4E0D\u53D7\u5F71\u54CD\uFF1B\u8BF7\u7A0D\u540E\u53D1\u9001 /repair \u91CD\u8BD5\u3002"));return}let A={attemptId:a.attemptId,actorOpenId:t,chatId:o,snapshot:a,verificationUrl:null,stopped:!1,announcedSaving:!1,announcedTerminal:!1};if(this.#T=A,a.verificationUrl)try{A.verificationUrl=$z(a.verificationUrl,this.#R)}catch{A.stopped=!0,await this.#v.cancel(this.#se(A)).catch(()=>{}),await this.#D(o,D("\u98DE\u4E66\u8FD4\u56DE\u4E86\u65E0\u6CD5\u5B89\u5168\u9A8C\u8BC1\u7684\u6388\u6743\u94FE\u63A5\uFF0C\u5DF2\u4E2D\u6B62\u672C\u6B21\u4FEE\u590D\u3002"));return}if(Vy.has(a.state)){A.announcedTerminal=!0,a.state!=="succeeded"&&await this.#D(o,this.#re(a));return}if(!A.verificationUrl){A.stopped=!0,await this.#D(o,D("\u98DE\u4E66\u672A\u8FD4\u56DE\u6388\u6743\u94FE\u63A5\uFF0C\u5DF2\u4E2D\u6B62\u672C\u6B21\u4FEE\u590D\u3002"));return}await this.#Ke(o,A.verificationUrl,a,{restarted:e}),this.#He(A)}async#Ue(t,o){let i=t,e=Date.now()+this.#U;for(;!i.verificationUrl&&Lk.has(i.state);){if(Date.now()>=e)throw new Error("Feishu repair link timed out");await Xz(Math.min(100,this.#O),this.#S),i=NC(await this.#v.status({botId:this.#_,attemptId:i.attemptId,actorOpenId:o.actorOpenId,chatId:o.chatId}),{botId:this.#_})}return i}async#le(t){let o=NC(await this.#v.status(this.#se(t)),{botId:this.#_});if(o.attemptId!==t.attemptId)throw new Error("Feishu repair attempt changed unexpectedly");return t.snapshot=o,o.verificationUrl&&(t.verificationUrl=$z(o.verificationUrl,this.#R)),o}#He(t){let o=++this.#F;(async()=>{for(;!t.stopped&&this.#T===t&&this.#F===o&&!this.#S?.aborted;){let i=Math.max(250,Math.min(1e4,t.snapshot.pollIntervalMs??this.#O));if(await Xz(i,this.#S),t.stopped||this.#T!==t||this.#F!==o)return;let e=await this.#le(t);if(e.state==="saving"&&!t.announcedSaving&&(t.announcedSaving=!0,await this.#D(t.chatId,D("\u6388\u6743\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u53D1\u9001\u5E76\u7B49\u5F85\u6D4B\u8BD5\u6309\u94AE\u56DE\u8C03\uFF1B\u6536\u5230\u771F\u5B9E\u56DE\u8C03\u540E\u624D\u4F1A\u5B8C\u6210\u3002"))),Vy.has(e.state)){t.stopped=!0,e.state!=="succeeded"&&!t.announcedTerminal&&(t.announcedTerminal=!0,await this.#D(t.chatId,this.#re(e)));return}}})().catch(async()=>{this.#S?.aborted||t.stopped||this.#T!==t||(t.stopped=!0,this.#w.warn?.("[dsh-feishu] callback repair status monitoring failed"),await this.#D(t.chatId,D("\u4FEE\u590D\u72B6\u6001\u67E5\u8BE2\u4E2D\u65AD\uFF0C\u73B0\u6709\u673A\u5668\u4EBA\u8FDE\u63A5\u4E0D\u53D7\u5F71\u54CD\uFF1B\u53D1\u9001 /repair status \u91CD\u8BD5\u67E5\u8BE2\u3002")).catch(()=>{}))})}async#Ke(t,o,i,{restarted:e=!1}={}){let a=i.remainingSeconds??(i.expiresAt?Math.max(0,Math.ceil((i.expiresAt-Date.now())/1e3)):null),A=a===null?D("\u94FE\u63A5\u4E3A\u77ED\u671F\u6709\u6548"):D("\u94FE\u63A5\u7EA6 {minutes} \u5206\u949F\u540E\u8FC7\u671F",{minutes:Math.max(1,Math.ceil(a/60))});await this.#D(t,[e?D("\u65E7\u6388\u6743\u94FE\u63A5\u5DF2\u4F5C\u5E9F\uFF0C\u5DF2\u751F\u6210\u65B0\u7684\u4FEE\u590D\u94FE\u63A5\u3002"):D("\u{1F527} \u51C6\u5907\u8865\u5168\u6743\u9650\u4E0E\u56DE\u8C03\u3002"),D("\u672C\u6B21\u6700\u591A\u589E\u91CF\u6DFB\u52A0\u4E09\u9879\uFF1A\u5361\u7247\u56DE\u8C03 card.action.trigger\uFF1B\u98DE\u4E66\u663E\u793A\u4E3A\u201C\u83B7\u53D6\u5355\u804A\u3001\u7FA4\u7EC4\u6D88\u606F\u201D\u7684\u79DF\u6237\u6743\u9650 im:message:readonly\uFF08\u7528\u4E8E\u8BFB\u53D6\u7528\u6237\u6D88\u606F\u4E2D\u7684\u56FE\u7247\u6216\u6587\u4EF6\uFF09\uFF1B\u4EE5\u53CA im:resource\uFF08\u7528\u4E8E\u4E0A\u4F20\u673A\u5668\u4EBA\u53D1\u9001\u7684\u56FE\u7247\u6216\u6587\u4EF6\uFF09\u3002\u786E\u8BA4\u9875\u53EA\u4F1A\u663E\u793A\u5F53\u524D\u7F3A\u5C11\u7684\u9879\uFF1B\u82E5\u51FA\u73B0\u4E0A\u8FF0\u8303\u56F4\u4E4B\u5916\u7684\u914D\u7F6E\uFF0C\u8BF7\u53D6\u6D88\u3002"),"",D("\u5F53\u524D\u8BBE\u5907\u76F4\u63A5\u6253\u5F00\uFF1A"),o,"",D("\u82E5\u8981\u7528\u53E6\u4E00\u53F0\u8BBE\u5907\u626B\u7801\uFF0C\u53D1\u9001 /repair qr\u3002{expiry}\u3002",{expiry:A})].join(` `))}async#xe(t,o,i){try{let e=await R_e.toBuffer(o,{errorCorrectionLevel:"M",margin:1,width:480,type:"png"}),a=await this.#e.im.v1.image.create({data:{image_type:"message",image:e}}),A=CA(a?.image_key)??CA(a?.data?.image_key);if(!A)throw new Error("Feishu QR upload returned no image key");let r=i.remainingSeconds??(i.expiresAt?Math.max(0,Math.ceil((i.expiresAt-Date.now())/1e3)):null),s=r===null?"":D("\uFF08\u5269\u4F59\u7EA6 {minutes} \u5206\u949F\uFF09",{minutes:Math.max(1,Math.ceil(r/60))});await this.#D(t,D("\u8BF7\u7528\u53E6\u4E00\u53F0\u8BBE\u5907\u626B\u7801\u5B8C\u6210\u6388\u6743{remaining}\u3002",{remaining:s}));let g=await this.#e.im.v1.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:t,msg_type:"image",content:JSON.stringify({image_key:A})}});if(g?.code&&g.code!==0)throw new Error("Feishu QR message send failed")}catch{await this.#D(t,D(`\u4E8C\u7EF4\u7801\u6682\u65F6\u65E0\u6CD5\u53D1\u9001\uFF0C\u8BF7\u76F4\u63A5\u6253\u5F00\u6388\u6743\u94FE\u63A5\uFF1A {url}`,{url:o}))}}#re(t,{verificationFocused:o=!1}={}){if(t.state==="succeeded")return D("\u2705 \u4FEE\u590D\u5B8C\u6210\uFF1A\u5DF2\u5B9E\u6D4B\u6536\u5230 card.action.trigger\uFF0C\u83DC\u5355\u6309\u94AE\u73B0\u5728\u53EF\u7528\u3002");if(t.state==="expired"||t.error?.code==="expired_token")return D("\u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F\uFF1B\u5E73\u53F0\u672A\u8FD4\u56DE\u6210\u529F\u7ED3\u679C\uFF0C\u65E0\u6CD5\u786E\u8BA4\u5DF2\u4FEE\u590D\u3002\u53D1\u9001 /repair \u751F\u6210\u65B0\u94FE\u63A5\u3002");if(t.state==="cancelled"||t.error?.code==="abort")return D("\u5DF2\u53D6\u6D88\u672C\u6B21\u4FEE\u590D\u6388\u6743\uFF0C\u672A\u786E\u8BA4\u5B8C\u6210\u4FEE\u590D\u3002");if(t.error?.code==="access_denied")return D("\u4F60\u5DF2\u53D6\u6D88\u6216\u62D2\u7EDD\u6388\u6743\uFF0C\u6CA1\u6709\u786E\u8BA4\u4FEE\u590D\uFF1B\u53D1\u9001 /repair \u53EF\u91CD\u8BD5\u3002");if(t.error?.code==="card_action_probe_timeout"||t.error?.code==="card-action-probe-timeout")return D("\u6388\u6743\u5DF2\u63D0\u4EA4\uFF0C\u4F46\u672A\u6536\u5230\u6D4B\u8BD5\u6309\u94AE\u56DE\u8C03\u3002\u53EF\u80FD\u5C1A\u672A\u70B9\u51FB\u6216\u914D\u7F6E\u4ECD\u5728\u4F20\u64AD\uFF1B\u7A0D\u540E\u53D1\u9001 /repair verify \u67E5\u8BE2\uFF0C\u4E0D\u8981\u76F2\u76EE\u91CD\u590D\u6388\u6743\u3002");if(t.state==="error")return D("\u4FEE\u590D\u6D41\u7A0B\u6682\u65F6\u5931\u8D25\uFF0C\u73B0\u6709\u673A\u5668\u4EBA\u8FDE\u63A5\u4E0D\u53D7\u5F71\u54CD\uFF1B\u53D1\u9001 /repair \u53EF\u91CD\u8BD5\u3002");if(t.state==="saving")return D("\u6388\u6743\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u7B49\u5F85\u4E13\u7528\u6D4B\u8BD5\u6309\u94AE\u7684\u771F\u5B9E\u56DE\u8C03\uFF1B\u56DE\u8C03\u5230\u8FBE\u524D\u4E0D\u4F1A\u5BA3\u544A\u6210\u529F\u3002");if(o)return D("\u6388\u6743\u5C1A\u672A\u5B8C\u6210\uFF0C\u6682\u65F6\u4E0D\u80FD\u9A8C\u8BC1\u5361\u7247\u6309\u94AE\u3002\u8BF7\u5148\u6253\u5F00\u6388\u6743\u94FE\u63A5\u5E76\u786E\u8BA4\u3002");let i=t.remainingSeconds===null?"":D("\uFF0C\u5269\u4F59\u7EA6 {minutes} \u5206\u949F",{minutes:Math.max(1,Math.ceil(t.remainingSeconds/60))});return D("\u4FEE\u590D\u4EFB\u52A1\u6B63\u5728\u7B49\u5F85\u6388\u6743{remaining}\u3002\u53D1\u9001 /repair qr \u53EF\u83B7\u53D6\u4E8C\u7EF4\u7801\uFF0C/repair cancel \u53EF\u53D6\u6D88\u3002",{remaining:i})}onCardAction(t){let o=CA(t?.operator?.open_id)??CA(t?.operator?.user_id)??CA(t?.operator?.operator_id?.open_id)??CA(t?.operator?.operator_id?.user_id)??CA(t?.open_id)??CA(t?.user_id);if(!(o!==null&&(this.#b.has("*")||this.#b.has(o))))return this.#w.warn?.("[dsh-feishu] ignoring card action from an unallowed sender"),Promise.resolve();let e=Zz(t?.action?.value),a=Zz(t?.action?.form_value),A=CA(e.action)??CA(t?.action?.action);if(!A)return Promise.resolve();let r=RC(t?.action?.option)??(A.endsWith("_pick")?Xs(t?.action?.options)[0]:null),s=[...new Set([...Xs(e.options),...Xs(t?.action?.options),...Xs(a[A]),...A==="watch_add"||A==="watch_remove"?Xs(t?.action?.option):[]])],g=A==="workspace_pick"&&typeof r=="string"?`workspace:${r}`:A==="session_pick"&&typeof r=="string"?`use:${r}`:A==="preset_pick"&&typeof r=="string"?`preset:select:${r}`:A==="model_pick"&&typeof r=="string"?`model:select:${r}`:A==="archive_pick"&&typeof r=="string"?`archive:${r}`:A==="steer_pick"&&typeof r=="string"?`steer:${r}`:A,c=CA(t?.context?.open_message_id)??CA(t?.open_message_id)??CA(t?.message_id),I=c?this.#Y.get(c):null;if(!I){let Y=CA(t?.context?.open_chat_id)??CA(t?.open_chat_id)??CA(t?.chat_id);return Y&&this.#D(Y,D("\u8FD9\u4E2A\u83DC\u5355\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u56DE\u590D /m \u91CD\u65B0\u6253\u5F00\u3002")).catch(()=>{}),Promise.resolve()}this.#Y.delete(c),this.#Y.set(c,I);let d={...I,messageId:c,selections:s,operatorOpenId:o},B=CA(e.source),f=CA(a.steer_text),Q=CA(t?.event_id)??CA(t?.header?.event_id)??CA(t?.uuid)??CA(t?.header?.uuid),y=JSON.stringify({messageId:c,resolvedAction:g,option:r,multiValues:s,source:B,formText:f}),m=g==="stop",_=g.startsWith("steer:")?g.slice(6):null,G=A==="steer"&&B==="quick"&&r!==null&&r!==_C||A==="steer"&&B==="form"&&f!==null||_!==null&&_!==""&&!(_==="custom"||_===_C);return this.#je(d,y,async()=>{if(A==="steer"){if(B==="quick"&&r){if(r===_C){await this.#W(d.chatId,Gk(),{key:d.key,updateMessageId:d.messageId});return}await this.#pe(d,r);return}if(B==="form"){if(f){await this.#pe(d,f);return}await this.#D(d.chatId,D("\u8BF7\u8F93\u5165\u8865\u5145\u6307\u4EE4\u540E\u518D\u63D0\u4EA4\u3002"));return}}await this.#ae(g,d)},{lane:m||G?"control":"regular",coalesceStop:m,eventId:Q,operatorOpenId:o})}#we(t=Date.now()){for(let[o,i]of this.#m)i<=t&&this.#m.delete(o);for(;this.#m.size>Vz;){let o=this.#m.keys().next().value;if(o===void 0)break;this.#m.delete(o)}}#Oe(t,o=Date.now()){t&&(this.#m.delete(t),this.#m.set(t,o+J_e),this.#we(o))}#Ye(t){let o=t.key,i=Date.now(),e=this.#y.get(o);if(e?.task||e&&i-e.at{}).finally(()=>{this.#l.delete(a);let A=this.#y.get(o);A?.task===a&&this.#y.set(o,{at:A.at,task:null})}),this.#y.delete(o),this.#y.set(o,{at:i,task:a}),this.#l.add(a);this.#y.size>200;){let A=this.#y.keys().next().value;if(A===void 0)break;this.#y.delete(A)}return a}#je(t,o,i,{lane:e="regular",coalesceStop:a=!1,eventId:A=null,operatorOpenId:r=null}={}){let s=t.key,g=A?`${s}\0${r??""}\0event:${A}`:null,c=g??`${s}\0${r??""}\0action:${o}`,I=Date.now();if(this.#we(I),g&&(this.#m.get(g)??0)>I)return Promise.resolve();let d=this.#u.get(c);if(d)return d;if(a){let j=this.#B.get(s);if(j){if(g)for(this.#f.delete(g),this.#f.set(g,j);this.#f.size>Vz;){let H=this.#f.keys().next().value;if(H===void 0)break;this.#f.delete(H)}return j}}let B=e==="control",f=B?this.#d:this.#p,Q=B?this.#E:this.#h,y=B?j_e:Y_e,m=Q.get(s)??0,_=a?y+1:y;if(m>=_)return this.#Ye(t);let N=f.get(s)??Promise.resolve();Q.set(s,m+1);let G,Y=!1;return G=N.catch(()=>{}).then(async()=>{this.#S?.throwIfAborted(),Y=!0,await i()}).catch(async j=>{this.#S?.aborted||await this.#x(t.chatId,j,{logLabel:"card action"})}).finally(()=>{if(this.#u.get(c)===G&&this.#u.delete(c),Y&&g&&this.#Oe(g),a&&this.#B.get(s)===G&&this.#B.delete(s),a){let H=Date.now();for(let[J,q]of this.#f)q===G&&(this.#f.delete(J),this.#Oe(J,H))}f.get(s)===G&&f.delete(s);let j=(Q.get(s)??1)-1;j>0?Q.set(s,j):Q.delete(s),this.#l.delete(G)}),this.#u.set(c,G),a&&this.#B.set(s,G),this.#l.add(G),f.set(s,G),G}async#ae(t,{chatId:o,key:i,messageId:e=null,sessionWorkspace:a=null,sessionPage:A=0,selections:r=[]}){if(t==="sessions"||/^sessions:\d+$/.test(t)){let s=t==="sessions"?0:Number(t.slice(9));await this.#ge({chatId:o,key:i},a,s,{updateMessageId:e});return}if(t==="workspaces"){await this.#be({chatId:o,key:i},{updateMessageId:e});return}if(t==="watchlist"){await this.#Ce(i,o,{updateMessageId:e});return}if(t==="watch_add"||t==="watch_remove"){if(r.length===0){await this.#D(o,D("\u8BF7\u5148\u9009\u62E9\u81F3\u5C11\u4E00\u4E2A\u4F1A\u8BDD\u3002"));return}let s=0,g=0;if(t==="watch_add"){let I=new Map;try{I=await this.#sA(a)}catch(d){this.#w.warn?.("[dsh-feishu] batch watch validation failed:",d.message)}for(let d of r){let B=I.get(d);if(!B){g+=1;continue}let f=await this.#he(i,o,d,{notify:!1,validatedTarget:B});f.changed?s+=1:f.ok||(g+=1)}}else for(let I of r){let d=await this.#Ee(i,o,I,{notify:!1});d.changed?s+=1:d.ok||(g+=1)}let c=s>0&&g>0?t==="watch_add"?D("\u5DF2\u6279\u91CF\u5173\u6CE8 {count} \u4E2A\u4F1A\u8BDD\uFF0C\u53E6\u6709 {failed} \u4E2A\u672A\u6210\u529F\u3002",{count:s,failed:g}):D("\u5DF2\u53D6\u6D88\u5173\u6CE8 {count} \u4E2A\u4F1A\u8BDD\uFF0C\u53E6\u6709 {failed} \u4E2A\u672A\u6210\u529F\u3002",{count:s,failed:g}):s>0?t==="watch_add"?D("\u5DF2\u6279\u91CF\u5173\u6CE8 {count} \u4E2A\u4F1A\u8BDD\u3002",{count:s}):D("\u5DF2\u53D6\u6D88\u5173\u6CE8 {count} \u4E2A\u4F1A\u8BDD\u3002",{count:s}):g>0?D("\u6240\u9009\u4F1A\u8BDD\u5747\u672A\u5904\u7406\u6210\u529F\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"):t==="watch_add"?D("\u6240\u9009\u4F1A\u8BDD\u5DF2\u5728\u5173\u6CE8\u5217\u8868\u4E2D\u3002"):D("\u6240\u9009\u4F1A\u8BDD\u5DF2\u4E0D\u5728\u5173\u6CE8\u5217\u8868\u4E2D\u3002");try{await this.#Ce(i,o,{updateMessageId:e})}catch(I){this.#w.warn?.("[dsh-feishu] watch list refresh failed:",I.message)}await this.#D(o,c).catch(I=>{this.#w.warn?.("[dsh-feishu] watch batch summary failed:",I.message)});return}if(t==="new"){if(this.#a.has(i)||this.#ee(i)){await this.#D(o,D("\u5F53\u524D\u4EFB\u52A1\u4ECD\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148\u505C\u6B62\u4EFB\u52A1\u6216\u7B49\u5F85\u4EFB\u52A1\u5B8C\u6210\u540E\u518D\u5F00\u542F\u65B0\u4F1A\u8BDD\u3002"));return}await this.#r.clearSession(i),await this.#D(o,D("\u5DF2\u5F00\u542F\u5168\u65B0 Harness \u4F1A\u8BDD\u3002")),await this.#X(i,o,{updateMessageId:e});return}if(t==="use:current"){let s=this.#r.sessionFor(i);if(typeof s!="string"||!s){await this.#D(o,D("\u5F53\u524D\u6CA1\u6709\u7ED1\u5B9A\u7684\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u4ECE\u4F1A\u8BDD\u5217\u8868\u9009\u62E9\u3002"));return}await this.#D(o,D("\u5DF2\u5C31\u7EEA\uFF0C\u76F4\u63A5\u53D1\u6D88\u606F\u5373\u53EF\u7EE7\u7EED\u5F53\u524D\u4F1A\u8BDD\u3002"));return}if(t==="archive_toggle"||t==="archive:on"||t==="archive:off"){let s=t==="archive:on"?!0:t==="archive:off"?!1:!(this.#r?.includesArchivedSessions?.()??!1);await this.#r?.setIncludeArchivedSessions?.(s),await this.#D(o,s?D("\u5DF2\u5F00\u542F\uFF1A\u4F1A\u8BDD\u5217\u8868\u5305\u542B\u5F52\u6863\u4F1A\u8BDD\u3002"):D("\u5DF2\u5173\u95ED\uFF1A\u4F1A\u8BDD\u5217\u8868\u9690\u85CF\u5F52\u6863\u4F1A\u8BDD\u3002")),await this.#X(i,o,{updateMessageId:e});return}if(t==="repair"){await this.#D(o,D("\u4FEE\u590D\u9700\u5728\u79C1\u804A\u4E2D\u9A8C\u8BC1\u63A5\u5165\u8005\u8EAB\u4EFD\uFF0C\u8BF7\u76F4\u63A5\u53D1\u9001 /repair \u5F00\u59CB\u3002"));return}if(t==="compact"){await this.#AA(i,o);return}if(t==="stop"){await this.#tA(i,o);return}if(t==="steer"){await this.#rA(i,o,{updateMessageId:e});return}if(t.startsWith("steer:")){let s=t.slice(6);if(s==="custom"){await this.#W(o,Gk(),{key:i,updateMessageId:e});return}await this.#pe({key:i,chatId:o},s);return}if(t==="presets"){await this.#We(i,o,{updateMessageId:e});return}if(t==="models"){await this.#Ze(i,o,{updateMessageId:e});return}if(t==="status"){await this.#$e(i,o,{updateMessageId:e});return}if(t==="help"){await this.#eA(i,o,{updateMessageId:e});return}if(t==="back_to_menu"){await this.#X(i,o,{updateMessageId:e});return}if(t==="preset_default"){await this.#_e(i,o,{updateMessageId:e});return}if(t.startsWith("preset:select:")){let s=t.slice(14);if(s===Ky){await this.#_e(i,o,{updateMessageId:e});return}await this.#aA(i,o,s,{updateMessageId:e});return}if(t.startsWith("model:select:")){let s=t.slice(13);await this.#iA(i,o,s,{updateMessageId:e});return}if(t.startsWith("use:")){await this.#ze(i,o,t.slice(4),{updateMessageId:e});return}if(t.startsWith("workspace:")){await this.#Ve(i,o,t.slice(10),{updateMessageId:e});return}if(t.startsWith("unwatch:")){(await this.#Ee(i,o,t.slice(8))).ok&&e&&await this.#ge({chatId:o,key:i},a,A,{updateMessageId:e});return}if(t.startsWith("watch:")){let s=t.slice(6);(await this.#he(i,o,s,{workspaceHint:a})).ok&&e&&await this.#ge({chatId:o,key:i},a,A,{updateMessageId:e})}}#ie(t,o){if(this.#L.size>=x_e){let i=this.#L.keys().next().value;i!==void 0&&this.#L.delete(i)}this.#L.delete(t),this.#L.set(t,{...o,expiresAt:Date.now()+K_e})}#Je(t){let o=this.#L.get(t);return o?o.expiresAto.archived!==!0):t}async#ge({chatId:t,key:o},i,e=0,{updateMessageId:a=null}={}){try{let A=this.#j(),r=await Ub(i??"",this.#t,{signal:A});if(r.error){await this.#D(t,r.error);return}let s=await this.#t.listWorkspaceSessions(r.workspace,{signal:A}),g=this.#oe(Array.isArray(s?.sessions)?s.sessions:[]),c=s?.workspace??r.workspace;if(g.length===0){await this.#D(t,D(`\u5DE5\u4F5C\u533A\uFF1A{workspace} \u8BE5\u5DE5\u4F5C\u533A\u6682\u65E0\u4F1A\u8BDD\u3002`,{workspace:c}));return}let I=Math.ceil(g.length/$g),d=Number.isSafeInteger(e)&&e>0?Math.min(e,I-1):0,B=new Set((this.#r.watchEntries?.(o)??[]).map(Q=>Q.sessionId)),f=g.slice(d*$g,(d+1)*$g);this.#ie(o,{kind:"sessions",sessions:f.map(Q=>({...Q,watched:B.has(Q.sessionId)}))}),await this.#W(t,Hz(c,g,d,g.length,B),{key:o,updateMessageId:a,sessionWorkspace:r.workspace,sessionPage:d})}catch(A){await this.#x(t,A,{logLabel:"session list"})}}async#be({chatId:t,key:o},{updateMessageId:i=null}={}){try{let{current:e,paths:a}=await zh(this.#t,{signal:this.#j()});this.#ie(o,{kind:"workspaces",paths:a}),await this.#W(t,Kz(a,e),{key:o,updateMessageId:i})}catch(e){await this.#x(t,e,{logLabel:"workspace list"})}}async#ze(t,o,i,{updateMessageId:e=null}={}){try{let a=await this.#t.bindWorkspaceSession(t,i),A=String(a?.title??"").replace(/\s+/gu," ").trim()||D("\u6682\u65E0\u6807\u9898");await this.#D(o,D(`\u5DF2\u7ED1\u5B9A\u4F1A\u8BDD\u300C{title}\u300D