aitable-workflow-core 0.1.27 → 0.1.28-beta.1789458587713
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.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -266,7 +266,7 @@ ${JSON.stringify(o.error.issues,null,2)}`);return o.data}a(ic,"loadAgentConfig")
|
|
|
266
266
|
|
|
267
267
|
---
|
|
268
268
|
|
|
269
|
-
`),d=o?.workDir??(n?.kbActive?n.kbRootDir:t.workDir);h.info("coding","\u8C03\u7528\u7F16\u7A0B Agent",{agent:i,workDir:d,promptLength:l.length,contextInjected:!!n,kbActive:n?.kbActive??!1});let u=new AbortController,f,p=Date.now();try{let g=await kt(l,{agent:i,configPath:t.configPath,workDir:d,model:o?.model??t.model,timeoutMs:o?.timeoutMs,signal:u.signal,adapterOptions:{permissionMode:"bypassPermissions",...n?.kbActive?{allowedTools:["Read","Glob","Grep"]}:{},...o?.adapterOptions??{}},onEvent:a(I=>{if(o?.onEvent&&o.onEvent({type:I.type,content:I.content}),!f&&ai(I)){let{question:k}=ci(I);f=k,u.abort()}},"onEvent")});if(f)return{response:`ASK_HUMAN_DETECTED: ${f}`,success:!1,sessionId:g.sessionId};let m=g.events.some(I=>I.type==="error"),w=lc(g.response,g.events)??(g.response.trim()?null:{kind:"empty_response",message:"agent \u672A\u8FD4\u56DE\u4EFB\u4F55\u54CD\u5E94"}),b=!m&&!w,x={agent:i,workDir:d,sessionId:g.sessionId,success:b,durationMs:Date.now()-p,...w?{failureKind:w.kind,failureMessage:w.message}:{}};return b?h.info("coding","\u7F16\u7A0B Agent \u6267\u884C\u5B8C\u6210",x):h.warn("coding","\u7F16\u7A0B Agent \u6267\u884C\u5B8C\u6210(\u6709\u9519\u8BEF)",x),{response:g.response,success:b,sessionId:g.sessionId,...w?{failure:w}:{}}}catch(g){if(f)return{response:`ASK_HUMAN_DETECTED: ${f}`,success:!1,sessionId:void 0};let m=g instanceof Error?g.message:String(g);h.error("coding","Agent \u6267\u884C\u5F02\u5E38",{agent:i,error:m});let y=lc("",[{type:"error",content:m}]);return{response:m,success:!1,sessionId:void 0,failure:y}}},activeAgent(){return e},available(){return e!==void 0}}}a(dS,"createCodingToolkit");function uS(){return{async run(){return{response:"\u5F53\u524D\u6A21\u5F0F\u4E3A llm_only\uFF0C\u65E0\u53EF\u7528\u7F16\u7A0B Agent\u3002\u8BF7\u5728\u914D\u7F6E\u4E2D\u8BBE\u7F6E agent.engine \u4E3A claude/qoder/codex/qwenwork \u7B49 Coding Agent\u3002",success:!1,sessionId:void 0}},activeAgent(){},available(){return!1}}}a(uS,"createNullCodingToolkit");function Sp(t){return t.name.replace(/[\\/]+$/g,"").split(/[\\/]/).pop()?.trim()||t.slug}a(Sp,"mountName");function fS(t=process.platform){return t==="win32"?"junction":"dir"}a(fS,"wikiDirectoryLinkType");function pS(t,e){try{let n=Ht.join(t,"wiki");In.mkdirSync(n,{recursive:!0});for(let r of e){let o=Ht.join(n,Sp(r));try{let i=In.readlinkSync(o);if(Ht.resolve(Ht.dirname(o),i)===Ht.resolve(r.dir))continue;In.rmSync(o,{force:!0})}catch{In.existsSync(o)&&In.rmSync(o,{recursive:!0,force:!0})}In.symlinkSync(r.dir,o,fS())}return!0}catch(n){return h.warn("coding","workspace wiki \u8F6F\u94FE\u5931\u8D25\uFF0C\u56DE\u9000\u7EDD\u5BF9\u8DEF\u5F84 KB \u5757",{workspaceDir:t,error:n instanceof Error?n.message:String(n)}),!1}}a(pS,"ensureWikiSymlinks");function gS(t){try{return In.mkdirSync(t,{recursive:!0}),t}catch(e){h.warn("coding","\u89D2\u8272 workspace \u76EE\u5F55\u521B\u5EFA\u5931\u8D25\uFF0C\u56DE\u9000\u5230 cwd",{workspaceDir:t,error:e instanceof Error?e.message:String(e)});return}}a(gS,"ensureWorkspaceDir");var mS=be.object({engine:be.enum(["claude","codex","qoder","codebuddy","opencode","qwen","deepseek","trae","qwenwork","llm_only"]).optional().describe("\u7F16\u7A0B Agent \u5F15\u64CE;llm_only \u8868\u793A\u4E0D\u542F\u7528 coding agent(\u964D\u7EA7\u4E3A\u4E0D\u53EF\u7528)"),model:be.string().min(1).optional().describe("coding agent \u4F7F\u7528\u7684\u6A21\u578B\u540D"),cwd:be.string().min(1).optional().describe("coding agent \u5DE5\u4F5C\u76EE\u5F55"),workspace_dir:be.string().min(1).optional().describe("agent \u6267\u884C workspace \u76EE\u5F55(\u76F8\u5BF9 configDir)\uFF0C\u7F3A\u7701 workspaces/<role.id>")}).strict(),xp={name:"coding",description:"\u7F16\u7A0B Agent \u80FD\u529B:\u8BA9 recipe \u8C03\u7528 coding agent \u751F\u6210\u4EE3\u7801/\u6587\u4EF6/\u6A21\u677F\u3002",configSchema:mS,methods:[{name:"run",description:"\u53D1\u9001 prompt \u7ED9\u7F16\u7A0B Agent \u6267\u884C\u4EFB\u52A1",params:be.object({prompt:be.string().describe("\u4EFB\u52A1\u63D0\u793A\u8BCD"),options:be.object({agent:be.string().optional().describe("\u8986\u76D6 Agent \u7C7B\u578B(claudecode/codex/qoder/qwenwork \u7B49)"),workDir:be.string().optional(),model:be.string().optional(),timeoutMs:be.number().optional()}).optional().describe("\u8FD0\u884C\u9009\u9879")}),output:be.promise(be.object({response:be.string(),success:be.boolean(),sessionId:be.string().optional()}))},{name:"activeAgent",description:"\u8FD4\u56DE\u5F53\u524D\u914D\u7F6E\u7684 Agent \u7C7B\u578B",output:be.string().optional()},{name:"available",description:"\u662F\u5426\u6709\u53EF\u7528\u7684\u7F16\u7A0B Agent",output:be.boolean()}],defaultConfig(t){return{model:t.agent.model,cwd:t.recipeDir}},build(t,e){let n=t.engine??e.settings.agent.engine;if(n==="llm_only")return uS();let r=e.roleContext?.id?.trim(),o=r&&/^[A-Za-z0-9._-]+$/.test(r)?r:void 0,i=t.workspace_dir?Ht.resolve(e.settings.configDir,t.workspace_dir):o?Ht.resolve(e.settings.configDir,"workspaces",o):void 0,s=i?gS(i):void 0,c=e.kbContext?.present===!0,l;if(c&&s&&(e.kbContext?.wikis?.length??0)>0&&pS(s,e.kbContext.wikis)){let u=gi(e.kbContext.wikis,{wikiRootOf:a(f=>`${Ht.posix.join("wiki",Sp(f))}/`,"wikiRootOf")});l=Hr({...e.roleContext?{roleContext:e.roleContext}:{},kbContext:e.kbContext,kbPromptBlock:u,kbRootDir:s})}return l||(l=Hr({...e.roleContext?{roleContext:e.roleContext}:{},...e.kbContext?{kbContext:e.kbContext}:{}})),dS({engine:n,workDir:s??t.cwd,model:t.model,configPath:bt(e.settings.configDir),...l?{injected:l}:{}})},permissions:[{method:"run",description:"\u542F\u52A8\u7F16\u7A0B Agent \u6267\u884C\u4EFB\u52A1(\u9650\u5B9A\u53EF\u7528\u7684 agent \u7C7B\u578B)",scopeSchema:be.array(be.string()).describe("\u5141\u8BB8\u4F7F\u7528\u7684 agent \u7C7B\u578B(\u5982 claudecode/codex/qoder/qwenwork)"),check:a((t,e)=>{let n=t,r=e[1]?.agent;return r==null?n.length>0:n.includes(r)},"check")}]};import{createHmac as ES}from"crypto";import{z as A}from"zod";var mc=class{static{a(this,"SessionWebhookRegistry")}map=new Map;register(e){if(!e.conversationId)return;let n=this.map.get(e.conversationId),r=e.sessionWebhook??n?.sessionWebhook,o=e.sessionWebhookExpiredTime??n?.sessionWebhookExpiredTime,i=e.conversationType??n?.conversationType;this.map.set(e.conversationId,{...e,...r?{sessionWebhook:r}:{},...typeof o=="number"?{sessionWebhookExpiredTime:o}:{},...i?{conversationType:i}:{},registeredAt:Date.now()}),this.prune()}lookup(e){if(!e)return;let n=this.map.get(e);if(n){if(this.isExpired(n)){this.map.delete(e);return}return n}}clear(){this.map.clear()}isExpired(e){let n=Date.now();return typeof e.sessionWebhookExpiredTime=="number"?n>=e.sessionWebhookExpiredTime:n-e.registeredAt>=54e5}prune(){for(let[e,n]of this.map)this.isExpired(n)&&this.map.delete(e)}},Rn=new mc;async function hc(t,e,n){let r=new Array(t.length),o=0,i=Array.from({length:Math.min(e,t.length)},async()=>{for(;o<t.length;){let s=o++;r[s]=await n(t[s])}});return await Promise.all(i),r}a(hc,"mapWithConcurrency");var hS=3600*1e3,yS=300*1e3,wS=1e3,Ip=15e3;function bS(t){if(!t||typeof t!="object")return[];let e=t,n=e.result,r=n&&typeof n=="object"?n.result:void 0,o=e.data&&typeof e.data=="object"?e.data.result:void 0;return(Array.isArray(n)?n:Array.isArray(r)?r:Array.isArray(o)?o:[]).filter(s=>!!s&&typeof s=="object")}a(bS,"contactCandidates");function kS(t,e){return async(n,r)=>{let o=r?.trim(),i=["contact","user","search","--query",n];o&&i.push("--profile",o),i.push("--format","json");let s=await ne(e,i,{timeoutMs:Ip,runner:t});if(s.exitCode!==0)throw new Error(`dws contact user search \u5931\u8D25(exit ${s.exitCode}): ${s.stderr.slice(0,200)}`);return s.stdout.trim()?JSON.parse(s.stdout):{}}}a(kS,"createDwsContactSearch");function mi(t={}){let e=t.now??Date.now,n=t.positiveTtlMs??hS,r=t.negativeTtlMs??yS,o=Math.max(1,Math.floor(t.maxCacheEntries??wS)),i=t.searchContacts??kS(t.runner??J,t.dwsBin??"dws"),s=new Map,c=a(u=>{for(let[f,p]of s)p.expiresAt<=u&&s.delete(f)},"pruneExpired"),l=a((u,f)=>{c(f);let p=s.get(u);if(p)return s.delete(u),s.set(u,p),p},"readCache"),d=a((u,f,p)=>{for(c(p),s.delete(u);s.size>=o;){let g=s.keys().next().value;if(g===void 0)break;s.delete(g)}s.set(u,f)},"writeCache");return async(u,f,p)=>{let g=u.trim();if(!g)return;if(/^\d+$/.test(g))return g;let m=f.trim();if(!m)return;let y=p?.trim()??"",w=`${y}\0${g}\0${m}`,b=e(),x=l(w,b);if(x)return x.userId;try{let I=[...new Set(bS(await i(m,y||void 0)).filter(k=>k.openDingTalkId?.trim()===g).map(k=>k.userId?.trim()??"").filter(Boolean))],v=I.length===1?I[0]:void 0;return d(w,{...v?{userId:v}:{},expiresAt:b+(v?n:r)},b),v}catch{d(w,{expiresAt:b+r},b);return}}}a(mi,"createDingTalkAtUserIdResolver");var vS=mi();function Rp(t,e,n,r){let o=typeof n=="string"&&n.trim()||void 0,i=typeof n=="function"?n:r;return i?mi({searchContacts:i})(t,e,o):vS(t,e,o)}a(Rp,"resolveDingTalkAtUserId");async function FW(t,e={}){let n=e.concurrency??5,r=e.log??(()=>{}),o=e.runner??J,i=e.dwsBin??"dws",s=e.timeoutMs??Ip,c=[],l=await hc(t,n,async u=>{try{let f=await ne(i,["contact","user","get","--ids",u,"--format","json"],{timeoutMs:s,runner:o});if(f.exitCode!==0)throw new Error(`exit ${f.exitCode}: ${f.stderr.slice(0,200)}`);let g=(f.stdout.trim()?JSON.parse(f.stdout):{}).result?.[0]?.orgEmployeeModel?.orgUserName;if(!g)throw new Error("\u672A\u67E5\u8BE2\u5230\u7EC4\u7EC7\u5185\u59D3\u540D");let m=await ne(i,["contact","user","search","--query",g,"--format","json"],{timeoutMs:s,runner:o});if(m.exitCode!==0)throw new Error(`search exit ${m.exitCode}: ${m.stderr.slice(0,200)}`);let w=((m.stdout.trim()?JSON.parse(m.stdout):{}).result??[]).find(b=>b.userId===u);if(w?.openDingTalkId&&w?.nick)return{userId:u,nick:w.nick,openDingTalkId:w.openDingTalkId};throw new Error("\u672A\u67E5\u8BE2\u5230\u5339\u914D\u7684 openDingTalkId/nick")}catch(f){let p=`${u}: ${f instanceof Error?f.message:String(f)}`;return c.push(p),r(`contact \u89E3\u6790\u5931\u8D25 ${p}`),null}}),d=new Map;for(let u of l)u&&d.set(u.userId,u);return{contacts:d,errors:c}}a(FW,"resolveContactsByUserIds");var SS="#007fff";function yc(t){return`<font color="${SS}">@${t}</font>`}a(yc,"formatDingTalkAtPlaceholder");function Cp(t,e){let n=t,r=[];for(let i of e)if(!n.includes(yc(i))){if(n.includes(`@${i}`)){n=n.split(`@${i}`).join(yc(i));continue}r.push(i)}return r.length===0?n:`${r.map(yc).join(" ")} ${n}`}a(Cp,"prependDingTalkAtPlaceholders");var xS="https://api.dingtalk.com",IS=300*1e3,RS=15e3,Tp=6,Et=class{static{a(this,"DingTalkRobotClient")}appKey;appSecret;openApiBase;timeoutMs;fetchImpl;tokenCache=null;tokenInflight=null;constructor(e){if(!e.appKey||!e.appSecret)throw new Error("DingTalkRobotClient \u9700\u8981 appKey/appSecret");this.appKey=e.appKey,this.appSecret=e.appSecret,this.openApiBase=(e.endpoint||xS).replace(/\/+$/,""),this.timeoutMs=e.timeoutMs??RS,this.fetchImpl=e.fetchImpl??globalThis.fetch}async getAccessToken(){let e=Date.now();return this.tokenCache&&e<this.tokenCache.expireAt-IS?this.tokenCache.value:this.tokenInflight?this.tokenInflight:(this.tokenInflight=this.fetchAccessToken().then(n=>(this.tokenCache=n,n.value)).finally(()=>{this.tokenInflight=null}),this.tokenInflight)}async fetchAccessToken(){let e=`${this.openApiBase}/v1.0/oauth2/accessToken`,n=await this.fetchImpl(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appKey:this.appKey,appSecret:this.appSecret}),signal:AbortSignal.timeout(this.timeoutMs)}),r=await n.text().catch(()=>""),o;try{o=r?JSON.parse(r):{}}catch{throw new Error(`\u6362\u53D6 access_token \u5931\u8D25 HTTP ${n.status}: \u54CD\u5E94\u975E JSON: ${r.slice(0,200)}`)}if(!n.ok||!o.accessToken)throw new Error(`\u6362\u53D6 access_token \u5931\u8D25 HTTP ${n.status}: ${r.slice(0,200)}`);let i=(o.expireIn??7200)*1e3;return h.debug("dingtalk-robot-client","access_token refreshed",{expireIn:o.expireIn}),{value:o.accessToken,expireAt:Date.now()+i}}async replyViaSessionWebhook(e,n,r){if(!e)throw new Error("replyViaSessionWebhook \u7F3A\u5C11 sessionWebhook");if(typeof r?.expiredTime=="number"&&Date.now()>r.expiredTime)throw new Error("sessionWebhook \u5DF2\u8FC7\u671F\uFF0C\u8BF7\u964D\u7EA7\u4E3A robot API \u4E3B\u52A8\u63A8\u9001");let o=(r?.atUserStaffIds??[]).map(hi).filter(Boolean),i=o.length>0?CS(n,o):n,s={msgtype:"markdown",markdown:{title:r?.title??TS(n),text:i},at:{isAtAll:r?.atAll??!1,...o.length>0?{atUserIds:o}:{}}};await this.postJson(e,s,void 0,"sessionWebhook")}async sendGroupMarkdown(e,n,r,o){if(!e||!n)throw new Error("sendGroupMarkdown \u7F3A\u5C11 robotCode/openConversationId");let i=await this.getAccessToken(),s=`${this.openApiBase}/v1.0/robot/groupMessages/send`,c={robotCode:e,openConversationId:n,msgKey:"sampleMarkdown",msgParam:JSON.stringify({title:r,text:o})};await this.postJson(s,c,{"x-acs-dingtalk-access-token":i},"robotApi")}async sendGroupText(e,n,r){if(!e||!n)throw new Error("sendGroupText \u7F3A\u5C11 robotCode/openConversationId");let o=await this.getAccessToken(),i=`${this.openApiBase}/v1.0/robot/groupMessages/send`,s={robotCode:e,openConversationId:n,msgKey:"sampleText",msgParam:JSON.stringify({content:r})};await this.postJson(i,s,{"x-acs-dingtalk-access-token":o},"robotApi")}async sendGroupActionCard(e,n,r){if(!e||!n)throw new Error("sendGroupActionCard \u7F3A\u5C11 robotCode/openConversationId");let o=_p(r,"sendGroupActionCard"),i=await this.getAccessToken(),s=`${this.openApiBase}/v1.0/robot/groupMessages/send`,c={robotCode:e,openConversationId:n,msgKey:o.msgKey,msgParam:o.msgParam},l=await this.postJson(s,c,{"x-acs-dingtalk-access-token":i},"robotApi.actionCard");return l.processQueryKey?{processQueryKey:l.processQueryKey}:{}}async sendActionCardToUsers(e,n,r){if(!e)throw new Error("sendActionCardToUsers \u7F3A\u5C11 robotCode");if(!Array.isArray(n)||n.length===0)throw new Error("sendActionCardToUsers \u7684 userIds \u4E0D\u80FD\u4E3A\u7A7A");let o=n.map(u=>String(u??"").trim());if(o.some(u=>!u))throw new Error("sendActionCardToUsers \u7684 userIds \u5305\u542B\u7A7A\u503C");if(new Set(o).size!==o.length)throw new Error("sendActionCardToUsers \u7684 userIds \u5305\u542B\u91CD\u590D\u9879");let i=_p(r,"sendActionCardToUsers"),s=await this.getAccessToken(),c=`${this.openApiBase}/v1.0/robot/oToMessages/batchSend`,l={robotCode:e,userIds:o,msgKey:i.msgKey,msgParam:i.msgParam},d=await this.postJson(c,l,{"x-acs-dingtalk-access-token":s},"robotApi.userActionCard");return d.processQueryKey?{processQueryKey:d.processQueryKey}:{}}async replyEmotion(e){await this.sendEmotion("reply",e)}async recallEmotion(e){await this.sendEmotion("recall",e)}async sendEmotion(e,n){if(!n.robotCode||!n.openMsgId||!n.openConversationId||!n.emotionName)throw new Error(`sendEmotion(${e}) \u7F3A\u5C11 robotCode/openMsgId/openConversationId/emotionName`);let r=await this.getAccessToken(),o=`${this.openApiBase}/v1.0/robot/emotion/${e}`,i={...n,emotionType:1};await this.postJson(o,i,{"x-acs-dingtalk-access-token":r},`emotion.${e}`,!0)}async downloadMessageFile(e,n){if(!e||!n)throw new Error("downloadMessageFile \u7F3A\u5C11 robotCode/downloadCode");let r=await this.getAccessToken(),o=`${this.openApiBase}/v1.0/robot/messageFiles/download`,i;try{i=await this.fetchImpl(o,{method:"POST",headers:{"Content-Type":"application/json","x-acs-dingtalk-access-token":r},body:JSON.stringify({downloadCode:n,robotCode:e}),signal:AbortSignal.timeout(this.timeoutMs)})}catch(l){let d=l instanceof Error?l.message:String(l);throw h.error("dingtalk-robot-client","\u4E0B\u8F7D\u6D88\u606F\u6587\u4EF6\u8BF7\u6C42\u5931\u8D25",{error:d}),new Error(`\u4E0B\u8F7D\u6D88\u606F\u6587\u4EF6\u8BF7\u6C42\u5931\u8D25: ${d}`)}let s=await i.text().catch(()=>""),c;try{c=s?JSON.parse(s):{}}catch{throw new Error(`\u4E0B\u8F7D\u6D88\u606F\u6587\u4EF6\u5931\u8D25 HTTP ${i.status}: \u54CD\u5E94\u975E JSON: ${s.slice(0,200)}`)}if(!i.ok||!c.downloadUrl)throw h.error("dingtalk-robot-client","\u4E0B\u8F7D\u6D88\u606F\u6587\u4EF6\u5931\u8D25",{status:i.status,errmsg:c.errmsg}),new Error(`\u4E0B\u8F7D\u6D88\u606F\u6587\u4EF6\u5931\u8D25 HTTP ${i.status}: ${c.errmsg??(s.slice(0,200)||"\u65E0 downloadUrl")}`);return c.downloadUrl}async postJson(e,n,r,o,i=!1){let s;try{s=await this.fetchImpl(e,{method:"POST",headers:{"Content-Type":"application/json",...r??{}},body:JSON.stringify(n),signal:AbortSignal.timeout(this.timeoutMs)})}catch(d){let u=d instanceof Error?d.message:String(d);throw h.error("dingtalk-robot-client","\u8BF7\u6C42\u5931\u8D25",{channel:o,error:u}),new Error(`\u9489\u9489\u51FA\u7AD9\u8BF7\u6C42\u5931\u8D25 (${o}): ${u}`)}let c=await s.text().catch(()=>""),l;try{if(i&&!c)throw new Error("empty response");l=c?JSON.parse(c):{}}catch{if(!s.ok)throw new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}) HTTP ${s.status}: ${c.slice(0,200)}`);if(i)throw new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}): \u54CD\u5E94\u975E JSON: ${c.slice(0,200)}`);l={}}if(!s.ok)throw h.error("dingtalk-robot-client","HTTP \u975E 2xx",{channel:o,status:s.status,errmsg:l.errmsg}),new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}) HTTP ${s.status}: ${l.errmsg??c.slice(0,200)}`);if(typeof l.errcode=="number"&&l.errcode!==0)throw h.error("dingtalk-robot-client","\u4E1A\u52A1\u5931\u8D25",{channel:o,errcode:l.errcode,errmsg:l.errmsg}),new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}) errcode=${l.errcode}: ${l.errmsg??""}`);if(l.success===!1)throw h.error("dingtalk-robot-client","\u4E1A\u52A1\u5931\u8D25",{channel:o,message:l.message}),new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}): ${l.message??c.slice(0,200)}`);if(typeof l.code=="string"&&l.code&&l.code!=="0")throw h.error("dingtalk-robot-client","\u4E1A\u52A1\u5931\u8D25",{channel:o,code:l.code,message:l.message}),new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}) code=${l.code}: ${l.message??""}`);return h.debug("dingtalk-robot-client","sent",{channel:o}),l}};function _p(t,e){if(!t?.title?.trim()||!t.text?.trim())throw new Error(`${e} \u7F3A\u5C11\u5361\u7247 title/text`);if(!Array.isArray(t.buttons)||t.buttons.length<1||t.buttons.length>5)throw new Error(`${e} \u7684 buttons \u5FC5\u987B\u5305\u542B 1\uFF5E5 \u4E2A\u6309\u94AE`);for(let[i,s]of t.buttons.entries())if(!s?.title?.trim()||!s.url?.trim())throw new Error(`${e} \u7684\u7B2C ${i+1} \u4E2A\u6309\u94AE\u7F3A\u5C11 title/url`);let n=t.buttons.length,r=t.orientation??(n===2?"horizontal":"vertical");if(r==="horizontal"&&n!==2)throw new Error(`${e} \u4EC5\u53CC\u6309\u94AE\u652F\u6301 horizontal \u6392\u5217`);if(n===1){let[i]=t.buttons;return{msgKey:"sampleActionCard",msgParam:JSON.stringify({title:t.title,text:t.text,singleTitle:i.title,singleURL:i.url})}}if(n===2&&r==="horizontal"){let[i,s]=t.buttons;return{msgKey:"sampleActionCard6",msgParam:JSON.stringify({title:t.title,text:t.text,buttonTitle1:i.title,buttonUrl1:i.url,buttonTitle2:s.title,buttonUrl2:s.url})}}let o={title:t.title,text:t.text};return t.buttons.forEach((i,s)=>{o[`actionTitle${s+1}`]=i.title,o[`actionURL${s+1}`]=i.url}),{msgKey:`sampleActionCard${n}`,msgParam:JSON.stringify(o)}}a(_p,"buildActionCardMessage");function hi(t){let e=String(t??"").trim();return e&&(e.length<Tp?e.padStart(Tp,"0"):e)}a(hi,"padStaffId");function CS(t,e){let n=e.filter(o=>!t.includes(`@${o}`));return n.length===0?t:`${n.map(o=>`@${o}`).join(" ")} ${t}`}a(CS,"prependAtPlaceholders");function TS(t){let e=t.match(/^\s*[【[]([^】\]]{1,20})[】\]]/);return e?.[1]?e[1].trim():(t.split(/\r?\n/).find(o=>o.trim().length>0)??"").replace(/[#*_`>~-]/g,"").trim().slice(0,20).trim()||"\u673A\u5668\u4EBA\u6D88\u606F"}a(TS,"deriveTitle");var _S="1",yi=class{static{a(this,"DingTalkSender")}robotClient;robotCode;registry;constructor(e={},n={}){n.robotClient?this.robotClient=n.robotClient:e.robot?.appKey&&e.robot?.appSecret&&(this.robotClient=new Et({appKey:e.robot.appKey,appSecret:e.robot.appSecret,...e.fetchImpl?{fetchImpl:e.fetchImpl}:{}})),this.robotCode=e.robotCode??e.robot?.appKey,this.registry=n.registry??Rn}get canReplyInSession(){return!!this.robotClient}async replyToConversation(e,n,r={}){let o=r.entry??this.registry.lookup(e),i=o?.conversationType===_S,s=i||r.mentionSender===!1?"":typeof r.mentionSender=="string"?r.mentionSender.trim():String(o?.senderStaffId??"").trim(),c=i?[]:[...new Set([s,...(r.mentionUserIds??[]).map(u=>u.trim())].filter(Boolean))],l=c.length>0?{atUserIds:c}:{};if(!r.preferWebhook&&this.robotClient&&o?.sessionWebhook)try{return await this.robotClient.replyViaSessionWebhook(o.sessionWebhook,n,{...c.length>0?{atUserStaffIds:c}:{},...typeof o.sessionWebhookExpiredTime=="number"?{expiredTime:o.sessionWebhookExpiredTime}:{},...r.title?{title:r.title}:{}}),{via:"session",...l}}catch(u){let f=u instanceof Error?u.message:String(u),p=await this.tryWebhook(n,c,r);if(p&&p.via==="webhook")return p;let g=p?.reason?` + ${p.reason}`:"";return{via:"skipped",reason:`session \u5931\u8D25: ${f}${g}`}}if(!r.preferWebhook&&this.robotClient&&this.robotCode&&!o?.sessionWebhook)try{let f=(r.senderName?`${r.senderName}
|
|
269
|
+
`),d=o?.workDir??(n?.kbActive?n.kbRootDir:t.workDir);h.info("coding","\u8C03\u7528\u7F16\u7A0B Agent",{agent:i,workDir:d,promptLength:l.length,contextInjected:!!n,kbActive:n?.kbActive??!1});let u=new AbortController,f,p=Date.now();try{let g=await kt(l,{agent:i,configPath:t.configPath,workDir:d,...o?.sessionId?{sessionId:o.sessionId}:{},model:o?.model??t.model,timeoutMs:o?.timeoutMs,signal:u.signal,adapterOptions:{permissionMode:"bypassPermissions",...n?.kbActive?{allowedTools:["Read","Glob","Grep"]}:{},...o?.adapterOptions??{}},onEvent:a(I=>{if(o?.onEvent&&o.onEvent({type:I.type,content:I.content}),!f&&ai(I)){let{question:k}=ci(I);f=k,u.abort()}},"onEvent")});if(f)return{response:`ASK_HUMAN_DETECTED: ${f}`,success:!1,sessionId:g.sessionId};let m=g.events.some(I=>I.type==="error"),w=lc(g.response,g.events)??(g.response.trim()?null:{kind:"empty_response",message:"agent \u672A\u8FD4\u56DE\u4EFB\u4F55\u54CD\u5E94"}),b=!m&&!w,x={agent:i,workDir:d,sessionId:g.sessionId,success:b,durationMs:Date.now()-p,...w?{failureKind:w.kind,failureMessage:w.message}:{}};return b?h.info("coding","\u7F16\u7A0B Agent \u6267\u884C\u5B8C\u6210",x):h.warn("coding","\u7F16\u7A0B Agent \u6267\u884C\u5B8C\u6210(\u6709\u9519\u8BEF)",x),{response:g.response,success:b,sessionId:g.sessionId,...w?{failure:w}:{}}}catch(g){if(f)return{response:`ASK_HUMAN_DETECTED: ${f}`,success:!1,sessionId:void 0};let m=g instanceof Error?g.message:String(g);h.error("coding","Agent \u6267\u884C\u5F02\u5E38",{agent:i,error:m});let y=lc("",[{type:"error",content:m}]);return{response:m,success:!1,sessionId:void 0,failure:y}}},activeAgent(){return e},available(){return e!==void 0}}}a(dS,"createCodingToolkit");function uS(){return{async run(){return{response:"\u5F53\u524D\u6A21\u5F0F\u4E3A llm_only\uFF0C\u65E0\u53EF\u7528\u7F16\u7A0B Agent\u3002\u8BF7\u5728\u914D\u7F6E\u4E2D\u8BBE\u7F6E agent.engine \u4E3A claude/qoder/codex/qwenwork \u7B49 Coding Agent\u3002",success:!1,sessionId:void 0}},activeAgent(){},available(){return!1}}}a(uS,"createNullCodingToolkit");function Sp(t){return t.name.replace(/[\\/]+$/g,"").split(/[\\/]/).pop()?.trim()||t.slug}a(Sp,"mountName");function fS(t=process.platform){return t==="win32"?"junction":"dir"}a(fS,"wikiDirectoryLinkType");function pS(t,e){try{let n=Ht.join(t,"wiki");In.mkdirSync(n,{recursive:!0});for(let r of e){let o=Ht.join(n,Sp(r));try{let i=In.readlinkSync(o);if(Ht.resolve(Ht.dirname(o),i)===Ht.resolve(r.dir))continue;In.rmSync(o,{force:!0})}catch{In.existsSync(o)&&In.rmSync(o,{recursive:!0,force:!0})}In.symlinkSync(r.dir,o,fS())}return!0}catch(n){return h.warn("coding","workspace wiki \u8F6F\u94FE\u5931\u8D25\uFF0C\u56DE\u9000\u7EDD\u5BF9\u8DEF\u5F84 KB \u5757",{workspaceDir:t,error:n instanceof Error?n.message:String(n)}),!1}}a(pS,"ensureWikiSymlinks");function gS(t){try{return In.mkdirSync(t,{recursive:!0}),t}catch(e){h.warn("coding","\u89D2\u8272 workspace \u76EE\u5F55\u521B\u5EFA\u5931\u8D25\uFF0C\u56DE\u9000\u5230 cwd",{workspaceDir:t,error:e instanceof Error?e.message:String(e)});return}}a(gS,"ensureWorkspaceDir");var mS=be.object({engine:be.enum(["claude","codex","qoder","codebuddy","opencode","qwen","deepseek","trae","qwenwork","llm_only"]).optional().describe("\u7F16\u7A0B Agent \u5F15\u64CE;llm_only \u8868\u793A\u4E0D\u542F\u7528 coding agent(\u964D\u7EA7\u4E3A\u4E0D\u53EF\u7528)"),model:be.string().min(1).optional().describe("coding agent \u4F7F\u7528\u7684\u6A21\u578B\u540D"),cwd:be.string().min(1).optional().describe("coding agent \u5DE5\u4F5C\u76EE\u5F55"),workspace_dir:be.string().min(1).optional().describe("agent \u6267\u884C workspace \u76EE\u5F55(\u76F8\u5BF9 configDir)\uFF0C\u7F3A\u7701 workspaces/<role.id>")}).strict(),xp={name:"coding",description:"\u7F16\u7A0B Agent \u80FD\u529B:\u8BA9 recipe \u8C03\u7528 coding agent \u751F\u6210\u4EE3\u7801/\u6587\u4EF6/\u6A21\u677F\u3002",configSchema:mS,methods:[{name:"run",description:"\u53D1\u9001 prompt \u7ED9\u7F16\u7A0B Agent \u6267\u884C\u4EFB\u52A1",params:be.object({prompt:be.string().describe("\u4EFB\u52A1\u63D0\u793A\u8BCD"),options:be.object({agent:be.string().optional().describe("\u8986\u76D6 Agent \u7C7B\u578B(claudecode/codex/qoder/qwenwork \u7B49)"),workDir:be.string().optional(),sessionId:be.string().min(1).optional().describe("\u7EED\u63A5\u540C\u4E00 Agent \u4E0E\u5DE5\u4F5C\u76EE\u5F55\u6B64\u524D\u521B\u5EFA\u7684\u4F1A\u8BDD"),model:be.string().optional(),timeoutMs:be.number().optional()}).optional().describe("\u8FD0\u884C\u9009\u9879")}),output:be.promise(be.object({response:be.string(),success:be.boolean(),sessionId:be.string().optional()}))},{name:"activeAgent",description:"\u8FD4\u56DE\u5F53\u524D\u914D\u7F6E\u7684 Agent \u7C7B\u578B",output:be.string().optional()},{name:"available",description:"\u662F\u5426\u6709\u53EF\u7528\u7684\u7F16\u7A0B Agent",output:be.boolean()}],defaultConfig(t){return{model:t.agent.model,cwd:t.recipeDir}},build(t,e){let n=t.engine??e.settings.agent.engine;if(n==="llm_only")return uS();let r=e.roleContext?.id?.trim(),o=r&&/^[A-Za-z0-9._-]+$/.test(r)?r:void 0,i=t.workspace_dir?Ht.resolve(e.settings.configDir,t.workspace_dir):o?Ht.resolve(e.settings.configDir,"workspaces",o):void 0,s=i?gS(i):void 0,c=e.kbContext?.present===!0,l;if(c&&s&&(e.kbContext?.wikis?.length??0)>0&&pS(s,e.kbContext.wikis)){let u=gi(e.kbContext.wikis,{wikiRootOf:a(f=>`${Ht.posix.join("wiki",Sp(f))}/`,"wikiRootOf")});l=Hr({...e.roleContext?{roleContext:e.roleContext}:{},kbContext:e.kbContext,kbPromptBlock:u,kbRootDir:s})}return l||(l=Hr({...e.roleContext?{roleContext:e.roleContext}:{},...e.kbContext?{kbContext:e.kbContext}:{}})),dS({engine:n,workDir:s??t.cwd,model:t.model,configPath:bt(e.settings.configDir),...l?{injected:l}:{}})},permissions:[{method:"run",description:"\u542F\u52A8\u7F16\u7A0B Agent \u6267\u884C\u4EFB\u52A1(\u9650\u5B9A\u53EF\u7528\u7684 agent \u7C7B\u578B)",scopeSchema:be.array(be.string()).describe("\u5141\u8BB8\u4F7F\u7528\u7684 agent \u7C7B\u578B(\u5982 claudecode/codex/qoder/qwenwork)"),check:a((t,e)=>{let n=t,r=e[1]?.agent;return r==null?n.length>0:n.includes(r)},"check")}]};import{createHmac as ES}from"crypto";import{z as A}from"zod";var mc=class{static{a(this,"SessionWebhookRegistry")}map=new Map;register(e){if(!e.conversationId)return;let n=this.map.get(e.conversationId),r=e.sessionWebhook??n?.sessionWebhook,o=e.sessionWebhookExpiredTime??n?.sessionWebhookExpiredTime,i=e.conversationType??n?.conversationType;this.map.set(e.conversationId,{...e,...r?{sessionWebhook:r}:{},...typeof o=="number"?{sessionWebhookExpiredTime:o}:{},...i?{conversationType:i}:{},registeredAt:Date.now()}),this.prune()}lookup(e){if(!e)return;let n=this.map.get(e);if(n){if(this.isExpired(n)){this.map.delete(e);return}return n}}clear(){this.map.clear()}isExpired(e){let n=Date.now();return typeof e.sessionWebhookExpiredTime=="number"?n>=e.sessionWebhookExpiredTime:n-e.registeredAt>=54e5}prune(){for(let[e,n]of this.map)this.isExpired(n)&&this.map.delete(e)}},Rn=new mc;async function hc(t,e,n){let r=new Array(t.length),o=0,i=Array.from({length:Math.min(e,t.length)},async()=>{for(;o<t.length;){let s=o++;r[s]=await n(t[s])}});return await Promise.all(i),r}a(hc,"mapWithConcurrency");var hS=3600*1e3,yS=300*1e3,wS=1e3,Ip=15e3;function bS(t){if(!t||typeof t!="object")return[];let e=t,n=e.result,r=n&&typeof n=="object"?n.result:void 0,o=e.data&&typeof e.data=="object"?e.data.result:void 0;return(Array.isArray(n)?n:Array.isArray(r)?r:Array.isArray(o)?o:[]).filter(s=>!!s&&typeof s=="object")}a(bS,"contactCandidates");function kS(t,e){return async(n,r)=>{let o=r?.trim(),i=["contact","user","search","--query",n];o&&i.push("--profile",o),i.push("--format","json");let s=await ne(e,i,{timeoutMs:Ip,runner:t});if(s.exitCode!==0)throw new Error(`dws contact user search \u5931\u8D25(exit ${s.exitCode}): ${s.stderr.slice(0,200)}`);return s.stdout.trim()?JSON.parse(s.stdout):{}}}a(kS,"createDwsContactSearch");function mi(t={}){let e=t.now??Date.now,n=t.positiveTtlMs??hS,r=t.negativeTtlMs??yS,o=Math.max(1,Math.floor(t.maxCacheEntries??wS)),i=t.searchContacts??kS(t.runner??J,t.dwsBin??"dws"),s=new Map,c=a(u=>{for(let[f,p]of s)p.expiresAt<=u&&s.delete(f)},"pruneExpired"),l=a((u,f)=>{c(f);let p=s.get(u);if(p)return s.delete(u),s.set(u,p),p},"readCache"),d=a((u,f,p)=>{for(c(p),s.delete(u);s.size>=o;){let g=s.keys().next().value;if(g===void 0)break;s.delete(g)}s.set(u,f)},"writeCache");return async(u,f,p)=>{let g=u.trim();if(!g)return;if(/^\d+$/.test(g))return g;let m=f.trim();if(!m)return;let y=p?.trim()??"",w=`${y}\0${g}\0${m}`,b=e(),x=l(w,b);if(x)return x.userId;try{let I=[...new Set(bS(await i(m,y||void 0)).filter(k=>k.openDingTalkId?.trim()===g).map(k=>k.userId?.trim()??"").filter(Boolean))],v=I.length===1?I[0]:void 0;return d(w,{...v?{userId:v}:{},expiresAt:b+(v?n:r)},b),v}catch{d(w,{expiresAt:b+r},b);return}}}a(mi,"createDingTalkAtUserIdResolver");var vS=mi();function Rp(t,e,n,r){let o=typeof n=="string"&&n.trim()||void 0,i=typeof n=="function"?n:r;return i?mi({searchContacts:i})(t,e,o):vS(t,e,o)}a(Rp,"resolveDingTalkAtUserId");async function FW(t,e={}){let n=e.concurrency??5,r=e.log??(()=>{}),o=e.runner??J,i=e.dwsBin??"dws",s=e.timeoutMs??Ip,c=[],l=await hc(t,n,async u=>{try{let f=await ne(i,["contact","user","get","--ids",u,"--format","json"],{timeoutMs:s,runner:o});if(f.exitCode!==0)throw new Error(`exit ${f.exitCode}: ${f.stderr.slice(0,200)}`);let g=(f.stdout.trim()?JSON.parse(f.stdout):{}).result?.[0]?.orgEmployeeModel?.orgUserName;if(!g)throw new Error("\u672A\u67E5\u8BE2\u5230\u7EC4\u7EC7\u5185\u59D3\u540D");let m=await ne(i,["contact","user","search","--query",g,"--format","json"],{timeoutMs:s,runner:o});if(m.exitCode!==0)throw new Error(`search exit ${m.exitCode}: ${m.stderr.slice(0,200)}`);let w=((m.stdout.trim()?JSON.parse(m.stdout):{}).result??[]).find(b=>b.userId===u);if(w?.openDingTalkId&&w?.nick)return{userId:u,nick:w.nick,openDingTalkId:w.openDingTalkId};throw new Error("\u672A\u67E5\u8BE2\u5230\u5339\u914D\u7684 openDingTalkId/nick")}catch(f){let p=`${u}: ${f instanceof Error?f.message:String(f)}`;return c.push(p),r(`contact \u89E3\u6790\u5931\u8D25 ${p}`),null}}),d=new Map;for(let u of l)u&&d.set(u.userId,u);return{contacts:d,errors:c}}a(FW,"resolveContactsByUserIds");var SS="#007fff";function yc(t){return`<font color="${SS}">@${t}</font>`}a(yc,"formatDingTalkAtPlaceholder");function Cp(t,e){let n=t,r=[];for(let i of e)if(!n.includes(yc(i))){if(n.includes(`@${i}`)){n=n.split(`@${i}`).join(yc(i));continue}r.push(i)}return r.length===0?n:`${r.map(yc).join(" ")} ${n}`}a(Cp,"prependDingTalkAtPlaceholders");var xS="https://api.dingtalk.com",IS=300*1e3,RS=15e3,Tp=6,Et=class{static{a(this,"DingTalkRobotClient")}appKey;appSecret;openApiBase;timeoutMs;fetchImpl;tokenCache=null;tokenInflight=null;constructor(e){if(!e.appKey||!e.appSecret)throw new Error("DingTalkRobotClient \u9700\u8981 appKey/appSecret");this.appKey=e.appKey,this.appSecret=e.appSecret,this.openApiBase=(e.endpoint||xS).replace(/\/+$/,""),this.timeoutMs=e.timeoutMs??RS,this.fetchImpl=e.fetchImpl??globalThis.fetch}async getAccessToken(){let e=Date.now();return this.tokenCache&&e<this.tokenCache.expireAt-IS?this.tokenCache.value:this.tokenInflight?this.tokenInflight:(this.tokenInflight=this.fetchAccessToken().then(n=>(this.tokenCache=n,n.value)).finally(()=>{this.tokenInflight=null}),this.tokenInflight)}async fetchAccessToken(){let e=`${this.openApiBase}/v1.0/oauth2/accessToken`,n=await this.fetchImpl(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appKey:this.appKey,appSecret:this.appSecret}),signal:AbortSignal.timeout(this.timeoutMs)}),r=await n.text().catch(()=>""),o;try{o=r?JSON.parse(r):{}}catch{throw new Error(`\u6362\u53D6 access_token \u5931\u8D25 HTTP ${n.status}: \u54CD\u5E94\u975E JSON: ${r.slice(0,200)}`)}if(!n.ok||!o.accessToken)throw new Error(`\u6362\u53D6 access_token \u5931\u8D25 HTTP ${n.status}: ${r.slice(0,200)}`);let i=(o.expireIn??7200)*1e3;return h.debug("dingtalk-robot-client","access_token refreshed",{expireIn:o.expireIn}),{value:o.accessToken,expireAt:Date.now()+i}}async replyViaSessionWebhook(e,n,r){if(!e)throw new Error("replyViaSessionWebhook \u7F3A\u5C11 sessionWebhook");if(typeof r?.expiredTime=="number"&&Date.now()>r.expiredTime)throw new Error("sessionWebhook \u5DF2\u8FC7\u671F\uFF0C\u8BF7\u964D\u7EA7\u4E3A robot API \u4E3B\u52A8\u63A8\u9001");let o=(r?.atUserStaffIds??[]).map(hi).filter(Boolean),i=o.length>0?CS(n,o):n,s={msgtype:"markdown",markdown:{title:r?.title??TS(n),text:i},at:{isAtAll:r?.atAll??!1,...o.length>0?{atUserIds:o}:{}}};await this.postJson(e,s,void 0,"sessionWebhook")}async sendGroupMarkdown(e,n,r,o){if(!e||!n)throw new Error("sendGroupMarkdown \u7F3A\u5C11 robotCode/openConversationId");let i=await this.getAccessToken(),s=`${this.openApiBase}/v1.0/robot/groupMessages/send`,c={robotCode:e,openConversationId:n,msgKey:"sampleMarkdown",msgParam:JSON.stringify({title:r,text:o})};await this.postJson(s,c,{"x-acs-dingtalk-access-token":i},"robotApi")}async sendGroupText(e,n,r){if(!e||!n)throw new Error("sendGroupText \u7F3A\u5C11 robotCode/openConversationId");let o=await this.getAccessToken(),i=`${this.openApiBase}/v1.0/robot/groupMessages/send`,s={robotCode:e,openConversationId:n,msgKey:"sampleText",msgParam:JSON.stringify({content:r})};await this.postJson(i,s,{"x-acs-dingtalk-access-token":o},"robotApi")}async sendGroupActionCard(e,n,r){if(!e||!n)throw new Error("sendGroupActionCard \u7F3A\u5C11 robotCode/openConversationId");let o=_p(r,"sendGroupActionCard"),i=await this.getAccessToken(),s=`${this.openApiBase}/v1.0/robot/groupMessages/send`,c={robotCode:e,openConversationId:n,msgKey:o.msgKey,msgParam:o.msgParam},l=await this.postJson(s,c,{"x-acs-dingtalk-access-token":i},"robotApi.actionCard");return l.processQueryKey?{processQueryKey:l.processQueryKey}:{}}async sendActionCardToUsers(e,n,r){if(!e)throw new Error("sendActionCardToUsers \u7F3A\u5C11 robotCode");if(!Array.isArray(n)||n.length===0)throw new Error("sendActionCardToUsers \u7684 userIds \u4E0D\u80FD\u4E3A\u7A7A");let o=n.map(u=>String(u??"").trim());if(o.some(u=>!u))throw new Error("sendActionCardToUsers \u7684 userIds \u5305\u542B\u7A7A\u503C");if(new Set(o).size!==o.length)throw new Error("sendActionCardToUsers \u7684 userIds \u5305\u542B\u91CD\u590D\u9879");let i=_p(r,"sendActionCardToUsers"),s=await this.getAccessToken(),c=`${this.openApiBase}/v1.0/robot/oToMessages/batchSend`,l={robotCode:e,userIds:o,msgKey:i.msgKey,msgParam:i.msgParam},d=await this.postJson(c,l,{"x-acs-dingtalk-access-token":s},"robotApi.userActionCard");return d.processQueryKey?{processQueryKey:d.processQueryKey}:{}}async replyEmotion(e){await this.sendEmotion("reply",e)}async recallEmotion(e){await this.sendEmotion("recall",e)}async sendEmotion(e,n){if(!n.robotCode||!n.openMsgId||!n.openConversationId||!n.emotionName)throw new Error(`sendEmotion(${e}) \u7F3A\u5C11 robotCode/openMsgId/openConversationId/emotionName`);let r=await this.getAccessToken(),o=`${this.openApiBase}/v1.0/robot/emotion/${e}`,i={...n,emotionType:1};await this.postJson(o,i,{"x-acs-dingtalk-access-token":r},`emotion.${e}`,!0)}async downloadMessageFile(e,n){if(!e||!n)throw new Error("downloadMessageFile \u7F3A\u5C11 robotCode/downloadCode");let r=await this.getAccessToken(),o=`${this.openApiBase}/v1.0/robot/messageFiles/download`,i;try{i=await this.fetchImpl(o,{method:"POST",headers:{"Content-Type":"application/json","x-acs-dingtalk-access-token":r},body:JSON.stringify({downloadCode:n,robotCode:e}),signal:AbortSignal.timeout(this.timeoutMs)})}catch(l){let d=l instanceof Error?l.message:String(l);throw h.error("dingtalk-robot-client","\u4E0B\u8F7D\u6D88\u606F\u6587\u4EF6\u8BF7\u6C42\u5931\u8D25",{error:d}),new Error(`\u4E0B\u8F7D\u6D88\u606F\u6587\u4EF6\u8BF7\u6C42\u5931\u8D25: ${d}`)}let s=await i.text().catch(()=>""),c;try{c=s?JSON.parse(s):{}}catch{throw new Error(`\u4E0B\u8F7D\u6D88\u606F\u6587\u4EF6\u5931\u8D25 HTTP ${i.status}: \u54CD\u5E94\u975E JSON: ${s.slice(0,200)}`)}if(!i.ok||!c.downloadUrl)throw h.error("dingtalk-robot-client","\u4E0B\u8F7D\u6D88\u606F\u6587\u4EF6\u5931\u8D25",{status:i.status,errmsg:c.errmsg}),new Error(`\u4E0B\u8F7D\u6D88\u606F\u6587\u4EF6\u5931\u8D25 HTTP ${i.status}: ${c.errmsg??(s.slice(0,200)||"\u65E0 downloadUrl")}`);return c.downloadUrl}async postJson(e,n,r,o,i=!1){let s;try{s=await this.fetchImpl(e,{method:"POST",headers:{"Content-Type":"application/json",...r??{}},body:JSON.stringify(n),signal:AbortSignal.timeout(this.timeoutMs)})}catch(d){let u=d instanceof Error?d.message:String(d);throw h.error("dingtalk-robot-client","\u8BF7\u6C42\u5931\u8D25",{channel:o,error:u}),new Error(`\u9489\u9489\u51FA\u7AD9\u8BF7\u6C42\u5931\u8D25 (${o}): ${u}`)}let c=await s.text().catch(()=>""),l;try{if(i&&!c)throw new Error("empty response");l=c?JSON.parse(c):{}}catch{if(!s.ok)throw new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}) HTTP ${s.status}: ${c.slice(0,200)}`);if(i)throw new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}): \u54CD\u5E94\u975E JSON: ${c.slice(0,200)}`);l={}}if(!s.ok)throw h.error("dingtalk-robot-client","HTTP \u975E 2xx",{channel:o,status:s.status,errmsg:l.errmsg}),new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}) HTTP ${s.status}: ${l.errmsg??c.slice(0,200)}`);if(typeof l.errcode=="number"&&l.errcode!==0)throw h.error("dingtalk-robot-client","\u4E1A\u52A1\u5931\u8D25",{channel:o,errcode:l.errcode,errmsg:l.errmsg}),new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}) errcode=${l.errcode}: ${l.errmsg??""}`);if(l.success===!1)throw h.error("dingtalk-robot-client","\u4E1A\u52A1\u5931\u8D25",{channel:o,message:l.message}),new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}): ${l.message??c.slice(0,200)}`);if(typeof l.code=="string"&&l.code&&l.code!=="0")throw h.error("dingtalk-robot-client","\u4E1A\u52A1\u5931\u8D25",{channel:o,code:l.code,message:l.message}),new Error(`\u9489\u9489\u51FA\u7AD9\u5931\u8D25 (${o}) code=${l.code}: ${l.message??""}`);return h.debug("dingtalk-robot-client","sent",{channel:o}),l}};function _p(t,e){if(!t?.title?.trim()||!t.text?.trim())throw new Error(`${e} \u7F3A\u5C11\u5361\u7247 title/text`);if(!Array.isArray(t.buttons)||t.buttons.length<1||t.buttons.length>5)throw new Error(`${e} \u7684 buttons \u5FC5\u987B\u5305\u542B 1\uFF5E5 \u4E2A\u6309\u94AE`);for(let[i,s]of t.buttons.entries())if(!s?.title?.trim()||!s.url?.trim())throw new Error(`${e} \u7684\u7B2C ${i+1} \u4E2A\u6309\u94AE\u7F3A\u5C11 title/url`);let n=t.buttons.length,r=t.orientation??(n===2?"horizontal":"vertical");if(r==="horizontal"&&n!==2)throw new Error(`${e} \u4EC5\u53CC\u6309\u94AE\u652F\u6301 horizontal \u6392\u5217`);if(n===1){let[i]=t.buttons;return{msgKey:"sampleActionCard",msgParam:JSON.stringify({title:t.title,text:t.text,singleTitle:i.title,singleURL:i.url})}}if(n===2&&r==="horizontal"){let[i,s]=t.buttons;return{msgKey:"sampleActionCard6",msgParam:JSON.stringify({title:t.title,text:t.text,buttonTitle1:i.title,buttonUrl1:i.url,buttonTitle2:s.title,buttonUrl2:s.url})}}let o={title:t.title,text:t.text};return t.buttons.forEach((i,s)=>{o[`actionTitle${s+1}`]=i.title,o[`actionURL${s+1}`]=i.url}),{msgKey:`sampleActionCard${n}`,msgParam:JSON.stringify(o)}}a(_p,"buildActionCardMessage");function hi(t){let e=String(t??"").trim();return e&&(e.length<Tp?e.padStart(Tp,"0"):e)}a(hi,"padStaffId");function CS(t,e){let n=e.filter(o=>!t.includes(`@${o}`));return n.length===0?t:`${n.map(o=>`@${o}`).join(" ")} ${t}`}a(CS,"prependAtPlaceholders");function TS(t){let e=t.match(/^\s*[【[]([^】\]]{1,20})[】\]]/);return e?.[1]?e[1].trim():(t.split(/\r?\n/).find(o=>o.trim().length>0)??"").replace(/[#*_`>~-]/g,"").trim().slice(0,20).trim()||"\u673A\u5668\u4EBA\u6D88\u606F"}a(TS,"deriveTitle");var _S="1",yi=class{static{a(this,"DingTalkSender")}robotClient;robotCode;registry;constructor(e={},n={}){n.robotClient?this.robotClient=n.robotClient:e.robot?.appKey&&e.robot?.appSecret&&(this.robotClient=new Et({appKey:e.robot.appKey,appSecret:e.robot.appSecret,...e.fetchImpl?{fetchImpl:e.fetchImpl}:{}})),this.robotCode=e.robotCode??e.robot?.appKey,this.registry=n.registry??Rn}get canReplyInSession(){return!!this.robotClient}async replyToConversation(e,n,r={}){let o=r.entry??this.registry.lookup(e),i=o?.conversationType===_S,s=i||r.mentionSender===!1?"":typeof r.mentionSender=="string"?r.mentionSender.trim():String(o?.senderStaffId??"").trim(),c=i?[]:[...new Set([s,...(r.mentionUserIds??[]).map(u=>u.trim())].filter(Boolean))],l=c.length>0?{atUserIds:c}:{};if(!r.preferWebhook&&this.robotClient&&o?.sessionWebhook)try{return await this.robotClient.replyViaSessionWebhook(o.sessionWebhook,n,{...c.length>0?{atUserStaffIds:c}:{},...typeof o.sessionWebhookExpiredTime=="number"?{expiredTime:o.sessionWebhookExpiredTime}:{},...r.title?{title:r.title}:{}}),{via:"session",...l}}catch(u){let f=u instanceof Error?u.message:String(u),p=await this.tryWebhook(n,c,r);if(p&&p.via==="webhook")return p;let g=p?.reason?` + ${p.reason}`:"";return{via:"skipped",reason:`session \u5931\u8D25: ${f}${g}`}}if(!r.preferWebhook&&this.robotClient&&this.robotCode&&!o?.sessionWebhook)try{let f=(r.senderName?`${r.senderName}
|
|
270
270
|
|
|
271
271
|
`:"")+n,p=r.title??f.slice(0,20).replace(/\n/g," ");return await this.robotClient.sendGroupMarkdown(this.robotCode,e,p,f),{via:"robotApi"}}catch(u){let f=u instanceof Error?u.message:String(u),p=await this.tryWebhook(n,c,r);if(p&&p.via==="webhook")return p;let g=p?.reason?` + ${p.reason}`:"";return{via:"skipped",reason:`robotApi \u5931\u8D25: ${f}${g}`}}let d=await this.tryWebhook(n,c,r);return d||{via:"skipped",reason:"\u65E0\u53EF\u7528 sessionWebhook\uFF08\u672A\u914D\u673A\u5668\u4EBA\u6216\u767B\u8BB0\u8868\u672A\u547D\u4E2D\uFF09\uFF0C\u4E14\u672A\u63D0\u4F9B webhookFallback"}}async tryWebhook(e,n,r){if(r.webhookFallback)try{let o=n.map(i=>hi(i)).filter(Boolean);return await r.webhookFallback(e,{...r.title?{title:r.title}:{},...o.length>0?{atUserIds:o}:{}}),{via:"webhook",...n.length>0?{atUserIds:n}:{}}}catch(o){return{via:"skipped",reason:`webhook \u964D\u7EA7\u5931\u8D25: ${o instanceof Error?o.message:String(o)}`}}}};var wc=class{static{a(this,"DingTalkRobotClientPool")}entries=new Map;get(e,n,r){let o=this.entries.get(e);if(o&&o.clientId===n.clientId&&o.clientSecret===n.clientSecret&&o.fetchImpl===r)return o.client;let i=new Et({appKey:n.clientId,appSecret:n.clientSecret,fetchImpl:r});return this.entries.set(e,{...n,fetchImpl:r,client:i}),i}clear(){this.entries.clear()}},Ap=new wc;var bc=["\u601D\u8003","\u4E13\u6CE8","\u7B49\u4E00\u7B49"],kc=class{static{a(this,"DingTalkEmotionFeedbackCoordinator")}states=new Map;begin(e,n){let r=qe(e);if(!r||this.states.get(r.openMsgId))return;let i={robotCode:r.robotCode,openMsgId:r.openMsgId,openConversationId:r.conversationId,emotionName:AS()},s={context:r,emotionContext:i,client:n,delivered:!1,addPromise:Promise.resolve().then(()=>n.replyEmotion(i)).then(()=>(h.debug("dingtalk-emotion-feedback","processing emotion added",{messageId:wi(r.openMsgId),credRef:r.credRef,emotionName:i.emotionName}),!0)).catch(c=>(h.warn("dingtalk-emotion-feedback","add processing emotion failed; workflow continues",{messageId:wi(r.openMsgId),credRef:r.credRef,emotionName:i.emotionName,error:c instanceof Error?c.message:String(c)}),!1))};this.states.set(r.openMsgId,s)}markDelivered(e,n){let r=qe(e);if(!r||n!==r.conversationId)return;let o=this.states.get(r.openMsgId);!o||!Ep(o.context,r)||o.finalizePromise||(o.delivered=!0)}finalize(e,n){let r=qe(e);if(!r)return Promise.resolve();let o=this.states.get(r.openMsgId);return!o||!Ep(o.context,r)?Promise.resolve():this.finalizeState(o,n)}clear(){this.states.clear()}size(){return this.states.size}finalizeState(e,n){if(e.finalizePromise)return e.finalizePromise;let r=e.delivered&&n.completed&&n.recorded;return e.finalizePromise=(async()=>{if(await e.addPromise&&!r)try{await e.client.recallEmotion(e.emotionContext),h.debug("dingtalk-emotion-feedback","processing emotion recalled",{messageId:wi(e.context.openMsgId),credRef:e.context.credRef,emotionName:e.emotionContext.emotionName})}catch(i){h.warn("dingtalk-emotion-feedback","recall processing emotion failed; workflow unaffected",{messageId:wi(e.context.openMsgId),credRef:e.context.credRef,emotionName:e.emotionContext.emotionName,error:i instanceof Error?i.message:String(i)})}})().finally(()=>{this.states.get(e.context.openMsgId)===e&&this.states.delete(e.context.openMsgId)}),e.finalizePromise}};function Ep(t,e){return t.openMsgId===e.openMsgId&&t.conversationId===e.conversationId&&t.robotCode===e.robotCode&&t.credRef===e.credRef}a(Ep,"sameContext");function wi(t){return t.length<=8?"***":`${t.slice(0,4)}\u2026${t.slice(-4)}`}a(wi,"maskMessageId");function AS(){let t=Math.floor(Math.random()*bc.length);return bc[t]??bc[0]}a(AS,"pickProcessingEmotion");var bi=new kc;var DS=15e3;function $S(t){let e=t.runner??J,n=t.dwsBin,r=t.timeoutMs,o=t.fetchImpl??globalThis.fetch,i=t.emotionFeedbackCoordinator??bi,s=t.robotClientPool??Ap,c=t.atUserIdResolver??Rp;function l(p,g,m){p.length>=2e3&&h.warn("messaging","\u6587\u672C\u8D85\u957F\uFF0C\u53EF\u80FD\u88AB\u9489\u9489\u9759\u9ED8\u4E22\u5F03",{channel:g,targetId:m,contentLen:p.length})}a(l,"warnIfContentTooLong");async function d(p){let g=Date.now(),m=p.slice(0,3).join(" ");h.debug("messaging","dws call",{cmd:m});let y=await ne(n,p,{timeoutMs:r,runner:e}),w=Date.now()-g;if(y.exitCode!==0)throw h.error("messaging","dws \u6D88\u606F\u53D1\u9001\u5931\u8D25",{cmd:m,exitCode:y.exitCode,stderr:y.stderr.slice(0,300),elapsed:w}),new Error(`dws \u6D88\u606F\u53D1\u9001\u5931\u8D25 (exit ${y.exitCode}): ${y.stderr.slice(0,200)}`);let b=MS(y.stdout);if(b)throw h.error("messaging","dws \u6D88\u606F\u53D1\u9001\u5931\u8D25",{cmd:m,code:b.code,desc:b.desc,elapsed:w}),new Error(`dws \u6D88\u606F\u53D1\u9001\u5931\u8D25 (${b.code}): ${b.desc}`);h.debug("messaging","dws call completed",{cmd:m,elapsed:w})}a(d,"runDws");let u=new yi({...t.robot?{robot:t.robot}:{},...t.robotCode?{robotCode:t.robotCode}:{},...t.fetchImpl?{fetchImpl:t.fetchImpl}:{}}),f={async sendToUser(p,g){h.info("messaging","sendToUser",{userId:p,contentLen:g.length}),l(g,"user",p),await d(["chat","message","send","--user",p,"--title",vc(g),"--text",g,"-y"])},async sendToGroup(p,g){h.info("messaging","sendToGroup",{groupId:p,contentLen:g.length}),l(g,"group",p),await d(["chat","message","send","--group",p,"--title",vc(g),"--text",g,"-y"])},async sendCard(p,g){let m=OS(g);p.type==="user"?await this.sendToUser(p.id,m):await this.sendToGroup(p.id,m)},async sendDingTalkActionCardToGroup(p,g,m){let y=qe(t.eventContext),w=y?.conversationId===p?y:void 0,x=m?.credRef?.trim()||w?.credRef;if(!x)throw new Error("sendDingTalkActionCardToGroup \u65E0\u6CD5\u786E\u5B9A\u673A\u5668\u4EBA\u8EAB\u4EFD\uFF1A\u4E3B\u52A8\u6216\u8DE8\u7FA4\u53D1\u9001\u5FC5\u987B\u63D0\u4F9B options.credRef");let I=t.robots?.[x];if(!I?.client_id||!I.client_secret)throw new Error(`sendDingTalkActionCardToGroup \u7684\u673A\u5668\u4EBA\u51ED\u636E credRef="${x}" \u672A\u914D\u7F6E\u6216\u4E0D\u5B8C\u6574`);let k=await s.get(x,{clientId:I.client_id,clientSecret:I.client_secret},o).sendGroupActionCard(I.client_id,p,g);return i.markDelivered(t.eventContext,p),h.info("messaging","sendDingTalkActionCardToGroup",{conversationId:p,credRef:x,hasProcessQueryKey:!!k.processQueryKey}),k},async sendDingTalkActionCardToUsers(p,g,m){let y=m?.credRef?.trim();if(!y)throw new Error("sendDingTalkActionCardToUsers \u5FC5\u987B\u63D0\u4F9B options.credRef");let w=t.robots?.[y];if(!w?.client_id||!w.client_secret)throw new Error(`sendDingTalkActionCardToUsers \u7684\u673A\u5668\u4EBA\u51ED\u636E credRef="${y}" \u672A\u914D\u7F6E\u6216\u4E0D\u5B8C\u6574`);let x=await s.get(y,{clientId:w.client_id,clientSecret:w.client_secret},o).sendActionCardToUsers(w.client_id,p,g);return h.info("messaging","sendDingTalkActionCardToUsers",{credRef:y,userCount:p.length,hasProcessQueryKey:!!x.processQueryKey}),x},async sendDingTalkActionCardByWebhook(p,g){let m=p?.trim();if(!m)throw new Error("sendDingTalkActionCardByWebhook \u7F3A\u5C11 credRef");let y=t.webhookCreds?.[m];if(!y?.url){let I=Object.keys(t.webhookCreds??{}).join(", ")||"\u65E0";throw new Error(`sendDingTalkActionCardByWebhook \u7684 Webhook \u51ED\u636E credRef="${m}" \u672A\u914D\u7F6E\u6216\u4E0D\u5B8C\u6574\uFF08\u53EF\u7528: ${I}\uFF09`)}PS(g,"sendDingTalkActionCardByWebhook");let w=Dp(y.url);h.info("messaging","sendDingTalkActionCardByWebhook",{credRef:m,host:w,signed:!!y.secret});let b={msgtype:"actionCard",actionCard:{title:g.title,text:g.text,btnOrientation:"1",btns:g.buttons.map(I=>({title:I.title,actionURL:I.url}))}},x=y.secret?$p(y.url,y.secret):y.url;await Pp(o,x,b,r,w)},async reply(p){h.warn("messaging","reply called without target context",{contentLen:p.length})},async replyToConversation(p,g,m){let y=m?.credRef?.trim(),w=y?t.webhookCreds?.[y]:void 0,b=y?!w&&!t.robots?.[y]:!1,x=b?`credRef="${y}" \u672A\u547D\u4E2D\u547D\u540D\u96C6(\u53EF\u7528: ${Object.keys(t.webhookCreds??{}).join(", ")||"\u65E0"})`:void 0,I=m?.webhook??w,v=I?.url?(T,_)=>f.sendToGroupByWebhook({url:I.url,...I.secret?{secret:I.secret}:{}},T,_):void 0,k=m?.mentionSender;if(m?.preferWebhook&&m.mentionSender!==!1&&typeof m.mentionSender!="string"){let T=Pr(t.eventContext);if(T?.conversationId===p&&T.corpId)try{k=await c(T.senderOpenDingTalkId,T.senderName,T.corpId)}catch(_){h.warn("messaging","Webhook @\u4EBA\u8EAB\u4EFD\u89E3\u6790\u5931\u8D25\uFF0C\u964D\u7EA7\u4E3A\u4E0D @ \u4EBA",{conversationId:p,error:_ instanceof Error?_.message:String(_)})}else T?.conversationId===p&&h.warn("messaging","Webhook \u7FA4\u672A\u914D\u7F6E corpId\uFF0C\u8DF3\u8FC7 @\u63D0\u95EE\u8005",{conversationId:p});(typeof k!="string"||!k.trim())&&(k=!1)}let R=await u.replyToConversation(p,g,{...k!==void 0?{mentionSender:k}:{},...m?.mentionUserIds?.length?{mentionUserIds:m.mentionUserIds}:{},...m?.senderName?{senderName:m.senderName}:{},...m?.title?{title:m.title}:{},...m?.preferWebhook?{preferWebhook:m.preferWebhook}:{},...v?{webhookFallback:v}:{}});return x&&(R.reason=R.reason?`${R.reason}; ${x}`:x),R.via==="session"||R.via==="robotApi"||R.via==="webhook"?i.markDelivered(t.eventContext,p):b&&(R.configError=!0),h.info("messaging","replyToConversation",{conversationId:p,via:R.via,atUserIds:R.atUserIds,reason:R.reason}),R},async replyToConversationWithButtons(p,g,m){try{let y=qe(t.eventContext),b=m?.credRef?.trim()||y?.credRef;if(!b)return{via:"skipped",reason:"replyToConversationWithButtons \u65E0\u6CD5\u786E\u5B9A\u673A\u5668\u4EBA\u8EAB\u4EFD\uFF08\u65E0 credRef\uFF09"};let x=t.robots?.[b];if(!x?.client_id||!x.client_secret)return{via:"skipped",reason:`replyToConversationWithButtons credRef="${b}" \u672A\u547D\u4E2D\u673A\u5668\u4EBA\u51ED\u636E`,configError:!0};let I=Rn.lookup(p),v=I?.conversationType,k=m?.senderStaffId?.trim()||I?.senderStaffId,R={title:g.title,text:g.text,buttons:g.buttons};return v==="1"?k?(await f.sendDingTalkActionCardToUsers([k],R,{credRef:b}),i.markDelivered(t.eventContext,p),{via:"session"}):{via:"skipped",reason:"\u5355\u804A ActionCard \u9700\u8981 senderStaffId \u4F46\u672A\u53D6\u5230"}:(await f.sendDingTalkActionCardToGroup(p,R,{credRef:b}),i.markDelivered(t.eventContext,p),{via:"session"})}catch(y){let w=y instanceof Error?y.message:String(y);return h.warn("messaging","replyToConversationWithButtons \u5931\u8D25",{conversationId:p,reason:w}),{via:"skipped",reason:w}}},beginDingTalkProcessingFeedback(p){let g=qe(p);if(!g)return;let m=t.robots?.[g.credRef];if(!m?.client_id||!m.client_secret){h.warn("messaging","skip processing emotion: credRef \u672A\u547D\u4E2D\u673A\u5668\u4EBA\u51ED\u8BC1",{credRef:g.credRef,available:Object.keys(t.robots??{})});return}let y=s.get(g.credRef,{clientId:m.client_id,clientSecret:m.client_secret},o);i.begin(p,y)},async sendToGroupByWebhook(p,g,m){let y=p?.url,w=p?.secret;if(!y)throw new Error("sendToGroupByWebhook \u7F3A\u5C11 url");let b=Dp(y);h.info("messaging","sendToGroupByWebhook",{host:b,contentLen:g.length,signed:!!w});let x=m?.title??vc(g),I=[...m?.atUserIds??[],...m?.atMobiles??[]],v=I.length>0?Cp(g,I):g,k={msgtype:"markdown",markdown:{title:x,text:v},at:{isAtAll:m?.atAll??!1,...m?.atUserIds?.length?{atUserIds:m.atUserIds}:{},...m?.atMobiles?.length?{atMobiles:m.atMobiles}:{}}},R=w?$p(y,w):y;await Pp(o,R,k,r,b)}};return f}a($S,"createMessagingToolkitFromConfig");function PS(t,e){if(!t?.title?.trim()||!t.text?.trim())throw new Error(`${e} \u7F3A\u5C11\u5361\u7247 title/text`);if(!Array.isArray(t.buttons)||t.buttons.length!==2)throw new Error(`${e} \u7684 buttons \u5FC5\u987B\u6070\u597D\u5305\u542B\u4E24\u4E2A\u6309\u94AE`);for(let[n,r]of t.buttons.entries())if(!r?.title?.trim()||!r.url?.trim())throw new Error(`${e} \u7684\u7B2C ${n+1} \u4E2A\u6309\u94AE\u7F3A\u5C11 title/url`)}a(PS,"validateDingTalkActionCard");function Dp(t){try{return new URL(t).host}catch{return"webhook"}}a(Dp,"safeHost");function $p(t,e){let n=Date.now(),r=`${n}
|
|
272
272
|
${e}`,o=ES("sha256",e).update(r,"utf8").digest("base64"),i=t.includes("?")?"&":"?";return`${t}${i}timestamp=${n}&sign=${encodeURIComponent(o)}`}a($p,"signWebhookUrl");async function Pp(t,e,n,r,o){let i;try{i=await t(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),signal:AbortSignal.timeout(r)})}catch(c){let l=c instanceof Error?c.message:String(c);throw h.error("messaging","webhook \u8BF7\u6C42\u5931\u8D25",{channel:o,error:l}),new Error(`webhook \u8BF7\u6C42\u5931\u8D25 (${o}): ${l}`)}if(!i.ok){let c=await i.text().catch(()=>"");throw h.error("messaging","webhook HTTP \u975E 2xx",{channel:o,status:i.status,body:c.slice(0,200)}),new Error(`webhook \u53D1\u9001\u5931\u8D25 (${o}) HTTP ${i.status}: ${c.slice(0,200)}`)}let s=await i.json().catch(()=>({}));if(s.errcode&&s.errcode!==0)throw h.error("messaging","webhook \u4E1A\u52A1\u5931\u8D25",{channel:o,errcode:s.errcode,errmsg:s.errmsg}),new Error(`webhook \u53D1\u9001\u5931\u8D25 (${o}) errcode=${s.errcode}: ${s.errmsg??""}`)}a(Pp,"postWebhook");function MS(t){let e=t.trim();if(!e)return null;let n;try{n=JSON.parse(e)}catch{return null}if(!n||typeof n!="object")return null;let r=n;if(r.success!==!1)return null;let o=r.data&&typeof r.data=="object"?r.data:{},i=String(r.code??o.code??r.errorCode??"UNKNOWN"),s=String(o.desc??r.errorMessage??r.message??"\u53D1\u9001\u5931\u8D25");return{code:i,desc:s}}a(MS,"parseDwsFailure");function vc(t){let e=t.match(/^\s*[【\[]([^】\]]{1,20})[】\]]/);return e?.[1]?e[1].trim():(t.split(/\r?\n/).find(i=>i.trim().length>0)??"").replace(/[#*_`>~-]/g,"").trim().slice(0,20).trim()||"\u5DE5\u4F5C\u6D41\u901A\u77E5"}a(vc,"deriveTitle");function OS(t){let e=[];if(e.push(`**${t.title}**`),e.push(""),e.push(t.content),t.actions&&t.actions.length>0){e.push(""),e.push("---");for(let n of t.actions)e.push(`- [${n.label}]`)}return e.join(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aitable-workflow-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28-beta.1789458587713",
|
|
4
4
|
"description": "配置驱动的 AI 表格工作流自动化引擎(core):YAML 定义业务流程,AI 逐步执行并回写钉钉 AI 表格;含 CLI 与工作流引擎。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"aitable-workflow-base": "0.1.
|
|
27
|
+
"aitable-workflow-base": "0.1.28-beta.1789458587713",
|
|
28
28
|
"@inquirer/prompts": "^8.5.2",
|
|
29
29
|
"cron-parser": "^5.6.2",
|
|
30
30
|
"cross-spawn": "^7.0.6",
|
|
@@ -49,7 +49,7 @@ AI 表格读写:读/查当前表记录、更新当前行、多表写入(create/u
|
|
|
49
49
|
- `workspace_dir`(string) — agent 执行 workspace 目录(相对 configDir),缺省 workspaces/<role.id>
|
|
50
50
|
|
|
51
51
|
**方法(methods):**
|
|
52
|
-
- `run(prompt: string, options?: { agent?: string, workDir?: string, model?: string, timeoutMs?: number }): Promise<{ response: string, success: boolean, sessionId?: string }>` — 发送 prompt 给编程 Agent 执行任务
|
|
52
|
+
- `run(prompt: string, options?: { agent?: string, workDir?: string, sessionId?: string, model?: string, timeoutMs?: number }): Promise<{ response: string, success: boolean, sessionId?: string }>` — 发送 prompt 给编程 Agent 执行任务
|
|
53
53
|
- `activeAgent(): string` — 返回当前配置的 Agent 类型
|
|
54
54
|
- `available(): boolean` — 是否有可用的编程 Agent
|
|
55
55
|
|