@fastgpt-plugin/sdk-factory 0.0.1-alpha.7 → 0.0.1-alpha.8

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.
Files changed (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import e from"zod";import{Readable as t}from"node:stream";import n,{Readable as r}from"stream";import{randomUUID as i}from"node:crypto";var a=class e{stream;closed=!1;constructor(e){this.stream=new t({objectMode:!0,read(){}}),e?.(this)}static create(t){return new e(t)}write(e){this.ensureWritable(),this.stream.push(e)}send(e){this.write(e)}close(){this.closed||(this.closed=!0,this.stream.push(null))}end(){this.close()}fail(e){this.closed=!0,this.stream.destroy(e)}toReadable(){return this.stream}onData(e){return this.stream.on(`data`,e),this}onEnd(e){return this.stream.on(`end`,e),this}onError(e){return this.stream.on(`error`,e),this}async consume(e){for await(let t of this.values())await e(t)}async*values(){for await(let e of this.stream)yield e}ensureWritable(){if(this.closed||this.stream.destroyed)throw Error(`StreamData is already closed`)}};const o={ready:`client.ready`,stdio:`client.stdio`,fail:`client.fail`,request:`client.request`},s=e.enum([o.ready,o.stdio,o.fail,o.request]);e.object({pid:e.number().optional(),version:e.string().optional(),runtimeMode:e.string().optional(),capabilities:e.array(e.string()).optional(),startedAt:e.number().optional(),meta:e.unknown().optional()}),e.object({stream:e.enum([`stdout`,`stderr`]),chunk:e.string(),timestamp:e.number().optional()}),e.object({reason:e.enum([`startup`,`runtime`,`crash`,`shutdown`,`unknown`]),error:e.object({code:e.string(),message:e.string(),data:e.unknown().optional()}).optional(),exitCode:e.number().nullable().optional(),signal:e.string().nullable().optional(),timestamp:e.number().optional()});const c={streamFrame:`channel.stream`},l=e.enum([c.streamFrame]),u={request:`host.request`,ping:`host.ping`,shutdown:`host.shutdown`},d=e.enum([u.request,u.ping,u.shutdown]);e.object({timestamp:e.number()}),e.object({timestamp:e.number(),receivedAt:e.number().optional()}),e.object({reason:e.string().optional(),timeoutMs:e.number().nonnegative().optional()}),e.object({accepted:e.boolean(),message:e.string().optional()}),e.union([s,l,d]);const f=e.literal(`1.0`),p=e.union([e.string(),e.number()]),m=e.object({code:e.string(),message:e.string(),data:e.unknown().optional()}),h={parseError:`PARSE_ERROR`,invalidMessage:`INVALID_MESSAGE`,methodNotFound:`METHOD_NOT_FOUND`,invalidParams:`INVALID_PARAMS`,internalError:`INTERNAL_ERROR`,requestTimeout:`REQUEST_TIMEOUT`,channelClosed:`CHANNEL_CLOSED`,streamError:`STREAM_ERROR`},g=e.object({protocol:f,id:p,method:e.string(),params:e.unknown().optional(),traceId:e.string().optional(),timestamp:e.number().optional()}),_=g.omit({id:!0}),v=e.object({protocol:f,id:p,result:e.unknown().optional(),traceId:e.string().optional(),timestamp:e.number().optional()}),y=e.object({protocol:f,id:p,error:m,traceId:e.string().optional(),timestamp:e.number().optional()});e.union([g,_,v,y]),e.enum([`ipc`,`tcp`,`http`]),e.enum([`host`,`client`]),e.object({streamId:e.string(),streamName:e.string(),meta:e.unknown().optional()}),e.discriminatedUnion(`type`,[e.object({type:e.literal(`start`),streamId:e.string(),streamName:e.string(),meta:e.unknown().optional()}),e.object({type:e.literal(`chunk`),streamId:e.string(),chunk:e.unknown()}),e.object({type:e.literal(`end`),streamId:e.string()}),e.object({type:e.literal(`error`),streamId:e.string(),error:m})]);const ee=e=>(e=e.replace(/(?<=https?:\/\/)[^\s]+/g,`xxx`),e=e.replace(/ns-[\w-]+/g,`xxx`),e),b=(e,t=``)=>ee(x(e)||t),x=(e,t=0)=>t>5?void 0:typeof e==`string`?e:!e||typeof e!=`object`?void 0:S(e,t)||T(C(e?.response?.data,t),C(e?.response?.body,t),C(e?.body,t),w(e?.response?.data?.reason),w(e?.response?.reason),e?.response?.data?.message||e?.response?.message||e?.message||e?.response?.data?.msg||e?.response?.msg||e?.msg,w(e?.response?.data?.error),w(e?.response?.error),w(e?.error),x(e?.error,t+1),x(e?.cause,t+1),w(e)),S=(e,t)=>{if(!(!(`reason`in e)&&!(`error`in e)))return E(w(e.reason),x(e.error,t+1))},C=(e,t)=>{if(e){if(typeof e!=`string`)return x(e,t+1);try{let n=JSON.parse(e);return x(n?.error,t+1)||x(n,t+1)}catch{return e||void 0}}},w=e=>{if(!e||typeof e!=`object`)return;let t=e,n=t[`zh-CN`]??t.en??t[`zh-Hant`];return typeof n==`string`?n:void 0},T=(...e)=>e.find(e=>typeof e==`string`&&e.length>0),E=(...e)=>{let t=e.filter((t,n)=>!!t&&e.indexOf(t)===n);return t.length>0?t.join(`: `):void 0},te=`application/javascript,application/json,application/yaml,application/zip,image/jpeg,image/png,image/gif,image/webp,image/svg+xml,application/pdf,text/plain,text/csv,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/msword,application/vnd.ms-excel,application/vnd.ms-powerpoint,text/markdown,audio/mpeg,video/mp4,audio/wav,text/html,application/xml,application/gzip,application/octet-stream,multipart/form-data,text/event-stream`.split(`,`),D=e.enum(te).and(e.string().regex(/^[^/]+\/[^/]+$/)),ne=e.object({fileKey:e.string(),fileName:e.string(),contentType:D,size:e.number(),etag:e.string(),createTime:e.date()}),re=e.object({fileKey:e.string().optional(),path:e.string().optional(),fileName:e.string().optional(),contentType:D.optional(),overwrite:e.boolean().optional(),file:e.union([e.instanceof(r,{error:`Stream cannot be empty`}),e.union([e.instanceof(Buffer,{error:`Buffer is required`}),e.instanceof(Uint8Array,{error:`Uint8Array is required`})]).transform(e=>e instanceof Uint8Array&&!(e instanceof Buffer)?Buffer.from(e):e)])});e.object({...re.omit({fileKey:!0,overwrite:!0,path:!0}).shape});const ie=e.object({...ne.omit({fileKey:!0}).partial().shape,accessURL:e.string()});e.object({username:e.string(),contact:e.string().nullish(),memberName:e.string().nullish(),orgs:e.array(e.object({pathId:e.string(),name:e.string()})),groups:e.array(e.object({name:e.string()}))});const O=e.enum([`uploadFile`,`userInfo`,`wecomCorpToken`]).enum,k=e=>[e,null];function A(e,t){return j(e)?[null,e]:[null,{reason:e,error:t}]}function j(e){return!!(e&&typeof e==`object`&&`reason`in e&&`error`in e)}var M=class{constructor(e,t={}){this.channel=e,this.options=t}async userInfo(){try{let[e,t]=(await this.channel.request(o.request,{method:O.userInfo,args:{}},{traceId:this.options.invocationId})).result;return t?A({en:`Failed to get user info`,"zh-CN":`获取用户信息失败`},t):k(e)}catch(e){return A({en:`Failed to get user info`,"zh-CN":`获取用户信息失败`},e)}}async uploadFile(e){try{let[t,n]=(await this.channel.request(o.request,{method:O.uploadFile,args:{contentType:e.contentType,fileName:e.fileName}},{traceId:this.options.invocationId,input:this.toUploadInputStream(e.file)})).result;return n?A({en:`Failed to upload file`,"zh-CN":`上传文件失败`},n):k(ie.parse(t))}catch(e){return A({en:`Failed to upload file`,"zh-CN":`上传文件失败`},e)}}toUploadInputStream(e){return e instanceof n.Readable?e:n.Readable.from(Buffer.from(e))}};const N=e.enum([`en`,`zh-CN`,`zh-Hant`]).enum;e.object({[N.en]:e.string(),[N[`zh-CN`]]:e.string().optional(),[N[`zh-Hant`]]:e.string().optional()});const P=e.object({[N.en]:e.string(),[N[`zh-CN`]]:e.string(),[N[`zh-Hant`]]:e.string()});e.object({pluginId:e.string(),version:e.string(),etag:e.string()});const F=e.literal(`system`).or(e.string()),I=e.object({id:e.string(),name:P});e.array(I);const L=e.enum([`localPool`,`serverless`]).enum;e.object({pluginId:e.string(),version:e.string().optional(),source:F.optional()});const R=`__fastgptChannelReply__`;var z=class{transport=`ipc`;pending=new Map;errorHandlers=new Set;closeHandlers=new Set;incomingStreams=new Map;bufferedIncomingStreams=new Map;pendingStreamWaiters=new Map;requestHandler=null;notificationHandler=null;closed=!1;unsubscribeMessage;constructor(e,t,n={}){this.side=e,this.endpoint=t,this.options=n,this.unsubscribeMessage=V(t,e=>{this.dispatch(e).catch(e=>{this.emitError(e instanceof Error?e:Error(String(e)))})})}async request(e,t,n){this.ensureOpen();let r=n?.id??i(),a=n?.timeoutMs??this.options.defaultTimeoutMs??3e4,o=n?.input===void 0?void 0:this.pipeStream(X(r),n.input,{traceId:n.traceId,streamId:n.inputStream?.streamId,streamName:n.inputStream?.streamName,meta:n.inputStream?.meta}),s=Date.now();o&&o.catch(e=>{this.emitError(e instanceof Error?e:Error(String(e)))});let c=await new Promise((i,o)=>{let s=setTimeout(()=>{this.pending.delete(r),o(Object.assign(Error(`Request timeout: ${String(e)}`),{code:h.requestTimeout,requestId:r,method:e}))},a);this.pending.set(r,{method:String(e),resolve:i,reject:o,timer:s}),this.send({protocol:`1.0`,id:r,method:String(e),params:t,...n?.traceId===void 0?{}:{traceId:n.traceId},timestamp:Date.now()}).catch(e=>{clearTimeout(s),this.pending.delete(r),o(e)})}),l=c,u;if(q(c)&&(l=c.result,c.hasOutputStream)){let e=Date.now()-s,t=Math.max(1,a-e);u=await this.waitForStream(Z(r),{timeoutMs:t})}return{requestId:r,result:l,...u===void 0?{}:{output:u},...o===void 0?{}:{inputDone:o}}}async notify(e,t,n){this.ensureOpen(),await this.send({protocol:`1.0`,method:String(e),params:t,...n?.traceId===void 0?{}:{traceId:n.traceId},timestamp:Date.now()})}setRequestHandler(e){this.requestHandler=e}setNotificationHandler(e){this.notificationHandler=e}async waitForStream(e,t){this.ensureOpen();let n=this.bufferedIncomingStreams.get(e);if(n&&n.length>0){let t=n.shift();return n.length===0&&this.bufferedIncomingStreams.delete(e),t}return new Promise((n,r)=>{let i={resolve:n,reject:r};t?.timeoutMs!==void 0&&(i.timer=setTimeout(()=>{let t=this.pendingStreamWaiters.get(e);if(!t)return;let n=t.indexOf(i);n>=0&&t.splice(n,1),t.length===0&&this.pendingStreamWaiters.delete(e),r(Error(`Wait stream timeout: ${e}`))},t.timeoutMs)),this.pendingStreamWaiters.has(e)||this.pendingStreamWaiters.set(e,[]),this.pendingStreamWaiters.get(e).push(i)})}async createWritableStream(e,t){this.ensureOpen();let n=t?.streamId??i(),r=!1,a=t?.streamName??e;return await this.sendStreamFrame({type:`start`,streamId:n,streamName:a,...t?.meta===void 0?{}:{meta:t.meta}},t?.traceId),{streamId:n,streamName:a,...t?.meta===void 0?{}:{meta:t.meta},write:async e=>{if(r)throw Error(`Stream is already closed: ${n}`);await this.sendStreamFrame({type:`chunk`,streamId:n,chunk:e},t?.traceId)},end:async()=>{r||(r=!0,await this.sendStreamFrame({type:`end`,streamId:n},t?.traceId))},fail:async e=>{r||(r=!0,await this.sendStreamFrame({type:`error`,streamId:n,error:J(e)},t?.traceId))}}}async pipeStream(e,t,n){let r=await this.createWritableStream(e,n);try{for await(let e of ae(t))await r.write(e);await r.end()}catch(e){throw await r.fail(e instanceof Error?e:Error(String(e))),e}}onError(e){return this.errorHandlers.add(e),()=>{this.errorHandlers.delete(e)}}onClose(e){return this.closeHandlers.add(e),()=>{this.closeHandlers.delete(e)}}async close(e=Error(`Channel closed`)){this.closed||(this.closed=!0,this.unsubscribeMessage(),this.rejectAllPending(e),this.rejectAllPendingStreamWaiters(e),this.failAllIncomingStreams(e),this.closeHandlers.forEach(t=>t(e)))}createReply(e,t){return{[R]:!0,...e===void 0?{}:{result:e},...t?.output===void 0?{}:{output:t.output},...t?.outputStream===void 0?{}:{outputStream:t.outputStream}}}async dispatch(e){if(!this.closed){if(G(e)){this.handleResponse(e);return}if(W(e)){await this.handleRequest(e);return}await this.handleNotification(e)}}handleResponse(e){let t=this.pending.get(e.id);if(t){if(clearTimeout(t.timer),this.pending.delete(e.id),`error`in e){t.reject(Y(e.error));return}t.resolve(e.result)}}async handleRequest(e){if(!this.requestHandler){await this.replyError(e,{code:h.methodNotFound,message:`Method not found: ${e.method}`});return}try{let t=await this.requestHandler({id:e.id,method:e.method,params:e.params,...e.traceId===void 0?{}:{traceId:e.traceId},raw:e,waitForInputStream:t=>this.waitForStream(X(e.id),t)});if(K(t)){await this.handleReplyDescriptor(e,t);return}await this.reply(e,t)}catch(t){await this.replyError(e,t instanceof Error?t:Error(String(t)))}}async handleNotification(e){if(e.method===c.streamFrame){await this.handleStreamFrame(e.params,e.traceId);return}await this.notificationHandler?.({method:e.method,params:e.params,...e.traceId===void 0?{}:{traceId:e.traceId},raw:e})}async handleReplyDescriptor(e,t){t.output!==void 0&&this.pipeStream(Z(e.id),t.output,{traceId:t.outputStream?.traceId??e.traceId,streamId:t.outputStream?.streamId,streamName:t.outputStream?.streamName,meta:t.outputStream?.meta}).catch(e=>{this.emitError(e instanceof Error?e:Error(String(e)))}),await this.reply(e,{[R]:!0,hasOutputStream:t.output!==void 0,...t.result===void 0?{}:{result:t.result}})}async reply(e,t){await this.send({protocol:`1.0`,id:e.id,...t===void 0?{}:{result:t},...e.traceId===void 0?{}:{traceId:e.traceId},timestamp:Date.now()})}async replyError(e,t){await this.send({protocol:`1.0`,id:e.id,error:J(t),...e.traceId===void 0?{}:{traceId:e.traceId},timestamp:Date.now()})}async sendStreamFrame(e,t){await this.notify(c.streamFrame,e,{traceId:t})}async handleStreamFrame(e,t){switch(e.type){case`start`:{let n={streamId:e.streamId,streamName:e.streamName,stream:a.create(),...t===void 0?{}:{traceId:t},...e.meta===void 0?{}:{meta:e.meta}};this.incomingStreams.set(e.streamId,n),this.dispatchIncomingStream(n);return}case`chunk`:{let t=this.incomingStreams.get(e.streamId);if(!t){this.emitError(Error(`Stream not found: ${e.streamId}`));return}t.stream.write(e.chunk);return}case`end`:{let t=this.incomingStreams.get(e.streamId);if(!t)return;t.stream.end(),this.incomingStreams.delete(e.streamId);return}case`error`:{let t=this.incomingStreams.get(e.streamId);if(!t)return;t.stream.fail(Y(e.error)),this.incomingStreams.delete(e.streamId);return}}}dispatchIncomingStream(e){let t=!1,n=this.pendingStreamWaiters.get(e.streamName);if(n&&n.length>0){let r=n.shift();r.timer&&clearTimeout(r.timer),n.length===0&&this.pendingStreamWaiters.delete(e.streamName),r.resolve(e),t=!0}t||(this.bufferedIncomingStreams.has(e.streamName)||this.bufferedIncomingStreams.set(e.streamName,[]),this.bufferedIncomingStreams.get(e.streamName).push(e))}rejectAllPending(e){this.pending.forEach((t,n)=>{clearTimeout(t.timer),t.reject(e),this.pending.delete(n)})}rejectAllPendingStreamWaiters(e){this.pendingStreamWaiters.forEach((t,n)=>{t.forEach(t=>{t.timer&&clearTimeout(t.timer),t.reject(e)}),this.pendingStreamWaiters.delete(n)})}failAllIncomingStreams(e){this.incomingStreams.forEach((t,n)=>{t.stream.fail(e),this.incomingStreams.delete(n)}),this.bufferedIncomingStreams.clear()}emitError(e){this.errorHandlers.forEach(t=>t(e))}async send(e){await H(this.endpoint,e)}ensureOpen(){if(this.closed)throw Error(`Channel closed`)}};function B(e){return new z(`client`,process,e)}function V(e,t){let n=e,r=e=>{U(e)&&t(e)};return n.on(`message`,r),()=>n.off(`message`,r)}function H(e,t){let n=e;if(typeof n.send!=`function`)throw Error(`IPC channel not available`);return new Promise((e,r)=>{n.send(t,t=>{if(t){r(t);return}e()})})}function U(e){return!!(e&&typeof e==`object`&&`protocol`in e)}function W(e){return`id`in e&&`method`in e}function G(e){return`id`in e&&!(`method`in e)&&(`result`in e||`error`in e)}function K(e){return!!(e&&typeof e==`object`&&R in e&&e[R]===!0)}function q(e){return!!(e&&typeof e==`object`&&R in e&&`hasOutputStream`in e)}function J(e){return typeof e==`string`?{code:h.internalError,message:e}:e instanceof Error?{code:e.code??h.internalError,message:e.message,...e.stack===void 0?{}:{data:{stack:e.stack}}}:e}function Y(e){return Object.assign(Error(e.message),{code:e.code,data:e.data})}function ae(e){return e instanceof a?e.values():e}function X(e){return`request.input:${String(e)}`}function Z(e){return`request.output:${String(e)}`}var oe=class{channel;getChannel(){if(!this.channel)throw Error(`Channel is not initialized yet.`);return this.channel}mode;checkRuntimeMode(){process.env.RUNTIME_MODE==L.localPool&&(this.mode=L.localPool),process.env.RUNTIME_MODE===`dev`&&(this.mode=`dev`)}async init(){this.checkRuntimeMode(),this.mode===`localPool`&&(this.channel=B(),setImmediate(()=>{this.getChannel().notify(o.ready,{pid:process.pid,runtimeMode:L.localPool,startedAt:Date.now()})})),this.mode===`dev`&&(this.channel=se().pluginChannel,setImmediate(()=>{this.getChannel().notify(o.ready,{pid:process.pid,runtimeMode:`dev`,startedAt:Date.now()})}))}constructor(){this.init()}};function se(){let e=globalThis.__FASTGPT_PLUGIN_LOCAL_DEBUG_RUNTIME__;if(!e)throw Error(`Local debug runtime is not initialized. Set it before importing the plugin.`);return e}function ce(e){return e}var Q=class t extends oe{toolHandlers=new Map;childManifests=new Map;secretSchema=e.record(e.string(),e.unknown());constructor(e){super(),this.userToolManifest=e,this.mode&&this.getChannel().setRequestHandler(async e=>{if(e.method===u.request&&e.params.eventName===`run`)try{let{input:t,systemVar:n,childId:r,secrets:i}=e.params.payload,o=this.toolHandlers.get(r??`tool`);if(!o)throw Error(`No tool registered`);let s=a.create();return(async()=>{try{let r=await o.handler(t,{systemVar:n,secrets:i,invoke:new M(this.getChannel(),{invocationId:e.traceId}),streamResponse:e=>{s.send({type:`stream`,data:e})}});s.send({type:`response`,data:r})}catch(e){s.send({data:b(e,`Unknown error during tool execution`),type:`error`})}finally{s.end()}})(),this.getChannel().createReply(void 0,{output:s})}catch(e){let t=a.create();return t.write({data:b(e,`Unknown error during tool execution`),type:`error`}),t.end(),this.getChannel().createReply(void 0,{output:t})}})}setSecretSchema(e){this.secretSchema=e}registerTool(e,t=`tool`,n){this.toolHandlers.set(t,e),n&&this.childManifests.set(t,n)}static getInstance(e){return new t(e)}getSecretSchema(){return this.secretSchema}getToolHandler(e=`tool`){return this.toolHandlers.get(e)}getUserToolManifest(){return this.userToolManifest}getChildManifests(){return[...this.childManifests.values()]}};const le=({manifest:t,handler:n})=>{let r=Q.getInstance(t);return r.setSecretSchema(n.secretSchema??e.object()),r.registerTool(n),r},$=({manifest:t,children:n,secretSchema:r})=>{let i=Q.getInstance(t);return n.forEach(e=>{i.registerTool(e.handler,e.id,{id:e.id,description:e.description,name:e.name,...e.icon===void 0?{}:{icon:e.icon},...e.toolDescription===void 0?{}:{toolDescription:e.toolDescription}})}),i.setSecretSchema(r??e.object()),i};export{ce as createToolHandler,le as defineTool,$ as defineToolSet};
1
+ import e from"zod";import{Readable as t}from"node:stream";import n,{Readable as r}from"stream";import{randomUUID as i}from"node:crypto";var a=class e{stream;closed=!1;constructor(e){this.stream=new t({objectMode:!0,read(){}}),e?.(this)}static create(t){return new e(t)}write(e){this.ensureWritable(),this.stream.push(e)}send(e){this.write(e)}close(){this.closed||(this.closed=!0,this.stream.push(null))}end(){this.close()}fail(e){this.closed=!0,this.stream.destroy(e)}toReadable(){return this.stream}onData(e){return this.stream.on(`data`,e),this}onEnd(e){return this.stream.on(`end`,e),this}onError(e){return this.stream.on(`error`,e),this}async consume(e){for await(let t of this.values())await e(t)}async*values(){for await(let e of this.stream)yield e}ensureWritable(){if(this.closed||this.stream.destroyed)throw Error(`StreamData is already closed`)}};const o={ready:`client.ready`,stdio:`client.stdio`,fail:`client.fail`,request:`client.request`},s=e.enum([o.ready,o.stdio,o.fail,o.request]);e.object({pid:e.number().optional(),version:e.string().optional(),runtimeMode:e.string().optional(),capabilities:e.array(e.string()).optional(),startedAt:e.number().optional(),meta:e.unknown().optional()}),e.object({stream:e.enum([`stdout`,`stderr`]),chunk:e.string(),timestamp:e.number().optional()}),e.object({reason:e.enum([`startup`,`runtime`,`crash`,`shutdown`,`unknown`]),error:e.object({code:e.string(),message:e.string(),data:e.unknown().optional()}).optional(),exitCode:e.number().nullable().optional(),signal:e.string().nullable().optional(),timestamp:e.number().optional()});const c={streamFrame:`channel.stream`},l=e.enum([c.streamFrame]),u={request:`host.request`,ping:`host.ping`,shutdown:`host.shutdown`},d=e.enum([u.request,u.ping,u.shutdown]);e.object({timestamp:e.number()}),e.object({timestamp:e.number(),receivedAt:e.number().optional()}),e.object({reason:e.string().optional(),timeoutMs:e.number().nonnegative().optional()}),e.object({accepted:e.boolean(),message:e.string().optional()}),e.union([s,l,d]);const f=e.literal(`1.0`),p=e.union([e.string(),e.number()]),m=e.object({code:e.string(),message:e.string(),data:e.unknown().optional()}),h={parseError:`PARSE_ERROR`,invalidMessage:`INVALID_MESSAGE`,methodNotFound:`METHOD_NOT_FOUND`,invalidParams:`INVALID_PARAMS`,internalError:`INTERNAL_ERROR`,requestTimeout:`REQUEST_TIMEOUT`,channelClosed:`CHANNEL_CLOSED`,streamError:`STREAM_ERROR`},g=e.object({protocol:f,id:p,method:e.string(),params:e.unknown().optional(),traceId:e.string().optional(),timestamp:e.number().optional()}),_=g.omit({id:!0}),v=e.object({protocol:f,id:p,result:e.unknown().optional(),traceId:e.string().optional(),timestamp:e.number().optional()}),y=e.object({protocol:f,id:p,error:m,traceId:e.string().optional(),timestamp:e.number().optional()});e.union([g,_,v,y]),e.enum([`ipc`,`tcp`,`http`]),e.enum([`host`,`client`]),e.object({streamId:e.string(),streamName:e.string(),meta:e.unknown().optional()}),e.discriminatedUnion(`type`,[e.object({type:e.literal(`start`),streamId:e.string(),streamName:e.string(),meta:e.unknown().optional()}),e.object({type:e.literal(`chunk`),streamId:e.string(),chunk:e.unknown()}),e.object({type:e.literal(`end`),streamId:e.string()}),e.object({type:e.literal(`error`),streamId:e.string(),error:m})]);const ee=e=>(e=e.replace(/(?<=https?:\/\/)[^\s]+/g,`xxx`),e=e.replace(/ns-[\w-]+/g,`xxx`),e),b=(e,t=``)=>ee(x(e)||t),x=(e,t=0)=>t>5?void 0:typeof e==`string`?e:!e||typeof e!=`object`?void 0:S(e,t)||T(C(e?.response?.data,t),C(e?.response?.body,t),C(e?.body,t),w(e?.response?.data?.reason),w(e?.response?.reason),e?.response?.data?.message||e?.response?.message||e?.message||e?.response?.data?.msg||e?.response?.msg||e?.msg,w(e?.response?.data?.error),w(e?.response?.error),w(e?.error),x(e?.error,t+1),x(e?.cause,t+1),w(e)),S=(e,t)=>{if(!(!(`reason`in e)&&!(`error`in e)))return E(w(e.reason),x(e.error,t+1))},C=(e,t)=>{if(e){if(typeof e!=`string`)return x(e,t+1);try{let n=JSON.parse(e);return x(n?.error,t+1)||x(n,t+1)}catch{return e||void 0}}},w=e=>{if(!e||typeof e!=`object`)return;let t=e,n=t[`zh-CN`]??t.en??t[`zh-Hant`];return typeof n==`string`?n:void 0},T=(...e)=>e.find(e=>typeof e==`string`&&e.length>0),E=(...e)=>{let t=e.filter((t,n)=>!!t&&e.indexOf(t)===n);return t.length>0?t.join(`: `):void 0},te=`application/javascript,application/json,application/yaml,application/zip,image/jpeg,image/png,image/gif,image/webp,image/svg+xml,application/pdf,text/plain,text/csv,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/msword,application/vnd.ms-excel,application/vnd.ms-powerpoint,text/markdown,audio/mpeg,video/mp4,audio/wav,text/html,application/xml,application/gzip,application/octet-stream,multipart/form-data,text/event-stream`.split(`,`),D=e.enum(te).and(e.string().regex(/^[^/]+\/[^/]+$/)),ne=e.object({fileKey:e.string(),fileName:e.string(),contentType:D,size:e.number(),etag:e.string(),createTime:e.date()}),re=e.object({fileKey:e.string().optional(),path:e.string().optional(),fileName:e.string().optional(),contentType:D.optional(),overwrite:e.boolean().optional(),file:e.union([e.instanceof(r,{error:`Stream cannot be empty`}),e.union([e.instanceof(Buffer,{error:`Buffer is required`}),e.instanceof(Uint8Array,{error:`Uint8Array is required`})]).transform(e=>e instanceof Uint8Array&&!(e instanceof Buffer)?Buffer.from(e):e)])});e.object({...re.omit({fileKey:!0,overwrite:!0,path:!0}).shape});const ie=e.object({...ne.omit({fileKey:!0}).partial().shape,accessURL:e.string()});e.object({username:e.string(),contact:e.string().nullish(),memberName:e.string().nullish(),orgs:e.array(e.object({pathId:e.string(),name:e.string()})),groups:e.array(e.object({name:e.string()}))});const O=e.enum([`uploadFile`,`userInfo`,`wecomCorpToken`]).enum,k=e=>[e,null];function A(e,t){return j(e)?[null,e]:[null,{reason:e,error:t}]}function j(e){return!!(e&&typeof e==`object`&&`reason`in e&&`error`in e)}var M=class{constructor(e,t={}){this.channel=e,this.options=t}async getWecomCorpToken(){try{let[e,t]=(await this.channel.request(o.request,{method:O.wecomCorpToken,args:{}},{traceId:this.options.invocationId})).result;return t?A({en:`Failed to get wecom corp token`,"zh-CN":`获取企业微信企业令牌失败`},t):k(e)}catch(e){return A({en:`Failed to get wecom corp token`,"zh-CN":`获取企业微信企业令牌失败`},e)}}async userInfo(){try{let[e,t]=(await this.channel.request(o.request,{method:O.userInfo,args:{}},{traceId:this.options.invocationId})).result;return t?A({en:`Failed to get user info`,"zh-CN":`获取用户信息失败`},t):k(e)}catch(e){return A({en:`Failed to get user info`,"zh-CN":`获取用户信息失败`},e)}}async uploadFile(e){try{let[t,n]=(await this.channel.request(o.request,{method:O.uploadFile,args:{contentType:e.contentType,fileName:e.fileName}},{traceId:this.options.invocationId,input:this.toUploadInputStream(e.file)})).result;return n?A({en:`Failed to upload file`,"zh-CN":`上传文件失败`},n):k(ie.parse(t))}catch(e){return A({en:`Failed to upload file`,"zh-CN":`上传文件失败`},e)}}toUploadInputStream(e){return e instanceof n.Readable?e:n.Readable.from(Buffer.from(e))}};const N=e.enum([`en`,`zh-CN`,`zh-Hant`]).enum;e.object({[N.en]:e.string(),[N[`zh-CN`]]:e.string().optional(),[N[`zh-Hant`]]:e.string().optional()});const P=e.object({[N.en]:e.string(),[N[`zh-CN`]]:e.string(),[N[`zh-Hant`]]:e.string()});e.object({pluginId:e.string(),version:e.string(),etag:e.string()});const F=e.literal(`system`).or(e.string()),I=e.object({id:e.string(),name:P});e.array(I);const L=e.enum([`localPool`,`serverless`]).enum;e.object({pluginId:e.string(),version:e.string().optional(),source:F.optional()});const R=`__fastgptChannelReply__`;var z=class{transport=`ipc`;pending=new Map;errorHandlers=new Set;closeHandlers=new Set;incomingStreams=new Map;bufferedIncomingStreams=new Map;pendingStreamWaiters=new Map;requestHandler=null;notificationHandler=null;closed=!1;unsubscribeMessage;constructor(e,t,n={}){this.side=e,this.endpoint=t,this.options=n,this.unsubscribeMessage=V(t,e=>{this.dispatch(e).catch(e=>{this.emitError(e instanceof Error?e:Error(String(e)))})})}async request(e,t,n){this.ensureOpen();let r=n?.id??i(),a=n?.timeoutMs??this.options.defaultTimeoutMs??3e4,o=n?.input===void 0?void 0:this.pipeStream(X(r),n.input,{traceId:n.traceId,streamId:n.inputStream?.streamId,streamName:n.inputStream?.streamName,meta:n.inputStream?.meta}),s=Date.now();o&&o.catch(e=>{this.emitError(e instanceof Error?e:Error(String(e)))});let c=await new Promise((i,o)=>{let s=setTimeout(()=>{this.pending.delete(r),o(Object.assign(Error(`Request timeout: ${String(e)}`),{code:h.requestTimeout,requestId:r,method:e}))},a);this.pending.set(r,{method:String(e),resolve:i,reject:o,timer:s}),this.send({protocol:`1.0`,id:r,method:String(e),params:t,...n?.traceId===void 0?{}:{traceId:n.traceId},timestamp:Date.now()}).catch(e=>{clearTimeout(s),this.pending.delete(r),o(e)})}),l=c,u;if(q(c)&&(l=c.result,c.hasOutputStream)){let e=Date.now()-s,t=Math.max(1,a-e);u=await this.waitForStream(Z(r),{timeoutMs:t})}return{requestId:r,result:l,...u===void 0?{}:{output:u},...o===void 0?{}:{inputDone:o}}}async notify(e,t,n){this.ensureOpen(),await this.send({protocol:`1.0`,method:String(e),params:t,...n?.traceId===void 0?{}:{traceId:n.traceId},timestamp:Date.now()})}setRequestHandler(e){this.requestHandler=e}setNotificationHandler(e){this.notificationHandler=e}async waitForStream(e,t){this.ensureOpen();let n=this.bufferedIncomingStreams.get(e);if(n&&n.length>0){let t=n.shift();return n.length===0&&this.bufferedIncomingStreams.delete(e),t}return new Promise((n,r)=>{let i={resolve:n,reject:r};t?.timeoutMs!==void 0&&(i.timer=setTimeout(()=>{let t=this.pendingStreamWaiters.get(e);if(!t)return;let n=t.indexOf(i);n>=0&&t.splice(n,1),t.length===0&&this.pendingStreamWaiters.delete(e),r(Error(`Wait stream timeout: ${e}`))},t.timeoutMs)),this.pendingStreamWaiters.has(e)||this.pendingStreamWaiters.set(e,[]),this.pendingStreamWaiters.get(e).push(i)})}async createWritableStream(e,t){this.ensureOpen();let n=t?.streamId??i(),r=!1,a=t?.streamName??e;return await this.sendStreamFrame({type:`start`,streamId:n,streamName:a,...t?.meta===void 0?{}:{meta:t.meta}},t?.traceId),{streamId:n,streamName:a,...t?.meta===void 0?{}:{meta:t.meta},write:async e=>{if(r)throw Error(`Stream is already closed: ${n}`);await this.sendStreamFrame({type:`chunk`,streamId:n,chunk:e},t?.traceId)},end:async()=>{r||(r=!0,await this.sendStreamFrame({type:`end`,streamId:n},t?.traceId))},fail:async e=>{r||(r=!0,await this.sendStreamFrame({type:`error`,streamId:n,error:J(e)},t?.traceId))}}}async pipeStream(e,t,n){let r=await this.createWritableStream(e,n);try{for await(let e of ae(t))await r.write(e);await r.end()}catch(e){throw await r.fail(e instanceof Error?e:Error(String(e))),e}}onError(e){return this.errorHandlers.add(e),()=>{this.errorHandlers.delete(e)}}onClose(e){return this.closeHandlers.add(e),()=>{this.closeHandlers.delete(e)}}async close(e=Error(`Channel closed`)){this.closed||(this.closed=!0,this.unsubscribeMessage(),this.rejectAllPending(e),this.rejectAllPendingStreamWaiters(e),this.failAllIncomingStreams(e),this.closeHandlers.forEach(t=>t(e)))}createReply(e,t){return{[R]:!0,...e===void 0?{}:{result:e},...t?.output===void 0?{}:{output:t.output},...t?.outputStream===void 0?{}:{outputStream:t.outputStream}}}async dispatch(e){if(!this.closed){if(G(e)){this.handleResponse(e);return}if(W(e)){await this.handleRequest(e);return}await this.handleNotification(e)}}handleResponse(e){let t=this.pending.get(e.id);if(t){if(clearTimeout(t.timer),this.pending.delete(e.id),`error`in e){t.reject(Y(e.error));return}t.resolve(e.result)}}async handleRequest(e){if(!this.requestHandler){await this.replyError(e,{code:h.methodNotFound,message:`Method not found: ${e.method}`});return}try{let t=await this.requestHandler({id:e.id,method:e.method,params:e.params,...e.traceId===void 0?{}:{traceId:e.traceId},raw:e,waitForInputStream:t=>this.waitForStream(X(e.id),t)});if(K(t)){await this.handleReplyDescriptor(e,t);return}await this.reply(e,t)}catch(t){await this.replyError(e,t instanceof Error?t:Error(String(t)))}}async handleNotification(e){if(e.method===c.streamFrame){await this.handleStreamFrame(e.params,e.traceId);return}await this.notificationHandler?.({method:e.method,params:e.params,...e.traceId===void 0?{}:{traceId:e.traceId},raw:e})}async handleReplyDescriptor(e,t){t.output!==void 0&&this.pipeStream(Z(e.id),t.output,{traceId:t.outputStream?.traceId??e.traceId,streamId:t.outputStream?.streamId,streamName:t.outputStream?.streamName,meta:t.outputStream?.meta}).catch(e=>{this.emitError(e instanceof Error?e:Error(String(e)))}),await this.reply(e,{[R]:!0,hasOutputStream:t.output!==void 0,...t.result===void 0?{}:{result:t.result}})}async reply(e,t){await this.send({protocol:`1.0`,id:e.id,...t===void 0?{}:{result:t},...e.traceId===void 0?{}:{traceId:e.traceId},timestamp:Date.now()})}async replyError(e,t){await this.send({protocol:`1.0`,id:e.id,error:J(t),...e.traceId===void 0?{}:{traceId:e.traceId},timestamp:Date.now()})}async sendStreamFrame(e,t){await this.notify(c.streamFrame,e,{traceId:t})}async handleStreamFrame(e,t){switch(e.type){case`start`:{let n={streamId:e.streamId,streamName:e.streamName,stream:a.create(),...t===void 0?{}:{traceId:t},...e.meta===void 0?{}:{meta:e.meta}};this.incomingStreams.set(e.streamId,n),this.dispatchIncomingStream(n);return}case`chunk`:{let t=this.incomingStreams.get(e.streamId);if(!t){this.emitError(Error(`Stream not found: ${e.streamId}`));return}t.stream.write(e.chunk);return}case`end`:{let t=this.incomingStreams.get(e.streamId);if(!t)return;t.stream.end(),this.incomingStreams.delete(e.streamId);return}case`error`:{let t=this.incomingStreams.get(e.streamId);if(!t)return;t.stream.fail(Y(e.error)),this.incomingStreams.delete(e.streamId);return}}}dispatchIncomingStream(e){let t=!1,n=this.pendingStreamWaiters.get(e.streamName);if(n&&n.length>0){let r=n.shift();r.timer&&clearTimeout(r.timer),n.length===0&&this.pendingStreamWaiters.delete(e.streamName),r.resolve(e),t=!0}t||(this.bufferedIncomingStreams.has(e.streamName)||this.bufferedIncomingStreams.set(e.streamName,[]),this.bufferedIncomingStreams.get(e.streamName).push(e))}rejectAllPending(e){this.pending.forEach((t,n)=>{clearTimeout(t.timer),t.reject(e),this.pending.delete(n)})}rejectAllPendingStreamWaiters(e){this.pendingStreamWaiters.forEach((t,n)=>{t.forEach(t=>{t.timer&&clearTimeout(t.timer),t.reject(e)}),this.pendingStreamWaiters.delete(n)})}failAllIncomingStreams(e){this.incomingStreams.forEach((t,n)=>{t.stream.fail(e),this.incomingStreams.delete(n)}),this.bufferedIncomingStreams.clear()}emitError(e){this.errorHandlers.forEach(t=>t(e))}async send(e){await H(this.endpoint,e)}ensureOpen(){if(this.closed)throw Error(`Channel closed`)}};function B(e){return new z(`client`,process,e)}function V(e,t){let n=e,r=e=>{U(e)&&t(e)};return n.on(`message`,r),()=>n.off(`message`,r)}function H(e,t){let n=e;if(typeof n.send!=`function`)throw Error(`IPC channel not available`);return new Promise((e,r)=>{n.send(t,t=>{if(t){r(t);return}e()})})}function U(e){return!!(e&&typeof e==`object`&&`protocol`in e)}function W(e){return`id`in e&&`method`in e}function G(e){return`id`in e&&!(`method`in e)&&(`result`in e||`error`in e)}function K(e){return!!(e&&typeof e==`object`&&R in e&&e[R]===!0)}function q(e){return!!(e&&typeof e==`object`&&R in e&&`hasOutputStream`in e)}function J(e){return typeof e==`string`?{code:h.internalError,message:e}:e instanceof Error?{code:e.code??h.internalError,message:e.message,...e.stack===void 0?{}:{data:{stack:e.stack}}}:e}function Y(e){return Object.assign(Error(e.message),{code:e.code,data:e.data})}function ae(e){return e instanceof a?e.values():e}function X(e){return`request.input:${String(e)}`}function Z(e){return`request.output:${String(e)}`}var oe=class{channel;getChannel(){if(!this.channel)throw Error(`Channel is not initialized yet.`);return this.channel}mode;checkRuntimeMode(){process.env.RUNTIME_MODE==L.localPool&&(this.mode=L.localPool),process.env.RUNTIME_MODE===`dev`&&(this.mode=`dev`)}async init(){this.checkRuntimeMode(),this.mode===`localPool`&&(this.channel=B(),setImmediate(()=>{this.getChannel().notify(o.ready,{pid:process.pid,runtimeMode:L.localPool,startedAt:Date.now()})})),this.mode===`dev`&&(this.channel=se().pluginChannel,setImmediate(()=>{this.getChannel().notify(o.ready,{pid:process.pid,runtimeMode:`dev`,startedAt:Date.now()})}))}constructor(){this.init()}};function se(){let e=globalThis.__FASTGPT_PLUGIN_LOCAL_DEBUG_RUNTIME__;if(!e)throw Error(`Local debug runtime is not initialized. Set it before importing the plugin.`);return e}function ce(e){return e}var Q=class t extends oe{toolHandlers=new Map;childManifests=new Map;secretSchema=e.record(e.string(),e.unknown());constructor(e){super(),this.userToolManifest=e,this.mode&&this.getChannel().setRequestHandler(async e=>{if(e.method===u.request&&e.params.eventName===`run`)try{let{input:t,systemVar:n,childId:r,secrets:i}=e.params.payload,o=this.toolHandlers.get(r??`tool`);if(!o)throw Error(`No tool registered`);let s=a.create();return(async()=>{try{let r=await o.handler(t,{systemVar:n,secrets:i,invoke:new M(this.getChannel(),{invocationId:e.traceId}),streamResponse:e=>{s.send({type:`stream`,data:e})}});s.send({type:`response`,data:r})}catch(e){s.send({data:b(e,`Unknown error during tool execution`),type:`error`})}finally{s.end()}})(),this.getChannel().createReply(void 0,{output:s})}catch(e){let t=a.create();return t.write({data:b(e,`Unknown error during tool execution`),type:`error`}),t.end(),this.getChannel().createReply(void 0,{output:t})}})}setSecretSchema(e){this.secretSchema=e}registerTool(e,t=`tool`,n){this.toolHandlers.set(t,e),n&&this.childManifests.set(t,n)}static getInstance(e){return new t(e)}getSecretSchema(){return this.secretSchema}getToolHandler(e=`tool`){return this.toolHandlers.get(e)}getUserToolManifest(){return this.userToolManifest}getChildManifests(){return[...this.childManifests.values()]}};const le=({manifest:t,handler:n})=>{let r=Q.getInstance(t);return r.setSecretSchema(n.secretSchema??e.object()),r.registerTool(n),r},$=({manifest:t,children:n,secretSchema:r})=>{let i=Q.getInstance(t);return n.forEach(e=>{i.registerTool(e.handler,e.id,{id:e.id,description:e.description,name:e.name,...e.icon===void 0?{}:{icon:e.icon},...e.toolDescription===void 0?{}:{toolDescription:e.toolDescription}})}),i.setSecretSchema(r??e.object()),i};export{ce as createToolHandler,le as defineTool,$ as defineToolSet};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastgpt-plugin/sdk-factory",
3
- "version": "0.0.1-alpha.7",
3
+ "version": "0.0.1-alpha.8",
4
4
  "devDependencies": {
5
5
  "tsdown": "^0.21.10"
6
6
  },