@wps365/openclaw-wpsxiezuo 1.11.4 → 1.11.6-beta.0
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/index.js +23 -23
- package/dist/tools/oapi/cloud-doc.d.ts +1 -1
- package/dist/tools/oapi/media.d.ts +1 -1
- package/openclaw.plugin.json +1 -3
- package/package.json +1 -1
- package/skills/wps-channel-rules/SKILL.md +78 -79
- package/skills/wps-cloud-doc/SKILL.md +1 -1
- package/skills/wps-im-send/SKILL.md +183 -183
- package/skills/wps-media/SKILL.md +106 -99
package/dist/index.js
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
var Ns=Object.defineProperty;var H=(e,t)=>()=>(e&&(t=e(e=0)),t);var St=(e,t)=>{for(var r in t)Ns(e,r,{get:t[r],enumerable:!0})};function Xr(e){if(!(e instanceof Re))return!1;let{wpsCode:t}=e.detail;return js.has(String(t))}function Vr(e){if(!(e instanceof Re))return!1;let{httpStatus:t,wpsCode:r}=e.detail;return t===401||Ms.has(String(r))}function Yr(e){return e===401?{hint:"invalid/expired token or app credentials",retriable:!1}:e===403?{hint:"permission denied or scope not granted",retriable:!1}:e===404?{hint:"resource not found",retriable:!1}:e===409?{hint:"resource state conflict",retriable:!1}:e===429?{hint:"rate limited by WPS API",retriable:!0}:e>=500?{hint:"WPS API temporarily unavailable",retriable:!0}:{hint:"unexpected WPS API status",retriable:!1}}var Re,pe,js,Ms,xt=H(()=>{"use strict";Re=class extends Error{detail;name="WpsRequestError";constructor(t,r){super(t),this.detail=r}get retriable(){return this.detail.retriable===!0}get stage(){return this.detail.stage}},pe=class extends Error{cause;name="WpsTokenError";constructor(t,r){super(t),this.cause=r}},js=new Set(["403000001","40300001","40300003","40300010","400002003"]),Ms=new Set(["40100002","40100011"])});var Xt={};St(Xt,{currentAccountId:()=>Kt,getDefaultAccountId:()=>en,getDelegatedScopes:()=>xe,getLazyClient:()=>tn,getLazyCreds:()=>nt,getLazyLog:()=>oe,getLazyWpsCfg:()=>rn,runWithAccountId:()=>fr,setAccountContext:()=>_r,setDefaultAccountId:()=>Qr,setDelegatedScopes:()=>Fs,setLazyClient:()=>zs,updateDelegatedScopes:()=>it});import{AsyncLocalStorage as Ws}from"node:async_hooks";function fr(e,t){return Zr.run(e,t)}function Kt(){return Zr.getStore()}function _r(e,t){if(!e?.trim())throw new Error("setAccountContext: accountId must not be empty");vt.set(e,{...t,delegatedScopes:t.delegatedScopes??[]})}function Qr(e){rt=e}function en(){return rt}function Ls(e){if(e)return e;let t=Zr.getStore();if(t)return t;if(rt)return rt;if(vt.size===1)return vt.keys().next().value;throw new Error("WPS accountId required: multiple accounts configured but no accountId specified and no default set")}function Jt(e){let t=Ls(e),r=vt.get(t);if(!r)throw new Error(`WPS account context not initialized for "${t}" (startAccount has not been called)`);return r}function tn(e){return Jt(e).client}function oe(e){if(!e&&!rt&&vt.size===0)return null;try{return Jt(e).log}catch{return null}}function rn(e){return Jt(e).wpsCfg}function nt(e){return Jt(e).creds}function it(e,t){let r=vt.get(e);r&&(r.delegatedScopes=t)}function xe(e){try{return Jt(e).delegatedScopes}catch{return[]}}function zs(e,t,r,n){_r(rt??"default",{client:e,log:t??null,wpsCfg:r,creds:n})}function Fs(e){it(rt??"default",e)}var Zr,vt,rt,ue=H(()=>{"use strict";Zr=new Ws;vt=new Map,rt=null});import{z as S}from"zod";function hr(e){return mr}function gr(e){let t=e?.defaultAccountId?.trim();if(t)return t;let r=e?.accounts?Object.keys(e.accounts)[0]:void 0;return r&&r.trim()?r:he}function Gs(e){let t={};for(let[r,n]of Object.entries(e))!Bs.has(r)&&n!==void 0&&(t[r]=n);return t}function nn(e,t){for(let[r,n]of Object.entries(t)){if(n===void 0)continue;let o=e[r];o&&typeof o=="object"&&!Array.isArray(o)&&n&&typeof n=="object"&&!Array.isArray(n)?e[r]={...o,...n}:e[r]=n}return e}function sn(e){if(!e)return{};let t=Gs(e);if(!e.accounts||Object.keys(e.accounts).length===0)return!t.appId||!t.appSecret?{}:{[he]:Tt.parse(t)};let r=e.accounts[he];if(r&&typeof r=="object"&&!Array.isArray(r)){let o={...t};nn(t,r),nn(t,o)}let n={};t.appId&&t.appSecret&&(n[he]=Tt.parse(t));for(let[o,i]of Object.entries(e.accounts)){if(o===he||!i||typeof i!="object"||Array.isArray(i))continue;let s=nn({...t},i);s.appId&&s.appSecret&&(n[o]=Tt.parse(s))}return n}function ve(e){return!e?.appId||!e?.appSecret?null:{clientId:e.appId,clientSecret:e.appSecret,baseUrl:e.baseUrl??"https://openapi.wps.cn"}}var Ei,Ai,Pi,Oi,$i,Ri,mr,Tt,on,Bs,E,ze,he,Et=H(()=>{"use strict";Ei=S.enum(["disabled","open","allowlist","pairing"]).default("pairing"),Ai=S.object({requireMention:S.boolean().optional(),toolPolicy:S.enum(["full","limited","none"]).optional()}).passthrough(),Pi=S.object({enabled:S.boolean().default(!1),mode:S.literal("app").default("app"),clientId:S.string().optional(),clientSecret:S.string().optional(),baseUrl:S.string().optional(),toolAllowlist:S.array(S.string()).min(1,"mcp.toolAllowlist must contain at least one tool").default(["wps_user_search","wps_user_get","wps_message_send","wps_calendar_create","wps_calendar_list_events","wps_calendar_search_events","wps_calendar_update_event","wps_calendar_delete_event","wps_calendar_get_event","wps_calendar_list_event_attendees","wps_calendar_add_event_attendees","wps_calendar_list_event_meeting_rooms","wps_calendar_event_meeting_rooms_batch_create","wps_calendar_event_meeting_rooms_batch_delete","wps_calendar_delete_event_attendees","wps_calendar_list_calendar_event_instances","wps_calendar_list_event_instances","wps_calendar_respond_invitation","wps_todo_create_personal_task","wps_todo_list_personal_tasks","wps_todo_get_personal_task","wps_todo_update_personal_task","wps_todo_update_personal_task_status","wps_cloud_doc_list_drives","wps_cloud_doc_list_children_files","wps_cloud_doc_create_file","wps_cloud_doc_upload_file","wps_cloud_doc_extract_file_content","wps_cloud_doc_get_file_meta","wps_cloud_doc_search_files","wps_airpage_create_file","wps_airpage_create_block_content","wps_airpage_query_document_blocks","wps_airpage_batch_query_document_blocks","wps_airpage_delete_block_content","wps_airpage_batch_delete_block_content","wps_airpage_update_document_block","wps_airpage_batch_update_document_blocks","wps_meeting_rooms_list","wps_meeting_rooms_get","wps_meeting_rooms_search","wps_meeting_room_bookings_batch_get","wps_meeting_room_bookings_update_status"])}),Oi=S.object({enabled:S.boolean().default(!0),text:S.string().default("\u5185\u5BB9\u5904\u7406\u4E2D\uFF0C\u8BF7\u7A0D\u5019...")}),$i=S.object({enabled:S.boolean().default(!1),logLevel:S.enum(["debug","info","warn","error"]).default("info"),endpoint:S.string().optional(),connectTimeoutMs:S.number().min(3e3).max(12e4).default(2e4),pongTimeout:S.number().min(3e4).max(3e5).default(15e4),autoReconnect:S.boolean().default(!0),reconnectBaseInterval:S.number().min(500).max(1e4).default(1e3),reconnectMaxInterval:S.number().min(1e4).max(3e5).default(6e4),reconnectMultiplier:S.number().min(1.5).max(3).default(2),reconnectMaxRetry:S.number().min(-1).max(100).default(-1),reconnectJitter:S.number().min(0).max(.5).default(.2)}),Ri=S.object({path:S.string().default("/wps/webhook"),port:S.number().default(3e3)}),mr="https://365.kdocs.cn/woa/openclaw/callback",Tt=S.object({enabled:S.boolean().default(!0),appId:S.string().describe("WPS App ID (client_id)"),appSecret:S.string().describe("WPS App Secret (client_secret)"),companyId:S.string().optional().describe("WPS Company ID"),baseUrl:S.string().default("https://openapi.wps.cn"),enableEncryption:S.boolean().default(!0),webhook:Ri.optional(),sdk:$i.optional(),dmPolicy:Ei.optional(),allowFrom:S.array(S.string()).optional(),groupPolicy:S.enum(["open","allowlist"]).optional(),groups:S.record(S.string(),Ai).optional(),instantAck:Oi.optional(),robotJoinGroupMessage:S.string().optional(),mcp:Pi.optional()}),on=Tt.partial().extend({defaultAccountId:S.string().optional(),accounts:S.record(S.string(),Tt).optional()});Bs=new Set(["accounts","defaultAccountId"]);E="wps-xiezuo",ze="wps-xiezuo",he="default"});import{randomBytes as qi,createCipheriv as Hs,createDecipheriv as Ks}from"node:crypto";import{existsSync as an,mkdirSync as Js,readFileSync as Ui,writeFileSync as Ni,unlinkSync as Dl}from"node:fs";import{join as Yt}from"node:path";import{homedir as Ci}from"node:os";function Wi(){return process.platform==="win32"?Yt(Ci(),"AppData","Local",Di):Yt(Ci(),".local","share",Di)}function Li(){let e=Wi();return an(e)||Js(e,{recursive:!0,mode:448}),e}function zi(){let e=Li(),t=Yt(e,Xs);if(an(t)){let n=Ui(t);if(n.length===32)return n}let r=qi(32);return Ni(t,r,{mode:384}),r}function Vs(e,t){let r=qi(At),n=Hs(Mi,t,r,{authTagLength:Vt}),o=Buffer.concat([n.update(e),n.final()]),i=n.getAuthTag();return Buffer.concat([r,i,o])}function Ys(e,t){if(e.length<At+Vt+1)throw new Error("Invalid encrypted data: too short");let r=e.subarray(0,At),n=e.subarray(At,At+Vt),o=e.subarray(At+Vt),i=Ks(Mi,t,r,{authTagLength:Vt});return i.setAuthTag(n),Buffer.concat([i.update(o),i.final()])}function dn(){try{let e=Wi(),t=Yt(e,ji);if(!an(t))return{};let r=zi(),n=Ui(t),o=Ys(n,r),i=JSON.parse(o.toString("utf8"));return!i||typeof i!="object"?{}:i}catch{return{}}}function cn(e){try{let t=zi(),r=JSON.stringify(e,null,2),n=Vs(Buffer.from(r,"utf8"),t),o=Li(),i=Yt(o,ji);Ni(i,n,{mode:384})}catch{}}function Zt(e){let t=dn();e in t&&(delete t[e],cn(t))}var Di,Xs,ji,Mi,At,Vt,Fi=H(()=>{"use strict";Di="openclaw-wps-xiezuo",Xs="master.key",ji="tokens.enc",Mi="aes-256-gcm",At=12,Vt=16});var Ki={};St(Ki,{clearGrantedScopes:()=>br,deleteUserToken:()=>Ir,exchangeCodeForToken:()=>xr,getUserToken:()=>Te,getUserTokenEntry:()=>Ot,hasUserToken:()=>Hi,putUserToken:()=>wr,restoreRefreshTimers:()=>Sr,setRefreshContext:()=>yr,takeUserToken:()=>Gi});function st(e,t){return`${e}:${t}`}function yr(e,t){ln.set(e,t)}function Pt(){if(!Bi){Bi=!0;try{let e=dn();for(let[t,r]of Object.entries(e))!r||typeof r!="object"||!r.accessToken||!r.expiresAt||se.set(t,r)}catch{}}}function pn(){let e={};for(let[t,r]of se)e[t]=r;cn(e)}function wr(e,t,r){Pt();let n=st(e,t);se.set(n,r),pn(),un(e,t,r)}function Te(e,t){Pt();let r=st(e,t),n=se.get(r);return n?Date.now()>=n.expiresAt?(se.delete(r),kr(r),Zt(r),null):n.accessToken:null}function Ot(e,t){Pt();let r=st(e,t),n=se.get(r);return n?Date.now()>=n.expiresAt?(se.delete(r),kr(r),Zt(r),null):n:null}function br(e,t){Pt();let r=st(e,t),n=se.get(r);n&&(n.grantedScopes=void 0,pn())}function Ir(e,t){Pt();let r=st(e,t);se.delete(r),kr(r),Zt(r)}function Gi(e,t){return Te(e,t)}function Hi(e,t){return Te(e,t)!==null}function kr(e){let t=ot.get(e);t&&(clearTimeout(t),ot.delete(e))}function un(e,t,r){let n=st(e,t);if(kr(n),!r.refreshToken)return;let o=Math.max(r.expiresAt-Date.now()-Zs,1e4),i=setTimeout(()=>{Qs(e,t).catch(s=>{oe(e)?.warn?.(`[TokenStore] Refresh failed for account=${e} user=${t}, token cleared \u2014 next tool call will trigger re-auth: ${String(s)}`),se.delete(n),ot.delete(n),Zt(n)})},o);i.unref?.(),ot.set(n,i)}async function Qs(e,t){let r=st(e,t),n=se.get(r);if(!n?.refreshToken){ot.delete(r);return}let o=ln.get(e);if(!o){oe(e)?.warn?.(`[TokenStore] Refresh skipped for account=${e} user=${t}: refreshCtx not set yet`),ot.delete(r);return}let i=o.baseUrl.replace(/\/$/,""),s=new URLSearchParams({grant_type:"refresh_token",client_id:o.appId,client_secret:o.appSecret,refresh_token:n.refreshToken}),a=await fetch(`${i}/oauth2/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()}),l=await a.text(),c;try{c=JSON.parse(l)}catch{throw new pe(`OAuth refresh: non-JSON response (${a.status}): ${l.slice(0,200)}`)}if(!a.ok||typeof c.code=="number"&&c.code!==0)throw new pe(`OAuth refresh failed (${a.status}): ${JSON.stringify(c)}`);let d=typeof c.access_token=="string"?c.access_token:"";if(!d)throw new pe(`OAuth refresh: missing access_token: ${JSON.stringify(c)}`);let p=typeof c.expires_in=="number"?c.expires_in:7200,u=typeof c.scope=="string"&&c.scope?c.scope.split(/[,\s]+/).filter(Boolean):void 0,_={accessToken:d,refreshToken:typeof c.refresh_token=="string"?c.refresh_token:n.refreshToken,expiresAt:Date.now()+p*1e3,openid:typeof c.openid=="string"?c.openid:n.openid,grantedScopes:u??n.grantedScopes};se.set(r,_),pn(),un(e,t,_)}function Sr(e){Pt();for(let[t,r]of se){if(!r.refreshToken||Date.now()>=r.expiresAt||ot.has(t))continue;let[n,o]=t.split(":",2);!n||!o||e&&n!==e||ln.has(n)&&un(n,o,r)}}async function xr(e){let t=e.baseUrl.replace(/\/$/,""),r=new URLSearchParams({grant_type:"authorization_code",client_id:e.appId,client_secret:e.appSecret,code:e.code,redirect_uri:e.redirectUri??mr}),n=await fetch(`${t}/oauth2/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r.toString()}),o=await n.text(),i;try{i=JSON.parse(o)}catch{throw new pe(`OAuth code exchange: non-JSON response (${n.status}): ${o.slice(0,200)}`)}if(!n.ok||typeof i.code=="number"&&i.code!==0)throw new pe(`OAuth code exchange failed (${n.status}): ${JSON.stringify(i)}`);let s=typeof i.access_token=="string"?i.access_token:"";if(!s)throw new pe(`OAuth code exchange: missing access_token in response: ${JSON.stringify(i)}`);let a=typeof i.expires_in=="number"?i.expires_in:7200,l=typeof i.scope=="string"&&i.scope?i.scope.split(/[,\s]+/).filter(Boolean):void 0;return{accessToken:s,refreshToken:typeof i.refresh_token=="string"?i.refresh_token:"",expiresAt:Date.now()+a*1e3,openid:typeof i.openid=="string"?i.openid:"",grantedScopes:l}}var se,ot,Zs,ln,Bi,Fe=H(()=>{"use strict";xt();Et();ue();Fi();se=new Map,ot=new Map,Zs=5*6e4,ln=new Map;Bi=!1});function fn(e){let{requiredScopes:t,accountId:r,wpsUserId:n}=e,o=!1,i=xe(r);if(i.length>0&&t.length>0){let a=new Set(i.map(c=>c.name)),l=t.filter(c=>!a.has(c));if(l.length>0)return{ok:!1,reason:"app_scope_missing",missingScopes:l,message:`\u8BE5\u529F\u80FD\u9700\u8981\u5728 WPS \u5F00\u653E\u5E73\u53F0\u5F00\u901A\u4EE5\u4E0B\u6743\u9650\uFF1A${l.join(", ")}`};o=!0}if(!Te(r,n))return{ok:!1,reason:"no_token",appScopeVerified:o,message:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u4F7F\u7528\u6B64\u529F\u80FD\u3002"};if(o&&t.length>0){let a=Ot(r,n);if(Array.isArray(a?.grantedScopes)){let l=new Set(a.grantedScopes),c=t.filter(d=>!l.has(d));if(c.length>0)return{ok:!1,reason:"user_scope_insufficient",appScopeVerified:o,missingScopes:c,message:`\u9700\u8981\u8865\u5145\u6388\u6743\u4EE5\u4E0B\u6743\u9650\uFF1A${c.join(", ")}`}}}return{ok:!0,appScopeVerified:o}}var _n=H(()=>{"use strict";ue();Fe()});function ra(e){return e===401?"invalid app credentials (check client_id/client_secret)":e===403?"app not authorized for this enterprise or scope":e===429?"rate limited by WPS token endpoint":e>=500?"WPS OAuth service unavailable":"unexpected OAuth response"}function R(e){let t=`${e.clientId}@${e.baseUrl}`,r=Ji.get(t);return r||(r=new vr(e),Ji.set(t,r)),r}var ea,ta,vr,Ji,mn=H(()=>{"use strict";xt();ea=6e4,ta=["/oauth2/token","/openapi/oauth2/token"];vr=class{creds;token=null;inFlight=null;constructor(t){this.creds=t}async getToken(){if(this.token&&Date.now()<this.token.expiresAt-ea)return this.token.accessToken;if(this.inFlight)return this.inFlight;this.inFlight=this.requestToken();try{return await this.inFlight}finally{this.inFlight=null}}invalidate(){this.token=null}async requestToken(){let t=this.creds.baseUrl.replace(/\/$/,""),r="unknown token error";for(let n of ta){let o=`${t}${n}`,i;try{i=await fetch(o,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"client_credentials",client_id:this.creds.clientId,client_secret:this.creds.clientSecret})})}catch(a){r=`Network error requesting token from ${o}: ${String(a)}`;continue}if(!i.ok){let a=await i.text();r=`Token request failed (${i.status}) at ${o}: ${ra(i.status)}; body=${a}`;continue}let s=await i.json();if(s.code!==void 0&&s.code!==0){r=`WPS OAuth error (code ${s.code}): ${s.msg??"unknown"}`;continue}if(!s.access_token||!s.expires_in){r=`Invalid token response from ${o}: missing access_token or expires_in`;continue}return this.token={accessToken:s.access_token,expiresAt:Date.now()+s.expires_in*1e3},this.token.accessToken}throw new pe(r)}},Ji=new Map});function C(e,t){return new Qt(e,new Tr(t))}function hn(e,t){return new Qt(e,new Er(t))}var Tr,Er,Qt,Ar=H(()=>{"use strict";xt();Tr=class{tokenStore;constructor(t){this.tokenStore=t}async getHeaders(){return{Authorization:`Bearer ${await this.tokenStore.getToken()}`}}},Er=class{accessToken;constructor(t){this.accessToken=t}async getHeaders(){return{Authorization:`Bearer ${this.accessToken}`}}},Qt=class{baseUrl;auth;constructor(t,r){this.baseUrl=t,this.auth=r}async request(t){let r=await this.auth.getHeaders(),n=this.buildUrl(t.path,t.query),o=t.method??"GET",i=await fetch(n,{method:o,headers:{"Content-Type":"application/json",...r,...t.headers??{}},body:t.body?JSON.stringify(t.body):void 0}),s=i.headers.get("X-Request-Id")??i.headers.get("x-request-id")??i.headers.get("X-Trace-Id")??i.headers.get("x-trace-id")??void 0;if(!i.ok){let a=await i.text(),l;try{let u=JSON.parse(a);l=u.code??u.result}catch{}let{hint:c,retriable:d}=Yr(i.status),p=s?` request_id=${s}`:"";throw console.error(`[WPS-API-ERROR] ${i.status} ${o} ${t.path}${p} body=${a}`),new Re(`WPS API error (${i.status} ${o} ${t.path}): ${a}`,{stage:"http",method:o,path:t.path,httpStatus:i.status,wpsCode:l,hint:c,retriable:d,requestId:s})}return this.parseResponse(i,o,t.path,s)}buildUrl(t,r){let n=new URL(t,this.baseUrl);if(r){for(let[o,i]of Object.entries(r))if(i!==void 0)if(Array.isArray(i))for(let s of i)n.searchParams.append(o,s);else n.searchParams.set(o,String(i))}return n.toString()}async parseResponse(t,r,n,o){let i=await t.text();if(!i||i.trim()==="")return{};let s;try{s=JSON.parse(i)}catch{throw new Re(`Failed to parse JSON from ${r} ${n}: ${i.slice(0,200)}`,{stage:"parse",method:r,path:n,hint:"response is not valid JSON",retriable:!1})}let a=s.code??s.result;if(a!==void 0&&a!==0&&a!=="ok"){let l=String(a)==="40300001"?"permission denied by WPS business policy":"WPS business validation failed",c=s.request_id??o,d=c?` request_id=${String(c)}`:"";throw console.error(`[WPS-API-ERROR] biz_code=${String(a)} ${r} ${n}${d} msg=${s.msg??s.message??"unknown"}`),new Re(`WPS business error code=${String(a)}: ${s.msg??s.message??"unknown"}`,{stage:"business",method:r,path:n,wpsCode:a,hint:l,retriable:!1,requestId:c?String(c):void 0})}return s}}});import{imageSize as na}from"image-size";function er(e,t=0){if(!e||typeof e!="object"||t>2)return null;let r=e;for(let n of ia){let o=r[n];if(typeof o=="string"&&o.trim())return o.trim()}return r.data&&typeof r.data=="object"?er(r.data,t+1):null}function gn(e){let t=er(e);if(!t)throw new Error("cannot resolve download URL from WPS API response");return t}function at(e){try{let t=na(Buffer.isBuffer(e)?e:Buffer.from(e));return t.width&&t.height?{width:t.width,height:t.height}:null}catch{return null}}var ia,tr=H(()=>{"use strict";ia=["url","download_url","downloadUrl","file_url","fileUrl"]});function yn(e){return Xi[e]??[]}var Xi,wn=H(()=>{"use strict";Xi={calendar:["kso.calendar_events.readwrite","kso.calendar_events.read"],todo:["kso.task.readwrite","kso.task.read"],"cloud-doc":["kso.drive.readwrite","kso.file.readwrite","kso.file.read","kso.file.search"],airsheet:["kso.airsheet.readwrite","kso.airsheet.read"],dbsheet:["kso.dbsheet.readwrite","kso.dbsheet.read"],airpage:["kso.airpage.readwrite","kso.airpage.read"]}});async function In(e,t,r){let n=R(e);await C(e.baseUrl,n).request({method:"POST",path:`/v7/chats/${encodeURIComponent(t)}/messages/${encodeURIComponent(r)}/reactions/create`,body:{reaction_type:bn}})}async function kn(e,t,r,n){try{let o=R(e);await C(e.baseUrl,o).request({method:"POST",path:`/v7/chats/${encodeURIComponent(t)}/messages/${encodeURIComponent(r)}/reactions/delete`,body:{reaction_type:bn}})}catch(o){let i=String(o);i.includes("msgRecalled")||i.includes("message_not_found")||i.includes("404")?(n?.info??console.log)(`WPS thinking reaction cleanup skipped (message gone): ${i.substring(0,100)}`):(n?.error??console.error)(`WPS thinking reaction cleanup failed: ${i}`)}}var bn,Sn=H(()=>{"use strict";mn();Ar();bn="emoji_busy"});var Be=H(()=>{"use strict";xt();_n();mn();Fe();Ar();tr();wn();Sn();Et()});function jn(e){let t=qt.get(e);return t?Date.now()-t<3e4?!0:(qt.delete(e),!1):!1}function ko(e){qt.set(e,Date.now()),Wa()}function So(e){qt.delete(e)}function Wa(){let e=Date.now();if(!(e-Io<Ma)){Io=e;for(let[t,r]of qt)e-r>=3e4&&qt.delete(t)}}function xo(e,t){if(jn(e))return Promise.resolve();let r=Dt.get(e);return r?(clearTimeout(r.timer),new Promise(n=>{r.waiters.push(n),r.timer=setTimeout(()=>{let o=Dt.get(e);Dt.delete(e);let i=()=>{o?.waiters.forEach(s=>s())};t().then(i,i)},150),r.timer.unref?.()})):new Promise(n=>{let o={timer:setTimeout(()=>{let i=Dt.get(e);Dt.delete(e);let s=()=>{i?.waiters.forEach(a=>a())};t().then(s,s)},150),waiters:[n]};o.timer.unref?.(),Dt.set(e,o)})}var Dt,qt,Ma,Io,Mn=H(()=>{"use strict";Dt=new Map,qt=new Map;Ma=6e4,Io=0});var ct={};St(ct,{ensureDelegatedScopesFresh:()=>Fa,invalidateDelegatedScopeCache:()=>La,markDelegatedScopeCacheFresh:()=>za,startDelegatedScopeRefresh:()=>Ga,stopAllDelegatedScopeRefresh:()=>Ka,stopDelegatedScopeRefresh:()=>Ha});function La(e){or.delete(e)}function za(e){or.set(e,Date.now())}async function Fa(e){let t=or.get(e);if(t&&Date.now()-t<To)return;let r=Wn.get(e);if(r)return r;let n=Ba(e).finally(()=>{Wn.delete(e)});return Wn.set(e,n),n}async function Ba(e){let t=oe(e);try{let r=nt(e),n=R(r),s=((await C(r.baseUrl,n).request({method:"GET",path:`/v7/developer/apps/${encodeURIComponent(r.clientId)}`,query:{lang:"zh-CN"}})).data?.scopes??[]).filter(p=>p.auth_types?.includes("delegated")).map(p=>({name:p.name??"",description:p.description??""})).filter(p=>p.name),a=xe(e),l=new Set(a.map(p=>p.name)),c=new Set(s.map(p=>p.name));(s.length!==a.length||s.some(p=>!l.has(p.name))||a.some(p=>!c.has(p.name)))&&(it(e,s),t?.info?.(`[scope-cache] delegated scopes updated for account=${e}, count=${s.length}`)),or.set(e,Date.now())}catch(r){or.set(e,Date.now()-To+vo),t?.warn?.(`[scope-cache] refresh failed for account=${e}, backing off ${vo}ms: ${String(r)}`)}}function Ga(e){}function Ha(e){}function Ka(){}var To,vo,or,Wn,lt=H(()=>{"use strict";ue();Be();To=30*1e3,vo=10*1e3,or=new Map,Wn=new Map});var Ao={};St(Ao,{dispatchSyntheticAuthComplete:()=>Ja});async function Ja(e){if(e.originalMessageId){let t=`${e.accountId}:${e.originalMessageId}`,r=$r.get(t);if(r&&Date.now()-r<Eo){e.log?.debug?.("synthetic message deduplicated",{dedupKey:t});return}$r.set(t,Date.now());for(let[n,o]of $r)Date.now()-o>Eo&&$r.delete(n)}try{let t=R(e.creds);await C(e.creds.baseUrl,t).request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:{type:e.receiverType,receiver_id:e.receiverId},content:{text:{content:"\u7528\u6237\u5DF2\u5B8C\u6210 WPS \u8D26\u53F7\u6388\u6743\uFF0C\u8BF7\u7EE7\u7EED\u6267\u884C\u4E4B\u524D\u7684\u64CD\u4F5C\u3002",type:"markdown"}}}})}catch(t){e.log?.warn?.(`[synthetic-message] Failed to send: ${String(t)}`)}}var Eo,$r,Po=H(()=>{"use strict";Be();Eo=6e4,$r=new Map});var Bn={};St(Bn,{buildAuthCard:()=>Co,buildAuthSuccessCard:()=>Do,buildAuthorizeUrl:()=>Ro,decodeState:()=>$o,encodeState:()=>Oo,handleAuthEvent:()=>Qa,sendAuthCard:()=>Fn});import{randomBytes as Xa}from"node:crypto";function Va(e){let{batchKey:t,totalParts:r}=e;if(!t||!r||r<=1)return!0;let n=Ln.get(t);return n||(n={completed:0,total:r},Ln.set(t,n),setTimeout(()=>Ln.delete(t),15*6e4).unref?.()),n.completed+=1,n.completed>=n.total}function Oo(e){let t=Xa(16).toString("hex");e.nonce=t;let r=t;return sr.set(r,e),setTimeout(()=>sr.delete(r),10*6e4).unref?.(),r}function $o(e){let t=sr.get(e);return t&&sr.delete(e),t??null}function Ro(e){let t=new URL("/oauth2/auth",e.baseUrl);return t.searchParams.set("response_type","code"),t.searchParams.set("client_id",e.appId),t.searchParams.set("redirect_uri",e.redirectUri),t.searchParams.set("scope",e.scopes.join(",")),t.searchParams.set("state",e.state),t.toString()}function Co(e,t,r){let n=t.length>Rr,i=(n?t.slice(0,Rr):t).join(`
|
|
1
|
+
var Us=Object.defineProperty;var G=(e,t)=>()=>(e&&(t=e(e=0)),t);var wt=(e,t)=>{for(var r in t)Us(e,r,{get:t[r],enumerable:!0})};function Jr(e){if(!(e instanceof Oe))return!1;let{wpsCode:t}=e.detail;return Ns.has(String(t))}function Xr(e){if(!(e instanceof Oe))return!1;let{httpStatus:t,wpsCode:r}=e.detail;return t===401||js.has(String(r))}function Vr(e){return e===401?{hint:"invalid/expired token or app credentials",retriable:!1}:e===403?{hint:"permission denied or scope not granted",retriable:!1}:e===404?{hint:"resource not found",retriable:!1}:e===409?{hint:"resource state conflict",retriable:!1}:e===429?{hint:"rate limited by WPS API",retriable:!0}:e>=500?{hint:"WPS API temporarily unavailable",retriable:!0}:{hint:"unexpected WPS API status",retriable:!1}}var Oe,pe,Ns,js,bt=G(()=>{"use strict";Oe=class extends Error{detail;name="WpsRequestError";constructor(t,r){super(t),this.detail=r}get retriable(){return this.detail.retriable===!0}get stage(){return this.detail.stage}},pe=class extends Error{cause;name="WpsTokenError";constructor(t,r){super(t),this.cause=r}},Ns=new Set(["403000001","40300001","40300003","40300010","400002003"]),js=new Set(["40100002","40100011"])});var Kt={};wt(Kt,{currentAccountId:()=>Gt,getDefaultAccountId:()=>Qr,getDelegatedScopes:()=>ke,getLazyClient:()=>en,getLazyCreds:()=>tt,getLazyLog:()=>ie,getLazyWpsCfg:()=>tn,runWithAccountId:()=>ur,setAccountContext:()=>fr,setDefaultAccountId:()=>Zr,setDelegatedScopes:()=>zs,setLazyClient:()=>Ls,updateDelegatedScopes:()=>rt});import{AsyncLocalStorage as Ms}from"node:async_hooks";function ur(e,t){return Yr.run(e,t)}function Gt(){return Yr.getStore()}function fr(e,t){if(!e?.trim())throw new Error("setAccountContext: accountId must not be empty");It.set(e,{...t,delegatedScopes:t.delegatedScopes??[]})}function Zr(e){et=e}function Qr(){return et}function Ws(e){if(e)return e;let t=Yr.getStore();if(t)return t;if(et)return et;if(It.size===1)return It.keys().next().value;throw new Error("WPS accountId required: multiple accounts configured but no accountId specified and no default set")}function Ht(e){let t=Ws(e),r=It.get(t);if(!r)throw new Error(`WPS account context not initialized for "${t}" (startAccount has not been called)`);return r}function en(e){return Ht(e).client}function ie(e){if(!e&&!et&&It.size===0)return null;try{return Ht(e).log}catch{return null}}function tn(e){return Ht(e).wpsCfg}function tt(e){return Ht(e).creds}function rt(e,t){let r=It.get(e);r&&(r.delegatedScopes=t)}function ke(e){try{return Ht(e).delegatedScopes}catch{return[]}}function Ls(e,t,r,n){fr(et??"default",{client:e,log:t??null,wpsCfg:r,creds:n})}function zs(e){rt(et??"default",e)}var Yr,It,et,ue=G(()=>{"use strict";Yr=new Ms;It=new Map,et=null});import{z as k}from"zod";function mr(e){return _r}function hr(e){let t=e?.defaultAccountId?.trim();if(t)return t;let r=e?.accounts?Object.keys(e.accounts)[0]:void 0;return r&&r.trim()?r:he}function Bs(e){let t={};for(let[r,n]of Object.entries(e))!Fs.has(r)&&n!==void 0&&(t[r]=n);return t}function rn(e,t){for(let[r,n]of Object.entries(t)){if(n===void 0)continue;let o=e[r];o&&typeof o=="object"&&!Array.isArray(o)&&n&&typeof n=="object"&&!Array.isArray(n)?e[r]={...o,...n}:e[r]=n}return e}function on(e){if(!e)return{};let t=Bs(e);if(!e.accounts||Object.keys(e.accounts).length===0)return!t.appId||!t.appSecret?{}:{[he]:St.parse(t)};let r=e.accounts[he];if(r&&typeof r=="object"&&!Array.isArray(r)){let o={...t};rn(t,r),rn(t,o)}let n={};t.appId&&t.appSecret&&(n[he]=St.parse(t));for(let[o,i]of Object.entries(e.accounts)){if(o===he||!i||typeof i!="object"||Array.isArray(i))continue;let s=rn({...t},i);s.appId&&s.appSecret&&(n[o]=St.parse(s))}return n}function xe(e){return!e?.appId||!e?.appSecret?null:{clientId:e.appId,clientSecret:e.appSecret,baseUrl:e.baseUrl??"https://openapi.wps.cn"}}var Ii,Si,ki,xi,vi,Ti,_r,St,nn,Fs,E,We,he,kt=G(()=>{"use strict";Ii=k.enum(["disabled","open","allowlist","pairing"]).default("pairing"),Si=k.object({requireMention:k.boolean().optional(),toolPolicy:k.enum(["full","limited","none"]).optional()}).passthrough(),ki=k.object({enabled:k.boolean().default(!1),mode:k.literal("app").default("app"),clientId:k.string().optional(),clientSecret:k.string().optional(),baseUrl:k.string().optional(),toolAllowlist:k.array(k.string()).min(1,"mcp.toolAllowlist must contain at least one tool").default(["wps_user_search","wps_user_get","wps_message_send","wps_calendar_create","wps_calendar_list_events","wps_calendar_search_events","wps_calendar_update_event","wps_calendar_delete_event","wps_calendar_get_event","wps_calendar_list_event_attendees","wps_calendar_add_event_attendees","wps_calendar_list_event_meeting_rooms","wps_calendar_event_meeting_rooms_batch_create","wps_calendar_event_meeting_rooms_batch_delete","wps_calendar_delete_event_attendees","wps_calendar_list_calendar_event_instances","wps_calendar_list_event_instances","wps_calendar_respond_invitation","wps_todo_create_personal_task","wps_todo_list_personal_tasks","wps_todo_get_personal_task","wps_todo_update_personal_task","wps_todo_update_personal_task_status","wps_cloud_doc_list_drives","wps_cloud_doc_list_children_files","wps_cloud_doc_create_file","wps_cloud_doc_upload_file","wps_cloud_doc_extract_file_content","wps_cloud_doc_get_file_meta","wps_cloud_doc_search_files","wps_airpage_create_file","wps_airpage_create_block_content","wps_airpage_query_document_blocks","wps_airpage_batch_query_document_blocks","wps_airpage_delete_block_content","wps_airpage_batch_delete_block_content","wps_airpage_update_document_block","wps_airpage_batch_update_document_blocks","wps_meeting_rooms_list","wps_meeting_rooms_get","wps_meeting_rooms_search","wps_meeting_room_bookings_batch_get","wps_meeting_room_bookings_update_status"])}),xi=k.object({enabled:k.boolean().default(!0),text:k.string().default("\u5185\u5BB9\u5904\u7406\u4E2D\uFF0C\u8BF7\u7A0D\u5019...")}),vi=k.object({enabled:k.boolean().default(!1),logLevel:k.enum(["debug","info","warn","error"]).default("info"),endpoint:k.string().optional(),connectTimeoutMs:k.number().min(3e3).max(12e4).default(2e4),pongTimeout:k.number().min(3e4).max(3e5).default(15e4),autoReconnect:k.boolean().default(!0),reconnectBaseInterval:k.number().min(500).max(1e4).default(1e3),reconnectMaxInterval:k.number().min(1e4).max(3e5).default(6e4),reconnectMultiplier:k.number().min(1.5).max(3).default(2),reconnectMaxRetry:k.number().min(-1).max(100).default(-1),reconnectJitter:k.number().min(0).max(.5).default(.2)}),Ti=k.object({path:k.string().default("/wps/webhook"),port:k.number().default(3e3)}),_r="https://365.kdocs.cn/woa/openclaw/callback",St=k.object({enabled:k.boolean().default(!0),appId:k.string().describe("WPS App ID (client_id)"),appSecret:k.string().describe("WPS App Secret (client_secret)"),companyId:k.string().optional().describe("WPS Company ID"),baseUrl:k.string().default("https://openapi.wps.cn"),enableEncryption:k.boolean().default(!0),webhook:Ti.optional(),sdk:vi.optional(),dmPolicy:Ii.optional(),allowFrom:k.array(k.string()).optional(),groupPolicy:k.enum(["open","allowlist"]).optional(),groups:k.record(k.string(),Si).optional(),instantAck:xi.optional(),robotJoinGroupMessage:k.string().optional(),mcp:ki.optional()}),nn=St.partial().extend({defaultAccountId:k.string().optional(),accounts:k.record(k.string(),St).optional()});Fs=new Set(["accounts","defaultAccountId"]);E="wps-xiezuo",We="wps-xiezuo",he="default"});import{randomBytes as Oi,createCipheriv as Gs,createDecipheriv as Hs}from"node:crypto";import{existsSync as sn,mkdirSync as Ks,readFileSync as Pi,writeFileSync as $i,unlinkSync as Rl}from"node:fs";import{join as Xt}from"node:path";import{homedir as Ei}from"node:os";function Di(){return process.platform==="win32"?Xt(Ei(),"AppData","Local",Ai):Xt(Ei(),".local","share",Ai)}function qi(){let e=Di();return sn(e)||Ks(e,{recursive:!0,mode:448}),e}function Ui(){let e=qi(),t=Xt(e,Js);if(sn(t)){let n=Pi(t);if(n.length===32)return n}let r=Oi(32);return $i(t,r,{mode:384}),r}function Xs(e,t){let r=Oi(xt),n=Gs(Ci,t,r,{authTagLength:Jt}),o=Buffer.concat([n.update(e),n.final()]),i=n.getAuthTag();return Buffer.concat([r,i,o])}function Vs(e,t){if(e.length<xt+Jt+1)throw new Error("Invalid encrypted data: too short");let r=e.subarray(0,xt),n=e.subarray(xt,xt+Jt),o=e.subarray(xt+Jt),i=Hs(Ci,t,r,{authTagLength:Jt});return i.setAuthTag(n),Buffer.concat([i.update(o),i.final()])}function an(){try{let e=Di(),t=Xt(e,Ri);if(!sn(t))return{};let r=Ui(),n=Pi(t),o=Vs(n,r),i=JSON.parse(o.toString("utf8"));return!i||typeof i!="object"?{}:i}catch{return{}}}function dn(e){try{let t=Ui(),r=JSON.stringify(e,null,2),n=Xs(Buffer.from(r,"utf8"),t),o=qi(),i=Xt(o,Ri);$i(i,n,{mode:384})}catch{}}function Vt(e){let t=an();e in t&&(delete t[e],dn(t))}var Ai,Js,Ri,Ci,xt,Jt,Ni=G(()=>{"use strict";Ai="openclaw-wps-xiezuo",Js="master.key",Ri="tokens.enc",Ci="aes-256-gcm",xt=12,Jt=16});var Li={};wt(Li,{clearGrantedScopes:()=>wr,deleteUserToken:()=>br,exchangeCodeForToken:()=>kr,getUserToken:()=>ve,getUserTokenEntry:()=>Tt,hasUserToken:()=>Wi,putUserToken:()=>yr,restoreRefreshTimers:()=>Sr,setRefreshContext:()=>gr,takeUserToken:()=>Mi});function it(e,t){return`${e}:${t}`}function gr(e,t){cn.set(e,t)}function vt(){if(!ji){ji=!0;try{let e=an();for(let[t,r]of Object.entries(e))!r||typeof r!="object"||!r.accessToken||!r.expiresAt||oe.set(t,r)}catch{}}}function ln(){let e={};for(let[t,r]of oe)e[t]=r;dn(e)}function yr(e,t,r){vt();let n=it(e,t);oe.set(n,r),ln(),pn(e,t,r)}function ve(e,t){vt();let r=it(e,t),n=oe.get(r);return n?Date.now()>=n.expiresAt?(oe.delete(r),Ir(r),Vt(r),null):n.accessToken:null}function Tt(e,t){vt();let r=it(e,t),n=oe.get(r);return n?Date.now()>=n.expiresAt?(oe.delete(r),Ir(r),Vt(r),null):n:null}function wr(e,t){vt();let r=it(e,t),n=oe.get(r);n&&(n.grantedScopes=void 0,ln())}function br(e,t){vt();let r=it(e,t);oe.delete(r),Ir(r),Vt(r)}function Mi(e,t){return ve(e,t)}function Wi(e,t){return ve(e,t)!==null}function Ir(e){let t=nt.get(e);t&&(clearTimeout(t),nt.delete(e))}function pn(e,t,r){let n=it(e,t);if(Ir(n),!r.refreshToken)return;let o=Math.max(r.expiresAt-Date.now()-Ys,1e4),i=setTimeout(()=>{Zs(e,t).catch(s=>{ie(e)?.warn?.(`[TokenStore] Refresh failed for account=${e} user=${t}, token cleared \u2014 next tool call will trigger re-auth: ${String(s)}`),oe.delete(n),nt.delete(n),Vt(n)})},o);i.unref?.(),nt.set(n,i)}async function Zs(e,t){let r=it(e,t),n=oe.get(r);if(!n?.refreshToken){nt.delete(r);return}let o=cn.get(e);if(!o){ie(e)?.warn?.(`[TokenStore] Refresh skipped for account=${e} user=${t}: refreshCtx not set yet`),nt.delete(r);return}let i=o.baseUrl.replace(/\/$/,""),s=new URLSearchParams({grant_type:"refresh_token",client_id:o.appId,client_secret:o.appSecret,refresh_token:n.refreshToken}),a=await fetch(`${i}/oauth2/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()}),l=await a.text(),c;try{c=JSON.parse(l)}catch{throw new pe(`OAuth refresh: non-JSON response (${a.status}): ${l.slice(0,200)}`)}if(!a.ok||typeof c.code=="number"&&c.code!==0)throw new pe(`OAuth refresh failed (${a.status}): ${JSON.stringify(c)}`);let d=typeof c.access_token=="string"?c.access_token:"";if(!d)throw new pe(`OAuth refresh: missing access_token: ${JSON.stringify(c)}`);let p=typeof c.expires_in=="number"?c.expires_in:7200,u=typeof c.scope=="string"&&c.scope?c.scope.split(/[,\s]+/).filter(Boolean):void 0,_={accessToken:d,refreshToken:typeof c.refresh_token=="string"?c.refresh_token:n.refreshToken,expiresAt:Date.now()+p*1e3,openid:typeof c.openid=="string"?c.openid:n.openid,grantedScopes:u??n.grantedScopes};oe.set(r,_),ln(),pn(e,t,_)}function Sr(e){vt();for(let[t,r]of oe){if(!r.refreshToken||Date.now()>=r.expiresAt||nt.has(t))continue;let[n,o]=t.split(":",2);!n||!o||e&&n!==e||cn.has(n)&&pn(n,o,r)}}async function kr(e){let t=e.baseUrl.replace(/\/$/,""),r=new URLSearchParams({grant_type:"authorization_code",client_id:e.appId,client_secret:e.appSecret,code:e.code,redirect_uri:e.redirectUri??_r}),n=await fetch(`${t}/oauth2/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r.toString()}),o=await n.text(),i;try{i=JSON.parse(o)}catch{throw new pe(`OAuth code exchange: non-JSON response (${n.status}): ${o.slice(0,200)}`)}if(!n.ok||typeof i.code=="number"&&i.code!==0)throw new pe(`OAuth code exchange failed (${n.status}): ${JSON.stringify(i)}`);let s=typeof i.access_token=="string"?i.access_token:"";if(!s)throw new pe(`OAuth code exchange: missing access_token in response: ${JSON.stringify(i)}`);let a=typeof i.expires_in=="number"?i.expires_in:7200,l=typeof i.scope=="string"&&i.scope?i.scope.split(/[,\s]+/).filter(Boolean):void 0;return{accessToken:s,refreshToken:typeof i.refresh_token=="string"?i.refresh_token:"",expiresAt:Date.now()+a*1e3,openid:typeof i.openid=="string"?i.openid:"",grantedScopes:l}}var oe,nt,Ys,cn,ji,Le=G(()=>{"use strict";bt();kt();ue();Ni();oe=new Map,nt=new Map,Ys=5*6e4,cn=new Map;ji=!1});function un(e){let{requiredScopes:t,accountId:r,wpsUserId:n}=e,o=!1,i=ke(r);if(i.length>0&&t.length>0){let a=new Set(i.map(c=>c.name)),l=t.filter(c=>!a.has(c));if(l.length>0)return{ok:!1,reason:"app_scope_missing",missingScopes:l,message:`\u8BE5\u529F\u80FD\u9700\u8981\u5728 WPS \u5F00\u653E\u5E73\u53F0\u5F00\u901A\u4EE5\u4E0B\u6743\u9650\uFF1A${l.join(", ")}`};o=!0}if(!ve(r,n))return{ok:!1,reason:"no_token",appScopeVerified:o,message:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u4F7F\u7528\u6B64\u529F\u80FD\u3002"};if(o&&t.length>0){let a=Tt(r,n);if(Array.isArray(a?.grantedScopes)){let l=new Set(a.grantedScopes),c=t.filter(d=>!l.has(d));if(c.length>0)return{ok:!1,reason:"user_scope_insufficient",appScopeVerified:o,missingScopes:c,message:`\u9700\u8981\u8865\u5145\u6388\u6743\u4EE5\u4E0B\u6743\u9650\uFF1A${c.join(", ")}`}}}return{ok:!0,appScopeVerified:o}}var fn=G(()=>{"use strict";ue();Le()});function ta(e){return e===401?"invalid app credentials (check client_id/client_secret)":e===403?"app not authorized for this enterprise or scope":e===429?"rate limited by WPS token endpoint":e>=500?"WPS OAuth service unavailable":"unexpected OAuth response"}function R(e){let t=`${e.clientId}@${e.baseUrl}`,r=zi.get(t);return r||(r=new xr(e),zi.set(t,r)),r}var Qs,ea,xr,zi,_n=G(()=>{"use strict";bt();Qs=6e4,ea=["/oauth2/token","/openapi/oauth2/token"];xr=class{creds;token=null;inFlight=null;constructor(t){this.creds=t}async getToken(){if(this.token&&Date.now()<this.token.expiresAt-Qs)return this.token.accessToken;if(this.inFlight)return this.inFlight;this.inFlight=this.requestToken();try{return await this.inFlight}finally{this.inFlight=null}}invalidate(){this.token=null}async requestToken(){let t=this.creds.baseUrl.replace(/\/$/,""),r="unknown token error";for(let n of ea){let o=`${t}${n}`,i;try{i=await fetch(o,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"client_credentials",client_id:this.creds.clientId,client_secret:this.creds.clientSecret})})}catch(a){r=`Network error requesting token from ${o}: ${String(a)}`;continue}if(!i.ok){let a=await i.text();r=`Token request failed (${i.status}) at ${o}: ${ta(i.status)}; body=${a}`;continue}let s=await i.json();if(s.code!==void 0&&s.code!==0){r=`WPS OAuth error (code ${s.code}): ${s.msg??"unknown"}`;continue}if(!s.access_token||!s.expires_in){r=`Invalid token response from ${o}: missing access_token or expires_in`;continue}return this.token={accessToken:s.access_token,expiresAt:Date.now()+s.expires_in*1e3},this.token.accessToken}throw new pe(r)}},zi=new Map});function C(e,t){return new Yt(e,new vr(t))}function mn(e,t){return new Yt(e,new Tr(t))}var vr,Tr,Yt,Er=G(()=>{"use strict";bt();vr=class{tokenStore;constructor(t){this.tokenStore=t}async getHeaders(){return{Authorization:`Bearer ${await this.tokenStore.getToken()}`}}},Tr=class{accessToken;constructor(t){this.accessToken=t}async getHeaders(){return{Authorization:`Bearer ${this.accessToken}`}}},Yt=class{baseUrl;auth;constructor(t,r){this.baseUrl=t,this.auth=r}async request(t){let r=await this.auth.getHeaders(),n=this.buildUrl(t.path,t.query),o=t.method??"GET",i=await fetch(n,{method:o,headers:{"Content-Type":"application/json",...r,...t.headers??{}},body:t.body?JSON.stringify(t.body):void 0}),s=i.headers.get("X-Request-Id")??i.headers.get("x-request-id")??i.headers.get("X-Trace-Id")??i.headers.get("x-trace-id")??void 0;if(!i.ok){let a=await i.text(),l;try{let u=JSON.parse(a);l=u.code??u.result}catch{}let{hint:c,retriable:d}=Vr(i.status),p=s?` request_id=${s}`:"";throw console.error(`[WPS-API-ERROR] ${i.status} ${o} ${t.path}${p} body=${a}`),new Oe(`WPS API error (${i.status} ${o} ${t.path}): ${a}`,{stage:"http",method:o,path:t.path,httpStatus:i.status,wpsCode:l,hint:c,retriable:d,requestId:s})}return this.parseResponse(i,o,t.path,s)}buildUrl(t,r){let n=new URL(t,this.baseUrl);if(r){for(let[o,i]of Object.entries(r))if(i!==void 0)if(Array.isArray(i))for(let s of i)n.searchParams.append(o,s);else n.searchParams.set(o,String(i))}return n.toString()}async parseResponse(t,r,n,o){let i=await t.text();if(!i||i.trim()==="")return{};let s;try{s=JSON.parse(i)}catch{throw new Oe(`Failed to parse JSON from ${r} ${n}: ${i.slice(0,200)}`,{stage:"parse",method:r,path:n,hint:"response is not valid JSON",retriable:!1})}let a=s.code??s.result;if(a!==void 0&&a!==0&&a!=="ok"){let l=String(a)==="40300001"?"permission denied by WPS business policy":"WPS business validation failed",c=s.request_id??o,d=c?` request_id=${String(c)}`:"";throw console.error(`[WPS-API-ERROR] biz_code=${String(a)} ${r} ${n}${d} msg=${s.msg??s.message??"unknown"}`),new Oe(`WPS business error code=${String(a)}: ${s.msg??s.message??"unknown"}`,{stage:"business",method:r,path:n,wpsCode:a,hint:l,retriable:!1,requestId:c?String(c):void 0})}return s}}});import{imageSize as ra}from"image-size";function Zt(e,t=0){if(!e||typeof e!="object"||t>2)return null;let r=e;for(let n of na){let o=r[n];if(typeof o=="string"&&o.trim())return o.trim()}return r.data&&typeof r.data=="object"?Zt(r.data,t+1):null}function hn(e){let t=Zt(e);if(!t)throw new Error("cannot resolve download URL from WPS API response");return t}function Et(e){try{let t=ra(Buffer.isBuffer(e)?e:Buffer.from(e));return t.width&&t.height?{width:t.width,height:t.height}:null}catch{return null}}var na,Qt=G(()=>{"use strict";na=["url","download_url","downloadUrl","file_url","fileUrl"]});function gn(e){return Fi[e]??[]}var Fi,yn=G(()=>{"use strict";Fi={calendar:["kso.calendar_events.readwrite","kso.calendar_events.read"],todo:["kso.task.readwrite","kso.task.read"],"cloud-doc":["kso.drive.readwrite","kso.file.readwrite","kso.file.read"],airsheet:["kso.airsheet.readwrite","kso.airsheet.read"],dbsheet:["kso.dbsheet.readwrite","kso.dbsheet.read"],airpage:["kso.airpage.readwrite","kso.airpage.read"]}});async function bn(e,t,r){let n=R(e);await C(e.baseUrl,n).request({method:"POST",path:`/v7/chats/${encodeURIComponent(t)}/messages/${encodeURIComponent(r)}/reactions/create`,body:{reaction_type:wn}})}async function In(e,t,r,n){try{let o=R(e);await C(e.baseUrl,o).request({method:"POST",path:`/v7/chats/${encodeURIComponent(t)}/messages/${encodeURIComponent(r)}/reactions/delete`,body:{reaction_type:wn}})}catch(o){let i=String(o);i.includes("msgRecalled")||i.includes("message_not_found")||i.includes("404")?(n?.info??console.log)(`WPS thinking reaction cleanup skipped (message gone): ${i.substring(0,100)}`):(n?.error??console.error)(`WPS thinking reaction cleanup failed: ${i}`)}}var wn,Sn=G(()=>{"use strict";_n();Er();wn="emoji_busy"});var ze=G(()=>{"use strict";bt();fn();_n();Le();Er();Qt();yn();Sn();kt()});function Nn(e){let t=Rt.get(e);return t?Date.now()-t<3e4?!0:(Rt.delete(e),!1):!1}function ho(e){Rt.set(e,Date.now()),Ma()}function go(e){Rt.delete(e)}function Ma(){let e=Date.now();if(!(e-mo<ja)){mo=e;for(let[t,r]of Rt)e-r>=3e4&&Rt.delete(t)}}function yo(e,t){if(Nn(e))return Promise.resolve();let r=$t.get(e);return r?(clearTimeout(r.timer),new Promise(n=>{r.waiters.push(n),r.timer=setTimeout(()=>{let o=$t.get(e);$t.delete(e);let i=()=>{o?.waiters.forEach(s=>s())};t().then(i,i)},150),r.timer.unref?.()})):new Promise(n=>{let o={timer:setTimeout(()=>{let i=$t.get(e);$t.delete(e);let s=()=>{i?.waiters.forEach(a=>a())};t().then(s,s)},150),waiters:[n]};o.timer.unref?.(),$t.set(e,o)})}var $t,Rt,ja,mo,jn=G(()=>{"use strict";$t=new Map,Rt=new Map;ja=6e4,mo=0});var st={};wt(st,{ensureDelegatedScopesFresh:()=>za,invalidateDelegatedScopeCache:()=>Wa,markDelegatedScopeCacheFresh:()=>La,startDelegatedScopeRefresh:()=>Ba,stopAllDelegatedScopeRefresh:()=>Ha,stopDelegatedScopeRefresh:()=>Ga});function Wa(e){nr.delete(e)}function La(e){nr.set(e,Date.now())}async function za(e){let t=nr.get(e);if(t&&Date.now()-t<bo)return;let r=Mn.get(e);if(r)return r;let n=Fa(e).finally(()=>{Mn.delete(e)});return Mn.set(e,n),n}async function Fa(e){let t=ie(e);try{let r=tt(e),n=R(r),s=((await C(r.baseUrl,n).request({method:"GET",path:`/v7/developer/apps/${encodeURIComponent(r.clientId)}`,query:{lang:"zh-CN"}})).data?.scopes??[]).filter(p=>p.auth_types?.includes("delegated")).map(p=>({name:p.name??"",description:p.description??""})).filter(p=>p.name),a=ke(e),l=new Set(a.map(p=>p.name)),c=new Set(s.map(p=>p.name));(s.length!==a.length||s.some(p=>!l.has(p.name))||a.some(p=>!c.has(p.name)))&&(rt(e,s),t?.info?.(`[scope-cache] delegated scopes updated for account=${e}, count=${s.length}`)),nr.set(e,Date.now())}catch(r){nr.set(e,Date.now()-bo+wo),t?.warn?.(`[scope-cache] refresh failed for account=${e}, backing off ${wo}ms: ${String(r)}`)}}function Ba(e){}function Ga(e){}function Ha(){}var bo,wo,nr,Mn,at=G(()=>{"use strict";ue();ze();bo=30*1e3,wo=10*1e3,nr=new Map,Mn=new Map});var So={};wt(So,{dispatchSyntheticAuthComplete:()=>Ka});async function Ka(e){if(e.originalMessageId){let t=`${e.accountId}:${e.originalMessageId}`,r=Pr.get(t);if(r&&Date.now()-r<Io){e.log?.debug?.("synthetic message deduplicated",{dedupKey:t});return}Pr.set(t,Date.now());for(let[n,o]of Pr)Date.now()-o>Io&&Pr.delete(n)}try{let t=R(e.creds);await C(e.creds.baseUrl,t).request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:{type:e.receiverType,receiver_id:e.receiverId},content:{text:{content:"\u7528\u6237\u5DF2\u5B8C\u6210 WPS \u8D26\u53F7\u6388\u6743\uFF0C\u8BF7\u7EE7\u7EED\u6267\u884C\u4E4B\u524D\u7684\u64CD\u4F5C\u3002",type:"markdown"}}}})}catch(t){e.log?.warn?.(`[synthetic-message] Failed to send: ${String(t)}`)}}var Io,Pr,ko=G(()=>{"use strict";ze();Io=6e4,Pr=new Map});var Fn={};wt(Fn,{buildAuthCard:()=>Eo,buildAuthSuccessCard:()=>Ao,buildAuthorizeUrl:()=>To,decodeState:()=>vo,encodeState:()=>xo,handleAuthEvent:()=>Za,sendAuthCard:()=>zn});import{randomBytes as Ja}from"node:crypto";function Xa(e){let{batchKey:t,totalParts:r}=e;if(!t||!r||r<=1)return!0;let n=Wn.get(t);return n||(n={completed:0,total:r},Wn.set(t,n),setTimeout(()=>Wn.delete(t),15*6e4).unref?.()),n.completed+=1,n.completed>=n.total}function xo(e){let t=Ja(16).toString("hex");e.nonce=t;let r=t;return ir.set(r,e),setTimeout(()=>ir.delete(r),10*6e4).unref?.(),r}function vo(e){let t=ir.get(e);return t&&ir.delete(e),t??null}function To(e){let t=new URL("/oauth2/auth",e.baseUrl);return t.searchParams.set("response_type","code"),t.searchParams.set("client_id",e.appId),t.searchParams.set("redirect_uri",e.redirectUri),t.searchParams.set("scope",e.scopes.join(",")),t.searchParams.set("state",e.state),t.toString()}function Eo(e,t,r){let n=t.length>$r,i=(n?t.slice(0,$r):t).join(`
|
|
2
2
|
`)+(n?`
|
|
3
3
|
... \u7B49\u5171 ${t.length} \u9879\u6743\u9650`:""),s=r?.totalScopes??t.length,a=r&&r.totalParts>1?`\uFF08\u7B2C ${r.partIndex}/${r.totalParts} \u7EC4\uFF0C\u672C\u7EC4 ${t.length} \u9879\uFF09`:"",l=r&&r.totalParts>1?`\u8BF7\u6388\u6743\u4EE5\u65B9\u4FBF\u7EE7\u7EED\u64CD\u4F5C\uFF08${r.partIndex}/${r.totalParts}\uFF09`:"\u8BF7\u6388\u6743\u4EE5\u65B9\u4FBF\u7EE7\u7EED\u64CD\u4F5C";return{card:{i18n_items:[{key:"zh-CN",value:{elements:[{text:{tag:"text",text:{content:`\u5E94\u7528\u9700\u8981\u6388\u6743 ${s} \u4E2A\u7528\u6237\u6743\u9650${a}\u3002`,text_align:"left",text_size:"small",type:"markdown"}}},{text:{tag:"text",text:{content:`**\u5C06\u8981\u6388\u6743\u7684\u6743\u9650\uFF1A**
|
|
4
4
|
|
|
5
5
|
${i}
|
|
6
6
|
`,text_align:"left",text_size:"small",type:"markdown"}}},{action:{actions:[{button:{disabled_tips:{content:"",type:"plain"},hover_tips:{content:"",type:"plain"},link:{url:e,pc_url:e,web_url:e,android_url:e,ios_url:e,harmony_url:e},margin:"0px 0px 0px 0px",style:"normal",tag:"button",text:{content:"\u524D\u5F80\u6388\u6743",type:"plain"}}}],layout:"exclusive_row",tag:"action"}},{text:{tag:"text",text:{content:`<font color='gray'>\u6388\u6743\u94FE\u63A5\u4EC5\u53EF\u4F7F\u7528\u4E00\u6B21\uFF0C10\u5206\u949F\u5185\u672A\u4F7F\u7528\u5C06\u81EA\u52A8\u8FC7\u671F</font>
|
|
7
|
-
`,text_align:"left",text_size:"small",type:"markdown"}}}],header:{subtitle:{tag:"text",text:{content:"",type:"plain"}},template:"blue",title:{tag:"text",text:{content:l,type:"plain"}}}}}]}}}function
|
|
7
|
+
`,text_align:"left",text_size:"small",type:"markdown"}}}],header:{subtitle:{tag:"text",text:{content:"",type:"plain"}},template:"blue",title:{tag:"text",text:{content:l,type:"plain"}}}}}]}}}function Va(e){if(e.length===0)return[[]];if(e.length<=Ln)return[e];let t=[];for(let r=0;r<e.length;r+=Ln)t.push(e.slice(r,r+Ln));return t}function Ao(e){let t=e.length>$r;return{card:{i18n_items:[{key:"zh-CN",value:{elements:[{text:{tag:"text",text:{content:`**\u5DF2\u5B8C\u6210\u4EE5\u4E0B\u6743\u9650\u6388\u6743\uFF1A**
|
|
8
8
|
|
|
9
|
-
${(t?e.slice(0
|
|
9
|
+
${(t?e.slice(0,$r):e).join(`
|
|
10
10
|
`)+(t?`
|
|
11
11
|
... \u7B49\u5171 ${e.length} \u9879\u6743\u9650`:"")}
|
|
12
|
-
`,text_align:"left",text_size:"small",type:"markdown"}}},{action:{actions:[{button:{disabled_tips:{content:"",type:"plain"},hover_tips:{content:"",type:"plain"},margin:"0px 0px 0px 0px",style:"disable",tag:"button",text:{content:"\u5DF2\u6388\u6743",type:"plain"}}}],layout:"exclusive_row",tag:"action"}}],header:{subtitle:{tag:"text",text:{content:"",type:"plain"}},template:"green",title:{tag:"text",text:{content:"\u6388\u6743\u5DF2\u5B8C\u6210",type:"plain"}}}}}]}}}async function Fn(e){if(e.accountId){let{ensureDelegatedScopesFresh:c}=await Promise.resolve().then(()=>(lt(),ct));await c(e.accountId)}let t;if(e.scopes&&e.scopes.names.length>0){let c=xe(e.accountId),d=new Set(c.map(u=>u.name)),p=e.scopes.names.filter(u=>!d.has(u));p.length>0&&c.length>0&&oe(e.accountId)?.warn?.(`[OAuth] Requested scopes not in delegated list: ${p.join(", ")}. \u9700\u5728\u5F00\u653E\u5E73\u53F0\u540E\u53F0\u5F00\u901A\u5BF9\u5E94\u80FD\u529B\u6743\u9650\u3002`),t=e.scopes.names}else{let c=xe(e.accountId);if(c.length===0)return oe(e.accountId)?.error?.("[OAuth] No delegated scopes available. \u5E94\u7528\u672A\u914D\u7F6E delegated \u6743\u9650\uFF0C\u8BF7\u5728\u5F00\u653E\u5E73\u53F0\u540E\u53F0\u5F00\u901A\u3002"),null;t=c.map(d=>d.name)}let r=hr(e.wpsCfg),n=R(e.creds),o=C(e.creds.baseUrl,n),i=e.wpsCfg.baseUrl??"https://openapi.wps.cn",s=Ya(t),a=null,l=s.length>1?`${e.accountId??""}:${e.wpsUserId}:${Date.now()}`:void 0;for(let c=0;c<s.length;c+=1){let d=s[c],p=Oo({accountId:e.accountId,wpsUserId:e.wpsUserId,receiverType:e.receiverType,receiverId:e.receiverId,nonce:"",originalMessage:e.originalMessage,requestedScopeNames:[...d],totalParts:s.length,batchKey:l}),u=Ro({baseUrl:i,appId:e.creds.clientId,scopes:d,state:p,redirectUri:r}),_=Co(u,d,{partIndex:c+1,totalParts:s.length,totalScopes:t.length}),f={type:"card",receiver:{type:e.receiverType,receiver_id:e.receiverId},content:_},y=(await o.request({method:"POST",path:"/v7/messages/create",body:f})).data?.message_id??"",m=sr.get(p);m&&(m.messageId=y),a||(a={messageId:y,authorizeUrl:u})}return a}async function Za(e,t,r,n){if(t)try{let o=R(e),i=C(e.baseUrl,o),s=Do(r);await i.request({method:"POST",path:`/v7/messages/${encodeURIComponent(t)}/update`,body:{type:"card",content:s}})}catch(o){n?.warn?.(`Failed to update auth card: ${String(o)}`)}}async function Qa(e){let{code:t,creds:r,log:n}=e,o=e.state?$o(e.state):null,i=o?.accountId??e.accountId,s=o?.wpsUserId??e.userId??"";if(!i){n?.warn?.("[OAuth] Missing accountId in state and opts, cannot store token securely \u2014 aborting");return}if(!s){n?.warn?.(`[OAuth] Cannot determine user: state=${e.state}, userId=${e.userId}`);return}e.accountId&&o?.accountId&&e.accountId!==o.accountId&&n?.warn?.(`[OAuth] accountId mismatch: state=${o.accountId} opts=${e.accountId} \u2014 using state accountId, but token exchange uses opts.creds (${r.clientId})`),n?.info?.(`[OAuth] Auth event for account=${i} user=${s}, code=${t.slice(0,8)}..., hasState=${!!o}`);let a=hr(e.wpsCfg),{getLazyCreds:l}=await Promise.resolve().then(()=>(ue(),Xt)),c=r;try{c=l(i)}catch{n?.warn?.(`[OAuth] Could not resolve creds for account=${i}, falling back to opts.creds`)}let d=await xr({appId:c.clientId,appSecret:c.clientSecret,baseUrl:c.baseUrl,code:t,redirectUri:a}),p=d.openid||"";if(o?.wpsUserId&&p&&p!==o.wpsUserId){n?.warn?.(`[OAuth] Identity mismatch: expected=${o.wpsUserId}, actual=${p}`);try{let f=R(c);await C(c.baseUrl,f).request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:{type:o.receiverType,receiver_id:o.receiverId},content:{text:{content:"\u6388\u6743\u5931\u8D25\uFF1A\u5B8C\u6210\u6388\u6743\u7684\u7528\u6237\u4E0E\u8BF7\u6C42\u6388\u6743\u7684\u7528\u6237\u4E0D\u4E00\u81F4\u3002\u8BF7\u7531\u672C\u4EBA\u70B9\u51FB\u6388\u6743\u5361\u7247\u5B8C\u6210\u6388\u6743\u3002",type:"markdown"}}}})}catch(f){n?.warn?.(`[OAuth] Failed to send identity mismatch notice: ${String(f)}`)}return}let{ensureDelegatedScopesFresh:u}=await Promise.resolve().then(()=>(lt(),ct));await u(i);{let f=(o?.requestedScopeNames??[]).filter(Boolean),g=Array.isArray(d.grantedScopes)?d.grantedScopes:[],y=Ot(i,s),m=Array.isArray(y?.grantedScopes)?y.grantedScopes:[];if(g.length>0){let h=new Set([...m,...g,...f]);d.grantedScopes=[...h]}else if(f.length>0){let h=new Set([...m,...f]);d.grantedScopes=[...h]}else m.length>0?d.grantedScopes=m:d.grantedScopes=xe(i).map(h=>h.name).filter(Boolean)}if(wr(i,s,d),So(`${i}:${s}`),n?.info?.(`[OAuth] Token exchange success for account=${i} user=${s}, openid=${d.openid}, expiresAt=${new Date(d.expiresAt).toISOString()}, hasRefresh=${!!d.refreshToken}`),o?.messageId){let f=o.requestedScopeNames&&o.requestedScopeNames.length>0?o.requestedScopeNames.filter(g=>g.length>0):xe(i).map(g=>g.name).filter(g=>g.length>0);await Za(r,o.messageId,f,n)}if(o?Va(o):!0){let{dispatchSyntheticAuthComplete:f}=await Promise.resolve().then(()=>(Po(),Ao));await f({accountId:i,creds:c,receiverType:o?.receiverType??"user",receiverId:o?.receiverId??s,originalMessageId:o?.messageId,log:n})}else n?.info?.(`[OAuth] Batch ${o?.batchKey} not complete yet (${o?.totalParts} parts), deferring synthetic message`)}var sr,Ln,Rr,zn,Cr=H(()=>{"use strict";Fe();Be();ue();Mn();Et();sr=new Map,Ln=new Map;Rr=6;zn=25});var Ko={};St(Ko,{detectScopeChanges:()=>wd,loadPersistedScopes:()=>Go,savePersistedScopes:()=>Ho});import{existsSync as zo,readFileSync as md,writeFileSync as hd,mkdirSync as gd}from"node:fs";import{join as qr}from"node:path";import{homedir as Wo}from"node:os";function Bo(){return process.platform==="win32"?qr(Wo(),"AppData","Local",Lo):qr(Wo(),".local","share",Lo)}function yd(){let e=Bo();return zo(e)||gd(e,{recursive:!0,mode:448}),e}function Go(){try{let e=Bo(),t=qr(e,Fo);if(!zo(t))return{};let r=md(t,"utf8");return JSON.parse(r)}catch{return{}}}function Ho(e){try{let t=yd(),r=qr(t,Fo);hd(r,JSON.stringify(e,null,2),{mode:384})}catch{}}function wd(e,t){let r=Go(),n=new Set(r[e]??[]),o=new Set(t),i=t.filter(a=>!n.has(a)),s=[...n].filter(a=>!o.has(a));return r[e]=t,Ho(r),{added:i,removed:s}}var Lo,Fo,Jo=H(()=>{"use strict";Lo="openclaw-wps-xiezuo",Fo="delegated-scopes.json"});Be();var Ee=null;(async()=>{try{Ee=await import("openclaw/plugin-sdk"),console.log("[sdk-helpers] openclaw/plugin-sdk \u52A0\u8F7D\u6210\u529F")}catch(e){Ee=null,console.log("[sdk-helpers] openclaw/plugin-sdk \u52A0\u8F7D\u5931\u8D25\uFF0C\u4F7F\u7528 fallback:",e instanceof Error?e.message:String(e))}})();function Vi(){return typeof Ee?.emptyPluginConfigSchema=="function"?Ee.emptyPluginConfigSchema():{type:"object",additionalProperties:!1,properties:{}}}function Yi(e){return typeof Ee?.buildChannelConfigSchema=="function"?Ee.buildChannelConfigSchema(e):e}function Zi(e){return typeof Ee?.formatPairingApproveHint=="function"?Ee.formatPairingApproveHint(e):`Run pairing approval command for channel '${e}'.`}function Qi(e,t){return typeof Ee?.waitUntilAbort=="function"?Ee.waitUntilAbort(e,t):new Promise(r=>{let n=()=>{e.removeEventListener("abort",n),t().finally(r)};if(e.aborted){n();return}e.addEventListener("abort",n,{once:!0})})}Be();import{existsSync as bd,readFileSync as Id}from"node:fs";import{readFile as Xo}from"node:fs/promises";import{homedir as kd}from"node:os";import Nr from"node:path";var Pr="kso.app_chat.message";import*as $t from"node:crypto";function eo(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.encrypted_data=="string"&&typeof t.nonce=="string"&&typeof t.signature=="string"&&typeof t.topic=="string"&&typeof t.time=="number"}function to(e){let t=`${e.appId}:${e.topic}:${e.nonce}:${e.time}:${e.encryptedData}`,r=$t.createHmac("sha256",e.appSecret);return r.update(t),r.digest("base64url").replace(/=+$/,"")===e.signature}function ro(e,t,r){let n=$t.createHash("md5").update(t).digest("hex"),o=Buffer.from(n,"utf-8"),i=Buffer.from(r,"utf-8").subarray(0,16),s=Buffer.from(e,"base64"),a=$t.createDecipheriv("aes-256-cbc",o,i),l=a.update(s);return l=Buffer.concat([l,a.final()]),l.toString("utf-8")}function vn(e){return typeof e=="string"&&e.trim()!==""&&e!==Pr}function dt(e){return e&&typeof e=="object"?e:{}}function xn(...e){for(let t of e){if(typeof t=="string"&&t.trim())return t.trim();if(typeof t=="number"&&Number.isFinite(t))return String(t)}return""}function oa(e){let t=e.content;if(!t||typeof t!="object")return{};let r=t,n=r.text;if(n&&typeof n=="object"&&n!==null&&"content"in n){let a=n.content;if((typeof a=="string"?a.trim():typeof a=="number"&&Number.isFinite(a)?String(a):"")!=="")return r}if(typeof r.text=="string")return{text:{content:r.text,type:"plain"}};let o=r.image;if(o&&typeof o=="object"){let a=typeof o.file_id=="string"?o.file_id:"",l=typeof o.storage_key=="string"?o.storage_key:"",c=typeof o.key=="string"?o.key:"",d=a||l||c;return d?{image:{...o,storage_key:d}}:r}let i=r.file;if(i&&typeof i=="object"){let a=typeof i.type=="string"?i.type:"",l=i.cloud;if((a==="cloud"||l)&&l&&typeof l=="object")return{file:{type:"cloud",cloud:l}};let c=i.file_id;if(c)return{file:{type:"local",local:{storage_key:c,name:i.name??"file"}}};let d=i.local;if(d&&typeof d=="object")return{file:{type:"local",local:d}}}let s=r.rich_text;return r}function sa(e){if(!Array.isArray(e))return;let t=e.map(r=>dt(r)).map(r=>{let n=dt(r.identity),o={id:typeof n.id=="string"?n.id:void 0,app_id:typeof n.app_id=="string"?n.app_id:void 0,name:typeof n.name=="string"?n.name:void 0,type:typeof n.type=="string"?n.type:void 0,company_id:typeof n.company_id=="string"?n.company_id:void 0},i=Object.values(o).some(s=>s!==void 0);return{type:typeof r.type=="string"?r.type:void 0,id:typeof r.id=="string"?r.id:void 0,user_id:typeof r.user_id=="string"?r.user_id:void 0,userId:typeof r.userId=="string"?r.userId:void 0,offset:typeof r.offset=="number"?r.offset:void 0,length:typeof r.length=="number"?r.length:void 0,...i?{identity:o}:{}}}).filter(r=>!!(r.id||r.user_id||r.userId||r.type||r.identity));return t.length>0?t:void 0}function aa(e){let t=dt(e),r=dt(t.sender),n=typeof t.sender_id=="string"?t.sender_id:void 0,o=typeof r.id=="string"?r.id:void 0;if(!(!n&&!o))return{sender_id:n,sender:o?{id:o}:void 0}}function no(e){let t=dt(e),r=dt(e.message),n=e.send_time<1e12?Math.floor(e.send_time*1e3):e.send_time,o=String(e.chat.id),i=String(e.message.id),s=String(e.sender.id);return{topic:typeof t.topic=="string"?t.topic:Pr,event_id:xn(t.event_id,t.id,i)||void 0,company_id:xn(t.company_id,t.companyId,t.corp_id)||void 0,chat:{id:o,type:e.chat.type},message:{id:i,type:e.message.type,content:oa(e.message),sender:{id:s,type:e.sender.type},mentions:sa(r.mentions),reply_to:aa(r.reply_to)},quote_msg_id:xn(t.quote_msg_id,t.quote_message_id,typeof r.quote_msg_id=="string"?r.quote_msg_id:void 0)||void 0,sender:{id:s,type:e.sender.type,name:e.sender.extended_attribute?.name},send_time:n}}function io(e,t,r,n){let o=dt(e);if(typeof o.challenge=="string")return n?.info?.("WPS webhook challenge verification"),{challenge:o.challenge};if(r&&eo(e)){let s=e;if(s.topic!==Pr)return n?.info?.(`WPS webhook skip non-message topic=${s.topic}`),{ok:!1,error:"skip",status:200};if(!to({appId:t.appId,appSecret:t.appSecret,topic:s.topic,nonce:s.nonce,time:s.time,encryptedData:s.encrypted_data,signature:s.signature}))return n?.error?.("WPS signature verification failed"),{ok:!1,error:"Invalid signature",status:403};try{let l=ro(s.encrypted_data,t.appSecret,s.nonce),c=JSON.parse(l);return c.topic=s.topic,c.event_id||(c.event_id=c.message?.id),n?.info?.(`WPS decrypted event: topic=${s.topic}, operation=${s.operation}`),{ok:!0,payload:c}}catch(l){return n?.error?.("WPS decryption failed:",l),{ok:!1,error:"Decryption failed",status:400}}}let i=e;return vn(i.topic)?(n?.info?.(`WPS webhook skip non-message topic=${String(i.topic)}`),{ok:!1,error:"skip",status:200}):(i.event_id||(i.event_id=i.message?.id),{ok:!0,payload:i})}function oo(e,t){return{...e,pongTimeout:t?.pongTimeout??15e4,autoReconnect:t?.autoReconnect??!0,reconnectBaseInterval:t?.reconnectBaseInterval??1e3,reconnectMaxInterval:t?.reconnectMaxInterval??6e4,reconnectMultiplier:t?.reconnectMultiplier??2,reconnectMaxRetry:t?.reconnectMaxRetry??-1,reconnectJitter:t?.reconnectJitter??.2}}import{Client as Sd,Dispatcher as xd}from"open-event-sdk";Et();Be();function k(...e){for(let t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function re(...e){for(let t of e){if(typeof t=="number"&&Number.isFinite(t))return t;if(typeof t=="string"&&t.trim()){let r=Number(t);if(Number.isFinite(r))return r}}}function Tn(e){return{kind:"image",storageKey:k(e.storage_key),name:k(e.name),mimeType:k(e.type),size:re(e.size),width:re(e.width),height:re(e.height),thumbnailStorageKey:k(e.thumbnail_storage_key)}}var da=["elements","paragraphs","blocks","fragments","items","body","children","nodes"];function so(e){for(let t of da){let r=e[t];if(Array.isArray(r)&&r.length>0)return r}return null}function ao(e){let t=e.rich_text;if(t&&typeof t=="object"){let n=t,o=so(n);if(o)return o;if(Array.isArray(n.elements))return n.elements}let r=so(e);return r||(Array.isArray(e.elements)?e.elements:null)}function co(e){let t=[],r=[],n=[],o=(i,s)=>{if(s>12||i==null||typeof i!="object")return;if(Array.isArray(i)){for(let m of i)o(m,s+1);return}let a=i,l=typeof a.type=="string"?a.type.toLowerCase():"",c=a.text_content;if(c&&typeof c=="object"){let m=c.content;typeof m=="string"&&m.trim()!==""&&r.push(m);let h=typeof m=="string"?k(m):"";h&&t.push(h)}let d=a.style_text_content;if(d&&typeof d=="object"){let m=d.text,h=typeof m=="string"?k(m):"";h&&t.push(h),typeof m=="string"&&m.trim()!==""&&r.push(m)}let p=a.mention_content;if(p&&typeof p=="object"){let m=p.text,h=typeof m=="string"?k(m):"";h&&t.push(h),typeof m=="string"&&m.trim()!==""&&r.push(m)}let u=a.link_content;if(u&&typeof u=="object"){let m=u,h=m.text,w=m.url,b=typeof h=="string"&&h.trim()!==""?h.trim():"",I=typeof w=="string"&&w.trim()!==""?w.trim():"";b&&t.push(b),b&&I?r.push(`[${b}](${I})`):b?r.push(b):I&&r.push(I)}let _=a.doc_content;if(_&&typeof _=="object"){let m=_,h=m.file;if(h&&typeof h=="object"){let w=k(h.link_url,m.link_url),b=k(h.link_id,m.link_id);n.push({kind:"file",name:k(m.text,a.alt_text),fileId:k(h.id),cloudType:!0,cloudLinkUrl:w||void 0,cloudLinkId:b||void 0})}if(l==="doc"){let w=typeof m.text=="string"?m.text.trim():"\u6587\u6863",b=m.file?.link_url,I=(typeof m.link_url=="string"?m.link_url.trim():"")||(typeof b=="string"?b.trim():"")||"";w&&t.push(w),I?r.push(`[${w}](${I})`):w&&r.push(w)}}let f=a.image_content;if(f&&typeof f=="object"){let m=f,h=typeof m.storage_key=="string"?m.storage_key.trim():"";if(h&&(n.push(Tn(m)),l==="image"||l==="custom_emoji")){let w=typeof m.name=="string"?m.name.trim():"\u56FE\u7247";r.push(``)}}if(!(c&&typeof c=="object"||d&&typeof d=="object"||p&&typeof p=="object"||u&&typeof u=="object"||f&&typeof f=="object"||_&&typeof _=="object")&&l!=="nl"&&l!=="ol"&&l!=="ul"){let m=k(a.alt_text);m&&t.push(m)}if(Array.isArray(a.elements))for(let m of a.elements)o(m,s+1);let y=a.runs;if(Array.isArray(y))for(let m of y)o(m,s+1);for(let m of["inline_entities","segments","inlines","spans"]){let h=a[m];if(Array.isArray(h))for(let w of h)o(w,s+1)}};for(let i of e)o(i,0);return{plainTextLines:t,markdownLines:r,attachments:n}}function lo(e){let t=ao(e);if(!t)return null;let r=co(t);return{plainText:r.plainTextLines.join(`
|
|
13
|
-
`).trim(),attachments:r.attachments}}function
|
|
14
|
-
`).trim();if(s)return s}return""}
|
|
12
|
+
`,text_align:"left",text_size:"small",type:"markdown"}}},{action:{actions:[{button:{disabled_tips:{content:"",type:"plain"},hover_tips:{content:"",type:"plain"},margin:"0px 0px 0px 0px",style:"disable",tag:"button",text:{content:"\u5DF2\u6388\u6743",type:"plain"}}}],layout:"exclusive_row",tag:"action"}}],header:{subtitle:{tag:"text",text:{content:"",type:"plain"}},template:"green",title:{tag:"text",text:{content:"\u6388\u6743\u5DF2\u5B8C\u6210",type:"plain"}}}}}]}}}async function zn(e){if(e.accountId){let{ensureDelegatedScopesFresh:c}=await Promise.resolve().then(()=>(at(),st));await c(e.accountId)}let t;if(e.scopes&&e.scopes.names.length>0){let c=ke(e.accountId),d=new Set(c.map(u=>u.name)),p=e.scopes.names.filter(u=>!d.has(u));p.length>0&&c.length>0&&ie(e.accountId)?.warn?.(`[OAuth] Requested scopes not in delegated list: ${p.join(", ")}. \u9700\u5728\u5F00\u653E\u5E73\u53F0\u540E\u53F0\u5F00\u901A\u5BF9\u5E94\u80FD\u529B\u6743\u9650\u3002`),t=e.scopes.names}else{let c=ke(e.accountId);if(c.length===0)return ie(e.accountId)?.error?.("[OAuth] No delegated scopes available. \u5E94\u7528\u672A\u914D\u7F6E delegated \u6743\u9650\uFF0C\u8BF7\u5728\u5F00\u653E\u5E73\u53F0\u540E\u53F0\u5F00\u901A\u3002"),null;t=c.map(d=>d.name)}let r=mr(e.wpsCfg),n=R(e.creds),o=C(e.creds.baseUrl,n),i=e.wpsCfg.baseUrl??"https://openapi.wps.cn",s=Va(t),a=null,l=s.length>1?`${e.accountId??""}:${e.wpsUserId}:${Date.now()}`:void 0;for(let c=0;c<s.length;c+=1){let d=s[c],p=xo({accountId:e.accountId,wpsUserId:e.wpsUserId,receiverType:e.receiverType,receiverId:e.receiverId,nonce:"",originalMessage:e.originalMessage,requestedScopeNames:[...d],totalParts:s.length,batchKey:l}),u=To({baseUrl:i,appId:e.creds.clientId,scopes:d,state:p,redirectUri:r}),_=Eo(u,d,{partIndex:c+1,totalParts:s.length,totalScopes:t.length}),f={type:"card",receiver:{type:e.receiverType,receiver_id:e.receiverId},content:_},y=(await o.request({method:"POST",path:"/v7/messages/create",body:f})).data?.message_id??"",m=ir.get(p);m&&(m.messageId=y),a||(a={messageId:y,authorizeUrl:u})}return a}async function Ya(e,t,r,n){if(t)try{let o=R(e),i=C(e.baseUrl,o),s=Ao(r);await i.request({method:"POST",path:`/v7/messages/${encodeURIComponent(t)}/update`,body:{type:"card",content:s}})}catch(o){n?.warn?.(`Failed to update auth card: ${String(o)}`)}}async function Za(e){let{code:t,creds:r,log:n}=e,o=e.state?vo(e.state):null,i=o?.accountId??e.accountId,s=o?.wpsUserId??e.userId??"";if(!i){n?.warn?.("[OAuth] Missing accountId in state and opts, cannot store token securely \u2014 aborting");return}if(!s){n?.warn?.(`[OAuth] Cannot determine user: state=${e.state}, userId=${e.userId}`);return}e.accountId&&o?.accountId&&e.accountId!==o.accountId&&n?.warn?.(`[OAuth] accountId mismatch: state=${o.accountId} opts=${e.accountId} \u2014 using state accountId, but token exchange uses opts.creds (${r.clientId})`),n?.info?.(`[OAuth] Auth event for account=${i} user=${s}, code=${t.slice(0,8)}..., hasState=${!!o}`);let a=mr(e.wpsCfg),{getLazyCreds:l}=await Promise.resolve().then(()=>(ue(),Kt)),c=r;try{c=l(i)}catch{n?.warn?.(`[OAuth] Could not resolve creds for account=${i}, falling back to opts.creds`)}let d=await kr({appId:c.clientId,appSecret:c.clientSecret,baseUrl:c.baseUrl,code:t,redirectUri:a}),p=d.openid||"";if(o?.wpsUserId&&p&&p!==o.wpsUserId){n?.warn?.(`[OAuth] Identity mismatch: expected=${o.wpsUserId}, actual=${p}`);try{let f=R(c);await C(c.baseUrl,f).request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:{type:o.receiverType,receiver_id:o.receiverId},content:{text:{content:"\u6388\u6743\u5931\u8D25\uFF1A\u5B8C\u6210\u6388\u6743\u7684\u7528\u6237\u4E0E\u8BF7\u6C42\u6388\u6743\u7684\u7528\u6237\u4E0D\u4E00\u81F4\u3002\u8BF7\u7531\u672C\u4EBA\u70B9\u51FB\u6388\u6743\u5361\u7247\u5B8C\u6210\u6388\u6743\u3002",type:"markdown"}}}})}catch(f){n?.warn?.(`[OAuth] Failed to send identity mismatch notice: ${String(f)}`)}return}let{ensureDelegatedScopesFresh:u}=await Promise.resolve().then(()=>(at(),st));await u(i);{let f=(o?.requestedScopeNames??[]).filter(Boolean),g=Array.isArray(d.grantedScopes)?d.grantedScopes:[],y=Tt(i,s),m=Array.isArray(y?.grantedScopes)?y.grantedScopes:[];if(g.length>0){let h=new Set([...m,...g,...f]);d.grantedScopes=[...h]}else if(f.length>0){let h=new Set([...m,...f]);d.grantedScopes=[...h]}else m.length>0?d.grantedScopes=m:d.grantedScopes=ke(i).map(h=>h.name).filter(Boolean)}if(yr(i,s,d),go(`${i}:${s}`),n?.info?.(`[OAuth] Token exchange success for account=${i} user=${s}, openid=${d.openid}, expiresAt=${new Date(d.expiresAt).toISOString()}, hasRefresh=${!!d.refreshToken}`),o?.messageId){let f=o.requestedScopeNames&&o.requestedScopeNames.length>0?o.requestedScopeNames.filter(g=>g.length>0):ke(i).map(g=>g.name).filter(g=>g.length>0);await Ya(r,o.messageId,f,n)}if(o?Xa(o):!0){let{dispatchSyntheticAuthComplete:f}=await Promise.resolve().then(()=>(ko(),So));await f({accountId:i,creds:c,receiverType:o?.receiverType??"user",receiverId:o?.receiverId??s,originalMessageId:o?.messageId,log:n})}else n?.info?.(`[OAuth] Batch ${o?.batchKey} not complete yet (${o?.totalParts} parts), deferring synthetic message`)}var ir,Wn,$r,Ln,Rr=G(()=>{"use strict";Le();ze();ue();jn();kt();ir=new Map,Wn=new Map;$r=6;Ln=25});var Bo={};wt(Bo,{detectScopeChanges:()=>gd,loadPersistedScopes:()=>zo,savePersistedScopes:()=>Fo});import{existsSync as Mo,readFileSync as fd,writeFileSync as _d,mkdirSync as md}from"node:fs";import{join as Dr}from"node:path";import{homedir as No}from"node:os";function Lo(){return process.platform==="win32"?Dr(No(),"AppData","Local",jo):Dr(No(),".local","share",jo)}function hd(){let e=Lo();return Mo(e)||md(e,{recursive:!0,mode:448}),e}function zo(){try{let e=Lo(),t=Dr(e,Wo);if(!Mo(t))return{};let r=fd(t,"utf8");return JSON.parse(r)}catch{return{}}}function Fo(e){try{let t=hd(),r=Dr(t,Wo);_d(r,JSON.stringify(e,null,2),{mode:384})}catch{}}function gd(e,t){let r=zo(),n=new Set(r[e]??[]),o=new Set(t),i=t.filter(a=>!n.has(a)),s=[...n].filter(a=>!o.has(a));return r[e]=t,Fo(r),{added:i,removed:s}}var jo,Wo,Go=G(()=>{"use strict";jo="openclaw-wps-xiezuo",Wo="delegated-scopes.json"});ze();var Te=null;(async()=>{try{Te=await import("openclaw/plugin-sdk"),console.log("[sdk-helpers] openclaw/plugin-sdk \u52A0\u8F7D\u6210\u529F")}catch(e){Te=null,console.log("[sdk-helpers] openclaw/plugin-sdk \u52A0\u8F7D\u5931\u8D25\uFF0C\u4F7F\u7528 fallback:",e instanceof Error?e.message:String(e))}})();function Bi(){return typeof Te?.emptyPluginConfigSchema=="function"?Te.emptyPluginConfigSchema():{type:"object",additionalProperties:!1,properties:{}}}function Gi(e){return typeof Te?.buildChannelConfigSchema=="function"?Te.buildChannelConfigSchema(e):e}function Hi(e){return typeof Te?.formatPairingApproveHint=="function"?Te.formatPairingApproveHint(e):`Run pairing approval command for channel '${e}'.`}function Ki(e,t){return typeof Te?.waitUntilAbort=="function"?Te.waitUntilAbort(e,t):new Promise(r=>{let n=()=>{e.removeEventListener("abort",n),t().finally(r)};if(e.aborted){n();return}e.addEventListener("abort",n,{once:!0})})}ze();import{existsSync as yd,readFileSync as wd}from"node:fs";import{readFile as Ho}from"node:fs/promises";import{homedir as bd}from"node:os";import Ur from"node:path";var Ar="kso.app_chat.message";import*as At from"node:crypto";function Ji(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.encrypted_data=="string"&&typeof t.nonce=="string"&&typeof t.signature=="string"&&typeof t.topic=="string"&&typeof t.time=="number"}function Xi(e){let t=`${e.appId}:${e.topic}:${e.nonce}:${e.time}:${e.encryptedData}`,r=At.createHmac("sha256",e.appSecret);return r.update(t),r.digest("base64url").replace(/=+$/,"")===e.signature}function Vi(e,t,r){let n=At.createHash("md5").update(t).digest("hex"),o=Buffer.from(n,"utf-8"),i=Buffer.from(r,"utf-8").subarray(0,16),s=Buffer.from(e,"base64"),a=At.createDecipheriv("aes-256-cbc",o,i),l=a.update(s);return l=Buffer.concat([l,a.final()]),l.toString("utf-8")}function xn(e){return typeof e=="string"&&e.trim()!==""&&e!==Ar}function ot(e){return e&&typeof e=="object"?e:{}}function kn(...e){for(let t of e){if(typeof t=="string"&&t.trim())return t.trim();if(typeof t=="number"&&Number.isFinite(t))return String(t)}return""}function ia(e){let t=e.content;if(!t||typeof t!="object")return{};let r=t,n=r.text;if(n&&typeof n=="object"&&n!==null&&"content"in n){let a=n.content;if((typeof a=="string"?a.trim():typeof a=="number"&&Number.isFinite(a)?String(a):"")!=="")return r}if(typeof r.text=="string")return{text:{content:r.text,type:"plain"}};let o=r.image;if(o&&typeof o=="object"){let a=typeof o.file_id=="string"?o.file_id:"",l=typeof o.storage_key=="string"?o.storage_key:"",c=typeof o.key=="string"?o.key:"",d=a||l||c;return d?{image:{...o,storage_key:d}}:r}let i=r.file;if(i&&typeof i=="object"){let a=typeof i.type=="string"?i.type:"",l=i.cloud;if((a==="cloud"||l)&&l&&typeof l=="object")return{file:{type:"cloud",cloud:l}};let c=i.file_id;if(c)return{file:{type:"local",local:{storage_key:c,name:i.name??"file"}}};let d=i.local;if(d&&typeof d=="object")return{file:{type:"local",local:d}}}let s=r.rich_text;return r}function oa(e){if(!Array.isArray(e))return;let t=e.map(r=>ot(r)).map(r=>{let n=ot(r.identity),o={id:typeof n.id=="string"?n.id:void 0,app_id:typeof n.app_id=="string"?n.app_id:void 0,name:typeof n.name=="string"?n.name:void 0,type:typeof n.type=="string"?n.type:void 0,company_id:typeof n.company_id=="string"?n.company_id:void 0},i=Object.values(o).some(s=>s!==void 0);return{type:typeof r.type=="string"?r.type:void 0,id:typeof r.id=="string"?r.id:void 0,user_id:typeof r.user_id=="string"?r.user_id:void 0,userId:typeof r.userId=="string"?r.userId:void 0,offset:typeof r.offset=="number"?r.offset:void 0,length:typeof r.length=="number"?r.length:void 0,...i?{identity:o}:{}}}).filter(r=>!!(r.id||r.user_id||r.userId||r.type||r.identity));return t.length>0?t:void 0}function sa(e){let t=ot(e),r=ot(t.sender),n=typeof t.sender_id=="string"?t.sender_id:void 0,o=typeof r.id=="string"?r.id:void 0;if(!(!n&&!o))return{sender_id:n,sender:o?{id:o}:void 0}}function Yi(e){let t=ot(e),r=ot(e.message),n=e.send_time<1e12?Math.floor(e.send_time*1e3):e.send_time,o=String(e.chat.id),i=String(e.message.id),s=String(e.sender.id);return{topic:typeof t.topic=="string"?t.topic:Ar,event_id:kn(t.event_id,t.id,i)||void 0,company_id:kn(t.company_id,t.companyId,t.corp_id)||void 0,chat:{id:o,type:e.chat.type},message:{id:i,type:e.message.type,content:ia(e.message),sender:{id:s,type:e.sender.type},mentions:oa(r.mentions),reply_to:sa(r.reply_to)},quote_msg_id:kn(t.quote_msg_id,t.quote_message_id,typeof r.quote_msg_id=="string"?r.quote_msg_id:void 0)||void 0,sender:{id:s,type:e.sender.type,name:e.sender.extended_attribute?.name},send_time:n}}function Zi(e,t,r,n){let o=ot(e);if(typeof o.challenge=="string")return n?.info?.("WPS webhook challenge verification"),{challenge:o.challenge};if(r&&Ji(e)){let s=e;if(s.topic!==Ar)return n?.info?.(`WPS webhook skip non-message topic=${s.topic}`),{ok:!1,error:"skip",status:200};if(!Xi({appId:t.appId,appSecret:t.appSecret,topic:s.topic,nonce:s.nonce,time:s.time,encryptedData:s.encrypted_data,signature:s.signature}))return n?.error?.("WPS signature verification failed"),{ok:!1,error:"Invalid signature",status:403};try{let l=Vi(s.encrypted_data,t.appSecret,s.nonce),c=JSON.parse(l);return c.topic=s.topic,c.event_id||(c.event_id=c.message?.id),n?.info?.(`WPS decrypted event: topic=${s.topic}, operation=${s.operation}`),{ok:!0,payload:c}}catch(l){return n?.error?.("WPS decryption failed:",l),{ok:!1,error:"Decryption failed",status:400}}}let i=e;return xn(i.topic)?(n?.info?.(`WPS webhook skip non-message topic=${String(i.topic)}`),{ok:!1,error:"skip",status:200}):(i.event_id||(i.event_id=i.message?.id),{ok:!0,payload:i})}function Qi(e,t){return{...e,pongTimeout:t?.pongTimeout??15e4,autoReconnect:t?.autoReconnect??!0,reconnectBaseInterval:t?.reconnectBaseInterval??1e3,reconnectMaxInterval:t?.reconnectMaxInterval??6e4,reconnectMultiplier:t?.reconnectMultiplier??2,reconnectMaxRetry:t?.reconnectMaxRetry??-1,reconnectJitter:t?.reconnectJitter??.2}}import{Client as Id,Dispatcher as Sd}from"open-event-sdk";kt();ze();function S(...e){for(let t of e)if(typeof t=="string"&&t.trim())return t.trim();return""}function te(...e){for(let t of e){if(typeof t=="number"&&Number.isFinite(t))return t;if(typeof t=="string"&&t.trim()){let r=Number(t);if(Number.isFinite(r))return r}}}function vn(e){return{kind:"image",storageKey:S(e.storage_key),name:S(e.name),mimeType:S(e.type),size:te(e.size),width:te(e.width),height:te(e.height),thumbnailStorageKey:S(e.thumbnail_storage_key)}}var aa=["elements","paragraphs","blocks","fragments","items","body","children","nodes"];function eo(e){for(let t of aa){let r=e[t];if(Array.isArray(r)&&r.length>0)return r}return null}function to(e){let t=e.rich_text;if(t&&typeof t=="object"){let n=t,o=eo(n);if(o)return o;if(Array.isArray(n.elements))return n.elements}let r=eo(e);return r||(Array.isArray(e.elements)?e.elements:null)}function ro(e){let t=[],r=[],n=[],o=(i,s)=>{if(s>12||i==null||typeof i!="object")return;if(Array.isArray(i)){for(let m of i)o(m,s+1);return}let a=i,l=typeof a.type=="string"?a.type.toLowerCase():"",c=a.text_content;if(c&&typeof c=="object"){let m=c.content;typeof m=="string"&&m.trim()!==""&&r.push(m);let h=typeof m=="string"?S(m):"";h&&t.push(h)}let d=a.style_text_content;if(d&&typeof d=="object"){let m=d.text,h=typeof m=="string"?S(m):"";h&&t.push(h),typeof m=="string"&&m.trim()!==""&&r.push(m)}let p=a.mention_content;if(p&&typeof p=="object"){let m=p.text,h=typeof m=="string"?S(m):"";h&&t.push(h),typeof m=="string"&&m.trim()!==""&&r.push(m)}let u=a.link_content;if(u&&typeof u=="object"){let m=u,h=m.text,w=m.url,b=typeof h=="string"&&h.trim()!==""?h.trim():"",I=typeof w=="string"&&w.trim()!==""?w.trim():"";b&&t.push(b),b&&I?r.push(`[${b}](${I})`):b?r.push(b):I&&r.push(I)}let _=a.doc_content;if(_&&typeof _=="object"){let m=_,h=m.file;if(h&&typeof h=="object"){let w=S(h.link_url,m.link_url),b=S(h.link_id,m.link_id);n.push({kind:"file",name:S(m.text,a.alt_text),fileId:S(h.id),cloudType:!0,cloudLinkUrl:w||void 0,cloudLinkId:b||void 0})}if(l==="doc"){let w=typeof m.text=="string"?m.text.trim():"\u6587\u6863",b=m.file?.link_url,I=(typeof m.link_url=="string"?m.link_url.trim():"")||(typeof b=="string"?b.trim():"")||"";w&&t.push(w),I?r.push(`[${w}](${I})`):w&&r.push(w)}}let f=a.image_content;if(f&&typeof f=="object"){let m=f,h=typeof m.storage_key=="string"?m.storage_key.trim():"";if(h&&(n.push(vn(m)),l==="image"||l==="custom_emoji")){let w=typeof m.name=="string"?m.name.trim():"\u56FE\u7247";r.push(``)}}if(!(c&&typeof c=="object"||d&&typeof d=="object"||p&&typeof p=="object"||u&&typeof u=="object"||f&&typeof f=="object"||_&&typeof _=="object")&&l!=="nl"&&l!=="ol"&&l!=="ul"){let m=S(a.alt_text);m&&t.push(m)}if(Array.isArray(a.elements))for(let m of a.elements)o(m,s+1);let y=a.runs;if(Array.isArray(y))for(let m of y)o(m,s+1);for(let m of["inline_entities","segments","inlines","spans"]){let h=a[m];if(Array.isArray(h))for(let w of h)o(w,s+1)}};for(let i of e)o(i,0);return{plainTextLines:t,markdownLines:r,attachments:n}}function no(e){let t=to(e);if(!t)return null;let r=ro(t);return{plainText:r.plainTextLines.join(`
|
|
13
|
+
`).trim(),attachments:r.attachments}}function Tn(e){if(typeof e=="string"){let i=e.trim();if(i.startsWith("{"))try{let s=JSON.parse(i);if(s&&typeof s=="object"&&!Array.isArray(s))return Tn(s)}catch{}return i}if(!e||typeof e!="object")return"";let t=e,r=t.text,n="";if(typeof r=="string")n=r.trim();else if(r&&typeof r=="object"&&"content"in r){let i=r.content;typeof i=="string"?n=i.trim():typeof i=="number"&&Number.isFinite(i)&&(n=String(i))}if(n)return n;let o=to(t);if(o){let{plainTextLines:i}=ro(o),s=i.join(`
|
|
14
|
+
`).trim();if(s)return s}return""}kt();var fe=class extends Error{code;name="SessionResolverError";constructor(t,r){super(r),this.code=t}};function ge(...e){for(let t of e){if(typeof t=="string"&&t.trim())return t.trim();if(typeof t=="number"&&Number.isFinite(t))return String(t)}return""}function Pe(e){return e&&typeof e=="object"?e:{}}function io(e){return e.trim().replace(/^wps-xiezuo:/i,"").replace(/^wps:/i,"").replace(/^user:/i,"")}function oo(e,t){let r=io(e),n=io(t);return r.length>0&&n.length>0&&r===n}function da(e){if(!Array.isArray(e))return[];let t=[];for(let r of e){let n=Pe(r),o=ge(n.type).toLowerCase(),i=Pe(n.identity),s=[ge(n.id,n.user_id,n.userId,n.open_id),ge(i.app_id,i.id)].filter(Boolean);for(let a of s)t.push({type:o,id:a})}return t}var er=class{config;idempotencyStore;constructor(t,r){this.config=t,this.idempotencyStore=r}normalizeEvent(t){let r=Pe(t),n=Pe(r.chat),o=Pe(r.message),i=Pe(r.sender),s=Pe(o.sender),a=ge(r.event_id,r.eventId,o.event_id,o.eventId,o.id),l=ge(o.id,r.message_id,r.messageId,a),c=ge(r.company_id,r.companyId),d=ge(n.type).toLowerCase(),p=ge(n.id),u=ge(s.id,i.id,r.user_id,r.userId),_=Tn(o.content),f=ge(_,r.message_text,r.messageText),g=u,y;if(d==="group")y=p;else if(["p2p","single","direct"].includes(d))y=void 0;else throw new fe("E_CHAT_TYPE_INVALID",`\u672A\u77E5\u7684 chat.type: ${d||"(empty)"}`);let m=da(o.mentions),h=m.some(F=>oo(F.id,this.config.botId)),w=d==="group"&&!h&&m.length===1&&m[0]?.type!=="all",b=h||w,I=Pe(o.reply_to),x=Pe(I.sender),M=ge(x.id,I.sender_id,I.senderId),K=oo(M,this.config.botId);return{event_id:a,message_id:l,company_id:c,user_id:g,group_id:y,chat_id:p||void 0,message:f,is_at_bot:b,is_reply_to_bot:K}}resolve(t){let r=t.group_id?"group":"p2p";if(!t.message_id)throw new fe("E_MESSAGE_ID_MISSING","\u7F3A\u5C11 message_id");if(!t.event_id)throw new fe("E_EVENT_ID_MISSING","\u7F3A\u5C11 event_id");if(!t.company_id)throw new fe("E_COMPANY_ID_MISSING","\u7F3A\u5C11 company_id");if(r==="group"&&!t.group_id)throw new fe("E_GROUP_ID_MISSING","\u7FA4\u804A\u6D88\u606F\u7F3A\u5C11 group_id");if(r==="p2p"&&!t.user_id)throw new fe("E_USER_ID_MISSING","\u79C1\u804A\u6D88\u606F\u7F3A\u5C11 user_id");let n=r==="group"?`${E}:${t.company_id}:acct:${this.config.accountId??"default"}:group:${t.group_id}:bot:${this.config.botId}`:`${E}:${t.company_id}:acct:${this.config.accountId??"default"}:p2p:${t.user_id}:bot:${this.config.botId}`;return{scene:r,session_key:n,idempotency_key:t.event_id,message_id:t.message_id,company_id:t.company_id,user_id:t.user_id,group_id:t.group_id,chat_id:t.chat_id}}async checkIdempotency(t){return this.idempotencyStore.check(t)}async markProcessed(t,r=36e5){await this.idempotencyStore.mark(t,r)}};var tr=class{store=new Map;async check(t){let r=this.store.get(t);return r?Date.now()>r?(this.store.delete(t),!1):!0:!1}async mark(t,r){this.store.set(t,Date.now()+r)}cleanup(){let t=Date.now();for(let[r,n]of this.store.entries())t>n&&this.store.delete(r)}};function ca(e){if(e==null)return{};if(typeof e=="string"){let t=e.trim();if(!t)return{};if(t.startsWith("{"))try{let r=JSON.parse(t);if(r&&typeof r=="object"&&!Array.isArray(r))return r}catch{}return{text:{content:t,type:"plain"}}}return typeof e=="object"&&!Array.isArray(e)?e:{}}var la=new Set(["text","content","title","caption","desc","description","md","markdown","alt_text"]);function En(e){let t=[],r=(n,o)=>{if(!(o>6||n==null)){if(typeof n=="string"){n.trim()&&t.push(n.trim());return}if(Array.isArray(n)){for(let i of n)r(i,o+1);return}if(typeof n=="object")for(let[i,s]of Object.entries(n))(la.has(i.toLowerCase())||typeof s=="object")&&r(s,o+1)}};return r(e,0),Array.from(new Set(t))}function pa(e){let t=String(e.type??"").toLowerCase();return["image","img","pic","picture"].includes(t)?!0:!!(e.image_url??e.pic_url??e.thumb_url??e.preview_url)}function ua(e){let t=String(e.type??"").toLowerCase();return["file","attachment","doc","document"].includes(t)?!0:!!(e.file_id??e.file_name??e.mime_type??e.download_url)}function An(e){let t=[],r=(n,o)=>{if(o>8||n==null)return;if(Array.isArray(n)){for(let l of n)r(l,o+1);return}if(typeof n!="object")return;let i=n,s=i.image_content;if(s&&typeof s=="object"&&S(s.storage_key)){t.push(vn(s));return}let a=i.doc_content;if(a&&typeof a=="object"){let l=a.file;if(l&&typeof l=="object"){let c=S(l.link_url,a.link_url),d=S(l.link_id,a.link_id);t.push({kind:"file",name:S(a.text,i.alt_text),fileId:S(l.id),cloudType:!0,cloudLinkUrl:c||void 0,cloudLinkId:d||void 0})}return}if(pa(i)){let l=S(i.storage_key,i.file_id);t.push({kind:"image",storageKey:l||void 0,name:S(i.name,i.file_name,i.title),fileId:S(i.file_id,i.id),url:S(i.image_url,i.pic_url,i.thumb_url,i.preview_url,i.url),mimeType:S(i.mime_type,i.content_type),size:te(i.size,i.file_size)})}else if(ua(i)){let l=S(i.storage_key,i.file_id);t.push({kind:"file",storageKey:l||void 0,name:S(i.file_name,i.name,i.title),fileId:S(i.file_id,i.id),url:S(i.download_url,i.url,i.preview_url),mimeType:S(i.mime_type,i.content_type),size:te(i.size,i.file_size)})}for(let l of Object.values(i))r(l,o+1)};return r(e,0),t}function Or(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function Ot(e){return e.map((t,r)=>{let n=[`#${r+1}`,t.kind==="image"?"\u56FE\u7247":"\u6587\u4EF6"];return t.cloudType&&n.push("type=cloud"),t.name&&n.push(`display_name=${t.name}`),t.mimeType&&n.push(`mime=${t.mimeType}`),t.size!==void 0&&n.push(`size=${Or(t.size)}`),t.width!==void 0&&t.height!==void 0&&n.push(`${t.width}x${t.height}`),t.fileId&&n.push(`fileId=${t.fileId}`),t.cloudLinkId&&n.push(`link_id=${t.cloudLinkId}`),t.cloudLinkUrl&&n.push(`link_url=${t.cloudLinkUrl}`),t.url&&n.push(`url=${t.url}`),n.join(" | ")})}function fa(e){let t=e.image;return!t||typeof t!="object"?null:{kind:"image",storageKey:S(t.storage_key,t.file_id),name:S(t.name),mimeType:S(t.type),size:te(t.size),width:te(t.width),height:te(t.height),thumbnailStorageKey:S(t.thumbnail_storage_key)}}function _a(e){let t=e.file;if(!t||typeof t!="object")return null;let r=S(t.type),n=t.cloud;if((r==="cloud"||!r&&n)&&n&&typeof n=="object")return{kind:"file",fileId:S(n.id),cloudType:!0,cloudLinkUrl:S(n.link_url),cloudLinkId:S(n.link_id),name:S(t.name,t.file_name)||void 0};let o=t.local;return o&&typeof o=="object"?{kind:"file",storageKey:S(o.storage_key,o.file_id),name:S(o.name),size:te(o.size)}:{kind:"file",storageKey:S(t.storage_key,t.file_id),name:S(t.name,t.file_name),size:te(t.size)}}function ma(e){let t=[],r=(n,o)=>{if(o>12||n==null)return;if(typeof n=="string"){n.trim()&&t.push(n.trim());return}if(Array.isArray(n)){for(let c of n)r(c,o+1);return}if(typeof n!="object")return;let i=n,s=String(i.tag??"").toLowerCase();if(s==="hr"||s==="action"||s==="button"||s==="dropdown"||i.config)return;let a=i.text;if(a&&typeof a=="object"&&typeof a.content=="string"){let c=a.content.trim();c&&t.push(c);return}typeof a=="string"&&a.trim()&&t.push(a.trim());let l=i.title;if(l&&typeof l=="object"){let c=l.text;if(c&&typeof c=="object"&&typeof c.content=="string"){let d=c.content.trim();d&&t.push(d)}}typeof i.content=="string"&&i.content.trim()&&t.push(i.content.trim());for(let c of Object.values(i))typeof c=="object"&&r(c,o+1)};for(let n of e)r(n,0);return t}function ao(e){let t=e.card;if(!t||typeof t!="object")return null;let r=t,o=r.i18n_items?.[0]?.value,i=o?.header?.title?.text?.content??r.header?.title?.text?.content??r.header?.title?.content??"",s=o?.elements??r.elements??[],a=Array.from(new Set(ma(s))),l=[];i&&l.push(`[\u5361\u7247\u6807\u9898] ${i}`),a.length>0&&l.push(a.join(`
|
|
15
15
|
`));let c=l.join(`
|
|
16
|
-
`).trim();return{headerTitle:i,plainText:c}}function
|
|
17
|
-
`).trim(),attachments:_}}if(n==="image"){let d=
|
|
18
|
-
`),attachments:[d]}}}if(n==="file"){let d=
|
|
19
|
-
`),attachments:[d]}}}if(n==="rich_text"){let d=r,p=
|
|
20
|
-
`).trim(),y=
|
|
21
|
-
`).trim(),attachments:m}}if(n==="card"){let d=
|
|
22
|
-
`),attachments:[d]}}}let o=
|
|
23
|
-
`).trim(),i=
|
|
24
|
-
`).trim(),attachments:i}}function On(e){return e.plainText.trim()!==""||e.attachments.length>0?!1:e.kind==="rich_text"||e.kind==="file"||e.kind==="image"}
|
|
25
|
-
`)}function
|
|
26
|
-
`)}else r(`WPS quote fetch: empty data for quote_msg_id=${
|
|
27
|
-
`));if(
|
|
28
|
-
`))}ee.length>0&&(
|
|
16
|
+
`).trim();return{headerTitle:i,plainText:c}}function ha(e){let t=e.sticker;if(!t||typeof t!="object")return null;let r=t.image;return!r||typeof r!="object"?null:{kind:"image",storageKey:S(r.storage_key),name:S(r.name),mimeType:S(r.type),size:te(r.size),width:te(r.width),height:te(r.height)}}function Pt(e,t){let r=e.filter(n=>n.storageKey);return r.length===0?[]:r.map(n=>`[\u9644\u4EF6\u5F85\u4E0B\u8F7D: ${n.kind}${n.name?` "${n.name}"`:""}${n.mimeType?` ${n.mimeType}`:""}]`)}function so(e){let t=new Set,r=[];for(let n of e){let o=n.storageKey?.trim()||[n.kind,n.fileId??"",n.url??n.cloudLinkUrl??"",n.name??""].join("|");!o||t.has(o)||(t.add(o),r.push(n))}return r}function rr(e,t){let r=ca(e?.content),n=(e?.type??"").toLowerCase();if(n==="text"){let d=r,p=d.text,u=S(p?.content,...p?[]:En(d)),_=so(An(d));if(_.length===0)return{kind:"text",plainText:u,agentText:u||"[\u6536\u5230\u6D88\u606F] type=text\uFF08\u5185\u5BB9\u4E3A\u7A7A\uFF09",attachments:[]};let f=[];u&&f.push(u),u&&f.push(""),f.push(`[\u672C\u6761\u6D88\u606F type=text\uFF0C\u4F46 content \u5185\u542B\u6709\u9644\u4EF6] count=${_.length}`),f.push(...Ot(_)),f.push(...Pt(_,t));let g=_.every(h=>h.kind==="image"),y=_.every(h=>h.kind==="file"),m="mixed";return!u&&g?m="image":!u&&y?m="file":u&&(m="mixed"),{kind:m,plainText:u,agentText:f.join(`
|
|
17
|
+
`).trim(),attachments:_}}if(n==="image"){let d=fa(r);if(d){let u=[`[\u6536\u5230\u56FE\u7247: ${[d.name||"\u672A\u547D\u540D\u56FE\u7247",d.width&&d.height?`${d.width}x${d.height}`:null,d.size?Or(d.size):null].filter(Boolean).join(", ")}]`,...Ot([d])];return u.push(...Pt([d],t)),{kind:"image",plainText:"",agentText:u.join(`
|
|
18
|
+
`),attachments:[d]}}}if(n==="file"){let d=_a(r);if(d){let u=[`[\u6536\u5230\u6587\u4EF6: ${[d.name||"\u672A\u547D\u540D\u6587\u4EF6",d.size?Or(d.size):null].filter(Boolean).join(", ")}]`,...Ot([d])];return d.cloudType&&(d.cloudLinkUrl||d.cloudLinkId)?(d.cloudLinkUrl&&u.push(`[\u4E91\u6587\u4EF6\u94FE\u63A5: ${d.cloudLinkUrl}]`),d.fileId&&u.push(`[\u6587\u4EF6ID: ${d.fileId}]`)):u.push(...Pt([d],t)),{kind:"file",plainText:"",agentText:u.join(`
|
|
19
|
+
`),attachments:[d]}}}if(n==="rich_text"){let d=r,p=S(typeof d.text=="string"?d.text:void 0,d.text?.content),u=no(d),_=(u?.plainText??"").trim(),f=u?.attachments??[],g=En(d).join(`
|
|
20
|
+
`).trim(),y=S(p,_,g),m=so([...f,...An(d)]),h=!!y,w=m.length>0;if(!h&&!w)return{kind:"rich_text",plainText:"",agentText:"[\u6536\u5230\u5BCC\u6587\u672C\u6D88\u606F]\uFF08\u672A\u89E3\u6790\u51FA\u6587\u672C/\u9644\u4EF6\u5143\u4FE1\u606F\uFF09",attachments:[]};let b=[];return h&&b.push(y),w&&(h&&b.push(""),b.push(`[\u6536\u5230\u5BCC\u6587\u672C\u9644\u4EF6] count=${m.length}`),b.push(...Ot(m)),b.push(...Pt(m,t))),{kind:h&&w?"mixed":"rich_text",plainText:y,agentText:b.join(`
|
|
21
|
+
`).trim(),attachments:m}}if(n==="card"){let d=ao(r);if(d)return{kind:"card",plainText:d.plainText,agentText:d.plainText||"[\u6536\u5230\u5361\u7247\u6D88\u606F] type=card\uFF08\u672A\u89E3\u6790\u51FA\u6587\u672C\u5185\u5BB9\uFF09",attachments:[]}}if(n==="sticker"){let d=ha(r);if(d){let u=[`[\u6536\u5230\u8868\u60C5\u5305: ${[d.name||"\u672A\u547D\u540D\u8868\u60C5",d.width&&d.height?`${d.width}x${d.height}`:null,d.size?Or(d.size):null].filter(Boolean).join(", ")}]`,...Ot([d])];return u.push(...Pt([d],t)),{kind:"sticker",plainText:"",agentText:u.join(`
|
|
22
|
+
`),attachments:[d]}}}let o=En(r).join(`
|
|
23
|
+
`).trim(),i=An(r),s=!!o,a=i.length>0,l="unknown";s&&!a&&(l="text"),!s&&a&&(l=i.every(d=>d.kind==="image")?"image":"file"),s&&a&&(l="mixed");let c=[];return s&&c.push(o),a&&(c.push(""),c.push(`[\u6536\u5230\u9644\u4EF6] kind=${l} count=${i.length}`),c.push(...Ot(i)),c.push(...Pt(i,t))),!s&&!a&&c.push(`[\u6536\u5230\u6D88\u606F] type=${e?.type??"unknown"}\uFF08\u672A\u89E3\u6790\u51FA\u6587\u672C/\u9644\u4EF6\u5143\u4FE1\u606F\uFF09`),{kind:l,plainText:o,agentText:c.join(`
|
|
24
|
+
`).trim(),attachments:i}}function On(e){return e.plainText.trim()!==""||e.attachments.length>0?!1:e.kind==="rich_text"||e.kind==="file"||e.kind==="image"}Qt();import{mkdir as ga,writeFile as co}from"node:fs/promises";import{createHash as ya}from"node:crypto";import{homedir as wa,tmpdir as ba}from"node:os";import Fe from"node:path";var Pn=5*1024*1024,Ia=10*1024*1024,Sa=64*1024,$n=".wps-forward.json";function ka(){let e=Fe.join(wa()||ba(),".openclaw"),t=Fe.join(e,"media","inbound");return Fe.isAbsolute(t)?t:Fe.resolve(t)}var lo=ka();function xa(e,t){let r=t?Fe.extname(t).replace(".",""):"";return r||({"image/png":"png","image/jpeg":"jpg","image/jpg":"jpg","image/gif":"gif","image/webp":"webp","image/bmp":"bmp","application/pdf":"pdf"}[e]??"bin")}function va(e){return ya("md5").update(e).digest("hex").substring(0,8)}var Ta=new Set(["md","markdown","txt","text","log","rst","json","yaml","yml","xml","html","htm","csv","tsv","js","mjs","cjs","ts","tsx","jsx","py","go","rs","java","kt","rb","php","c","h","cc","cpp","hpp","cs","swift","m","mm","sh","bash","zsh","fish","ps1","ini","conf","cfg","toml","env","properties","sql","graphql","proto"]),Ea=["text/"],Aa=new Set(["application/json","application/xml","application/yaml","application/x-yaml","application/javascript","application/typescript","application/x-sh","application/toml"]);function Oa(e,t){let r=(e||"").toLowerCase();if(Ea.some(o=>r.startsWith(o))||Aa.has(r))return!0;let n=t?Fe.extname(t).replace(".","").toLowerCase():"";return n?Ta.has(n):!1}var po={md:"markdown",markdown:"markdown",json:"json",yaml:"yaml",yml:"yaml",xml:"xml",html:"html",htm:"html",csv:"csv",tsv:"tsv",js:"javascript",mjs:"javascript",cjs:"javascript",ts:"typescript",tsx:"tsx",jsx:"jsx",py:"python",go:"go",rs:"rust",java:"java",kt:"kotlin",rb:"ruby",php:"php",c:"c",h:"c",cc:"cpp",cpp:"cpp",hpp:"cpp",cs:"csharp",swift:"swift",sh:"bash",bash:"bash",zsh:"bash",fish:"bash",ps1:"powershell",toml:"toml",ini:"ini",conf:"ini",cfg:"ini",env:"ini",sql:"sql",graphql:"graphql",proto:"protobuf"};function Pa(e,t){let r=e?Fe.extname(e).replace(".","").toLowerCase():"";return r&&po[r]?po[r]:t==="application/json"?"json":t.startsWith("text/")?t.slice(5):""}function $a(e){let t=0,r=/`+/g,n;for(;(n=r.exec(e))!==null;)n[0].length>t&&(t=n[0].length);return"`".repeat(Math.max(3,t+1))}async function Rn(e){let{client:t,chatId:r,messageId:n,attachments:o,log:i}=e,s=i?.info??(()=>{}),a=o.filter(d=>d.storageKey);if(!a.length||!r||!n)return{fetched:[],skipped:a.map(d=>({storageKey:d.storageKey??"",reason:r?n?"no storageKey":"missing messageId":"missing chatId"}))};await ga(lo,{recursive:!0});let l={fetched:[],skipped:[]},c=0;for(let d of a){let p=d.storageKey;try{if(d.size&&d.size>Pn){l.skipped.push({storageKey:p,reason:`too large: ${d.size} bytes`});continue}if(c>=Ia){l.skipped.push({storageKey:p,reason:"total download budget exceeded"});continue}s(`WPS prefetch: downloading ${p.substring(0,20)}\u2026 chatId=${r} messageId=${n}`);let u=await t.request({method:"GET",path:`/v7/chats/${encodeURIComponent(r)}/messages/${encodeURIComponent(n)}/resources/${encodeURIComponent(p)}/download`}),_=Zt(u);if(!_){l.skipped.push({storageKey:p,reason:"no download URL in API response"}),s(`WPS prefetch skip: no download URL for ${p.substring(0,20)}\u2026`);continue}s("WPS prefetch: resolved download URL, fetching bytes\u2026");let f=await fetch(_);if(!f.ok){l.skipped.push({storageKey:p,reason:`HTTP ${f.status}`}),s(`WPS prefetch skip: HTTP ${f.status} for ${p.substring(0,20)}\u2026`);continue}let g=Number(f.headers.get("content-length")??"0");if(g>Pn){l.skipped.push({storageKey:p,reason:`content-length ${g} > limit`});continue}let y=new Uint8Array(await f.arrayBuffer());if(y.byteLength>Pn){l.skipped.push({storageKey:p,reason:`downloaded ${y.byteLength} > limit`});continue}c+=y.byteLength;let m=f.headers.get("content-type")?.split(";")[0]?.trim()??"",h=m&&m!=="application/octet-stream"?m:d.mimeType??(m||"application/octet-stream"),w=d.name?.trim(),b=va(p),I=w?`${b}_${w}`:`${n}_${b}.${xa(h,d.name)}`,x=Fe.join(lo,I);if(await co(x,y),h.startsWith("image/")){let K={v:1,storage_key:p},F=d.width,W=d.height;if(typeof F=="number"&&typeof W=="number"&&Number.isFinite(F)&&Number.isFinite(W)&&F>0&&W>0)K.width=Math.trunc(F),K.height=Math.trunc(W);else{let ne=Et(Buffer.from(y));ne&&(K.width=ne.width,K.height=ne.height)}await co(x+$n,JSON.stringify(K),"utf8")}let M;if(Oa(h,d.name)&&y.byteLength<=Sa)try{M=new TextDecoder("utf-8",{fatal:!1}).decode(y)}catch{M=void 0}l.fetched.push({storageKey:p,displayName:d.name??"attachment",mimeType:h,size:y.byteLength,localPath:x,...M!==void 0?{inlineText:M}:{}}),s(`WPS prefetch ok: ${p.substring(0,20)}\u2026 \u2192 ${x} (${h}, ${y.byteLength}B${M!==void 0?", text inlined":""})`)}catch(u){l.skipped.push({storageKey:p,reason:String(u)}),s(`WPS prefetch failed: ${p.substring(0,20)}\u2026 ${String(u)}`)}}return l}function Cn(e,t){let r=[];for(let n of e.fetched){let o=n.mimeType.startsWith("image/"),i=n.inlineText!==void 0?"\u5DF2\u4E0B\u8F7D\u6587\u672C\u9644\u4EF6":o?"\u5DF2\u4E0B\u8F7D\u56FE\u7247":"\u5DF2\u4E0B\u8F7D\u6587\u4EF6";if(r.push(`[${i}: ${n.displayName} | ${n.mimeType} | ${Ra(n.size)} | path=${n.localPath}]`),n.inlineText!==void 0){r.push("\u4EE5\u4E0B\u662F\u6587\u4EF6\u5B8C\u6574\u5185\u5BB9\uFF1A");let s=$a(n.inlineText),a=Pa(n.displayName,n.mimeType);r.push(`${s}${a}`),r.push(n.inlineText),r.push(s)}}for(let n of e.skipped){let o=[t?.chatId?`chatId=${t.chatId}`:"",t?.messageId?`messageId=${t.messageId}`:""].filter(Boolean).join(" | ");r.push(`[\u9644\u4EF6\u672A\u4E0B\u8F7D: ${o?o+" | ":""}\u539F\u56E0: ${n.reason}]`)}return e.fetched.length>0&&r.push('[CRITICAL] \u4E0A\u65B9\u6587\u4EF6\u5DF2\u5728\u672C\u5730\uFF0C\u7981\u6B62\u8C03\u7528 wps_media_fetch_base64 / wps_media_download\u3002\u53D1\u56DE/\u8F6C\u53D1\uFF1Amessage(action="send", media="<\u4E0A\u65B9path>")\u3002\u56FE\u7247\u8BC6\u522B\u7531\u5BBF\u4E3B [Image] block \u63D0\u4F9B\uFF1B\u65E0 [Image] block \u65F6\u4E0D\u731C\u6D4B\u5185\u5BB9\uFF0C\u4F46\u4ECD\u53EF\u53D1\u56DE\u3002\u4E0D\u8981\u4E3B\u52A8\u544A\u77E5\u300C\u5DF2\u4E0B\u8F7D\u300D\u6216\u5217\u51FA\u8DEF\u5F84/\u64CD\u4F5C\u83DC\u5355\uFF0C\u7B49\u7528\u6237\u8BF4\u51FA\u9700\u6C42\u518D\u884C\u52A8\u3002'),e.skipped.length>0&&t?.chatId&&t?.messageId&&r.push(`[\u64CD\u4F5C\u6307\u5F15] \u7528\u6237\u660E\u786E\u8981\u6C42\u83B7\u53D6/\u4E0B\u8F7D/\u53D1\u56DE\u65F6\uFF0C\u76F4\u63A5\u8C03\u7528 wps_media_fetch_base64(chat_id="${t.chatId}", message_id="${t.messageId}", storage_key=<\u4E0A\u65B9storage_key>) \u4E0B\u8F7D\uFF0C\u4E0D\u8981\u56DE\u590D"\u7B49\u540C\u6B65"/"\u91CD\u65B0\u53D1\u9001"/"\u65E0\u6CD5\u83B7\u53D6"\u3002\u7981\u6B62\u7528 exec \u67E5\u6587\u4EF6\u7CFB\u7EDF\u3002\u7528\u6237\u672A\u660E\u786E\u610F\u56FE\u65F6\uFF0C\u7B80\u77ED\u8BE2\u95EE\u300C\u6536\u5230\uFF0C\u8BF7\u95EE\u60A8\u9700\u8981\u6211\u505A\u4EC0\u4E48\uFF1F\u300Dchat_id/message_id \u53D6\u81EA\u6B64\u5904\u6807\u6CE8\u503C\uFF0C\u7981\u6B62\u4ECE From/OriginatingTo/SessionKey \u53D6\u503C\u3002`),r.join(`
|
|
25
|
+
`)}function Ra(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}import{readFile as Ca}from"node:fs/promises";import Da from"node:os";import Dn from"node:path";function uo(e){return globalThis.process?.env?.[e]}function qa(){let e=uo("OPENCLAW_CREDENTIALS_DIR")?.trim();if(e)return e;let t=uo("OPENCLAW_HOME")?.trim()||Dn.join(Da.homedir(),".openclaw");return Dn.join(t,"credentials")}function Ua(e){return e.trim().replace(/^wps-xiezuo:/i,"").replace(/^wps:/i,"")}async function fo(e){let t=Dn.join(qa(),`${e.channelId}-${e.accountId}-allowFrom.json`),r="";try{r=await Ca(t,"utf8")}catch(n){return n?.code!=="ENOENT"&&e.log?.debug?.(`[wps-xiezuo] load pairing allowFrom failed: ${String(n)}`),[]}try{let n=JSON.parse(r);return Array.isArray(n.allowFrom)?n.allowFrom.map(o=>Ua(String(o))).filter(o=>o.length>0):[]}catch(n){return e.log?.warn?.(`[wps-xiezuo] invalid pairing allowFrom json (${t}): ${String(n)}`),[]}}Sn();var qn=new Map,Na=30*60*1e3;function _o(e,t){qn.set(e,{...t,ts:Date.now()})}function Un(e){let t=qn.get(e);if(t){if(Date.now()-t.ts>Na){qn.delete(e);return}return t}}var Qa=36e5;function Oo(e){if(!e||typeof e!="object")return null;let t=e;if(typeof t.id=="string"&&typeof t.type=="string")return t;let r=t.message;return r&&typeof r=="object"&&typeof r.id=="string"?r:null}function ed(e){if(!e.trim())return[];let t=/(?:https?:\/\/)?([a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*\.kdocs\.cn)\/wiki\/l\/0l([A-Za-z0-9]+)(?=[/?#\s]|$)/gi,r=[],n=new Set,o;for(;(o=t.exec(e))!==null;){let i=o[1].trim().toLowerCase(),s=o[2].trim();if(!i||!s)continue;let a=`${i}|${s}`;n.has(a)||(n.add(a),r.push({host:i,linkId:s,canonicalUrl:`https://${i}/wiki/l/0l${s}`}))}return r}var Po=new Map;function td(e,t){let r=`${e}:${t}`,n=Po.get(r);return n||(n=new er({botId:t,accountId:e},new tr),Po.set(r,n)),n}function Bn(e){return e.trim().replace(/^wps-xiezuo:/i,"").replace(/^wps:/i,"")}function rd(e,t,r){if(r==="disabled")return!1;if(r==="open")return!0;if(!t||t.length===0)return!1;let n=Bn(e);return t.some(o=>o==="*"||Bn(o)===n)}function nd(e,t){let r=e?.groups??{};return(r[t]??r["*"])?.requireMention??!0}function id(e){let t=(r,n)=>n>8||r==null?!1:typeof r=="string"?/<at\b[^>]*>/i.test(r)||/@\S+/.test(r):Array.isArray(r)?r.some(o=>t(o,n+1)):typeof r=="object"?Object.values(r).some(o=>t(o,n+1)):!1;return t(e,0)}function od(e){let t=String(e??"").toLowerCase();return t==="image"||t==="file"||t==="sticker"}function sd(e){let t=e.match(/:group:([^:]+)/);if(t)return{type:"chat",receiver_id:t[1]};let r=e.match(/:p2p:([^:]+)/);return r?{type:"user",receiver_id:r[1]}:{type:"user",receiver_id:e}}async function dt(e,t,r){let n=R(e),o=C(e.baseUrl,n),i=sd(t);await o.request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:i,content:{text:{content:r,type:"markdown"}}}})}async function ad(e,t,r,n){let o=R(e);await C(e.baseUrl,o).request({method:"POST",path:`/v7/chats/${encodeURIComponent(t)}/messages/${encodeURIComponent(r)}/reply`,body:{type:"text",content:{text:{content:n,type:"markdown"}}}})}async function Gn(e){let t=e.log??{},r=t.info??console.log,n=t.error??console.error,{cfg:o,accountId:i,channelRuntime:s,wpsCfg:a,creds:l,eventPayload:c}=e;if(xn(c.topic)){r(`WPS skip non-message topic: ${String(c.topic)}`);return}let d=c.message,p=c.sender,u=c.chat;if(!d||!p)return;let _=td(i,l.clientId),f,g;try{f=_.normalizeEvent(c),g=_.resolve(f)}catch($){if($ instanceof fe){r(`WPS session resolve skipped: code=${$.code}, reason=${$.message}`);return}n("WPS session resolve failed:",$);return}if(!g){r(`WPS skip inbound: not mentioning/replying bot (event_id=${f.event_id||"unknown"})`);return}if(g.scene==="group"){let $=g.group_id??u?.id??"",q=nd(a,$),L=id(d.content),D=od(d.type);if(q&&!(f.is_at_bot||f.is_reply_to_bot||L||D)){r(`WPS skip: group not mentioning bot (event_id=${f.event_id||"unknown"})`);return}}if(await _.checkIdempotency(g.idempotency_key)){r(`WPS dedupe: skip duplicate event_id=${g.idempotency_key}`);return}await _.markProcessed(g.idempotency_key,Qa);let m=g.user_id||p.id||"";if(!m){n("Unable to identify sender");return}let h=g.chat_id??g.group_id??u?.id??"",w=d.id??"",b=rr(d,{chatId:h,messageId:w});if(On(b)&&h&&w)try{let $=R(l),q=C(l.baseUrl,$);r(`WPS inbound: empty parse (kind=${b.kind}), fetching message detail chatId=${h} messageId=${w}`);let L=await q.request({method:"GET",path:`/v7/chats/${encodeURIComponent(h)}/messages/${encodeURIComponent(w)}`}),D=Oo(L?.data??null),P=D?.content,Ue=P&&typeof P=="object"&&!Array.isArray(P)&&Object.keys(P).length>0;D&&Ue&&(d={...d,...D,content:D.content??d.content},b=rr(d,{chatId:h,messageId:w}),r(`WPS inbound: reparsed after GET detail kind=${b.kind} previewLen=${b.plainText.length}`))}catch($){n(`WPS inbound: message detail GET failed: ${String($)}`)}let I=g.scene==="p2p",x=g.session_key,M=I?`wps:${m}`:g.session_key;_o(i,{chatId:h,senderId:m,isDirect:I});let K=b.agentText,F,W=[],ne=[],ee=[];b.agentText?ee.push(b.agentText):b.plainText&&ee.push(b.plainText);let ce=c.quote_msg_id,gt,zt=[];{let $=d.content&&typeof d.content=="object"?Object.keys(d.content).join(","):typeof d.content,q=d.content?.image,L=q&&typeof q=="object"?Object.keys(q).join(","):"",D=d.reply_to?JSON.stringify(d.reply_to).substring(0,120):"";r(`WPS media context: type=${d.type??"?"} chatId=${h||"(empty)"} messageId=${w||"(empty)"} quoteMsgId=${ce||"(none)"} contentKeys=[${$}] imgKeys=[${L}]${D?` reply_to=${D}`:""} attachments=${b.attachments.length} downloadable=${b.attachments.filter(P=>P.storageKey).length} kinds=${b.attachments.map(P=>`${P.kind}:sk=${!!P.storageKey}`).join(",")||"(none)"}`)}if(ce&&h){let $=R(l),q=C(l.baseUrl,$);try{r(`WPS quote fetch: chatId=${h} quote_msg_id=${ce}`);let L=await q.request({method:"GET",path:`/v7/chats/${encodeURIComponent(h)}/messages/${encodeURIComponent(ce)}`}),D=Oo(L?.data??null);if(D){let P=rr(D,{chatId:h,messageId:ce}),Ue=P.attachments.filter(z=>z.storageKey),Ne=P.attachments.filter(z=>z.cloudType),me=[];if(me.push("[\u7528\u6237\u5F15\u7528\u4E86\u4EE5\u4E0B\u6D88\u606F]"),P.plainText&&me.push(P.plainText),Ue.length>0){let z=await Rn({client:q,chatId:h,messageId:ce,attachments:Ue,log:t});if(z.fetched.length>0||z.skipped.length>0){me.push(Cn(z,{chatId:h,messageId:ce,fromQuote:!0}));for(let B of z.fetched)zt.push({storageKey:B.storageKey,displayName:B.displayName,mimeType:B.mimeType,size:B.size,localPath:B.localPath,fromQuote:!0}),W.push(B.localPath),ne.push(B.mimeType);r(`WPS quote prefetch: ${z.fetched.length} ok, ${z.skipped.length} skipped`)}}if(Ne.length>0)for(let z of Ne){let B=z.name||"\u672A\u547D\u540D\u4E91\u6587\u4EF6";me.push(`[\u5F15\u7528\u4E91\u6587\u4EF6: ${B}]`),z.cloudLinkUrl&&me.push(`\u94FE\u63A5: ${z.cloudLinkUrl}`),z.fileId&&me.push(`\u6587\u4EF6ID: ${z.fileId}`)}Ue.length===0&&Ne.length===0&&P.attachments.length===0&&!P.plainText&&me.push(`[\u5F15\u7528\u6D88\u606F\u5185\u5BB9\u4E3A\u7A7A\u6216\u672A\u89E3\u6790] type=${D.type??"unknown"}`),gt=me.join(`
|
|
26
|
+
`)}else r(`WPS quote fetch: empty data for quote_msg_id=${ce}`)}catch(L){n(`WPS quote fetch failed for quote_msg_id=${ce}:`,L),gt=`[\u5F15\u7528\u6D88\u606F\u83B7\u53D6\u5931\u8D25 quote_msg_id=${ce}]`}}if(b.attachments.some($=>$.storageKey)&&h&&w){let $=R(l),q=C(l.baseUrl,$),L=await Rn({client:q,chatId:h,messageId:w,attachments:b.attachments,log:t});if(L.fetched.length>0||L.skipped.length>0){ee.length>0&&(ee[0]=b.plainText||""),ee.push(Cn(L,{chatId:h,messageId:w})),F=L.fetched.map(D=>({storageKey:D.storageKey,displayName:D.displayName,mimeType:D.mimeType,size:D.size,localPath:D.localPath}));for(let D of L.fetched)W.push(D.localPath),ne.push(D.mimeType);r(`WPS media prefetch: ${L.fetched.length} ok, ${L.skipped.length} skipped`)}}gt&&ee.push(gt);let lr=ed(ee.join(`
|
|
27
|
+
`));if(lr.length>0){let $=["[\u8BC6\u522B\u5230\u77E5\u8BC6\u5E93\u6587\u6863\u94FE\u63A5]"];for(let q of lr)$.push(`- \u94FE\u63A5: ${q.canonicalUrl} \u2192 file_id: ${q.linkId}`);ee.push($.join(`
|
|
28
|
+
`))}ee.length>0&&(K=ee.join(`
|
|
29
29
|
|
|
30
|
-
`)),
|
|
30
|
+
`)),zt.length>0&&(F=[...F??[],...zt]);let yt=K,Se=b.plainText||K;r(`WPS received: kind=${b.kind}, chatId=${h||"(empty)"}, messageId=${w}, isDirect=${I}, session_key=${g.session_key}, preview=${Se.substring(0,50)}`);try{let $=(a.allowFrom??[]).map(A=>Bn(String(A))),q=a.dmPolicy??"pairing",L=I&&(q==="pairing"||q==="allowlist")?await fo({channelId:E,accountId:i,log:t}):[],D=Array.from(new Set([...$,...L]));if(I&&q==="disabled"){r(`Direct message denied by dmPolicy=disabled (accountId=${i}, sender=${m})`);return}if(I&&!rd(m,D,q)){if(r(`Sender ${m} not in allowFrom (policy: ${q})`),q==="pairing"&&s?.pairing){let A=s.pairing;if(A?.upsertPairingRequest&&A?.buildPairingReply){let{code:X,created:le}=await A.upsertPairingRequest({channel:E,accountId:i,id:m});if(X&&le){let Bt=`${A.buildPairingReply({channel:E,idLine:`Your WPS user id: ${m}`,code:X})}
|
|
31
31
|
|
|
32
32
|
For multi-account channels, approve with:
|
|
33
|
-
openclaw pairing approve --channel ${E} --account ${i} ${
|
|
34
|
-
`));let
|
|
35
|
-
${JSON.stringify(A,null,2)}`);return}if(!s){r("WPS: channelRuntime not available \u2014 skipping AI dispatch");return}let O=s.reply,Me=s.routing,We="main",me="",z=i;if(Me?.resolveAgentRoute){let A=Me.resolveAgentRoute({cfg:o,channel:E,accountId:i,peer:{kind:I?"direct":"group",id:g.session_key}});We=A.agentId,me=A.sessionKey?.trim()??"",A.accountId&&(z=A.accountId,r(`WPS route account override: ${i} -> ${A.accountId}`))}let G=me||g.session_key,yi=z;r(`WPS route: agentId=${We}, inboundSessionKey=${G}, accountId=${yi}`),W.length>0&&r(`WPS media context: MediaPath=${W[0]}, MediaType=${ie[0]}, count=${W.length}`);let wi={Body:It,BodyForAgent:It,...W.length>0?{MediaPath:W[0],MediaUrl:W[0],MediaType:ie[0],MediaPaths:W,MediaUrls:W,MediaTypes:ie}:{},RawBody:JSON.stringify({session:g,chatId:h,messageId:w,senderId:m,replyTarget:I?`user:${m}`:`chat:${h}`,messageType:b.kind,plainText:b.plainText,attachments:b.attachments,...B?{prefetchedMedia:B}:{},_idHint:"To reply, omit the 'to' parameter (framework auto-routes). To send to a DIFFERENT conversation, use replyTarget or 'chat:<chatId>' / 'user:<senderId>'. AK-prefixed strings are bot/app IDs, NOT chat IDs \u2014 never use them as receiver."}),CommandBody:It,CommandAuthorized:!0,From:M,To:I?`user:${m}`:`chat:${h}`,ReplyTarget:I?`user:${m}`:`chat:${h}`,SessionKey:G,Label:G,ConversationLabel:G,DisplayName:G,SessionLabel:G,AccountId:yi,ChatType:I?"direct":"group",GroupId:void 0,SenderName:p.name??void 0,SenderId:m,Provider:E,Surface:"wps",Channel:E,Timestamp:c.send_time??Date.now(),OriginatingChannel:E,OriginatingFrom:`wps:${m}`,OriginatingTo:I?`user:${m}`:`chat:${h}`},bi=O.finalizeInboundContext?O.finalizeInboundContext(wi):wi,Ht=null;if(h&&w)try{await In(l,h,w),Ht={kind:"reaction",chatId:h,messageId:w},r(`WPS thinking reaction added: chatId=${h}, messageId=${w}`)}catch(A){r(`WPS thinking reaction failed, falling back to text: ${String(A)}`);try{await pt(l,x,"\u6B63\u5728\u601D\u8003\u4E2D..."),Ht={kind:"text-fallback"}}catch(F){r(`WPS thinking fallback text failed: ${String(F)}`)}}let Ii=18e4,ki=!1,Si=async()=>{if(!(ki||Ht?.kind!=="reaction")){ki=!0;try{await kn(l,Ht.chatId,Ht.messageId,t),r("WPS thinking reaction removed")}catch{}}},xi=()=>async(A,F)=>{let te=A.text??"";if(!te)return;let Se=te.trim();if(/Message:.*[\\/](?:openclaw-media|wps-prefetch|\.openclaw[\\/]media)[\\/].*failed/i.test(Se)){r(`WPS deliver: suppressed media-failed noise: ${Se.substring(0,80)}`);return}await Si(),r(`WPS deliver: text length=${te.length}, preview=${te.substring(0,80)}`),!I&&h&&w?await dd(l,h,w,te):await pt(l,x,te)},vi=(A,F,te)=>{let Se,tt=new Promise(($e,kt)=>{Se=setTimeout(()=>kt(new Error(`${te} timed out after ${F}ms`)),F)});return Promise.race([A,tt]).finally(()=>clearTimeout(Se))};try{if(r(`WPS: starting dispatch (sessionKey=${G})`),O.dispatchReplyWithBufferedBlockDispatcher)await vi(O.dispatchReplyWithBufferedBlockDispatcher({ctx:bi,cfg:o,dispatcherOptions:{deliver:xi(),responsePrefix:"",humanDelay:O.resolveHumanDelayConfig?O.resolveHumanDelayConfig(o,We):void 0,onError:(A,F)=>{n(`WPS ${F.kind} reply error: ${String(A)}`)}}}),Ii,"dispatchReplyWithBufferedBlockDispatcher"),r("WPS: agent dispatch completed");else if(O.dispatchReplyFromConfig&&O.createReplyDispatcherWithTyping){let A=O.resolveHumanDelayConfig?O.resolveHumanDelayConfig(o,We):void 0,{dispatcher:F,replyOptions:te,markDispatchIdle:Se}=O.createReplyDispatcherWithTyping({responsePrefix:"",humanDelay:A,deliver:xi(),onError:(tt,$e)=>{n(`WPS ${$e.kind} reply error: ${String(tt)}`)}});try{await vi(O.dispatchReplyFromConfig({ctx:bi,cfg:o,dispatcher:F,replyOptions:te}),Ii,"dispatchReplyFromConfig")}finally{Se()}r("WPS: agent dispatch completed (fallback path)")}else r("WPS: channelRuntime.reply dispatch APIs not found, skipping agent dispatch")}catch(A){n(`WPS dispatch failed: ${A instanceof Error?A.message:String(A)}`)}finally{await Si()}}catch($){n("WPS async inbound error:",$)}}ue();Fe();tr();import{createHash as cd}from"node:crypto";function ae(e){return{error:e instanceof Error?e.message:String(e)}}function T(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function V(e,t){let r=e[t];if(r==null)return;if(typeof r!="string")throw new Error(`${t} must be a string`);let n=r.trim();return n===""?void 0:n}function Y(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function ne(e,t){let r=e[t];if(r!=null){if(typeof r=="boolean")return r;if(r==="true")return!0;if(r==="false")return!1;throw new Error(`${t} must be a boolean`)}}function ut(e,t){let r=e[t];if(r!=null){if(!Array.isArray(r))throw new Error(`${t} must be an array of strings`);return r.map(n=>String(n).trim()).filter(Boolean)}}function ye(e,t="chat_id"){let r=T(e,t),n=r.startsWith("wps:")?r.slice(4):r;if(/^AK\d{8}/i.test(n))throw new Error(`${t}="${r}" is a bot/app ID (AK-prefixed), NOT a chat ID. The correct chat_id is a numeric ID like '77183700'. Look for chatId in RawBody JSON (parse the RawBody string first). Do NOT use values from From, OriginatingTo, SessionKey, or SenderId fields.`);if(n.includes(":")&&n.includes("AK"))throw new Error(`${t}="${r}" looks like a session_key or compound ID, NOT a chat ID. The correct chat_id is in RawBody.chatId (a numeric string like '77183700').`);return n}function He(e,t){let r=e[t];if(r==null)throw new Error(`${t} is required`);let n=typeof r=="number"?r:parseInt(String(r),10);if(!Number.isFinite(n)||n<0)throw new Error(`${t} must be a non-negative integer`);return n}function ld(e){return cd("sha256").update(e).digest("hex")}var No=20*1024*1024;function Jn(e){let t=e.trim();return!t||t.startsWith("http://")||t.startsWith("https://")?!1:!!(/^[a-zA-Z]:[\\/]/.test(t)||t.startsWith("\\\\")||t.startsWith("/tmp/")||t.startsWith("/var/folders/")||t.includes("openclaw-media")||t.includes("wps-prefetch")||t.includes(".openclaw/media")||t.includes(".openclaw\\media"))}function Mo(e){let t=e.trim();return t.startsWith("http://")||t.startsWith("https://")?!1:t.includes("openclaw-media")||t.includes("wps-prefetch")||t.includes(".openclaw/media")||t.includes(".openclaw\\media")}function pd(e,t){let r={};for(let[n,o]of Object.entries(e)){if(typeof o!="string")continue;let i=n.trim();if(!i)continue;let s=i.toLowerCase();s==="transfer-encoding"||s==="content-length"||(r[i]=o)}return r}async function Xn(e,t,r,n,o){let i=o?.info??console.log,s=o?.error??console.error,a=n.byteLength;if(a===0)throw new Error("upload content is empty");if(a>No)throw new Error(`file too large: ${a} bytes (max ${No})`);let l=ld(n);i(`[upload] phase1 start: fileName=${t} fileType=${r} size=${a} checksum=${l.substring(0,16)}\u2026`);let c;try{c=await e.request({method:"POST",path:"/v7/chats/resources/upload",body:{file_name:t,file_size:a,file_type:r,checksum:l}})}catch(w){let b=w instanceof Error?w.message:String(w);throw s(`[upload] phase1 request failed: ${b}`),new Error(`upload phase 1 request failed: ${b}`)}let d=c.data??c;if(!d||typeof d!="object")throw new Error(`upload phase 1 returned no data: ${JSON.stringify(c).substring(0,300)}`);let p=d.data,u=p&&typeof p=="object"?p:d;i(`[upload] phase1 response keys: source=[${Object.keys(u)}] hasNested=${!!p}`);let _=u.upload_entry;_&&i(`[upload] upload_entry keys: [${Object.keys(_)}]`);let f=typeof u.url=="string"&&u.url.trim()?u.url.trim():typeof u.upload_url=="string"&&u.upload_url.trim()?u.upload_url.trim():_&&typeof _.url=="string"&&_.url.trim()?_.url.trim():null,g=typeof u.storage_key=="string"&&u.storage_key.trim()?u.storage_key.trim():null;if(!f)throw new Error(`upload phase 1 did not return an upload URL: keys=${JSON.stringify(Object.keys(u))}, raw=${JSON.stringify(d).substring(0,300)}`);if(!g)throw new Error(`upload phase 1 did not return a storage_key: keys=${JSON.stringify(Object.keys(u))}`);i(`[upload] phase1 ok: storageKey=${g.substring(0,20)}\u2026 uploadUrl=${f.substring(0,80)}\u2026`);let y=_&&typeof _.headers=="object"&&_.headers&&Object.keys(_.headers).length>0,m=pd(y?_.headers:{},f);i(`[upload] phase2 PUT headers: ${JSON.stringify(Object.keys(m))}`);let h;try{h=await fetch(f,{method:"PUT",headers:m,body:n})}catch(w){let b=w instanceof Error?w.message:String(w);throw s(`[upload] phase2 PUT network error: ${b} url=${f.substring(0,80)}\u2026`),new Error(`upload phase 2 PUT network error: ${b}`)}if(!h.ok){let w=await h.text().catch(()=>"");throw s(`[upload] phase2 PUT failed: HTTP ${h.status} body=${w.substring(0,300)}`),new Error(`upload phase 2 PUT failed: HTTP ${h.status} ${w.substring(0,200)}`)}return i(`[upload] phase2 PUT ok: HTTP ${h.status} storageKey=${g.substring(0,20)}\u2026`),{storage_key:g,file_name:t,file_size:a}}function Kn(e){return e.data??null}function Dr(e){return{error:e instanceof Error?e.message:String(e)}}function Ae(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function ud(e,t){let r=e[t];if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} is required and must be a finite number`)}function fd(e){let t=e.trim();return!!(t.endsWith("=")||t.includes(":")&&t.length>30||/^[A-Za-z0-9+/]{40,}={0,2}$/.test(t))}function jo(e,t){if(e===t)throw new Error("message_id and storage_key are identical \u2014 this is wrong. message_id should be the message ID (from RawBody.messageId), not the storage_key. Please check the RawBody JSON for the correct messageId field.");if(fd(e))throw new Error(`message_id="${e.substring(0,30)}\u2026" looks like a storage_key (contains ':' or ends with '='). message_id should be the message ID from RawBody.messageId, not the attachment storage_key. These are different values \u2014 check the RawBody JSON.`)}function _d(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number when provided`)}}function Vn(e,t,r){let n=r?.info??(()=>{}),o=r?.error??(()=>{});t({name:"wps_media_download",description:"Obtain a pre-signed download URL for a message attachment. DO NOT call this tool if the file is already downloaded locally (Body shows '[\u5DF2\u4E0B\u8F7D\u56FE\u7247/\u6587\u4EF6: ... path=...]') \u2014 use message(media=<path>) instead. Only use for attachments NOT pre-downloaded (Body shows '[\u9644\u4EF6\u672A\u4E0B\u8F7D]'). chat_id and message_id come from RawBody JSON (chatId / messageId fields). message_id and storage_key are DIFFERENT values \u2014 do NOT pass storage_key as message_id.",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."},message_id:{type:"string",description:"Message id (from RawBody.messageId). NOT the storage_key."},storage_key:{type:"string",description:"Resource storage key from the attachment."}},required:["chat_id","message_id","storage_key"]},async execute(i,s){try{let a=ye(s),l=Ae(s,"message_id"),c=Ae(s,"storage_key");jo(l,c);let d=encodeURIComponent(a),p=encodeURIComponent(l),u=encodeURIComponent(c),_=await e.request({method:"GET",path:`/v7/chats/${d}/messages/${p}/resources/${u}/download`});return Kn(_)}catch(a){return Dr(a)}}}),t({name:"wps_media_fetch_base64",description:"Fetch attachment bytes from WPS cloud and return base64. DO NOT call this tool if the file is already downloaded locally (Body shows '[\u5DF2\u4E0B\u8F7D\u56FE\u7247/\u6587\u4EF6: ... path=...]') \u2014 use message(media=<path>) instead. Only use this tool for attachments NOT pre-downloaded (Body shows '[\u9644\u4EF6\u672A\u4E0B\u8F7D]'). chat_id and message_id come from RawBody JSON (chatId / messageId fields). message_id and storage_key are DIFFERENT values \u2014 do NOT pass storage_key as message_id.",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."},message_id:{type:"string",description:"Message id (from RawBody.messageId). NOT the storage_key."},storage_key:{type:"string",description:"Resource storage key from the attachment."},max_bytes:{type:"number",description:"Optional max bytes limit for safety (default 5MB). If exceeded, tool returns an error."}},required:["chat_id","message_id","storage_key"]},async execute(i,s){try{let a=ye(s),l=Ae(s,"message_id"),c=Ae(s,"storage_key");jo(l,c);let d=encodeURIComponent(a),p=encodeURIComponent(l),u=encodeURIComponent(c),_=_d(s,"max_bytes")??5*1024*1024;if(_<=0)throw new Error("max_bytes must be positive");n(`[tool:wps_media_fetch_base64] start: chatId=${a} msgId=${l} sk=${c.substring(0,20)}\u2026`);let f=await e.request({method:"GET",path:`/v7/chats/${d}/messages/${p}/resources/${u}/download`}),g=Kn(f),y=gn(g),m=await fetch(y);if(!m.ok)throw new Error(`download url request failed: HTTP ${m.status}`);let h=Number(m.headers.get("content-length")??"0");if(Number.isFinite(h)&&h>_)throw new Error(`attachment too large: ${h} bytes > max_bytes=${_}`);let w=m.headers.get("content-type")??"application/octet-stream",b=new Uint8Array(await m.arrayBuffer());if(b.byteLength>_)throw new Error(`attachment too large after download: ${b.byteLength} bytes > max_bytes=${_}`);let I=w.startsWith("image/")?at(Buffer.from(b)):null;return n(`[tool:wps_media_fetch_base64] ok: ${w} ${b.byteLength}B${I?` ${I.width}x${I.height}`:""}`),{chat_id:a,message_id:l,storage_key:c,mime_type:w,size:b.byteLength,base64:Buffer.from(b).toString("base64"),...I?{width:I.width,height:I.height}:{}}}catch(a){return o("[tool:wps_media_fetch_base64] error:",a),Dr(a)}}}),t({name:"wps_media_upload",description:"Low-level Phase 1 upload (POST /v7/chats/resources/upload). Returns pre-signed URL + storage_key. The API requires a `checksum` of the file bytes (SHA256 lowercase hex). Prefer wps_media_upload_base64 which computes checksum and completes the PUT automatically.",parameters:{type:"object",properties:{file_name:{type:"string",description:"Original file name including extension."},file_size:{type:"number",description:"File size in bytes."},file_type:{type:"string",description:"MIME type or WPS file type discriminator as required by the API (e.g. image/png)."},checksum:{type:"string",description:"SHA256 lowercase hex digest of the entire file (must match the bytes you will PUT in phase 2 and file_size)."}},required:["file_name","file_size","file_type","checksum"]},async execute(i,s){try{let a=Ae(s,"file_name"),l=ud(s,"file_size"),c=Ae(s,"file_type"),d=Ae(s,"checksum");if(l<0)throw new Error("file_size must be non-negative");let p=await e.request({method:"POST",path:"/v7/chats/resources/upload",body:{file_name:a,file_size:l,file_type:c,checksum:d}});return Kn(p)}catch(a){return Dr(a)}}}),t({name:"wps_media_upload_base64",description:`Upload a file to WPS and get a storage_key for sending as image/file message. Accepts base64-encoded file content. Internally performs: 1) POST metadata (includes SHA256 checksum of decoded bytes) to get pre-signed upload URL + storage_key, 2) PUT raw bytes to the pre-signed URL. Returns { storage_key, file_name, file_size, width?, height? }. For images, width and height are auto-detected from bytes. After getting storage_key, use wps_message_send with msg_type='image' and include width/height in the content: content='{"image":{"storage_key":"...","width":W,"height":H}}'.`,parameters:{type:"object",properties:{file_name:{type:"string",description:"File name with extension (e.g. photo.png)."},file_type:{type:"string",description:"MIME type (e.g. image/png, image/jpeg, application/pdf)."},base64:{type:"string",description:"Base64-encoded file content. For images previously fetched, pass the base64 from wps_media_fetch_base64 or from a local file read."}},required:["file_name","file_type","base64"]},async execute(i,s){try{let a=Ae(s,"file_name"),l=Ae(s,"file_type"),c=Ae(s,"base64"),d=Buffer.from(c,"base64");n(`[tool:wps_media_upload_base64] start: ${a} ${l} ${d.byteLength}B`);let{storage_key:p,file_name:u,file_size:_}=await Xn(e,a,l,d),f=l.startsWith("image/")?at(d):null;return n(`[tool:wps_media_upload_base64] ok: storage_key=${p.substring(0,20)}\u2026 ${u} ${_}B${f?` ${f.width}x${f.height}`:""}`),{storage_key:p,file_name:u,file_size:_,...f?{width:f.width,height:f.height}:{}}}catch(a){return o("[tool:wps_media_upload_base64] error:",a),Dr(a)}}})}tr();var vd={Debug:0,Info:1,Warn:2,Error:3},Ut=null;function Qo(e){Ut=e}function Td(){if(!Ut)throw new Error("WPS plugin runtime not initialized");return Ut}var Ur=new Map;function Ed(e,t){let r=t.chat?.id?.trim(),n=t.message?.sender?.id?.trim()??t.sender?.id?.trim();return!r||!n?null:`wps:${e}:${r}:${n}`}function Ad(e,t){let n=(Ur.get(e)??Promise.resolve()).then(t,t);Ur.set(e,n),n.finally(()=>{Ur.get(e)===n&&Ur.delete(e)})}var jr="wps",Vo={id:E,label:"WPS",selectionLabel:"WPS365 (Open Platform)",docsPath:"/channels/wps-xiezuo",docsLabel:"WPS",blurb:"WPS365 Open Platform bot integration.",aliases:[E,jr,"wps365"],order:70};function dr(e){let t=e.channels;if(t)return t[E]??t[jr]}function Ke(e){return sn(dr(e))}function Pd(){let e=Nr.join(kd(),".openclaw","openclaw.json");if(!bd(e))return null;try{let t=Id(e,"utf8");return t.trim()?JSON.parse(t):null}catch{return null}}function Yn(e){let t=e&&typeof e=="object"?e:null;if(t&&Object.keys(Ke(t)).length>0)return t;let r=Ut?.config&&typeof Ut.config=="object"?Ut.config:null;if(r&&Object.keys(Ke(r)).length>0)return r;let n=Pd();return n&&Object.keys(Ke(n)).length>0?n:t??r??n??{}}function de(e){return gr(dr(e))}function we(e,t){let r=Ke(e);return r[t]??r[de(e)]??r[he]}function Od(e,t=he){let r=we(e,t);return{accountId:t,enabled:r?.enabled!==!1,configured:!!ve(r),config:r??{enabled:!1}}}function Zn(e){return e.trim().replace(/^wps-xiezuo:/i,"").replace(/^wps:/i,"")}function $d(e){return e.trim().length>0}var ft=/AK\d{8}/i;function ar(e,t){if(ft.test(e))throw new Error(`to="${t}" contains a bot/app ID pattern ("${e}"). Omit the 'to' parameter to reply in the current conversation, or use 'chat:<RawBody.chatId>' (group) / 'user:<SenderId>' (DM).`)}function Yo(e){let t=e;return t.startsWith("wps-xiezuo:")?t=t.slice(11):t.startsWith("wps:")&&(t=t.slice(4)),t=t.replace(/:acct:[^:]+$/,""),t}function es(e){if(e.startsWith("user:")){let t=e.slice(5),r=Yo(t);return ar(r,e),{type:"user",id:r}}if(e.startsWith("chat:")){let t=e.slice(5),r=Yo(t);return ar(r,e),{type:"chat",id:r}}if(e.startsWith("wps:")||e.startsWith("wps-xiezuo:")){let t=e.match(/:group:([^:]+)/);if(t)return{type:"chat",id:t[1]};let r=e.match(/:p2p:([^:]+)/);if(r)return{type:"user",id:r[1]};let n=e.split(":");if(n.length===2){let a=n[1];return ar(a,e),{type:"user",id:a}}let o=n[2]??n[1],s=n[3]??n[2]??n[n.length-1]??e;return ar(s,e),{type:o==="group"?"chat":"user",id:s}}return ar(e,e),{type:"user",id:e}}function ts(e){return e.match(/:acct:([^:]+)/)?.[1]}function Zo(e,t,r){let n=r??ts(t)??Kt()??de(e),o=we(e,n),i=ve(o);if(!i)throw new Error(`WPS credentials not configured for account "${n}"`);return i}async function Qn(e,t,r){let n=R(e),o=C(e.baseUrl,n),i=es(t);return{messageId:(await o.request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:{type:i.type,receiver_id:i.id},content:{text:{content:r,type:"markdown"}}}})).data?.message_id??""}}var ei={id:E,meta:{...Vo,aliases:[...Vo.aliases]},capabilities:{chatTypes:["direct","group"],media:!0,threads:!0,nativeCommands:!1,blockStreaming:!0},reload:{configPrefixes:[`channels.${E}`,`channels.${jr}`]},configSchema:Yi(on),messaging:{normalizeTarget:e=>e.trim(),targetResolver:{hint:"WPS target: user_id or chat_id (obfuscated string, case-sensitive)",looksLikeId:e=>e.trim().length>0}},config:{listAccountIds:e=>{let t=Yn(e),r=Object.keys(Ke(t));return r.length>0?r:[he]},resolveAccount:e=>{let t=Yn(e);return Od(t,de(t))},defaultAccountId:e=>{let t=Yn(e);return de(t)},setAccountEnabled:({cfg:e,enabled:t})=>({...e,channels:{...e.channels,[E]:{...dr(e),accounts:{...Ke(e),[de(e)]:{...we(e,de(e))??{},enabled:t}}}}}),deleteAccount:({cfg:e})=>{let t={...e},r={...t.channels},n=dr(e);if(n){let o=de(e),i={...Ke(e)};delete i[o],r[E]={...n,accounts:i}}else delete r[E],delete r[jr];return t.channels=Object.keys(r).length>0?r:void 0,t},isConfigured:(e,t)=>!!ve(we(t,e.accountId)),describeAccount:e=>({accountId:e.accountId,enabled:e.enabled,configured:e.configured}),resolveAllowFrom:({cfg:e,accountId:t})=>{let r=e;return we(r,t??de(r))?.allowFrom??[]},formatAllowFrom:({allowFrom:e})=>e.map(t=>Zn(String(t)))},security:{resolveDmPolicy:({cfg:e})=>{let t=e,r=de(t),n=we(t,r);return{policy:n?.dmPolicy??"pairing",allowFrom:n?.allowFrom??[],policyPath:`channels.${E}.accounts.${r}.dmPolicy`,allowFromPath:`channels.${E}.accounts.${r}.allowFrom`,approveHint:Zi(E),normalizeEntry:Zn}},collectWarnings:({cfg:e})=>{let t=[],r=Ke(e);for(let[n,o]of Object.entries(r))o.dmPolicy==="open"&&t.push(`- WPS account '${n}' DMs are open to anyone. Set channels.${E}.accounts.${n}.dmPolicy="pairing" or "allowlist" for security.`),(o.groupPolicy??"allowlist")==="open"&&t.push(`- WPS account '${n}' groups: groupPolicy="open" allows any group to trigger. Set channels.${E}.accounts.${n}.groupPolicy="allowlist".`);return t}},pairing:{idLabel:"wpsUserId",normalizeAllowEntry:Zn,notifyApproval:async({cfg:e,id:t,accountId:r})=>{let n=e,o=we(n,r??de(n)),i=ve(o);if(!i)throw new Error("WPS credentials not configured");await Qn(i,`user:${t}`,"Your pairing request has been approved. You can now chat with this bot.")}},groups:{resolveRequireMention:({cfg:e,groupId:t})=>{let r=e,n=we(r,de(r));return!n?.groups||!t?!0:(n.groups[t]??n.groups["*"])?.requireMention??!0},resolveToolPolicy:()=>{}},outbound:{deliveryMode:"direct",textChunkLimit:5e3,chunker:(e,t)=>Td().channel.text.chunkMarkdownText(e,t),chunkerMode:"markdown",resolveTarget:({to:e,allowFrom:t})=>{let r=e?.trim()??"";if(r.startsWith("wps-xiezuo:")?r=r.slice(11):r.startsWith("wps:")&&(r=r.slice(4)),ft.test(r)){let o=r.match(/:acct:([^:]+)/),i=o?.[1]?`:acct:${o[1]}`:"",s=r.match(/:p2p:([^:]+)/);if(s?.[1]&&!ft.test(s[1]))return{ok:!0,to:`user:${s[1]}${i}`};let a=r.match(/:group:([^:]+)/);return a?.[1]&&!ft.test(a[1])?{ok:!0,to:`chat:${a[1]}${i}`}:{ok:!1,error:new Error(`recipient is not a valid target (bot/app ID "${r}" from stale session)`)}}if(r&&$d(r))return{ok:!0,to:r};let n=t?.[0];return n?{ok:!0,to:String(n).trim()}:{ok:!1,error:new Error("WPS target is required (user_id or chat_id)")}},sendText:async({cfg:e,to:t,text:r,accountId:n})=>{let i=Zo(e,t,n??void 0);return Qn(i,t,r)},sendMedia:async({cfg:e,to:t,mediaUrl:r,mimeType:n,accountId:o})=>{let s=Zo(e,t,o??void 0),a=R(s),l=C(s.baseUrl,a),c=es(t),d=(r??"").trim();if(!d)throw new Error("WPS sendMedia requires mediaUrl");let p,u,_=(n??"").trim()||"application/octet-stream",f=null;if(Jn(d)){let h=await Xo(d),w=Nr.basename(d)||"attachment";if(p=/^[0-9a-f]{8}_/.test(w)?w.substring(9):w,!(n??"").trim()){let I=Nr.extname(p).toLowerCase();_={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp",".pdf":"application/pdf",".html":"text/html",".htm":"text/html",".txt":"text/plain",".json":"application/json",".csv":"text/csv",".xml":"application/xml",".zip":"application/zip",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation"}[I]??"application/octet-stream"}u=h.byteLength;let b=!1;if(Mo(d))try{let I=await Xo(d+Rn,"utf8"),x=JSON.parse(I);x.v===1&&x.storage_key&&(d=x.storage_key,typeof x.width=="number"&&typeof x.height=="number"&&x.width>0&&x.height>0&&(f={width:x.width,height:x.height}),b=!0)}catch{}b||(d=(await Xn(l,p,_,h)).storage_key),!f&&_.startsWith("image/")&&(f=at(h),console.log(`[${E}] sendMedia: parsed dimensions ${f?`${f.width}x${f.height}`:"(null)"} for ${p}`))}let g=_.startsWith("image/"),y={type:"file",receiver:{type:c.type,receiver_id:c.id},content:{file:{type:"local",local:{storage_key:d,...p?{name:p}:{},...u!==void 0?{size:u}:{}}}}},m={type:"image",receiver:{type:c.type,receiver_id:c.id},content:{image:{storage_key:d,..._.startsWith("image/")?{type:_}:{},...p?{name:p}:{},...u!==void 0?{size:u}:{},...f?{width:f.width,height:f.height}:{}}}};if(g)try{return await l.request({method:"POST",path:"/v7/messages/create",body:m})}catch(h){let w=h instanceof Error?h.message:String(h);throw console.error(`[${E}] sendMedia image failed: ${w} storageKey=${d.substring(0,30)}\u2026 displayName=${p}`),h}try{return await l.request({method:"POST",path:"/v7/messages/create",body:y})}catch(h){let w=h instanceof Error?h.message:String(h);if(!(/\b400\b/.test(w)||/InvalidMessage|invalid.*file_type/i.test(w)))throw console.error(`[${E}] sendMedia file failed (non-retryable): ${w}`),h;console.log(`[${E}] sendMedia file rejected (400), retrying as image: ${w} displayName=${p}`);try{return await l.request({method:"POST",path:"/v7/messages/create",body:m})}catch(I){let x=I instanceof Error?I.message:String(I);throw console.error(`[${E}] sendMedia image fallback also failed: ${x} displayName=${p}`),I}}}},status:{defaultRuntime:{accountId:he,running:!1,lastStartAt:null,lastStopAt:null,lastError:null},collectStatusIssues:e=>e.flatMap(t=>{let r=[];return t.enabled&&!t.configured&&r.push({channel:E,accountId:t.accountId,kind:"config",message:"WPS credentials not configured (appId and appSecret required).",fix:`Set channels.${E}.accounts.${t.accountId}.appId and channels.${E}.accounts.${t.accountId}.appSecret.`}),r}),buildChannelSummary:({snapshot:e})=>({configured:e.configured??!1,running:e.running??!1,lastStartAt:e.lastStartAt??null,lastStopAt:e.lastStopAt??null,lastError:e.lastError??null,probe:e.probe,lastProbeAt:e.lastProbeAt??null}),probeAccount:async({account:e})=>{let t=ve(e.config);if(!t)return{ok:!1,error:"Not configured"};try{return{ok:!0,token:(await R(t).getToken()).substring(0,8)+"..."}}catch(r){return{ok:!1,error:String(r)}}},buildAccountSnapshot:({account:e,runtime:t,probe:r})=>({accountId:e.accountId,enabled:e.enabled,configured:e.configured,running:t?.running??!1,lastStartAt:t?.lastStartAt??null,lastStopAt:t?.lastStopAt??null,lastError:t?.lastError??null,lastInboundAt:t?.lastInboundAt??null,lastOutboundAt:t?.lastOutboundAt??null,dmPolicy:e.config.dmPolicy??"pairing",probe:r})},gateway:{startAccount:async e=>{let t=we(e.cfg,e.accountId);if(!t?.enabled){e.log?.info?.(`[${e.accountId}] WPS provider disabled`);return}let r=ve(t);if(!r){e.log?.error?.(`[${e.accountId}] WPS credentials not configured`);return}let n=async()=>{},o=a=>{let l=Ed(e.accountId,a),c=()=>fr(e.accountId,()=>Hn({cfg:e.cfg,accountId:e.accountId,channelRuntime:e.channelRuntime??void 0,wpsCfg:t,creds:r,eventPayload:a,log:e.log})).catch(d=>e.log?.error?.("WPS inbound handler error:",d));l?Ad(l,c):c()},i=!1;if(t.sdk?.enabled)try{let a=Sd,l=xd,c=vd,p={debug:c.Debug,warn:c.Warn,error:c.Error}[t.sdk.logLevel??"info"]??c.Info,u=new l().onV7AppChatMessageCreate(async y=>{try{let m=y.parsedData;e.log?.info?.(`[WPS SDK][${e.accountId}/${r.clientId}] message: chat_id=${m.chat.id}, message_id=${m.message.id}`);let h=no(m);o(h)}catch(m){e.log?.error?.("WPS SDK message handler error:",m)}}).onV7AppGroupChatMemberRobotCreate(async y=>{let m=y.parsedData;if(e.log?.info?.(`[WPS SDK] robot joined group: chat_id=${m.chat_id}`),t.robotJoinGroupMessage!==void 0){let h=t.robotJoinGroupMessage||"\u4F60\u597D\uFF01\u6211\u662F AI \u52A9\u624B\uFF0C\u53EF\u4EE5\u5E2E\u52A9\u5927\u5BB6\u5904\u7406\u5404\u79CD\u95EE\u9898\u3002";try{let w=R(r);await C(r.baseUrl,w).request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:{type:"chat",receiver_id:m.chat_id},content:{text:{content:h,type:"markdown"}}}})}catch(w){e.log?.error?.("WPS welcome message failed:",w)}}}).onV7AppGroupChatMemberRobotDelete(async y=>{e.log?.info?.(`[WPS SDK] robot left group: chat_id=${y.parsedData.chat_id}`)}).registerFallbackFunc(y=>{let m=null;if(y.parsedData&&typeof y.parsedData=="object")m=y.parsedData;else if(typeof y.data=="string"&&y.data)try{m=JSON.parse(y.data)}catch{}let h=m?Object.keys(m).join(","):"N/A";if(e.log?.info?.(`[WPS SDK] unhandled event: ${y.eventCode}, keys=${h}`),m&&e.log?.info?.(`[WPS SDK] event payload: ${JSON.stringify(m).slice(0,500)}`),m){let w=typeof m.code=="string"?m.code:typeof m.authorization_code=="string"?m.authorization_code:void 0,b=typeof m.state=="string"?m.state:void 0;if(w){let I=typeof m.user_id=="string"?m.user_id:void 0;e.log?.info?.(`[WPS SDK] Auth code detected: eventCode=${y.eventCode}, code=${w.slice(0,8)}..., state=${b??"(none)"}, userId=${I??"(none)"}`),(async()=>{try{let{handleAuthEvent:x}=await Promise.resolve().then(()=>(Cr(),Bn));await x({code:w,state:b??"",creds:r,wpsCfg:t,log:e.log,userId:I,accountId:e.accountId})}catch(x){e.log?.error?.(`[WPS SDK] Auth event handling failed: ${String(x)}`)}})()}}}),_=new a(oo({appId:r.clientId,appSecret:r.clientSecret,dispatcher:u,logLevel:p,endpoint:t.sdk.endpoint},t.sdk));_.start().catch(y=>{e.log?.error?.("WPS SDK client.run ended:",y)});let f=t.sdk.connectTimeoutMs??2e4,g=Date.now()+f;for(;Date.now()<g&&!_.isConnected();)await new Promise(y=>setTimeout(y,150));if(_.isConnected()){i=!0,e.log?.info?.("[WPS SDK] long connection established");let y=()=>_.stop();e.abortSignal.addEventListener("abort",y),n=async()=>{e.abortSignal.removeEventListener("abort",y),_.stop()}}else _.stop(),e.log?.warn?.(`[WPS SDK] connect timeout (${f}ms), falling back to Webhook`)}catch(a){e.log?.warn?.(`[WPS SDK] init failed: ${String(a)}, falling back to Webhook`)}if(!i){let a=await import("express"),l=(a.default||a)();l.use(a.json());let c=t.webhook?.port??3e3,d=t.webhook?.path??"/wps/webhook",p=t.enableEncryption!==!1;l.post(d,(_,f)=>{let g=io(_.body,{appId:r.clientId,appSecret:r.clientSecret},p,e.log);if("challenge"in g){f.status(200).json({challenge:g.challenge});return}if(!g.ok){let y=g.status??200;y===200?f.status(200).json({code:0,msg:"ok"}):f.status(y).json({code:-1,msg:g.error});return}f.status(200).json({code:0,msg:"ok"}),o(g.payload)});let u=l.listen(c,()=>{e.log?.info?.(`[${e.accountId}] WPS webhook listening on :${c}${d}`)});n=async()=>{u&&(u.close(),u=null)}}let s=i?"sdk":"webhook";e.setStatus({accountId:e.accountId,running:!0,lastStartAt:Date.now(),mode:s}),e.log?.info?.(`[${e.accountId}] WPS channel started (mode=${s})`);try{let a=R(r),l=C(r.baseUrl,a);_r(e.accountId,{client:l,log:e.log??null,wpsCfg:t,creds:r}),yr(e.accountId,{appId:r.clientId,appSecret:r.clientSecret,baseUrl:r.baseUrl}),Sr(e.accountId);let c=gr(dr(e.cfg));e.accountId===c&&Qr(e.accountId),e.log?.info?.(`[${e.accountId}] WPS client initialized for OAPI tools`);try{let p=((await l.request({method:"GET",path:`/v7/developer/apps/${encodeURIComponent(r.clientId)}`,query:{lang:"zh-CN"}})).data?.scopes??[]).filter(g=>g.auth_types?.includes("delegated")).map(g=>({name:g.name??"",description:g.description??""})).filter(g=>g.name);it(e.accountId,p),e.log?.info?.(`[${e.accountId}] Delegated scopes: ${p.map(g=>g.name).join(", ")||"(none)"}`);let{detectScopeChanges:u}=await Promise.resolve().then(()=>(Jo(),Ko)),_=u(e.accountId,p.map(g=>g.name));_.added.length>0&&e.log?.info?.(`[${e.accountId}] Delegated scopes ADDED since last startup: ${_.added.join(", ")}`),_.removed.length>0&&e.log?.info?.(`[${e.accountId}] Delegated scopes REMOVED since last startup: ${_.removed.join(", ")}`);let{markDelegatedScopeCacheFresh:f}=await Promise.resolve().then(()=>(lt(),ct));f(e.accountId),e.log?.info?.(`[${e.accountId}] Delegated scope on-demand cache enabled (30s TTL)`)}catch(d){it(e.accountId,[]);let p=String(d);p.includes("invalid_scope")?e.log?.info?.(`[${e.accountId}] Delegated scopes unavailable (invalid_scope). OAuth \u6388\u6743\u5361\u7247\u80FD\u529B\u4E0D\u53EF\u7528\uFF0C\u4F46\u4E0D\u5F71\u54CD\u666E\u901A\u6D88\u606F\u6536\u53D1\u3002`):e.log?.warn?.(`[${e.accountId}] Failed to fetch delegated scopes: ${p}`)}}catch(a){e.log?.error?.(`[${e.accountId}] WPS client init failed:`,a)}return Qi(e.abortSignal,n)}},onboarding:{channel:E,getStatus:async({cfg:e})=>{let t=e,r=we(t,de(t)),n=!!ve(r);return{channel:E,configured:n,statusLines:[`WPS: ${n?"configured":"needs appId and appSecret"}`],selectionHint:n?"configured":"needs credentials",quickstartScore:n?2:1}},configure:async({cfg:e})=>({cfg:e})},agentPrompt:{messageToolHints:()=>["- WPS targeting: omit `to` to reply in the current conversation (framework auto-routes to the correct chat/user). To send to a **different** conversation, use `message(action=send, to=chat:<chat_id>, message=...)`.","- To find a chat by name, use `wps_chat_find_by_name` first, then use the returned chat_id as `to=chat:<chat_id>`.","- AK-prefixed strings (e.g. AK12345678) are bot/app IDs \u2014 NEVER use them as chat_id, receiver_id, or `to` values.","- IMPORTANT: User-sent images/files are auto-downloaded to local paths (shown in the conversation body). To send back / forward / download for the user, use `message(action=send, media=<local_path>)`. NEVER call wps_media_fetch_base64 or wps_media_download for already-downloaded files \u2014 they will fail because the correct chat_id is NOT available as a top-level context field."]},actions:{describeMessageTool:()=>({actions:["send"]}),handleAction:e=>{let t=e.cfg,r=e.params.to??e.params.target??e.params.receiver_id,n=r&&typeof r=="string"?r.trim():"",o=ts(n),i=e.accountId||o||de(t);return fr(i,async()=>{if(e.action!=="send")throw new Error(`WPS does not support action: ${e.action}`);let s=e.params.message??e.params.text??e.params.content,a=e.params.media,l=we(t,i),c=ve(l);if(!c)throw new Error("WPS credentials not configured");let d=r&&typeof r=="string"&&r.trim()?r.trim():"";if(d.startsWith("wps-xiezuo:")?d=d.slice(11):d.startsWith("wps:")&&(d=d.slice(4)),ft.test(d)){let u=d.match(/:acct:([^:]+)/),_=u?.[1]?`:acct:${u[1]}`:"",f=d.match(/:p2p:([^:]+)/);if(f?.[1]&&!ft.test(f[1]))d=`user:${f[1]}${_}`;else{let g=d.match(/:group:([^:]+)/);if(g?.[1]&&!ft.test(g[1]))d=`chat:${g[1]}${_}`;else{let y=Nn(i);if(y)d=y.isDirect?`user:${y.senderId}`:`chat:${y.chatId}`;else return console.warn(`[WPS handleAction] to="${r}" contains a bot/app ID pattern, no inbound context to auto-correct.`),{text:"\u53D1\u9001\u5931\u8D25\uFF1A\u76EE\u6807\u5730\u5740\u65E0\u6548\u3002\u8BF7\u7701\u7565 to \u53C2\u6570\u4EE5\u81EA\u52A8\u56DE\u590D\u5F53\u524D\u4F1A\u8BDD\uFF0C\u6216\u4F7F\u7528 chat:<chatId> / user:<userId> \u6307\u5B9A\u76EE\u6807\u3002"}}}}if(!d){let u=Nn(i);u&&(d=u.isDirect?`user:${u.senderId}`:`chat:${u.chatId}`)}if(a&&typeof a=="string"&&a.trim()){let u=a.trim();if(Jn(u)){if(!d)throw new Error("WPS send with media requires 'to' (e.g. 'user:<id>' or 'chat:<id>')");return await ei.outbound.sendMedia({cfg:e.cfg,to:d,mediaUrl:u,mimeType:void 0}),{text:`Media sent (${Nr.basename(u)||"attachment"})`}}}if(!d)throw new Error("WPS send requires 'to' (e.g. 'user:<id>' or 'chat:<id>')");if(!s||typeof s!="string"||!s.trim())throw new Error("WPS send requires 'message' or 'text'");return{text:`Message sent (id: ${(await Qn(c,d,s.trim())).messageId})`}})}}};ue();function Mr(e){return e.data??null}function Wr(e){return{error:e instanceof Error?e.message:String(e)}}function Je(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function ti(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function Rd(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}function rs(e){try{return JSON.parse(e)}catch{throw new Error("content must be valid JSON matching the WPS message content structure")}}function Cd(e,t){if(e==="file"){let r=t.file;if(!r){let n=t.storage_key;if(n)return{file:{type:"local",local:{storage_key:n,...t.name?{name:t.name}:{},...t.size!==void 0?{size:t.size}:{}}}};throw new Error(`file content must contain a 'file' object. Required structure: {"file":{"type":"local","local":{"storage_key":"..."}}}`)}if(r.type||(r.type="local"),r.type==="local"&&!r.local){let n=r.storage_key;if(n)r.local={storage_key:n,...r.name?{name:r.name}:{},...r.size!==void 0?{size:r.size}:{}},delete r.storage_key,delete r.name,delete r.size;else throw new Error(`file.local is required for type='local'. Expected: {"file":{"type":"local","local":{"storage_key":"..."}}}`)}return t}if(e==="image"){if(!t.image){let n=t.storage_key;if(n)return{image:{storage_key:n,...typeof t.width=="number"?{width:t.width}:{},...typeof t.height=="number"?{height:t.height}:{}}};throw new Error(`image content must contain an 'image' object. Required structure: {"image":{"storage_key":"..."}}`)}return t}return t}function Dd(e,t){if(e==="text"){try{let n=JSON.parse(t);if(n&&typeof n=="object"&&"text"in n)return{type:"text",content:n}}catch{}return{type:"text",content:{text:{content:t,type:"markdown"}}}}let r=rs(t);if(typeof r!="object"||r===null)throw new Error(`content for ${e} must be a JSON object (message content subtree)`);return e==="rich_text"?{type:"rich_text",content:r}:{type:"image",content:r}}function ri(e,t){t({name:"wps_message_send",description:`Send a message to any WPS user or chat via OpenAPI. IMPORTANT: When the user asks to send a message to someone or to a chat/group, use THIS tool. If the user provides a chat name instead of an ID, call wps_chat_find_by_name first to resolve the chat_id, then call this tool with receiver_type='chat'. receiver_type: 'user' (for P2P/DM by user_id) or 'chat' (for group/chat by chat_id). receiver_id MUST be the real WPS chat id or user id (numeric/string id from the WPS API). For replies in the current conversation, read inbound RawBody JSON \`chatId\` and \`SenderId\`: use receiver_type='chat' + receiver_id=chatId when chatId is present, else receiver_type='user' + receiver_id=SenderId. NEVER use SessionKey segments after ':bot:' (often looks like AK\u2026) as receiver_id \u2014 that is a bot/app id, not a chat id, and causes invalid chatId / deMixValue errors. Text: msg_type='text', content='{"text":{"content":"hello","type":"markdown"}}'. Image: first call wps_media_upload_base64 for storage_key (it also returns width & height), then msg_type='image', content='{"image":{"storage_key":"...","width":W,"height":H}}'. File: first call wps_media_upload_base64 for storage_key, then msg_type='file', content='{"file":{"type":"local","local":{"storage_key":"...","name":"filename.ext"}}}'. CRITICAL: cloud documents (type=cloud) CANNOT be sent or forwarded via this API. To share a cloud doc with the user, use msg_type='text' and include the link URL in the text content. NEVER attempt to send cloud files with msg_type='file' or msg_type='image' \u2014 it will always fail.`,parameters:{type:"object",properties:{receiver_type:{type:"string",enum:["user","chat"],description:"Target kind: `user` opens or uses p2p with that user id; `chat` sends to a chat id."},receiver_id:{type:"string",description:"WPS user id or chat id from the API (not SessionKey `:bot:` segment). For the active thread, prefer RawBody `chatId` or user id."},msg_type:{type:"string",enum:["text","rich_text","image","file"],description:"WPS message type field sent as `type` in the API body."},content:{type:"string",description:"JSON string for the WPS message `content` object (structure depends on msg_type)."},mentions:{type:"array",description:"Optional mention list for group messages.",items:{type:"object",additionalProperties:!0}}},required:["receiver_type","receiver_id","msg_type","content"]},async execute(r,n){try{let o=Je(n,"receiver_type");if(o!=="user"&&o!=="chat")throw new Error("receiver_type must be 'user' or 'chat'");let i=Je(n,"receiver_id");if(i.startsWith("wps-xiezuo:")?i=i.slice(11):i.startsWith("wps:")&&(i=i.slice(4)),/AK\d{8}/i.test(i))throw new Error(`receiver_id="${n.receiver_id}" contains a bot/app ID pattern ("${i}"). Omit the 'to' parameter in the message tool to reply in the current conversation, or use receiver_type='user' with SenderId, or receiver_type='chat' with RawBody.chatId.`);if(i.includes(":"))throw new Error(`receiver_id="${n.receiver_id}" looks like a session key or compound ID, NOT a receiver ID. Use a bare numeric ID from RawBody.chatId (group) or SenderId (DM).`);let s=Je(n,"msg_type");if(!["text","rich_text","image","file"].includes(s))throw new Error("msg_type must be one of: text, rich_text, image, file");let a=Je(n,"content");if(a.length>5e3)throw new Error("content JSON string exceeds 5000 characters");let l=rs(a);if(typeof l!="object"||l===null)throw new Error("parsed content must be a JSON object");let c=s==="file"||s==="image"?Cd(s,l):l,d={type:s,receiver:{type:o,receiver_id:i},content:c},p=n.mentions;if(p!==void 0){if(!Array.isArray(p))throw new Error("mentions must be an array when provided");d.mentions=p}let u=await e.request({method:"POST",path:"/v7/messages/create",body:d});return Mr(u)}catch(o){return Wr(o)}}}),t({name:"wps_message_reply",description:"Reply to an existing message in a chat (POST /v7/chats/{chat_id}/messages/{message_id}/reply). Use this to reply in-thread to a specific message. For sending NEW messages (not replies), use wps_message_send instead. Supports msg_type text, rich_text, or image. For text, content can be plain text or JSON content object.",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."},message_id:{type:"string",description:"Message id to reply to (from RawBody.messageId)."},msg_type:{type:"string",enum:["text","rich_text","image"],description:"Reply payload type."},content:{type:"string",description:"For text: plain string or JSON string of `content`. For rich_text/image: JSON string of the `content` subtree."}},required:["chat_id","message_id","msg_type","content"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=encodeURIComponent(Je(n,"message_id")),s=Je(n,"msg_type");if(s!=="text"&&s!=="rich_text"&&s!=="image")throw new Error("msg_type must be text, rich_text, or image");let a=Je(n,"content"),l=Dd(s,a),c=await e.request({method:"POST",path:`/v7/chats/${o}/messages/${i}/reply`,body:l});return Mr(c)}catch(o){return Wr(o)}}}),t({name:"wps_message_list",description:"List messages in a chat (GET /v7/chats/{chat_id}/messages). page_size defaults to 50. `start_time` and `end_time` are Unix timestamps in **seconds** (converted to milliseconds for the API). Returns paginated message list; use page_token for next pages.",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."},start_time:{type:"number",description:"Optional inclusive range start (Unix seconds); sent as start_time query in ms."},end_time:{type:"number",description:"Optional inclusive range end (Unix seconds); sent as end_time query in ms."},page_size:{type:"number",description:"Page size (default 50, max 100)."},page_token:{type:"string",description:"Pagination cursor from a previous response."}},required:["chat_id"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=ti(n,"start_time"),s=ti(n,"end_time"),a=ti(n,"page_size")??50,l=Rd(n,"page_token"),c={page_size:a};l!==void 0&&(c.page_token=l),i!==void 0&&(c.start_time=Math.trunc(i*1e3)),s!==void 0&&(c.end_time=Math.trunc(s*1e3));let d=await e.request({method:"GET",path:`/v7/chats/${o}/messages`,query:c});return Mr(d)}catch(o){return Wr(o)}}}),t({name:"wps_message_get",description:"Fetch a single message by id within a chat (GET /v7/chats/{chat_id}/messages/{message_id}).",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."},message_id:{type:"string",description:"Message id (from RawBody.messageId)."}},required:["chat_id","message_id"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=encodeURIComponent(Je(n,"message_id")),s=await e.request({method:"GET",path:`/v7/chats/${o}/messages/${i}`});return Mr(s)}catch(o){return Wr(o)}}})}function ns(e){return e.data??null}function is(e){return{error:e instanceof Error?e.message:String(e)}}function qd(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function Ud(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function Nd(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}var jd=["active"],Md=["user_name","email","phone"],Wd=["company_user"],Ld=50;function ni(e,t){t({name:"wps_user_get",description:"Get the current authenticated bot/app user profile (GET /v7/users/current). Returns fields such as id, user_name, avatar, and company_id when exposed by the API.",parameters:{type:"object",properties:{},required:[]},async execute(r,n){try{let o=await e.request({method:"GET",path:"/v7/users/current"});return ns(o)}catch(o){return is(o)}}}),t({name:"wps_user_search",description:"Search company users by keyword (GET /v7/users/search). Always applies status=active, search_field=user_name+email+phone, and search_source=company_user. page_size defaults to 50 (WPS API requires this field). Returns a paginated user list; use page_token for next pages. If no results found, suggest the user refine the keyword or try email/phone.",parameters:{type:"object",properties:{keyword:{type:"string",description:"Search keyword (name, email fragment, phone, etc.)."},page_size:{type:"number",description:"Page size (default 50, max 100)."},page_token:{type:"string",description:"Pagination token from a prior call."}},required:["keyword"]},async execute(r,n){try{let o=qd(n,"keyword"),i=Ud(n,"page_size")??Ld,s=Nd(n,"page_token"),a={keyword:o,status:[...jd],search_field:[...Md],search_source:[...Wd],page_size:i};s!==void 0&&(a.page_token=s);let l=await e.request({method:"GET",path:"/v7/users/search",query:a});return ns(l)}catch(o){return is(o)}}})}function cr(e){return e.data??null}function Nt(e){return{error:e instanceof Error?e.message:String(e)}}function os(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function ss(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function ii(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}var as=50;function zd(e,t){let r=e[t];if(!Array.isArray(r)||r.length===0)throw new Error(`${t} must be a non-empty array of user id strings`);let n=[];for(let o=0;o<r.length;o++){let i=r[o];if(typeof i!="string"||!i.trim())throw new Error(`${t}[${o}] must be a non-empty string`);n.push(i.trim())}return n}function oi(e,t="user"){return{id:e,type:t}}var Lr=null;async function Fd(e){if(Lr)return Lr;let r=(await e.request({method:"GET",path:"/v7/users/current"})).data;if(!r||typeof r.id!="string"||!r.id.trim())throw new Error("Cannot retrieve current operator identity from /v7/users/current. Ensure the app has kso.user_base.read permission.");return Lr={id:r.id.trim(),type:"user"},Lr}function si(e,t){t({name:"wps_chat_create",description:"Create a p2p or group chat (POST /v7/chats/create). For P2P: provide exactly 2 user ids in member_ids (no auto-injection). For group: provide other member user ids; the current operator is auto-included and becomes owner. Requires kso.chat.readwrite permission.",parameters:{type:"object",properties:{type:{type:"string",enum:["p2p","group"],description:"Chat kind: p2p or group."},member_ids:{type:"array",items:{type:"string"},description:"For P2P: exactly 2 user ids. For group: other member ids (operator auto-included)."},name:{type:"string",description:"Group chat display name (only for group type)."}},required:["type","member_ids"]},async execute(r,n){try{let o=os(n,"type");if(o!=="p2p"&&o!=="group")throw new Error("type must be 'p2p' or 'group'");let i=zd(n,"member_ids"),s,a={type:o};if(o==="group"){let c=await Fd(e),d=new Set;s=[],d.add(c.id),s.push(oi(c.id));for(let u of i)d.has(u)||(s.push(oi(u)),d.add(u));a.owner_id=c.id;let p=ii(n,"name");p!==void 0&&p!==""&&(a.name=p)}else{let c=[...new Set(i)];if(c.length!==2)throw new Error(`P2P chat requires exactly 2 distinct user ids in member_ids. Got ${c.length} after dedup.`);s=c.map(d=>oi(d))}a.account_id_list=s;let l=await e.request({method:"POST",path:"/v7/chats/create",body:a});return cr(l)}catch(o){return Nt(o)}}}),t({name:"wps_chat_list",description:"List chats for the current context (GET /v7/chats). page_size defaults to 50. Returns paginated chat list; use page_token for next pages.",parameters:{type:"object",properties:{page_size:{type:"number",description:"Page size (default 50, max 100)."},page_token:{type:"string",description:"Pagination token from a prior call."}},required:[]},async execute(r,n){try{let o=ss(n,"page_size")??as,i=ii(n,"page_token"),s={page_size:o};i!==void 0&&(s.page_token=i);let a=await e.request({method:"GET",path:"/v7/chats",query:s});return cr(a)}catch(o){return Nt(o)}}}),t({name:"wps_chat_get",description:"Get metadata for a single chat (GET /v7/chats/{chat_id}).",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."}},required:["chat_id"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=await e.request({method:"GET",path:`/v7/chats/${o}`});return cr(i)}catch(o){return Nt(o)}}}),t({name:"wps_chat_members",description:"List members of a chat (GET /v7/chats/{chat_id}/members). page_size defaults to 50. Returns paginated member list; use page_token for next pages.",parameters:{type:"object",properties:{chat_id:{type:"string",description:"Chat session id."},page_size:{type:"number",description:"Page size (default 50, max 100)."},page_token:{type:"string",description:"Pagination token from a prior call."}},required:["chat_id"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=ss(n,"page_size")??as,s=ii(n,"page_token"),a={page_size:i};s!==void 0&&(a.page_token=s);let l=await e.request({method:"GET",path:`/v7/chats/${o}/members`,query:a});return cr(l)}catch(o){return Nt(o)}}}),t({name:"wps_chat_is_member",description:"Check whether the current operator is a member of the chat (GET /v7/chats/{chat_id}/members/is_in_chat).",parameters:{type:"object",properties:{chat_id:{type:"string",description:"Chat session id."}},required:["chat_id"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=await e.request({method:"GET",path:`/v7/chats/${o}/members/is_in_chat`});return cr(i)}catch(o){return Nt(o)}}}),t({name:"wps_chat_find_by_name",description:"Find a WPS chat/group by name. IMPORTANT: When the user says 'send message to <group name>' or '\u7ED9 <\u7FA4\u540D> \u53D1\u6D88\u606F', ALWAYS call this tool first to resolve the chat_id, then use wps_message_send with receiver_type='chat' and the resolved chat_id. Returns matching chats with owner info for disambiguation. If multiple matches, present the list to the user for selection.",parameters:{type:"object",properties:{keyword:{type:"string",description:"Chat name keyword to search for."}},required:["keyword"]},async execute(r,n){try{let o=os(n,"keyword").toLowerCase(),i=[],s,a=!1;for(let c=0;c<10;c++){let d={page_size:100};s&&(d.page_token=s);let p=await e.request({method:"GET",path:"/v7/chats",query:d});for(let u of p.data?.items??[])u.chat_id&&u.name?.toLowerCase().includes(o)&&i.push({chat_id:u.chat_id,name:u.name,owner_id:u.owner_id});if(!p.data?.has_more)break;if(s=p.data?.page_token,!s){a=!0;break}}let l={};return a&&(l.warning="Results may be incomplete: pagination was truncated due to missing page_token."),i.length===0?{...l,found:!1,message:`No chats found matching "${o}"`}:i.length===1?{...l,found:!0,match:i[0]}:{...l,found:!0,multiple:!0,matches:i,hint:"Multiple matches found. Present the list to the user with chat name and owner info for selection."}}catch(o){return Nt(o)}}})}Fe();ue();Ar();Be();Cr();Mn();_n();wn();xt();function Bd(e){if(e)return e;let t=Kt();if(t)return t;let r=en();if(r)return r;throw new Error("WPS accountId required: no explicit accountId, no ALS context, no default account set")}async function _e(e){let t=Bd(e.accountId),r=e.toolModule?yn(e.toolModule):[];if(r.length>0){let{ensureDelegatedScopesFresh:s}=await Promise.resolve().then(()=>(lt(),ct));await s(t);let a=fn({requiredScopes:r,accountId:t,wpsUserId:e.wpsUserId});if(!a.ok)switch(a.reason){case"app_scope_missing":return await Gd(t,e,a.message),{needsAppScope:!0,message:a.message};case"no_token":case"user_scope_insufficient":{if(a.appScopeVerified){let l=await zr(t,e);return{needsAuth:!0,message:Fr(l,a.message)}}return{needsAuth:!0,message:`${a.message} \u8BF7\u4F7F\u7528 /wpsxiezuo auth \u624B\u52A8\u6388\u6743\u3002`}}}}let n=Te(t,e.wpsUserId);if(!n){let s=await zr(t,e);return{needsAuth:!0,message:Fr(s,e.needsAuthMessage)}}let o=nt(t),i=hn(o.baseUrl,n);try{return await e.run(i,t)}catch(s){if(Vr(s)){Ir(t,e.wpsUserId);let{getDelegatedScopes:a}=await Promise.resolve().then(()=>(ue(),Xt));if(a(t).length>0){let l=await zr(t,e);return{needsAuth:!0,message:Fr(l,"token \u5DF2\u5931\u6548\uFF0C\u9700\u8981\u91CD\u65B0\u6388\u6743\u3002")}}return{needsAuth:!0,message:"token \u5DF2\u5931\u6548\uFF0C\u9700\u8981\u91CD\u65B0\u6388\u6743\u3002\u8BF7\u4F7F\u7528 /wpsxiezuo auth \u624B\u52A8\u6388\u6743\u3002"}}if(Xr(s)){br(t,e.wpsUserId);let a=oe(t),{invalidateDelegatedScopeCache:l,ensureDelegatedScopesFresh:c}=await Promise.resolve().then(()=>(lt(),ct));l(t),await c(t);let{getDelegatedScopes:d}=await Promise.resolve().then(()=>(ue(),Xt)),p=d(t),u=new Set(p.map(f=>f.name)),_=r.filter(f=>!u.has(f));if(p.length>0&&_.length>0)return a?.info?.(`[${e.logTag}] 403 scope error: app missing scopes [${_.join(", ")}] \u2192 hint`),{needsAppScope:!0,message:`\u6743\u9650\u4E0D\u8DB3\uFF0C\u8BF7\u5728 WPS \u5F00\u653E\u5E73\u53F0\u7533\u8BF7\u5BF9\u5E94\u529F\u80FD\u6743\u9650\u3002${`\u9700\u8981\u7684\u6743\u9650\uFF1A${_.join(", ")}`}`};if(p.length>0){a?.info?.(`[${e.logTag}] 403 scope error: user scope revoked \u2192 sending auth card`);let f=await zr(t,e);return{needsAuth:!0,message:Fr(f,"\u6743\u9650\u4E0D\u8DB3\uFF0C\u9700\u8981\u91CD\u65B0\u6388\u6743\u3002")}}return a?.info?.(`[${e.logTag}] 403 scope error: delegated list empty after refresh \u2192 conservative, no auto card`),{needsAuth:!0,message:"\u6743\u9650\u4E0D\u8DB3\uFF0C\u8BF7\u4F7F\u7528 /wpsxiezuo auth \u624B\u52A8\u6388\u6743\u3002"}}throw s}}async function zr(e,t){let r=t.messageId?`${e}:${t.wpsUserId}:${t.messageId}`:`${e}:${t.wpsUserId}`;if(jn(r))return"cooldown";let n=!1;return await xo(r,async()=>{let o=rn(e),i=nt(e),s=oe(e);try{await Fn({accountId:e,creds:i,wpsCfg:o,wpsUserId:t.wpsUserId,receiverType:"user",receiverId:t.wpsUserId,originalMessage:t.authCardOriginalMessage}),ko(r),n=!0}catch(a){s?.error?.(`[${t.logTag}] Failed to send auth card: ${String(a)}`)}}),n?"sent":"failed"}function Fr(e,t){switch(e){case"sent":return t;case"cooldown":return`${t} \u6388\u6743\u5361\u7247\u5DF2\u53D1\u9001\uFF0C\u8BF7\u70B9\u51FB\u4E4B\u524D\u7684\u5361\u7247\u5B8C\u6210\u6388\u6743\u3002`;case"failed":return`${t} \u6388\u6743\u5361\u7247\u53D1\u9001\u5931\u8D25\uFF0C\u8BF7\u4F7F\u7528 /wpsxiezuo auth \u624B\u52A8\u6388\u6743\u3002`}}async function Gd(e,t,r){let n=nt(e),o=oe(e);try{let i=R(n);await C(n.baseUrl,i).request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:{type:"user",receiver_id:t.wpsUserId},content:{text:{content:r,type:"markdown"}}}})}catch(i){o?.warn?.(`[${t.logTag}] Failed to send app scope hint: ${String(i)}`)}}var ds=31*24*60*60*1e3,Hd=100,cs=200,ls=50,ps=100;function K(e){return{error:e instanceof Error?e.message:String(e)}}function P(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function v(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}function jt(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function Mt(e,t){let r=e[t];if(r!=null){if(typeof r=="boolean")return r;if(r==="true"||r==="false")return r==="true";throw new Error(`${t} must be a boolean`)}}function Kd(e,t){let r=e[t];if(r==null)throw new Error(`${t} is required and must be a finite number`);if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}function Br(e,t){let r=new Date(t.trim());if(Number.isNaN(r.getTime()))throw new Error(`${e} must be a valid RFC3339 / ISO 8601 datetime string`);return r}function Wt(e){return e.toISOString()}function ai(e){let t=e.now??new Date,r,n,o=!!e.startRfc?.trim(),i=!!e.endRfc?.trim();if(o&&i?(r=Br("start_time",e.startRfc),n=Br("end_time",e.endRfc)):o?(r=Br("start_time",e.startRfc),n=new Date(r.getTime()+14*86400*1e3)):i?(n=Br("end_time",e.endRfc),r=new Date(n.getTime()-14*86400*1e3)):(r=new Date(t.getTime()-86400*1e3),n=new Date(t.getTime()+14*86400*1e3)),n.getTime()<r.getTime())throw new Error("end_time must be >= start_time (RFC3339 range)");return n.getTime()-r.getTime()>ds&&(n=new Date(r.getTime()+ds)),{start:r,end:n}}function Jd(e){let{start:t,end:r}=ai({startRfc:e.startRfc,endRfc:e.endRfc,now:e.now}),n={start_time:Wt(t),end_time:Wt(r)},o=e.pageSize??30;return n.page_size=Math.max(1,Math.min(500,Math.trunc(o))),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(n.page_token=e.pageToken.trim()),n}function Xd(e){let{start:t,end:r}=ai({startRfc:e.startRfc,endRfc:e.endRfc,now:e.now});return{start_time:Wt(t),end_time:Wt(r)}}function Vd(e){let t={},r=e.pageSize??30;if(t.page_size=Math.max(1,Math.min(500,Math.trunc(r))),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(t.page_token=e.pageToken.trim()),e.withCancelled===!0&&(t.with_cancelled=!0),e.syncToken!==void 0&&e.syncToken.trim()!==""&&(t.sync_token=e.syncToken.trim()),e.anchorTime!==void 0&&e.anchorTime.trim()!==""&&(t.anchor_time=e.anchorTime.trim()),t.sync_token)return t;let{start:n,end:o}=ai({startRfc:e.startRfc,endRfc:e.endRfc,now:e.now});return t.start_time=Wt(n),t.end_time=Wt(o),t}function Yd(e){let t=new Date(e.trim());if(Number.isNaN(t.getTime()))throw new Error("start_time must be a valid ISO 8601 datetime");return t.setTime(t.getTime()+60*60*1e3),t.toISOString()}function De(e,t){return`/v7/calendars/${encodeURIComponent(e)}/events/${encodeURIComponent(t)}`}function Zd(e,t){return`${De(e,t)}/respond`}function di(e,t){return`${De(e,t)}/attendees`}function Qd(e,t){return`${di(e,t)}/batch_create`}function ec(e,t){return`${di(e,t)}/batch_delete`}function tc(e,t){return`${De(e,t)}/meeting_rooms`}function rc(e,t){return`${De(e,t)}/meeting_rooms/batch_create`}function nc(e,t){return`${De(e,t)}/meeting_rooms/batch_delete`}function us(e){if(!Array.isArray(e)||e.length===0)throw new Error("room_ids is required and must be a non-empty array");let t=e.map((r,n)=>{if(typeof r!="string")throw new Error(`room_ids[${n}] must be a string`);let o=r.trim();if(!o)throw new Error(`room_ids[${n}] must be non-empty`);return o});if(t.length>ps)throw new Error(`room_ids length must be <= ${ps}`);return{room_ids:t}}function ic(e){let t=e.pageSize??30,n={page_size:Math.max(1,Math.min(Hd,Math.trunc(t)))};return e.pageToken!==void 0&&e.pageToken.trim()!==""&&(n.page_token=e.pageToken.trim()),n}function Xe(e){let t=v(e,"x_kso_id_type");if(t===void 0||t.trim()==="")return;let r=t.trim();if(r!=="internal"&&r!=="external")throw new Error("x_kso_id_type must be internal or external when provided");return{"X-Kso-Id-Type":r}}async function Z(e,t,r){try{return await _e({wpsUserId:e,toolModule:"calendar",authCardOriginalMessage:t,needsAuthMessage:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u64CD\u4F5C\u65E5\u7A0B\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u5B8C\u6210\u6388\u6743\u540E\u91CD\u8BD5\u3002",logTag:"calendar",run:r})}catch(n){return K(n)}}function ci(e,t){t({name:"wps_calendar_create",description:"Create a calendar event for the current user via WPS OpenAPI. Requires user OAuth authorization. If the user has not authorized, an authorization card will be sent automatically. IMPORTANT: Use the SenderId from the current conversation context as wps_user_id. Do NOT call wps_user_search or wps_user_get to look up the user. If end_time is omitted, it defaults to start_time + 1 hour (computed as UTC ISO).",parameters:{type:"object",properties:{summary:{type:"string",description:"Event title."},start_time:{type:"string",description:"Start time in ISO 8601 with timezone (e.g. '2026-04-22T14:00:00+08:00')."},end_time:{type:"string",description:"End time in ISO 8601 with timezone. Omit to default to start_time + 1 hour."},description:{type:"string",description:"Optional event description."},location:{type:"string",description:"Optional event location."},wps_user_id:{type:"string",description:"WPS user ID. Use SenderId from the conversation context. Do NOT call wps_user_search or wps_user_get for this."}},required:["summary","start_time"]},async execute(o,i){try{let s=P(i,"summary"),a=P(i,"start_time"),l=v(i,"end_time"),c=l&&l.trim()!==""?l.trim():Yd(a),d=v(i,"description"),p=v(i,"location"),u=v(i,"wps_user_id")??"";return u?await Z(u,s,async _=>{let f={summary:s,start_time:{datetime:a},end_time:{datetime:c}};d&&(f.description=d),p&&(f.locations=[{name:p}]);let g=await _.request({method:"POST",path:"/v7/calendars/primary/events/create",body:f});return g.data??g}):K(new Error("wps_user_id is required. Use the SenderId from the conversation context."))}catch(s){return K(s)}}}),t({name:"wps_calendar_list_events",description:"List calendar events on the user's primary calendar: GET `/v7/calendars/primary/events` (same as `/v7/calendars/{calendar_id}/events` with calendar_id `primary`). Official doc: https://365.kdocs.cn/3rd/open/documents/app-integration-dev/wps365/server/calendar/calendar-event/get-calendar-event-list Requires user delegated OAuth (same as wps_calendar_create). Use SenderId as wps_user_id. Time range: `start_time` and `end_time` query params are **RFC3339 / ISO8601 strings** (not Unix seconds). If both are omitted, defaults to about last 24 hours through next 14 days, clamped to max 31-day span per API. If `sync_token` is set, incremental sync mode: only sync_token/page_token/page_size/with_cancelled are sent (no automatic time window). Optional: anchor_time (RFC3339), with_cancelled (boolean).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},start_time:{type:"string",description:"Optional range start (RFC3339 / ISO8601). Must be used with end_time for explicit window, or omit both for defaults."},end_time:{type:"string",description:"Optional range end (RFC3339 / ISO8601). API allows 0\u201331 days between start and end; longer ranges are truncated."},page_size:{type:"number",description:"Page size (default 30 per API doc, max 500 client-side cap)."},page_token:{type:"string",description:"Pagination cursor from data.next_page_token."},with_cancelled:{type:"boolean",description:"Include cancelled events (per API)."},sync_token:{type:"string",description:"Incremental sync token from data.next_sync_token; when set, time range is not auto-filled."},anchor_time:{type:"string",description:"Anchor time RFC3339 for incremental sync (per API)."}},required:["wps_user_id"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=v(i,"start_time"),l=v(i,"end_time"),c=jt(i,"page_size"),d=v(i,"page_token"),p=Mt(i,"with_cancelled"),u=v(i,"sync_token"),_=v(i,"anchor_time");return await Z(s,"\u67E5\u8BE2\u4E3B\u65E5\u5386\u65E5\u7A0B\u5217\u8868",async f=>{let g=Vd({startRfc:a,endRfc:l,pageSize:c,pageToken:d,withCancelled:p,syncToken:u,anchorTime:_}),y=await f.request({method:"GET",path:"/v7/calendars/primary/events",query:g});return y.data??y})}catch(s){return K(s)}}}),t({name:"wps_calendar_get_event",description:"Get **one** calendar event by id (official \u67E5\u8BE2\u65E5\u7A0B): GET `/v7/calendars/{calendar_id}/events/{event_id}`. Response `data` is a single event object (summary, recurrence, online_meeting, etc.), not `items[]`. Requires `event_id` from `wps_calendar_list_events` (or equivalent). Same delegated Bearer auth as `wps_calendar_create`. Optional `calendar_id` (default `primary`). Optional header `X-Kso-Id-Type`: pass `x_kso_id_type` as `internal` or `external` per API.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from the calendar event list API."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type` header: `internal` or `external` (per WPS API).",enum:["internal","external"]}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary";return await Z(s,"\u67E5\u8BE2\u65E5\u7A0B\u8BE6\u60C5",async c=>{let d=await c.request({method:"GET",path:De(l,a),headers:Xe(i)});return d.data??d})}catch(s){return K(s)}}}),t({name:"wps_calendar_list_event_attendees",description:"List attendees for one calendar event (official \u83B7\u53D6\u65E5\u7A0B\u53C2\u4E0E\u8005\u5217\u8868): GET `/v7/calendars/{calendar_id}/events/{event_id}/attendees`. Response `data` typically has `items[]` and optional `next_page_token`. Requires `event_id` from `wps_calendar_list_events` or `wps_calendar_get_event`. Same delegated Bearer auth as `wps_calendar_create`. Optional `calendar_id` (default `primary`). Query: optional `page_size` (default 30, max 100 per API), `page_token` from `data.next_page_token`. Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from the calendar event list API."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},page_size:{type:"number",description:"Page size (default 30; API max 100)."},page_token:{type:"string",description:"Pagination cursor from data.next_page_token."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary",c=jt(i,"page_size"),d=v(i,"page_token");return await Z(s,"\u83B7\u53D6\u65E5\u7A0B\u53C2\u4E0E\u8005\u5217\u8868",async p=>{let u=ic({pageSize:c,pageToken:d}),_=await p.request({method:"GET",path:di(l,a),query:u,headers:Xe(i)});return _.data??_})}catch(s){return K(s)}}}),t({name:"wps_calendar_add_event_attendees",description:"Batch add attendees to one event (official \u6DFB\u52A0\u65E5\u7A0B\u53C2\u4E0E\u8005): POST `/v7/calendars/{calendar_id}/events/{event_id}/attendees/batch_create`. Requires delegated OAuth (same as `wps_calendar_create`). Body requires `attendees` array (max 200 per request; total attendees per event max 1000). Each attendee item typically includes `type`, `user_id` or `third_party_email`, optional `is_optional` and `response_status`. Optional `is_notification` controls whether attendees receive invitation notifications (default true). Optional `calendar_id` (default `primary`). Optional `x_kso_id_type` maps to `X-Kso-Id-Type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from event list/search/get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},attendees:{type:"array",description:"Attendees to add in batch (required, max 200 per request). Each item supports fields like { type, user_id, third_party_email, is_optional, response_status }.",items:{type:"object",properties:{type:{type:"string"},user_id:{type:"string"},third_party_email:{type:"string"},is_optional:{type:"boolean"},response_status:{type:"string"}}}},is_notification:{type:"boolean",description:"Whether to notify added attendees (default true)."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id","attendees"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary",c=Mt(i,"is_notification"),d=i.attendees;if(!Array.isArray(d)||d.length===0)throw new Error("attendees is required and must be a non-empty array");if(d.length>cs)throw new Error(`attendees length must be <= ${cs}`);let p=d.map((u,_)=>{if(typeof u!="object"||u===null||Array.isArray(u))throw new Error(`attendees[${_}] must be an object`);let f=u,g={};if(f.type!==void 0){if(typeof f.type!="string"||!f.type.trim())throw new Error(`attendees[${_}].type must be a non-empty string when provided`);g.type=f.type.trim()}if(f.user_id!==void 0){if(typeof f.user_id!="string"||!f.user_id.trim())throw new Error(`attendees[${_}].user_id must be a non-empty string when provided`);g.user_id=f.user_id.trim()}if(f.third_party_email!==void 0){if(typeof f.third_party_email!="string"||!f.third_party_email.trim())throw new Error(`attendees[${_}].third_party_email must be a non-empty string when provided`);g.third_party_email=f.third_party_email.trim()}if(f.is_optional!==void 0){if(typeof f.is_optional!="boolean")throw new Error(`attendees[${_}].is_optional must be a boolean when provided`);g.is_optional=f.is_optional}if(f.response_status!==void 0){if(typeof f.response_status!="string"||!f.response_status.trim())throw new Error(`attendees[${_}].response_status must be a non-empty string when provided`);g.response_status=f.response_status.trim()}if(Object.keys(g).length===0)throw new Error(`attendees[${_}] must contain at least one valid field`);return g});return await Z(s,"\u6DFB\u52A0\u65E5\u7A0B\u53C2\u4E0E\u8005",async u=>{let _={attendees:p};c!==void 0&&(_.is_notification=c);let f=await u.request({method:"POST",path:Qd(l,a),body:_,headers:Xe(i)});return f.data??f})}catch(s){return K(s)}}}),t({name:"wps_calendar_list_event_meeting_rooms",description:"List meeting rooms bound to one calendar event (\u83B7\u53D6\u67D0\u4E2A\u65E5\u7A0B\u7684\u4F1A\u8BAE\u5BA4\u5217\u8868): GET `/v7/calendars/{calendar_id}/events/{event_id}/meeting_rooms`. Requires delegated OAuth **`kso.calendar_events.read`** (or `readwrite`) and `event_id`. Optional `calendar_id` (default `primary`). Response `data.items[]` commonly includes room/book fields like `room_id`, `name`, `booking_id`, `result`, `fail_reason`. Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from event list / search / get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary";return await Z(s,"\u83B7\u53D6\u65E5\u7A0B\u4F1A\u8BAE\u5BA4\u5217\u8868",async c=>{let d=await c.request({method:"GET",path:tc(l,a),headers:Xe(i)});return d.data??d})}catch(s){return K(s)}}}),t({name:"wps_calendar_event_meeting_rooms_batch_create",description:"Batch add meeting rooms to one calendar event (\u6279\u91CF\u6DFB\u52A0\u67D0\u4E2A\u65E5\u7A0B\u7684\u4F1A\u8BAE\u5BA4): POST `/v7/calendars/{calendar_id}/events/{event_id}/meeting_rooms/batch_create`. Requires delegated OAuth **`kso.calendar_events.readwrite`** (per API). Use SenderId as wps_user_id. Required: `event_id`, non-empty **`room_ids`** (string array; room ids from `wps_meeting_rooms_list` / search / get). Optional `calendar_id` (default `primary`). Response `data.items[]` may include `room_id`, `name`, `result`, `booking_id`, `fail_reason`. Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from event list / search / get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},room_ids:{type:"array",description:"Meeting room ids to attach to this event (non-empty; max 100 per request).",items:{type:"string"}},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id","room_ids"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary",c=i.room_ids;if(!Array.isArray(c))throw new Error("room_ids is required and must be an array");let d=us(c);return await Z(s,"\u6279\u91CF\u6DFB\u52A0\u65E5\u7A0B\u4F1A\u8BAE\u5BA4",async p=>{let u=await p.request({method:"POST",path:rc(l,a),body:d,headers:Xe(i)});return u.data??u})}catch(s){return K(s)}}}),t({name:"wps_calendar_event_meeting_rooms_batch_delete",description:"Batch delete meeting rooms from one calendar event (\u6279\u91CF\u5220\u9664\u67D0\u4E2A\u65E5\u7A0B\u7684\u4F1A\u8BAE\u5BA4): POST `/v7/calendars/{calendar_id}/events/{event_id}/meeting_rooms/batch_delete`. Requires delegated OAuth **`kso.calendar_events.readwrite`**. Use SenderId as wps_user_id. Required: `event_id`, non-empty **`room_ids`** (meeting room ids bound to this event). Optional `calendar_id` (default `primary`). Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from event list / search / get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},room_ids:{type:"array",description:"Meeting room ids to remove from this event (non-empty; max 100 per request).",items:{type:"string"}},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id","room_ids"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary",c=i.room_ids;if(!Array.isArray(c))throw new Error("room_ids is required and must be an array");let d=us(c);return await Z(s,"\u6279\u91CF\u5220\u9664\u65E5\u7A0B\u4F1A\u8BAE\u5BA4",async p=>{let u=await p.request({method:"POST",path:nc(l,a),body:d,headers:Xe(i)});return u.data??u})}catch(s){return K(s)}}}),t({name:"wps_calendar_delete_event_attendees",description:"Batch delete attendees from one event (official \u5220\u9664\u65E5\u7A0B\u53C2\u4E0E\u8005): POST `/v7/calendars/{calendar_id}/events/{event_id}/attendees/batch_delete`. Requires delegated OAuth (same as `wps_calendar_create`). Body requires `attendees` array and supports optional `attendee_ids` array. Per API, `attendee_ids.length + attendees.length` must be <= 50 in one request. Optional `is_notification` controls whether removed attendees receive notification (default true). Optional `calendar_id` (default `primary`). Optional `x_kso_id_type` maps to `X-Kso-Id-Type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from event list/search/get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},attendee_ids:{type:"array",description:"Optional attendee id list. Combined count with `attendees` must be <= 50.",items:{type:"string"}},attendees:{type:"array",description:"Attendees payload to remove (required). Combined count with `attendee_ids` must be <= 50. Each item supports fields like { type, user_id, third_party_email }.",items:{type:"object",properties:{type:{type:"string"},user_id:{type:"string"},third_party_email:{type:"string"}}}},is_notification:{type:"boolean",description:"Whether to notify removed attendees (default true)."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id","attendees"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary",c=Mt(i,"is_notification"),d=i.attendee_ids,p;if(d!==void 0){if(!Array.isArray(d))throw new Error("attendee_ids must be an array of strings when provided");p=d.map((g,y)=>{if(typeof g!="string"||!g.trim())throw new Error(`attendee_ids[${y}] must be a non-empty string`);return g.trim()})}let u=i.attendees;if(!Array.isArray(u)||u.length===0)throw new Error("attendees is required and must be a non-empty array");let _=u.map((g,y)=>{if(typeof g!="object"||g===null||Array.isArray(g))throw new Error(`attendees[${y}] must be an object`);let m=g,h={};if(m.type!==void 0){if(typeof m.type!="string"||!m.type.trim())throw new Error(`attendees[${y}].type must be a non-empty string when provided`);h.type=m.type.trim()}if(m.user_id!==void 0){if(typeof m.user_id!="string"||!m.user_id.trim())throw new Error(`attendees[${y}].user_id must be a non-empty string when provided`);h.user_id=m.user_id.trim()}if(m.third_party_email!==void 0){if(typeof m.third_party_email!="string"||!m.third_party_email.trim())throw new Error(`attendees[${y}].third_party_email must be a non-empty string when provided`);h.third_party_email=m.third_party_email.trim()}if(Object.keys(h).length===0)throw new Error(`attendees[${y}] must contain at least one valid field`);return h});if((p?.length??0)+_.length>ls)throw new Error(`attendee_ids.length + attendees.length must be <= ${ls}`);return await Z(s,"\u5220\u9664\u65E5\u7A0B\u53C2\u4E0E\u8005",async g=>{let y={attendees:_};p&&p.length>0&&(y.attendee_ids=p),c!==void 0&&(y.is_notification=c);let m=await g.request({method:"POST",path:ec(l,a),body:y,headers:Xe(i)});return m.data??m})}catch(s){return K(s)}}}),t({name:"wps_calendar_respond_invitation",description:"Reply to a calendar invitation (official \u7B54\u590D\u65E5\u7A0B\u9080\u8BF7): POST `/v7/calendars/{calendar_id}/events/{event_id}/respond`. Requires delegated OAuth (same as `wps_calendar_create`). Body per API: `mod_type` (`normal` = non-recurring reply, `one` = one occurrence of recurring, `all` = entire series), `response_status` (`accepted` | `declined` | `tentative`), `which_day_time` = **start time in milliseconds** (Unix ms) for the occurrence being answered. Use `event_id` from `wps_calendar_list_events` / `wps_calendar_get_event`; for recurring series pick `which_day_time` from instance or event `start_time`. Optional `calendar_id` (default `primary`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Calendar event id (from event list or get-event API)."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},mod_type:{type:"string",description:"Reply scope per WPS API.",enum:["normal","one","all"]},response_status:{type:"string",description:"Invitation response.",enum:["accepted","declined","tentative"]},which_day_time:{type:"number",description:"Schedule start time as **milliseconds since Unix epoch** (per API `which_day_time`). Use the occurrence start from list/get/event_instances."}},required:["wps_user_id","event_id","mod_type","response_status","which_day_time"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary",c=P(i,"mod_type");if(c!=="normal"&&c!=="one"&&c!=="all")throw new Error("mod_type must be normal, one, or all");let d=P(i,"response_status");if(d!=="accepted"&&d!=="declined"&&d!=="tentative")throw new Error("response_status must be accepted, declined, or tentative");let p=Math.trunc(Kd(i,"which_day_time"));return await Z(s,"\u7B54\u590D\u65E5\u7A0B\u9080\u8BF7",async u=>{let _=await u.request({method:"POST",path:Zd(l,a),body:{mod_type:c,response_status:d,which_day_time:p}});return _.data??_})}catch(s){return K(s)}}}),t({name:"wps_calendar_list_calendar_event_instances",description:"List expanded **calendar-level** event instances (all occurrences in a time window): GET `/v7/calendars/{calendar_id}/event_instances` (use `calendar_id=primary` for main calendar). Same delegated Bearer auth as `wps_calendar_create`. Query: RFC3339 `start_time` / `end_time` (0\u201331 days), optional `page_size` (default 30), `page_token`. Use when you need many instances across the calendar without a specific `event_id`. To expand **one** recurring event by id, use `wps_calendar_list_event_instances` instead.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},calendar_id:{type:"string",description:"Calendar id or the literal `primary` (default)."},start_time:{type:"string",description:"Optional range start (RFC3339). Omit both for default window."},end_time:{type:"string",description:"Optional range end (RFC3339). Max 31-day span; longer truncated."},page_size:{type:"number",description:"Page size (default 30, max 500)."},page_token:{type:"string",description:"Pagination cursor if returned by API."}},required:["wps_user_id"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=v(i,"calendar_id")??"primary",l=v(i,"start_time"),c=v(i,"end_time"),d=jt(i,"page_size"),p=v(i,"page_token");return await Z(s,"\u67E5\u8BE2\u65E5\u5386\u65E5\u7A0B\u5B9E\u4F8B\u5217\u8868",async u=>{let _=Jd({startRfc:l,endRfc:c,pageSize:d,pageToken:p}),f=await u.request({method:"GET",path:`/v7/calendars/${encodeURIComponent(a)}/event_instances`,query:_});return f.data??f})}catch(s){return K(s)}}}),t({name:"wps_calendar_list_event_instances",description:"Query **instances of one calendar event** (expand a recurring series for that event id): GET `/v7/calendars/{calendar_id}/events/{event_id}/event_instances` per WPS365 doc. Requires `event_id` from `wps_calendar_list_events` (or equivalent). Optional query: `start_time` / `end_time` **RFC3339** strings; range 0\u201331 days (truncated if longer); omit both for default window. Same delegated Bearer auth as `wps_calendar_create`. Optional `calendar_id` (default `primary`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Calendar event id from the event list API."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},start_time:{type:"string",description:"Optional query range start (RFC3339). Used with end_time; omit both for defaults."},end_time:{type:"string",description:"Optional query range end (RFC3339)."}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary",c=v(i,"start_time"),d=v(i,"end_time");return await Z(s,"\u67E5\u8BE2\u5355\u6761\u65E5\u7A0B\u5B9E\u4F8B",async p=>{let u=Xd({startRfc:c,endRfc:d}),_=await p.request({method:"GET",path:`${De(l,a)}/event_instances`,query:u});return _.data??_})}catch(s){return K(s)}}});let r=100,n=500;t({name:"wps_calendar_search_events",description:"Search calendar events by keyword (official \u641C\u7D22\u65E5\u7A0B): POST `/v7/calendars/{calendar_id}/events/search`. Searches event titles, descriptions, and notes. Requires user delegated OAuth (same as wps_calendar_create). Use SenderId as wps_user_id. Body: `keyword` (required, 1-100 chars), optional `page_size` (default 200, max 500), optional `page_token`. Response: `data.items[]` (event list) and optional `data.next_page_token`. Optional `calendar_id` (default `primary`). Optional header `X-Kso-Id-Type`: pass `x_kso_id_type` as `internal` or `external` per API.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},keyword:{type:"string",description:"Search keyword (1-100 chars). Matches event title, description, notes."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},page_size:{type:"number",description:"Page size (default 200 per API, max 500)."},page_token:{type:"string",description:"Pagination cursor from data.next_page_token."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type` header: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","keyword"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"keyword");if(a.length>r)throw new Error(`keyword must be at most ${r} characters`);let l=v(i,"calendar_id")??"primary",c=jt(i,"page_size"),d=v(i,"page_token");return await Z(s,"\u641C\u7D22\u65E5\u7A0B",async p=>{let u={keyword:a},_=c??200;u.page_size=Math.max(1,Math.min(n,Math.trunc(_))),d!==void 0&&d.trim()!==""&&(u.page_token=d.trim());let f=await p.request({method:"POST",path:`/v7/calendars/${encodeURIComponent(l)}/events/search`,body:u,headers:Xe(i)});return f.data??f})}catch(s){return K(s)}}}),t({name:"wps_calendar_update_event",description:"Update (modify) a calendar event (official \u4FEE\u6539\u65E5\u7A0B): POST `/v7/calendars/{calendar_id}/events/{event_id}/update`. Requires user delegated OAuth (same as wps_calendar_create). Use SenderId as wps_user_id. All body fields are optional \u2014 only pass what needs to change. For recurring events: set `mod_type` to `one` (single occurrence, requires `which_day_time` in ms) or `all` (entire series). Set `is_notification` to false to suppress attendee notifications. Set `online_meeting` to null to clear the meeting. Optional `calendar_id` (default `primary`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from calendar event list or search."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},summary:{type:"string",description:"New event title."},description:{type:"string",description:"New event description / notes."},start_time:{type:"string",description:"New start time in ISO 8601 with timezone (e.g. '2026-05-10T14:00:00+08:00')."},end_time:{type:"string",description:"New end time in ISO 8601 with timezone."},location:{type:"string",description:"New event location (API supports max 1 location)."},free_busy_status:{type:"string",description:"Busy/free status during the event.",enum:["busy","free"]},visibility:{type:"string",description:"Event visibility scope.",enum:["default","public","private"]},attendee_ability:{type:"string",description:"Attendee permission level.",enum:["can_see_others","can_invite_others"]},mod_type:{type:"string",description:"For recurring events only: `one` = edit single occurrence (requires which_day_time), `all` = edit entire series.",enum:["one","all"]},which_day_time:{type:"number",description:"When mod_type=one, the start time of the occurrence to modify in **milliseconds** (Unix epoch ms)."},is_notification:{type:"boolean",description:"Whether to notify attendees about the update (default true)."},is_reinvition:{type:"boolean",description:"When true and time/recurrence changes, reset all attendees to not-accepted (default true)."},reminders:{type:"array",description:"Reminder list (max 10). Each item: { minutes: number }.",items:{type:"object",properties:{minutes:{type:"number"}},required:["minutes"]}}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary",c=v(i,"mod_type");if(c!==void 0&&c!=="one"&&c!=="all")throw new Error("mod_type must be one or all when provided");let d=jt(i,"which_day_time");if(c==="one"&&d==null)throw new Error("which_day_time (ms) is required when mod_type is one");let p=v(i,"free_busy_status");if(p!==void 0&&p!=="busy"&&p!=="free")throw new Error("free_busy_status must be busy or free");let u=v(i,"visibility");if(u!==void 0&&u!=="default"&&u!=="public"&&u!=="private")throw new Error("visibility must be default, public, or private");let _=v(i,"attendee_ability");if(_!==void 0&&_!=="can_see_others"&&_!=="can_invite_others")throw new Error("attendee_ability must be can_see_others or can_invite_others");return await Z(s,"\u4FEE\u6539\u65E5\u7A0B",async f=>{let g={},y=v(i,"summary");y!==void 0&&(g.summary=y);let m=v(i,"description");m!==void 0&&(g.description=m);let h=v(i,"start_time");h!==void 0&&(g.start_time={datetime:h});let w=v(i,"end_time");w!==void 0&&(g.end_time={datetime:w});let b=v(i,"location");b!==void 0&&(g.locations=[{name:b}]),p!==void 0&&(g.free_busy_status=p),u!==void 0&&(g.visibility=u),_!==void 0&&(g.attendee_ability=_),c!==void 0&&(g.mod_type=c),d!==void 0&&(g.which_day_time=Math.trunc(d));let I=Mt(i,"is_notification");I!==void 0&&(g.is_notification=I);let x=Mt(i,"is_reinvition");x!==void 0&&(g.is_reinvition=x);let M=i.reminders;Array.isArray(M)&&(g.reminders=M.slice(0,10).map(B=>{let W=B;return{minutes:typeof W.minutes=="number"?Math.trunc(W.minutes):0}}));let J=await f.request({method:"POST",path:`${De(l,a)}/update`,body:g});return J.data??J})}catch(s){return K(s)}}}),t({name:"wps_calendar_delete_event",description:"Delete a calendar event (official \u5220\u9664\u65E5\u7A0B): POST `/v7/calendars/{calendar_id}/events/{event_id}/delete`. Requires user delegated OAuth (same as wps_calendar_create). Use SenderId as wps_user_id. Optional body: `is_notification` (default true). For recurring events: set `mod_type` to `one` (delete one occurrence, requires `which_day_time` in ms) or `all` (delete entire series). Optional `calendar_id` (default `primary`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from calendar list/search/get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},is_notification:{type:"boolean",description:"Whether to notify attendees about deletion (default true)."},mod_type:{type:"string",description:"For recurring events only: `one` (single occurrence, requires which_day_time) or `all` (entire series).",enum:["one","all"]},which_day_time:{type:"number",description:"When mod_type=one, the start time of occurrence to delete in milliseconds."}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=P(i,"wps_user_id"),a=P(i,"event_id"),l=v(i,"calendar_id")??"primary",c=v(i,"mod_type");if(c!==void 0&&c!=="one"&&c!=="all")throw new Error("mod_type must be one or all when provided");let d=jt(i,"which_day_time");if(c==="one"&&d===void 0)throw new Error("which_day_time (ms) is required when mod_type is one");let p=Mt(i,"is_notification");return await Z(s,"\u5220\u9664\u65E5\u7A0B",async u=>{let _={};p!==void 0&&(_.is_notification=p),c!==void 0&&(_.mod_type=c),d!==void 0&&(_.which_day_time=Math.trunc(d));let f=await u.request({method:"POST",path:`${De(l,a)}/delete`,body:_});return f.data??f})}catch(s){return K(s)}}})}var oc="/v7/todo/personal_tasks",sc="/v7/todo/personal_tasks/batch_get";function Gr(e){return`/v7/todo/personal_tasks/${encodeURIComponent(e.trim())}`}function ac(e){return`${Gr(e.trim())}/update`}function dc(e){return`${Gr(e.trim())}/update_status`}var fs=100,cc=20,lc=50;function zt(e){return{error:e instanceof Error?e.message:String(e)}}function qe(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function Q(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}function _t(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function pc(e,t){let r=e[t];if(r==null)return;if(!Array.isArray(r))throw new Error(`${t} must be an array of strings`);let n=r.map(o=>String(o).trim()).filter(Boolean);return n.length>0?n:void 0}function uc(e,t){let r=e[t];if(r==null)return;if(!Array.isArray(r))throw new Error(`${t} must be an array of objects with name and value`);let n=[];for(let o of r){if(typeof o!="object"||o===null)continue;let i=o;typeof i.name!="string"||typeof i.value!="string"||n.push({name:i.name.trim(),value:i.value})}return n.length>0?n:void 0}function fc(e,t){let r=Q(e,t);if(!(r===void 0||r.trim()===""))try{let n=JSON.parse(r);if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`${t} must be a JSON object`);return n}catch(n){throw n instanceof SyntaxError?new Error(`${t} must be valid JSON`):n}}function Lt(e){let t=Q(e,"x_kso_id_type");if(t===void 0||t.trim()==="")return;let r=t.trim();if(r!=="internal"&&r!=="external")throw new Error("x_kso_id_type must be internal or external when provided");return{"X-Kso-Id-Type":r}}function _c(e){let t=e.titleSubject.trim();if(!t)throw new Error("title_subject must be non-empty");let r={subject:t};e.titlePrefix!==void 0&&e.titlePrefix.trim()!==""&&(r.prefix=e.titlePrefix.trim());let n={title:r};if(e.description!==void 0&&e.description.trim()!==""&&(n.description=e.description.trim()),e.dueTimeMs!==void 0){if(!Number.isFinite(e.dueTimeMs))throw new Error("due_time_ms must be a finite number");n.due_time=Math.trunc(e.dueTimeMs)}if((e.status==="todo"||e.status==="finish")&&(n.status=e.status),e.executors!==void 0&&e.executors.length>0){if(e.executors.length>fs)throw new Error(`executors must have at most ${fs} entries`);n.executors=[...e.executors]}return n}function mc(e){let t={};if(e.keyword!==void 0&&e.keyword.trim()!==""&&(t.keyword=e.keyword.trim().slice(0,50)),e.executor!==void 0&&e.executor.trim()!==""&&(t.executor=e.executor.trim()),(e.status==="todo"||e.status==="finish")&&(t.status=e.status),e.pageSize!==void 0){let r=e.pageSize;t.page_size=Math.max(1,Math.min(lc,Math.trunc(r)))}else t.page_size=cc;if(e.pageToken!==void 0&&e.pageToken.trim()!==""&&(t.page_token=e.pageToken.trim()),e.createdTimeStartMs!==void 0||e.createdTimeEndMs!==void 0){let r={};e.createdTimeStartMs!==void 0&&Number.isFinite(e.createdTimeStartMs)&&(r.start_time=Math.trunc(e.createdTimeStartMs)),e.createdTimeEndMs!==void 0&&Number.isFinite(e.createdTimeEndMs)&&(r.end_time=Math.trunc(e.createdTimeEndMs)),Object.keys(r).length>0&&(t.created_time=r)}if(e.dueTimeStartMs!==void 0||e.dueTimeEndMs!==void 0){let r={};e.dueTimeStartMs!==void 0&&Number.isFinite(e.dueTimeStartMs)&&(r.start_time=Math.trunc(e.dueTimeStartMs)),e.dueTimeEndMs!==void 0&&Number.isFinite(e.dueTimeEndMs)&&(r.end_time=Math.trunc(e.dueTimeEndMs)),Object.keys(r).length>0&&(t.due_time=r)}return t}function hc(e){let t={},r=e.titleSubject?.trim()??"",n=e.titlePrefix?.trim()??"";if(r!==""||n!==""){let o={};r!==""&&(o.subject=r),n!==""&&(o.prefix=n),t.title=o}if(e.description!==void 0&&e.description.trim()!==""&&(t.description=e.description.trim()),e.dueTimeMs!==void 0){if(!Number.isFinite(e.dueTimeMs))throw new Error("due_time_ms must be a finite number");t.due_time=Math.trunc(e.dueTimeMs)}if(e.extAttrs!==void 0&&e.extAttrs.length>0&&(t.ext_attrs=e.extAttrs.map(o=>({name:o.name,value:o.value}))),e.notifyConfig!==void 0&&Object.keys(e.notifyConfig).length>0&&(t.notify_config=e.notifyConfig),Object.keys(t).length===0)throw new Error("provide at least one of: title_subject, title_prefix, description, due_time_ms, ext_attrs, notify_config_json");return t}var gc=new Set(["finish","unfinish","finish_all","unfinish_all"]);function yc(e){return gc.has(e)}function _s(e){let t=e.trim();if(!yc(t))throw new Error("action must be exactly one of: finish, unfinish, finish_all, unfinish_all");return t}function wc(e){return{action:_s(e.action)}}function bc(e){if(e==null||typeof e!="object")return null;let t=e,r=["creator_id","creator_user_id","create_user_id","owner_id"];for(let o of r){let i=t[o];if(typeof i=="string"&&i.trim())return i.trim()}let n=t.creator;if(n!==null&&typeof n=="object"&&!Array.isArray(n)){let o=n;for(let i of["id","user_id","userId"]){let s=o[i];if(typeof s=="string"&&s.trim())return s.trim()}}return null}function Ic(e,t){let r=e.trim(),n=t.trim();return r===n?!0:r.toLowerCase()===n.toLowerCase()}function kc(e){let{hasCompletion:t,completionRaw:r,markScopeRaw:n,actionParam:o,isCreator:i,taskId:s,creatorId:a}=e,l=n?.trim()??"";if(t){if(r!=="complete"&&r!=="incomplete")throw new Error("completion must be complete or incomplete");let d=r==="complete";if(i){if(!l||l==="none")return{kind:"needs_confirmation",taskId:s,completion:r,creatorId:a};if(l!=="self"&&l!=="all")throw new Error("mark_scope must be none, self, or all when provided");return{kind:"post",action:l==="all"?d?"finish_all":"unfinish_all":d?"finish":"unfinish"}}return{kind:"post",action:d?"finish":"unfinish"}}let c=_s(o);if(!i&&(c==="finish_all"||c==="unfinish_all"))throw new Error("\u5F53\u524D\u7528\u6237\u4E0D\u662F\u8BE5\u5F85\u529E\u7684\u521B\u5EFA\u8005\uFF08\u6216\u672A\u89E3\u6790\u5230 creator_id\uFF09\uFF0C\u4E0D\u80FD\u4F7F\u7528 finish_all / unfinish_all\uFF1B\u8BF7\u4F7F\u7528 finish \u6216 unfinish\u3002");return i?{kind:"needs_confirmation",taskId:s,completion:c==="finish"||c==="finish_all"?"complete":"incomplete",creatorId:a,requested_action:c}:{kind:"post",action:c}}async function lr(e,t,r){try{return await _e({wpsUserId:e,toolModule:"todo",authCardOriginalMessage:t,needsAuthMessage:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u4F7F\u7528\u5F85\u529E\u80FD\u529B\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u5B8C\u6210\u6388\u6743\u540E\u91CD\u8BD5\u3002",logTag:"todo",run:r})}catch(n){return zt(n)}}function li(e,t){t({name:"wps_todo_create_personal_task",description:"Create a personal todo/task via WPS OpenAPI (\u521B\u5EFA\u4E2A\u4EBA\u5F85\u529E): POST `/v7/todo/personal_tasks`. Requires user delegated OAuth scope `kso.task.readwrite` (or equivalent per console). Use SenderId as `wps_user_id`. Required: `title_subject` \u2192 body `title.subject`; optional `title_prefix` \u2192 `title.prefix`. Optional: `description`, `due_time_ms` (deadline **milliseconds** Unix epoch), `status` (`todo`|`finish`), `executors` (\u2264100 user ids). Response `data.task_id` is the new task id. Optional `x_kso_id_type`: `internal`|`external` \u2192 header `X-Kso-Id-Type`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},title_subject:{type:"string",description:"Todo title subject (maps to request body title.subject)."},title_prefix:{type:"string",description:"Optional. Maps to title.prefix."},description:{type:"string",description:"Optional todo description."},due_time_ms:{type:"number",description:"Optional deadline as Unix timestamp in **milliseconds** (due_time)."},status:{type:"string",description:"Optional initial status.",enum:["todo","finish"]},executors:{type:"array",items:{type:"string"},description:"Optional executor user ids (max 100)."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","title_subject"]},async execute(r,n){try{let o=qe(n,"wps_user_id"),i=qe(n,"title_subject"),s=Q(n,"title_prefix"),a=Q(n,"description"),l=_t(n,"due_time_ms"),c=Q(n,"status"),d=pc(n,"executors"),p;if(c!==void 0){if(c!=="todo"&&c!=="finish")throw new Error("status must be todo or finish when provided");p=c}let u=_c({titleSubject:i,titlePrefix:s,description:a,dueTimeMs:l,status:p,executors:d});return await lr(o,"\u521B\u5EFA\u4E2A\u4EBA\u5F85\u529E",async _=>{let f=await _.request({method:"POST",path:oc,body:u,headers:Lt(n)});return f.data??f})}catch(o){return zt(o)}}}),t({name:"wps_todo_list_personal_tasks",description:"List personal todos via WPS OpenAPI (\u83B7\u53D6\u4E2A\u4EBA\u5F85\u529E\u5217\u8868): POST `/v7/todo/personal_tasks/batch_get`. Requires delegated OAuth (`kso.task.read` / `kso.task.readwrite`). Use SenderId as `wps_user_id`. Body filters are optional: `keyword` (\u226450 chars), `executor`, `status` (`todo`|`finish`), `page_size` (default 20, max 50), `page_token` (from previous `data` pagination field per API). `created_time` / `due_time` ranges use **milliseconds** (`*_start_ms`, `*_end_ms`). Response `data` typically includes `tasks`, `total`, `next_offset`. Optional `x_kso_id_type`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},keyword:{type:"string",description:"Optional. Fuzzy match title/description (max 50 chars)."},executor:{type:"string",description:"Optional. Filter by executor user id."},status:{type:"string",description:"Optional list filter: todo (=\u672A\u5B8C\u6210) or finish (=\u5DF2\u5B8C\u6210).",enum:["todo","finish"]},page_size:{type:"number",description:"Page size (default 20; API max 50)."},page_token:{type:"string",description:"Pagination cursor from previous response (see API field names e.g. next_offset)."},created_time_start_ms:{type:"number",description:"Optional. Creation range start (Unix ms)."},created_time_end_ms:{type:"number",description:"Optional. Creation range end (Unix ms)."},due_time_start_ms:{type:"number",description:"Optional. Due range start (Unix ms)."},due_time_end_ms:{type:"number",description:"Optional. Due range end (Unix ms)."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id"]},async execute(r,n){try{let o=qe(n,"wps_user_id"),i=Q(n,"keyword"),s=Q(n,"executor"),a=Q(n,"status"),l=_t(n,"page_size"),c=Q(n,"page_token"),d=_t(n,"created_time_start_ms"),p=_t(n,"created_time_end_ms"),u=_t(n,"due_time_start_ms"),_=_t(n,"due_time_end_ms"),f;if(a!==void 0){if(a!=="todo"&&a!=="finish")throw new Error("status must be todo or finish when provided");f=a}let g=mc({keyword:i,executor:s,status:f,pageSize:l,pageToken:c,createdTimeStartMs:d,createdTimeEndMs:p,dueTimeStartMs:u,dueTimeEndMs:_});return await lr(o,"\u83B7\u53D6\u4E2A\u4EBA\u5F85\u529E\u5217\u8868",async y=>{let m=await y.request({method:"POST",path:sc,body:g,headers:Lt(n)});return m.data??m})}catch(o){return zt(o)}}}),t({name:"wps_todo_get_personal_task",description:"Get one personal todo by id (\u83B7\u53D6\u4E2A\u4EBA\u5F85\u529E\u8BE6\u60C5): GET `/v7/todo/personal_tasks/{task_id}`. Requires delegated OAuth (`kso.task.read` / `kso.task.readwrite`). Use SenderId as `wps_user_id`. Requires **`task_id`** from `wps_todo_list_personal_tasks` (`tasks[].id`) or create response. Response `data` is a single todo object (`todo_personal_task`). Optional `x_kso_id_type`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},task_id:{type:"string",description:"Todo task id from list or create API."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","task_id"]},async execute(r,n){try{let o=qe(n,"wps_user_id"),i=qe(n,"task_id");return await lr(o,"\u83B7\u53D6\u4E2A\u4EBA\u5F85\u529E\u8BE6\u60C5",async s=>{let a=await s.request({method:"GET",path:Gr(i),headers:Lt(n)});return a.data??a})}catch(o){return zt(o)}}}),t({name:"wps_todo_update_personal_task_status",description:"POST `/v7/todo/personal_tasks/{task_id}/update_status`. HTTP body: `{ action }`. Enum: `finish`, `unfinish`, `finish_all`, `unfinish_all` (`finish_all`/`unfinish_all` creator-only). **Creators**: without `mark_scope` (or `mark_scope: none`) or `action`-only \u2192 returns `needsUserConfirmation`, ask user to choose scope; then call again with `completion` + `mark_scope: self|all`. **Non-creators**: `completion` or `action` (`finish`|`unfinish`); omit `mark_scope`. Requires delegated `kso.task.readwrite`; `wps_user_id` = SenderId.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},task_id:{type:"string",description:"Todo id to update status."},completion:{type:"string",description:"`complete`/`incomplete`. Creators: omit `mark_scope` or use `none` \u2192 returns `needsUserConfirmation`; after user confirms, call again with `mark_scope: self|all`. Mutually exclusive with `action`.",enum:["complete","incomplete"]},mark_scope:{type:"string",description:"**Creators only**: omit or `none` \u2192 \u89E6\u53D1\u4E8C\u6B21\u786E\u8BA4\uFF1B`self` = \u4EC5\u81EA\u5DF1\uFF1B`all` = \u5168\u90E8\u53C2\u4E0E\u4EBA\u3002\u975E\u521B\u5EFA\u8005\u52FF\u4F20\u3002",enum:["none","self","all"]},action:{type:"string",description:"Maps to HTTP body `action`. `finish`|`unfinish` (single); `finish_all`|`unfinish_all` (creator, all participants). Non-creators: `finish`|`unfinish` only. Creators using `action` alone \u2192 `needsUserConfirmation` (then use `completion`+`mark_scope`).",enum:["finish","unfinish","finish_all","unfinish_all"]},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","task_id"]},async execute(r,n){try{let o=qe(n,"wps_user_id"),i=qe(n,"task_id"),s=Q(n,"completion"),a=Q(n,"mark_scope"),l=Q(n,"action"),c=s!==void 0,d=l!==void 0&&l!=="";if(c===d)throw!c&&!d?new Error("Provide exactly one of: completion (complete|incomplete) or action (finish|unfinish|...)"):new Error("Provide only one of: completion or action");if(a!==void 0&&!c)throw new Error("mark_scope is only used together with completion");return await lr(o,"\u66F4\u65B0\u4E2A\u4EBA\u5F85\u529E\u72B6\u6001",async p=>{let u=await p.request({method:"GET",path:Gr(i),headers:Lt(n)}),_=u.data??u,f=bc(_),g=f!==null&&Ic(o,f),y=kc({hasCompletion:c,completionRaw:s,markScopeRaw:a,actionParam:l,isCreator:g,taskId:i,creatorId:f});if(y.kind==="needs_confirmation")return{needsUserConfirmation:!0,reason:"creator_must_choose_scope",message:"\u60A8\u662F\u8BE5\u5F85\u529E\u7684\u521B\u5EFA\u8005\uFF0C\u8BF7\u5148\u786E\u8BA4\uFF1A\u6807\u8BB0\u300C\u4EC5\u81EA\u5DF1\u300D\u8FD8\u662F\u300C\u5168\u90E8\u53C2\u4E0E\u4EBA\u300D\uFF1F\u786E\u8BA4\u540E\u518D\u6B21\u8C03\u7528\uFF0C\u4F20\u5165 completion + mark_scope\uFF08self \u6216 all\uFF09\u3002",task_id:y.taskId,completion:y.completion,creator_id:y.creatorId,...y.requested_action!==void 0?{requested_action:y.requested_action}:{}};let m=wc({action:y.action}),h=await p.request({method:"POST",path:dc(i),body:m,headers:Lt(n)});return h.data??h})}catch(o){return zt(o)}}}),t({name:"wps_todo_update_personal_task",description:"Update a personal todo (\u66F4\u65B0\u4E2A\u4EBA\u5F85\u529E): POST `/v7/todo/personal_tasks/{task_id}/update`. Requires delegated **`kso.task.readwrite`**. Use SenderId as `wps_user_id`. Requires **`task_id`**. Body fields are optional but **at least one** must be provided: `title_subject` / `title_prefix` (maps to `title`), `description`, `due_time_ms` (ms), `ext_attrs` (`[{name,value}]`), or `notify_config_json` (JSON object string for `notify_config`). Response is typically `code` + `msg` only.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},task_id:{type:"string",description:"Todo id to update."},title_subject:{type:"string",description:"Optional. Maps to title.subject."},title_prefix:{type:"string",description:"Optional. Maps to title.prefix."},description:{type:"string",description:"Optional. New description."},due_time_ms:{type:"number",description:"Optional. New deadline as Unix **milliseconds**."},ext_attrs:{type:"array",items:{type:"object",properties:{name:{type:"string"},value:{type:"string"}},required:["name","value"]},description:"Optional. Extension attributes."},notify_config_json:{type:"string",description:"Optional. JSON object string for notify_config (e.g. reminders, switch). Must parse to an object."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","task_id"]},async execute(r,n){try{let o=qe(n,"wps_user_id"),i=qe(n,"task_id"),s=Q(n,"title_subject"),a=Q(n,"title_prefix"),l=Q(n,"description"),c=_t(n,"due_time_ms"),d=uc(n,"ext_attrs"),p=fc(n,"notify_config_json"),u=hc({titleSubject:s,titlePrefix:a,description:l,dueTimeMs:c,extAttrs:d,notifyConfig:p});return await lr(o,"\u66F4\u65B0\u4E2A\u4EBA\u5F85\u529E",async _=>{let f=await _.request({method:"POST",path:ac(i),body:u,headers:Lt(n)});return f.data??f})}catch(o){return zt(o)}}})}function Ue(e){return`/v7/coop/dbsheet/${encodeURIComponent(e)}`}function Sc(e){return`/v7/dbsheet/${encodeURIComponent(e)}`}function Ve(e){let t=e.sheet_id;if(t==null)throw new Error("sheet_id is required");let r=typeof t=="number"?t:parseInt(String(t),10);if(!Number.isFinite(r)||r<=0)throw new Error("sheet_id must be a positive integer");return r}function ms(e,t="fields_value"){if(typeof e=="string")return e;if(e!==null&&typeof e=="object")return JSON.stringify(e);throw new Error(`${t} must be a JSON string or object`)}async function Pe(e,t,r){return _e({wpsUserId:e,toolModule:"dbsheet",authCardOriginalMessage:"\u7528\u6237\u8BF7\u6C42\u64CD\u4F5C\u591A\u7EF4\u8868\u683C",needsAuthMessage:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u8BBF\u95EE\u591A\u7EF4\u8868\u683C\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",logTag:t,run:r})}function pi(e,t){t({name:"wps_dbsheet_get_schema",description:"Get DBSheet schema (\u83B7\u53D6\u591A\u7EF4\u8868\u683C Schema): GET `/v7/coop/dbsheet/{file_id}/schema`. Returns all sheets with their fields (name/type/id/data) and views. Use this first to understand the table structure before reading or writing records. Requires delegated OAuth (`kso.dbsheet.read`). Use current SenderId as `wps_user_id`. Do NOT call `wps_user_search` to resolve `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"DBSheet file ID."}},required:["wps_user_id","file_id"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id");return await Pe(o,"wps_dbsheet_get_schema",async s=>{let a=await s.request({method:"GET",path:`${Ue(i)}/schema`});return a.data??a})}catch(o){return ae(o)}}}),t({name:"wps_dbsheet_batch_create_sheets",description:"Batch create sheets (\u6279\u91CF\u521B\u5EFA\u5DE5\u4F5C\u8868): POST `/v7/dbsheet/{file_id}/sheets/batch_create`. Creates one or more sheets. Each sheet requires `name`; optionally include `fields` (field definitions with name/type/data) and `position` (after_sheet_id or before_sheet_id). Requires delegated OAuth (`kso.dbsheet.readwrite`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheets:{type:"array",description:"Array of sheet definitions. Each: { name: string (required), fields?: [{name, type, data?}], position?: {after_sheet_id?: number, before_sheet_id?: number} }.",items:{type:"object",properties:{name:{type:"string"},fields:{type:"array",items:{type:"object",additionalProperties:!0}},position:{type:"object",additionalProperties:!0}},required:["name"]}}},required:["wps_user_id","file_id","sheets"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=n.sheets;if(!Array.isArray(s)||s.length===0)throw new Error("sheets must be a non-empty array");return await Pe(o,"wps_dbsheet_batch_create_sheets",async a=>{let l=await a.request({method:"POST",path:`${Sc(i)}/sheets/batch_create`,body:{sheets:s}});return l.data??l})}catch(o){return ae(o)}}}),t({name:"wps_dbsheet_update_sheet",description:"Update sheet (\u66F4\u65B0\u5DE5\u4F5C\u8868): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/update`. Currently supports renaming a sheet. Obtain `sheet_id` (integer) from `wps_dbsheet_get_schema`. Requires delegated OAuth (`kso.dbsheet.readwrite`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer). From wps_dbsheet_get_schema."},name:{type:"string",description:"New sheet name."}},required:["wps_user_id","file_id","sheet_id","name"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Ve(n),a=T(n,"name");return await Pe(o,"wps_dbsheet_update_sheet",async l=>{let c=await l.request({method:"POST",path:`${Ue(i)}/sheets/${s}/update`,body:{name:a}});return c.data??c})}catch(o){return ae(o)}}}),t({name:"wps_dbsheet_create_records",description:'Create records (\u521B\u5EFA\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/create`. Creates one or more records. Each record\'s `fields_value` is a JSON string (or object \u2014 auto-stringified) mapping field name to value. Example: `{"\u6587\u672C\u5B57\u6BB5": "hello", "\u6570\u5B57\u5B57\u6BB5": 42}`. Auto fields (Formula/AutoNumber/CreatedBy/CreatedTime/LastModifiedBy/Lookup) must NOT be set. Requires delegated OAuth (`kso.dbsheet.readwrite`). Use current SenderId as `wps_user_id`.',parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer). From wps_dbsheet_get_schema."},records:{type:"array",description:"Array of records to create. Each: { fields_value: string|object }. fields_value maps field names to values as JSON string or object.",items:{type:"object",properties:{fields_value:{type:"string",description:'Field values as JSON string or object. E.g. {"\u6587\u672C": "hello", "\u6570\u5B57": 42}'}},required:["fields_value"]}}},required:["wps_user_id","file_id","sheet_id","records"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Ve(n),a=n.records;if(!Array.isArray(a)||a.length===0)throw new Error("records must be a non-empty array");let l=a.map((c,d)=>{if(!c||typeof c!="object")throw new Error(`records[${d}] must be an object`);return{fields_value:ms(c.fields_value,`records[${d}].fields_value`)}});return await Pe(o,"wps_dbsheet_create_records",async c=>{let d=await c.request({method:"POST",path:`${Ue(i)}/sheets/${s}/records/create`,body:{records:l}});return d.data??d})}catch(o){return ae(o)}}}),t({name:"wps_dbsheet_update_records",description:"Update records (\u66F4\u65B0\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/update`. Updates one or more records by record ID. Each item must include `id` (record ID) and `fields_value`. `fields_value` maps field names to new values (JSON string or object \u2014 auto-stringified). Auto fields (Formula/AutoNumber/CreatedBy/CreatedTime/LastModifiedBy/Lookup) must NOT be updated. Requires delegated OAuth (`kso.dbsheet.readwrite`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer). From wps_dbsheet_get_schema."},records:{type:"array",description:"Array of records to update. Each: { id: string (record ID), fields_value: string|object }.",items:{type:"object",properties:{id:{type:"string",description:"Record ID."},fields_value:{type:"string",description:"Field values as JSON string or object."}},required:["id","fields_value"]}}},required:["wps_user_id","file_id","sheet_id","records"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Ve(n),a=n.records;if(!Array.isArray(a)||a.length===0)throw new Error("records must be a non-empty array");let l=a.map((c,d)=>{if(!c||typeof c!="object")throw new Error(`records[${d}] must be an object`);let p=c;if(!p.id||typeof p.id!="string")throw new Error(`records[${d}].id is required and must be a string`);return{id:p.id,fields_value:ms(p.fields_value,`records[${d}].fields_value`)}});return await Pe(o,"wps_dbsheet_update_records",async c=>{let d=await c.request({method:"POST",path:`${Ue(i)}/sheets/${s}/records/update`,body:{records:l}});return d.data??d})}catch(o){return ae(o)}}}),t({name:"wps_dbsheet_list_records",description:"List records with cursor pagination (\u5217\u4E3E\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records`. Returns records with optional filter and cursor-based pagination (page_token). Use `page_token` from previous response to fetch next page. For page-number pagination use `wps_dbsheet_list_records_by_page`. Requires delegated OAuth (`kso.dbsheet.read`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer)."},fields:{type:"array",items:{type:"string"},description:"Optional. Field names to include. Omit to return all fields."},filter:{type:"object",additionalProperties:!0,description:"Optional filter. Structure: { mode: 'AND'|'OR', criteria: [{ field: string, operator: string, values: string[] }] }. operator: Equals|NotEqu|Greater|GreaterEqu|Less|LessEqu|GreaterEquAndLessEqu|LessOrGreater|BeginWith|EndWith|Contains|NotContains|Intersected|Empty|NotEmpty."},max_records:{type:"integer",description:"Optional. Max records to return."},page_size:{type:"integer",description:"Optional. Records per page, default 100, max 1000."},page_token:{type:"string",description:"Optional. Cursor from previous response."},view_id:{type:"string",description:"Optional. View ID to apply view visibility."},text_value:{type:"string",enum:["original","text","compound"],description:"Optional. Return value format. Default: original."},show_fields_info:{type:"boolean",description:"Optional. Include field schema in response."},show_record_extra_info:{type:"boolean",description:"Optional. Include creator/creation time/last-modifier metadata."}},required:["wps_user_id","file_id","sheet_id"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Ve(n),a={},l=ut(n,"fields");l&&(a.fields=l),n.filter!==void 0&&n.filter!==null&&(a.filter=n.filter);let c=Y(n,"max_records");c!==void 0&&(a.max_records=c);let d=Y(n,"page_size");d!==void 0&&(a.page_size=d);let p=V(n,"page_token");p!==void 0&&p!==""&&(a.page_token=p);let u=V(n,"view_id");u!==void 0&&u!==""&&(a.view_id=u);let _=V(n,"text_value");_!==void 0&&(a.text_value=_);let f=ne(n,"show_fields_info");f!==void 0&&(a.show_fields_info=f);let g=ne(n,"show_record_extra_info");return g!==void 0&&(a.show_record_extra_info=g),await Pe(o,"wps_dbsheet_list_records",async y=>{let m=await y.request({method:"POST",path:`${Ue(i)}/sheets/${s}/records`,body:a});return m.data??m})}catch(o){return ae(o)}}}),t({name:"wps_dbsheet_list_records_by_page",description:"List records with page-number pagination (\u6309\u9875\u5217\u4E3E\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/list_by_page`. Uses page_num (starts from 1) / page_size. Also returns total count. For cursor-based pagination use `wps_dbsheet_list_records`. Requires delegated OAuth (`kso.dbsheet.read`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer)."},fields:{type:"array",items:{type:"string"},description:"Optional. Field names to include."},filter:{type:"object",additionalProperties:!0,description:"Optional filter. Structure: { mode: 'AND'|'OR', criteria: [{ field, operator, values[] }] }."},max_records:{type:"integer",description:"Optional. Max records to return."},page_num:{type:"integer",description:"Optional. Page number starting from 1."},page_size:{type:"integer",description:"Optional. Records per page, default 100, max 1000."},view_id:{type:"string",description:"Optional. View ID."},text_value:{type:"string",enum:["original","text","compound"],description:"Optional. Return value format."},show_fields_info:{type:"boolean",description:"Optional. Include field schema."},show_record_extra_info:{type:"boolean",description:"Optional. Include metadata."}},required:["wps_user_id","file_id","sheet_id"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Ve(n),a={},l=ut(n,"fields");l&&(a.fields=l),n.filter!==void 0&&n.filter!==null&&(a.filter=n.filter);let c=Y(n,"max_records");c!==void 0&&(a.max_records=c);let d=Y(n,"page_num");d!==void 0&&(a.page_num=d);let p=Y(n,"page_size");p!==void 0&&(a.page_size=p);let u=V(n,"view_id");u!==void 0&&u!==""&&(a.view_id=u);let _=V(n,"text_value");_!==void 0&&(a.text_value=_);let f=ne(n,"show_fields_info");f!==void 0&&(a.show_fields_info=f);let g=ne(n,"show_record_extra_info");return g!==void 0&&(a.show_record_extra_info=g),await Pe(o,"wps_dbsheet_list_records_by_page",async y=>{let m=await y.request({method:"POST",path:`${Ue(i)}/sheets/${s}/records/list_by_page`,body:a});return m.data??m})}catch(o){return ae(o)}}}),t({name:"wps_dbsheet_get_records",description:"Get multiple records by ID (\u6309 ID \u6279\u91CF\u68C0\u7D22\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/search`. Retrieves specific records by their IDs. Use when you already know the record IDs. For filter-based listing use `wps_dbsheet_list_records` instead. Requires delegated OAuth (`kso.dbsheet.read`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer)."},records:{type:"array",items:{type:"string"},description:"Array of record IDs to retrieve."},text_value:{type:"string",enum:["original","text","compound"],description:"Optional. Return value format."},show_fields_info:{type:"boolean",description:"Optional. Include field schema."},show_record_extra_info:{type:"boolean",description:"Optional. Include metadata."}},required:["wps_user_id","file_id","sheet_id","records"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Ve(n),a=ut(n,"records");if(!a||a.length===0)throw new Error("records must be a non-empty array of record IDs");let l={records:a},c=V(n,"text_value");c!==void 0&&(l.text_value=c);let d=ne(n,"show_fields_info");d!==void 0&&(l.show_fields_info=d);let p=ne(n,"show_record_extra_info");return p!==void 0&&(l.show_record_extra_info=p),await Pe(o,"wps_dbsheet_get_records",async u=>{let _=await u.request({method:"POST",path:`${Ue(i)}/sheets/${s}/records/search`,body:l});return _.data??_})}catch(o){return ae(o)}}}),t({name:"wps_dbsheet_get_record",description:"Get a single record (\u68C0\u7D22\u5355\u6761\u8BB0\u5F55): GET `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/{record_id}`. Retrieves a single record by its ID. Requires delegated OAuth (`kso.dbsheet.read`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer)."},record_id:{type:"string",description:"Record ID to retrieve."},text_value:{type:"string",enum:["original","text","compound"],description:"Optional. Return value format."},show_fields_info:{type:"boolean",description:"Optional. Include field schema."},show_record_extra_info:{type:"boolean",description:"Optional. Include metadata."}},required:["wps_user_id","file_id","sheet_id","record_id"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Ve(n),a=T(n,"record_id"),l={},c=V(n,"text_value");c!==void 0&&(l.text_value=c);let d=ne(n,"show_fields_info");d!==void 0&&(l.show_fields_info=d);let p=ne(n,"show_record_extra_info");return p!==void 0&&(l.show_record_extra_info=p),await Pe(o,"wps_dbsheet_get_record",async u=>{let _=await u.request({method:"GET",path:`${Ue(i)}/sheets/${s}/records/${encodeURIComponent(a)}`,query:Object.keys(l).length>0?l:void 0});return _.data??_})}catch(o){return ae(o)}}}),t({name:"wps_dbsheet_delete_records",description:"Delete records (\u6279\u91CF\u5220\u9664\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/batch_delete`. Deletes one or more records by their IDs. This operation is irreversible. Requires delegated OAuth (`kso.dbsheet.readwrite`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer)."},records:{type:"array",items:{type:"string"},description:"Array of record IDs to delete."}},required:["wps_user_id","file_id","sheet_id","records"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Ve(n),a=ut(n,"records");if(!a||a.length===0)throw new Error("records must be a non-empty array of record IDs");return await Pe(o,"wps_dbsheet_delete_records",async l=>{let c=await l.request({method:"POST",path:`${Ue(i)}/sheets/${s}/records/batch_delete`,body:{records:a}});return c.data??c})}catch(o){return ae(o)}}})}Fe();import{createHash as xc}from"node:crypto";import{readFile as vc,stat as Tc}from"node:fs/promises";var Ec="/v7/drives",Ac="/v7/files/search",Pc=50,Oc=500,$c=50,Rc=500,Cc=50,Dc=500,hs=["folder","file","shortcut"],Hr=["fail","rename","overwrite","replace"],xs=["kdc","plain","markdown"],vs=["sync","async","auto"],qc=["para","table","component","textbox","all"],gs=["file_name","content","all"],ys=["folder","file","shortcut"],ws=["ctime","mtime","otime","stime"],bs=["desc","asc"],Is=["ctime","mtime"],ks=["desc","asc"],Ss=["ctime","mtime","dtime","fname","fsize"],Uc=["all","share_by_me","share_to_me","latest","personal_drive","group_drive","recycle","customize","latest_opened","latest_edited"];function Ze(e){return{error:e instanceof Error?e.message:String(e)}}function j(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function U(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}function Ft(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function ce(e,t){let r=e[t];if(r!=null){if(typeof r=="boolean")return r;if(r==="true"||r==="false")return r==="true";throw new Error(`${t} must be a boolean`)}}function X(e,t){let r=e[t];if(r==null)return;if(!Array.isArray(r))throw new Error(`${t} must be an array of strings`);let n=r.map(o=>String(o).trim()).filter(Boolean);return n.length>0?n:void 0}function Ye(e){let t=U(e,"x_kso_id_type");if(t===void 0||t.trim()==="")return;let r=t.trim();if(r!=="internal"&&r!=="external")throw new Error("x_kso_id_type must be internal or external when provided");return{"X-Kso-Id-Type":r}}function Nc(e){let t={};for(let[r,n]of Object.entries(e.requestHeaders)){let o=r.trim();if(o==="")continue;let i=o.toLowerCase();i==="content-length"||i==="transfer-encoding"||i==="content-type"||(t[o]=n)}return t["Content-Type"]="application/octet-stream",t}function jc(e){let t=e.trim();if(!t)throw new Error("url is required and must be a non-empty string");let r;try{r=new URL(t)}catch{throw new Error("url must be an absolute URL from step-1 data.store_request.url (e.g. https://...); relative paths are not supported")}if(r.protocol!=="https:"&&r.protocol!=="http:")throw new Error(`url must use http: or https: scheme, got: ${r.protocol}`)}function Mc(e){let t={allotee_type:e.alloteeType,page_size:Math.max(1,Math.min(Oc,Math.trunc(e.pageSize??Pc)))};return e.alloteeId!==void 0&&e.alloteeId.trim()!==""&&(t.allotee_id=e.alloteeId.trim()),e.withExtAttrs!==void 0&&(t.with_ext_attrs=e.withExtAttrs),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(t.page_token=e.pageToken.trim()),e.sources!==void 0&&e.sources.length>0&&(t.sources=[...e.sources]),t}function Wc(e,t){return`/v7/drives/${encodeURIComponent(e.trim())}/files/${encodeURIComponent(t.trim())}/create`}function Lc(e,t){return`/v7/drives/${encodeURIComponent(e.trim())}/files/${encodeURIComponent(t.trim())}/children`}function zc(e){let t={page_size:Math.max(1,Math.min(Dc,Math.trunc(e.pageSize??Cc)))};return e.withPermission!==void 0&&(t.with_permission=e.withPermission),e.withExtAttrs!==void 0&&(t.with_ext_attrs=e.withExtAttrs),e.filterExts!==void 0&&e.filterExts.trim()!==""&&(t.filter_exts=e.filterExts.trim()),e.filterType!==void 0&&Object.keys(e.filterType).length>0&&(t.filter_type=JSON.stringify(e.filterType)),e.order!==void 0&&(t.order=e.order),e.orderBy!==void 0&&(t.order_by=e.orderBy),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(t.page_token=e.pageToken.trim()),t}function Fc(e,t){return`/v7/drives/${encodeURIComponent(e.trim())}/files/${encodeURIComponent(t.trim())}/request_upload`}function Bc(e,t){return`/v7/drives/${encodeURIComponent(e.trim())}/files/${encodeURIComponent(t.trim())}/commit_upload`}function Gc(e){let t=e.name.trim();if(!t)throw new Error("name must be a non-empty string");let r={file_type:e.fileType,name:t};if(e.fileType==="shortcut"){if(!e.fileId||!e.fileId.trim())throw new Error("file_id is required when file_type is shortcut");r.file_id=e.fileId.trim()}else e.fileId!==void 0&&e.fileId.trim()!==""&&(r.file_id=e.fileId.trim());return e.onNameConflict!==void 0&&(r.on_name_conflict=e.onNameConflict),e.parentPath!==void 0&&e.parentPath.length>0&&(r.parent_path=[...e.parentPath]),r}function Hc(e){let t={size:Math.max(0,Math.trunc(e.size))};return e.fileId!==void 0&&e.fileId.trim()!==""&&(t.file_id=e.fileId.trim()),e.hashes!==void 0&&e.hashes.length>0&&(t.hashes=e.hashes.map(r=>({type:r.type,sum:r.sum.trim()}))),e.internal!==void 0&&(t.internal=e.internal),e.name!==void 0&&e.name.trim()!==""&&(t.name=e.name.trim()),e.onNameConflict!==void 0&&(t.on_name_conflict=e.onNameConflict),e.parentPath!==void 0&&e.parentPath.length>0&&(t.parent_path=[...e.parentPath]),e.storageBaseDomain!==void 0&&e.storageBaseDomain.trim()!==""&&(t.storage_base_domain=e.storageBaseDomain.trim()),e.uploadScene!==void 0&&e.uploadScene.trim()!==""&&(t.upload_scene=e.uploadScene.trim()),t}function Kc(e){let t={};return e.id!==void 0&&e.id.trim()!==""&&(t.id=e.id.trim()),e.uploadId!==void 0&&e.uploadId.trim()!==""&&(t.upload_id=e.uploadId.trim()),t}function Jc(e,t){return`/v7/drives/${encodeURIComponent(e.trim())}/files/${encodeURIComponent(t.trim())}/content`}function Xc(e){let t={};if(e.format!==void 0&&e.format.trim()!==""){let r=e.format.trim();if(!xs.includes(r))throw new Error("format must be one of: kdc, plain, markdown");t.format=r}if(e.includeElements!==void 0&&e.includeElements.length>0){let r=e.includeElements.map(n=>n.trim()).filter(Boolean).filter((n,o,i)=>i.indexOf(n)===o);for(let n of r)if(!qc.includes(n))throw new Error("include_elements items must be one of: para, table, component, textbox, all");r.length>0&&(t.include_elements=r)}if(e.mode!==void 0&&e.mode.trim()!==""){let r=e.mode.trim();if(!vs.includes(r))throw new Error("mode must be one of: sync, async, auto");t.mode=r}return e.taskId!==void 0&&e.taskId.trim()!==""&&(t.task_id=e.taskId.trim()),t}function Vc(e){return`/v7/files/${encodeURIComponent(e.trim())}/meta`}function Yc(e){let t={};return e.withPermission!==void 0&&(t.with_permission=e.withPermission),e.withExtAttrs!==void 0&&(t.with_ext_attrs=e.withExtAttrs),e.withDrive!==void 0&&(t.with_drive=e.withDrive),t}function Zc(e){let t={type:e.type,page_size:Math.max(1,Math.min(Rc,Math.trunc(e.pageSize??$c)))};return e.keyword!==void 0&&e.keyword.trim()!==""&&(t.keyword=e.keyword.trim()),e.fileType!==void 0&&(t.file_type=e.fileType),e.fileExts!==void 0&&e.fileExts.length>0&&(t.file_exts=[...e.fileExts]),e.driveIds!==void 0&&e.driveIds.length>0&&(t.drive_ids=[...e.driveIds]),e.parentIds!==void 0&&e.parentIds.length>0&&(t.parent_ids=[...e.parentIds]),e.creatorIds!==void 0&&e.creatorIds.length>0&&(t.creator_ids=[...e.creatorIds]),e.modifierIds!==void 0&&e.modifierIds.length>0&&(t.modifier_ids=[...e.modifierIds]),e.sharerIds!==void 0&&e.sharerIds.length>0&&(t.sharer_ids=[...e.sharerIds]),e.receiverIds!==void 0&&e.receiverIds.length>0&&(t.receiver_ids=[...e.receiverIds]),e.timeType!==void 0&&(t.time_type=e.timeType),e.startTime!==void 0&&(t.start_time=Math.trunc(e.startTime)),e.endTime!==void 0&&(t.end_time=Math.trunc(e.endTime)),e.withPermission!==void 0&&(t.with_permission=e.withPermission),e.withLink!==void 0&&(t.with_link=e.withLink),e.withTotal!==void 0&&(t.with_total=e.withTotal),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(t.page_token=e.pageToken.trim()),e.channels!==void 0&&e.channels.length>0&&(t.channels=[...e.channels]),e.deviceIds!==void 0&&e.deviceIds.length>0&&(t.device_ids=[...e.deviceIds]),e.excludeChannels!==void 0&&e.excludeChannels.length>0&&(t.exclude_channels=[...e.excludeChannels]),e.excludeFileExts!==void 0&&e.excludeFileExts.length>0&&(t.exclude_file_exts=[...e.excludeFileExts]),e.filterUserId!==void 0&&(t.filter_user_id=Math.trunc(e.filterUserId)),e.fileExtGroups!==void 0&&e.fileExtGroups.length>0&&(t.file_ext_groups=[...e.fileExtGroups]),e.withFolder!==void 0&&(t.with_folder=e.withFolder),e.withDrive!==void 0&&(t.with_drive=e.withDrive),e.order!==void 0&&(t.order=e.order),e.orderBy!==void 0&&(t.order_by=e.orderBy),e.scope!==void 0&&e.scope.length>0&&(t.scope=[...e.scope]),e.searchOperatorName!==void 0&&(t.search_operator_name=e.searchOperatorName),t}async function mt(e,t,r,n){try{return await _e({wpsUserId:e,toolModule:"cloud-doc",authCardOriginalMessage:t,needsAuthMessage:r,logTag:"drive",run:n})}catch(o){return Ze(o)}}function ui(e,t){t({name:"wps_cloud_doc_list_drives",description:"List cloud drives (\u83B7\u53D6\u76D8\u5217\u8868): GET `/v7/drives`. Requires delegated OAuth (`kso.drive.readwrite`). Use SenderId as `wps_user_id`. Required query: `allotee_type` (`user` | `group` | `app`). Optional `allotee_id` can be supplied for user/group/app scopes. Optional: `with_ext_attrs`, `page_size` (default 50, max 500), `page_token`, `sources` (array). Optional `x_kso_id_type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},allotee_type:{type:"string",description:"Drive allocation type.",enum:["user","group","app"]},allotee_id:{type:"string",description:"Optional allocation id for user/group/app scope."},with_ext_attrs:{type:"boolean",description:"Optional. Include ext_attrs in response."},page_size:{type:"number",description:"Optional. Page size (default 50, max 500)."},page_token:{type:"string",description:"Optional pagination token."},sources:{type:"array",items:{type:"string"},description:"Optional source filters."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","allotee_type"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"allotee_type");if(i!=="user"&&i!=="group"&&i!=="app")throw new Error("allotee_type must be user, group, or app");let s=i,a=U(n,"allotee_id"),l=ce(n,"with_ext_attrs"),c=Ft(n,"page_size"),d=U(n,"page_token"),p=X(n,"sources");return await mt(o,"\u83B7\u53D6\u76D8\u5217\u8868","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u8BBF\u95EE\u4E91\u6587\u6863\u76D8\u5217\u8868\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async u=>{let _=Mc({alloteeType:s,alloteeId:a,withExtAttrs:l,pageSize:c,pageToken:d,sources:p}),f=await u.request({method:"GET",path:Ec,query:_,headers:Ye(n)});return f.data??f})}catch(o){return Ze(o)}}}),t({name:"wps_cloud_doc_list_children_files",description:"List child files under a parent folder (\u83B7\u53D6\u5B50\u6587\u4EF6\u5217\u8868): GET `/v7/drives/{drive_id}/files/{parent_id}/children`. Requires delegated OAuth (`kso.file.read`). Use SenderId as `wps_user_id`. Required: `drive_id`, `parent_id` (root parent_id is `0`). Optional query: `with_permission`, `with_ext_attrs`, `filter_exts`, `filter_type`, `order`, `order_by`, `page_size`, `page_token`. Optional `x_kso_id_type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId)."},drive_id:{type:"string",description:"Drive ID."},parent_id:{type:"string",description:"Parent folder id (root is `0`)."},with_permission:{type:"boolean",description:"Optional. Include operation permissions in response."},with_ext_attrs:{type:"boolean",description:"Optional. Include file ext_attrs in response."},filter_exts:{type:"string",description:"Optional. Extension filter string separated by semicolons, e.g. `docx;xlsx`."},filter_type:{type:"object",description:"Optional file type filter object (passed through to API query `filter_type`).",additionalProperties:!0},order:{type:"string",enum:[...ks],description:"Optional order direction."},order_by:{type:"string",enum:[...Ss],description:"Optional order field."},page_size:{type:"number",description:"Optional page size (default 50, max 500)."},page_token:{type:"string",description:"Optional pagination token."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","drive_id","parent_id"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"drive_id"),s=j(n,"parent_id"),a=ce(n,"with_permission"),l=ce(n,"with_ext_attrs"),c=U(n,"filter_exts"),d=Ft(n,"page_size"),p=U(n,"page_token"),u=U(n,"order");if(u!==void 0&&!ks.includes(u))throw new Error("order must be one of: desc, asc");let _=u,f=U(n,"order_by");if(f!==void 0&&!Ss.includes(f))throw new Error("order_by must be one of: ctime, mtime, dtime, fname, fsize");let g=f,y=n.filter_type,m;if(y!=null){if(typeof y!="object"||Array.isArray(y))throw new Error("filter_type must be an object when provided");m=y}return await mt(o,"\u83B7\u53D6\u5B50\u6587\u4EF6\u5217\u8868","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u83B7\u53D6\u5B50\u6587\u4EF6\u5217\u8868\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async h=>{let w=zc({withPermission:a,withExtAttrs:l,filterExts:c,filterType:m,order:_,orderBy:g,pageSize:d,pageToken:p}),b=await h.request({method:"GET",path:Lc(i,s),query:w,headers:Ye(n)});return b.data??b})}catch(o){return Ze(o)}}}),t({name:"wps_cloud_doc_create_file",description:"Create file/folder/shortcut (\u65B0\u5EFA\u6587\u4EF6(\u5939)): POST `/v7/drives/{drive_id}/files/{parent_id}/create`. Requires delegated OAuth (`kso.file.readwrite`). Use SenderId as `wps_user_id`. Required: `drive_id`, `parent_id`, `file_type` (`folder` | `file` | `shortcut`), `name`. When `file_type` is `shortcut`, `file_id` is required. Optional: `on_name_conflict` (`fail` | `rename` | `overwrite` | `replace`), `parent_path` (string array). Optional `x_kso_id_type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},drive_id:{type:"string",description:"Drive ID."},parent_id:{type:"string",description:"Parent file/folder ID (root is 0)."},file_type:{type:"string",enum:[...hs],description:"Created resource type: folder, file, or shortcut."},name:{type:"string",description:"Name to create. Include extension for files when needed."},file_id:{type:"string",description:"Required only for file_type=shortcut (target file id)."},on_name_conflict:{type:"string",enum:[...Hr],description:"Name conflict behavior."},parent_path:{type:"array",items:{type:"string"},description:"Optional relative nested path array under parent_id."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","drive_id","parent_id","file_type","name"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"drive_id"),s=j(n,"parent_id"),a=j(n,"file_type");if(!hs.includes(a))throw new Error("file_type must be one of: folder, file, shortcut");let l=a,c=j(n,"name"),d=U(n,"file_id"),p=U(n,"on_name_conflict");if(p!==void 0&&!Hr.includes(p))throw new Error("on_name_conflict must be one of: fail, rename, overwrite, replace");let u=p,_=X(n,"parent_path");return await mt(o,"\u65B0\u5EFA\u6587\u4EF6\uFF08\u5939\uFF09","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u65B0\u5EFA\u4E91\u6587\u6863\u6587\u4EF6\uFF08\u5939\uFF09\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async f=>{let g=Gc({fileType:l,name:c,fileId:d,onNameConflict:u,parentPath:_}),y=await f.request({method:"POST",path:Wc(i,s),body:g,headers:Ye(n)});return y.data??y})}catch(o){return Ze(o)}}}),t({name:"wps_cloud_doc_upload_file",description:"**THE ONLY tool for uploading files** (\u4E00\u4F53\u5316\u4E0A\u4F20). Combines step-1 request_upload, step-2 upload bytes, and step-3 commit_upload into a **single tool call**. Pass `file_path` (local file path, e.g. from prefetched attachment `localPath`); the plugin reads the file directly from disk. The plugin computes `size` and `sha256` hash from the actual file bytes \u2014 **no need for the caller to compute or pass `size` / `hashes`**. This avoids `ContentLengthInvalid` and `BadDigest` errors (no base64 encoding, no truncation risk). Requires delegated OAuth (`kso.file.readwrite`). Use SenderId as `wps_user_id`. Returns the final committed file object.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId)."},drive_id:{type:"string",description:"Drive ID."},parent_id:{type:"string",description:"Parent file/folder ID (root is 0)."},file_path:{type:"string",description:"Absolute path to the local file to upload (e.g. from prefetched attachment `localPath`). The plugin reads bytes directly from disk \u2014 no base64 encoding needed, no truncation risk."},name:{type:"string",description:"Filename for the uploaded file (e.g. 'report.doc'). If omitted, the filename is extracted from `file_path`."},on_name_conflict:{type:"string",enum:[...Hr],description:"Optional name conflict behavior (default: server decides)."},file_id:{type:"string",description:"Optional target file id for update upload."},internal:{type:"boolean",description:"Optional internal endpoint preference."},upload_scene:{type:"string",description:"Optional upload scene."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","drive_id","parent_id","file_path"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"drive_id"),s=j(n,"parent_id"),a=j(n,"file_path"),l=U(n,"name"),c=U(n,"on_name_conflict");if(c!==void 0&&!Hr.includes(c))throw new Error("on_name_conflict must be one of: fail, rename, overwrite, replace");let d=c,p=U(n,"file_id"),u=ce(n,"internal"),_=U(n,"upload_scene"),f=a.trim();try{if(!(await Tc(f)).isFile())throw new Error("path is not a regular file")}catch(h){throw new Error(`file_path "${f}" is not accessible: ${h instanceof Error?h.message:String(h)}`)}let g=await vc(f);if(!l){let h=Math.max(f.lastIndexOf("/"),f.lastIndexOf("\\")),b=(h>=0?f.substring(h+1):f).replace(/^[0-9a-f]{8}_/i,"");b&&(l=b)}if(g.byteLength===0)throw new Error("upload content is empty (file has zero bytes)");let y=g.byteLength,m=xc("sha256").update(g).digest("hex");return await mt(o,"\u4E00\u4F53\u5316\u4E0A\u4F20\u6587\u4EF6","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u4E0A\u4F20\u4E91\u6587\u6863\u6587\u4EF6\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async(h,w)=>{let b=Hc({size:y,fileId:p??void 0,hashes:[{type:"sha256",sum:m}],internal:u??void 0,name:l??void 0,onNameConflict:d,uploadScene:_??void 0}),I=await h.request({method:"POST",path:Fc(i,s),body:b,headers:Ye(n)}),x=I.data??I,M=x.store_request;if(!M||typeof M.url!="string"||!M.url.trim())throw new Error(`step-1 response missing store_request.url \u2014 cannot proceed with upload. Response: ${JSON.stringify(x).substring(0,300)}`);let J=typeof M.method=="string"?M.method.toUpperCase():"PUT",B=M.url;jc(B);let W=M.headers??{},ie=typeof x.upload_id=="string"?x.upload_id:void 0,ee=Te(w,o);if(!ee||!ee.trim())throw new Error("delegated access token missing after auth gate");let le=Nc({requestHeaders:W}),bt={Authorization:`Bearer ${ee.trim()}`,...le},Gt=new Uint8Array(g.buffer,g.byteOffset,g.byteLength),et;try{et=await fetch(B,{method:J,headers:bt,body:Gt})}catch(ke){let $=ke instanceof Error?ke.message:String(ke);throw new Error(`upload step-2 fetch failed: ${$}. Check outbound HTTPS/DNS/firewall from the gateway to the presigned URL.`)}if(!et.ok){let ke=await et.text().catch(()=>"");throw new Error(`upload step-2 failed: HTTP ${et.status} ${ke.substring(0,300)} [diag: size=${y}, sha256=${m}]`)}if(!ie)return{step1:x,step2_status:et.status,etag:et.headers.get("etag")??void 0,warning:"upload_id missing from step-1 \u2014 skipped commit_upload."};let ur=Kc({uploadId:ie}),It=await h.request({method:"POST",path:Bc(i,s),body:ur,headers:Ye(n)});return It.data??It})}catch(o){return Ze(o)}}}),t({name:"wps_cloud_doc_extract_file_content",description:"Extract file content (\u6587\u6863\u5185\u5BB9\u62BD\u53D6): GET `/v7/drives/{drive_id}/files/{file_id}/content`. Requires delegated OAuth (`kso.file.read`). Use SenderId as `wps_user_id`. Required: `drive_id`, `file_id`. Optional query: `format` (`kdc` | `plain` | `markdown`), `include_elements` (`para` | `table` | `component` | `textbox` | `all`), `mode` (`sync` | `async` | `auto`), `task_id`. Returns upstream `data` as-is (for fields like `task_id`, `task_status`, `doc`, `markdown`, `plain`, etc.).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},drive_id:{type:"string",description:"Drive ID."},file_id:{type:"string",description:"File ID."},format:{type:"string",enum:[...xs],description:"Optional output format."},include_elements:{type:"array",items:{type:"string"},description:"Optional extracted element types."},mode:{type:"string",enum:[...vs],description:"Optional extraction mode."},task_id:{type:"string",description:"Optional task id for async/auto result polling."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","drive_id","file_id"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"drive_id"),s=j(n,"file_id"),a=U(n,"format"),l=X(n,"include_elements"),c=U(n,"mode"),d=U(n,"task_id");return await mt(o,"\u6587\u6863\u5185\u5BB9\u62BD\u53D6","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u8FDB\u884C\u6587\u6863\u5185\u5BB9\u62BD\u53D6\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async p=>{let u=Xc({format:a,includeElements:l,mode:c,taskId:d}),_=await p.request({method:"GET",path:Jc(i,s),query:Object.keys(u).length>0?u:void 0,headers:Ye(n)});return _.data??_})}catch(o){return Ze(o)}}}),t({name:"wps_cloud_doc_get_file_meta",description:"Get file metadata (\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F): GET `/v7/files/{file_id}/meta`. Requires delegated OAuth (`kso.file.read`). Use SenderId as `wps_user_id`. Required: `file_id`. Optional query: `with_permission`, `with_ext_attrs`, `with_drive` (boolean). Returns upstream `data` as-is (for fields like `drive`, `permission`, `ext_attrs`, etc.).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"File ID."},with_permission:{type:"boolean",description:"Optional. Include permission field in response."},with_ext_attrs:{type:"boolean",description:"Optional. Include ext_attrs field in response."},with_drive:{type:"boolean",description:"Optional. Include drive field in response."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","file_id"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"file_id"),s=ce(n,"with_permission"),a=ce(n,"with_ext_attrs"),l=ce(n,"with_drive");return await mt(o,"\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async c=>{let d=Yc({withPermission:s,withExtAttrs:a,withDrive:l}),p=await c.request({method:"GET",path:Vc(i),query:Object.keys(d).length>0?d:void 0,headers:Ye(n)});return p.data??p})}catch(o){return Ze(o)}}}),t({name:"wps_cloud_doc_search_files",description:"Search files (\u6587\u4EF6\u641C\u7D22): GET `/v7/files/search`. Requires delegated OAuth (`kso.file.search`). Use SenderId as `wps_user_id`. Required query: `type` (`file_name` | `content` | `all`), `page_size` (default 50, max 500). Supports optional filters: keyword, file_type, file_exts, drive_ids, parent_ids, creator_ids, modifier_ids, sharer_ids, receiver_ids, time_type/start_time/end_time, with_permission/with_link/with_total, page_token, channels/device_ids/exclude_channels/exclude_file_exts, filter_user_id, file_ext_groups, with_folder, with_drive, order/order_by, scope, search_operator_name.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId)."},keyword:{type:"string",description:"Optional search keyword."},type:{type:"string",enum:[...gs],description:"Search type."},file_type:{type:"string",enum:[...ys],description:"Optional file type filter."},file_exts:{type:"array",items:{type:"string"},description:"Optional file extension filters."},drive_ids:{type:"array",items:{type:"string"},description:"Optional drive id filters."},parent_ids:{type:"array",items:{type:"string"},description:"Optional parent id filters."},creator_ids:{type:"array",items:{type:"string"},description:"Optional creator id filters."},modifier_ids:{type:"array",items:{type:"string"},description:"Optional modifier id filters."},sharer_ids:{type:"array",items:{type:"string"},description:"Optional sharer id filters."},receiver_ids:{type:"array",items:{type:"string"},description:"Optional receiver id filters."},time_type:{type:"string",enum:[...ws],description:"Optional time type."},start_time:{type:"number",description:"Optional start time (unix seconds)."},end_time:{type:"number",description:"Optional end time (unix seconds)."},with_permission:{type:"boolean",description:"Optional. Include permission fields."},with_link:{type:"boolean",description:"Optional. Include sharing link fields."},with_total:{type:"boolean",description:"Optional. Include total count in response."},page_size:{type:"number",description:"Optional. Default 50, max 500."},page_token:{type:"string",description:"Optional pagination token."},channels:{type:"array",items:{type:"string"},description:"Optional channel filters."},device_ids:{type:"array",items:{type:"string"},description:"Optional device filters."},exclude_channels:{type:"array",items:{type:"string"},description:"Optional excluded channel filters."},exclude_file_exts:{type:"array",items:{type:"string"},description:"Optional excluded file extension filters."},filter_user_id:{type:"number",description:"Optional filter user id."},file_ext_groups:{type:"array",items:{type:"string"},description:"Optional file extension groups."},with_folder:{type:"boolean",description:"Optional include folder results."},with_drive:{type:"boolean",description:"Optional include drive info."},order:{type:"string",enum:[...bs],description:"Optional order."},order_by:{type:"string",enum:[...Is],description:"Optional order by field."},scope:{type:"array",items:{type:"string"},description:"Optional search scopes."},search_operator_name:{type:"boolean",description:"Optional search by operator name switch."},x_kso_id_type:{type:"string",enum:["internal","external"],description:"Optional. Sent as X-Kso-Id-Type."}},required:["wps_user_id","type"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"type");if(!gs.includes(i))throw new Error("type must be one of: file_name, content, all");let s=i,a=U(n,"file_type");if(a!==void 0&&!ys.includes(a))throw new Error("file_type must be one of: folder, file, shortcut");let l=a,c=U(n,"time_type");if(c!==void 0&&!ws.includes(c))throw new Error("time_type must be one of: ctime, mtime, otime, stime");let d=c,p=U(n,"order");if(p!==void 0&&!bs.includes(p))throw new Error("order must be one of: desc, asc");let u=p,_=U(n,"order_by");if(_!==void 0&&!Is.includes(_))throw new Error("order_by must be one of: ctime, mtime");let f=_,g=X(n,"scope");if(g!==void 0){for(let y of g)if(!Uc.includes(y))throw new Error("scope items must be one of: all, share_by_me, share_to_me, latest, personal_drive, group_drive, recycle, customize, latest_opened, latest_edited")}return await mt(o,"\u6587\u4EF6\u641C\u7D22","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u641C\u7D22\u4E91\u6587\u6863\u6587\u4EF6\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async y=>{let m=Zc({keyword:U(n,"keyword"),type:s,fileType:l,fileExts:X(n,"file_exts"),driveIds:X(n,"drive_ids"),parentIds:X(n,"parent_ids"),creatorIds:X(n,"creator_ids"),modifierIds:X(n,"modifier_ids"),sharerIds:X(n,"sharer_ids"),receiverIds:X(n,"receiver_ids"),timeType:d,startTime:Ft(n,"start_time"),endTime:Ft(n,"end_time"),withPermission:ce(n,"with_permission"),withLink:ce(n,"with_link"),withTotal:ce(n,"with_total"),pageSize:Ft(n,"page_size"),pageToken:U(n,"page_token"),channels:X(n,"channels"),deviceIds:X(n,"device_ids"),excludeChannels:X(n,"exclude_channels"),excludeFileExts:X(n,"exclude_file_exts"),filterUserId:Ft(n,"filter_user_id"),fileExtGroups:X(n,"file_ext_groups"),withFolder:ce(n,"with_folder"),withDrive:ce(n,"with_drive"),order:u,orderBy:f,scope:g,searchOperatorName:ce(n,"search_operator_name")}),h=await y.request({method:"GET",path:Ac,query:m,headers:Ye(n)});return h.data??h})}catch(o){return Ze(o)}}})}var Qc="/v7/airpage/files";function ht(e,t){return`/v7/airpage/${encodeURIComponent(e.trim())}${t}`}function yt(e){return{arg:Buffer.from(JSON.stringify(e),"utf8").toString("base64")}}function gt(e,t){return e.length>36?`${t} (${e.slice(0,36)}...)`:`${t} (${e})`}function Es(e,t){let r=e.operation,n=e.blockId;if(typeof r!="string"||!r.trim())throw new Error(`${t}.operation is required and must be a non-empty string`);if(typeof n!="string"||!n.trim())throw new Error(`${t}.blockId is required and must be a non-empty string`)}var fi=["rename","fail","overwrite"];function Ne(e){return{error:e instanceof Error?e.message:String(e)}}function N(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function Ts(e,t){let r=e[t];if(r==null)return;if(typeof r!="string")throw new Error(`${t} must be a string`);let n=r.trim();return n===""?void 0:n}function Jr(e,t){let r=e[t];if(!Array.isArray(r))throw new Error(`${t} is required and must be an array`);return r}function el(e,t){let n=Jr(e,t).map(o=>String(o).trim()).filter(Boolean);if(n.length===0)throw new Error(`${t} must contain at least one non-empty string`);return n}function tl(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return Math.max(0,Math.trunc(r));if(typeof r=="string"&&r.trim()!==""){let n=Number(r.trim());if(Number.isFinite(n))return Math.max(0,Math.trunc(n))}throw new Error(`${t} must be a finite integer when provided`)}}function Kr(e,t){let r=e[t];if(r==null)throw new Error(`${t} is required and must be a finite integer`);if(typeof r=="number"&&Number.isFinite(r))return Math.trunc(r);if(typeof r=="string"&&r.trim()!==""){let n=Number(r.trim());if(Number.isFinite(n))return Math.trunc(n)}throw new Error(`${t} must be a finite integer`)}function rl(e){let t={blockId:e.blockId.trim(),content:e.content},r=e.index;return r!==void 0&&(t.index=r),yt(t)}function nl(e){let t={blockId:e.blockId.trim()};return yt(t)}function il(e){let t={blockIds:e.blockIds.map(r=>r.trim()).filter(Boolean)};if(t.blockIds.length===0)throw new Error("blockIds must contain at least one non-empty id");return yt(t)}function ol(e){if(e.endIndex<=e.startIndex)throw new Error("endIndex must be greater than startIndex");let t={blockId:e.blockId.trim(),startIndex:Math.trunc(e.startIndex),endIndex:Math.trunc(e.endIndex)};if(!t.blockId)throw new Error("blockId must be non-empty");return yt(t)}function sl(e){if(!Array.isArray(e)||e.length===0)throw new Error("delete_items must contain at least one delete range");let t=e.map(r=>{let n=r.blockId.trim(),o=Math.trunc(r.startIndex),i=Math.trunc(r.endIndex);if(!n)throw new Error("delete_items.blockId must be non-empty");if(i<=o)throw new Error("delete_items.endIndex must be greater than delete_items.startIndex");return{blockId:n,startIndex:o,endIndex:i}});return yt(t)}function al(e){return Es(e,"operation"),yt(e)}function dl(e){if(!Array.isArray(e)||e.length===0)throw new Error("operations must contain at least one operation object");for(let[t,r]of e.entries()){if(!r||typeof r!="object"||Array.isArray(r))throw new Error(`operations[${t}] must be an object`);Es(r,`operations[${t}]`)}return yt(e)}function cl(e){let t=e.trim().toLowerCase();if(fi.includes(t))return t;throw new Error(`on_name_conflict must be one of: ${fi.join(", ")} (got: ${e})`)}function ll(e){let t={drive_id:e.driveId,name:e.name,on_name_conflict:e.onNameConflict};return e.parentId!==void 0&&(t.parent_id=e.parentId),e.templateId!==void 0&&(t.template_id=e.templateId),t}async function Qe(e,t,r){try{return await _e({wpsUserId:e,toolModule:"airpage",authCardOriginalMessage:t,needsAuthMessage:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u64CD\u4F5C\u667A\u80FD\u6587\u6863\uFF08Airpage\uFF09\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u5B8C\u6210\u6388\u6743\u540E\u91CD\u8BD5\u3002",logTag:"airpage",run:r})}catch(n){return Ne(n)}}function _i(e,t){t({name:"wps_airpage_create_file",description:"Create a blank Smart Document (Airpage / \u667A\u80FD\u6587\u6863) via WPS OpenAPI: POST `/v7/airpage/files`. Requires user delegated OAuth with scope `kso.airpage.readwrite` (or equivalent). Use SenderId as `wps_user_id`. Required: `drive_id`, `name` (document title without file extension), `on_name_conflict` (`rename` | `fail` | `overwrite`). Optional: `parent_id` (parent folder id), `template_id` (create from template). Obtain `drive_id` via `wps_cloud_doc_list_drives`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},drive_id:{type:"string",description:"Target drive id (from wps_cloud_doc_list_drives)."},name:{type:"string",description:"Document name without extension (per API)."},on_name_conflict:{type:"string",enum:[...fi],description:"Strategy when the name already exists: rename, fail, or overwrite."},parent_id:{type:"string",description:"Optional parent folder id."},template_id:{type:"string",description:"Optional template id to create from."}},required:["wps_user_id","drive_id","name","on_name_conflict"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"drive_id"),s=N(n,"name"),a=N(n,"on_name_conflict"),l=cl(a),c=Ts(n,"parent_id"),d=Ts(n,"template_id"),p=`\u521B\u5EFA\u667A\u80FD\u6587\u6863: ${s}`;return await Qe(o,p,async u=>{let _=ll({driveId:i,name:s,onNameConflict:l,parentId:c,templateId:d}),f=await u.request({method:"POST",path:Qc,body:_});return f.data??f})}catch(o){return Ne(o)}}}),t({name:"wps_airpage_create_block_content",description:'Insert block content into a Smart Document (Airpage): POST `/v7/airpage/{file_id}/blocks/create`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON). JSON fields: `blockId` (parent block; use literal `doc` for document root), optional `index` (insert position; omit for API default 0), required `content` (array of child block nodes). Requires delegated `kso.airpage.readwrite`. Use SenderId as `wps_user_id`.\n\n## Block node types (used in `content` array):\nEach node: `{ type, attrs?, content? }`. `content` is an array of child blocks or inline nodes.\n\n- **title**: Document title (unique, must be first child of doc). attrs: `align` (1=left,2=center,3=right). content: inline nodes.\n- **paragraph**: Paragraph (also used for lists). attrs: `indent` (0|1), `contentIndent` (>=0), `align` (1|2|3), `listAttrs` `{id,type(1=unordered,2=ordered,3=task),styleType(1-13),level,styleFormat(1-9)}`. content: inline nodes.\n- **heading**: Heading h1-h6. attrs: `level` (1-6), `indent`, `contentIndent`, `align`, `listAttrs` (same as paragraph). content: inline nodes.\n- **blockQuote**: Quote block. attrs: `indent`, `contentIndent`, `align`. content: block nodes (paragraph, heading, etc.). Inline `br` for line breaks inside.\n- **codeBlock**: Code block. attrs: `lang` (1=plaintext,2=css,3=go,4=python,5=shell,...19=javascript,12=typescript,17=json,43=yaml, etc.), `autoWrap` (bool), `theme` (1=light,2=dark). content: text nodes (may contain `\\n`).\n- **highLightBlock**: Highlight block. attrs: `emoji` (required), `style {fontColor(1-12),backgroundColor(1-6),borderColor}`. content: block nodes. Cannot contain title, table, column, highLightBlock, lockBlock.\n- **lockBlock**: Content protection area (only file creator can edit). No attrs. content: block nodes. Cannot contain title, lockBlock.\n- **table**: Table. attrs: `borderStyle` (1=none,2=solid). content: tableRow nodes.\n - **tableRow**: Table row. No attrs. content: tableCell nodes.\n - **tableCell**: Cell. attrs: `width`, `height`, `colspan` (>=1), `rowspan` (>=1), `verticalAlign` (1=top,2=middle,3=bottom). content: block nodes.\n- **column**: Column layout (1-10 columns). attrs: `backgroundColor` (1-12). content: columnItem nodes.\n - **columnItem**: Column item. attrs: `width` (percent string e.g. "50.00%"), `backgroundColor` (1-42). content: block nodes.\n- **pictureColumn**: Side-by-side images (2-5). attrs: `width` (percent), `align` (1|2|3). content: picture nodes.\n- **picture**: Image. attrs (required: sourceKey, width, height): `sourceKey` (image resource id from attachment upload), `width`, `height`, `renderWidth`, `caption`, `rotate` (0|-90|-180|-270), `borderType` (0|1), `align`. No content.\n- **blockAnchor**: Placeholder. attrs (required: id, aimType, width, height): `id`, `aimType` (\'picture\'|\'video\'|\'processon\'|\'spreadsheet\'), `width`, `height`. No content.\n- **hr**: Horizontal rule. No attrs, no content.\n- **video**: Video. attrs (required: sourceId, sourceKey, width, height): `sourceId`, `sourceKey` (cover image id), `width`, `height`, `title`, `align`.\n- **audio**: Audio. attrs (required: sourceId): `sourceId`, `title`.\n- **videoLink**: Video link. attrs (required: url): `url`, `platform` (1=bilibili), `align`.\n- **countdown**: Countdown. attrs (required: type): `type` (1=date,2=time), `duration` (ms, 0-86399999000).\n- **map**: Map (Amap). attrs (required: lng, lat, address, addressName): `lng`, `lat`, `address`, `addressName`, `platform` (1), `mapZoom`, `align`.\n- **thirdResource**: 3rd-party embed. attrs (required: url): `url`, `type` (1=mooc,2=modao,3=masterGo,4=netease,5=aliyun,6=survey,7=figma,8=pixso,9=xiaohuazhuo), `align`.\n- **dbsheet**: Multi-dim table. attrs (required: sourceId): `sourceId`, `width`, `height`.\n- **spreadsheet**: Spreadsheet. attrs (required: sourceId): `sourceId`, `sheetId`.\n- **groupCard**: Group card. attrs (required: id, name, masterName): `id`, `name`, `masterName`.\n- **appComponent**: App plugin. attrs: `type` (1=vote,2=video_channel,...8=canvas).\n- **processon**: Flowchart/mindmap. attrs (required: type, sourceId, sourceKey, width, height): `type` (1=flow,2=mind), `sourceId`, `sourceKey`, `caption`, `rotate`, `width`, `height`, `renderWidth`, `borderType`, `align`.\n\n## Inline node types (used in content of paragraph, heading, blockQuote, title, codeBlock):\n- **text**: Text. `content` field is a non-empty string (only in codeBlock may contain `\\n`). Common attrs: `bold`, `italic`, `underline`, `strike`, `sup`, `sub` (all bool); `fontSize {fontSize: 9|11|13|15|16|19|22}`; `color {fontColor,backgroundColor,fontGradientColor(1-6)}`.\n- **emoji**: Emoji. attrs (required: emoji): single emoji character.\n- **br**: Line break (used inside blockQuote). No attrs.\n- **latex**: Formula. attrs (required: width, height, latexStr): `width`, `height`, `latexStr`.\n- **linkView**: Hyperlink view. attrs (required: title, url, viewType, sourceKey, description): `title`, `url`, `viewType` (1=title,2=card \u2014 card requires paragraph parent with no siblings), `sourceKey` (icon id), `description`.\n- **schedule**: Schedule. attrs (required: id, name, startTime, endTime): `id` (taskId|sid|teamId), `name`, `startTime` (unix ms), `endTime` (unix ms), `actionType` (1=partial,2=allday).\n- **staticTime**: Date. attrs (required: time): `time` (unix ms), `timeType` (1=date,2=datetime).\n- **WPSUser**: @mention. attrs (required: userId, name): `userId`, `name`, `avatar`.\n- **WPSDocument**: Cloud doc / local file. attrs (required: wpsDocumentId, wpsDocumentName, wpsDocumentType): `wpsDocumentId`, `wpsDocumentName`, `wpsDocumentType`, `wpsDocumentLink` (required for cloud doc), `viewType` (1=title,2=preview,3=card,4=attachment \u2014 2/3/4 require paragraph parent with no siblings), `size` (bytes, required for local file), `width`, `height`, `align`.\n\n## Examples:\nParagraph: `{"type":"paragraph","content":[{"type":"text","content":"Hello"}]}`\nHeading h2: `{"type":"heading","attrs":{"level":2},"content":[{"type":"text","content":"Title"}]}`\nBold text: `{"type":"paragraph","content":[{"type":"text","attrs":{"bold":true},"content":"bold text"}]}`\nOrdered list: `{"type":"paragraph","attrs":{"listAttrs":{"type":2,"styleType":4,"level":0}},"content":[{"type":"text","content":"item 1"}]}`\nCode block: `{"type":"codeBlock","attrs":{"lang":19},"content":[{"type":"text","content":"console.log(\'hi\')"}]}`\nTable 2x2: `{"type":"table","attrs":{"borderStyle":2},"content":[{"type":"tableRow","content":[{"type":"tableCell","attrs":{"width":200,"height":40},"content":[{"type":"paragraph","content":[{"type":"text","content":"A1"}]}]},{"type":"tableCell","attrs":{"width":200,"height":40},"content":[{"type":"paragraph","content":[{"type":"text","content":"B1"}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{"width":200,"height":40},"content":[{"type":"paragraph","content":[{"type":"text","content":"A2"}]}]},{"type":"tableCell","attrs":{"width":200,"height":40},"content":[{"type":"paragraph","content":[{"type":"text","content":"B2"}]}]}]}]}`',parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/create)."},block_id:{type:"string",description:"Parent block id. Use the string `doc` to insert under the document root; otherwise use a block id from the query-document-blocks API."},index:{type:"integer",description:"Optional insert position (0-based, must be >= 0). 0 = insert before first child. To append at the end, use a large number (e.g. 9999) or omit this field. Negative values are NOT supported and will cause API errors."},content:{type:"array",description:"Required array of block nodes to insert. Each node has `type` (string), optional `attrs` (object), and optional `content` (child nodes or text string for text nodes). See description above for all supported block and inline types.",items:{type:"object",additionalProperties:!0}}},required:["wps_user_id","file_id","block_id","content"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),s=N(n,"block_id"),a=Jr(n,"content"),l=tl(n,"index"),c=rl({blockId:s,content:a,index:l}),d=gt(i,"\u667A\u80FD\u6587\u6863\u521B\u5EFA\u5757\u5185\u5BB9");return await Qe(o,d,async p=>{let u=await p.request({method:"POST",path:ht(i,"/blocks/create"),body:c});return u.data??u})}catch(o){return Ne(o)}}}),t({name:"wps_airpage_query_document_blocks",description:"Query blocks from a Smart Document (Airpage): POST `/v7/airpage/{file_id}/blocks`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON). JSON fields: required `blockId` (use literal `doc` to query the whole document tree, or pass a specific block id to query its children). Requires delegated Airpage permission (`kso.airpage.read` or `kso.airpage.readwrite` depending on app grants). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks)."},block_id:{type:"string",description:"Target block id mapped to request JSON field blockId. Use doc to query entire document blocks."}},required:["wps_user_id","file_id","block_id"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),s=N(n,"block_id"),a=nl({blockId:s}),l=gt(i,"\u667A\u80FD\u6587\u6863\u67E5\u8BE2\u6587\u6863\u5757");return await Qe(o,l,async c=>{let d=await c.request({method:"POST",path:ht(i,"/blocks"),body:a});return d.data??d})}catch(o){return Ne(o)}}}),t({name:"wps_airpage_batch_query_document_blocks",description:"Batch query blocks from a Smart Document (Airpage): POST `/v7/airpage/{file_id}/blocks/batch_get`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON), with JSON field `blockIds` (string array). Use this when querying multiple specific block ids in one request. Requires delegated Airpage permission (`kso.airpage.read` or `kso.airpage.readwrite`). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/batch_get)."},block_ids:{type:"array",description:"Required block id list mapped to JSON blockIds for batch query.",items:{type:"string"}}},required:["wps_user_id","file_id","block_ids"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),s=el(n,"block_ids"),a=il({blockIds:s}),l=gt(i,"\u667A\u80FD\u6587\u6863\u6279\u91CF\u67E5\u8BE2\u6587\u6863\u5757");return await Qe(o,l,async c=>{let d=await c.request({method:"POST",path:ht(i,"/blocks/batch_get"),body:a});return d.data??d})}catch(o){return Ne(o)}}}),t({name:"wps_airpage_delete_block_content",description:"Delete block content from a Smart Document (Airpage): POST `/v7/airpage/{file_id}/blocks/delete`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON), with JSON fields: `blockId`, `startIndex`, `endIndex` (`endIndex` must be > `startIndex`). Use SenderId as `wps_user_id`. Requires delegated `kso.airpage.readwrite`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/delete)."},block_id:{type:"string",description:"Parent block id mapped to JSON field blockId. Commonly use doc for document root."},start_index:{type:"integer",description:"Required delete start position (mapped to JSON startIndex)."},end_index:{type:"integer",description:"Required delete end position (mapped to JSON endIndex), must be greater than start_index."}},required:["wps_user_id","file_id","block_id","start_index","end_index"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),s=N(n,"block_id"),a=Kr(n,"start_index"),l=Kr(n,"end_index"),c=ol({blockId:s,startIndex:a,endIndex:l}),d=gt(i,"\u667A\u80FD\u6587\u6863\u5220\u9664\u5757\u5185\u5BB9");return await Qe(o,d,async p=>{let u=await p.request({method:"POST",path:ht(i,"/blocks/delete"),body:c});return u.data??u})}catch(o){return Ne(o)}}}),t({name:"wps_airpage_batch_delete_block_content",description:"Batch delete block content ranges from a Smart Document (Airpage): POST `/v7/airpage/{file_id}/blocks/batch_delete`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON), with JSON as an array of delete-range objects: `[{ blockId, startIndex, endIndex }]` and each item requires `endIndex > startIndex`. Use SenderId as `wps_user_id`. Requires delegated `kso.airpage.readwrite`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/batch_delete)."},delete_items:{type:"array",description:"Required delete range array. Each item: block_id, start_index, end_index (end_index > start_index).",items:{type:"object",properties:{block_id:{type:"string"},start_index:{type:"integer"},end_index:{type:"integer"}},required:["block_id","start_index","end_index"]}}},required:["wps_user_id","file_id","delete_items"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),a=Jr(n,"delete_items").map((d,p)=>{if(!d||typeof d!="object"||Array.isArray(d))throw new Error(`delete_items[${p}] must be an object`);let u=d,_=N(u,"block_id"),f=Kr(u,"start_index"),g=Kr(u,"end_index");return{blockId:_,startIndex:f,endIndex:g}}),l=sl(a),c=gt(i,"\u667A\u80FD\u6587\u6863\u6279\u91CF\u5220\u9664\u5757\u5185\u5BB9");return await Qe(o,c,async d=>{let p=await d.request({method:"POST",path:ht(i,"/blocks/batch_delete"),body:l});return p.data??p})}catch(o){return Ne(o)}}}),t({name:"wps_airpage_update_document_block",description:"Update Smart Document blocks via Airpage operation object: POST `/v7/airpage/{file_id}/blocks/update`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON) of ONE operation object (e.g. update_content, update_attrs, insert_table_rows, insert_table_columns, delete_table_rows, delete_table_columns, merge_table_cells, split_table_cell, replace_anchor, replace_feature). At minimum operation JSON should contain `operation` and `blockId`; other fields depend on operation type. Use SenderId as `wps_user_id`. Requires delegated `kso.airpage.readwrite`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/update)."},operation:{type:"object",description:"Required operation object that will be encoded as arg JSON. Must include operation + blockId. Example: {operation:'update_content', blockId:'xxx', content:[...]}",additionalProperties:!0}},required:["wps_user_id","file_id","operation"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),s=n.operation;if(!s||typeof s!="object"||Array.isArray(s))throw new Error("operation is required and must be an object");let l=al(s),c=gt(i,"\u667A\u80FD\u6587\u6863\u66F4\u65B0\u6587\u6863\u5757");return await Qe(o,c,async d=>{let p=await d.request({method:"POST",path:ht(i,"/blocks/update"),body:l});return p.data??p})}catch(o){return Ne(o)}}}),t({name:"wps_airpage_batch_update_document_blocks",description:"Batch update Smart Document blocks via Airpage operation array: POST `/v7/airpage/{file_id}/blocks/batch_update`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON) of an operation object array. Each operation object must include `operation` + `blockId`; other fields depend on operation type (update_content, update_attrs, insert_table_rows, insert_table_columns, delete_table_rows, delete_table_columns, merge_table_cells, split_table_cell, replace_anchor, replace_feature). Use SenderId as `wps_user_id`. Requires delegated `kso.airpage.readwrite`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/batch_update)."},operations:{type:"array",description:"Required operation object array. Each item must include operation + blockId; extra fields depend on operation type.",items:{type:"object",additionalProperties:!0}}},required:["wps_user_id","file_id","operations"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),a=Jr(n,"operations").map((d,p)=>{if(!d||typeof d!="object"||Array.isArray(d))throw new Error(`operations[${p}] must be an object`);return d}),l=dl(a),c=gt(i,"\u667A\u80FD\u6587\u6863\u6279\u91CF\u66F4\u65B0\u6587\u6863\u5757");return await Qe(o,c,async d=>{let p=await d.request({method:"POST",path:ht(i,"/blocks/batch_update"),body:l});return p.data??p})}catch(o){return Ne(o)}}})}var pl="/v7/meeting_rooms",ul="/v7/meeting_rooms/search",fl="/v7/meeting_room_bookings/batch_get",_l=["success","failed"];var Os=["success","failed","approving"];function pr(e){return{error:e instanceof Error?e.message:String(e)}}function je(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function Bt(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}function mi(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function As(e,t){let r=e[t];if(r==null)throw new Error(`${t} is required and must be a finite number`);if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}function ml(e,t){let r=e[t];if(r!=null){if(typeof r=="boolean")return r;if(r==="true"||r==="false")return r==="true";throw new Error(`${t} must be a boolean`)}}function $s(e,t){let r=e[t];if(r==null)return;if(!Array.isArray(r))throw new Error(`${t} must be an array`);let n=[];for(let o of r){if(typeof o!="string")throw new Error(`${t} entries must be strings`);let i=o.trim();i!==""&&n.push(i)}return n.length>0?n:void 0}function hl(e,t){let r=$s(e,t);if(r===void 0)return;let n=new Set(Os),o=r.filter(i=>n.has(i));return o.length>0?o:void 0}function Ps(e){let t=Bt(e,"x_kso_id_type");if(t===void 0||t.trim()==="")return;let r=t.trim();if(r!=="internal"&&r!=="external")throw new Error("x_kso_id_type must be internal or external when provided");return{"X-Kso-Id-Type":r}}function gl(e){let t=e.pageSize??20,n={page_size:Math.max(1,Math.min(500,Math.trunc(t)))};return e.roomLevelId!==void 0&&e.roomLevelId.trim()!==""&&(n.room_level_id=e.roomLevelId.trim()),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(n.page_token=e.pageToken.trim()),n}function yl(e){let t=e.trim();if(!t)throw new Error("room_id must be a non-empty string");return`/v7/meeting_rooms/${encodeURIComponent(t)}`}function wl(e){let t=e.keyword.trim();if(!t)throw new Error("keyword is required and must be a non-empty string");let r=e.pageSize??20,n=Math.max(1,Math.min(100,Math.trunc(r))),o={keyword:t,page_size:n};return e.pageToken!==void 0&&e.pageToken.trim()!==""&&(o.page_token=e.pageToken.trim()),o}function bl(e){let t=Math.trunc(Number(e.startTimeSec)),r=Math.trunc(Number(e.endTimeSec));if(!Number.isFinite(t)||!Number.isFinite(r))throw new Error("start_time and end_time must be finite Unix timestamps in seconds");if(r<t)throw new Error("end_time must be >= start_time (Unix seconds)");let n=e.roomLevelId?.trim()??"",o=n!=="",i=e.roomIds?.filter(d=>d.trim()!=="").map(d=>d.trim())??[],s=i.length>0;if(o&&s)throw new Error("Provide either room_ids or room_level_id, not both");if(!o&&!s)throw new Error("Provide exactly one of room_ids (non-empty array) or room_level_id");let a=e.pageSize??20,l=Math.max(1,Math.min(500,Math.trunc(Number(a))));if(!Number.isFinite(l))throw new Error("page_size must be finite");let c={start_time:t,end_time:r,page_size:l};return o&&(c.room_level_id=n),s&&(c.room_ids=i),e.includeDeleted===!0&&(c.include_deleted=!0),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(c.page_token=e.pageToken.trim()),e.results!==void 0&&e.results.length>0&&(c.results=[...e.results]),c}function Il(e){let t=e.trim();if(!t)throw new Error("booking_id must be a non-empty string");return`/v7/meeting_room_bookings/${encodeURIComponent(t)}/update_status`}function kl(e){let t=e.trim();if(t!=="success"&&t!=="failed")throw new Error("status must be success or failed");return{status:t}}function hi(e,t){t({name:"wps_meeting_rooms_list",description:"List meeting rooms (\u67E5\u8BE2\u4F1A\u8BAE\u5BA4\u5217\u8868): GET `/v7/meeting_rooms`. Uses **application** access_token (client_credentials); requires app scopes **`kso.meeting_rooms.read`** or **`kso.meeting_rooms.readwrite`** on the Open Platform (often **app-only**, not user OAuth). Still pass SenderId as `wps_user_id` for session context (not sent as HTTP user identity). Optional: `room_level_id` (\u4F1A\u8BAE\u5BA4\u5C42\u7EA7 id), `page_size` (default 20, max 500), `page_token` (omit on first page). Response `data` typically includes `items[]` (id, name, capacity, level_id, disable, remark, device_list, tag_list) and `next_page_token`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},room_level_id:{type:"string",description:"Optional. Meeting room level id (\u4F1A\u8BAE\u5BA4\u5C42\u7EA7 id)."},page_size:{type:"number",description:"Optional. Items per page (default 20 per API, max 500 client cap)."},page_token:{type:"string",description:"Optional. Pagination token from data.next_page_token; omit for first request."}},required:["wps_user_id"]},async execute(r,n){try{je(n,"wps_user_id");let o=Bt(n,"room_level_id"),i=mi(n,"page_size"),s=Bt(n,"page_token"),a=gl({roomLevelId:o,pageSize:i,pageToken:s}),l=await e.request({method:"GET",path:pl,query:a});return l.data??l}catch(o){return pr(o)}}}),t({name:"wps_meeting_rooms_get",description:"Get meeting room details (\u67E5\u8BE2\u4F1A\u8BAE\u5BA4\u8BE6\u60C5): GET `/v7/meeting_rooms/{room_id}`. Uses **application** access_token; requires app **`kso.meeting_rooms.read`** or **`kso.meeting_rooms.readwrite`**. Pass SenderId as `wps_user_id` for context only. Required: `room_id` from `wps_meeting_rooms_list` items[]. Response `data` is a single room object (id, name, capacity, level_id, disable, remark, device_list, tag_list).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},room_id:{type:"string",description:"Meeting room id from the meeting room list (\u4F1A\u8BAE\u5BA4 id\uFF0C\u53EF\u901A\u8FC7\u4F1A\u8BAE\u5BA4\u5217\u8868\u67E5\u8BE2)."}},required:["wps_user_id","room_id"]},async execute(r,n){try{je(n,"wps_user_id");let o=je(n,"room_id"),i=await e.request({method:"GET",path:yl(o)});return i.data??i}catch(o){return pr(o)}}}),t({name:"wps_meeting_rooms_search",description:"Search meeting rooms by keyword (\u641C\u7D22\u4F1A\u8BAE\u5BA4): POST `/v7/meeting_rooms/search`. Uses **application** access_token; requires app **`kso.meeting_rooms.read`** or **`kso.meeting_rooms.readwrite`**. Pass SenderId as `wps_user_id` for context only. Required body: `keyword` (meeting room name search). Optional: `page_size` (default 20, max 100 per API), `page_token` (omit on first page; use data.next_page_token). Response `data` typically includes `items[]` and `next_page_token`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},keyword:{type:"string",description:"Search keyword; supports meeting room name (\u641C\u7D22\u5173\u952E\u8BCD\uFF0C\u652F\u6301\u4F1A\u8BAE\u5BA4\u540D\u79F0\u641C\u7D22)."},page_size:{type:"number",description:"Optional. Items per page (default 20 per API, max 100)."},page_token:{type:"string",description:"Optional. Pagination token from data.next_page_token; omit for first request."}},required:["wps_user_id","keyword"]},async execute(r,n){try{je(n,"wps_user_id");let o=je(n,"keyword"),i=mi(n,"page_size"),s=Bt(n,"page_token"),a=wl({keyword:o,pageSize:i,pageToken:s}),l=await e.request({method:"POST",path:ul,body:a});return l.data??l}catch(o){return pr(o)}}}),t({name:"wps_meeting_room_bookings_batch_get",description:"Batch query meeting room bookings (\u6279\u91CF\u67E5\u8BE2\u4F1A\u8BAE\u5BA4\u9884\u7EA6): POST `/v7/meeting_room_bookings/batch_get`. Uses **application** access_token; requires app **`kso.meeting_rooms.read`** or **`kso.meeting_rooms.readwrite`**. Pass SenderId as `wps_user_id` for context only. Required JSON body params: `start_time`, `end_time` (**Unix timestamps in seconds**). Exactly one of: non-empty **`room_ids`** (string[]) **or** **`room_level_id`** (string)\u2014not both, not neither. Optional: `include_deleted` (boolean, default false), `page_size` (default 20, max 500), `page_token`, `results` filter array (`success`|`failed`|`approving`). Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},start_time:{type:"number",description:"Query window start (**Unix timestamp in seconds**, \u5FC5\u586B)."},end_time:{type:"number",description:"Query window end (**Unix timestamp in seconds**, \u5FC5\u586B)."},room_ids:{type:"array",items:{type:"string"},description:"Meeting room id list. Mutually exclusive with room_level_id."},room_level_id:{type:"string",description:"Meeting room level id. Mutually exclusive with room_ids."},include_deleted:{type:"boolean",description:"Whether to include deleted bookings (\u9ED8\u8BA4 false)."},page_size:{type:"number",description:"Page size (default 20 per API, max 500 client cap)."},page_token:{type:"string",description:"Pagination token; omit on first page when unused."},results:{type:"array",items:{type:"string",enum:[...Os]},description:"Optional filter by reservation result: success, failed, approving."},x_kso_id_type:{type:"string",enum:["internal","external"],description:"Optional. Maps to HTTP header X-Kso-Id-Type."}},required:["wps_user_id","start_time","end_time"]},async execute(r,n){try{je(n,"wps_user_id");let o=As(n,"start_time"),i=As(n,"end_time"),s=$s(n,"room_ids"),a=Bt(n,"room_level_id"),l=ml(n,"include_deleted"),c=mi(n,"page_size"),d=Bt(n,"page_token"),p=hl(n,"results"),u=bl({startTimeSec:o,endTimeSec:i,roomIds:s,roomLevelId:a,includeDeleted:l,pageSize:c,pageToken:d,results:p??void 0}),_=await e.request({method:"POST",path:fl,body:u,headers:Ps(n)});return _.data??_}catch(o){return pr(o)}}}),t({name:"wps_meeting_room_bookings_update_status",description:"Update meeting room booking status (\u66F4\u65B0\u4F1A\u8BAE\u5BA4\u9884\u7EA6\u72B6\u6001): POST `/v7/meeting_room_bookings/{booking_id}/update_status`. Uses **application** access_token; requires app **`kso.meeting_rooms.readwrite`** (per API). Pass SenderId as `wps_user_id` for context only. Path: **`booking_id`** from booking list / batch query (`items[].id`). JSON body: **`status`** enum **`success`** (\u9884\u7EA6\u6210\u529F) or **`failed`** (\u9884\u7EA6\u5931\u8D25). Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},booking_id:{type:"string",description:"Meeting room booking id (\u4F1A\u8BAE\u5BA4\u9884\u7EA6 id\uFF0C\u53EF\u4ECE\u6279\u91CF\u67E5\u8BE2\u9884\u7EA6\u7B49\u63A5\u53E3 items[].id \u53D6\u5F97)."},status:{type:"string",enum:[..._l],description:"Updated reservation outcome: success or failed."},x_kso_id_type:{type:"string",enum:["internal","external"],description:"Optional. Maps to HTTP header X-Kso-Id-Type."}},required:["wps_user_id","booking_id","status"]},async execute(r,n){try{je(n,"wps_user_id");let o=je(n,"booking_id"),i=je(n,"status"),s=kl(i),a=await e.request({method:"POST",path:Il(o),body:s,headers:Ps(n)});return a.data??a}catch(o){return pr(o)}}})}var be={type:"string",description:"WPS user ID (current SenderId). Do NOT call wps_user_search for this."},Oe={type:"string",description:"Smart Sheet file ID."},wt={type:"integer",description:"Worksheet ID (integer). From wps_airsheet_list_worksheets."};async function Sl(e,t,r){return _e({wpsUserId:e,toolModule:"airsheet",authCardOriginalMessage:"\u7528\u6237\u8BF7\u6C42\u64CD\u4F5C\u667A\u80FD\u8868\u683C",needsAuthMessage:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u64CD\u4F5C\u667A\u80FD\u8868\u683C\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",logTag:t,run:r})}function Ie(e,t){return async(r,n)=>{try{let o=T(n,"wps_user_id");return await Sl(o,e,i=>t(n,i))}catch(o){return ae(o)}}}function gi(e,t){t({name:"wps_airsheet_create_file",description:"Create a Smart Sheet (\u667A\u80FD\u8868\u683C / AirSheet): POST `/v7/airsheet/files`. Creates a new smart sheet file in the specified drive. Required: `drive_id` (from `wps_cloud_doc_list_drives`), `name` (file name, may omit extension; if extension is provided it must be `ksheet`). Optional: `on_name_conflict` (`rename` (default) | `fail`), `parent_id` (folder id, empty = root), `parent_path` (string array of folder names as relative path; auto-created if not exists). Requires delegated OAuth with scope `kso.airsheet.readwrite`. Use SenderId as `wps_user_id`. Response includes `id`, `link_id`, `link_url`, `name`, `parent_id`.",parameters:{type:"object",properties:{wps_user_id:be,drive_id:{type:"string",description:"Target drive id (from wps_cloud_doc_list_drives)."},name:{type:"string",description:"File name. May omit extension; if extension is provided it must be ksheet."},on_name_conflict:{type:"string",enum:["rename","fail"],description:"Optional. Strategy when name conflicts: rename (default) or fail."},parent_id:{type:"string",description:"Optional. Parent folder id. Empty means root directory."},parent_path:{type:"array",items:{type:"string"},description:"Optional. Relative path as array of folder names (not ids). If the path does not exist, the system will auto-create it."}},required:["wps_user_id","drive_id","name"]},execute:Ie("wps_airsheet_create_file",async(r,n)=>{let o=T(r,"drive_id"),i=T(r,"name"),s=V(r,"on_name_conflict"),a=V(r,"parent_id"),l=ut(r,"parent_path");if(s&&s!=="rename"&&s!=="fail")throw new Error("on_name_conflict must be 'rename' or 'fail'");let c={drive_id:o,name:i};s&&(c.on_name_conflict=s),a!==void 0&&(c.parent_id=a),l&&l.length>0&&(c.parent_path=l);let d=await n.request({method:"POST",path:"/v7/airsheet/files",body:c});return d.data??d})}),t({name:"wps_airsheet_create_worksheet",description:"Create a worksheet in a Smart Sheet (\u521B\u5EFA\u5DE5\u4F5C\u8868): POST `/v7/airsheet/{file_id}/worksheets`. Creates a new worksheet (tab) inside an existing smart sheet file. Required: `file_id`, `position` (object \u2014 at least one of `after_sheet_id`, `before_sheet_id`, or `end` must be set). Optional: `name` (worksheet name), `col_width` (default column width in pixels). Position rules: set `end: true` to append at the end; or use `after_sheet_id`/`before_sheet_id` (integer) to place relative to an existing sheet. Requires delegated OAuth with scope `kso.airsheet.readwrite`. Use SenderId as `wps_user_id`. Response includes `data.sheet_id` (integer).",parameters:{type:"object",properties:{wps_user_id:be,file_id:Oe,name:{type:"string",description:"Optional. Worksheet name."},col_width:{type:"number",description:"Optional. Default column width in pixels."},position:{type:"object",description:"Insertion position. Must provide at least one of: after_sheet_id (integer), before_sheet_id (integer), end (boolean, true = append).",properties:{after_sheet_id:{type:"integer",description:"Insert after this sheet id."},before_sheet_id:{type:"integer",description:"Insert before this sheet id."},end:{type:"boolean",description:"If true, append at the end."}}}},required:["wps_user_id","file_id","position"]},execute:Ie("wps_airsheet_create_worksheet",async(r,n)=>{let o=T(r,"file_id"),i=V(r,"name"),s=Y(r,"col_width"),a=r.position;if(!a||typeof a!="object")throw new Error("position is required and must be an object");let l=a,c={},d=Y(l,"after_sheet_id");d!==void 0&&(c.after_sheet_id=d);let p=Y(l,"before_sheet_id");p!==void 0&&(c.before_sheet_id=p);let u=ne(l,"end");u!==void 0&&(c.end=u);let _={position:c};i!==void 0&&(_.name=i),s!==void 0&&(_.col_width=s);let f=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets`,body:_});return f.data??f})}),t({name:"wps_airsheet_list_worksheets",description:"List worksheets in a Smart Sheet (\u83B7\u53D6 Sheet \u5217\u8868\u4FE1\u606F): GET `/v7/airsheet/{file_id}/worksheets`. Returns all worksheets (tabs) in the specified smart sheet file. Each sheet includes: `sheet_id` (integer), `name`, `index`, `hidden`, `empty`, `max_row`, `max_col`, `resource_type` (et = normal spreadsheet), and `active_area` (col_from, col_to, row_from, row_to \u2014 the editing region). Use this to discover `sheet_id` before reading/writing data. Requires delegated OAuth (`kso.airsheet.read` or `kso.airsheet.readwrite`). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Oe},required:["wps_user_id","file_id"]},execute:Ie("wps_airsheet_list_worksheets",async(r,n)=>{let o=T(r,"file_id"),i=await n.request({method:"GET",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets`});return i.data??i})}),t({name:"wps_airsheet_copy_worksheet",description:"Copy a worksheet (\u590D\u5236\u5DE5\u4F5C\u8868): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/copy`. Duplicates an existing worksheet within the same smart sheet file. Required: `file_id`, `worksheet_id` (integer, from `wps_airsheet_list_worksheets`). Optional: `copy_first_sheet` (boolean \u2014 if true, copies the first sheet regardless of `worksheet_id`). Requires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`. Response includes `data.sheet_id` (integer) \u2014 the new copied sheet's id.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Oe,worksheet_id:wt,copy_first_sheet:{type:"boolean",description:"Optional. If true, copies the first sheet."}},required:["wps_user_id","file_id","worksheet_id"]},execute:Ie("wps_airsheet_copy_worksheet",async(r,n)=>{let o=T(r,"file_id"),i=He(r,"worksheet_id"),s=ne(r,"copy_first_sheet"),a={};s!==void 0&&(a.copy_first_sheet=s);let l=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/copy`,body:a});return l.data??l})}),t({name:"wps_airsheet_update_worksheet",description:"Update a worksheet (\u66F4\u65B0\u5DE5\u4F5C\u8868): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/update`. Renames or moves a worksheet within the same smart sheet file. Required: `file_id`, `worksheet_id` (integer). Optional: `name` (new worksheet name), `move_sheet_id` (integer \u2014 reference sheet id for move), `move_type` (`sheet_move_type_before` | `sheet_move_type_after` \u2014 move before/after the reference sheet). Requires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`. Response: `{ code, msg }`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Oe,worksheet_id:wt,name:{type:"string",description:"Optional. New worksheet name."},move_sheet_id:{type:"integer",description:"Optional. Reference sheet id for repositioning."},move_type:{type:"string",enum:["sheet_move_type_before","sheet_move_type_after"],description:"Optional. Move before or after the reference sheet."}},required:["wps_user_id","file_id","worksheet_id"]},execute:Ie("wps_airsheet_update_worksheet",async(r,n)=>{let o=T(r,"file_id"),i=He(r,"worksheet_id"),s=V(r,"name"),a=Y(r,"move_sheet_id"),l=V(r,"move_type");if(l&&l!=="sheet_move_type_before"&&l!=="sheet_move_type_after")throw new Error("move_type must be 'sheet_move_type_before' or 'sheet_move_type_after'");let c={};s!==void 0&&(c.name=s),a!==void 0&&(c.move_sheet_id=a),l!==void 0&&(c.move_type=l);let d=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/update`,body:c});return d.data??d})}),t({name:"wps_airsheet_delete_worksheets",description:"Delete worksheets (\u5220\u9664\u5DE5\u4F5C\u8868): POST `/v7/airsheet/{file_id}/worksheets/batch_delete`. Batch-deletes one or more worksheets by their IDs. **This operation is irreversible.** Required: `file_id`, `worksheet_ids` (array of integers \u2014 sheet IDs from `wps_airsheet_list_worksheets`). Requires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`. Response: `{ code, msg }`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Oe,worksheet_ids:{type:"array",items:{type:"integer"},description:"Array of worksheet IDs (integers) to delete."}},required:["wps_user_id","file_id","worksheet_ids"]},execute:Ie("wps_airsheet_delete_worksheets",async(r,n)=>{let o=T(r,"file_id"),i=r.worksheet_ids;if(!Array.isArray(i)||i.length===0)throw new Error("worksheet_ids must be a non-empty array of integers");let s=i.map((l,c)=>{let d=typeof l=="number"?l:parseInt(String(l),10);if(!Number.isFinite(d)||d<0)throw new Error(`worksheet_ids[${c}] must be a non-negative integer`);return d}),a=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/batch_delete`,body:{worksheet_ids:s}});return a.data??a})}),t({name:"wps_airsheet_create_rows",description:"Create rows in a worksheet (\u521B\u5EFA\u884C): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/rows`. Inserts one or more rows with cell data into the specified worksheet. Required: `file_id`, `worksheet_id` (integer). Optional: `range_data` (array of cell objects). Each cell object can include: `col` (integer, 0-based column index), `formula` (string, cell formula or plain value), `op_type` (string, e.g. `cell_operation_type_formula`), `cell_pic_info` (object for image cells: `{ height, width, pic_content, tag }` where tag = `sheet_pic_type_local`). If `range_data` is omitted, an empty row is appended. Requires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`. Response: `{ code, msg }`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Oe,worksheet_id:wt,range_data:{type:"array",description:"Optional. Array of cell data objects. Each: { col: integer (0-based), formula?: string, op_type?: string, cell_pic_info?: { height: number, width: number, pic_content: string, tag: string } }.",items:{type:"object",properties:{col:{type:"integer",description:"0-based column index."},formula:{type:"string",description:"Cell formula or plain text value."},op_type:{type:"string",description:"Operation type, e.g. cell_operation_type_formula."},cell_pic_info:{type:"object",description:"Image cell info: { height, width, pic_content, tag }.",properties:{height:{type:"number"},width:{type:"number"},pic_content:{type:"string"},tag:{type:"string",description:"e.g. sheet_pic_type_local"}}}}}}},required:["wps_user_id","file_id","worksheet_id"]},execute:Ie("wps_airsheet_create_rows",async(r,n)=>{let o=T(r,"file_id"),i=He(r,"worksheet_id"),s={},a=r.range_data;if(a!=null){if(!Array.isArray(a))throw new Error("range_data must be an array");s.range_data=a}let l=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/rows`,body:s});return l.data??l})}),t({name:"wps_airsheet_get_range_data",description:"Get cell range data (\u83B7\u53D6\u5355\u5143\u683C\u9009\u533A\u6570\u636E): GET `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/range_data`. Reads cell values from a rectangular region defined by row/col indices (0-based). Required: `file_id`, `worksheet_id` (integer), `row_from`, `row_to`, `col_from`, `col_to` (all integers). Use `wps_airsheet_list_worksheets` first to get `sheet_id` and `active_area` for valid ranges. Response: `data.range_data` array of cell objects, each with: `cell_text` (display value), `col_from`, `col_to`, `row_from`, `row_to`, `is_cell_pic` (boolean), `num_format`, `original_cell_value` (formula bar value), `pic_content`, `pic_data` (image id for online files), `sha1` (image hash for local images), `tag`. Requires delegated OAuth (`kso.airsheet.read` or `kso.airsheet.readwrite`). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Oe,worksheet_id:wt,row_from:{type:"integer",description:"Start row index (0-based, inclusive)."},row_to:{type:"integer",description:"End row index (0-based, inclusive)."},col_from:{type:"integer",description:"Start column index (0-based, inclusive)."},col_to:{type:"integer",description:"End column index (0-based, inclusive)."}},required:["wps_user_id","file_id","worksheet_id","row_from","row_to","col_from","col_to"]},execute:Ie("wps_airsheet_get_range_data",async(r,n)=>{let o=T(r,"file_id"),i=He(r,"worksheet_id"),s=Y(r,"row_from"),a=Y(r,"row_to"),l=Y(r,"col_from"),c=Y(r,"col_to");if(s===void 0||a===void 0||l===void 0||c===void 0)throw new Error("row_from, row_to, col_from, col_to are all required");let d=await n.request({method:"GET",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/range_data`,query:{row_from:s,row_to:a,col_from:l,col_to:c}});return d.data??d})}),t({name:"wps_airsheet_find_cells",description:"Find cells in a worksheet (\u67E5\u627E\u5355\u5143\u683C): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/range_data/find`. Searches cells within a specified range using filter conditions, with optional pagination and deduplication. Required: `file_id`, `worksheet_id`, `filter` (object), `range` (object with row_from/row_to/col_from/col_to). Optional: `ignore_hidden_cell` (boolean, default false \u2014 skip hidden cells), `option_cols` (array of integers \u2014 column indices to get option/dropdown values for), `page` (object: { page: integer (min 1), page_size: integer (default 100) }), `show_total` (boolean, default false \u2014 include total count in response). \n\n**filter structure**: `{ condition: [{ col: integer, info: [{ value: string }], mode: 'filter_mode_and' | 'filter_mode_or' }], duplicates: { col: [integer] }, search: [{ col: integer, value: [string] }] }`. All sub-fields in filter are optional. \n\nResponse: `data.range_data` (matched cells), `data.merge_range_data` (merged cell data), `data.option_col` (option column results with texts/count), `data.result_type` (0=fail, 1=success), `data.total`. Requires delegated OAuth (`kso.airsheet.read` or `kso.airsheet.readwrite`). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Oe,worksheet_id:wt,filter:{type:"object",description:"Filter conditions. Structure: { condition?: [{ col: int, info: [{ value: string }], mode: 'filter_mode_and'|'filter_mode_or' }], duplicates?: { col: [int] }, search?: [{ col: int, value: [string] }] }."},range:{type:"object",description:"Search range (required). { row_from: int, row_to: int, col_from: int, col_to: int }.",properties:{row_from:{type:"integer",description:"Start row index (0-based)."},row_to:{type:"integer",description:"End row index (0-based)."},col_from:{type:"integer",description:"Start column index (0-based)."},col_to:{type:"integer",description:"End column index (0-based)."}},required:["row_from","row_to","col_from","col_to"]},ignore_hidden_cell:{type:"boolean",description:"Optional. If true, skip hidden cells. Default false."},option_cols:{type:"array",items:{type:"integer"},description:"Optional. Column indices to retrieve option/dropdown values for (relative to range)."},page:{type:"object",description:"Optional pagination. { page: integer (min 1), page_size: integer (default 100) }.",properties:{page:{type:"integer",description:"Page number, min 1."},page_size:{type:"integer",description:"Page size, default 100."}}},show_total:{type:"boolean",description:"Optional. If true, include total count in response. Default false."}},required:["wps_user_id","file_id","worksheet_id","filter","range"]},execute:Ie("wps_airsheet_find_cells",async(r,n)=>{let o=T(r,"file_id"),i=He(r,"worksheet_id"),s=r.filter;if(!s||typeof s!="object")throw new Error("filter is required and must be an object");let a=r.range;if(!a||typeof a!="object")throw new Error("range is required and must be an object");let l={filter:s,range:a},c=ne(r,"ignore_hidden_cell");c!==void 0&&(l.ignore_hidden_cell=c);let d=r.option_cols;if(d!=null){if(!Array.isArray(d))throw new Error("option_cols must be an array of integers");l.option_cols=d.map((f,g)=>{let y=typeof f=="number"?f:parseInt(String(f),10);if(!Number.isFinite(y)||y<0)throw new Error(`option_cols[${g}] must be a non-negative integer`);return y})}let p=r.page;if(p!=null){if(typeof p!="object")throw new Error("page must be an object");l.page=p}let u=ne(r,"show_total");u!==void 0&&(l.show_total=u);let _=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/range_data/find`,body:l});return _.data??_})}),t({name:"wps_airsheet_batch_update_cells",description:"Batch update cell range data (\u66F4\u65B0\u5355\u5143\u683C\u9009\u533A\u6570\u636E): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/range_data/batch_update`. Updates one or more cells in a worksheet. Each cell in `range_data` specifies its position (row_from, row_to, col_from, col_to) and operation type (`op_type`). \n\n**op_type values**: `cell_operation_type_formula` \u2014 set cell value/formula (use `formula` field), `cell_operation_type_picture` \u2014 set cell image (use `cell_pic_info` with height/width/pic_content/tag), `cell_operation_type_format` \u2014 set cell formatting (use `xf` field for styles), `cell_operation_type_merge` \u2014 merge cells (use `merge_type`: merge_type_center / merge_type_content / merge_type_same / merge_type_columns). \n\n**cell_pic_info.tag values**: `sheet_pic_type_local`, `sheet_pic_type_attachment`, `sheet_pic_type_url`. \n\n**xf (format) object** includes: `alc_h` (horizontal align), `alc_v` (vertical align), border colors (`clr_bottom/clr_top/clr_left/clr_right/clr_diag_down/clr_diag_up/clr_inside_horz/clr_inside_vert` \u2014 each `{tint,type,value}`), border styles (`dg_bottom/dg_top/dg_left/dg_right/dg_diag_down/dg_diag_up/dg_inside_horz/dg_inside_vert`), `fill` ({back:{tint,type,value}, fore:{tint,type,value}, type}), `font` ({bls,char_set,color:{tint,type,value},dy_height,italic,name,sss,strikeout,theme_font,uls}), `hidden`, `indent`, `locked`, `mask_cats`, `mask_cats_font`, `numfmt`, `reading_order`, `shrink_to_fit`, `trot`, `wrap`. \n\nRequires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`. Response: `{ code, msg }`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Oe,worksheet_id:wt,range_data:{type:"array",description:"Array of cell update objects. Each must include: row_from (int), row_to (int), col_from (int), col_to (int), op_type (string). Depending on op_type, also include: formula (string), cell_pic_info (object), merge_type (string), xf (format object).",items:{type:"object",properties:{row_from:{type:"integer",description:"Start row (0-based)."},row_to:{type:"integer",description:"End row (0-based)."},col_from:{type:"integer",description:"Start column (0-based)."},col_to:{type:"integer",description:"End column (0-based)."},op_type:{type:"string",enum:["cell_operation_type_formula","cell_operation_type_picture","cell_operation_type_format","cell_operation_type_merge"],description:"Cell operation type."},formula:{type:"string",description:"Cell value or formula (for op_type=formula)."},cell_pic_info:{type:"object",description:"Image info (for op_type=picture): { height, width, pic_content, tag }."},merge_type:{type:"string",enum:["merge_type_center","merge_type_content","merge_type_same","merge_type_columns"],description:"Merge type (for op_type=merge)."},xf:{type:"object",description:"Format/style object (for op_type=format). See tool description for full structure."}},required:["row_from","row_to","col_from","col_to","op_type"]}}},required:["wps_user_id","file_id","worksheet_id","range_data"]},execute:Ie("wps_airsheet_batch_update_cells",async(r,n)=>{let o=T(r,"file_id"),i=He(r,"worksheet_id"),s=r.range_data;if(!Array.isArray(s)||s.length===0)throw new Error("range_data must be a non-empty array");let a=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/range_data/batch_update`,body:{range_data:s}});return a.data??a})}),t({name:"wps_airsheet_batch_delete_cells",description:"Batch delete cell range data (\u5220\u9664\u5355\u5143\u683C\u9009\u533A\u6570\u636E): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/range_data/batch_delete`. Deletes data in specified cell ranges. Caller must ensure row/col indices are within the worksheet's max row/col limits (obtainable via getSheetInfo). \n\nRequired: `file_id`, `worksheet_id`, `range_data` (array of range objects, each with `col_from`, `col_to`, `row_from`, `row_to` \u2014 all integers, required). \n\nOptional: `shift_type` \u2014 how remaining cells shift after deletion. Values: `shift_up` (default, shift up) or `shift_left` (shift left). \n\nResponse: `{ code, msg }`. Requires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Oe,worksheet_id:wt,range_data:{type:"array",description:"Array of range objects to delete. Each must include col_from, col_to, row_from, row_to (all integers).",items:{type:"object",properties:{col_from:{type:"integer",description:"Start column index (0-based)."},col_to:{type:"integer",description:"End column index (0-based)."},row_from:{type:"integer",description:"Start row index (0-based)."},row_to:{type:"integer",description:"End row index (0-based)."}},required:["col_from","col_to","row_from","row_to"]}},shift_type:{type:"string",enum:["shift_up","shift_left"],description:"Optional. How remaining cells shift after deletion. Default: shift_up."}},required:["wps_user_id","file_id","worksheet_id","range_data"]},execute:Ie("wps_airsheet_batch_delete_cells",async(r,n)=>{let o=T(r,"file_id"),i=He(r,"worksheet_id"),s=r.range_data;if(!Array.isArray(s)||s.length===0)throw new Error("range_data must be a non-empty array");let a={range_data:s},l=V(r,"shift_type");l!==void 0&&(a.shift_type=l);let c=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/range_data/batch_delete`,body:a});return c.data??c})})}function xl(){return new Proxy({},{get(e,t,r){let n=tn(),o=Reflect.get(n,t,r);return typeof o=="function"?o.bind(n):o}})}function Rs(e){let t=[],r=o=>{e(()=>({name:o.name,label:o.name,description:o.description,parameters:o.parameters,async execute(s,a){let l=await o.execute(s,a);if(l&&typeof l=="object"&&"error"in l)throw new Error(l.error);return{content:[{type:"text",text:JSON.stringify(l,null,2)}],details:l}}}),{name:o.name}),t.push(o.name)},n=xl();return ri(n,r),ni(n,r),si(n,r),Vn(n,r),ci(n,r),li(n,r),ui(n,r),pi(n,r),_i(n,r),hi(n,r),gi(n,r),console.log(`[wps-xiezuo] OAPI tools registered: ${t.length} tools`),t.length}var vl={id:ze,name:"WPS Xiezuo",description:"WPS365 Open Platform channel plugin for OpenClaw",configSchema:Vi(),register(e){Qo(e.runtime);let t=e.logger??{info:()=>{},warn:()=>{},error:()=>{}};if(e.registerChannel({plugin:ei}),typeof e.registerTool=="function"){t.info(`[${ze}] registerTool is available (type: ${typeof e.registerTool})`);try{let r=Rs(e.registerTool);t.info(`[${ze}] registered ${r} WPS OAPI tool factories`)}catch(r){t.error(`[${ze}] tool registration failed: ${r}`)}}else t.warn(`[${ze}] registerTool not available (type: ${typeof e.registerTool})`);t.info(`[${ze}] plugin registered`)}},Hf=vl;export{Hf as default};
|
|
33
|
+
openclaw pairing approve --channel ${E} --account ${i} ${X}`;await dt(l,x,Bt)}}}return}if(!I){let A=a?.groupPolicy??"allowlist",X=a?.groups??{};if(A==="allowlist"&&!X[h]&&!X["*"]){r(`Group ${h} blocked by groupPolicy=allowlist`);return}}if(Se.trim()==="/wpsxiezuo auth"){let{sendAuthCard:A}=await Promise.resolve().then(()=>(Rr(),Fn)),{getLazyWpsCfg:X,getDelegatedScopes:le}=await Promise.resolve().then(()=>(ue(),Kt)),{getUserTokenEntry:Qe}=await Promise.resolve().then(()=>(Le(),Li)),{ensureDelegatedScopesFresh:Bt}=await Promise.resolve().then(()=>(at(),st));try{await Bt(i);let je=le(i),pr=Qe(i,m),Rs=new Set(pr?.grantedScopes??[]),Me=["**WPS \u6388\u6743\u72B6\u6001**",""];if(je.length===0)Me.push("\u5E94\u7528 delegated \u6743\u9650\uFF1A\uFF08\u672A\u83B7\u53D6\u6216\u4E3A\u7A7A\uFF09");else{Me.push(`\u5E94\u7528 delegated \u6743\u9650\uFF08\u5171 ${je.length} \u9879\uFF09\uFF1A`);for(let bi of je){let qs=Rs.has(bi.name)?"\u2705":"\u2B1C";Me.push(`${qs} ${bi.name}`)}}Me.push(""),pr?pr.grantedScopes===void 0?Me.push("\u7528\u6237 token\uFF1A\u5DF2\u6388\u6743\uFF08scope \u672A\u8BB0\u5F55\uFF0C\u65E7\u7248 token\uFF09"):Me.push(`\u7528\u6237 token\uFF1A\u5DF2\u6388\u6743\uFF08${pr.grantedScopes.length} \u9879 scope\uFF09`):Me.push("\u7528\u6237 token\uFF1A\u672A\u6388\u6743"),await dt(l,x,Me.join(`
|
|
34
|
+
`));let Cs=h?"chat":"user",Ds=h||m;await A({accountId:i,creds:l,wpsCfg:X(i),wpsUserId:m,receiverType:Cs,receiverId:Ds})||await dt(l,x,"\u5F53\u524D\u5E94\u7528\u6CA1\u6709\u53EF\u6388\u6743\u7684\u7528\u6237\u6743\u9650\uFF08delegated scopes \u4E3A\u7A7A\uFF09\uFF0C\u8BF7\u5148\u5728\u5F00\u653E\u5E73\u53F0\u540E\u53F0\u5F00\u901A\u3002")}catch(je){n("WPS /wpsxiezuo auth failed:",je),await dt(l,x,`\u6388\u6743\u5361\u7247\u53D1\u9001\u5931\u8D25\uFF1A${String(je)}`)}return}if(Se.trim()==="/wps-id"||Se.trim().startsWith("/wps-id ")){let A={sender:{id:p.id??"",type:p.type??"",name:p.name??""},chat:{id:u?.id??"",type:u?.type??""},message:{id:d.id??"",type:d.type??""},isDirect:I};await dt(l,x,`WPS id debug:
|
|
35
|
+
${JSON.stringify(A,null,2)}`);return}if(!s){r("WPS: channelRuntime not available \u2014 skipping AI dispatch");return}let P=s.reply,Ue=s.routing,Ne="main",me="",z=i;if(Ue?.resolveAgentRoute){let A=Ue.resolveAgentRoute({cfg:o,channel:E,accountId:i,peer:{kind:I?"direct":"group",id:g.session_key}});Ne=A.agentId,me=A.sessionKey?.trim()??"",A.accountId&&(z=A.accountId,r(`WPS route account override: ${i} -> ${A.accountId}`))}let B=me||g.session_key,mi=z;r(`WPS route: agentId=${Ne}, inboundSessionKey=${B}, accountId=${mi}`),W.length>0&&r(`WPS media context: MediaPath=${W[0]}, MediaType=${ne[0]}, count=${W.length}`);let hi={Body:yt,BodyForAgent:yt,...W.length>0?{MediaPath:W[0],MediaUrl:W[0],MediaType:ne[0],MediaPaths:W,MediaUrls:W,MediaTypes:ne}:{},RawBody:JSON.stringify({session:g,chatId:h,messageId:w,senderId:m,replyTarget:I?`user:${m}`:`chat:${h}`,messageType:b.kind,plainText:b.plainText,attachments:b.attachments,...F?{prefetchedMedia:F}:{},_idHint:"To reply, omit the 'to' parameter (framework auto-routes). To send to a DIFFERENT conversation, use replyTarget or 'chat:<chatId>' / 'user:<senderId>'. AK-prefixed strings are bot/app IDs, NOT chat IDs \u2014 never use them as receiver."}),CommandBody:yt,CommandAuthorized:!0,From:M,To:I?`user:${m}`:`chat:${h}`,ReplyTarget:I?`user:${m}`:`chat:${h}`,SessionKey:B,Label:B,ConversationLabel:B,DisplayName:B,SessionLabel:B,AccountId:mi,ChatType:I?"direct":"group",GroupId:void 0,SenderName:p.name??void 0,SenderId:m,Provider:E,Surface:"wps",Channel:E,Timestamp:c.send_time??Date.now(),OriginatingChannel:E,OriginatingFrom:`wps:${m}`,OriginatingTo:I?`user:${m}`:`chat:${h}`},gi=P.finalizeInboundContext?P.finalizeInboundContext(hi):hi,Ft=null;if(h&&w)try{await bn(l,h,w),Ft={kind:"reaction",chatId:h,messageId:w},r(`WPS thinking reaction added: chatId=${h}, messageId=${w}`)}catch(A){r(`WPS thinking reaction failed, falling back to text: ${String(A)}`);try{await dt(l,x,"\u6B63\u5728\u601D\u8003\u4E2D..."),Ft={kind:"text-fallback"}}catch(X){r(`WPS thinking fallback text failed: ${String(X)}`)}}let yi=!1,$s=async()=>{if(!(yi||Ft?.kind!=="reaction")){yi=!0;try{await In(l,Ft.chatId,Ft.messageId,t),r("WPS thinking reaction removed")}catch{}}},wi=()=>async(A,X)=>{let le=A.text??"";if(!le)return;let Qe=le.trim();if(/Message:.*[\\/](?:openclaw-media|wps-prefetch|\.openclaw[\\/]media)[\\/].*failed/i.test(Qe)){r(`WPS deliver: suppressed media-failed noise: ${Qe.substring(0,80)}`);return}r(`WPS deliver: text length=${le.length}, preview=${le.substring(0,80)}`),!I&&h&&w?await ad(l,h,w,le):await dt(l,x,le)};try{if(r(`WPS: starting dispatch (sessionKey=${B})`),P.dispatchReplyWithBufferedBlockDispatcher)await P.dispatchReplyWithBufferedBlockDispatcher({ctx:gi,cfg:o,dispatcherOptions:{deliver:wi(),responsePrefix:"",humanDelay:P.resolveHumanDelayConfig?P.resolveHumanDelayConfig(o,Ne):void 0,onError:(A,X)=>{n(`WPS ${X.kind} reply error: ${String(A)}`)}}}),r("WPS: agent dispatch completed");else if(P.dispatchReplyFromConfig&&P.createReplyDispatcherWithTyping){let A=P.resolveHumanDelayConfig?P.resolveHumanDelayConfig(o,Ne):void 0,{dispatcher:X,replyOptions:le,markDispatchIdle:Qe}=P.createReplyDispatcherWithTyping({responsePrefix:"",humanDelay:A,deliver:wi(),onError:(Bt,je)=>{n(`WPS ${je.kind} reply error: ${String(Bt)}`)}});try{await P.dispatchReplyFromConfig({ctx:gi,cfg:o,dispatcher:X,replyOptions:le})}finally{Qe()}r("WPS: agent dispatch completed (fallback path)")}else r("WPS: channelRuntime.reply dispatch APIs not found, skipping agent dispatch")}catch(A){n(`WPS dispatch failed: ${A instanceof Error?A.message:String(A)}`)}finally{await $s()}}catch($){n("WPS async inbound error:",$)}}ue();Le();Qt();import{createHash as dd}from"node:crypto";function se(e){return{error:e instanceof Error?e.message:String(e)}}function T(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function V(e,t){let r=e[t];if(r==null)return;if(typeof r!="string")throw new Error(`${t} must be a string`);let n=r.trim();return n===""?void 0:n}function Y(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function re(e,t){let r=e[t];if(r!=null){if(typeof r=="boolean")return r;if(r==="true")return!0;if(r==="false")return!1;throw new Error(`${t} must be a boolean`)}}function ct(e,t){let r=e[t];if(r!=null){if(!Array.isArray(r))throw new Error(`${t} must be an array of strings`);return r.map(n=>String(n).trim()).filter(Boolean)}}function ye(e,t="chat_id"){let r=T(e,t),n=r.startsWith("wps:")?r.slice(4):r;if(/^AK\d{8}/i.test(n))throw new Error(`${t}="${r}" is a bot/app ID (AK-prefixed), NOT a chat ID. The correct chat_id is a numeric ID like '77183700'. Look for chatId in RawBody JSON (parse the RawBody string first). Do NOT use values from From, OriginatingTo, SessionKey, or SenderId fields.`);if(n.includes(":")&&n.includes("AK"))throw new Error(`${t}="${r}" looks like a session_key or compound ID, NOT a chat ID. The correct chat_id is in RawBody.chatId (a numeric string like '77183700').`);return n}function Be(e,t){let r=e[t];if(r==null)throw new Error(`${t} is required`);let n=typeof r=="number"?r:parseInt(String(r),10);if(!Number.isFinite(n)||n<0)throw new Error(`${t} must be a non-negative integer`);return n}function cd(e){return dd("sha256").update(e).digest("hex")}var $o=20*1024*1024;function Hn(e){let t=e.trim();return!t||t.startsWith("http://")||t.startsWith("https://")?!1:!!(/^[a-zA-Z]:[\\/]/.test(t)||t.startsWith("\\\\")||t.startsWith("/tmp/")||t.startsWith("/var/folders/")||t.includes("openclaw-media")||t.includes("wps-prefetch")||t.includes(".openclaw/media")||t.includes(".openclaw\\media"))}function qo(e){let t=e.trim();return t.startsWith("http://")||t.startsWith("https://")?!1:t.includes("openclaw-media")||t.includes("wps-prefetch")||t.includes(".openclaw/media")||t.includes(".openclaw\\media")}function ld(e,t){let r={};for(let[n,o]of Object.entries(e)){if(typeof o!="string")continue;let i=n.trim();if(!i)continue;let s=i.toLowerCase();s==="transfer-encoding"||s==="content-length"||(r[i]=o)}return r}async function Uo(e,t,r,n,o){let i=o?.info??console.log,s=o?.error??console.error,a=n.byteLength;if(a===0)throw new Error("upload content is empty");if(a>$o)throw new Error(`file too large: ${a} bytes (max ${$o})`);let l=cd(n);i(`[upload] phase1 start: fileName=${t} fileType=${r} size=${a} checksum=${l.substring(0,16)}\u2026`);let c;try{c=await e.request({method:"POST",path:"/v7/chats/resources/upload",body:{file_name:t,file_size:a,file_type:r,checksum:l}})}catch(w){let b=w instanceof Error?w.message:String(w);throw s(`[upload] phase1 request failed: ${b}`),new Error(`upload phase 1 request failed: ${b}`)}let d=c.data??c;if(!d||typeof d!="object")throw new Error(`upload phase 1 returned no data: ${JSON.stringify(c).substring(0,300)}`);let p=d.data,u=p&&typeof p=="object"?p:d;i(`[upload] phase1 response keys: source=[${Object.keys(u)}] hasNested=${!!p}`);let _=u.upload_entry;_&&i(`[upload] upload_entry keys: [${Object.keys(_)}]`);let f=typeof u.url=="string"&&u.url.trim()?u.url.trim():typeof u.upload_url=="string"&&u.upload_url.trim()?u.upload_url.trim():_&&typeof _.url=="string"&&_.url.trim()?_.url.trim():null,g=typeof u.storage_key=="string"&&u.storage_key.trim()?u.storage_key.trim():null;if(!f)throw new Error(`upload phase 1 did not return an upload URL: keys=${JSON.stringify(Object.keys(u))}, raw=${JSON.stringify(d).substring(0,300)}`);if(!g)throw new Error(`upload phase 1 did not return a storage_key: keys=${JSON.stringify(Object.keys(u))}`);i(`[upload] phase1 ok: storageKey=${g.substring(0,20)}\u2026 uploadUrl=${f.substring(0,80)}\u2026`);let y=_&&typeof _.headers=="object"&&_.headers&&Object.keys(_.headers).length>0,m=ld(y?_.headers:{},f);i(`[upload] phase2 PUT headers: ${JSON.stringify(Object.keys(m))}`);let h;try{h=await fetch(f,{method:"PUT",headers:m,body:n})}catch(w){let b=w instanceof Error?w.message:String(w);throw s(`[upload] phase2 PUT network error: ${b} url=${f.substring(0,80)}\u2026`),new Error(`upload phase 2 PUT network error: ${b}`)}if(!h.ok){let w=await h.text().catch(()=>"");throw s(`[upload] phase2 PUT failed: HTTP ${h.status} body=${w.substring(0,300)}`),new Error(`upload phase 2 PUT failed: HTTP ${h.status} ${w.substring(0,200)}`)}return i(`[upload] phase2 PUT ok: HTTP ${h.status} storageKey=${g.substring(0,20)}\u2026`),{storage_key:g,file_name:t,file_size:a}}function Ro(e){return e.data??null}function Co(e){return{error:e instanceof Error?e.message:String(e)}}function Cr(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function pd(e){let t=e.trim();return!!(t.endsWith("=")||t.includes(":")&&t.length>30||/^[A-Za-z0-9+/]{40,}={0,2}$/.test(t))}function Do(e,t){if(e===t)throw new Error("message_id and storage_key are identical \u2014 this is wrong. message_id should be the message ID (from RawBody.messageId), not the storage_key. Please check the RawBody JSON for the correct messageId field.");if(pd(e))throw new Error(`message_id="${e.substring(0,30)}\u2026" looks like a storage_key (contains ':' or ends with '='). message_id should be the message ID from RawBody.messageId, not the attachment storage_key. These are different values \u2014 check the RawBody JSON.`)}function ud(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number when provided`)}}function Kn(e,t,r){let n=r?.info??(()=>{}),o=r?.error??(()=>{});t({name:"wps_media_download",description:"Obtain a pre-signed download URL for a message attachment. DO NOT call this tool if the file is already downloaded locally (Body shows '[\u5DF2\u4E0B\u8F7D\u56FE\u7247/\u6587\u4EF6: ... path=...]') \u2014 use message(media=<path>) instead. Only use for attachments NOT pre-downloaded (Body shows '[\u9644\u4EF6\u672A\u4E0B\u8F7D]'). chat_id and message_id come from RawBody JSON (chatId / messageId fields). message_id and storage_key are DIFFERENT values \u2014 do NOT pass storage_key as message_id.",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."},message_id:{type:"string",description:"Message id (from RawBody.messageId). NOT the storage_key."},storage_key:{type:"string",description:"Resource storage key from the attachment."}},required:["chat_id","message_id","storage_key"]},async execute(i,s){try{let a=ye(s),l=Cr(s,"message_id"),c=Cr(s,"storage_key");Do(l,c);let d=encodeURIComponent(a),p=encodeURIComponent(l),u=encodeURIComponent(c),_=await e.request({method:"GET",path:`/v7/chats/${d}/messages/${p}/resources/${u}/download`});return Ro(_)}catch(a){return Co(a)}}}),t({name:"wps_media_fetch_base64",description:"Fetch attachment bytes from WPS cloud and return base64. DO NOT call this tool if the file is already downloaded locally (Body shows '[\u5DF2\u4E0B\u8F7D\u56FE\u7247/\u6587\u4EF6: ... path=...]') \u2014 use message(media=<path>) instead. Only use this tool for attachments NOT pre-downloaded (Body shows '[\u9644\u4EF6\u672A\u4E0B\u8F7D]'). chat_id and message_id come from RawBody JSON (chatId / messageId fields). message_id and storage_key are DIFFERENT values \u2014 do NOT pass storage_key as message_id.",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."},message_id:{type:"string",description:"Message id (from RawBody.messageId). NOT the storage_key."},storage_key:{type:"string",description:"Resource storage key from the attachment."},max_bytes:{type:"number",description:"Optional max bytes limit for safety (default 5MB). If exceeded, tool returns an error."}},required:["chat_id","message_id","storage_key"]},async execute(i,s){try{let a=ye(s),l=Cr(s,"message_id"),c=Cr(s,"storage_key");Do(l,c);let d=encodeURIComponent(a),p=encodeURIComponent(l),u=encodeURIComponent(c),_=ud(s,"max_bytes")??5*1024*1024;if(_<=0)throw new Error("max_bytes must be positive");n(`[tool:wps_media_fetch_base64] start: chatId=${a} msgId=${l} sk=${c.substring(0,20)}\u2026`);let f=await e.request({method:"GET",path:`/v7/chats/${d}/messages/${p}/resources/${u}/download`}),g=Ro(f),y=hn(g),m=await fetch(y);if(!m.ok)throw new Error(`download url request failed: HTTP ${m.status}`);let h=Number(m.headers.get("content-length")??"0");if(Number.isFinite(h)&&h>_)throw new Error(`attachment too large: ${h} bytes > max_bytes=${_}`);let w=m.headers.get("content-type")??"application/octet-stream",b=new Uint8Array(await m.arrayBuffer());if(b.byteLength>_)throw new Error(`attachment too large after download: ${b.byteLength} bytes > max_bytes=${_}`);let I=w.startsWith("image/")?Et(Buffer.from(b)):null;return n(`[tool:wps_media_fetch_base64] ok: ${w} ${b.byteLength}B${I?` ${I.width}x${I.height}`:""}`),{chat_id:a,message_id:l,storage_key:c,mime_type:w,size:b.byteLength,base64:Buffer.from(b).toString("base64"),...I?{width:I.width,height:I.height}:{}}}catch(a){return o("[tool:wps_media_fetch_base64] error:",a),Co(a)}}})}Qt();var kd={Debug:0,Info:1,Warn:2,Error:3},Ct=null;function Vo(e){Ct=e}function xd(){if(!Ct)throw new Error("WPS plugin runtime not initialized");return Ct}var qr=new Map;function vd(e,t){let r=t.chat?.id?.trim(),n=t.message?.sender?.id?.trim()??t.sender?.id?.trim();return!r||!n?null:`wps:${e}:${r}:${n}`}function Td(e,t){let n=(qr.get(e)??Promise.resolve()).then(t,t);qr.set(e,n),n.finally(()=>{qr.get(e)===n&&qr.delete(e)})}var Nr="wps",Ko={id:E,label:"WPS",selectionLabel:"WPS365 (Open Platform)",docsPath:"/channels/wps-xiezuo",docsLabel:"WPS",blurb:"WPS365 Open Platform bot integration.",aliases:[E,Nr,"wps365"],order:70};function sr(e){let t=e.channels;if(t)return t[E]??t[Nr]}function Ge(e){return on(sr(e))}function Ed(){let e=Ur.join(bd(),".openclaw","openclaw.json");if(!yd(e))return null;try{let t=wd(e,"utf8");return t.trim()?JSON.parse(t):null}catch{return null}}function Jn(e){let t=e&&typeof e=="object"?e:null;if(t&&Object.keys(Ge(t)).length>0)return t;let r=Ct?.config&&typeof Ct.config=="object"?Ct.config:null;if(r&&Object.keys(Ge(r)).length>0)return r;let n=Ed();return n&&Object.keys(Ge(n)).length>0?n:t??r??n??{}}function ae(e){return hr(sr(e))}function we(e,t){let r=Ge(e);return r[t]??r[ae(e)]??r[he]}function Ad(e,t=he){let r=we(e,t);return{accountId:t,enabled:r?.enabled!==!1,configured:!!xe(r),config:r??{enabled:!1}}}function Xn(e){return e.trim().replace(/^wps-xiezuo:/i,"").replace(/^wps:/i,"")}function Od(e){return e.trim().length>0}var lt=/AK\d{8}/i;function or(e,t){if(lt.test(e))throw new Error(`to="${t}" contains a bot/app ID pattern ("${e}"). Omit the 'to' parameter to reply in the current conversation, or use 'chat:<RawBody.chatId>' (group) / 'user:<SenderId>' (DM).`)}function Jo(e){let t=e;return t.startsWith("wps-xiezuo:")?t=t.slice(11):t.startsWith("wps:")&&(t=t.slice(4)),t=t.replace(/:acct:[^:]+$/,""),t}function Yo(e){if(e.startsWith("user:")){let t=e.slice(5),r=Jo(t);return or(r,e),{type:"user",id:r}}if(e.startsWith("chat:")){let t=e.slice(5),r=Jo(t);return or(r,e),{type:"chat",id:r}}if(e.startsWith("wps:")||e.startsWith("wps-xiezuo:")){let t=e.match(/:group:([^:]+)/);if(t)return{type:"chat",id:t[1]};let r=e.match(/:p2p:([^:]+)/);if(r)return{type:"user",id:r[1]};let n=e.split(":");if(n.length===2){let a=n[1];return or(a,e),{type:"user",id:a}}let o=n[2]??n[1],s=n[3]??n[2]??n[n.length-1]??e;return or(s,e),{type:o==="group"?"chat":"user",id:s}}return or(e,e),{type:"user",id:e}}function Zo(e){return e.match(/:acct:([^:]+)/)?.[1]}function Xo(e,t,r){let n=r??Zo(t)??Gt()??ae(e),o=we(e,n),i=xe(o);if(!i)throw new Error(`WPS credentials not configured for account "${n}"`);return i}async function Vn(e,t,r){let n=R(e),o=C(e.baseUrl,n),i=Yo(t);return{messageId:(await o.request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:{type:i.type,receiver_id:i.id},content:{text:{content:r,type:"markdown"}}}})).data?.message_id??""}}var Yn={id:E,meta:{...Ko,aliases:[...Ko.aliases]},capabilities:{chatTypes:["direct","group"],media:!0,threads:!0,nativeCommands:!1,blockStreaming:!0},reload:{configPrefixes:[`channels.${E}`,`channels.${Nr}`]},configSchema:Gi(nn),messaging:{normalizeTarget:e=>e.trim(),targetResolver:{hint:"WPS target: user_id or chat_id (obfuscated string, case-sensitive)",looksLikeId:e=>e.trim().length>0}},config:{listAccountIds:e=>{let t=Jn(e),r=Object.keys(Ge(t));return r.length>0?r:[he]},resolveAccount:e=>{let t=Jn(e);return Ad(t,ae(t))},defaultAccountId:e=>{let t=Jn(e);return ae(t)},setAccountEnabled:({cfg:e,enabled:t})=>({...e,channels:{...e.channels,[E]:{...sr(e),accounts:{...Ge(e),[ae(e)]:{...we(e,ae(e))??{},enabled:t}}}}}),deleteAccount:({cfg:e})=>{let t={...e},r={...t.channels},n=sr(e);if(n){let o=ae(e),i={...Ge(e)};delete i[o],r[E]={...n,accounts:i}}else delete r[E],delete r[Nr];return t.channels=Object.keys(r).length>0?r:void 0,t},isConfigured:(e,t)=>!!xe(we(t,e.accountId)),describeAccount:e=>({accountId:e.accountId,enabled:e.enabled,configured:e.configured}),resolveAllowFrom:({cfg:e,accountId:t})=>{let r=e;return we(r,t??ae(r))?.allowFrom??[]},formatAllowFrom:({allowFrom:e})=>e.map(t=>Xn(String(t)))},security:{resolveDmPolicy:({cfg:e})=>{let t=e,r=ae(t),n=we(t,r);return{policy:n?.dmPolicy??"pairing",allowFrom:n?.allowFrom??[],policyPath:`channels.${E}.accounts.${r}.dmPolicy`,allowFromPath:`channels.${E}.accounts.${r}.allowFrom`,approveHint:Hi(E),normalizeEntry:Xn}},collectWarnings:({cfg:e})=>{let t=[],r=Ge(e);for(let[n,o]of Object.entries(r))o.dmPolicy==="open"&&t.push(`- WPS account '${n}' DMs are open to anyone. Set channels.${E}.accounts.${n}.dmPolicy="pairing" or "allowlist" for security.`),(o.groupPolicy??"allowlist")==="open"&&t.push(`- WPS account '${n}' groups: groupPolicy="open" allows any group to trigger. Set channels.${E}.accounts.${n}.groupPolicy="allowlist".`);return t}},pairing:{idLabel:"wpsUserId",normalizeAllowEntry:Xn,notifyApproval:async({cfg:e,id:t,accountId:r})=>{let n=e,o=we(n,r??ae(n)),i=xe(o);if(!i)throw new Error("WPS credentials not configured");await Vn(i,`user:${t}`,"Your pairing request has been approved. You can now chat with this bot.")}},groups:{resolveRequireMention:({cfg:e,groupId:t})=>{let r=e,n=we(r,ae(r));return!n?.groups||!t?!0:(n.groups[t]??n.groups["*"])?.requireMention??!0},resolveToolPolicy:()=>{}},outbound:{deliveryMode:"direct",textChunkLimit:5e3,chunker:(e,t)=>xd().channel.text.chunkMarkdownText(e,t),chunkerMode:"markdown",resolveTarget:({to:e,allowFrom:t})=>{let r=e?.trim()??"";if(r.startsWith("wps-xiezuo:")?r=r.slice(11):r.startsWith("wps:")&&(r=r.slice(4)),lt.test(r)){let o=r.match(/:acct:([^:]+)/),i=o?.[1]?`:acct:${o[1]}`:"",s=r.match(/:p2p:([^:]+)/);if(s?.[1]&&!lt.test(s[1]))return{ok:!0,to:`user:${s[1]}${i}`};let a=r.match(/:group:([^:]+)/);return a?.[1]&&!lt.test(a[1])?{ok:!0,to:`chat:${a[1]}${i}`}:{ok:!1,error:new Error(`recipient is not a valid target (bot/app ID "${r}" from stale session)`)}}if(r&&Od(r))return{ok:!0,to:r};let n=t?.[0];return n?{ok:!0,to:String(n).trim()}:{ok:!1,error:new Error("WPS target is required (user_id or chat_id)")}},sendText:async({cfg:e,to:t,text:r,accountId:n})=>{let i=Xo(e,t,n??void 0);return Vn(i,t,r)},sendMedia:async({cfg:e,to:t,mediaUrl:r,mimeType:n,accountId:o})=>{let s=Xo(e,t,o??void 0),a=R(s),l=C(s.baseUrl,a),c=Yo(t),d=(r??"").trim();if(!d)throw new Error("WPS sendMedia requires mediaUrl");let p,u,_=(n??"").trim()||"application/octet-stream",f=null;if(Hn(d)){let h=await Ho(d),w=Ur.basename(d)||"attachment";if(p=/^[0-9a-f]{8}_/.test(w)?w.substring(9):w,!(n??"").trim()){let I=Ur.extname(p).toLowerCase();_={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp",".pdf":"application/pdf",".html":"text/html",".htm":"text/html",".txt":"text/plain",".json":"application/json",".csv":"text/csv",".xml":"application/xml",".zip":"application/zip",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation"}[I]??"application/octet-stream"}u=h.byteLength;let b=!1;if(qo(d))try{let I=await Ho(d+$n,"utf8"),x=JSON.parse(I);x.v===1&&x.storage_key&&(d=x.storage_key,typeof x.width=="number"&&typeof x.height=="number"&&x.width>0&&x.height>0&&(f={width:x.width,height:x.height}),b=!0)}catch{}b||(d=(await Uo(l,p,_,h)).storage_key),!f&&_.startsWith("image/")&&(f=Et(h),console.log(`[${E}] sendMedia: parsed dimensions ${f?`${f.width}x${f.height}`:"(null)"} for ${p}`))}let g=_.startsWith("image/"),y={type:"file",receiver:{type:c.type,receiver_id:c.id},content:{file:{type:"local",local:{storage_key:d,...p?{name:p}:{},...u!==void 0?{size:u}:{}}}}},m={type:"image",receiver:{type:c.type,receiver_id:c.id},content:{image:{storage_key:d,..._.startsWith("image/")?{type:_}:{},...p?{name:p}:{},...u!==void 0?{size:u}:{},...f?{width:f.width,height:f.height}:{}}}};if(g)try{return await l.request({method:"POST",path:"/v7/messages/create",body:m})}catch(h){let w=h instanceof Error?h.message:String(h);throw console.error(`[${E}] sendMedia image failed: ${w} storageKey=${d.substring(0,30)}\u2026 displayName=${p}`),h}try{return await l.request({method:"POST",path:"/v7/messages/create",body:y})}catch(h){let w=h instanceof Error?h.message:String(h);if(!(/\b400\b/.test(w)||/InvalidMessage|invalid.*file_type/i.test(w)))throw console.error(`[${E}] sendMedia file failed (non-retryable): ${w}`),h;console.log(`[${E}] sendMedia file rejected (400), retrying as image: ${w} displayName=${p}`);try{return await l.request({method:"POST",path:"/v7/messages/create",body:m})}catch(I){let x=I instanceof Error?I.message:String(I);throw console.error(`[${E}] sendMedia image fallback also failed: ${x} displayName=${p}`),I}}}},status:{defaultRuntime:{accountId:he,running:!1,lastStartAt:null,lastStopAt:null,lastError:null},collectStatusIssues:e=>e.flatMap(t=>{let r=[];return t.enabled&&!t.configured&&r.push({channel:E,accountId:t.accountId,kind:"config",message:"WPS credentials not configured (appId and appSecret required).",fix:`Set channels.${E}.accounts.${t.accountId}.appId and channels.${E}.accounts.${t.accountId}.appSecret.`}),r}),buildChannelSummary:({snapshot:e})=>({configured:e.configured??!1,running:e.running??!1,lastStartAt:e.lastStartAt??null,lastStopAt:e.lastStopAt??null,lastError:e.lastError??null,probe:e.probe,lastProbeAt:e.lastProbeAt??null}),probeAccount:async({account:e})=>{let t=xe(e.config);if(!t)return{ok:!1,error:"Not configured"};try{return{ok:!0,token:(await R(t).getToken()).substring(0,8)+"..."}}catch(r){return{ok:!1,error:String(r)}}},buildAccountSnapshot:({account:e,runtime:t,probe:r})=>({accountId:e.accountId,enabled:e.enabled,configured:e.configured,running:t?.running??!1,lastStartAt:t?.lastStartAt??null,lastStopAt:t?.lastStopAt??null,lastError:t?.lastError??null,lastInboundAt:t?.lastInboundAt??null,lastOutboundAt:t?.lastOutboundAt??null,dmPolicy:e.config.dmPolicy??"pairing",probe:r})},gateway:{startAccount:async e=>{let t=we(e.cfg,e.accountId);if(!t?.enabled){e.log?.info?.(`[${e.accountId}] WPS provider disabled`);return}let r=xe(t);if(!r){e.log?.error?.(`[${e.accountId}] WPS credentials not configured`);return}let n=async()=>{},o=a=>{let l=vd(e.accountId,a),c=()=>ur(e.accountId,()=>Gn({cfg:e.cfg,accountId:e.accountId,channelRuntime:e.channelRuntime??void 0,wpsCfg:t,creds:r,eventPayload:a,log:e.log})).catch(d=>e.log?.error?.("WPS inbound handler error:",d));l?Td(l,c):c()},i=!1;if(t.sdk?.enabled)try{let a=Id,l=Sd,c=kd,p={debug:c.Debug,warn:c.Warn,error:c.Error}[t.sdk.logLevel??"info"]??c.Info,u=new l().onV7AppChatMessageCreate(async y=>{try{let m=y.parsedData;e.log?.info?.(`[WPS SDK][${e.accountId}/${r.clientId}] message: chat_id=${m.chat.id}, message_id=${m.message.id}`);let h=Yi(m);o(h)}catch(m){e.log?.error?.("WPS SDK message handler error:",m)}}).onV7AppGroupChatMemberRobotCreate(async y=>{let m=y.parsedData;if(e.log?.info?.(`[WPS SDK] robot joined group: chat_id=${m.chat_id}`),t.robotJoinGroupMessage!==void 0){let h=t.robotJoinGroupMessage||"\u4F60\u597D\uFF01\u6211\u662F AI \u52A9\u624B\uFF0C\u53EF\u4EE5\u5E2E\u52A9\u5927\u5BB6\u5904\u7406\u5404\u79CD\u95EE\u9898\u3002";try{let w=R(r);await C(r.baseUrl,w).request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:{type:"chat",receiver_id:m.chat_id},content:{text:{content:h,type:"markdown"}}}})}catch(w){e.log?.error?.("WPS welcome message failed:",w)}}}).onV7AppGroupChatMemberRobotDelete(async y=>{e.log?.info?.(`[WPS SDK] robot left group: chat_id=${y.parsedData.chat_id}`)}).registerFallbackFunc(y=>{let m=null;if(y.parsedData&&typeof y.parsedData=="object")m=y.parsedData;else if(typeof y.data=="string"&&y.data)try{m=JSON.parse(y.data)}catch{}let h=m?Object.keys(m).join(","):"N/A";if(e.log?.info?.(`[WPS SDK] unhandled event: ${y.eventCode}, keys=${h}`),m&&e.log?.info?.(`[WPS SDK] event payload: ${JSON.stringify(m).slice(0,500)}`),m){let w=typeof m.code=="string"?m.code:typeof m.authorization_code=="string"?m.authorization_code:void 0,b=typeof m.state=="string"?m.state:void 0;if(w){let I=typeof m.user_id=="string"?m.user_id:void 0;e.log?.info?.(`[WPS SDK] Auth code detected: eventCode=${y.eventCode}, code=${w.slice(0,8)}..., state=${b??"(none)"}, userId=${I??"(none)"}`),(async()=>{try{let{handleAuthEvent:x}=await Promise.resolve().then(()=>(Rr(),Fn));await x({code:w,state:b??"",creds:r,wpsCfg:t,log:e.log,userId:I,accountId:e.accountId})}catch(x){e.log?.error?.(`[WPS SDK] Auth event handling failed: ${String(x)}`)}})()}}}),_=new a(Qi({appId:r.clientId,appSecret:r.clientSecret,dispatcher:u,logLevel:p,endpoint:t.sdk.endpoint},t.sdk));_.start().catch(y=>{e.log?.error?.("WPS SDK client.run ended:",y)});let f=t.sdk.connectTimeoutMs??2e4,g=Date.now()+f;for(;Date.now()<g&&!_.isConnected();)await new Promise(y=>setTimeout(y,150));if(_.isConnected()){i=!0,e.log?.info?.("[WPS SDK] long connection established");let y=()=>_.stop();e.abortSignal.addEventListener("abort",y),n=async()=>{e.abortSignal.removeEventListener("abort",y),_.stop()}}else _.stop(),e.log?.warn?.(`[WPS SDK] connect timeout (${f}ms), falling back to Webhook`)}catch(a){e.log?.warn?.(`[WPS SDK] init failed: ${String(a)}, falling back to Webhook`)}if(!i){let a=await import("express"),l=(a.default||a)();l.use(a.json());let c=t.webhook?.port??3e3,d=t.webhook?.path??"/wps/webhook",p=t.enableEncryption!==!1;l.post(d,(_,f)=>{let g=Zi(_.body,{appId:r.clientId,appSecret:r.clientSecret},p,e.log);if("challenge"in g){f.status(200).json({challenge:g.challenge});return}if(!g.ok){let y=g.status??200;y===200?f.status(200).json({code:0,msg:"ok"}):f.status(y).json({code:-1,msg:g.error});return}f.status(200).json({code:0,msg:"ok"}),o(g.payload)});let u=l.listen(c,()=>{e.log?.info?.(`[${e.accountId}] WPS webhook listening on :${c}${d}`)});n=async()=>{u&&(u.close(),u=null)}}let s=i?"sdk":"webhook";e.setStatus({accountId:e.accountId,running:!0,lastStartAt:Date.now(),mode:s}),e.log?.info?.(`[${e.accountId}] WPS channel started (mode=${s})`);try{let a=R(r),l=C(r.baseUrl,a);fr(e.accountId,{client:l,log:e.log??null,wpsCfg:t,creds:r}),gr(e.accountId,{appId:r.clientId,appSecret:r.clientSecret,baseUrl:r.baseUrl}),Sr(e.accountId);let c=hr(sr(e.cfg));e.accountId===c&&Zr(e.accountId),e.log?.info?.(`[${e.accountId}] WPS client initialized for OAPI tools`);try{let p=((await l.request({method:"GET",path:`/v7/developer/apps/${encodeURIComponent(r.clientId)}`,query:{lang:"zh-CN"}})).data?.scopes??[]).filter(g=>g.auth_types?.includes("delegated")).map(g=>({name:g.name??"",description:g.description??""})).filter(g=>g.name);rt(e.accountId,p),e.log?.info?.(`[${e.accountId}] Delegated scopes: ${p.map(g=>g.name).join(", ")||"(none)"}`);let{detectScopeChanges:u}=await Promise.resolve().then(()=>(Go(),Bo)),_=u(e.accountId,p.map(g=>g.name));_.added.length>0&&e.log?.info?.(`[${e.accountId}] Delegated scopes ADDED since last startup: ${_.added.join(", ")}`),_.removed.length>0&&e.log?.info?.(`[${e.accountId}] Delegated scopes REMOVED since last startup: ${_.removed.join(", ")}`);let{markDelegatedScopeCacheFresh:f}=await Promise.resolve().then(()=>(at(),st));f(e.accountId),e.log?.info?.(`[${e.accountId}] Delegated scope on-demand cache enabled (30s TTL)`)}catch(d){rt(e.accountId,[]);let p=String(d);p.includes("invalid_scope")?e.log?.info?.(`[${e.accountId}] Delegated scopes unavailable (invalid_scope). OAuth \u6388\u6743\u5361\u7247\u80FD\u529B\u4E0D\u53EF\u7528\uFF0C\u4F46\u4E0D\u5F71\u54CD\u666E\u901A\u6D88\u606F\u6536\u53D1\u3002`):e.log?.warn?.(`[${e.accountId}] Failed to fetch delegated scopes: ${p}`)}}catch(a){e.log?.error?.(`[${e.accountId}] WPS client init failed:`,a)}return Ki(e.abortSignal,n)}},onboarding:{channel:E,getStatus:async({cfg:e})=>{let t=e,r=we(t,ae(t)),n=!!xe(r);return{channel:E,configured:n,statusLines:[`WPS: ${n?"configured":"needs appId and appSecret"}`],selectionHint:n?"configured":"needs credentials",quickstartScore:n?2:1}},configure:async({cfg:e})=>({cfg:e})},agentPrompt:{messageToolHints:()=>["- WPS targeting: omit `to` to reply in the current conversation (framework auto-routes to the correct chat/user). To send to a **different** conversation, use `message(action=send, to=chat:<chat_id>, message=...)`.","- To find a chat by name, use `wps_chat_find_by_name` first, then use the returned chat_id as `to=chat:<chat_id>`.","- AK-prefixed strings (e.g. AK12345678) are bot/app IDs \u2014 NEVER use them as chat_id, receiver_id, or `to` values.","- IMPORTANT: User-sent images/files are auto-downloaded to local paths (shown in the conversation body). To send back / forward / download for the user, use `message(action=send, media=<local_path>)`. NEVER call wps_media_fetch_base64 or wps_media_download for already-downloaded files \u2014 they will fail because the correct chat_id is NOT available as a top-level context field."]},actions:{describeMessageTool:()=>({actions:["send"]}),handleAction:e=>{let t=e.cfg,r=e.params.to??e.params.target??e.params.receiver_id,n=r&&typeof r=="string"?r.trim():"",o=Zo(n),i=e.accountId||o||ae(t);return ur(i,async()=>{if(e.action!=="send")throw new Error(`WPS does not support action: ${e.action}`);let s=e.params.message??e.params.text??e.params.content,a=e.params.media,l=we(t,i),c=xe(l);if(!c)throw new Error("WPS credentials not configured");let d=r&&typeof r=="string"&&r.trim()?r.trim():"";if(d.startsWith("wps-xiezuo:")?d=d.slice(11):d.startsWith("wps:")&&(d=d.slice(4)),lt.test(d)){let u=d.match(/:acct:([^:]+)/),_=u?.[1]?`:acct:${u[1]}`:"",f=d.match(/:p2p:([^:]+)/);if(f?.[1]&&!lt.test(f[1]))d=`user:${f[1]}${_}`;else{let g=d.match(/:group:([^:]+)/);if(g?.[1]&&!lt.test(g[1]))d=`chat:${g[1]}${_}`;else{let y=Un(i);if(y)d=y.isDirect?`user:${y.senderId}`:`chat:${y.chatId}`;else return console.warn(`[WPS handleAction] to="${r}" contains a bot/app ID pattern, no inbound context to auto-correct.`),{text:"\u53D1\u9001\u5931\u8D25\uFF1A\u76EE\u6807\u5730\u5740\u65E0\u6548\u3002\u8BF7\u7701\u7565 to \u53C2\u6570\u4EE5\u81EA\u52A8\u56DE\u590D\u5F53\u524D\u4F1A\u8BDD\uFF0C\u6216\u4F7F\u7528 chat:<chatId> / user:<userId> \u6307\u5B9A\u76EE\u6807\u3002"}}}}if(!d){let u=Un(i);u&&(d=u.isDirect?`user:${u.senderId}`:`chat:${u.chatId}`)}if(a&&typeof a=="string"&&a.trim()){let u=a.trim();if(Hn(u)){if(!d)throw new Error("WPS send with media requires 'to' (e.g. 'user:<id>' or 'chat:<id>')");return await Yn.outbound.sendMedia({cfg:e.cfg,to:d,mediaUrl:u,mimeType:void 0}),{text:`Media sent (${Ur.basename(u)||"attachment"})`}}}if(!d)throw new Error("WPS send requires 'to' (e.g. 'user:<id>' or 'chat:<id>')");if(!s||typeof s!="string"||!s.trim())throw new Error("WPS send requires 'message' or 'text'");return{text:`Message sent (id: ${(await Vn(c,d,s.trim())).messageId})`}})}}};ue();function jr(e){return e.data??null}function Mr(e){return{error:e instanceof Error?e.message:String(e)}}function He(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function Zn(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function Pd(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}function Qo(e){try{return JSON.parse(e)}catch{throw new Error("content must be valid JSON matching the WPS message content structure")}}function $d(e,t){if(e==="file"){let r=t.file;if(!r){let n=t.storage_key;if(n)return{file:{type:"local",local:{storage_key:n,...t.name?{name:t.name}:{},...t.size!==void 0?{size:t.size}:{}}}};throw new Error(`file content must contain a 'file' object. Required structure: {"file":{"type":"local","local":{"storage_key":"..."}}}`)}if(r.type||(r.type="local"),r.type==="local"&&!r.local){let n=r.storage_key;if(n)r.local={storage_key:n,...r.name?{name:r.name}:{},...r.size!==void 0?{size:r.size}:{}},delete r.storage_key,delete r.name,delete r.size;else throw new Error(`file.local is required for type='local'. Expected: {"file":{"type":"local","local":{"storage_key":"..."}}}`)}return t}if(e==="image"){if(!t.image){let n=t.storage_key;if(n)return{image:{storage_key:n,...typeof t.width=="number"?{width:t.width}:{},...typeof t.height=="number"?{height:t.height}:{}}};throw new Error(`image content must contain an 'image' object. Required structure: {"image":{"storage_key":"..."}}`)}return t}return t}function es(e){let t=e.text;t&&typeof t=="object"&&!t.type&&(t.type="plain")}function Rd(e,t){if(e==="text"){try{let n=JSON.parse(t);if(n&&typeof n=="object"&&"text"in n)return es(n),{type:"text",content:n}}catch{}return{type:"text",content:{text:{content:t,type:"markdown"}}}}let r=Qo(t);if(typeof r!="object"||r===null)throw new Error(`content for ${e} must be a JSON object (message content subtree)`);return e==="rich_text"?{type:"rich_text",content:r}:{type:"image",content:r}}function Qn(e,t){t({name:"wps_message_send",description:`Send a message to any WPS user or chat via OpenAPI. IMPORTANT: When the user asks to send a message to someone or to a chat/group, use THIS tool. If the user provides a chat name instead of an ID, call wps_chat_find_by_name first to resolve the chat_id, then call this tool with receiver_type='chat'. receiver_type: 'user' (for P2P/DM by user_id) or 'chat' (for group/chat by chat_id). receiver_id MUST be the real WPS chat id or user id (numeric/string id from the WPS API). For replies in the current conversation, read inbound RawBody JSON \`chatId\` and \`SenderId\`: use receiver_type='chat' + receiver_id=chatId when chatId is present, else receiver_type='user' + receiver_id=SenderId. NEVER use SessionKey segments after ':bot:' (often looks like AK\u2026) as receiver_id \u2014 that is a bot/app id, not a chat id, and causes invalid chatId / deMixValue errors. Text: msg_type='text', content='{"text":{"content":"hello","type":"markdown"}}'. Image/File: PREFERRED method is message(action='send', media='<local_path>') which handles upload automatically. If you already have a storage_key: Image msg_type='image', content='{"image":{"storage_key":"...","width":W,"height":H}}'. File msg_type='file', content='{"file":{"type":"local","local":{"storage_key":"...","name":"filename.ext"}}}'. CRITICAL: cloud documents (type=cloud) CANNOT be sent or forwarded via this API. To share a cloud doc with the user, use msg_type='text' and include the link URL in the text content. NEVER attempt to send cloud files with msg_type='file' or msg_type='image' \u2014 it will always fail.`,parameters:{type:"object",properties:{receiver_type:{type:"string",enum:["user","chat"],description:"Target kind: `user` opens or uses p2p with that user id; `chat` sends to a chat id."},receiver_id:{type:"string",description:"WPS user id or chat id from the API (not SessionKey `:bot:` segment). For the active thread, prefer RawBody `chatId` or user id."},msg_type:{type:"string",enum:["text","rich_text","image","file"],description:"WPS message type field sent as `type` in the API body."},content:{type:"string",description:"JSON string for the WPS message `content` object (structure depends on msg_type)."},mentions:{type:"array",description:"Optional mention list for group messages.",items:{type:"object",additionalProperties:!0}}},required:["receiver_type","receiver_id","msg_type","content"]},async execute(r,n){try{let o=He(n,"receiver_type");if(o!=="user"&&o!=="chat")throw new Error("receiver_type must be 'user' or 'chat'");let i=He(n,"receiver_id");if(i.startsWith("wps-xiezuo:")?i=i.slice(11):i.startsWith("wps:")&&(i=i.slice(4)),/AK\d{8}/i.test(i))throw new Error(`receiver_id="${n.receiver_id}" contains a bot/app ID pattern ("${i}"). Omit the 'to' parameter in the message tool to reply in the current conversation, or use receiver_type='user' with SenderId, or receiver_type='chat' with RawBody.chatId.`);if(i.includes(":"))throw new Error(`receiver_id="${n.receiver_id}" looks like a session key or compound ID, NOT a receiver ID. Use a bare numeric ID from RawBody.chatId (group) or SenderId (DM).`);let s=He(n,"msg_type");if(!["text","rich_text","image","file"].includes(s))throw new Error("msg_type must be one of: text, rich_text, image, file");let a=He(n,"content");if(a.length>5e3)throw new Error("content JSON string exceeds 5000 characters");let l=Qo(a);if(typeof l!="object"||l===null)throw new Error("parsed content must be a JSON object");let c=s==="file"||s==="image"?$d(s,l):l;s==="text"&&es(c);let d={type:s,receiver:{type:o,receiver_id:i},content:c},p=n.mentions;if(p!==void 0){if(!Array.isArray(p))throw new Error("mentions must be an array when provided");d.mentions=p}let u=await e.request({method:"POST",path:"/v7/messages/create",body:d});return jr(u)}catch(o){return Mr(o)}}}),t({name:"wps_message_reply",description:"Reply to an existing message in a chat (POST /v7/chats/{chat_id}/messages/{message_id}/reply). Use this to reply in-thread to a specific message. For sending NEW messages (not replies), use wps_message_send instead. Supports msg_type text, rich_text, or image. For text, content can be plain text or JSON content object.",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."},message_id:{type:"string",description:"Message id to reply to (from RawBody.messageId)."},msg_type:{type:"string",enum:["text","rich_text","image"],description:"Reply payload type."},content:{type:"string",description:"For text: plain string or JSON string of `content`. For rich_text/image: JSON string of the `content` subtree."}},required:["chat_id","message_id","msg_type","content"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=encodeURIComponent(He(n,"message_id")),s=He(n,"msg_type");if(s!=="text"&&s!=="rich_text"&&s!=="image")throw new Error("msg_type must be text, rich_text, or image");let a=He(n,"content"),l=Rd(s,a),c=await e.request({method:"POST",path:`/v7/chats/${o}/messages/${i}/reply`,body:l});return jr(c)}catch(o){return Mr(o)}}}),t({name:"wps_message_list",description:"List messages in a chat (GET /v7/chats/{chat_id}/messages). page_size defaults to 50. `start_time` and `end_time` are Unix timestamps in **seconds** (converted to milliseconds for the API). Returns paginated message list; use page_token for next pages.",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."},start_time:{type:"number",description:"Optional inclusive range start (Unix seconds); sent as start_time query in ms."},end_time:{type:"number",description:"Optional inclusive range end (Unix seconds); sent as end_time query in ms."},page_size:{type:"number",description:"Page size (default 50, max 100)."},page_token:{type:"string",description:"Pagination cursor from a previous response."}},required:["chat_id"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=Zn(n,"start_time"),s=Zn(n,"end_time"),a=Zn(n,"page_size")??50,l=Pd(n,"page_token"),c={page_size:a};l!==void 0&&(c.page_token=l),i!==void 0&&(c.start_time=Math.trunc(i*1e3)),s!==void 0&&(c.end_time=Math.trunc(s*1e3));let d=await e.request({method:"GET",path:`/v7/chats/${o}/messages`,query:c});return jr(d)}catch(o){return Mr(o)}}}),t({name:"wps_message_get",description:"Fetch a single message by id within a chat (GET /v7/chats/{chat_id}/messages/{message_id}).",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."},message_id:{type:"string",description:"Message id (from RawBody.messageId)."}},required:["chat_id","message_id"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=encodeURIComponent(He(n,"message_id")),s=await e.request({method:"GET",path:`/v7/chats/${o}/messages/${i}`});return jr(s)}catch(o){return Mr(o)}}})}function ts(e){return e.data??null}function rs(e){return{error:e instanceof Error?e.message:String(e)}}function Cd(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function Dd(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function qd(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}var Ud=["active"],Nd=["user_name","email","phone"],jd=["company_user"],Md=50;function ei(e,t){t({name:"wps_user_get",description:"Get the current authenticated bot/app user profile (GET /v7/users/current). Returns fields such as id, user_name, avatar, and company_id when exposed by the API.",parameters:{type:"object",properties:{},required:[]},async execute(r,n){try{let o=await e.request({method:"GET",path:"/v7/users/current"});return ts(o)}catch(o){return rs(o)}}}),t({name:"wps_user_search",description:"Search company users by keyword (GET /v7/users/search). Always applies status=active, search_field=user_name+email+phone, and search_source=company_user. page_size defaults to 50 (WPS API requires this field). Returns a paginated user list; use page_token for next pages. If no results found, suggest the user refine the keyword or try email/phone.",parameters:{type:"object",properties:{keyword:{type:"string",description:"Search keyword (name, email fragment, phone, etc.)."},page_size:{type:"number",description:"Page size (default 50, max 100)."},page_token:{type:"string",description:"Pagination token from a prior call."}},required:["keyword"]},async execute(r,n){try{let o=Cd(n,"keyword"),i=Dd(n,"page_size")??Md,s=qd(n,"page_token"),a={keyword:o,status:[...Ud],search_field:[...Nd],search_source:[...jd],page_size:i};s!==void 0&&(a.page_token=s);let l=await e.request({method:"GET",path:"/v7/users/search",query:a});return ts(l)}catch(o){return rs(o)}}})}function ar(e){return e.data??null}function Dt(e){return{error:e instanceof Error?e.message:String(e)}}function ns(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function is(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function ti(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}var os=50;function Wd(e,t){let r=e[t];if(!Array.isArray(r)||r.length===0)throw new Error(`${t} must be a non-empty array of user id strings`);let n=[];for(let o=0;o<r.length;o++){let i=r[o];if(typeof i!="string"||!i.trim())throw new Error(`${t}[${o}] must be a non-empty string`);n.push(i.trim())}return n}function ri(e,t="user"){return{id:e,type:t}}var Wr=null;async function Ld(e){if(Wr)return Wr;let r=(await e.request({method:"GET",path:"/v7/users/current"})).data;if(!r||typeof r.id!="string"||!r.id.trim())throw new Error("Cannot retrieve current operator identity from /v7/users/current. Ensure the app has kso.user_base.read permission.");return Wr={id:r.id.trim(),type:"user"},Wr}function ni(e,t){t({name:"wps_chat_create",description:"Create a p2p or group chat (POST /v7/chats/create). For P2P: provide exactly 2 user ids in member_ids (no auto-injection). For group: provide other member user ids; the current operator is auto-included and becomes owner. Requires kso.chat.readwrite permission.",parameters:{type:"object",properties:{type:{type:"string",enum:["p2p","group"],description:"Chat kind: p2p or group."},member_ids:{type:"array",items:{type:"string"},description:"For P2P: exactly 2 user ids. For group: other member ids (operator auto-included)."},name:{type:"string",description:"Group chat display name (only for group type)."}},required:["type","member_ids"]},async execute(r,n){try{let o=ns(n,"type");if(o!=="p2p"&&o!=="group")throw new Error("type must be 'p2p' or 'group'");let i=Wd(n,"member_ids"),s,a={type:o};if(o==="group"){let c=await Ld(e),d=new Set;s=[],d.add(c.id),s.push(ri(c.id));for(let u of i)d.has(u)||(s.push(ri(u)),d.add(u));a.owner_id=c.id;let p=ti(n,"name");p!==void 0&&p!==""&&(a.name=p)}else{let c=[...new Set(i)];if(c.length!==2)throw new Error(`P2P chat requires exactly 2 distinct user ids in member_ids. Got ${c.length} after dedup.`);s=c.map(d=>ri(d))}a.account_id_list=s;let l=await e.request({method:"POST",path:"/v7/chats/create",body:a});return ar(l)}catch(o){return Dt(o)}}}),t({name:"wps_chat_list",description:"List chats for the current context (GET /v7/chats). page_size defaults to 50. Returns paginated chat list; use page_token for next pages.",parameters:{type:"object",properties:{page_size:{type:"number",description:"Page size (default 50, max 100)."},page_token:{type:"string",description:"Pagination token from a prior call."}},required:[]},async execute(r,n){try{let o=is(n,"page_size")??os,i=ti(n,"page_token"),s={page_size:o};i!==void 0&&(s.page_token=i);let a=await e.request({method:"GET",path:"/v7/chats",query:s});return ar(a)}catch(o){return Dt(o)}}}),t({name:"wps_chat_get",description:"Get metadata for a single chat (GET /v7/chats/{chat_id}).",parameters:{type:"object",properties:{chat_id:{type:"string",description:"OAPI chat id (from RawBody.chatId)."}},required:["chat_id"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=await e.request({method:"GET",path:`/v7/chats/${o}`});return ar(i)}catch(o){return Dt(o)}}}),t({name:"wps_chat_members",description:"List members of a chat (GET /v7/chats/{chat_id}/members). page_size defaults to 50. Returns paginated member list; use page_token for next pages.",parameters:{type:"object",properties:{chat_id:{type:"string",description:"Chat session id."},page_size:{type:"number",description:"Page size (default 50, max 100)."},page_token:{type:"string",description:"Pagination token from a prior call."}},required:["chat_id"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=is(n,"page_size")??os,s=ti(n,"page_token"),a={page_size:i};s!==void 0&&(a.page_token=s);let l=await e.request({method:"GET",path:`/v7/chats/${o}/members`,query:a});return ar(l)}catch(o){return Dt(o)}}}),t({name:"wps_chat_is_member",description:"Check whether the current operator is a member of the chat (GET /v7/chats/{chat_id}/members/is_in_chat).",parameters:{type:"object",properties:{chat_id:{type:"string",description:"Chat session id."}},required:["chat_id"]},async execute(r,n){try{let o=encodeURIComponent(ye(n)),i=await e.request({method:"GET",path:`/v7/chats/${o}/members/is_in_chat`});return ar(i)}catch(o){return Dt(o)}}}),t({name:"wps_chat_find_by_name",description:"Find a WPS chat/group by name. IMPORTANT: When the user says 'send message to <group name>' or '\u7ED9 <\u7FA4\u540D> \u53D1\u6D88\u606F', ALWAYS call this tool first to resolve the chat_id, then use wps_message_send with receiver_type='chat' and the resolved chat_id. Returns matching chats with owner info for disambiguation. If multiple matches, present the list to the user for selection.",parameters:{type:"object",properties:{keyword:{type:"string",description:"Chat name keyword to search for."}},required:["keyword"]},async execute(r,n){try{let o=ns(n,"keyword").toLowerCase(),i=[],s,a=!1;for(let c=0;c<10;c++){let d={page_size:100};s&&(d.page_token=s);let p=await e.request({method:"GET",path:"/v7/chats",query:d});for(let u of p.data?.items??[])u.chat_id&&u.name?.toLowerCase().includes(o)&&i.push({chat_id:u.chat_id,name:u.name,owner_id:u.owner_id});if(!p.data?.has_more)break;if(s=p.data?.page_token,!s){a=!0;break}}let l={};return a&&(l.warning="Results may be incomplete: pagination was truncated due to missing page_token."),i.length===0?{...l,found:!1,message:`No chats found matching "${o}"`}:i.length===1?{...l,found:!0,match:i[0]}:{...l,found:!0,multiple:!0,matches:i,hint:"Multiple matches found. Present the list to the user with chat name and owner info for selection."}}catch(o){return Dt(o)}}})}Le();ue();Er();ze();Rr();jn();fn();yn();bt();function zd(e){if(e)return e;let t=Gt();if(t)return t;let r=Qr();if(r)return r;throw new Error("WPS accountId required: no explicit accountId, no ALS context, no default account set")}async function _e(e){let t=zd(e.accountId),r=e.toolModule?gn(e.toolModule):[];if(r.length>0){let{ensureDelegatedScopesFresh:s}=await Promise.resolve().then(()=>(at(),st));await s(t);let a=un({requiredScopes:r,accountId:t,wpsUserId:e.wpsUserId});if(!a.ok)switch(a.reason){case"app_scope_missing":return await Fd(t,e,a.message),{needsAppScope:!0,message:a.message};case"no_token":case"user_scope_insufficient":{if(a.appScopeVerified){let l=await Lr(t,e);return{needsAuth:!0,message:zr(l,a.message)}}return{needsAuth:!0,message:`${a.message} \u8BF7\u4F7F\u7528 /wpsxiezuo auth \u624B\u52A8\u6388\u6743\u3002`}}}}let n=ve(t,e.wpsUserId);if(!n){let s=await Lr(t,e);return{needsAuth:!0,message:zr(s,e.needsAuthMessage)}}let o=tt(t),i=mn(o.baseUrl,n);try{return await e.run(i,t)}catch(s){if(Xr(s)){br(t,e.wpsUserId);let{getDelegatedScopes:a}=await Promise.resolve().then(()=>(ue(),Kt));if(a(t).length>0){let l=await Lr(t,e);return{needsAuth:!0,message:zr(l,"token \u5DF2\u5931\u6548\uFF0C\u9700\u8981\u91CD\u65B0\u6388\u6743\u3002")}}return{needsAuth:!0,message:"token \u5DF2\u5931\u6548\uFF0C\u9700\u8981\u91CD\u65B0\u6388\u6743\u3002\u8BF7\u4F7F\u7528 /wpsxiezuo auth \u624B\u52A8\u6388\u6743\u3002"}}if(Jr(s)){wr(t,e.wpsUserId);let a=ie(t),{invalidateDelegatedScopeCache:l,ensureDelegatedScopesFresh:c}=await Promise.resolve().then(()=>(at(),st));l(t),await c(t);let{getDelegatedScopes:d}=await Promise.resolve().then(()=>(ue(),Kt)),p=d(t),u=new Set(p.map(f=>f.name)),_=r.filter(f=>!u.has(f));if(p.length>0&&_.length>0)return a?.info?.(`[${e.logTag}] 403 scope error: app missing scopes [${_.join(", ")}] \u2192 hint`),{needsAppScope:!0,message:`\u6743\u9650\u4E0D\u8DB3\uFF0C\u8BF7\u5728 WPS \u5F00\u653E\u5E73\u53F0\u7533\u8BF7\u5BF9\u5E94\u529F\u80FD\u6743\u9650\u3002${`\u9700\u8981\u7684\u6743\u9650\uFF1A${_.join(", ")}`}`};if(p.length>0){a?.info?.(`[${e.logTag}] 403 scope error: user scope revoked \u2192 sending auth card`);let f=await Lr(t,e);return{needsAuth:!0,message:zr(f,"\u6743\u9650\u4E0D\u8DB3\uFF0C\u9700\u8981\u91CD\u65B0\u6388\u6743\u3002")}}return a?.info?.(`[${e.logTag}] 403 scope error: delegated list empty after refresh \u2192 conservative, no auto card`),{needsAuth:!0,message:"\u6743\u9650\u4E0D\u8DB3\uFF0C\u8BF7\u4F7F\u7528 /wpsxiezuo auth \u624B\u52A8\u6388\u6743\u3002"}}throw s}}async function Lr(e,t){let r=t.messageId?`${e}:${t.wpsUserId}:${t.messageId}`:`${e}:${t.wpsUserId}`;if(Nn(r))return"cooldown";let n=!1;return await yo(r,async()=>{let o=tn(e),i=tt(e),s=ie(e);try{await zn({accountId:e,creds:i,wpsCfg:o,wpsUserId:t.wpsUserId,receiverType:"user",receiverId:t.wpsUserId,originalMessage:t.authCardOriginalMessage}),ho(r),n=!0}catch(a){s?.error?.(`[${t.logTag}] Failed to send auth card: ${String(a)}`)}}),n?"sent":"failed"}function zr(e,t){switch(e){case"sent":return t;case"cooldown":return`${t} \u6388\u6743\u5361\u7247\u5DF2\u53D1\u9001\uFF0C\u8BF7\u70B9\u51FB\u4E4B\u524D\u7684\u5361\u7247\u5B8C\u6210\u6388\u6743\u3002`;case"failed":return`${t} \u6388\u6743\u5361\u7247\u53D1\u9001\u5931\u8D25\uFF0C\u8BF7\u4F7F\u7528 /wpsxiezuo auth \u624B\u52A8\u6388\u6743\u3002`}}async function Fd(e,t,r){let n=tt(e),o=ie(e);try{let i=R(n);await C(n.baseUrl,i).request({method:"POST",path:"/v7/messages/create",body:{type:"text",receiver:{type:"user",receiver_id:t.wpsUserId},content:{text:{content:r,type:"markdown"}}}})}catch(i){o?.warn?.(`[${t.logTag}] Failed to send app scope hint: ${String(i)}`)}}var ss=31*24*60*60*1e3,Bd=100,as=200,ds=50,cs=100;function H(e){return{error:e instanceof Error?e.message:String(e)}}function O(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function v(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}function qt(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function Ut(e,t){let r=e[t];if(r!=null){if(typeof r=="boolean")return r;if(r==="true"||r==="false")return r==="true";throw new Error(`${t} must be a boolean`)}}function Gd(e,t){let r=e[t];if(r==null)throw new Error(`${t} is required and must be a finite number`);if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}function Fr(e,t){let r=new Date(t.trim());if(Number.isNaN(r.getTime()))throw new Error(`${e} must be a valid RFC3339 / ISO 8601 datetime string`);return r}function Nt(e){return e.toISOString()}function ii(e){let t=e.now??new Date,r,n,o=!!e.startRfc?.trim(),i=!!e.endRfc?.trim();if(o&&i?(r=Fr("start_time",e.startRfc),n=Fr("end_time",e.endRfc)):o?(r=Fr("start_time",e.startRfc),n=new Date(r.getTime()+14*86400*1e3)):i?(n=Fr("end_time",e.endRfc),r=new Date(n.getTime()-14*86400*1e3)):(r=new Date(t.getTime()-86400*1e3),n=new Date(t.getTime()+14*86400*1e3)),n.getTime()<r.getTime())throw new Error("end_time must be >= start_time (RFC3339 range)");return n.getTime()-r.getTime()>ss&&(n=new Date(r.getTime()+ss)),{start:r,end:n}}function Hd(e){let{start:t,end:r}=ii({startRfc:e.startRfc,endRfc:e.endRfc,now:e.now}),n={start_time:Nt(t),end_time:Nt(r)},o=e.pageSize??30;return n.page_size=Math.max(1,Math.min(500,Math.trunc(o))),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(n.page_token=e.pageToken.trim()),n}function Kd(e){let{start:t,end:r}=ii({startRfc:e.startRfc,endRfc:e.endRfc,now:e.now});return{start_time:Nt(t),end_time:Nt(r)}}function Jd(e){let t={},r=e.pageSize??30;if(t.page_size=Math.max(1,Math.min(500,Math.trunc(r))),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(t.page_token=e.pageToken.trim()),e.withCancelled===!0&&(t.with_cancelled=!0),e.syncToken!==void 0&&e.syncToken.trim()!==""&&(t.sync_token=e.syncToken.trim()),e.anchorTime!==void 0&&e.anchorTime.trim()!==""&&(t.anchor_time=e.anchorTime.trim()),t.sync_token)return t;let{start:n,end:o}=ii({startRfc:e.startRfc,endRfc:e.endRfc,now:e.now});return t.start_time=Nt(n),t.end_time=Nt(o),t}function Xd(e){let t=new Date(e.trim());if(Number.isNaN(t.getTime()))throw new Error("start_time must be a valid ISO 8601 datetime");return t.setTime(t.getTime()+60*60*1e3),t.toISOString()}function $e(e,t){return`/v7/calendars/${encodeURIComponent(e)}/events/${encodeURIComponent(t)}`}function Vd(e,t){return`${$e(e,t)}/respond`}function oi(e,t){return`${$e(e,t)}/attendees`}function Yd(e,t){return`${oi(e,t)}/batch_create`}function Zd(e,t){return`${oi(e,t)}/batch_delete`}function Qd(e,t){return`${$e(e,t)}/meeting_rooms`}function ec(e,t){return`${$e(e,t)}/meeting_rooms/batch_create`}function tc(e,t){return`${$e(e,t)}/meeting_rooms/batch_delete`}function ls(e){if(!Array.isArray(e)||e.length===0)throw new Error("room_ids is required and must be a non-empty array");let t=e.map((r,n)=>{if(typeof r!="string")throw new Error(`room_ids[${n}] must be a string`);let o=r.trim();if(!o)throw new Error(`room_ids[${n}] must be non-empty`);return o});if(t.length>cs)throw new Error(`room_ids length must be <= ${cs}`);return{room_ids:t}}function rc(e){let t=e.pageSize??30,n={page_size:Math.max(1,Math.min(Bd,Math.trunc(t)))};return e.pageToken!==void 0&&e.pageToken.trim()!==""&&(n.page_token=e.pageToken.trim()),n}function Ke(e){let t=v(e,"x_kso_id_type");if(t===void 0||t.trim()==="")return;let r=t.trim();if(r!=="internal"&&r!=="external")throw new Error("x_kso_id_type must be internal or external when provided");return{"X-Kso-Id-Type":r}}async function Z(e,t,r){try{return await _e({wpsUserId:e,toolModule:"calendar",authCardOriginalMessage:t,needsAuthMessage:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u64CD\u4F5C\u65E5\u7A0B\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u5B8C\u6210\u6388\u6743\u540E\u91CD\u8BD5\u3002",logTag:"calendar",run:r})}catch(n){return H(n)}}function si(e,t){t({name:"wps_calendar_create",description:"Create a calendar event for the current user via WPS OpenAPI. Requires user OAuth authorization. If the user has not authorized, an authorization card will be sent automatically. IMPORTANT: Use the SenderId from the current conversation context as wps_user_id. Do NOT call wps_user_search or wps_user_get to look up the user. If end_time is omitted, it defaults to start_time + 1 hour (computed as UTC ISO).",parameters:{type:"object",properties:{summary:{type:"string",description:"Event title."},start_time:{type:"string",description:"Start time in ISO 8601 with timezone (e.g. '2026-04-22T14:00:00+08:00')."},end_time:{type:"string",description:"End time in ISO 8601 with timezone. Omit to default to start_time + 1 hour."},description:{type:"string",description:"Optional event description."},location:{type:"string",description:"Optional event location."},wps_user_id:{type:"string",description:"WPS user ID. Use SenderId from the conversation context. Do NOT call wps_user_search or wps_user_get for this."}},required:["summary","start_time"]},async execute(o,i){try{let s=O(i,"summary"),a=O(i,"start_time"),l=v(i,"end_time"),c=l&&l.trim()!==""?l.trim():Xd(a),d=v(i,"description"),p=v(i,"location"),u=v(i,"wps_user_id")??"";return u?await Z(u,s,async _=>{let f={summary:s,start_time:{datetime:a},end_time:{datetime:c}};d&&(f.description=d),p&&(f.locations=[{name:p}]);let g=await _.request({method:"POST",path:"/v7/calendars/primary/events/create",body:f});return g.data??g}):H(new Error("wps_user_id is required. Use the SenderId from the conversation context."))}catch(s){return H(s)}}}),t({name:"wps_calendar_list_events",description:"List calendar events on the user's primary calendar: GET `/v7/calendars/primary/events` (same as `/v7/calendars/{calendar_id}/events` with calendar_id `primary`). Official doc: https://365.kdocs.cn/3rd/open/documents/app-integration-dev/wps365/server/calendar/calendar-event/get-calendar-event-list Requires user delegated OAuth (same as wps_calendar_create). Use SenderId as wps_user_id. Time range: `start_time` and `end_time` query params are **RFC3339 / ISO8601 strings** (not Unix seconds). If both are omitted, defaults to about last 24 hours through next 14 days, clamped to max 31-day span per API. If `sync_token` is set, incremental sync mode: only sync_token/page_token/page_size/with_cancelled are sent (no automatic time window). Optional: anchor_time (RFC3339), with_cancelled (boolean).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},start_time:{type:"string",description:"Optional range start (RFC3339 / ISO8601). Must be used with end_time for explicit window, or omit both for defaults."},end_time:{type:"string",description:"Optional range end (RFC3339 / ISO8601). API allows 0\u201331 days between start and end; longer ranges are truncated."},page_size:{type:"number",description:"Page size (default 30 per API doc, max 500 client-side cap)."},page_token:{type:"string",description:"Pagination cursor from data.next_page_token."},with_cancelled:{type:"boolean",description:"Include cancelled events (per API)."},sync_token:{type:"string",description:"Incremental sync token from data.next_sync_token; when set, time range is not auto-filled."},anchor_time:{type:"string",description:"Anchor time RFC3339 for incremental sync (per API)."}},required:["wps_user_id"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=v(i,"start_time"),l=v(i,"end_time"),c=qt(i,"page_size"),d=v(i,"page_token"),p=Ut(i,"with_cancelled"),u=v(i,"sync_token"),_=v(i,"anchor_time");return await Z(s,"\u67E5\u8BE2\u4E3B\u65E5\u5386\u65E5\u7A0B\u5217\u8868",async f=>{let g=Jd({startRfc:a,endRfc:l,pageSize:c,pageToken:d,withCancelled:p,syncToken:u,anchorTime:_}),y=await f.request({method:"GET",path:"/v7/calendars/primary/events",query:g});return y.data??y})}catch(s){return H(s)}}}),t({name:"wps_calendar_get_event",description:"Get **one** calendar event by id (official \u67E5\u8BE2\u65E5\u7A0B): GET `/v7/calendars/{calendar_id}/events/{event_id}`. Response `data` is a single event object (summary, recurrence, online_meeting, etc.), not `items[]`. Requires `event_id` from `wps_calendar_list_events` (or equivalent). Same delegated Bearer auth as `wps_calendar_create`. Optional `calendar_id` (default `primary`). Optional header `X-Kso-Id-Type`: pass `x_kso_id_type` as `internal` or `external` per API.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from the calendar event list API."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type` header: `internal` or `external` (per WPS API).",enum:["internal","external"]}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary";return await Z(s,"\u67E5\u8BE2\u65E5\u7A0B\u8BE6\u60C5",async c=>{let d=await c.request({method:"GET",path:$e(l,a),headers:Ke(i)});return d.data??d})}catch(s){return H(s)}}}),t({name:"wps_calendar_list_event_attendees",description:"List attendees for one calendar event (official \u83B7\u53D6\u65E5\u7A0B\u53C2\u4E0E\u8005\u5217\u8868): GET `/v7/calendars/{calendar_id}/events/{event_id}/attendees`. Response `data` typically has `items[]` and optional `next_page_token`. Requires `event_id` from `wps_calendar_list_events` or `wps_calendar_get_event`. Same delegated Bearer auth as `wps_calendar_create`. Optional `calendar_id` (default `primary`). Query: optional `page_size` (default 30, max 100 per API), `page_token` from `data.next_page_token`. Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from the calendar event list API."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},page_size:{type:"number",description:"Page size (default 30; API max 100)."},page_token:{type:"string",description:"Pagination cursor from data.next_page_token."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary",c=qt(i,"page_size"),d=v(i,"page_token");return await Z(s,"\u83B7\u53D6\u65E5\u7A0B\u53C2\u4E0E\u8005\u5217\u8868",async p=>{let u=rc({pageSize:c,pageToken:d}),_=await p.request({method:"GET",path:oi(l,a),query:u,headers:Ke(i)});return _.data??_})}catch(s){return H(s)}}}),t({name:"wps_calendar_add_event_attendees",description:"Batch add attendees to one event (official \u6DFB\u52A0\u65E5\u7A0B\u53C2\u4E0E\u8005): POST `/v7/calendars/{calendar_id}/events/{event_id}/attendees/batch_create`. Requires delegated OAuth (same as `wps_calendar_create`). Body requires `attendees` array (max 200 per request; total attendees per event max 1000). Each attendee item typically includes `type`, `user_id` or `third_party_email`, optional `is_optional` and `response_status`. Optional `is_notification` controls whether attendees receive invitation notifications (default true). Optional `calendar_id` (default `primary`). Optional `x_kso_id_type` maps to `X-Kso-Id-Type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from event list/search/get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},attendees:{type:"array",description:"Attendees to add in batch (required, max 200 per request). Each item supports fields like { type, user_id, third_party_email, is_optional, response_status }.",items:{type:"object",properties:{type:{type:"string"},user_id:{type:"string"},third_party_email:{type:"string"},is_optional:{type:"boolean"},response_status:{type:"string"}}}},is_notification:{type:"boolean",description:"Whether to notify added attendees (default true)."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id","attendees"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary",c=Ut(i,"is_notification"),d=i.attendees;if(!Array.isArray(d)||d.length===0)throw new Error("attendees is required and must be a non-empty array");if(d.length>as)throw new Error(`attendees length must be <= ${as}`);let p=d.map((u,_)=>{if(typeof u!="object"||u===null||Array.isArray(u))throw new Error(`attendees[${_}] must be an object`);let f=u,g={};if(f.type!==void 0){if(typeof f.type!="string"||!f.type.trim())throw new Error(`attendees[${_}].type must be a non-empty string when provided`);g.type=f.type.trim()}if(f.user_id!==void 0){if(typeof f.user_id!="string"||!f.user_id.trim())throw new Error(`attendees[${_}].user_id must be a non-empty string when provided`);g.user_id=f.user_id.trim()}if(f.third_party_email!==void 0){if(typeof f.third_party_email!="string"||!f.third_party_email.trim())throw new Error(`attendees[${_}].third_party_email must be a non-empty string when provided`);g.third_party_email=f.third_party_email.trim()}if(f.is_optional!==void 0){if(typeof f.is_optional!="boolean")throw new Error(`attendees[${_}].is_optional must be a boolean when provided`);g.is_optional=f.is_optional}if(f.response_status!==void 0){if(typeof f.response_status!="string"||!f.response_status.trim())throw new Error(`attendees[${_}].response_status must be a non-empty string when provided`);g.response_status=f.response_status.trim()}if(Object.keys(g).length===0)throw new Error(`attendees[${_}] must contain at least one valid field`);return g});return await Z(s,"\u6DFB\u52A0\u65E5\u7A0B\u53C2\u4E0E\u8005",async u=>{let _={attendees:p};c!==void 0&&(_.is_notification=c);let f=await u.request({method:"POST",path:Yd(l,a),body:_,headers:Ke(i)});return f.data??f})}catch(s){return H(s)}}}),t({name:"wps_calendar_list_event_meeting_rooms",description:"List meeting rooms bound to one calendar event (\u83B7\u53D6\u67D0\u4E2A\u65E5\u7A0B\u7684\u4F1A\u8BAE\u5BA4\u5217\u8868): GET `/v7/calendars/{calendar_id}/events/{event_id}/meeting_rooms`. Requires delegated OAuth **`kso.calendar_events.read`** (or `readwrite`) and `event_id`. Optional `calendar_id` (default `primary`). Response `data.items[]` commonly includes room/book fields like `room_id`, `name`, `booking_id`, `result`, `fail_reason`. Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from event list / search / get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary";return await Z(s,"\u83B7\u53D6\u65E5\u7A0B\u4F1A\u8BAE\u5BA4\u5217\u8868",async c=>{let d=await c.request({method:"GET",path:Qd(l,a),headers:Ke(i)});return d.data??d})}catch(s){return H(s)}}}),t({name:"wps_calendar_event_meeting_rooms_batch_create",description:"Batch add meeting rooms to one calendar event (\u6279\u91CF\u6DFB\u52A0\u67D0\u4E2A\u65E5\u7A0B\u7684\u4F1A\u8BAE\u5BA4): POST `/v7/calendars/{calendar_id}/events/{event_id}/meeting_rooms/batch_create`. Requires delegated OAuth **`kso.calendar_events.readwrite`** (per API). Use SenderId as wps_user_id. Required: `event_id`, non-empty **`room_ids`** (string array; room ids from `wps_meeting_rooms_list` / search / get). Optional `calendar_id` (default `primary`). Response `data.items[]` may include `room_id`, `name`, `result`, `booking_id`, `fail_reason`. Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from event list / search / get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},room_ids:{type:"array",description:"Meeting room ids to attach to this event (non-empty; max 100 per request).",items:{type:"string"}},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id","room_ids"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary",c=i.room_ids;if(!Array.isArray(c))throw new Error("room_ids is required and must be an array");let d=ls(c);return await Z(s,"\u6279\u91CF\u6DFB\u52A0\u65E5\u7A0B\u4F1A\u8BAE\u5BA4",async p=>{let u=await p.request({method:"POST",path:ec(l,a),body:d,headers:Ke(i)});return u.data??u})}catch(s){return H(s)}}}),t({name:"wps_calendar_event_meeting_rooms_batch_delete",description:"Batch delete meeting rooms from one calendar event (\u6279\u91CF\u5220\u9664\u67D0\u4E2A\u65E5\u7A0B\u7684\u4F1A\u8BAE\u5BA4): POST `/v7/calendars/{calendar_id}/events/{event_id}/meeting_rooms/batch_delete`. Requires delegated OAuth **`kso.calendar_events.readwrite`**. Use SenderId as wps_user_id. Required: `event_id`, non-empty **`room_ids`** (meeting room ids bound to this event). Optional `calendar_id` (default `primary`). Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from event list / search / get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},room_ids:{type:"array",description:"Meeting room ids to remove from this event (non-empty; max 100 per request).",items:{type:"string"}},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id","room_ids"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary",c=i.room_ids;if(!Array.isArray(c))throw new Error("room_ids is required and must be an array");let d=ls(c);return await Z(s,"\u6279\u91CF\u5220\u9664\u65E5\u7A0B\u4F1A\u8BAE\u5BA4",async p=>{let u=await p.request({method:"POST",path:tc(l,a),body:d,headers:Ke(i)});return u.data??u})}catch(s){return H(s)}}}),t({name:"wps_calendar_delete_event_attendees",description:"Batch delete attendees from one event (official \u5220\u9664\u65E5\u7A0B\u53C2\u4E0E\u8005): POST `/v7/calendars/{calendar_id}/events/{event_id}/attendees/batch_delete`. Requires delegated OAuth (same as `wps_calendar_create`). Body requires `attendees` array and supports optional `attendee_ids` array. Per API, `attendee_ids.length + attendees.length` must be <= 50 in one request. Optional `is_notification` controls whether removed attendees receive notification (default true). Optional `calendar_id` (default `primary`). Optional `x_kso_id_type` maps to `X-Kso-Id-Type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from event list/search/get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},attendee_ids:{type:"array",description:"Optional attendee id list. Combined count with `attendees` must be <= 50.",items:{type:"string"}},attendees:{type:"array",description:"Attendees payload to remove (required). Combined count with `attendee_ids` must be <= 50. Each item supports fields like { type, user_id, third_party_email }.",items:{type:"object",properties:{type:{type:"string"},user_id:{type:"string"},third_party_email:{type:"string"}}}},is_notification:{type:"boolean",description:"Whether to notify removed attendees (default true)."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type`: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","event_id","attendees"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary",c=Ut(i,"is_notification"),d=i.attendee_ids,p;if(d!==void 0){if(!Array.isArray(d))throw new Error("attendee_ids must be an array of strings when provided");p=d.map((g,y)=>{if(typeof g!="string"||!g.trim())throw new Error(`attendee_ids[${y}] must be a non-empty string`);return g.trim()})}let u=i.attendees;if(!Array.isArray(u)||u.length===0)throw new Error("attendees is required and must be a non-empty array");let _=u.map((g,y)=>{if(typeof g!="object"||g===null||Array.isArray(g))throw new Error(`attendees[${y}] must be an object`);let m=g,h={};if(m.type!==void 0){if(typeof m.type!="string"||!m.type.trim())throw new Error(`attendees[${y}].type must be a non-empty string when provided`);h.type=m.type.trim()}if(m.user_id!==void 0){if(typeof m.user_id!="string"||!m.user_id.trim())throw new Error(`attendees[${y}].user_id must be a non-empty string when provided`);h.user_id=m.user_id.trim()}if(m.third_party_email!==void 0){if(typeof m.third_party_email!="string"||!m.third_party_email.trim())throw new Error(`attendees[${y}].third_party_email must be a non-empty string when provided`);h.third_party_email=m.third_party_email.trim()}if(Object.keys(h).length===0)throw new Error(`attendees[${y}] must contain at least one valid field`);return h});if((p?.length??0)+_.length>ds)throw new Error(`attendee_ids.length + attendees.length must be <= ${ds}`);return await Z(s,"\u5220\u9664\u65E5\u7A0B\u53C2\u4E0E\u8005",async g=>{let y={attendees:_};p&&p.length>0&&(y.attendee_ids=p),c!==void 0&&(y.is_notification=c);let m=await g.request({method:"POST",path:Zd(l,a),body:y,headers:Ke(i)});return m.data??m})}catch(s){return H(s)}}}),t({name:"wps_calendar_respond_invitation",description:"Reply to a calendar invitation (official \u7B54\u590D\u65E5\u7A0B\u9080\u8BF7): POST `/v7/calendars/{calendar_id}/events/{event_id}/respond`. Requires delegated OAuth (same as `wps_calendar_create`). Body per API: `mod_type` (`normal` = non-recurring reply, `one` = one occurrence of recurring, `all` = entire series), `response_status` (`accepted` | `declined` | `tentative`), `which_day_time` = **start time in milliseconds** (Unix ms) for the occurrence being answered. Use `event_id` from `wps_calendar_list_events` / `wps_calendar_get_event`; for recurring series pick `which_day_time` from instance or event `start_time`. Optional `calendar_id` (default `primary`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Calendar event id (from event list or get-event API)."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},mod_type:{type:"string",description:"Reply scope per WPS API.",enum:["normal","one","all"]},response_status:{type:"string",description:"Invitation response.",enum:["accepted","declined","tentative"]},which_day_time:{type:"number",description:"Schedule start time as **milliseconds since Unix epoch** (per API `which_day_time`). Use the occurrence start from list/get/event_instances."}},required:["wps_user_id","event_id","mod_type","response_status","which_day_time"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary",c=O(i,"mod_type");if(c!=="normal"&&c!=="one"&&c!=="all")throw new Error("mod_type must be normal, one, or all");let d=O(i,"response_status");if(d!=="accepted"&&d!=="declined"&&d!=="tentative")throw new Error("response_status must be accepted, declined, or tentative");let p=Math.trunc(Gd(i,"which_day_time"));return await Z(s,"\u7B54\u590D\u65E5\u7A0B\u9080\u8BF7",async u=>{let _=await u.request({method:"POST",path:Vd(l,a),body:{mod_type:c,response_status:d,which_day_time:p}});return _.data??_})}catch(s){return H(s)}}}),t({name:"wps_calendar_list_calendar_event_instances",description:"List expanded **calendar-level** event instances (all occurrences in a time window): GET `/v7/calendars/{calendar_id}/event_instances` (use `calendar_id=primary` for main calendar). Same delegated Bearer auth as `wps_calendar_create`. Query: RFC3339 `start_time` / `end_time` (0\u201331 days), optional `page_size` (default 30), `page_token`. Use when you need many instances across the calendar without a specific `event_id`. To expand **one** recurring event by id, use `wps_calendar_list_event_instances` instead.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},calendar_id:{type:"string",description:"Calendar id or the literal `primary` (default)."},start_time:{type:"string",description:"Optional range start (RFC3339). Omit both for default window."},end_time:{type:"string",description:"Optional range end (RFC3339). Max 31-day span; longer truncated."},page_size:{type:"number",description:"Page size (default 30, max 500)."},page_token:{type:"string",description:"Pagination cursor if returned by API."}},required:["wps_user_id"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=v(i,"calendar_id")??"primary",l=v(i,"start_time"),c=v(i,"end_time"),d=qt(i,"page_size"),p=v(i,"page_token");return await Z(s,"\u67E5\u8BE2\u65E5\u5386\u65E5\u7A0B\u5B9E\u4F8B\u5217\u8868",async u=>{let _=Hd({startRfc:l,endRfc:c,pageSize:d,pageToken:p}),f=await u.request({method:"GET",path:`/v7/calendars/${encodeURIComponent(a)}/event_instances`,query:_});return f.data??f})}catch(s){return H(s)}}}),t({name:"wps_calendar_list_event_instances",description:"Query **instances of one calendar event** (expand a recurring series for that event id): GET `/v7/calendars/{calendar_id}/events/{event_id}/event_instances` per WPS365 doc. Requires `event_id` from `wps_calendar_list_events` (or equivalent). Optional query: `start_time` / `end_time` **RFC3339** strings; range 0\u201331 days (truncated if longer); omit both for default window. Same delegated Bearer auth as `wps_calendar_create`. Optional `calendar_id` (default `primary`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Calendar event id from the event list API."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},start_time:{type:"string",description:"Optional query range start (RFC3339). Used with end_time; omit both for defaults."},end_time:{type:"string",description:"Optional query range end (RFC3339)."}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary",c=v(i,"start_time"),d=v(i,"end_time");return await Z(s,"\u67E5\u8BE2\u5355\u6761\u65E5\u7A0B\u5B9E\u4F8B",async p=>{let u=Kd({startRfc:c,endRfc:d}),_=await p.request({method:"GET",path:`${$e(l,a)}/event_instances`,query:u});return _.data??_})}catch(s){return H(s)}}});let r=100,n=500;t({name:"wps_calendar_search_events",description:"Search calendar events by keyword (official \u641C\u7D22\u65E5\u7A0B): POST `/v7/calendars/{calendar_id}/events/search`. Searches event titles, descriptions, and notes. Requires user delegated OAuth (same as wps_calendar_create). Use SenderId as wps_user_id. Body: `keyword` (required, 1-100 chars), optional `page_size` (default 200, max 500), optional `page_token`. Response: `data.items[]` (event list) and optional `data.next_page_token`. Optional `calendar_id` (default `primary`). Optional header `X-Kso-Id-Type`: pass `x_kso_id_type` as `internal` or `external` per API.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},keyword:{type:"string",description:"Search keyword (1-100 chars). Matches event title, description, notes."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},page_size:{type:"number",description:"Page size (default 200 per API, max 500)."},page_token:{type:"string",description:"Pagination cursor from data.next_page_token."},x_kso_id_type:{type:"string",description:"Optional. When set, sent as `X-Kso-Id-Type` header: `internal` or `external`.",enum:["internal","external"]}},required:["wps_user_id","keyword"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"keyword");if(a.length>r)throw new Error(`keyword must be at most ${r} characters`);let l=v(i,"calendar_id")??"primary",c=qt(i,"page_size"),d=v(i,"page_token");return await Z(s,"\u641C\u7D22\u65E5\u7A0B",async p=>{let u={keyword:a},_=c??200;u.page_size=Math.max(1,Math.min(n,Math.trunc(_))),d!==void 0&&d.trim()!==""&&(u.page_token=d.trim());let f=await p.request({method:"POST",path:`/v7/calendars/${encodeURIComponent(l)}/events/search`,body:u,headers:Ke(i)});return f.data??f})}catch(s){return H(s)}}}),t({name:"wps_calendar_update_event",description:"Update (modify) a calendar event (official \u4FEE\u6539\u65E5\u7A0B): POST `/v7/calendars/{calendar_id}/events/{event_id}/update`. Requires user delegated OAuth (same as wps_calendar_create). Use SenderId as wps_user_id. All body fields are optional \u2014 only pass what needs to change. For recurring events: set `mod_type` to `one` (single occurrence, requires `which_day_time` in ms) or `all` (entire series). Set `is_notification` to false to suppress attendee notifications. Set `online_meeting` to null to clear the meeting. Optional `calendar_id` (default `primary`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from calendar event list or search."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},summary:{type:"string",description:"New event title."},description:{type:"string",description:"New event description / notes."},start_time:{type:"string",description:"New start time in ISO 8601 with timezone (e.g. '2026-05-10T14:00:00+08:00')."},end_time:{type:"string",description:"New end time in ISO 8601 with timezone."},location:{type:"string",description:"New event location (API supports max 1 location)."},free_busy_status:{type:"string",description:"Busy/free status during the event.",enum:["busy","free"]},visibility:{type:"string",description:"Event visibility scope.",enum:["default","public","private"]},attendee_ability:{type:"string",description:"Attendee permission level.",enum:["can_see_others","can_invite_others"]},mod_type:{type:"string",description:"For recurring events only: `one` = edit single occurrence (requires which_day_time), `all` = edit entire series.",enum:["one","all"]},which_day_time:{type:"number",description:"When mod_type=one, the start time of the occurrence to modify in **milliseconds** (Unix epoch ms)."},is_notification:{type:"boolean",description:"Whether to notify attendees about the update (default true)."},is_reinvition:{type:"boolean",description:"When true and time/recurrence changes, reset all attendees to not-accepted (default true)."},reminders:{type:"array",description:"Reminder list (max 10). Each item: { minutes: number }.",items:{type:"object",properties:{minutes:{type:"number"}},required:["minutes"]}}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary",c=v(i,"mod_type");if(c!==void 0&&c!=="one"&&c!=="all")throw new Error("mod_type must be one or all when provided");let d=qt(i,"which_day_time");if(c==="one"&&d==null)throw new Error("which_day_time (ms) is required when mod_type is one");let p=v(i,"free_busy_status");if(p!==void 0&&p!=="busy"&&p!=="free")throw new Error("free_busy_status must be busy or free");let u=v(i,"visibility");if(u!==void 0&&u!=="default"&&u!=="public"&&u!=="private")throw new Error("visibility must be default, public, or private");let _=v(i,"attendee_ability");if(_!==void 0&&_!=="can_see_others"&&_!=="can_invite_others")throw new Error("attendee_ability must be can_see_others or can_invite_others");return await Z(s,"\u4FEE\u6539\u65E5\u7A0B",async f=>{let g={},y=v(i,"summary");y!==void 0&&(g.summary=y);let m=v(i,"description");m!==void 0&&(g.description=m);let h=v(i,"start_time");h!==void 0&&(g.start_time={datetime:h});let w=v(i,"end_time");w!==void 0&&(g.end_time={datetime:w});let b=v(i,"location");b!==void 0&&(g.locations=[{name:b}]),p!==void 0&&(g.free_busy_status=p),u!==void 0&&(g.visibility=u),_!==void 0&&(g.attendee_ability=_),c!==void 0&&(g.mod_type=c),d!==void 0&&(g.which_day_time=Math.trunc(d));let I=Ut(i,"is_notification");I!==void 0&&(g.is_notification=I);let x=Ut(i,"is_reinvition");x!==void 0&&(g.is_reinvition=x);let M=i.reminders;Array.isArray(M)&&(g.reminders=M.slice(0,10).map(F=>{let W=F;return{minutes:typeof W.minutes=="number"?Math.trunc(W.minutes):0}}));let K=await f.request({method:"POST",path:`${$e(l,a)}/update`,body:g});return K.data??K})}catch(s){return H(s)}}}),t({name:"wps_calendar_delete_event",description:"Delete a calendar event (official \u5220\u9664\u65E5\u7A0B): POST `/v7/calendars/{calendar_id}/events/{event_id}/delete`. Requires user delegated OAuth (same as wps_calendar_create). Use SenderId as wps_user_id. Optional body: `is_notification` (default true). For recurring events: set `mod_type` to `one` (delete one occurrence, requires `which_day_time` in ms) or `all` (delete entire series). Optional `calendar_id` (default `primary`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},event_id:{type:"string",description:"Event id from calendar list/search/get-event APIs."},calendar_id:{type:"string",description:"Calendar id or `primary` (default)."},is_notification:{type:"boolean",description:"Whether to notify attendees about deletion (default true)."},mod_type:{type:"string",description:"For recurring events only: `one` (single occurrence, requires which_day_time) or `all` (entire series).",enum:["one","all"]},which_day_time:{type:"number",description:"When mod_type=one, the start time of occurrence to delete in milliseconds."}},required:["wps_user_id","event_id"]},async execute(o,i){try{let s=O(i,"wps_user_id"),a=O(i,"event_id"),l=v(i,"calendar_id")??"primary",c=v(i,"mod_type");if(c!==void 0&&c!=="one"&&c!=="all")throw new Error("mod_type must be one or all when provided");let d=qt(i,"which_day_time");if(c==="one"&&d===void 0)throw new Error("which_day_time (ms) is required when mod_type is one");let p=Ut(i,"is_notification");return await Z(s,"\u5220\u9664\u65E5\u7A0B",async u=>{let _={};p!==void 0&&(_.is_notification=p),c!==void 0&&(_.mod_type=c),d!==void 0&&(_.which_day_time=Math.trunc(d));let f=await u.request({method:"POST",path:`${$e(l,a)}/delete`,body:_});return f.data??f})}catch(s){return H(s)}}})}var nc="/v7/todo/personal_tasks",ic="/v7/todo/personal_tasks/batch_get";function Br(e){return`/v7/todo/personal_tasks/${encodeURIComponent(e.trim())}`}function oc(e){return`${Br(e.trim())}/update`}function sc(e){return`${Br(e.trim())}/update_status`}var ps=100,ac=20,dc=50;function Mt(e){return{error:e instanceof Error?e.message:String(e)}}function Re(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function Q(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}function pt(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function cc(e,t){let r=e[t];if(r==null)return;if(!Array.isArray(r))throw new Error(`${t} must be an array of strings`);let n=r.map(o=>String(o).trim()).filter(Boolean);return n.length>0?n:void 0}function lc(e,t){let r=e[t];if(r==null)return;if(!Array.isArray(r))throw new Error(`${t} must be an array of objects with name and value`);let n=[];for(let o of r){if(typeof o!="object"||o===null)continue;let i=o;typeof i.name!="string"||typeof i.value!="string"||n.push({name:i.name.trim(),value:i.value})}return n.length>0?n:void 0}function pc(e,t){let r=Q(e,t);if(!(r===void 0||r.trim()===""))try{let n=JSON.parse(r);if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`${t} must be a JSON object`);return n}catch(n){throw n instanceof SyntaxError?new Error(`${t} must be valid JSON`):n}}function jt(e){let t=Q(e,"x_kso_id_type");if(t===void 0||t.trim()==="")return;let r=t.trim();if(r!=="internal"&&r!=="external")throw new Error("x_kso_id_type must be internal or external when provided");return{"X-Kso-Id-Type":r}}function uc(e){let t=e.titleSubject.trim();if(!t)throw new Error("title_subject must be non-empty");let r={subject:t};e.titlePrefix!==void 0&&e.titlePrefix.trim()!==""&&(r.prefix=e.titlePrefix.trim());let n={title:r};if(e.description!==void 0&&e.description.trim()!==""&&(n.description=e.description.trim()),e.dueTimeMs!==void 0){if(!Number.isFinite(e.dueTimeMs))throw new Error("due_time_ms must be a finite number");n.due_time=Math.trunc(e.dueTimeMs)}if((e.status==="todo"||e.status==="finish")&&(n.status=e.status),e.executors!==void 0&&e.executors.length>0){if(e.executors.length>ps)throw new Error(`executors must have at most ${ps} entries`);n.executors=[...e.executors]}return n}function fc(e){let t={};if(e.keyword!==void 0&&e.keyword.trim()!==""&&(t.keyword=e.keyword.trim().slice(0,50)),e.executor!==void 0&&e.executor.trim()!==""&&(t.executor=e.executor.trim()),(e.status==="todo"||e.status==="finish")&&(t.status=e.status),e.pageSize!==void 0){let r=e.pageSize;t.page_size=Math.max(1,Math.min(dc,Math.trunc(r)))}else t.page_size=ac;if(e.pageToken!==void 0&&e.pageToken.trim()!==""&&(t.page_token=e.pageToken.trim()),e.createdTimeStartMs!==void 0||e.createdTimeEndMs!==void 0){let r={};e.createdTimeStartMs!==void 0&&Number.isFinite(e.createdTimeStartMs)&&(r.start_time=Math.trunc(e.createdTimeStartMs)),e.createdTimeEndMs!==void 0&&Number.isFinite(e.createdTimeEndMs)&&(r.end_time=Math.trunc(e.createdTimeEndMs)),Object.keys(r).length>0&&(t.created_time=r)}if(e.dueTimeStartMs!==void 0||e.dueTimeEndMs!==void 0){let r={};e.dueTimeStartMs!==void 0&&Number.isFinite(e.dueTimeStartMs)&&(r.start_time=Math.trunc(e.dueTimeStartMs)),e.dueTimeEndMs!==void 0&&Number.isFinite(e.dueTimeEndMs)&&(r.end_time=Math.trunc(e.dueTimeEndMs)),Object.keys(r).length>0&&(t.due_time=r)}return t}function _c(e){let t={},r=e.titleSubject?.trim()??"",n=e.titlePrefix?.trim()??"";if(r!==""||n!==""){let o={};r!==""&&(o.subject=r),n!==""&&(o.prefix=n),t.title=o}if(e.description!==void 0&&e.description.trim()!==""&&(t.description=e.description.trim()),e.dueTimeMs!==void 0){if(!Number.isFinite(e.dueTimeMs))throw new Error("due_time_ms must be a finite number");t.due_time=Math.trunc(e.dueTimeMs)}if(e.extAttrs!==void 0&&e.extAttrs.length>0&&(t.ext_attrs=e.extAttrs.map(o=>({name:o.name,value:o.value}))),e.notifyConfig!==void 0&&Object.keys(e.notifyConfig).length>0&&(t.notify_config=e.notifyConfig),Object.keys(t).length===0)throw new Error("provide at least one of: title_subject, title_prefix, description, due_time_ms, ext_attrs, notify_config_json");return t}var mc=new Set(["finish","unfinish","finish_all","unfinish_all"]);function hc(e){return mc.has(e)}function us(e){let t=e.trim();if(!hc(t))throw new Error("action must be exactly one of: finish, unfinish, finish_all, unfinish_all");return t}function gc(e){return{action:us(e.action)}}function yc(e){if(e==null||typeof e!="object")return null;let t=e,r=["creator_id","creator_user_id","create_user_id","owner_id"];for(let o of r){let i=t[o];if(typeof i=="string"&&i.trim())return i.trim()}let n=t.creator;if(n!==null&&typeof n=="object"&&!Array.isArray(n)){let o=n;for(let i of["id","user_id","userId"]){let s=o[i];if(typeof s=="string"&&s.trim())return s.trim()}}return null}function wc(e,t){let r=e.trim(),n=t.trim();return r===n?!0:r.toLowerCase()===n.toLowerCase()}function bc(e){let{hasCompletion:t,completionRaw:r,markScopeRaw:n,actionParam:o,isCreator:i,taskId:s,creatorId:a}=e,l=n?.trim()??"";if(t){if(r!=="complete"&&r!=="incomplete")throw new Error("completion must be complete or incomplete");let d=r==="complete";if(i){if(!l||l==="none")return{kind:"needs_confirmation",taskId:s,completion:r,creatorId:a};if(l!=="self"&&l!=="all")throw new Error("mark_scope must be none, self, or all when provided");return{kind:"post",action:l==="all"?d?"finish_all":"unfinish_all":d?"finish":"unfinish"}}return{kind:"post",action:d?"finish":"unfinish"}}let c=us(o);if(!i&&(c==="finish_all"||c==="unfinish_all"))throw new Error("\u5F53\u524D\u7528\u6237\u4E0D\u662F\u8BE5\u5F85\u529E\u7684\u521B\u5EFA\u8005\uFF08\u6216\u672A\u89E3\u6790\u5230 creator_id\uFF09\uFF0C\u4E0D\u80FD\u4F7F\u7528 finish_all / unfinish_all\uFF1B\u8BF7\u4F7F\u7528 finish \u6216 unfinish\u3002");return i?{kind:"needs_confirmation",taskId:s,completion:c==="finish"||c==="finish_all"?"complete":"incomplete",creatorId:a,requested_action:c}:{kind:"post",action:c}}async function dr(e,t,r){try{return await _e({wpsUserId:e,toolModule:"todo",authCardOriginalMessage:t,needsAuthMessage:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u4F7F\u7528\u5F85\u529E\u80FD\u529B\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u5B8C\u6210\u6388\u6743\u540E\u91CD\u8BD5\u3002",logTag:"todo",run:r})}catch(n){return Mt(n)}}function ai(e,t){t({name:"wps_todo_create_personal_task",description:"Create a personal todo/task via WPS OpenAPI (\u521B\u5EFA\u4E2A\u4EBA\u5F85\u529E): POST `/v7/todo/personal_tasks`. Requires user delegated OAuth scope `kso.task.readwrite` (or equivalent per console). Use SenderId as `wps_user_id`. Required: `title_subject` \u2192 body `title.subject`; optional `title_prefix` \u2192 `title.prefix`. Optional: `description`, `due_time_ms` (deadline **milliseconds** Unix epoch), `status` (`todo`|`finish`), `executors` (\u2264100 user ids). Response `data.task_id` is the new task id. Optional `x_kso_id_type`: `internal`|`external` \u2192 header `X-Kso-Id-Type`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},title_subject:{type:"string",description:"Todo title subject (maps to request body title.subject)."},title_prefix:{type:"string",description:"Optional. Maps to title.prefix."},description:{type:"string",description:"Optional todo description."},due_time_ms:{type:"number",description:"Optional deadline as Unix timestamp in **milliseconds** (due_time)."},status:{type:"string",description:"Optional initial status.",enum:["todo","finish"]},executors:{type:"array",items:{type:"string"},description:"Optional executor user ids (max 100)."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","title_subject"]},async execute(r,n){try{let o=Re(n,"wps_user_id"),i=Re(n,"title_subject"),s=Q(n,"title_prefix"),a=Q(n,"description"),l=pt(n,"due_time_ms"),c=Q(n,"status"),d=cc(n,"executors"),p;if(c!==void 0){if(c!=="todo"&&c!=="finish")throw new Error("status must be todo or finish when provided");p=c}let u=uc({titleSubject:i,titlePrefix:s,description:a,dueTimeMs:l,status:p,executors:d});return await dr(o,"\u521B\u5EFA\u4E2A\u4EBA\u5F85\u529E",async _=>{let f=await _.request({method:"POST",path:nc,body:u,headers:jt(n)});return f.data??f})}catch(o){return Mt(o)}}}),t({name:"wps_todo_list_personal_tasks",description:"List personal todos via WPS OpenAPI (\u83B7\u53D6\u4E2A\u4EBA\u5F85\u529E\u5217\u8868): POST `/v7/todo/personal_tasks/batch_get`. Requires delegated OAuth (`kso.task.read` / `kso.task.readwrite`). Use SenderId as `wps_user_id`. Body filters are optional: `keyword` (\u226450 chars), `executor`, `status` (`todo`|`finish`), `page_size` (default 20, max 50), `page_token` (from previous `data` pagination field per API). `created_time` / `due_time` ranges use **milliseconds** (`*_start_ms`, `*_end_ms`). Response `data` typically includes `tasks`, `total`, `next_offset`. Optional `x_kso_id_type`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},keyword:{type:"string",description:"Optional. Fuzzy match title/description (max 50 chars)."},executor:{type:"string",description:"Optional. Filter by executor user id."},status:{type:"string",description:"Optional list filter: todo (=\u672A\u5B8C\u6210) or finish (=\u5DF2\u5B8C\u6210).",enum:["todo","finish"]},page_size:{type:"number",description:"Page size (default 20; API max 50)."},page_token:{type:"string",description:"Pagination cursor from previous response (see API field names e.g. next_offset)."},created_time_start_ms:{type:"number",description:"Optional. Creation range start (Unix ms)."},created_time_end_ms:{type:"number",description:"Optional. Creation range end (Unix ms)."},due_time_start_ms:{type:"number",description:"Optional. Due range start (Unix ms)."},due_time_end_ms:{type:"number",description:"Optional. Due range end (Unix ms)."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id"]},async execute(r,n){try{let o=Re(n,"wps_user_id"),i=Q(n,"keyword"),s=Q(n,"executor"),a=Q(n,"status"),l=pt(n,"page_size"),c=Q(n,"page_token"),d=pt(n,"created_time_start_ms"),p=pt(n,"created_time_end_ms"),u=pt(n,"due_time_start_ms"),_=pt(n,"due_time_end_ms"),f;if(a!==void 0){if(a!=="todo"&&a!=="finish")throw new Error("status must be todo or finish when provided");f=a}let g=fc({keyword:i,executor:s,status:f,pageSize:l,pageToken:c,createdTimeStartMs:d,createdTimeEndMs:p,dueTimeStartMs:u,dueTimeEndMs:_});return await dr(o,"\u83B7\u53D6\u4E2A\u4EBA\u5F85\u529E\u5217\u8868",async y=>{let m=await y.request({method:"POST",path:ic,body:g,headers:jt(n)});return m.data??m})}catch(o){return Mt(o)}}}),t({name:"wps_todo_get_personal_task",description:"Get one personal todo by id (\u83B7\u53D6\u4E2A\u4EBA\u5F85\u529E\u8BE6\u60C5): GET `/v7/todo/personal_tasks/{task_id}`. Requires delegated OAuth (`kso.task.read` / `kso.task.readwrite`). Use SenderId as `wps_user_id`. Requires **`task_id`** from `wps_todo_list_personal_tasks` (`tasks[].id`) or create response. Response `data` is a single todo object (`todo_personal_task`). Optional `x_kso_id_type`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},task_id:{type:"string",description:"Todo task id from list or create API."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","task_id"]},async execute(r,n){try{let o=Re(n,"wps_user_id"),i=Re(n,"task_id");return await dr(o,"\u83B7\u53D6\u4E2A\u4EBA\u5F85\u529E\u8BE6\u60C5",async s=>{let a=await s.request({method:"GET",path:Br(i),headers:jt(n)});return a.data??a})}catch(o){return Mt(o)}}}),t({name:"wps_todo_update_personal_task_status",description:"POST `/v7/todo/personal_tasks/{task_id}/update_status`. HTTP body: `{ action }`. Enum: `finish`, `unfinish`, `finish_all`, `unfinish_all` (`finish_all`/`unfinish_all` creator-only). **Creators**: without `mark_scope` (or `mark_scope: none`) or `action`-only \u2192 returns `needsUserConfirmation`, ask user to choose scope; then call again with `completion` + `mark_scope: self|all`. **Non-creators**: `completion` or `action` (`finish`|`unfinish`); omit `mark_scope`. Requires delegated `kso.task.readwrite`; `wps_user_id` = SenderId.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},task_id:{type:"string",description:"Todo id to update status."},completion:{type:"string",description:"`complete`/`incomplete`. Creators: omit `mark_scope` or use `none` \u2192 returns `needsUserConfirmation`; after user confirms, call again with `mark_scope: self|all`. Mutually exclusive with `action`.",enum:["complete","incomplete"]},mark_scope:{type:"string",description:"**Creators only**: omit or `none` \u2192 \u89E6\u53D1\u4E8C\u6B21\u786E\u8BA4\uFF1B`self` = \u4EC5\u81EA\u5DF1\uFF1B`all` = \u5168\u90E8\u53C2\u4E0E\u4EBA\u3002\u975E\u521B\u5EFA\u8005\u52FF\u4F20\u3002",enum:["none","self","all"]},action:{type:"string",description:"Maps to HTTP body `action`. `finish`|`unfinish` (single); `finish_all`|`unfinish_all` (creator, all participants). Non-creators: `finish`|`unfinish` only. Creators using `action` alone \u2192 `needsUserConfirmation` (then use `completion`+`mark_scope`).",enum:["finish","unfinish","finish_all","unfinish_all"]},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","task_id"]},async execute(r,n){try{let o=Re(n,"wps_user_id"),i=Re(n,"task_id"),s=Q(n,"completion"),a=Q(n,"mark_scope"),l=Q(n,"action"),c=s!==void 0,d=l!==void 0&&l!=="";if(c===d)throw!c&&!d?new Error("Provide exactly one of: completion (complete|incomplete) or action (finish|unfinish|...)"):new Error("Provide only one of: completion or action");if(a!==void 0&&!c)throw new Error("mark_scope is only used together with completion");return await dr(o,"\u66F4\u65B0\u4E2A\u4EBA\u5F85\u529E\u72B6\u6001",async p=>{let u=await p.request({method:"GET",path:Br(i),headers:jt(n)}),_=u.data??u,f=yc(_),g=f!==null&&wc(o,f),y=bc({hasCompletion:c,completionRaw:s,markScopeRaw:a,actionParam:l,isCreator:g,taskId:i,creatorId:f});if(y.kind==="needs_confirmation")return{needsUserConfirmation:!0,reason:"creator_must_choose_scope",message:"\u60A8\u662F\u8BE5\u5F85\u529E\u7684\u521B\u5EFA\u8005\uFF0C\u8BF7\u5148\u786E\u8BA4\uFF1A\u6807\u8BB0\u300C\u4EC5\u81EA\u5DF1\u300D\u8FD8\u662F\u300C\u5168\u90E8\u53C2\u4E0E\u4EBA\u300D\uFF1F\u786E\u8BA4\u540E\u518D\u6B21\u8C03\u7528\uFF0C\u4F20\u5165 completion + mark_scope\uFF08self \u6216 all\uFF09\u3002",task_id:y.taskId,completion:y.completion,creator_id:y.creatorId,...y.requested_action!==void 0?{requested_action:y.requested_action}:{}};let m=gc({action:y.action}),h=await p.request({method:"POST",path:sc(i),body:m,headers:jt(n)});return h.data??h})}catch(o){return Mt(o)}}}),t({name:"wps_todo_update_personal_task",description:"Update a personal todo (\u66F4\u65B0\u4E2A\u4EBA\u5F85\u529E): POST `/v7/todo/personal_tasks/{task_id}/update`. Requires delegated **`kso.task.readwrite`**. Use SenderId as `wps_user_id`. Requires **`task_id`**. Body fields are optional but **at least one** must be provided: `title_subject` / `title_prefix` (maps to `title`), `description`, `due_time_ms` (ms), `ext_attrs` (`[{name,value}]`), or `notify_config_json` (JSON object string for `notify_config`). Response is typically `code` + `msg` only.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},task_id:{type:"string",description:"Todo id to update."},title_subject:{type:"string",description:"Optional. Maps to title.subject."},title_prefix:{type:"string",description:"Optional. Maps to title.prefix."},description:{type:"string",description:"Optional. New description."},due_time_ms:{type:"number",description:"Optional. New deadline as Unix **milliseconds**."},ext_attrs:{type:"array",items:{type:"object",properties:{name:{type:"string"},value:{type:"string"}},required:["name","value"]},description:"Optional. Extension attributes."},notify_config_json:{type:"string",description:"Optional. JSON object string for notify_config (e.g. reminders, switch). Must parse to an object."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","task_id"]},async execute(r,n){try{let o=Re(n,"wps_user_id"),i=Re(n,"task_id"),s=Q(n,"title_subject"),a=Q(n,"title_prefix"),l=Q(n,"description"),c=pt(n,"due_time_ms"),d=lc(n,"ext_attrs"),p=pc(n,"notify_config_json"),u=_c({titleSubject:s,titlePrefix:a,description:l,dueTimeMs:c,extAttrs:d,notifyConfig:p});return await dr(o,"\u66F4\u65B0\u4E2A\u4EBA\u5F85\u529E",async _=>{let f=await _.request({method:"POST",path:oc(i),body:u,headers:jt(n)});return f.data??f})}catch(o){return Mt(o)}}})}function Ce(e){return`/v7/coop/dbsheet/${encodeURIComponent(e)}`}function Ic(e){return`/v7/dbsheet/${encodeURIComponent(e)}`}function Je(e){let t=e.sheet_id;if(t==null)throw new Error("sheet_id is required");let r=typeof t=="number"?t:parseInt(String(t),10);if(!Number.isFinite(r)||r<=0)throw new Error("sheet_id must be a positive integer");return r}function fs(e,t="fields_value"){if(typeof e=="string")return e;if(e!==null&&typeof e=="object")return JSON.stringify(e);throw new Error(`${t} must be a JSON string or object`)}async function Ee(e,t,r){return _e({wpsUserId:e,toolModule:"dbsheet",authCardOriginalMessage:"\u7528\u6237\u8BF7\u6C42\u64CD\u4F5C\u591A\u7EF4\u8868\u683C",needsAuthMessage:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u8BBF\u95EE\u591A\u7EF4\u8868\u683C\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",logTag:t,run:r})}function di(e,t){t({name:"wps_dbsheet_get_schema",description:"Get DBSheet schema (\u83B7\u53D6\u591A\u7EF4\u8868\u683C Schema): GET `/v7/coop/dbsheet/{file_id}/schema`. Returns all sheets with their fields (name/type/id/data) and views. Use this first to understand the table structure before reading or writing records. Requires delegated OAuth (`kso.dbsheet.read`). Use current SenderId as `wps_user_id`. Do NOT call `wps_user_search` to resolve `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"DBSheet file ID."}},required:["wps_user_id","file_id"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id");return await Ee(o,"wps_dbsheet_get_schema",async s=>{let a=await s.request({method:"GET",path:`${Ce(i)}/schema`});return a.data??a})}catch(o){return se(o)}}}),t({name:"wps_dbsheet_batch_create_sheets",description:"Batch create sheets (\u6279\u91CF\u521B\u5EFA\u5DE5\u4F5C\u8868): POST `/v7/dbsheet/{file_id}/sheets/batch_create`. Creates one or more sheets. Each sheet requires `name`; optionally include `fields` (field definitions with name/type/data) and `position` (after_sheet_id or before_sheet_id). Requires delegated OAuth (`kso.dbsheet.readwrite`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheets:{type:"array",description:"Array of sheet definitions. Each: { name: string (required), fields?: [{name, type, data?}], position?: {after_sheet_id?: number, before_sheet_id?: number} }.",items:{type:"object",properties:{name:{type:"string"},fields:{type:"array",items:{type:"object",additionalProperties:!0}},position:{type:"object",additionalProperties:!0}},required:["name"]}}},required:["wps_user_id","file_id","sheets"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=n.sheets;if(!Array.isArray(s)||s.length===0)throw new Error("sheets must be a non-empty array");return await Ee(o,"wps_dbsheet_batch_create_sheets",async a=>{let l=await a.request({method:"POST",path:`${Ic(i)}/sheets/batch_create`,body:{sheets:s}});return l.data??l})}catch(o){return se(o)}}}),t({name:"wps_dbsheet_update_sheet",description:"Update sheet (\u66F4\u65B0\u5DE5\u4F5C\u8868): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/update`. Currently supports renaming a sheet. Obtain `sheet_id` (integer) from `wps_dbsheet_get_schema`. Requires delegated OAuth (`kso.dbsheet.readwrite`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer). From wps_dbsheet_get_schema."},name:{type:"string",description:"New sheet name."}},required:["wps_user_id","file_id","sheet_id","name"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Je(n),a=T(n,"name");return await Ee(o,"wps_dbsheet_update_sheet",async l=>{let c=await l.request({method:"POST",path:`${Ce(i)}/sheets/${s}/update`,body:{name:a}});return c.data??c})}catch(o){return se(o)}}}),t({name:"wps_dbsheet_create_records",description:'Create records (\u521B\u5EFA\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/create`. Creates one or more records. Each record\'s `fields_value` is a JSON string (or object \u2014 auto-stringified) mapping field name to value. Example: `{"\u6587\u672C\u5B57\u6BB5": "hello", "\u6570\u5B57\u5B57\u6BB5": 42}`. Auto fields (Formula/AutoNumber/CreatedBy/CreatedTime/LastModifiedBy/Lookup) must NOT be set. Requires delegated OAuth (`kso.dbsheet.readwrite`). Use current SenderId as `wps_user_id`.',parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer). From wps_dbsheet_get_schema."},records:{type:"array",description:"Array of records to create. Each: { fields_value: string|object }. fields_value maps field names to values as JSON string or object.",items:{type:"object",properties:{fields_value:{type:"string",description:'Field values as JSON string or object. E.g. {"\u6587\u672C": "hello", "\u6570\u5B57": 42}'}},required:["fields_value"]}}},required:["wps_user_id","file_id","sheet_id","records"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Je(n),a=n.records;if(!Array.isArray(a)||a.length===0)throw new Error("records must be a non-empty array");let l=a.map((c,d)=>{if(!c||typeof c!="object")throw new Error(`records[${d}] must be an object`);return{fields_value:fs(c.fields_value,`records[${d}].fields_value`)}});return await Ee(o,"wps_dbsheet_create_records",async c=>{let d=await c.request({method:"POST",path:`${Ce(i)}/sheets/${s}/records/create`,body:{records:l}});return d.data??d})}catch(o){return se(o)}}}),t({name:"wps_dbsheet_update_records",description:"Update records (\u66F4\u65B0\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/update`. Updates one or more records by record ID. Each item must include `id` (record ID) and `fields_value`. `fields_value` maps field names to new values (JSON string or object \u2014 auto-stringified). Auto fields (Formula/AutoNumber/CreatedBy/CreatedTime/LastModifiedBy/Lookup) must NOT be updated. Requires delegated OAuth (`kso.dbsheet.readwrite`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer). From wps_dbsheet_get_schema."},records:{type:"array",description:"Array of records to update. Each: { id: string (record ID), fields_value: string|object }.",items:{type:"object",properties:{id:{type:"string",description:"Record ID."},fields_value:{type:"string",description:"Field values as JSON string or object."}},required:["id","fields_value"]}}},required:["wps_user_id","file_id","sheet_id","records"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Je(n),a=n.records;if(!Array.isArray(a)||a.length===0)throw new Error("records must be a non-empty array");let l=a.map((c,d)=>{if(!c||typeof c!="object")throw new Error(`records[${d}] must be an object`);let p=c;if(!p.id||typeof p.id!="string")throw new Error(`records[${d}].id is required and must be a string`);return{id:p.id,fields_value:fs(p.fields_value,`records[${d}].fields_value`)}});return await Ee(o,"wps_dbsheet_update_records",async c=>{let d=await c.request({method:"POST",path:`${Ce(i)}/sheets/${s}/records/update`,body:{records:l}});return d.data??d})}catch(o){return se(o)}}}),t({name:"wps_dbsheet_list_records",description:"List records with cursor pagination (\u5217\u4E3E\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records`. Returns records with optional filter and cursor-based pagination (page_token). Use `page_token` from previous response to fetch next page. For page-number pagination use `wps_dbsheet_list_records_by_page`. Requires delegated OAuth (`kso.dbsheet.read`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer)."},fields:{type:"array",items:{type:"string"},description:"Optional. Field names to include. Omit to return all fields."},filter:{type:"object",additionalProperties:!0,description:"Optional filter. Structure: { mode: 'AND'|'OR', criteria: [{ field: string, operator: string, values: string[] }] }. operator: Equals|NotEqu|Greater|GreaterEqu|Less|LessEqu|GreaterEquAndLessEqu|LessOrGreater|BeginWith|EndWith|Contains|NotContains|Intersected|Empty|NotEmpty."},max_records:{type:"integer",description:"Optional. Max records to return."},page_size:{type:"integer",description:"Optional. Records per page, default 100, max 1000."},page_token:{type:"string",description:"Optional. Cursor from previous response."},view_id:{type:"string",description:"Optional. View ID to apply view visibility."},text_value:{type:"string",enum:["original","text","compound"],description:"Optional. Return value format. Default: original."},show_fields_info:{type:"boolean",description:"Optional. Include field schema in response."},show_record_extra_info:{type:"boolean",description:"Optional. Include creator/creation time/last-modifier metadata."}},required:["wps_user_id","file_id","sheet_id"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Je(n),a={},l=ct(n,"fields");l&&(a.fields=l),n.filter!==void 0&&n.filter!==null&&(a.filter=n.filter);let c=Y(n,"max_records");c!==void 0&&(a.max_records=c);let d=Y(n,"page_size");d!==void 0&&(a.page_size=d);let p=V(n,"page_token");p!==void 0&&p!==""&&(a.page_token=p);let u=V(n,"view_id");u!==void 0&&u!==""&&(a.view_id=u);let _=V(n,"text_value");_!==void 0&&(a.text_value=_);let f=re(n,"show_fields_info");f!==void 0&&(a.show_fields_info=f);let g=re(n,"show_record_extra_info");return g!==void 0&&(a.show_record_extra_info=g),await Ee(o,"wps_dbsheet_list_records",async y=>{let m=await y.request({method:"POST",path:`${Ce(i)}/sheets/${s}/records`,body:a});return m.data??m})}catch(o){return se(o)}}}),t({name:"wps_dbsheet_list_records_by_page",description:"List records with page-number pagination (\u6309\u9875\u5217\u4E3E\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/list_by_page`. Uses page_num (starts from 1) / page_size. Also returns total count. For cursor-based pagination use `wps_dbsheet_list_records`. Requires delegated OAuth (`kso.dbsheet.read`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer)."},fields:{type:"array",items:{type:"string"},description:"Optional. Field names to include."},filter:{type:"object",additionalProperties:!0,description:"Optional filter. Structure: { mode: 'AND'|'OR', criteria: [{ field, operator, values[] }] }."},max_records:{type:"integer",description:"Optional. Max records to return."},page_num:{type:"integer",description:"Optional. Page number starting from 1."},page_size:{type:"integer",description:"Optional. Records per page, default 100, max 1000."},view_id:{type:"string",description:"Optional. View ID."},text_value:{type:"string",enum:["original","text","compound"],description:"Optional. Return value format."},show_fields_info:{type:"boolean",description:"Optional. Include field schema."},show_record_extra_info:{type:"boolean",description:"Optional. Include metadata."}},required:["wps_user_id","file_id","sheet_id"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Je(n),a={},l=ct(n,"fields");l&&(a.fields=l),n.filter!==void 0&&n.filter!==null&&(a.filter=n.filter);let c=Y(n,"max_records");c!==void 0&&(a.max_records=c);let d=Y(n,"page_num");d!==void 0&&(a.page_num=d);let p=Y(n,"page_size");p!==void 0&&(a.page_size=p);let u=V(n,"view_id");u!==void 0&&u!==""&&(a.view_id=u);let _=V(n,"text_value");_!==void 0&&(a.text_value=_);let f=re(n,"show_fields_info");f!==void 0&&(a.show_fields_info=f);let g=re(n,"show_record_extra_info");return g!==void 0&&(a.show_record_extra_info=g),await Ee(o,"wps_dbsheet_list_records_by_page",async y=>{let m=await y.request({method:"POST",path:`${Ce(i)}/sheets/${s}/records/list_by_page`,body:a});return m.data??m})}catch(o){return se(o)}}}),t({name:"wps_dbsheet_get_records",description:"Get multiple records by ID (\u6309 ID \u6279\u91CF\u68C0\u7D22\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/search`. Retrieves specific records by their IDs. Use when you already know the record IDs. For filter-based listing use `wps_dbsheet_list_records` instead. Requires delegated OAuth (`kso.dbsheet.read`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer)."},records:{type:"array",items:{type:"string"},description:"Array of record IDs to retrieve."},text_value:{type:"string",enum:["original","text","compound"],description:"Optional. Return value format."},show_fields_info:{type:"boolean",description:"Optional. Include field schema."},show_record_extra_info:{type:"boolean",description:"Optional. Include metadata."}},required:["wps_user_id","file_id","sheet_id","records"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Je(n),a=ct(n,"records");if(!a||a.length===0)throw new Error("records must be a non-empty array of record IDs");let l={records:a},c=V(n,"text_value");c!==void 0&&(l.text_value=c);let d=re(n,"show_fields_info");d!==void 0&&(l.show_fields_info=d);let p=re(n,"show_record_extra_info");return p!==void 0&&(l.show_record_extra_info=p),await Ee(o,"wps_dbsheet_get_records",async u=>{let _=await u.request({method:"POST",path:`${Ce(i)}/sheets/${s}/records/search`,body:l});return _.data??_})}catch(o){return se(o)}}}),t({name:"wps_dbsheet_get_record",description:"Get a single record (\u68C0\u7D22\u5355\u6761\u8BB0\u5F55): GET `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/{record_id}`. Retrieves a single record by its ID. Requires delegated OAuth (`kso.dbsheet.read`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer)."},record_id:{type:"string",description:"Record ID to retrieve."},text_value:{type:"string",enum:["original","text","compound"],description:"Optional. Return value format."},show_fields_info:{type:"boolean",description:"Optional. Include field schema."},show_record_extra_info:{type:"boolean",description:"Optional. Include metadata."}},required:["wps_user_id","file_id","sheet_id","record_id"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Je(n),a=T(n,"record_id"),l={},c=V(n,"text_value");c!==void 0&&(l.text_value=c);let d=re(n,"show_fields_info");d!==void 0&&(l.show_fields_info=d);let p=re(n,"show_record_extra_info");return p!==void 0&&(l.show_record_extra_info=p),await Ee(o,"wps_dbsheet_get_record",async u=>{let _=await u.request({method:"GET",path:`${Ce(i)}/sheets/${s}/records/${encodeURIComponent(a)}`,query:Object.keys(l).length>0?l:void 0});return _.data??_})}catch(o){return se(o)}}}),t({name:"wps_dbsheet_delete_records",description:"Delete records (\u6279\u91CF\u5220\u9664\u8BB0\u5F55): POST `/v7/coop/dbsheet/{file_id}/sheets/{sheet_id}/records/batch_delete`. Deletes one or more records by their IDs. This operation is irreversible. Requires delegated OAuth (`kso.dbsheet.readwrite`). Use current SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (current SenderId)."},file_id:{type:"string",description:"DBSheet file ID."},sheet_id:{type:"string",description:"Sheet ID (integer)."},records:{type:"array",items:{type:"string"},description:"Array of record IDs to delete."}},required:["wps_user_id","file_id","sheet_id","records"]},async execute(r,n){try{let o=T(n,"wps_user_id"),i=T(n,"file_id"),s=Je(n),a=ct(n,"records");if(!a||a.length===0)throw new Error("records must be a non-empty array of record IDs");return await Ee(o,"wps_dbsheet_delete_records",async l=>{let c=await l.request({method:"POST",path:`${Ce(i)}/sheets/${s}/records/batch_delete`,body:{records:a}});return c.data??c})}catch(o){return se(o)}}})}Le();import{createHash as Sc}from"node:crypto";import{readFile as kc,stat as xc}from"node:fs/promises";var vc="/v7/drives",Tc="/v7/files/search",Ec=50,Ac=500,Oc=50,Pc=500,$c=50,Rc=500,_s=["folder","file","shortcut"],Gr=["fail","rename","overwrite","replace"],Ss=["kdc","plain","markdown"],ks=["sync","async","auto"],Cc=["para","table","component","textbox","all"],ms=["file_name","content","all"],hs=["folder","file","shortcut"],gs=["ctime","mtime","otime","stime"],ys=["desc","asc"],ws=["ctime","mtime"],bs=["desc","asc"],Is=["ctime","mtime","dtime","fname","fsize"],Dc=["all","share_by_me","share_to_me","latest","personal_drive","group_drive","recycle","customize","latest_opened","latest_edited"];function Ve(e){return{error:e instanceof Error?e.message:String(e)}}function j(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function U(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}function Wt(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function de(e,t){let r=e[t];if(r!=null){if(typeof r=="boolean")return r;if(r==="true"||r==="false")return r==="true";throw new Error(`${t} must be a boolean`)}}function J(e,t){let r=e[t];if(r==null)return;if(!Array.isArray(r))throw new Error(`${t} must be an array of strings`);let n=r.map(o=>String(o).trim()).filter(Boolean);return n.length>0?n:void 0}function Xe(e){let t=U(e,"x_kso_id_type");if(t===void 0||t.trim()==="")return;let r=t.trim();if(r!=="internal"&&r!=="external")throw new Error("x_kso_id_type must be internal or external when provided");return{"X-Kso-Id-Type":r}}function qc(e){let t={};for(let[r,n]of Object.entries(e.requestHeaders)){let o=r.trim();if(o==="")continue;let i=o.toLowerCase();i==="content-length"||i==="transfer-encoding"||i==="content-type"||(t[o]=n)}return t["Content-Type"]="application/octet-stream",t}function Uc(e){let t=e.trim();if(!t)throw new Error("url is required and must be a non-empty string");let r;try{r=new URL(t)}catch{throw new Error("url must be an absolute URL from step-1 data.store_request.url (e.g. https://...); relative paths are not supported")}if(r.protocol!=="https:"&&r.protocol!=="http:")throw new Error(`url must use http: or https: scheme, got: ${r.protocol}`)}function Nc(e){let t={allotee_type:e.alloteeType,page_size:Math.max(1,Math.min(Ac,Math.trunc(e.pageSize??Ec)))};return e.alloteeId!==void 0&&e.alloteeId.trim()!==""&&(t.allotee_id=e.alloteeId.trim()),e.withExtAttrs!==void 0&&(t.with_ext_attrs=e.withExtAttrs),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(t.page_token=e.pageToken.trim()),e.sources!==void 0&&e.sources.length>0&&(t.sources=[...e.sources]),t}function jc(e,t){return`/v7/drives/${encodeURIComponent(e.trim())}/files/${encodeURIComponent(t.trim())}/create`}function Mc(e,t){return`/v7/drives/${encodeURIComponent(e.trim())}/files/${encodeURIComponent(t.trim())}/children`}function Wc(e){let t={page_size:Math.max(1,Math.min(Rc,Math.trunc(e.pageSize??$c)))};return e.withPermission!==void 0&&(t.with_permission=e.withPermission),e.withExtAttrs!==void 0&&(t.with_ext_attrs=e.withExtAttrs),e.filterExts!==void 0&&e.filterExts.trim()!==""&&(t.filter_exts=e.filterExts.trim()),e.filterType!==void 0&&Object.keys(e.filterType).length>0&&(t.filter_type=JSON.stringify(e.filterType)),e.order!==void 0&&(t.order=e.order),e.orderBy!==void 0&&(t.order_by=e.orderBy),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(t.page_token=e.pageToken.trim()),t}function Lc(e,t){return`/v7/drives/${encodeURIComponent(e.trim())}/files/${encodeURIComponent(t.trim())}/request_upload`}function zc(e,t){return`/v7/drives/${encodeURIComponent(e.trim())}/files/${encodeURIComponent(t.trim())}/commit_upload`}function Fc(e){let t=e.name.trim();if(!t)throw new Error("name must be a non-empty string");let r={file_type:e.fileType,name:t};if(e.fileType==="shortcut"){if(!e.fileId||!e.fileId.trim())throw new Error("file_id is required when file_type is shortcut");r.file_id=e.fileId.trim()}else e.fileId!==void 0&&e.fileId.trim()!==""&&(r.file_id=e.fileId.trim());return e.onNameConflict!==void 0&&(r.on_name_conflict=e.onNameConflict),e.parentPath!==void 0&&e.parentPath.length>0&&(r.parent_path=[...e.parentPath]),r}function Bc(e){let t={size:Math.max(0,Math.trunc(e.size))};return e.fileId!==void 0&&e.fileId.trim()!==""&&(t.file_id=e.fileId.trim()),e.hashes!==void 0&&e.hashes.length>0&&(t.hashes=e.hashes.map(r=>({type:r.type,sum:r.sum.trim()}))),e.internal!==void 0&&(t.internal=e.internal),e.name!==void 0&&e.name.trim()!==""&&(t.name=e.name.trim()),e.onNameConflict!==void 0&&(t.on_name_conflict=e.onNameConflict),e.parentPath!==void 0&&e.parentPath.length>0&&(t.parent_path=[...e.parentPath]),e.storageBaseDomain!==void 0&&e.storageBaseDomain.trim()!==""&&(t.storage_base_domain=e.storageBaseDomain.trim()),e.uploadScene!==void 0&&e.uploadScene.trim()!==""&&(t.upload_scene=e.uploadScene.trim()),t}function Gc(e){let t={};return e.id!==void 0&&e.id.trim()!==""&&(t.id=e.id.trim()),e.uploadId!==void 0&&e.uploadId.trim()!==""&&(t.upload_id=e.uploadId.trim()),t}function Hc(e,t){return`/v7/drives/${encodeURIComponent(e.trim())}/files/${encodeURIComponent(t.trim())}/content`}function Kc(e){let t={};if(e.format!==void 0&&e.format.trim()!==""){let r=e.format.trim();if(!Ss.includes(r))throw new Error("format must be one of: kdc, plain, markdown");t.format=r}if(e.includeElements!==void 0&&e.includeElements.length>0){let r=e.includeElements.map(n=>n.trim()).filter(Boolean).filter((n,o,i)=>i.indexOf(n)===o);for(let n of r)if(!Cc.includes(n))throw new Error("include_elements items must be one of: para, table, component, textbox, all");r.length>0&&(t.include_elements=r)}if(e.mode!==void 0&&e.mode.trim()!==""){let r=e.mode.trim();if(!ks.includes(r))throw new Error("mode must be one of: sync, async, auto");t.mode=r}return e.taskId!==void 0&&e.taskId.trim()!==""&&(t.task_id=e.taskId.trim()),t}function Jc(e){return`/v7/files/${encodeURIComponent(e.trim())}/meta`}function Xc(e){let t={};return e.withPermission!==void 0&&(t.with_permission=e.withPermission),e.withExtAttrs!==void 0&&(t.with_ext_attrs=e.withExtAttrs),e.withDrive!==void 0&&(t.with_drive=e.withDrive),t}function Vc(e){let t={type:e.type,page_size:Math.max(1,Math.min(Pc,Math.trunc(e.pageSize??Oc)))};return e.keyword!==void 0&&e.keyword.trim()!==""&&(t.keyword=e.keyword.trim()),e.fileType!==void 0&&(t.file_type=e.fileType),e.fileExts!==void 0&&e.fileExts.length>0&&(t.file_exts=[...e.fileExts]),e.driveIds!==void 0&&e.driveIds.length>0&&(t.drive_ids=[...e.driveIds]),e.parentIds!==void 0&&e.parentIds.length>0&&(t.parent_ids=[...e.parentIds]),e.creatorIds!==void 0&&e.creatorIds.length>0&&(t.creator_ids=[...e.creatorIds]),e.modifierIds!==void 0&&e.modifierIds.length>0&&(t.modifier_ids=[...e.modifierIds]),e.sharerIds!==void 0&&e.sharerIds.length>0&&(t.sharer_ids=[...e.sharerIds]),e.receiverIds!==void 0&&e.receiverIds.length>0&&(t.receiver_ids=[...e.receiverIds]),e.timeType!==void 0&&(t.time_type=e.timeType),e.startTime!==void 0&&(t.start_time=Math.trunc(e.startTime)),e.endTime!==void 0&&(t.end_time=Math.trunc(e.endTime)),e.withPermission!==void 0&&(t.with_permission=e.withPermission),e.withLink!==void 0&&(t.with_link=e.withLink),e.withTotal!==void 0&&(t.with_total=e.withTotal),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(t.page_token=e.pageToken.trim()),e.channels!==void 0&&e.channels.length>0&&(t.channels=[...e.channels]),e.deviceIds!==void 0&&e.deviceIds.length>0&&(t.device_ids=[...e.deviceIds]),e.excludeChannels!==void 0&&e.excludeChannels.length>0&&(t.exclude_channels=[...e.excludeChannels]),e.excludeFileExts!==void 0&&e.excludeFileExts.length>0&&(t.exclude_file_exts=[...e.excludeFileExts]),e.filterUserId!==void 0&&(t.filter_user_id=Math.trunc(e.filterUserId)),e.fileExtGroups!==void 0&&e.fileExtGroups.length>0&&(t.file_ext_groups=[...e.fileExtGroups]),e.withFolder!==void 0&&(t.with_folder=e.withFolder),e.withDrive!==void 0&&(t.with_drive=e.withDrive),e.order!==void 0&&(t.order=e.order),e.orderBy!==void 0&&(t.order_by=e.orderBy),e.scope!==void 0&&e.scope.length>0&&(t.scope=[...e.scope]),e.searchOperatorName!==void 0&&(t.search_operator_name=e.searchOperatorName),t}async function ut(e,t,r,n){try{return await _e({wpsUserId:e,toolModule:"cloud-doc",authCardOriginalMessage:t,needsAuthMessage:r,logTag:"drive",run:n})}catch(o){return Ve(o)}}function ci(e,t){t({name:"wps_cloud_doc_list_drives",description:"List cloud drives (\u83B7\u53D6\u76D8\u5217\u8868): GET `/v7/drives`. Requires delegated OAuth (`kso.drive.readwrite`). Use SenderId as `wps_user_id`. Required query: `allotee_type` (`user` | `group` | `app`). Optional `allotee_id` can be supplied for user/group/app scopes. Optional: `with_ext_attrs`, `page_size` (default 50, max 500), `page_token`, `sources` (array). Optional `x_kso_id_type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},allotee_type:{type:"string",description:"Drive allocation type.",enum:["user","group","app"]},allotee_id:{type:"string",description:"Optional allocation id for user/group/app scope."},with_ext_attrs:{type:"boolean",description:"Optional. Include ext_attrs in response."},page_size:{type:"number",description:"Optional. Page size (default 50, max 500)."},page_token:{type:"string",description:"Optional pagination token."},sources:{type:"array",items:{type:"string"},description:"Optional source filters."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","allotee_type"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"allotee_type");if(i!=="user"&&i!=="group"&&i!=="app")throw new Error("allotee_type must be user, group, or app");let s=i,a=U(n,"allotee_id"),l=de(n,"with_ext_attrs"),c=Wt(n,"page_size"),d=U(n,"page_token"),p=J(n,"sources");return await ut(o,"\u83B7\u53D6\u76D8\u5217\u8868","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u8BBF\u95EE\u4E91\u6587\u6863\u76D8\u5217\u8868\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async u=>{let _=Nc({alloteeType:s,alloteeId:a,withExtAttrs:l,pageSize:c,pageToken:d,sources:p}),f=await u.request({method:"GET",path:vc,query:_,headers:Xe(n)});return f.data??f})}catch(o){return Ve(o)}}}),t({name:"wps_cloud_doc_list_children_files",description:"List child files under a parent folder (\u83B7\u53D6\u5B50\u6587\u4EF6\u5217\u8868): GET `/v7/drives/{drive_id}/files/{parent_id}/children`. Requires delegated OAuth (`kso.file.read`). Use SenderId as `wps_user_id`. Required: `drive_id`, `parent_id` (root parent_id is `0`). Optional query: `with_permission`, `with_ext_attrs`, `filter_exts`, `filter_type`, `order`, `order_by`, `page_size`, `page_token`. Optional `x_kso_id_type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId)."},drive_id:{type:"string",description:"Drive ID."},parent_id:{type:"string",description:"Parent folder id (root is `0`)."},with_permission:{type:"boolean",description:"Optional. Include operation permissions in response."},with_ext_attrs:{type:"boolean",description:"Optional. Include file ext_attrs in response."},filter_exts:{type:"string",description:"Optional. Extension filter string separated by semicolons, e.g. `docx;xlsx`."},filter_type:{type:"object",description:"Optional file type filter object (passed through to API query `filter_type`).",additionalProperties:!0},order:{type:"string",enum:[...bs],description:"Optional order direction."},order_by:{type:"string",enum:[...Is],description:"Optional order field."},page_size:{type:"number",description:"Optional page size (default 50, max 500)."},page_token:{type:"string",description:"Optional pagination token."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","drive_id","parent_id"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"drive_id"),s=j(n,"parent_id"),a=de(n,"with_permission"),l=de(n,"with_ext_attrs"),c=U(n,"filter_exts"),d=Wt(n,"page_size"),p=U(n,"page_token"),u=U(n,"order");if(u!==void 0&&!bs.includes(u))throw new Error("order must be one of: desc, asc");let _=u,f=U(n,"order_by");if(f!==void 0&&!Is.includes(f))throw new Error("order_by must be one of: ctime, mtime, dtime, fname, fsize");let g=f,y=n.filter_type,m;if(y!=null){if(typeof y!="object"||Array.isArray(y))throw new Error("filter_type must be an object when provided");m=y}return await ut(o,"\u83B7\u53D6\u5B50\u6587\u4EF6\u5217\u8868","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u83B7\u53D6\u5B50\u6587\u4EF6\u5217\u8868\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async h=>{let w=Wc({withPermission:a,withExtAttrs:l,filterExts:c,filterType:m,order:_,orderBy:g,pageSize:d,pageToken:p}),b=await h.request({method:"GET",path:Mc(i,s),query:w,headers:Xe(n)});return b.data??b})}catch(o){return Ve(o)}}}),t({name:"wps_cloud_doc_create_file",description:"Create file/folder/shortcut (\u65B0\u5EFA\u6587\u4EF6(\u5939)): POST `/v7/drives/{drive_id}/files/{parent_id}/create`. Requires delegated OAuth (`kso.file.readwrite`). Use SenderId as `wps_user_id`. Required: `drive_id`, `parent_id`, `file_type` (`folder` | `file` | `shortcut`), `name`. When `file_type` is `shortcut`, `file_id` is required. Optional: `on_name_conflict` (`fail` | `rename` | `overwrite` | `replace`), `parent_path` (string array). Optional `x_kso_id_type` header (`internal` | `external`).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},drive_id:{type:"string",description:"Drive ID."},parent_id:{type:"string",description:"Parent file/folder ID (root is 0)."},file_type:{type:"string",enum:[..._s],description:"Created resource type: folder, file, or shortcut."},name:{type:"string",description:"Name to create. Include extension for files when needed."},file_id:{type:"string",description:"Required only for file_type=shortcut (target file id)."},on_name_conflict:{type:"string",enum:[...Gr],description:"Name conflict behavior."},parent_path:{type:"array",items:{type:"string"},description:"Optional relative nested path array under parent_id."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","drive_id","parent_id","file_type","name"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"drive_id"),s=j(n,"parent_id"),a=j(n,"file_type");if(!_s.includes(a))throw new Error("file_type must be one of: folder, file, shortcut");let l=a,c=j(n,"name"),d=U(n,"file_id"),p=U(n,"on_name_conflict");if(p!==void 0&&!Gr.includes(p))throw new Error("on_name_conflict must be one of: fail, rename, overwrite, replace");let u=p,_=J(n,"parent_path");return await ut(o,"\u65B0\u5EFA\u6587\u4EF6\uFF08\u5939\uFF09","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u65B0\u5EFA\u4E91\u6587\u6863\u6587\u4EF6\uFF08\u5939\uFF09\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async f=>{let g=Fc({fileType:l,name:c,fileId:d,onNameConflict:u,parentPath:_}),y=await f.request({method:"POST",path:jc(i,s),body:g,headers:Xe(n)});return y.data??y})}catch(o){return Ve(o)}}}),t({name:"wps_cloud_doc_upload_file",description:"**THE ONLY tool for uploading files** (\u4E00\u4F53\u5316\u4E0A\u4F20). Combines step-1 request_upload, step-2 upload bytes, and step-3 commit_upload into a **single tool call**. Pass `file_path` (local file path, e.g. from prefetched attachment `localPath`); the plugin reads the file directly from disk. The plugin computes `size` and `sha256` hash from the actual file bytes \u2014 **no need for the caller to compute or pass `size` / `hashes`**. This avoids `ContentLengthInvalid` and `BadDigest` errors (no base64 encoding, no truncation risk). Requires delegated OAuth (`kso.file.readwrite`). Use SenderId as `wps_user_id`. Returns the final committed file object.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId)."},drive_id:{type:"string",description:"Drive ID."},parent_id:{type:"string",description:"Parent file/folder ID (root is 0)."},file_path:{type:"string",description:"Absolute path to the local file to upload (e.g. from prefetched attachment `localPath`). The plugin reads bytes directly from disk \u2014 no base64 encoding needed, no truncation risk."},name:{type:"string",description:"Filename for the uploaded file (e.g. 'report.doc'). If omitted, the filename is extracted from `file_path`."},on_name_conflict:{type:"string",enum:[...Gr],description:"Optional name conflict behavior (default: server decides)."},file_id:{type:"string",description:"Optional target file id for update upload."},internal:{type:"boolean",description:"Optional internal endpoint preference."},upload_scene:{type:"string",description:"Optional upload scene."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","drive_id","parent_id","file_path"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"drive_id"),s=j(n,"parent_id"),a=j(n,"file_path"),l=U(n,"name"),c=U(n,"on_name_conflict");if(c!==void 0&&!Gr.includes(c))throw new Error("on_name_conflict must be one of: fail, rename, overwrite, replace");let d=c,p=U(n,"file_id"),u=de(n,"internal"),_=U(n,"upload_scene"),f=a.trim();try{if(!(await xc(f)).isFile())throw new Error("path is not a regular file")}catch(h){throw new Error(`file_path "${f}" is not accessible: ${h instanceof Error?h.message:String(h)}`)}let g=await kc(f);if(!l){let h=Math.max(f.lastIndexOf("/"),f.lastIndexOf("\\")),b=(h>=0?f.substring(h+1):f).replace(/^[0-9a-f]{8}_/i,"");b&&(l=b)}if(g.byteLength===0)throw new Error("upload content is empty (file has zero bytes)");let y=g.byteLength,m=Sc("sha256").update(g).digest("hex");return await ut(o,"\u4E00\u4F53\u5316\u4E0A\u4F20\u6587\u4EF6","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u4E0A\u4F20\u4E91\u6587\u6863\u6587\u4EF6\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async(h,w)=>{let b=Bc({size:y,fileId:p??void 0,hashes:[{type:"sha256",sum:m}],internal:u??void 0,name:l??void 0,onNameConflict:d,uploadScene:_??void 0}),I=await h.request({method:"POST",path:Lc(i,s),body:b,headers:Xe(n)}),x=I.data??I,M=x.store_request;if(!M||typeof M.url!="string"||!M.url.trim())throw new Error(`step-1 response missing store_request.url \u2014 cannot proceed with upload. Response: ${JSON.stringify(x).substring(0,300)}`);let K=typeof M.method=="string"?M.method.toUpperCase():"PUT",F=M.url;Uc(F);let W=M.headers??{},ne=typeof x.upload_id=="string"?x.upload_id:void 0,ee=ve(w,o);if(!ee||!ee.trim())throw new Error("delegated access token missing after auth gate");let ce=qc({requestHeaders:W}),gt={Authorization:`Bearer ${ee.trim()}`,...ce},zt=new Uint8Array(g.buffer,g.byteOffset,g.byteLength),Ze;try{Ze=await fetch(F,{method:K,headers:gt,body:zt})}catch(Se){let $=Se instanceof Error?Se.message:String(Se);throw new Error(`upload step-2 fetch failed: ${$}. Check outbound HTTPS/DNS/firewall from the gateway to the presigned URL.`)}if(!Ze.ok){let Se=await Ze.text().catch(()=>"");throw new Error(`upload step-2 failed: HTTP ${Ze.status} ${Se.substring(0,300)} [diag: size=${y}, sha256=${m}]`)}if(!ne)return{step1:x,step2_status:Ze.status,etag:Ze.headers.get("etag")??void 0,warning:"upload_id missing from step-1 \u2014 skipped commit_upload."};let lr=Gc({uploadId:ne}),yt=await h.request({method:"POST",path:zc(i,s),body:lr,headers:Xe(n)});return yt.data??yt})}catch(o){return Ve(o)}}}),t({name:"wps_cloud_doc_extract_file_content",description:"Extract file content (\u6587\u6863\u5185\u5BB9\u62BD\u53D6): GET `/v7/drives/{drive_id}/files/{file_id}/content`. Requires delegated OAuth (`kso.file.read`). Use SenderId as `wps_user_id`. Required: `drive_id`, `file_id`. Optional query: `format` (`kdc` | `plain` | `markdown`), `include_elements` (`para` | `table` | `component` | `textbox` | `all`), `mode` (`sync` | `async` | `auto`), `task_id`. Returns upstream `data` as-is (for fields like `task_id`, `task_status`, `doc`, `markdown`, `plain`, etc.).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},drive_id:{type:"string",description:"Drive ID."},file_id:{type:"string",description:"File ID."},format:{type:"string",enum:[...Ss],description:"Optional output format."},include_elements:{type:"array",items:{type:"string"},description:"Optional extracted element types."},mode:{type:"string",enum:[...ks],description:"Optional extraction mode."},task_id:{type:"string",description:"Optional task id for async/auto result polling."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","drive_id","file_id"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"drive_id"),s=j(n,"file_id"),a=U(n,"format"),l=J(n,"include_elements"),c=U(n,"mode"),d=U(n,"task_id");return await ut(o,"\u6587\u6863\u5185\u5BB9\u62BD\u53D6","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u8FDB\u884C\u6587\u6863\u5185\u5BB9\u62BD\u53D6\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async p=>{let u=Kc({format:a,includeElements:l,mode:c,taskId:d}),_=await p.request({method:"GET",path:Hc(i,s),query:Object.keys(u).length>0?u:void 0,headers:Xe(n)});return _.data??_})}catch(o){return Ve(o)}}}),t({name:"wps_cloud_doc_get_file_meta",description:"Get file metadata (\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F): GET `/v7/files/{file_id}/meta`. Requires delegated OAuth (`kso.file.read`). Use SenderId as `wps_user_id`. Required: `file_id`. Optional query: `with_permission`, `with_ext_attrs`, `with_drive` (boolean). Returns upstream `data` as-is (for fields like `drive`, `permission`, `ext_attrs`, etc.).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"File ID."},with_permission:{type:"boolean",description:"Optional. Include permission field in response."},with_ext_attrs:{type:"boolean",description:"Optional. Include ext_attrs field in response."},with_drive:{type:"boolean",description:"Optional. Include drive field in response."},x_kso_id_type:{type:"string",description:"Optional. Sent as X-Kso-Id-Type: internal or external.",enum:["internal","external"]}},required:["wps_user_id","file_id"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"file_id"),s=de(n,"with_permission"),a=de(n,"with_ext_attrs"),l=de(n,"with_drive");return await ut(o,"\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u83B7\u53D6\u6587\u4EF6\u4FE1\u606F\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async c=>{let d=Xc({withPermission:s,withExtAttrs:a,withDrive:l}),p=await c.request({method:"GET",path:Jc(i),query:Object.keys(d).length>0?d:void 0,headers:Xe(n)});return p.data??p})}catch(o){return Ve(o)}}}),t({name:"wps_cloud_doc_search_files",description:"Search files (\u6587\u4EF6\u641C\u7D22): GET `/v7/files/search`. Requires delegated OAuth (`kso.file.read`). Use SenderId as `wps_user_id`. Required query: `type` (`file_name` | `content` | `all`), `page_size` (default 50, max 500). Supports optional filters: keyword, file_type, file_exts, drive_ids, parent_ids, creator_ids, modifier_ids, sharer_ids, receiver_ids, time_type/start_time/end_time, with_permission/with_link/with_total, page_token, channels/device_ids/exclude_channels/exclude_file_exts, filter_user_id, file_ext_groups, with_folder, with_drive, order/order_by, scope, search_operator_name.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId)."},keyword:{type:"string",description:"Optional search keyword."},type:{type:"string",enum:[...ms],description:"Search type."},file_type:{type:"string",enum:[...hs],description:"Optional file type filter."},file_exts:{type:"array",items:{type:"string"},description:"Optional file extension filters."},drive_ids:{type:"array",items:{type:"string"},description:"Optional drive id filters."},parent_ids:{type:"array",items:{type:"string"},description:"Optional parent id filters."},creator_ids:{type:"array",items:{type:"string"},description:"Optional creator id filters."},modifier_ids:{type:"array",items:{type:"string"},description:"Optional modifier id filters."},sharer_ids:{type:"array",items:{type:"string"},description:"Optional sharer id filters."},receiver_ids:{type:"array",items:{type:"string"},description:"Optional receiver id filters."},time_type:{type:"string",enum:[...gs],description:"Optional time type."},start_time:{type:"number",description:"Optional start time (unix seconds)."},end_time:{type:"number",description:"Optional end time (unix seconds)."},with_permission:{type:"boolean",description:"Optional. Include permission fields."},with_link:{type:"boolean",description:"Optional. Include sharing link fields."},with_total:{type:"boolean",description:"Optional. Include total count in response."},page_size:{type:"number",description:"Optional. Default 50, max 500."},page_token:{type:"string",description:"Optional pagination token."},channels:{type:"array",items:{type:"string"},description:"Optional channel filters."},device_ids:{type:"array",items:{type:"string"},description:"Optional device filters."},exclude_channels:{type:"array",items:{type:"string"},description:"Optional excluded channel filters."},exclude_file_exts:{type:"array",items:{type:"string"},description:"Optional excluded file extension filters."},filter_user_id:{type:"number",description:"Optional filter user id."},file_ext_groups:{type:"array",items:{type:"string"},description:"Optional file extension groups."},with_folder:{type:"boolean",description:"Optional include folder results."},with_drive:{type:"boolean",description:"Optional include drive info."},order:{type:"string",enum:[...ys],description:"Optional order."},order_by:{type:"string",enum:[...ws],description:"Optional order by field."},scope:{type:"array",items:{type:"string"},description:"Optional search scopes."},search_operator_name:{type:"boolean",description:"Optional search by operator name switch."},x_kso_id_type:{type:"string",enum:["internal","external"],description:"Optional. Sent as X-Kso-Id-Type."}},required:["wps_user_id","type"]},async execute(r,n){try{let o=j(n,"wps_user_id"),i=j(n,"type");if(!ms.includes(i))throw new Error("type must be one of: file_name, content, all");let s=i,a=U(n,"file_type");if(a!==void 0&&!hs.includes(a))throw new Error("file_type must be one of: folder, file, shortcut");let l=a,c=U(n,"time_type");if(c!==void 0&&!gs.includes(c))throw new Error("time_type must be one of: ctime, mtime, otime, stime");let d=c,p=U(n,"order");if(p!==void 0&&!ys.includes(p))throw new Error("order must be one of: desc, asc");let u=p,_=U(n,"order_by");if(_!==void 0&&!ws.includes(_))throw new Error("order_by must be one of: ctime, mtime");let f=_,g=J(n,"scope");if(g!==void 0){for(let y of g)if(!Dc.includes(y))throw new Error("scope items must be one of: all, share_by_me, share_to_me, latest, personal_drive, group_drive, recycle, customize, latest_opened, latest_edited")}return await ut(o,"\u6587\u4EF6\u641C\u7D22","\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u641C\u7D22\u4E91\u6587\u6863\u6587\u4EF6\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",async y=>{let m=Vc({keyword:U(n,"keyword"),type:s,fileType:l,fileExts:J(n,"file_exts"),driveIds:J(n,"drive_ids"),parentIds:J(n,"parent_ids"),creatorIds:J(n,"creator_ids"),modifierIds:J(n,"modifier_ids"),sharerIds:J(n,"sharer_ids"),receiverIds:J(n,"receiver_ids"),timeType:d,startTime:Wt(n,"start_time"),endTime:Wt(n,"end_time"),withPermission:de(n,"with_permission"),withLink:de(n,"with_link"),withTotal:de(n,"with_total"),pageSize:Wt(n,"page_size"),pageToken:U(n,"page_token"),channels:J(n,"channels"),deviceIds:J(n,"device_ids"),excludeChannels:J(n,"exclude_channels"),excludeFileExts:J(n,"exclude_file_exts"),filterUserId:Wt(n,"filter_user_id"),fileExtGroups:J(n,"file_ext_groups"),withFolder:de(n,"with_folder"),withDrive:de(n,"with_drive"),order:u,orderBy:f,scope:g,searchOperatorName:de(n,"search_operator_name")}),h=await y.request({method:"GET",path:Tc,query:m,headers:Xe(n)});return h.data??h})}catch(o){return Ve(o)}}})}var Yc="/v7/airpage/files";function ft(e,t){return`/v7/airpage/${encodeURIComponent(e.trim())}${t}`}function mt(e){return{arg:Buffer.from(JSON.stringify(e),"utf8").toString("base64")}}function _t(e,t){return e.length>36?`${t} (${e.slice(0,36)}...)`:`${t} (${e})`}function vs(e,t){let r=e.operation,n=e.blockId;if(typeof r!="string"||!r.trim())throw new Error(`${t}.operation is required and must be a non-empty string`);if(typeof n!="string"||!n.trim())throw new Error(`${t}.blockId is required and must be a non-empty string`)}var li=["rename","fail","overwrite"];function De(e){return{error:e instanceof Error?e.message:String(e)}}function N(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function xs(e,t){let r=e[t];if(r==null)return;if(typeof r!="string")throw new Error(`${t} must be a string`);let n=r.trim();return n===""?void 0:n}function Kr(e,t){let r=e[t];if(!Array.isArray(r))throw new Error(`${t} is required and must be an array`);return r}function Zc(e,t){let n=Kr(e,t).map(o=>String(o).trim()).filter(Boolean);if(n.length===0)throw new Error(`${t} must contain at least one non-empty string`);return n}function Qc(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return Math.max(0,Math.trunc(r));if(typeof r=="string"&&r.trim()!==""){let n=Number(r.trim());if(Number.isFinite(n))return Math.max(0,Math.trunc(n))}throw new Error(`${t} must be a finite integer when provided`)}}function Hr(e,t){let r=e[t];if(r==null)throw new Error(`${t} is required and must be a finite integer`);if(typeof r=="number"&&Number.isFinite(r))return Math.trunc(r);if(typeof r=="string"&&r.trim()!==""){let n=Number(r.trim());if(Number.isFinite(n))return Math.trunc(n)}throw new Error(`${t} must be a finite integer`)}function el(e){let t={blockId:e.blockId.trim(),content:e.content},r=e.index;return r!==void 0&&(t.index=r),mt(t)}function tl(e){let t={blockId:e.blockId.trim()};return mt(t)}function rl(e){let t={blockIds:e.blockIds.map(r=>r.trim()).filter(Boolean)};if(t.blockIds.length===0)throw new Error("blockIds must contain at least one non-empty id");return mt(t)}function nl(e){if(e.endIndex<=e.startIndex)throw new Error("endIndex must be greater than startIndex");let t={blockId:e.blockId.trim(),startIndex:Math.trunc(e.startIndex),endIndex:Math.trunc(e.endIndex)};if(!t.blockId)throw new Error("blockId must be non-empty");return mt(t)}function il(e){if(!Array.isArray(e)||e.length===0)throw new Error("delete_items must contain at least one delete range");let t=e.map(r=>{let n=r.blockId.trim(),o=Math.trunc(r.startIndex),i=Math.trunc(r.endIndex);if(!n)throw new Error("delete_items.blockId must be non-empty");if(i<=o)throw new Error("delete_items.endIndex must be greater than delete_items.startIndex");return{blockId:n,startIndex:o,endIndex:i}});return mt(t)}function ol(e){return vs(e,"operation"),mt(e)}function sl(e){if(!Array.isArray(e)||e.length===0)throw new Error("operations must contain at least one operation object");for(let[t,r]of e.entries()){if(!r||typeof r!="object"||Array.isArray(r))throw new Error(`operations[${t}] must be an object`);vs(r,`operations[${t}]`)}return mt(e)}function al(e){let t=e.trim().toLowerCase();if(li.includes(t))return t;throw new Error(`on_name_conflict must be one of: ${li.join(", ")} (got: ${e})`)}function dl(e){let t={drive_id:e.driveId,name:e.name,on_name_conflict:e.onNameConflict};return e.parentId!==void 0&&(t.parent_id=e.parentId),e.templateId!==void 0&&(t.template_id=e.templateId),t}async function Ye(e,t,r){try{return await _e({wpsUserId:e,toolModule:"airpage",authCardOriginalMessage:t,needsAuthMessage:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u64CD\u4F5C\u667A\u80FD\u6587\u6863\uFF08Airpage\uFF09\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u5B8C\u6210\u6388\u6743\u540E\u91CD\u8BD5\u3002",logTag:"airpage",run:r})}catch(n){return De(n)}}function pi(e,t){t({name:"wps_airpage_create_file",description:"Create a blank Smart Document (Airpage / \u667A\u80FD\u6587\u6863) via WPS OpenAPI: POST `/v7/airpage/files`. Requires user delegated OAuth with scope `kso.airpage.readwrite` (or equivalent). Use SenderId as `wps_user_id`. Required: `drive_id`, `name` (document title without file extension), `on_name_conflict` (`rename` | `fail` | `overwrite`). Optional: `parent_id` (parent folder id), `template_id` (create from template). Obtain `drive_id` via `wps_cloud_doc_list_drives`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},drive_id:{type:"string",description:"Target drive id (from wps_cloud_doc_list_drives)."},name:{type:"string",description:"Document name without extension (per API)."},on_name_conflict:{type:"string",enum:[...li],description:"Strategy when the name already exists: rename, fail, or overwrite."},parent_id:{type:"string",description:"Optional parent folder id."},template_id:{type:"string",description:"Optional template id to create from."}},required:["wps_user_id","drive_id","name","on_name_conflict"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"drive_id"),s=N(n,"name"),a=N(n,"on_name_conflict"),l=al(a),c=xs(n,"parent_id"),d=xs(n,"template_id"),p=`\u521B\u5EFA\u667A\u80FD\u6587\u6863: ${s}`;return await Ye(o,p,async u=>{let _=dl({driveId:i,name:s,onNameConflict:l,parentId:c,templateId:d}),f=await u.request({method:"POST",path:Yc,body:_});return f.data??f})}catch(o){return De(o)}}}),t({name:"wps_airpage_create_block_content",description:'Insert block content into a Smart Document (Airpage): POST `/v7/airpage/{file_id}/blocks/create`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON). JSON fields: `blockId` (parent block; use literal `doc` for document root), optional `index` (insert position; omit for API default 0), required `content` (array of child block nodes). Requires delegated `kso.airpage.readwrite`. Use SenderId as `wps_user_id`.\n\n## Block node types (used in `content` array):\nEach node: `{ type, attrs?, content? }`. `content` is an array of child blocks or inline nodes.\n\n- **title**: Document title (unique, must be first child of doc). attrs: `align` (1=left,2=center,3=right). content: inline nodes.\n- **paragraph**: Paragraph (also used for lists). attrs: `indent` (0|1), `contentIndent` (>=0), `align` (1|2|3), `listAttrs` `{id,type(1=unordered,2=ordered,3=task),styleType(1-13),level,styleFormat(1-9)}`. content: inline nodes.\n- **heading**: Heading h1-h6. attrs: `level` (1-6), `indent`, `contentIndent`, `align`, `listAttrs` (same as paragraph). content: inline nodes.\n- **blockQuote**: Quote block. attrs: `indent`, `contentIndent`, `align`. content: block nodes (paragraph, heading, etc.). Inline `br` for line breaks inside.\n- **codeBlock**: Code block. attrs: `lang` (1=plaintext,2=css,3=go,4=python,5=shell,...19=javascript,12=typescript,17=json,43=yaml, etc.), `autoWrap` (bool), `theme` (1=light,2=dark). content: text nodes (may contain `\\n`).\n- **highLightBlock**: Highlight block. attrs: `emoji` (required), `style {fontColor(1-12),backgroundColor(1-6),borderColor}`. content: block nodes. Cannot contain title, table, column, highLightBlock, lockBlock.\n- **lockBlock**: Content protection area (only file creator can edit). No attrs. content: block nodes. Cannot contain title, lockBlock.\n- **table**: Table. attrs: `borderStyle` (1=none,2=solid). content: tableRow nodes.\n - **tableRow**: Table row. No attrs. content: tableCell nodes.\n - **tableCell**: Cell. attrs: `width`, `height`, `colspan` (>=1), `rowspan` (>=1), `verticalAlign` (1=top,2=middle,3=bottom). content: block nodes.\n- **column**: Column layout (1-10 columns). attrs: `backgroundColor` (1-12). content: columnItem nodes.\n - **columnItem**: Column item. attrs: `width` (percent string e.g. "50.00%"), `backgroundColor` (1-42). content: block nodes.\n- **pictureColumn**: Side-by-side images (2-5). attrs: `width` (percent), `align` (1|2|3). content: picture nodes.\n- **picture**: Image. attrs (required: sourceKey, width, height): `sourceKey` (image resource id from attachment upload), `width`, `height`, `renderWidth`, `caption`, `rotate` (0|-90|-180|-270), `borderType` (0|1), `align`. No content.\n- **blockAnchor**: Placeholder. attrs (required: id, aimType, width, height): `id`, `aimType` (\'picture\'|\'video\'|\'processon\'|\'spreadsheet\'), `width`, `height`. No content.\n- **hr**: Horizontal rule. No attrs, no content.\n- **video**: Video. attrs (required: sourceId, sourceKey, width, height): `sourceId`, `sourceKey` (cover image id), `width`, `height`, `title`, `align`.\n- **audio**: Audio. attrs (required: sourceId): `sourceId`, `title`.\n- **videoLink**: Video link. attrs (required: url): `url`, `platform` (1=bilibili), `align`.\n- **countdown**: Countdown. attrs (required: type): `type` (1=date,2=time), `duration` (ms, 0-86399999000).\n- **map**: Map (Amap). attrs (required: lng, lat, address, addressName): `lng`, `lat`, `address`, `addressName`, `platform` (1), `mapZoom`, `align`.\n- **thirdResource**: 3rd-party embed. attrs (required: url): `url`, `type` (1=mooc,2=modao,3=masterGo,4=netease,5=aliyun,6=survey,7=figma,8=pixso,9=xiaohuazhuo), `align`.\n- **dbsheet**: Multi-dim table. attrs (required: sourceId): `sourceId`, `width`, `height`.\n- **spreadsheet**: Spreadsheet. attrs (required: sourceId): `sourceId`, `sheetId`.\n- **groupCard**: Group card. attrs (required: id, name, masterName): `id`, `name`, `masterName`.\n- **appComponent**: App plugin. attrs: `type` (1=vote,2=video_channel,...8=canvas).\n- **processon**: Flowchart/mindmap. attrs (required: type, sourceId, sourceKey, width, height): `type` (1=flow,2=mind), `sourceId`, `sourceKey`, `caption`, `rotate`, `width`, `height`, `renderWidth`, `borderType`, `align`.\n\n## Inline node types (used in content of paragraph, heading, blockQuote, title, codeBlock):\n- **text**: Text. `content` field is a non-empty string (only in codeBlock may contain `\\n`). Common attrs: `bold`, `italic`, `underline`, `strike`, `sup`, `sub` (all bool); `fontSize {fontSize: 9|11|13|15|16|19|22}`; `color {fontColor,backgroundColor,fontGradientColor(1-6)}`.\n- **emoji**: Emoji. attrs (required: emoji): single emoji character.\n- **br**: Line break (used inside blockQuote). No attrs.\n- **latex**: Formula. attrs (required: width, height, latexStr): `width`, `height`, `latexStr`.\n- **linkView**: Hyperlink view. attrs (required: title, url, viewType, sourceKey, description): `title`, `url`, `viewType` (1=title,2=card \u2014 card requires paragraph parent with no siblings), `sourceKey` (icon id), `description`.\n- **schedule**: Schedule. attrs (required: id, name, startTime, endTime): `id` (taskId|sid|teamId), `name`, `startTime` (unix ms), `endTime` (unix ms), `actionType` (1=partial,2=allday).\n- **staticTime**: Date. attrs (required: time): `time` (unix ms), `timeType` (1=date,2=datetime).\n- **WPSUser**: @mention. attrs (required: userId, name): `userId`, `name`, `avatar`.\n- **WPSDocument**: Cloud doc / local file. attrs (required: wpsDocumentId, wpsDocumentName, wpsDocumentType): `wpsDocumentId`, `wpsDocumentName`, `wpsDocumentType`, `wpsDocumentLink` (required for cloud doc), `viewType` (1=title,2=preview,3=card,4=attachment \u2014 2/3/4 require paragraph parent with no siblings), `size` (bytes, required for local file), `width`, `height`, `align`.\n\n## Examples:\nParagraph: `{"type":"paragraph","content":[{"type":"text","content":"Hello"}]}`\nHeading h2: `{"type":"heading","attrs":{"level":2},"content":[{"type":"text","content":"Title"}]}`\nBold text: `{"type":"paragraph","content":[{"type":"text","attrs":{"bold":true},"content":"bold text"}]}`\nOrdered list: `{"type":"paragraph","attrs":{"listAttrs":{"type":2,"styleType":4,"level":0}},"content":[{"type":"text","content":"item 1"}]}`\nCode block: `{"type":"codeBlock","attrs":{"lang":19},"content":[{"type":"text","content":"console.log(\'hi\')"}]}`\nTable 2x2: `{"type":"table","attrs":{"borderStyle":2},"content":[{"type":"tableRow","content":[{"type":"tableCell","attrs":{"width":200,"height":40},"content":[{"type":"paragraph","content":[{"type":"text","content":"A1"}]}]},{"type":"tableCell","attrs":{"width":200,"height":40},"content":[{"type":"paragraph","content":[{"type":"text","content":"B1"}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{"width":200,"height":40},"content":[{"type":"paragraph","content":[{"type":"text","content":"A2"}]}]},{"type":"tableCell","attrs":{"width":200,"height":40},"content":[{"type":"paragraph","content":[{"type":"text","content":"B2"}]}]}]}]}`',parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/create)."},block_id:{type:"string",description:"Parent block id. Use the string `doc` to insert under the document root; otherwise use a block id from the query-document-blocks API."},index:{type:"integer",description:"Optional insert position (0-based, must be >= 0). 0 = insert before first child. To append at the end, use a large number (e.g. 9999) or omit this field. Negative values are NOT supported and will cause API errors."},content:{type:"array",description:"Required array of block nodes to insert. Each node has `type` (string), optional `attrs` (object), and optional `content` (child nodes or text string for text nodes). See description above for all supported block and inline types.",items:{type:"object",additionalProperties:!0}}},required:["wps_user_id","file_id","block_id","content"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),s=N(n,"block_id"),a=Kr(n,"content"),l=Qc(n,"index"),c=el({blockId:s,content:a,index:l}),d=_t(i,"\u667A\u80FD\u6587\u6863\u521B\u5EFA\u5757\u5185\u5BB9");return await Ye(o,d,async p=>{let u=await p.request({method:"POST",path:ft(i,"/blocks/create"),body:c});return u.data??u})}catch(o){return De(o)}}}),t({name:"wps_airpage_query_document_blocks",description:"Query blocks from a Smart Document (Airpage): POST `/v7/airpage/{file_id}/blocks`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON). JSON fields: required `blockId` (use literal `doc` to query the whole document tree, or pass a specific block id to query its children). Requires delegated Airpage permission (`kso.airpage.read` or `kso.airpage.readwrite` depending on app grants). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks)."},block_id:{type:"string",description:"Target block id mapped to request JSON field blockId. Use doc to query entire document blocks."}},required:["wps_user_id","file_id","block_id"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),s=N(n,"block_id"),a=tl({blockId:s}),l=_t(i,"\u667A\u80FD\u6587\u6863\u67E5\u8BE2\u6587\u6863\u5757");return await Ye(o,l,async c=>{let d=await c.request({method:"POST",path:ft(i,"/blocks"),body:a});return d.data??d})}catch(o){return De(o)}}}),t({name:"wps_airpage_batch_query_document_blocks",description:"Batch query blocks from a Smart Document (Airpage): POST `/v7/airpage/{file_id}/blocks/batch_get`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON), with JSON field `blockIds` (string array). Use this when querying multiple specific block ids in one request. Requires delegated Airpage permission (`kso.airpage.read` or `kso.airpage.readwrite`). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/batch_get)."},block_ids:{type:"array",description:"Required block id list mapped to JSON blockIds for batch query.",items:{type:"string"}}},required:["wps_user_id","file_id","block_ids"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),s=Zc(n,"block_ids"),a=rl({blockIds:s}),l=_t(i,"\u667A\u80FD\u6587\u6863\u6279\u91CF\u67E5\u8BE2\u6587\u6863\u5757");return await Ye(o,l,async c=>{let d=await c.request({method:"POST",path:ft(i,"/blocks/batch_get"),body:a});return d.data??d})}catch(o){return De(o)}}}),t({name:"wps_airpage_delete_block_content",description:"Delete block content from a Smart Document (Airpage): POST `/v7/airpage/{file_id}/blocks/delete`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON), with JSON fields: `blockId`, `startIndex`, `endIndex` (`endIndex` must be > `startIndex`). Use SenderId as `wps_user_id`. Requires delegated `kso.airpage.readwrite`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/delete)."},block_id:{type:"string",description:"Parent block id mapped to JSON field blockId. Commonly use doc for document root."},start_index:{type:"integer",description:"Required delete start position (mapped to JSON startIndex)."},end_index:{type:"integer",description:"Required delete end position (mapped to JSON endIndex), must be greater than start_index."}},required:["wps_user_id","file_id","block_id","start_index","end_index"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),s=N(n,"block_id"),a=Hr(n,"start_index"),l=Hr(n,"end_index"),c=nl({blockId:s,startIndex:a,endIndex:l}),d=_t(i,"\u667A\u80FD\u6587\u6863\u5220\u9664\u5757\u5185\u5BB9");return await Ye(o,d,async p=>{let u=await p.request({method:"POST",path:ft(i,"/blocks/delete"),body:c});return u.data??u})}catch(o){return De(o)}}}),t({name:"wps_airpage_batch_delete_block_content",description:"Batch delete block content ranges from a Smart Document (Airpage): POST `/v7/airpage/{file_id}/blocks/batch_delete`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON), with JSON as an array of delete-range objects: `[{ blockId, startIndex, endIndex }]` and each item requires `endIndex > startIndex`. Use SenderId as `wps_user_id`. Requires delegated `kso.airpage.readwrite`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/batch_delete)."},delete_items:{type:"array",description:"Required delete range array. Each item: block_id, start_index, end_index (end_index > start_index).",items:{type:"object",properties:{block_id:{type:"string"},start_index:{type:"integer"},end_index:{type:"integer"}},required:["block_id","start_index","end_index"]}}},required:["wps_user_id","file_id","delete_items"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),a=Kr(n,"delete_items").map((d,p)=>{if(!d||typeof d!="object"||Array.isArray(d))throw new Error(`delete_items[${p}] must be an object`);let u=d,_=N(u,"block_id"),f=Hr(u,"start_index"),g=Hr(u,"end_index");return{blockId:_,startIndex:f,endIndex:g}}),l=il(a),c=_t(i,"\u667A\u80FD\u6587\u6863\u6279\u91CF\u5220\u9664\u5757\u5185\u5BB9");return await Ye(o,c,async d=>{let p=await d.request({method:"POST",path:ft(i,"/blocks/batch_delete"),body:l});return p.data??p})}catch(o){return De(o)}}}),t({name:"wps_airpage_update_document_block",description:"Update Smart Document blocks via Airpage operation object: POST `/v7/airpage/{file_id}/blocks/update`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON) of ONE operation object (e.g. update_content, update_attrs, insert_table_rows, insert_table_columns, delete_table_rows, delete_table_columns, merge_table_cells, split_table_cell, replace_anchor, replace_feature). At minimum operation JSON should contain `operation` and `blockId`; other fields depend on operation type. Use SenderId as `wps_user_id`. Requires delegated `kso.airpage.readwrite`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/update)."},operation:{type:"object",description:"Required operation object that will be encoded as arg JSON. Must include operation + blockId. Example: {operation:'update_content', blockId:'xxx', content:[...]}",additionalProperties:!0}},required:["wps_user_id","file_id","operation"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),s=n.operation;if(!s||typeof s!="object"||Array.isArray(s))throw new Error("operation is required and must be an object");let l=ol(s),c=_t(i,"\u667A\u80FD\u6587\u6863\u66F4\u65B0\u6587\u6863\u5757");return await Ye(o,c,async d=>{let p=await d.request({method:"POST",path:ft(i,"/blocks/update"),body:l});return p.data??p})}catch(o){return De(o)}}}),t({name:"wps_airpage_batch_update_document_blocks",description:"Batch update Smart Document blocks via Airpage operation array: POST `/v7/airpage/{file_id}/blocks/batch_update`. Body is `{ arg }` where `arg` is Base64(UTF-8 JSON) of an operation object array. Each operation object must include `operation` + `blockId`; other fields depend on operation type (update_content, update_attrs, insert_table_rows, insert_table_columns, delete_table_rows, delete_table_columns, merge_table_cells, split_table_cell, replace_anchor, replace_feature). Use SenderId as `wps_user_id`. Requires delegated `kso.airpage.readwrite`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},file_id:{type:"string",description:"Smart document file id (path segment in /v7/airpage/{file_id}/blocks/batch_update)."},operations:{type:"array",description:"Required operation object array. Each item must include operation + blockId; extra fields depend on operation type.",items:{type:"object",additionalProperties:!0}}},required:["wps_user_id","file_id","operations"]},async execute(r,n){try{let o=N(n,"wps_user_id"),i=N(n,"file_id"),a=Kr(n,"operations").map((d,p)=>{if(!d||typeof d!="object"||Array.isArray(d))throw new Error(`operations[${p}] must be an object`);return d}),l=sl(a),c=_t(i,"\u667A\u80FD\u6587\u6863\u6279\u91CF\u66F4\u65B0\u6587\u6863\u5757");return await Ye(o,c,async d=>{let p=await d.request({method:"POST",path:ft(i,"/blocks/batch_update"),body:l});return p.data??p})}catch(o){return De(o)}}})}var cl="/v7/meeting_rooms",ll="/v7/meeting_rooms/search",pl="/v7/meeting_room_bookings/batch_get",ul=["success","failed"];var As=["success","failed","approving"];function cr(e){return{error:e instanceof Error?e.message:String(e)}}function qe(e,t){let r=e[t];if(typeof r!="string"||!r.trim())throw new Error(`${t} is required and must be a non-empty string`);return r.trim()}function Lt(e,t){let r=e[t];if(r!=null){if(typeof r!="string")throw new Error(`${t} must be a string`);return r}}function ui(e,t){let r=e[t];if(r!=null){if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}}function Ts(e,t){let r=e[t];if(r==null)throw new Error(`${t} is required and must be a finite number`);if(typeof r=="number"&&Number.isFinite(r))return r;if(typeof r=="string"&&r.trim()!==""){let n=Number(r);if(Number.isFinite(n))return n}throw new Error(`${t} must be a finite number`)}function fl(e,t){let r=e[t];if(r!=null){if(typeof r=="boolean")return r;if(r==="true"||r==="false")return r==="true";throw new Error(`${t} must be a boolean`)}}function Os(e,t){let r=e[t];if(r==null)return;if(!Array.isArray(r))throw new Error(`${t} must be an array`);let n=[];for(let o of r){if(typeof o!="string")throw new Error(`${t} entries must be strings`);let i=o.trim();i!==""&&n.push(i)}return n.length>0?n:void 0}function _l(e,t){let r=Os(e,t);if(r===void 0)return;let n=new Set(As),o=r.filter(i=>n.has(i));return o.length>0?o:void 0}function Es(e){let t=Lt(e,"x_kso_id_type");if(t===void 0||t.trim()==="")return;let r=t.trim();if(r!=="internal"&&r!=="external")throw new Error("x_kso_id_type must be internal or external when provided");return{"X-Kso-Id-Type":r}}function ml(e){let t=e.pageSize??20,n={page_size:Math.max(1,Math.min(500,Math.trunc(t)))};return e.roomLevelId!==void 0&&e.roomLevelId.trim()!==""&&(n.room_level_id=e.roomLevelId.trim()),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(n.page_token=e.pageToken.trim()),n}function hl(e){let t=e.trim();if(!t)throw new Error("room_id must be a non-empty string");return`/v7/meeting_rooms/${encodeURIComponent(t)}`}function gl(e){let t=e.keyword.trim();if(!t)throw new Error("keyword is required and must be a non-empty string");let r=e.pageSize??20,n=Math.max(1,Math.min(100,Math.trunc(r))),o={keyword:t,page_size:n};return e.pageToken!==void 0&&e.pageToken.trim()!==""&&(o.page_token=e.pageToken.trim()),o}function yl(e){let t=Math.trunc(Number(e.startTimeSec)),r=Math.trunc(Number(e.endTimeSec));if(!Number.isFinite(t)||!Number.isFinite(r))throw new Error("start_time and end_time must be finite Unix timestamps in seconds");if(r<t)throw new Error("end_time must be >= start_time (Unix seconds)");let n=e.roomLevelId?.trim()??"",o=n!=="",i=e.roomIds?.filter(d=>d.trim()!=="").map(d=>d.trim())??[],s=i.length>0;if(o&&s)throw new Error("Provide either room_ids or room_level_id, not both");if(!o&&!s)throw new Error("Provide exactly one of room_ids (non-empty array) or room_level_id");let a=e.pageSize??20,l=Math.max(1,Math.min(500,Math.trunc(Number(a))));if(!Number.isFinite(l))throw new Error("page_size must be finite");let c={start_time:t,end_time:r,page_size:l};return o&&(c.room_level_id=n),s&&(c.room_ids=i),e.includeDeleted===!0&&(c.include_deleted=!0),e.pageToken!==void 0&&e.pageToken.trim()!==""&&(c.page_token=e.pageToken.trim()),e.results!==void 0&&e.results.length>0&&(c.results=[...e.results]),c}function wl(e){let t=e.trim();if(!t)throw new Error("booking_id must be a non-empty string");return`/v7/meeting_room_bookings/${encodeURIComponent(t)}/update_status`}function bl(e){let t=e.trim();if(t!=="success"&&t!=="failed")throw new Error("status must be success or failed");return{status:t}}function fi(e,t){t({name:"wps_meeting_rooms_list",description:"List meeting rooms (\u67E5\u8BE2\u4F1A\u8BAE\u5BA4\u5217\u8868): GET `/v7/meeting_rooms`. Uses **application** access_token (client_credentials); requires app scopes **`kso.meeting_rooms.read`** or **`kso.meeting_rooms.readwrite`** on the Open Platform (often **app-only**, not user OAuth). Still pass SenderId as `wps_user_id` for session context (not sent as HTTP user identity). Optional: `room_level_id` (\u4F1A\u8BAE\u5BA4\u5C42\u7EA7 id), `page_size` (default 20, max 500), `page_token` (omit on first page). Response `data` typically includes `items[]` (id, name, capacity, level_id, disable, remark, device_list, tag_list) and `next_page_token`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},room_level_id:{type:"string",description:"Optional. Meeting room level id (\u4F1A\u8BAE\u5BA4\u5C42\u7EA7 id)."},page_size:{type:"number",description:"Optional. Items per page (default 20 per API, max 500 client cap)."},page_token:{type:"string",description:"Optional. Pagination token from data.next_page_token; omit for first request."}},required:["wps_user_id"]},async execute(r,n){try{qe(n,"wps_user_id");let o=Lt(n,"room_level_id"),i=ui(n,"page_size"),s=Lt(n,"page_token"),a=ml({roomLevelId:o,pageSize:i,pageToken:s}),l=await e.request({method:"GET",path:cl,query:a});return l.data??l}catch(o){return cr(o)}}}),t({name:"wps_meeting_rooms_get",description:"Get meeting room details (\u67E5\u8BE2\u4F1A\u8BAE\u5BA4\u8BE6\u60C5): GET `/v7/meeting_rooms/{room_id}`. Uses **application** access_token; requires app **`kso.meeting_rooms.read`** or **`kso.meeting_rooms.readwrite`**. Pass SenderId as `wps_user_id` for context only. Required: `room_id` from `wps_meeting_rooms_list` items[]. Response `data` is a single room object (id, name, capacity, level_id, disable, remark, device_list, tag_list).",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},room_id:{type:"string",description:"Meeting room id from the meeting room list (\u4F1A\u8BAE\u5BA4 id\uFF0C\u53EF\u901A\u8FC7\u4F1A\u8BAE\u5BA4\u5217\u8868\u67E5\u8BE2)."}},required:["wps_user_id","room_id"]},async execute(r,n){try{qe(n,"wps_user_id");let o=qe(n,"room_id"),i=await e.request({method:"GET",path:hl(o)});return i.data??i}catch(o){return cr(o)}}}),t({name:"wps_meeting_rooms_search",description:"Search meeting rooms by keyword (\u641C\u7D22\u4F1A\u8BAE\u5BA4): POST `/v7/meeting_rooms/search`. Uses **application** access_token; requires app **`kso.meeting_rooms.read`** or **`kso.meeting_rooms.readwrite`**. Pass SenderId as `wps_user_id` for context only. Required body: `keyword` (meeting room name search). Optional: `page_size` (default 20, max 100 per API), `page_token` (omit on first page; use data.next_page_token). Response `data` typically includes `items[]` and `next_page_token`.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},keyword:{type:"string",description:"Search keyword; supports meeting room name (\u641C\u7D22\u5173\u952E\u8BCD\uFF0C\u652F\u6301\u4F1A\u8BAE\u5BA4\u540D\u79F0\u641C\u7D22)."},page_size:{type:"number",description:"Optional. Items per page (default 20 per API, max 100)."},page_token:{type:"string",description:"Optional. Pagination token from data.next_page_token; omit for first request."}},required:["wps_user_id","keyword"]},async execute(r,n){try{qe(n,"wps_user_id");let o=qe(n,"keyword"),i=ui(n,"page_size"),s=Lt(n,"page_token"),a=gl({keyword:o,pageSize:i,pageToken:s}),l=await e.request({method:"POST",path:ll,body:a});return l.data??l}catch(o){return cr(o)}}}),t({name:"wps_meeting_room_bookings_batch_get",description:"Batch query meeting room bookings (\u6279\u91CF\u67E5\u8BE2\u4F1A\u8BAE\u5BA4\u9884\u7EA6): POST `/v7/meeting_room_bookings/batch_get`. Uses **application** access_token; requires app **`kso.meeting_rooms.read`** or **`kso.meeting_rooms.readwrite`**. Pass SenderId as `wps_user_id` for context only. Required JSON body params: `start_time`, `end_time` (**Unix timestamps in seconds**). Exactly one of: non-empty **`room_ids`** (string[]) **or** **`room_level_id`** (string)\u2014not both, not neither. Optional: `include_deleted` (boolean, default false), `page_size` (default 20, max 500), `page_token`, `results` filter array (`success`|`failed`|`approving`). Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},start_time:{type:"number",description:"Query window start (**Unix timestamp in seconds**, \u5FC5\u586B)."},end_time:{type:"number",description:"Query window end (**Unix timestamp in seconds**, \u5FC5\u586B)."},room_ids:{type:"array",items:{type:"string"},description:"Meeting room id list. Mutually exclusive with room_level_id."},room_level_id:{type:"string",description:"Meeting room level id. Mutually exclusive with room_ids."},include_deleted:{type:"boolean",description:"Whether to include deleted bookings (\u9ED8\u8BA4 false)."},page_size:{type:"number",description:"Page size (default 20 per API, max 500 client cap)."},page_token:{type:"string",description:"Pagination token; omit on first page when unused."},results:{type:"array",items:{type:"string",enum:[...As]},description:"Optional filter by reservation result: success, failed, approving."},x_kso_id_type:{type:"string",enum:["internal","external"],description:"Optional. Maps to HTTP header X-Kso-Id-Type."}},required:["wps_user_id","start_time","end_time"]},async execute(r,n){try{qe(n,"wps_user_id");let o=Ts(n,"start_time"),i=Ts(n,"end_time"),s=Os(n,"room_ids"),a=Lt(n,"room_level_id"),l=fl(n,"include_deleted"),c=ui(n,"page_size"),d=Lt(n,"page_token"),p=_l(n,"results"),u=yl({startTimeSec:o,endTimeSec:i,roomIds:s,roomLevelId:a,includeDeleted:l,pageSize:c,pageToken:d,results:p??void 0}),_=await e.request({method:"POST",path:pl,body:u,headers:Es(n)});return _.data??_}catch(o){return cr(o)}}}),t({name:"wps_meeting_room_bookings_update_status",description:"Update meeting room booking status (\u66F4\u65B0\u4F1A\u8BAE\u5BA4\u9884\u7EA6\u72B6\u6001): POST `/v7/meeting_room_bookings/{booking_id}/update_status`. Uses **application** access_token; requires app **`kso.meeting_rooms.readwrite`** (per API). Pass SenderId as `wps_user_id` for context only. Path: **`booking_id`** from booking list / batch query (`items[].id`). JSON body: **`status`** enum **`success`** (\u9884\u7EA6\u6210\u529F) or **`failed`** (\u9884\u7EA6\u5931\u8D25). Optional `x_kso_id_type` \u2192 `X-Kso-Id-Type` header.",parameters:{type:"object",properties:{wps_user_id:{type:"string",description:"WPS user ID (SenderId). Do NOT call wps_user_search for this."},booking_id:{type:"string",description:"Meeting room booking id (\u4F1A\u8BAE\u5BA4\u9884\u7EA6 id\uFF0C\u53EF\u4ECE\u6279\u91CF\u67E5\u8BE2\u9884\u7EA6\u7B49\u63A5\u53E3 items[].id \u53D6\u5F97)."},status:{type:"string",enum:[...ul],description:"Updated reservation outcome: success or failed."},x_kso_id_type:{type:"string",enum:["internal","external"],description:"Optional. Maps to HTTP header X-Kso-Id-Type."}},required:["wps_user_id","booking_id","status"]},async execute(r,n){try{qe(n,"wps_user_id");let o=qe(n,"booking_id"),i=qe(n,"status"),s=bl(i),a=await e.request({method:"POST",path:wl(o),body:s,headers:Es(n)});return a.data??a}catch(o){return cr(o)}}})}var be={type:"string",description:"WPS user ID (current SenderId). Do NOT call wps_user_search for this."},Ae={type:"string",description:"Smart Sheet file ID."},ht={type:"integer",description:"Worksheet ID (integer). From wps_airsheet_list_worksheets."};async function Il(e,t,r){return _e({wpsUserId:e,toolModule:"airsheet",authCardOriginalMessage:"\u7528\u6237\u8BF7\u6C42\u64CD\u4F5C\u667A\u80FD\u8868\u683C",needsAuthMessage:"\u9700\u8981\u7528\u6237\u6388\u6743\u624D\u80FD\u64CD\u4F5C\u667A\u80FD\u8868\u683C\u3002\u5DF2\u53D1\u9001\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u70B9\u51FB\u300C\u524D\u5F80\u6388\u6743\u300D\u540E\u91CD\u8BD5\u3002",logTag:t,run:r})}function Ie(e,t){return async(r,n)=>{try{let o=T(n,"wps_user_id");return await Il(o,e,i=>t(n,i))}catch(o){return se(o)}}}function _i(e,t){t({name:"wps_airsheet_create_file",description:"Create a Smart Sheet (\u667A\u80FD\u8868\u683C / AirSheet): POST `/v7/airsheet/files`. Creates a new smart sheet file in the specified drive. Required: `drive_id` (from `wps_cloud_doc_list_drives`), `name` (file name, may omit extension; if extension is provided it must be `ksheet`). Optional: `on_name_conflict` (`rename` (default) | `fail`), `parent_id` (folder id, empty = root), `parent_path` (string array of folder names as relative path; auto-created if not exists). Requires delegated OAuth with scope `kso.airsheet.readwrite`. Use SenderId as `wps_user_id`. Response includes `id`, `link_id`, `link_url`, `name`, `parent_id`.",parameters:{type:"object",properties:{wps_user_id:be,drive_id:{type:"string",description:"Target drive id (from wps_cloud_doc_list_drives)."},name:{type:"string",description:"File name. May omit extension; if extension is provided it must be ksheet."},on_name_conflict:{type:"string",enum:["rename","fail"],description:"Optional. Strategy when name conflicts: rename (default) or fail."},parent_id:{type:"string",description:"Optional. Parent folder id. Empty means root directory."},parent_path:{type:"array",items:{type:"string"},description:"Optional. Relative path as array of folder names (not ids). If the path does not exist, the system will auto-create it."}},required:["wps_user_id","drive_id","name"]},execute:Ie("wps_airsheet_create_file",async(r,n)=>{let o=T(r,"drive_id"),i=T(r,"name"),s=V(r,"on_name_conflict"),a=V(r,"parent_id"),l=ct(r,"parent_path");if(s&&s!=="rename"&&s!=="fail")throw new Error("on_name_conflict must be 'rename' or 'fail'");let c={drive_id:o,name:i};s&&(c.on_name_conflict=s),a!==void 0&&(c.parent_id=a),l&&l.length>0&&(c.parent_path=l);let d=await n.request({method:"POST",path:"/v7/airsheet/files",body:c});return d.data??d})}),t({name:"wps_airsheet_create_worksheet",description:"Create a worksheet in a Smart Sheet (\u521B\u5EFA\u5DE5\u4F5C\u8868): POST `/v7/airsheet/{file_id}/worksheets`. Creates a new worksheet (tab) inside an existing smart sheet file. Required: `file_id`, `position` (object \u2014 at least one of `after_sheet_id`, `before_sheet_id`, or `end` must be set). Optional: `name` (worksheet name), `col_width` (default column width in pixels). Position rules: set `end: true` to append at the end; or use `after_sheet_id`/`before_sheet_id` (integer) to place relative to an existing sheet. Requires delegated OAuth with scope `kso.airsheet.readwrite`. Use SenderId as `wps_user_id`. Response includes `data.sheet_id` (integer).",parameters:{type:"object",properties:{wps_user_id:be,file_id:Ae,name:{type:"string",description:"Optional. Worksheet name."},col_width:{type:"number",description:"Optional. Default column width in pixels."},position:{type:"object",description:"Insertion position. Must provide at least one of: after_sheet_id (integer), before_sheet_id (integer), end (boolean, true = append).",properties:{after_sheet_id:{type:"integer",description:"Insert after this sheet id."},before_sheet_id:{type:"integer",description:"Insert before this sheet id."},end:{type:"boolean",description:"If true, append at the end."}}}},required:["wps_user_id","file_id","position"]},execute:Ie("wps_airsheet_create_worksheet",async(r,n)=>{let o=T(r,"file_id"),i=V(r,"name"),s=Y(r,"col_width"),a=r.position;if(!a||typeof a!="object")throw new Error("position is required and must be an object");let l=a,c={},d=Y(l,"after_sheet_id");d!==void 0&&(c.after_sheet_id=d);let p=Y(l,"before_sheet_id");p!==void 0&&(c.before_sheet_id=p);let u=re(l,"end");u!==void 0&&(c.end=u);let _={position:c};i!==void 0&&(_.name=i),s!==void 0&&(_.col_width=s);let f=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets`,body:_});return f.data??f})}),t({name:"wps_airsheet_list_worksheets",description:"List worksheets in a Smart Sheet (\u83B7\u53D6 Sheet \u5217\u8868\u4FE1\u606F): GET `/v7/airsheet/{file_id}/worksheets`. Returns all worksheets (tabs) in the specified smart sheet file. Each sheet includes: `sheet_id` (integer), `name`, `index`, `hidden`, `empty`, `max_row`, `max_col`, `resource_type` (et = normal spreadsheet), and `active_area` (col_from, col_to, row_from, row_to \u2014 the editing region). Use this to discover `sheet_id` before reading/writing data. Requires delegated OAuth (`kso.airsheet.read` or `kso.airsheet.readwrite`). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Ae},required:["wps_user_id","file_id"]},execute:Ie("wps_airsheet_list_worksheets",async(r,n)=>{let o=T(r,"file_id"),i=await n.request({method:"GET",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets`});return i.data??i})}),t({name:"wps_airsheet_copy_worksheet",description:"Copy a worksheet (\u590D\u5236\u5DE5\u4F5C\u8868): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/copy`. Duplicates an existing worksheet within the same smart sheet file. Required: `file_id`, `worksheet_id` (integer, from `wps_airsheet_list_worksheets`). Optional: `copy_first_sheet` (boolean \u2014 if true, copies the first sheet regardless of `worksheet_id`). Requires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`. Response includes `data.sheet_id` (integer) \u2014 the new copied sheet's id.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Ae,worksheet_id:ht,copy_first_sheet:{type:"boolean",description:"Optional. If true, copies the first sheet."}},required:["wps_user_id","file_id","worksheet_id"]},execute:Ie("wps_airsheet_copy_worksheet",async(r,n)=>{let o=T(r,"file_id"),i=Be(r,"worksheet_id"),s=re(r,"copy_first_sheet"),a={};s!==void 0&&(a.copy_first_sheet=s);let l=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/copy`,body:a});return l.data??l})}),t({name:"wps_airsheet_update_worksheet",description:"Update a worksheet (\u66F4\u65B0\u5DE5\u4F5C\u8868): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/update`. Renames or moves a worksheet within the same smart sheet file. Required: `file_id`, `worksheet_id` (integer). Optional: `name` (new worksheet name), `move_sheet_id` (integer \u2014 reference sheet id for move), `move_type` (`sheet_move_type_before` | `sheet_move_type_after` \u2014 move before/after the reference sheet). Requires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`. Response: `{ code, msg }`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Ae,worksheet_id:ht,name:{type:"string",description:"Optional. New worksheet name."},move_sheet_id:{type:"integer",description:"Optional. Reference sheet id for repositioning."},move_type:{type:"string",enum:["sheet_move_type_before","sheet_move_type_after"],description:"Optional. Move before or after the reference sheet."}},required:["wps_user_id","file_id","worksheet_id"]},execute:Ie("wps_airsheet_update_worksheet",async(r,n)=>{let o=T(r,"file_id"),i=Be(r,"worksheet_id"),s=V(r,"name"),a=Y(r,"move_sheet_id"),l=V(r,"move_type");if(l&&l!=="sheet_move_type_before"&&l!=="sheet_move_type_after")throw new Error("move_type must be 'sheet_move_type_before' or 'sheet_move_type_after'");let c={};s!==void 0&&(c.name=s),a!==void 0&&(c.move_sheet_id=a),l!==void 0&&(c.move_type=l);let d=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/update`,body:c});return d.data??d})}),t({name:"wps_airsheet_delete_worksheets",description:"Delete worksheets (\u5220\u9664\u5DE5\u4F5C\u8868): POST `/v7/airsheet/{file_id}/worksheets/batch_delete`. Batch-deletes one or more worksheets by their IDs. **This operation is irreversible.** Required: `file_id`, `worksheet_ids` (array of integers \u2014 sheet IDs from `wps_airsheet_list_worksheets`). Requires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`. Response: `{ code, msg }`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Ae,worksheet_ids:{type:"array",items:{type:"integer"},description:"Array of worksheet IDs (integers) to delete."}},required:["wps_user_id","file_id","worksheet_ids"]},execute:Ie("wps_airsheet_delete_worksheets",async(r,n)=>{let o=T(r,"file_id"),i=r.worksheet_ids;if(!Array.isArray(i)||i.length===0)throw new Error("worksheet_ids must be a non-empty array of integers");let s=i.map((l,c)=>{let d=typeof l=="number"?l:parseInt(String(l),10);if(!Number.isFinite(d)||d<0)throw new Error(`worksheet_ids[${c}] must be a non-negative integer`);return d}),a=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/batch_delete`,body:{worksheet_ids:s}});return a.data??a})}),t({name:"wps_airsheet_create_rows",description:"Create rows in a worksheet (\u521B\u5EFA\u884C): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/rows`. Inserts one or more rows with cell data into the specified worksheet. Required: `file_id`, `worksheet_id` (integer). Optional: `range_data` (array of cell objects). Each cell object can include: `col` (integer, 0-based column index), `formula` (string, cell formula or plain value), `op_type` (string, e.g. `cell_operation_type_formula`), `cell_pic_info` (object for image cells: `{ height, width, pic_content, tag }` where tag = `sheet_pic_type_local`). If `range_data` is omitted, an empty row is appended. Requires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`. Response: `{ code, msg }`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Ae,worksheet_id:ht,range_data:{type:"array",description:"Optional. Array of cell data objects. Each: { col: integer (0-based), formula?: string, op_type?: string, cell_pic_info?: { height: number, width: number, pic_content: string, tag: string } }.",items:{type:"object",properties:{col:{type:"integer",description:"0-based column index."},formula:{type:"string",description:"Cell formula or plain text value."},op_type:{type:"string",description:"Operation type, e.g. cell_operation_type_formula."},cell_pic_info:{type:"object",description:"Image cell info: { height, width, pic_content, tag }.",properties:{height:{type:"number"},width:{type:"number"},pic_content:{type:"string"},tag:{type:"string",description:"e.g. sheet_pic_type_local"}}}}}}},required:["wps_user_id","file_id","worksheet_id"]},execute:Ie("wps_airsheet_create_rows",async(r,n)=>{let o=T(r,"file_id"),i=Be(r,"worksheet_id"),s={},a=r.range_data;if(a!=null){if(!Array.isArray(a))throw new Error("range_data must be an array");s.range_data=a}let l=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/rows`,body:s});return l.data??l})}),t({name:"wps_airsheet_get_range_data",description:"Get cell range data (\u83B7\u53D6\u5355\u5143\u683C\u9009\u533A\u6570\u636E): GET `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/range_data`. Reads cell values from a rectangular region defined by row/col indices (0-based). Required: `file_id`, `worksheet_id` (integer), `row_from`, `row_to`, `col_from`, `col_to` (all integers). Use `wps_airsheet_list_worksheets` first to get `sheet_id` and `active_area` for valid ranges. Response: `data.range_data` array of cell objects, each with: `cell_text` (display value), `col_from`, `col_to`, `row_from`, `row_to`, `is_cell_pic` (boolean), `num_format`, `original_cell_value` (formula bar value), `pic_content`, `pic_data` (image id for online files), `sha1` (image hash for local images), `tag`. Requires delegated OAuth (`kso.airsheet.read` or `kso.airsheet.readwrite`). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Ae,worksheet_id:ht,row_from:{type:"integer",description:"Start row index (0-based, inclusive)."},row_to:{type:"integer",description:"End row index (0-based, inclusive)."},col_from:{type:"integer",description:"Start column index (0-based, inclusive)."},col_to:{type:"integer",description:"End column index (0-based, inclusive)."}},required:["wps_user_id","file_id","worksheet_id","row_from","row_to","col_from","col_to"]},execute:Ie("wps_airsheet_get_range_data",async(r,n)=>{let o=T(r,"file_id"),i=Be(r,"worksheet_id"),s=Y(r,"row_from"),a=Y(r,"row_to"),l=Y(r,"col_from"),c=Y(r,"col_to");if(s===void 0||a===void 0||l===void 0||c===void 0)throw new Error("row_from, row_to, col_from, col_to are all required");let d=await n.request({method:"GET",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/range_data`,query:{row_from:s,row_to:a,col_from:l,col_to:c}});return d.data??d})}),t({name:"wps_airsheet_find_cells",description:"Find cells in a worksheet (\u67E5\u627E\u5355\u5143\u683C): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/range_data/find`. Searches cells within a specified range using filter conditions, with optional pagination and deduplication. Required: `file_id`, `worksheet_id`, `filter` (object), `range` (object with row_from/row_to/col_from/col_to). Optional: `ignore_hidden_cell` (boolean, default false \u2014 skip hidden cells), `option_cols` (array of integers \u2014 column indices to get option/dropdown values for), `page` (object: { page: integer (min 1), page_size: integer (default 100) }), `show_total` (boolean, default false \u2014 include total count in response). \n\n**filter structure**: `{ condition: [{ col: integer, info: [{ value: string }], mode: 'filter_mode_and' | 'filter_mode_or' }], duplicates: { col: [integer] }, search: [{ col: integer, value: [string] }] }`. All sub-fields in filter are optional. \n\nResponse: `data.range_data` (matched cells), `data.merge_range_data` (merged cell data), `data.option_col` (option column results with texts/count), `data.result_type` (0=fail, 1=success), `data.total`. Requires delegated OAuth (`kso.airsheet.read` or `kso.airsheet.readwrite`). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Ae,worksheet_id:ht,filter:{type:"object",description:"Filter conditions. Structure: { condition?: [{ col: int, info: [{ value: string }], mode: 'filter_mode_and'|'filter_mode_or' }], duplicates?: { col: [int] }, search?: [{ col: int, value: [string] }] }."},range:{type:"object",description:"Search range (required). { row_from: int, row_to: int, col_from: int, col_to: int }.",properties:{row_from:{type:"integer",description:"Start row index (0-based)."},row_to:{type:"integer",description:"End row index (0-based)."},col_from:{type:"integer",description:"Start column index (0-based)."},col_to:{type:"integer",description:"End column index (0-based)."}},required:["row_from","row_to","col_from","col_to"]},ignore_hidden_cell:{type:"boolean",description:"Optional. If true, skip hidden cells. Default false."},option_cols:{type:"array",items:{type:"integer"},description:"Optional. Column indices to retrieve option/dropdown values for (relative to range)."},page:{type:"object",description:"Optional pagination. { page: integer (min 1), page_size: integer (default 100) }.",properties:{page:{type:"integer",description:"Page number, min 1."},page_size:{type:"integer",description:"Page size, default 100."}}},show_total:{type:"boolean",description:"Optional. If true, include total count in response. Default false."}},required:["wps_user_id","file_id","worksheet_id","filter","range"]},execute:Ie("wps_airsheet_find_cells",async(r,n)=>{let o=T(r,"file_id"),i=Be(r,"worksheet_id"),s=r.filter;if(!s||typeof s!="object")throw new Error("filter is required and must be an object");let a=r.range;if(!a||typeof a!="object")throw new Error("range is required and must be an object");let l={filter:s,range:a},c=re(r,"ignore_hidden_cell");c!==void 0&&(l.ignore_hidden_cell=c);let d=r.option_cols;if(d!=null){if(!Array.isArray(d))throw new Error("option_cols must be an array of integers");l.option_cols=d.map((f,g)=>{let y=typeof f=="number"?f:parseInt(String(f),10);if(!Number.isFinite(y)||y<0)throw new Error(`option_cols[${g}] must be a non-negative integer`);return y})}let p=r.page;if(p!=null){if(typeof p!="object")throw new Error("page must be an object");l.page=p}let u=re(r,"show_total");u!==void 0&&(l.show_total=u);let _=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/range_data/find`,body:l});return _.data??_})}),t({name:"wps_airsheet_batch_update_cells",description:"Batch update cell range data (\u66F4\u65B0\u5355\u5143\u683C\u9009\u533A\u6570\u636E): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/range_data/batch_update`. Updates one or more cells in a worksheet. Each cell in `range_data` specifies its position (row_from, row_to, col_from, col_to) and operation type (`op_type`). \n\n**op_type values**: `cell_operation_type_formula` \u2014 set cell value/formula (use `formula` field), `cell_operation_type_picture` \u2014 set cell image (use `cell_pic_info` with height/width/pic_content/tag), `cell_operation_type_format` \u2014 set cell formatting (use `xf` field for styles), `cell_operation_type_merge` \u2014 merge cells (use `merge_type`: merge_type_center / merge_type_content / merge_type_same / merge_type_columns). \n\n**cell_pic_info.tag values**: `sheet_pic_type_local`, `sheet_pic_type_attachment`, `sheet_pic_type_url`. \n\n**xf (format) object** includes: `alc_h` (horizontal align), `alc_v` (vertical align), border colors (`clr_bottom/clr_top/clr_left/clr_right/clr_diag_down/clr_diag_up/clr_inside_horz/clr_inside_vert` \u2014 each `{tint,type,value}`), border styles (`dg_bottom/dg_top/dg_left/dg_right/dg_diag_down/dg_diag_up/dg_inside_horz/dg_inside_vert`), `fill` ({back:{tint,type,value}, fore:{tint,type,value}, type}), `font` ({bls,char_set,color:{tint,type,value},dy_height,italic,name,sss,strikeout,theme_font,uls}), `hidden`, `indent`, `locked`, `mask_cats`, `mask_cats_font`, `numfmt`, `reading_order`, `shrink_to_fit`, `trot`, `wrap`. \n\nRequires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`. Response: `{ code, msg }`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Ae,worksheet_id:ht,range_data:{type:"array",description:"Array of cell update objects. Each must include: row_from (int), row_to (int), col_from (int), col_to (int), op_type (string). Depending on op_type, also include: formula (string), cell_pic_info (object), merge_type (string), xf (format object).",items:{type:"object",properties:{row_from:{type:"integer",description:"Start row (0-based)."},row_to:{type:"integer",description:"End row (0-based)."},col_from:{type:"integer",description:"Start column (0-based)."},col_to:{type:"integer",description:"End column (0-based)."},op_type:{type:"string",enum:["cell_operation_type_formula","cell_operation_type_picture","cell_operation_type_format","cell_operation_type_merge"],description:"Cell operation type."},formula:{type:"string",description:"Cell value or formula (for op_type=formula)."},cell_pic_info:{type:"object",description:"Image info (for op_type=picture): { height, width, pic_content, tag }."},merge_type:{type:"string",enum:["merge_type_center","merge_type_content","merge_type_same","merge_type_columns"],description:"Merge type (for op_type=merge)."},xf:{type:"object",description:"Format/style object (for op_type=format). See tool description for full structure."}},required:["row_from","row_to","col_from","col_to","op_type"]}}},required:["wps_user_id","file_id","worksheet_id","range_data"]},execute:Ie("wps_airsheet_batch_update_cells",async(r,n)=>{let o=T(r,"file_id"),i=Be(r,"worksheet_id"),s=r.range_data;if(!Array.isArray(s)||s.length===0)throw new Error("range_data must be a non-empty array");let a=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/range_data/batch_update`,body:{range_data:s}});return a.data??a})}),t({name:"wps_airsheet_batch_delete_cells",description:"Batch delete cell range data (\u5220\u9664\u5355\u5143\u683C\u9009\u533A\u6570\u636E): POST `/v7/airsheet/{file_id}/worksheets/{worksheet_id}/range_data/batch_delete`. Deletes data in specified cell ranges. Caller must ensure row/col indices are within the worksheet's max row/col limits (obtainable via getSheetInfo). \n\nRequired: `file_id`, `worksheet_id`, `range_data` (array of range objects, each with `col_from`, `col_to`, `row_from`, `row_to` \u2014 all integers, required). \n\nOptional: `shift_type` \u2014 how remaining cells shift after deletion. Values: `shift_up` (default, shift up) or `shift_left` (shift left). \n\nResponse: `{ code, msg }`. Requires delegated OAuth (`kso.airsheet.readwrite`). Use SenderId as `wps_user_id`.",parameters:{type:"object",properties:{wps_user_id:be,file_id:Ae,worksheet_id:ht,range_data:{type:"array",description:"Array of range objects to delete. Each must include col_from, col_to, row_from, row_to (all integers).",items:{type:"object",properties:{col_from:{type:"integer",description:"Start column index (0-based)."},col_to:{type:"integer",description:"End column index (0-based)."},row_from:{type:"integer",description:"Start row index (0-based)."},row_to:{type:"integer",description:"End row index (0-based)."}},required:["col_from","col_to","row_from","row_to"]}},shift_type:{type:"string",enum:["shift_up","shift_left"],description:"Optional. How remaining cells shift after deletion. Default: shift_up."}},required:["wps_user_id","file_id","worksheet_id","range_data"]},execute:Ie("wps_airsheet_batch_delete_cells",async(r,n)=>{let o=T(r,"file_id"),i=Be(r,"worksheet_id"),s=r.range_data;if(!Array.isArray(s)||s.length===0)throw new Error("range_data must be a non-empty array");let a={range_data:s},l=V(r,"shift_type");l!==void 0&&(a.shift_type=l);let c=await n.request({method:"POST",path:`/v7/airsheet/${encodeURIComponent(o)}/worksheets/${i}/range_data/batch_delete`,body:a});return c.data??c})})}function Sl(){return new Proxy({},{get(e,t,r){let n=en(),o=Reflect.get(n,t,r);return typeof o=="function"?o.bind(n):o}})}function Ps(e){let t=[],r=o=>{e(()=>({name:o.name,label:o.name,description:o.description,parameters:o.parameters,async execute(s,a){let l=await o.execute(s,a);if(l&&typeof l=="object"&&"error"in l)throw new Error(l.error);return{content:[{type:"text",text:JSON.stringify(l,null,2)}],details:l}}}),{name:o.name}),t.push(o.name)},n=Sl();return Qn(n,r),ei(n,r),ni(n,r),Kn(n,r),si(n,r),ai(n,r),ci(n,r),di(n,r),pi(n,r),fi(n,r),_i(n,r),console.log(`[wps-xiezuo] OAPI tools registered: ${t.length} tools`),t.length}var kl={id:We,name:"WPS Xiezuo",description:"WPS365 Open Platform channel plugin for OpenClaw",configSchema:Bi(),register(e){Vo(e.runtime);let t=e.logger??{info:()=>{},warn:()=>{},error:()=>{}};if(e.registerChannel({plugin:Yn}),typeof e.registerTool=="function"){t.info(`[${We}] registerTool is available (type: ${typeof e.registerTool})`);try{let r=Ps(e.registerTool);t.info(`[${We}] registered ${r} WPS OAPI tool factories`)}catch(r){t.error(`[${We}] tool registration failed: ${r}`)}}else t.warn(`[${We}] registerTool not available (type: ${typeof e.registerTool})`);t.info(`[${We}] plugin registered`)}},Bf=kl;export{Bf as default};
|
|
36
36
|
//# sourceMappingURL=__bundle.tmp.js.map
|