@fastgpt-plugin/cli 0.1.0-beta.7 → 0.1.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +380 -76
- package/package.json +1 -1
- package/templates/tool/index.tool.ts +11 -3
- package/templates/tool/index.toolset.ts +39 -11
package/dist/index.js
CHANGED
|
@@ -166,6 +166,7 @@ const ToolManifestSchema = z.object({
|
|
|
166
166
|
|
|
167
167
|
//#endregion
|
|
168
168
|
//#region src/build/index.ts
|
|
169
|
+
const SDK_FACTORY_PACKAGE = "@fastgpt-plugin/sdk-factory";
|
|
169
170
|
/**
|
|
170
171
|
* 核心构建逻辑:给定入口目录和输出目录,完成一次工具构建。
|
|
171
172
|
*
|
|
@@ -196,11 +197,11 @@ async function buildToolPackage(options) {
|
|
|
196
197
|
const tempIndexPath = path.join(tempDir, "index.ts");
|
|
197
198
|
const tBuildStart = Date.now();
|
|
198
199
|
await build({
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
200
|
+
config: false,
|
|
201
|
+
deps: {
|
|
202
|
+
alwaysBundle: (id) => !isSdkFactoryImport(id),
|
|
203
|
+
neverBundle: [SDK_FACTORY_PACKAGE, `${SDK_FACTORY_PACKAGE}/*`]
|
|
204
|
+
},
|
|
204
205
|
entry: { index: tempIndexPath },
|
|
205
206
|
outDir: outputDir,
|
|
206
207
|
format: [options.format],
|
|
@@ -378,6 +379,9 @@ function pickToolDescription$1(explicitDescription, fallbackSource) {
|
|
|
378
379
|
function getOptionalString$1(value) {
|
|
379
380
|
return typeof value === "string" ? value : void 0;
|
|
380
381
|
}
|
|
382
|
+
function isSdkFactoryImport(id) {
|
|
383
|
+
return id === SDK_FACTORY_PACKAGE || id.startsWith(`${SDK_FACTORY_PACKAGE}/`);
|
|
384
|
+
}
|
|
381
385
|
function escapeRegExp(value) {
|
|
382
386
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
383
387
|
}
|
|
@@ -539,7 +543,7 @@ var CheckCommand = class extends BaseCommand {
|
|
|
539
543
|
//#endregion
|
|
540
544
|
//#region package.json
|
|
541
545
|
var name = "@fastgpt-plugin/cli";
|
|
542
|
-
var version = "0.1.0-beta.
|
|
546
|
+
var version = "0.1.0-beta.9";
|
|
543
547
|
|
|
544
548
|
//#endregion
|
|
545
549
|
//#region src/constants.ts
|
|
@@ -888,7 +892,10 @@ const InvokeUploadFileInputSchema = z.object({ ...FileCreateSchema.omit({
|
|
|
888
892
|
overwrite: true,
|
|
889
893
|
path: true
|
|
890
894
|
}).shape });
|
|
891
|
-
const InvokeUploadFileOutputSchema = z.object({
|
|
895
|
+
const InvokeUploadFileOutputSchema = z.object({
|
|
896
|
+
...FileMetaSchema.omit({ fileKey: true }).partial().shape,
|
|
897
|
+
accessURL: z.string()
|
|
898
|
+
});
|
|
892
899
|
const InvokeUserInfoOutputSchema = z.object({
|
|
893
900
|
username: z.string(),
|
|
894
901
|
contact: z.string().nullish(),
|
|
@@ -899,9 +906,17 @@ const InvokeUserInfoOutputSchema = z.object({
|
|
|
899
906
|
})),
|
|
900
907
|
groups: z.array(z.object({ name: z.string() }))
|
|
901
908
|
});
|
|
902
|
-
const InvokeMethodEnumSchema = z.enum([
|
|
909
|
+
const InvokeMethodEnumSchema = z.enum([
|
|
910
|
+
"uploadFile",
|
|
911
|
+
"userInfo",
|
|
912
|
+
"wecomCorpToken"
|
|
913
|
+
]);
|
|
903
914
|
const InvokeMethodEnum = InvokeMethodEnumSchema.enum;
|
|
904
915
|
|
|
916
|
+
//#endregion
|
|
917
|
+
//#region ../../packages/domain/src/value-objects/result.vo.ts
|
|
918
|
+
const successResult = (data) => [data, null];
|
|
919
|
+
|
|
905
920
|
//#endregion
|
|
906
921
|
//#region ../../packages/domain/src/value-objects/stream.vo.ts
|
|
907
922
|
var StreamData = class StreamData {
|
|
@@ -1020,58 +1035,328 @@ const ToolRunInputSchema = z.object({
|
|
|
1020
1035
|
});
|
|
1021
1036
|
|
|
1022
1037
|
//#endregion
|
|
1023
|
-
//#region ../../packages/infrastructure/src/plugin/plugin-runtime/
|
|
1024
|
-
|
|
1038
|
+
//#region ../../packages/infrastructure/src/plugin/plugin-runtime/ports/channel/event/client.ts
|
|
1039
|
+
/**
|
|
1040
|
+
* client -> host 的事件集合。
|
|
1041
|
+
*
|
|
1042
|
+
* client 是插件运行侧,host 是插件宿主侧。这里的 method 只能由 client 发送,
|
|
1043
|
+
* host 只能在 handler 中接收。
|
|
1044
|
+
*/
|
|
1045
|
+
const PluginChannelClientMethod = {
|
|
1046
|
+
/**
|
|
1047
|
+
* 插件 runtime 初始化完成,host 收到后可以把 pod 标记为 ready。
|
|
1048
|
+
*/
|
|
1049
|
+
ready: "client.ready",
|
|
1050
|
+
/**
|
|
1051
|
+
* 插件 runtime 的 stdout/stderr 输出。
|
|
1052
|
+
*/
|
|
1053
|
+
stdio: "client.stdio",
|
|
1054
|
+
/**
|
|
1055
|
+
* 插件 runtime 主动报告启动失败、运行失败或崩溃信息。
|
|
1056
|
+
*/
|
|
1057
|
+
fail: "client.fail",
|
|
1058
|
+
/**
|
|
1059
|
+
* 插件反向调用 host 能力,例如 uploadFile、userInfo。
|
|
1060
|
+
*/
|
|
1061
|
+
request: "client.request"
|
|
1062
|
+
};
|
|
1063
|
+
const PluginChannelClientMethodSchema = z.enum([
|
|
1064
|
+
PluginChannelClientMethod.ready,
|
|
1065
|
+
PluginChannelClientMethod.stdio,
|
|
1066
|
+
PluginChannelClientMethod.fail,
|
|
1067
|
+
PluginChannelClientMethod.request
|
|
1068
|
+
]);
|
|
1069
|
+
const PluginChannelReadyParamsSchema = z.object({
|
|
1070
|
+
pid: z.number().optional(),
|
|
1071
|
+
version: z.string().optional(),
|
|
1072
|
+
runtimeMode: z.string().optional(),
|
|
1073
|
+
capabilities: z.array(z.string()).optional(),
|
|
1074
|
+
startedAt: z.number().optional(),
|
|
1075
|
+
meta: z.unknown().optional()
|
|
1076
|
+
});
|
|
1077
|
+
const PluginChannelStdioParamsSchema = z.object({
|
|
1078
|
+
stream: z.enum(["stdout", "stderr"]),
|
|
1079
|
+
chunk: z.string(),
|
|
1080
|
+
timestamp: z.number().optional()
|
|
1081
|
+
});
|
|
1082
|
+
const PluginChannelFailParamsSchema = z.object({
|
|
1083
|
+
reason: z.enum([
|
|
1084
|
+
"startup",
|
|
1085
|
+
"runtime",
|
|
1086
|
+
"crash",
|
|
1087
|
+
"shutdown",
|
|
1088
|
+
"unknown"
|
|
1089
|
+
]),
|
|
1090
|
+
error: z.object({
|
|
1091
|
+
code: z.string(),
|
|
1092
|
+
message: z.string(),
|
|
1093
|
+
data: z.unknown().optional()
|
|
1094
|
+
}).optional(),
|
|
1095
|
+
exitCode: z.number().nullable().optional(),
|
|
1096
|
+
signal: z.string().nullable().optional(),
|
|
1097
|
+
timestamp: z.number().optional()
|
|
1098
|
+
});
|
|
1099
|
+
|
|
1100
|
+
//#endregion
|
|
1101
|
+
//#region ../../packages/infrastructure/src/plugin/plugin-runtime/ports/channel/event/common.ts
|
|
1102
|
+
const PluginChannelCommonMethod = {
|
|
1103
|
+
/**
|
|
1104
|
+
* 双向通用的流 frame 通道。
|
|
1105
|
+
*
|
|
1106
|
+
* 业务侧不直接调用这个 method;使用 `request({ input })`、`createReply({ output })`
|
|
1107
|
+
* 或 `pipeStream()` 时由底层 channel 自动发送。
|
|
1108
|
+
*/
|
|
1109
|
+
streamFrame: "channel.stream" };
|
|
1110
|
+
const PluginChannelCommonMethodSchema = z.enum([PluginChannelCommonMethod.streamFrame]);
|
|
1111
|
+
|
|
1112
|
+
//#endregion
|
|
1113
|
+
//#region ../../packages/infrastructure/src/plugin/plugin-runtime/ports/channel/event/host.ts
|
|
1114
|
+
/**
|
|
1115
|
+
* host -> client 的事件集合。
|
|
1116
|
+
*
|
|
1117
|
+
* host 是插件宿主侧,client 是插件运行侧。这里的 method 只能由 host 发送,
|
|
1118
|
+
* client 只能在 handler 中接收。
|
|
1119
|
+
*/
|
|
1120
|
+
const PluginChannelHostMethod = {
|
|
1121
|
+
/**
|
|
1122
|
+
* 调用插件业务事件,例如 run。
|
|
1123
|
+
*/
|
|
1124
|
+
request: "host.request",
|
|
1125
|
+
/**
|
|
1126
|
+
* 健康检查。
|
|
1127
|
+
*/
|
|
1128
|
+
ping: "host.ping",
|
|
1129
|
+
/**
|
|
1130
|
+
* 通知插件 runtime 准备退出。
|
|
1131
|
+
*/
|
|
1132
|
+
shutdown: "host.shutdown"
|
|
1133
|
+
};
|
|
1134
|
+
const PluginChannelHostMethodSchema = z.enum([
|
|
1135
|
+
PluginChannelHostMethod.request,
|
|
1136
|
+
PluginChannelHostMethod.ping,
|
|
1137
|
+
PluginChannelHostMethod.shutdown
|
|
1138
|
+
]);
|
|
1139
|
+
const PluginChannelPingParamsSchema = z.object({ timestamp: z.number() });
|
|
1140
|
+
const PluginChannelPingResultSchema = z.object({
|
|
1141
|
+
timestamp: z.number(),
|
|
1142
|
+
receivedAt: z.number().optional()
|
|
1143
|
+
});
|
|
1144
|
+
const PluginChannelShutdownParamsSchema = z.object({
|
|
1145
|
+
reason: z.string().optional(),
|
|
1146
|
+
timeoutMs: z.number().nonnegative().optional()
|
|
1147
|
+
});
|
|
1148
|
+
const PluginChannelShutdownResultSchema = z.object({
|
|
1149
|
+
accepted: z.boolean(),
|
|
1150
|
+
message: z.string().optional()
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
//#endregion
|
|
1154
|
+
//#region ../../packages/infrastructure/src/plugin/plugin-runtime/ports/channel/event/index.ts
|
|
1155
|
+
const PluginChannelKnownMethodSchema = z.union([
|
|
1156
|
+
PluginChannelClientMethodSchema,
|
|
1157
|
+
PluginChannelCommonMethodSchema,
|
|
1158
|
+
PluginChannelHostMethodSchema
|
|
1159
|
+
]);
|
|
1160
|
+
|
|
1161
|
+
//#endregion
|
|
1162
|
+
//#region ../../packages/infrastructure/src/plugin/plugin-runtime/ports/channel/message.ts
|
|
1163
|
+
/**
|
|
1164
|
+
* Channel 协议只描述可跨传输层传递的 JSON 数据。
|
|
1165
|
+
*
|
|
1166
|
+
* 它刻意不绑定 Node IPC、TCP、HTTP 等具体实现;不同 driver 只需要负责把这些
|
|
1167
|
+
* message 发给对端,并把收到的 message 重新交给 channel port 分发。
|
|
1168
|
+
*/
|
|
1169
|
+
const PluginChannelProtocolVersionSchema = z.literal("1.0");
|
|
1170
|
+
const PluginChannelMessageIdSchema = z.union([z.string(), z.number()]);
|
|
1171
|
+
const PluginChannelErrorSchema = z.object({
|
|
1172
|
+
code: z.string(),
|
|
1173
|
+
message: z.string(),
|
|
1174
|
+
data: z.unknown().optional()
|
|
1175
|
+
});
|
|
1176
|
+
/**
|
|
1177
|
+
* request message:需要对端返回 success/error。
|
|
1178
|
+
*
|
|
1179
|
+
* `method` 的合法集合由 `event/` 里的方向化类型控制;这里保持 string 是为了让
|
|
1180
|
+
* 底层协议可以承载未来扩展的 method。
|
|
1181
|
+
*/
|
|
1182
|
+
const PluginChannelRequestMessageSchema = z.object({
|
|
1183
|
+
protocol: PluginChannelProtocolVersionSchema,
|
|
1184
|
+
id: PluginChannelMessageIdSchema,
|
|
1185
|
+
method: z.string(),
|
|
1186
|
+
params: z.unknown().optional(),
|
|
1187
|
+
traceId: z.string().optional(),
|
|
1188
|
+
timestamp: z.number().optional()
|
|
1189
|
+
});
|
|
1190
|
+
/**
|
|
1191
|
+
* notification message:单向事件,不产生响应。
|
|
1192
|
+
*
|
|
1193
|
+
* ready、stdio、fail 和 stream frame 都属于 notification。
|
|
1194
|
+
*/
|
|
1195
|
+
const PluginChannelNotificationMessageSchema = PluginChannelRequestMessageSchema.omit({ id: true });
|
|
1196
|
+
/**
|
|
1197
|
+
* success message:request 的成功响应。
|
|
1198
|
+
*
|
|
1199
|
+
* 流式输出不会直接塞进 `result`,而是先返回一个 stream descriptor/envelope,
|
|
1200
|
+
* 再通过 `channel.stream` notification 发送 chunk。
|
|
1201
|
+
*/
|
|
1202
|
+
const PluginChannelSuccessMessageSchema = z.object({
|
|
1203
|
+
protocol: PluginChannelProtocolVersionSchema,
|
|
1204
|
+
id: PluginChannelMessageIdSchema,
|
|
1205
|
+
result: z.unknown().optional(),
|
|
1206
|
+
traceId: z.string().optional(),
|
|
1207
|
+
timestamp: z.number().optional()
|
|
1208
|
+
});
|
|
1209
|
+
/**
|
|
1210
|
+
* error message:request 的失败响应。
|
|
1211
|
+
*/
|
|
1212
|
+
const PluginChannelErrorMessageSchema = z.object({
|
|
1213
|
+
protocol: PluginChannelProtocolVersionSchema,
|
|
1214
|
+
id: PluginChannelMessageIdSchema,
|
|
1215
|
+
error: PluginChannelErrorSchema,
|
|
1216
|
+
traceId: z.string().optional(),
|
|
1217
|
+
timestamp: z.number().optional()
|
|
1218
|
+
});
|
|
1219
|
+
const PluginChannelMessageSchema = z.union([
|
|
1220
|
+
PluginChannelRequestMessageSchema,
|
|
1221
|
+
PluginChannelNotificationMessageSchema,
|
|
1222
|
+
PluginChannelSuccessMessageSchema,
|
|
1223
|
+
PluginChannelErrorMessageSchema
|
|
1224
|
+
]);
|
|
1225
|
+
const PluginChannelTransportSchema = z.enum([
|
|
1226
|
+
"ipc",
|
|
1227
|
+
"tcp",
|
|
1228
|
+
"http"
|
|
1229
|
+
]);
|
|
1230
|
+
/**
|
|
1231
|
+
* host:插件宿主侧,例如 local-pool 的主进程。
|
|
1232
|
+
* client:插件运行侧,例如 fork 出来的插件子进程或 debug runtime。
|
|
1233
|
+
*/
|
|
1234
|
+
const PluginChannelSideSchema = z.enum(["host", "client"]);
|
|
1235
|
+
const PluginChannelStreamDescriptorSchema = z.object({
|
|
1236
|
+
streamId: z.string(),
|
|
1237
|
+
streamName: z.string(),
|
|
1238
|
+
meta: z.unknown().optional()
|
|
1239
|
+
});
|
|
1240
|
+
/**
|
|
1241
|
+
* 流数据统一通过 notification 发送 frame。
|
|
1242
|
+
*
|
|
1243
|
+
* 一个 stream 生命周期为 start -> chunk* -> end/error。chunk 的 payload 保持
|
|
1244
|
+
* unknown,由具体事件类型决定真实数据结构。
|
|
1245
|
+
*/
|
|
1246
|
+
const PluginChannelStreamFrameSchema = z.discriminatedUnion("type", [
|
|
1247
|
+
z.object({
|
|
1248
|
+
type: z.literal("start"),
|
|
1249
|
+
streamId: z.string(),
|
|
1250
|
+
streamName: z.string(),
|
|
1251
|
+
meta: z.unknown().optional()
|
|
1252
|
+
}),
|
|
1253
|
+
z.object({
|
|
1254
|
+
type: z.literal("chunk"),
|
|
1255
|
+
streamId: z.string(),
|
|
1256
|
+
chunk: z.unknown()
|
|
1257
|
+
}),
|
|
1258
|
+
z.object({
|
|
1259
|
+
type: z.literal("end"),
|
|
1260
|
+
streamId: z.string()
|
|
1261
|
+
}),
|
|
1262
|
+
z.object({
|
|
1263
|
+
type: z.literal("error"),
|
|
1264
|
+
streamId: z.string(),
|
|
1265
|
+
error: PluginChannelErrorSchema
|
|
1266
|
+
})
|
|
1267
|
+
]);
|
|
1025
1268
|
|
|
1026
1269
|
//#endregion
|
|
1027
1270
|
//#region src/debug/runtime.ts
|
|
1028
1271
|
const LOCAL_DEBUG_RUNTIME_GLOBAL_KEY = "__FASTGPT_PLUGIN_LOCAL_DEBUG_RUNTIME__";
|
|
1029
|
-
const
|
|
1272
|
+
const LOCAL_DEBUG_REPLY_MARK = "__localDebugReply__";
|
|
1030
1273
|
var LocalDebugChannel = class {
|
|
1031
|
-
|
|
1274
|
+
transport = "local-debug";
|
|
1275
|
+
requestHandler = null;
|
|
1276
|
+
notificationHandler = null;
|
|
1277
|
+
errorHandlers = /* @__PURE__ */ new Set();
|
|
1278
|
+
closeHandlers = /* @__PURE__ */ new Set();
|
|
1279
|
+
constructor(side, runtime) {
|
|
1280
|
+
this.side = side;
|
|
1032
1281
|
this.runtime = runtime;
|
|
1033
1282
|
}
|
|
1283
|
+
async request(method, params, options) {
|
|
1284
|
+
return this.runtime.dispatchFromSide(this.side, method, params, options);
|
|
1285
|
+
}
|
|
1286
|
+
async notify(method, params, options) {
|
|
1287
|
+
await this.runtime.notifyFromSide(this.side, method, params, options);
|
|
1288
|
+
}
|
|
1034
1289
|
setRequestHandler(handler) {
|
|
1035
|
-
this.
|
|
1290
|
+
this.requestHandler = handler;
|
|
1036
1291
|
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1292
|
+
setNotificationHandler(handler) {
|
|
1293
|
+
this.notificationHandler = handler;
|
|
1294
|
+
}
|
|
1295
|
+
async waitForStream() {
|
|
1296
|
+
throw new Error("Local debug channel does not support detached stream waiters.");
|
|
1297
|
+
}
|
|
1298
|
+
async createWritableStream(streamName, options) {
|
|
1299
|
+
const stream = StreamData.create();
|
|
1300
|
+
return {
|
|
1301
|
+
streamId: options?.streamId ?? randomUUID(),
|
|
1302
|
+
streamName: options?.streamName ?? streamName,
|
|
1303
|
+
...options?.meta !== void 0 ? { meta: options.meta } : {},
|
|
1304
|
+
write: async (chunk) => stream.write(chunk),
|
|
1305
|
+
end: async () => stream.end(),
|
|
1306
|
+
fail: async (error) => stream.fail(error instanceof Error ? error : new Error(String(error)))
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
async pipeStream() {
|
|
1310
|
+
throw new Error("Local debug channel does not support detached stream piping.");
|
|
1042
1311
|
}
|
|
1043
|
-
|
|
1312
|
+
createReply(result, options) {
|
|
1044
1313
|
return {
|
|
1045
|
-
[
|
|
1314
|
+
[LOCAL_DEBUG_REPLY_MARK]: true,
|
|
1046
1315
|
...result !== void 0 ? { result } : {},
|
|
1047
1316
|
...options?.output !== void 0 ? { output: options.output } : {},
|
|
1048
|
-
...options ? { options: {
|
|
1049
|
-
traceId: options.traceId,
|
|
1050
|
-
outputMeta: options.outputMeta,
|
|
1051
|
-
outputStreamId: options.outputStreamId
|
|
1052
|
-
} } : {}
|
|
1317
|
+
...options?.outputStream !== void 0 ? { outputStream: options.outputStream } : {}
|
|
1053
1318
|
};
|
|
1054
1319
|
}
|
|
1055
|
-
|
|
1056
|
-
this.
|
|
1320
|
+
onError(handler) {
|
|
1321
|
+
this.errorHandlers.add(handler);
|
|
1322
|
+
return () => {
|
|
1323
|
+
this.errorHandlers.delete(handler);
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
onClose(handler) {
|
|
1327
|
+
this.closeHandlers.add(handler);
|
|
1328
|
+
return () => {
|
|
1329
|
+
this.closeHandlers.delete(handler);
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
async close(reason) {
|
|
1333
|
+
this.closeHandlers.forEach((handler) => handler(reason));
|
|
1334
|
+
}
|
|
1335
|
+
async handleRequest(request) {
|
|
1336
|
+
if (!this.requestHandler) throw new Error(`Local debug request handler is not configured: ${String(request.method)}`);
|
|
1337
|
+
return this.requestHandler(request);
|
|
1338
|
+
}
|
|
1339
|
+
async handleNotification(notification) {
|
|
1340
|
+
await this.notificationHandler?.(notification);
|
|
1057
1341
|
}
|
|
1058
1342
|
};
|
|
1059
1343
|
var LocalDebugRuntime = class {
|
|
1060
|
-
pluginRequestHandler = null;
|
|
1061
1344
|
hostRequestHandler = null;
|
|
1062
1345
|
ready = false;
|
|
1063
1346
|
readyPromise;
|
|
1064
1347
|
resolveReady;
|
|
1348
|
+
hostChannel;
|
|
1065
1349
|
pluginChannel;
|
|
1066
1350
|
constructor() {
|
|
1067
|
-
this.
|
|
1351
|
+
this.hostChannel = new LocalDebugChannel("host", this);
|
|
1352
|
+
this.pluginChannel = new LocalDebugChannel("client", this);
|
|
1353
|
+
this.hostChannel.setNotificationHandler(async (notification) => {
|
|
1354
|
+
if (notification.method === PluginChannelClientMethod.ready) this.markReady();
|
|
1355
|
+
});
|
|
1068
1356
|
this.readyPromise = new Promise((resolve) => {
|
|
1069
1357
|
this.resolveReady = resolve;
|
|
1070
1358
|
});
|
|
1071
1359
|
}
|
|
1072
|
-
setPluginRequestHandler(handler) {
|
|
1073
|
-
this.pluginRequestHandler = handler;
|
|
1074
|
-
}
|
|
1075
1360
|
setHostRequestHandler(handler) {
|
|
1076
1361
|
this.hostRequestHandler = handler;
|
|
1077
1362
|
}
|
|
@@ -1084,27 +1369,59 @@ var LocalDebugRuntime = class {
|
|
|
1084
1369
|
await this.readyPromise;
|
|
1085
1370
|
}
|
|
1086
1371
|
async invokePlugin(method, params, options) {
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
});
|
|
1092
|
-
}
|
|
1093
|
-
async
|
|
1094
|
-
|
|
1095
|
-
const
|
|
1096
|
-
return
|
|
1097
|
-
|
|
1372
|
+
return this.hostChannel.request(PluginChannelHostMethod.request, {
|
|
1373
|
+
eventName: method,
|
|
1374
|
+
payload: params,
|
|
1375
|
+
returnStream: true
|
|
1376
|
+
}, options);
|
|
1377
|
+
}
|
|
1378
|
+
async dispatchFromSide(side, method, params, options) {
|
|
1379
|
+
const requestId = options?.id ?? randomUUID();
|
|
1380
|
+
const target = side === "host" ? this.pluginChannel : this.hostChannel;
|
|
1381
|
+
return toRequestResult(requestId, side === "client" && method === PluginChannelClientMethod.request ? await this.invokeHostRequest(params, options) : await target.handleRequest({
|
|
1382
|
+
id: requestId,
|
|
1098
1383
|
method,
|
|
1099
|
-
|
|
1100
|
-
traceId: options.traceId,
|
|
1101
|
-
|
|
1102
|
-
|
|
1384
|
+
params,
|
|
1385
|
+
...options?.traceId !== void 0 ? { traceId: options.traceId } : {},
|
|
1386
|
+
raw: {
|
|
1387
|
+
protocol: "1.0",
|
|
1388
|
+
id: requestId,
|
|
1389
|
+
method: String(method),
|
|
1390
|
+
params,
|
|
1391
|
+
...options?.traceId !== void 0 ? { traceId: options.traceId } : {},
|
|
1392
|
+
timestamp: Date.now()
|
|
1393
|
+
},
|
|
1394
|
+
waitForInputStream: async () => createIncomingStream({
|
|
1395
|
+
source: options?.input ?? StreamData.create(),
|
|
1396
|
+
streamName: String(method),
|
|
1397
|
+
streamId: randomUUID(),
|
|
1398
|
+
traceId: options?.traceId
|
|
1399
|
+
})
|
|
1103
1400
|
}), options);
|
|
1104
1401
|
}
|
|
1105
|
-
async
|
|
1106
|
-
|
|
1107
|
-
|
|
1402
|
+
async notifyFromSide(side, method, params, options) {
|
|
1403
|
+
await (side === "host" ? this.pluginChannel : this.hostChannel).handleNotification({
|
|
1404
|
+
method,
|
|
1405
|
+
params,
|
|
1406
|
+
...options?.traceId !== void 0 ? { traceId: options.traceId } : {},
|
|
1407
|
+
raw: {
|
|
1408
|
+
protocol: "1.0",
|
|
1409
|
+
method: String(method),
|
|
1410
|
+
params,
|
|
1411
|
+
...options?.traceId !== void 0 ? { traceId: options.traceId } : {},
|
|
1412
|
+
timestamp: Date.now()
|
|
1413
|
+
}
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
async invokeHostRequest(params, options) {
|
|
1417
|
+
if (!this.hostRequestHandler) throw new Error(`Local debug host handler is not configured: ${params.method}`);
|
|
1418
|
+
return this.hostRequestHandler({
|
|
1419
|
+
method: params.method,
|
|
1420
|
+
args: params.args,
|
|
1421
|
+
traceId: options?.traceId,
|
|
1422
|
+
input: options?.input,
|
|
1423
|
+
createReply: (result, replyOptions) => this.pluginChannel.createReply(result, replyOptions)
|
|
1424
|
+
});
|
|
1108
1425
|
}
|
|
1109
1426
|
};
|
|
1110
1427
|
const createLocalDebugRuntime = () => new LocalDebugRuntime();
|
|
@@ -1116,35 +1433,25 @@ const setCurrentLocalDebugRuntime = (runtime) => {
|
|
|
1116
1433
|
}
|
|
1117
1434
|
store[LOCAL_DEBUG_RUNTIME_GLOBAL_KEY] = runtime;
|
|
1118
1435
|
};
|
|
1119
|
-
function createMessage(method, params, options) {
|
|
1120
|
-
return {
|
|
1121
|
-
id: options?.requestId ?? randomUUID(),
|
|
1122
|
-
messageType: "request",
|
|
1123
|
-
method,
|
|
1124
|
-
params,
|
|
1125
|
-
traceId: options?.traceId,
|
|
1126
|
-
timestamp: Date.now()
|
|
1127
|
-
};
|
|
1128
|
-
}
|
|
1129
1436
|
function isLocalDebugReplyDescriptor(value) {
|
|
1130
|
-
return Boolean(value && typeof value === "object" &&
|
|
1437
|
+
return Boolean(value && typeof value === "object" && LOCAL_DEBUG_REPLY_MARK in value && value[LOCAL_DEBUG_REPLY_MARK] === true);
|
|
1131
1438
|
}
|
|
1132
|
-
function
|
|
1439
|
+
function toRequestResult(requestId, response, options) {
|
|
1133
1440
|
const inputDone = options?.input !== void 0 ? Promise.resolve() : void 0;
|
|
1134
1441
|
if (!isLocalDebugReplyDescriptor(response)) return {
|
|
1135
|
-
requestId
|
|
1442
|
+
requestId,
|
|
1136
1443
|
result: response,
|
|
1137
1444
|
...inputDone ? { inputDone } : {}
|
|
1138
1445
|
};
|
|
1139
1446
|
const output = response.output !== void 0 ? createIncomingStream({
|
|
1140
1447
|
source: response.output,
|
|
1141
|
-
streamName: response.
|
|
1142
|
-
streamId: response.
|
|
1143
|
-
traceId: response.
|
|
1144
|
-
meta: response.
|
|
1448
|
+
streamName: response.outputStream?.streamName ?? "stream",
|
|
1449
|
+
streamId: response.outputStream?.streamId ?? randomUUID(),
|
|
1450
|
+
traceId: response.outputStream?.traceId,
|
|
1451
|
+
meta: response.outputStream?.meta
|
|
1145
1452
|
}) : void 0;
|
|
1146
1453
|
return {
|
|
1147
|
-
requestId
|
|
1454
|
+
requestId,
|
|
1148
1455
|
result: response.result,
|
|
1149
1456
|
...output ? { output } : {},
|
|
1150
1457
|
...inputDone ? { inputDone } : {}
|
|
@@ -1310,11 +1617,8 @@ function pickTargetTool(snapshot, toolId) {
|
|
|
1310
1617
|
}
|
|
1311
1618
|
function createVirtualHostHandler(uploadDir) {
|
|
1312
1619
|
return async ({ method, args, input }) => {
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
const invokeMethod = payload.method;
|
|
1316
|
-
const invokeArgs = ensurePlainObject(payload.args);
|
|
1317
|
-
switch (invokeMethod) {
|
|
1620
|
+
const invokeArgs = ensurePlainObject(args);
|
|
1621
|
+
switch (method) {
|
|
1318
1622
|
case InvokeMethodEnum.uploadFile: {
|
|
1319
1623
|
const buffer = await readSourceToBuffer(input);
|
|
1320
1624
|
const fileName = sanitizeFileName(typeof invokeArgs.fileName === "string" && invokeArgs.fileName.trim().length > 0 ? invokeArgs.fileName : "debug-upload.bin");
|
|
@@ -1323,16 +1627,16 @@ function createVirtualHostHandler(uploadDir) {
|
|
|
1323
1627
|
const outputPath = path.join(saveDir, `${Date.now()}-${randomUUID().slice(0, 8)}-${fileName}`);
|
|
1324
1628
|
await fs.mkdir(saveDir, { recursive: true });
|
|
1325
1629
|
await fs.writeFile(outputPath, buffer);
|
|
1326
|
-
return {
|
|
1630
|
+
return successResult({
|
|
1327
1631
|
fileName,
|
|
1328
1632
|
contentType,
|
|
1329
1633
|
size: buffer.length,
|
|
1330
1634
|
etag: createHash("md5").update(buffer).digest("hex"),
|
|
1331
1635
|
createTime: /* @__PURE__ */ new Date(),
|
|
1332
1636
|
accessURL: pathToFileURL(outputPath).href
|
|
1333
|
-
};
|
|
1637
|
+
});
|
|
1334
1638
|
}
|
|
1335
|
-
default: throw new Error(`本地虚拟环境暂不支持反向调用: ${String(
|
|
1639
|
+
default: throw new Error(`本地虚拟环境暂不支持反向调用: ${String(method)}`);
|
|
1336
1640
|
}
|
|
1337
1641
|
};
|
|
1338
1642
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createToolHandler,
|
|
3
|
+
defineTool,
|
|
4
|
+
type InputSchemaMetaType,
|
|
5
|
+
type OutputSchemaMetaType
|
|
6
|
+
} from '@fastgpt-plugin/sdk-factory';
|
|
2
7
|
import z from 'zod';
|
|
3
8
|
|
|
4
9
|
const handler = createToolHandler({
|
|
5
10
|
inputSchema: z.object({
|
|
6
|
-
delay: z.number()
|
|
11
|
+
delay: z.number().meta({
|
|
12
|
+
title: 'Delay',
|
|
13
|
+
description: 'Delay duration in milliseconds'
|
|
14
|
+
} satisfies InputSchemaMetaType)
|
|
7
15
|
}),
|
|
8
|
-
outputSchema: z.object({}),
|
|
16
|
+
outputSchema: z.object({}).meta({} satisfies OutputSchemaMetaType),
|
|
9
17
|
handler: async (input, _ctx) => {
|
|
10
18
|
await new Promise((resolve) => setTimeout(resolve, input.delay));
|
|
11
19
|
return {};
|
|
@@ -1,21 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
createToolHandler,
|
|
3
|
+
defineToolSet,
|
|
4
|
+
type InputSchemaMetaType,
|
|
5
|
+
type OutputSchemaMetaType,
|
|
6
|
+
type SecretSchemaMetaType
|
|
7
|
+
} from '@fastgpt-plugin/sdk-factory';
|
|
3
8
|
import z from 'zod';
|
|
4
9
|
|
|
5
10
|
const secretSchema = z.object({
|
|
6
|
-
host: z.string()
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
host: z.string().meta({
|
|
12
|
+
title: 'Host',
|
|
13
|
+
isSecret: false
|
|
14
|
+
} satisfies SecretSchemaMetaType),
|
|
15
|
+
port: z.number().meta({
|
|
16
|
+
title: 'Port',
|
|
17
|
+
isSecret: false
|
|
18
|
+
} satisfies SecretSchemaMetaType),
|
|
19
|
+
username: z.string().meta({
|
|
20
|
+
title: 'Username',
|
|
21
|
+
isSecret: false
|
|
22
|
+
} satisfies SecretSchemaMetaType),
|
|
23
|
+
password: z.string().meta({
|
|
24
|
+
title: 'Password',
|
|
25
|
+
isSecret: true
|
|
26
|
+
} satisfies SecretSchemaMetaType),
|
|
27
|
+
database: z.string().meta({
|
|
28
|
+
title: 'Database',
|
|
29
|
+
isSecret: false
|
|
30
|
+
} satisfies SecretSchemaMetaType)
|
|
11
31
|
});
|
|
12
32
|
|
|
13
33
|
const mysqlHandler = createToolHandler({
|
|
14
34
|
inputSchema: z.object({
|
|
15
|
-
query: z.string()
|
|
35
|
+
query: z.string().meta({
|
|
36
|
+
title: 'SQL Query'
|
|
37
|
+
} satisfies InputSchemaMetaType)
|
|
16
38
|
}),
|
|
17
39
|
outputSchema: z.object({
|
|
18
|
-
results: z.array(z.record(z.string(), z.unknown()))
|
|
40
|
+
results: z.array(z.record(z.string(), z.unknown())).meta({
|
|
41
|
+
title: 'Query Results'
|
|
42
|
+
} satisfies OutputSchemaMetaType)
|
|
19
43
|
}),
|
|
20
44
|
secretSchema,
|
|
21
45
|
handler: async (input, ctx) => {
|
|
@@ -37,10 +61,14 @@ const mysqlHandler = createToolHandler({
|
|
|
37
61
|
|
|
38
62
|
const pgsqlHandler = createToolHandler({
|
|
39
63
|
inputSchema: z.object({
|
|
40
|
-
query: z.string()
|
|
64
|
+
query: z.string().meta({
|
|
65
|
+
title: 'SQL Query'
|
|
66
|
+
} satisfies InputSchemaMetaType)
|
|
41
67
|
}),
|
|
42
68
|
outputSchema: z.object({
|
|
43
|
-
results: z.array(z.record(z.string(), z.unknown()))
|
|
69
|
+
results: z.array(z.record(z.string(), z.unknown())).meta({
|
|
70
|
+
title: 'Query Results'
|
|
71
|
+
} satisfies OutputSchemaMetaType)
|
|
44
72
|
}),
|
|
45
73
|
secretSchema,
|
|
46
74
|
handler: async (input, ctx) => {
|