deepfish-ai 1.0.28 → 2.0.2

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 (62) hide show
  1. package/README.md +126 -368
  2. package/dist/index.js +23320 -0
  3. package/dist/serve/client/assets/index-DUHYC91l.js +1 -0
  4. package/dist/serve/client/assets/index-zcrdNLZs.css +1 -0
  5. package/dist/serve/client/index.html +14 -0
  6. package/dist/serve/pm2-server.js +21015 -0
  7. package/dist/serve/server/entry-server.mjs +224 -0
  8. package/package.json +50 -70
  9. package/LICENSE +0 -21
  10. package/README_CN.md +0 -460
  11. package/src/AgentRobot/AgentRobotFactory/MainAgentRobot.js +0 -88
  12. package/src/AgentRobot/AgentRobotFactory/SubAgentRobot.js +0 -45
  13. package/src/AgentRobot/AgentRobotFactory/SubSkillAgentRobot.js +0 -45
  14. package/src/AgentRobot/AgentRobotFactory/index.js +0 -48
  15. package/src/AgentRobot/BaseAgentRobot/Brain.js +0 -210
  16. package/src/AgentRobot/BaseAgentRobot/BrainEvent.js +0 -17
  17. package/src/AgentRobot/BaseAgentRobot/Hand.js +0 -119
  18. package/src/AgentRobot/BaseAgentRobot/Heart.js +0 -0
  19. package/src/AgentRobot/BaseAgentRobot/Logger.js +0 -114
  20. package/src/AgentRobot/BaseAgentRobot/ScreenPrinter.js +0 -49
  21. package/src/AgentRobot/BaseAgentRobot/index.js +0 -266
  22. package/src/AgentRobot/BaseAgentRobot/lazy-tools/AliBailian.js +0 -997
  23. package/src/AgentRobot/BaseAgentRobot/lazy-tools/doc-transform.js +0 -204
  24. package/src/AgentRobot/BaseAgentRobot/lazy-tools/docx.js +0 -1286
  25. package/src/AgentRobot/BaseAgentRobot/lazy-tools/img.js +0 -765
  26. package/src/AgentRobot/BaseAgentRobot/lazy-tools/pdf.js +0 -736
  27. package/src/AgentRobot/BaseAgentRobot/lazy-tools/pptx.js +0 -567
  28. package/src/AgentRobot/BaseAgentRobot/lazy-tools/video.js +0 -36
  29. package/src/AgentRobot/BaseAgentRobot/lazy-tools/xlsx.js +0 -611
  30. package/src/AgentRobot/BaseAgentRobot/tools/BaseTools.js +0 -13
  31. package/src/AgentRobot/BaseAgentRobot/tools/CreateAgentTools.js +0 -158
  32. package/src/AgentRobot/BaseAgentRobot/tools/FileTools.js +0 -768
  33. package/src/AgentRobot/BaseAgentRobot/tools/GenerateTools.js +0 -441
  34. package/src/AgentRobot/BaseAgentRobot/tools/InquirerTools.js +0 -244
  35. package/src/AgentRobot/BaseAgentRobot/tools/SystemTools.js +0 -263
  36. package/src/AgentRobot/BaseAgentRobot/tools/TaskTools.js +0 -211
  37. package/src/AgentRobot/BaseAgentRobot/tools/TestTools.js +0 -100
  38. package/src/AgentRobot/BaseAgentRobot/tools/UserTool.js +0 -87
  39. package/src/AgentRobot/BaseAgentRobot/tools/WebTools.js +0 -257
  40. package/src/AgentRobot/BaseAgentRobot/utils/AIRequest.js +0 -297
  41. package/src/AgentRobot/BaseAgentRobot/utils/AIToolManager.js +0 -131
  42. package/src/AgentRobot/BaseAgentRobot/utils/AgentTree.js +0 -66
  43. package/src/AgentRobot/BaseAgentRobot/utils/AttachmentToolScanner.js +0 -235
  44. package/src/AgentRobot/BaseAgentRobot/utils/MessageCompresser.js +0 -236
  45. package/src/AgentRobot/BaseAgentRobot/utils/aiConsole.js +0 -74
  46. package/src/AgentRobot/BaseAgentRobot/utils/aiInquirer.js +0 -78
  47. package/src/AgentRobot/BaseAgentRobot/utils/analyzeReturn.test.js +0 -104
  48. package/src/AgentRobot/BaseAgentRobot/utils/copilot.js +0 -117
  49. package/src/AgentRobot/BaseAgentRobot/utils/node-root.js +0 -138
  50. package/src/AgentRobot/BaseAgentRobot/utils/normal.js +0 -399
  51. package/src/cli/ConfigManager.js +0 -283
  52. package/src/cli/DefaultConfig.js +0 -98
  53. package/src/cli/GlobalVariable.js +0 -8
  54. package/src/cli/MemoryManager.js +0 -53
  55. package/src/cli/SkillConfigManager.js +0 -343
  56. package/src/cli/SkillParser.js +0 -58
  57. package/src/cli/ai-auth.js +0 -231
  58. package/src/cli/ai-config.js +0 -225
  59. package/src/cli/ai-memory.js +0 -22
  60. package/src/cli/ai-skill.js +0 -65
  61. package/src/cli/index.js +0 -77
  62. package/src/index.js +0 -54
@@ -1,765 +0,0 @@
1
- /**
2
- * @Author: Roman 306863030@qq.com
3
- * @Description: 图片处理工具集(sharp)
4
- */
5
- const path = require('path')
6
- const fs = require('fs-extra')
7
- const sharp = require('sharp')
8
- const PDFKit = require('pdfkit')
9
-
10
- // ─── 统一返回结构 ─────────────────────────────────────────────────────────────
11
-
12
- function ok(data = null) {
13
- return { success: true, data }
14
- }
15
-
16
- function fail(error, data = null) {
17
- return { success: false, error: error?.message || String(error), data }
18
- }
19
-
20
- function resolvePath(filePath) {
21
- return path.resolve(process.cwd(), filePath)
22
- }
23
-
24
- function ensureOutputDir(outputPath) {
25
- fs.ensureDirSync(path.dirname(outputPath))
26
- }
27
-
28
- // ─── 工具函数 ─────────────────────────────────────────────────────────────────
29
-
30
- /**
31
- * 获取图片元数据(尺寸、格式、色彩空间等)
32
- */
33
- async function getImageInfo(filePath) {
34
- try {
35
- const fullPath = resolvePath(filePath)
36
- if (!fs.existsSync(fullPath)) return fail(`File does not exist: ${fullPath}`, { filePath: fullPath })
37
- const meta = await sharp(fullPath).metadata()
38
- const stat = fs.statSync(fullPath)
39
- return ok({
40
- filePath: fullPath,
41
- format: meta.format,
42
- width: meta.width,
43
- height: meta.height,
44
- channels: meta.channels,
45
- space: meta.space,
46
- hasAlpha: meta.hasAlpha,
47
- density: meta.density,
48
- size: stat.size,
49
- mtime: stat.mtime,
50
- exif: meta.exif ? true : false,
51
- icc: meta.icc ? true : false,
52
- })
53
- } catch (error) {
54
- return fail(error, { filePath })
55
- }
56
- }
57
-
58
- /**
59
- * 调整图片尺寸
60
- */
61
- async function resizeImage(filePath, outputPath, width, height, options = {}) {
62
- try {
63
- const fullInput = resolvePath(filePath)
64
- const fullOutput = resolvePath(outputPath)
65
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
66
- ensureOutputDir(fullOutput)
67
- const fitMap = { contain: 'contain', cover: 'cover', fill: 'fill', inside: 'inside', outside: 'outside' }
68
- const fit = fitMap[options.fit] || 'cover'
69
- await sharp(fullInput)
70
- .resize(width || null, height || null, {
71
- fit,
72
- withoutEnlargement: options.withoutEnlargement !== false,
73
- background: options.background || { r: 255, g: 255, b: 255, alpha: 1 },
74
- })
75
- .toFile(fullOutput)
76
- const meta = await sharp(fullOutput).metadata()
77
- return ok({ filePath: fullInput, outputPath: fullOutput, width: meta.width, height: meta.height })
78
- } catch (error) {
79
- return fail(error, { filePath, outputPath })
80
- }
81
- }
82
-
83
- /**
84
- * 裁剪图片(从指定坐标裁出矩形区域)
85
- */
86
- async function cropImage(filePath, outputPath, left, top, width, height) {
87
- try {
88
- const fullInput = resolvePath(filePath)
89
- const fullOutput = resolvePath(outputPath)
90
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
91
- ensureOutputDir(fullOutput)
92
- await sharp(fullInput)
93
- .extract({ left: left || 0, top: top || 0, width, height })
94
- .toFile(fullOutput)
95
- return ok({ filePath: fullInput, outputPath: fullOutput, left, top, width, height })
96
- } catch (error) {
97
- return fail(error, { filePath, outputPath })
98
- }
99
- }
100
-
101
- /**
102
- * 旋转图片
103
- */
104
- async function rotateImage(filePath, outputPath, angle) {
105
- try {
106
- const fullInput = resolvePath(filePath)
107
- const fullOutput = resolvePath(outputPath)
108
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
109
- ensureOutputDir(fullOutput)
110
- await sharp(fullInput)
111
- .rotate(angle || 90, { background: { r: 255, g: 255, b: 255, alpha: 1 } })
112
- .toFile(fullOutput)
113
- return ok({ filePath: fullInput, outputPath: fullOutput, angle })
114
- } catch (error) {
115
- return fail(error, { filePath, outputPath })
116
- }
117
- }
118
-
119
- /**
120
- * 翻转图片(水平或垂直)
121
- */
122
- async function flipImage(filePath, outputPath, direction) {
123
- try {
124
- const fullInput = resolvePath(filePath)
125
- const fullOutput = resolvePath(outputPath)
126
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
127
- ensureOutputDir(fullOutput)
128
- const inst = sharp(fullInput)
129
- if (direction === 'vertical') {
130
- inst.flip()
131
- } else {
132
- inst.flop()
133
- }
134
- await inst.toFile(fullOutput)
135
- return ok({ filePath: fullInput, outputPath: fullOutput, direction: direction || 'horizontal' })
136
- } catch (error) {
137
- return fail(error, { filePath, outputPath })
138
- }
139
- }
140
-
141
- /**
142
- * 转换图片格式(jpeg/png/webp/avif/gif/tiff)
143
- */
144
- async function convertImage(filePath, outputPath, format, options = {}) {
145
- try {
146
- const fullInput = resolvePath(filePath)
147
- const fullOutput = resolvePath(outputPath)
148
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
149
- ensureOutputDir(fullOutput)
150
- const fmt = (format || path.extname(outputPath).slice(1) || 'jpeg').toLowerCase()
151
- const formatOptions = {}
152
- if (options.quality) formatOptions.quality = options.quality
153
- await sharp(fullInput).toFormat(fmt, formatOptions).toFile(fullOutput)
154
- return ok({ filePath: fullInput, outputPath: fullOutput, format: fmt })
155
- } catch (error) {
156
- return fail(error, { filePath, outputPath })
157
- }
158
- }
159
-
160
- /**
161
- * 压缩图片质量
162
- */
163
- async function compressImage(filePath, outputPath, quality) {
164
- try {
165
- const fullInput = resolvePath(filePath)
166
- const fullOutput = resolvePath(outputPath)
167
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
168
- ensureOutputDir(fullOutput)
169
- const meta = await sharp(fullInput).metadata()
170
- const q = Math.max(1, Math.min(100, quality || 75))
171
- const fmt = meta.format || 'jpeg'
172
- await sharp(fullInput).toFormat(fmt, { quality: q }).toFile(fullOutput)
173
- const sizeBefore = fs.statSync(fullInput).size
174
- const sizeAfter = fs.statSync(fullOutput).size
175
- return ok({
176
- filePath: fullInput,
177
- outputPath: fullOutput,
178
- quality: q,
179
- sizeBefore,
180
- sizeAfter,
181
- ratio: Math.round((1 - sizeAfter / sizeBefore) * 100) + '%',
182
- })
183
- } catch (error) {
184
- return fail(error, { filePath, outputPath })
185
- }
186
- }
187
-
188
- /**
189
- * 转换为灰度图
190
- */
191
- async function grayscaleImage(filePath, outputPath) {
192
- try {
193
- const fullInput = resolvePath(filePath)
194
- const fullOutput = resolvePath(outputPath)
195
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
196
- ensureOutputDir(fullOutput)
197
- await sharp(fullInput).grayscale().toFile(fullOutput)
198
- return ok({ filePath: fullInput, outputPath: fullOutput })
199
- } catch (error) {
200
- return fail(error, { filePath, outputPath })
201
- }
202
- }
203
-
204
- /**
205
- * 对图片进行高斯模糊
206
- */
207
- async function blurImage(filePath, outputPath, sigma) {
208
- try {
209
- const fullInput = resolvePath(filePath)
210
- const fullOutput = resolvePath(outputPath)
211
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
212
- ensureOutputDir(fullOutput)
213
- await sharp(fullInput).blur(sigma || 3).toFile(fullOutput)
214
- return ok({ filePath: fullInput, outputPath: fullOutput, sigma: sigma || 3 })
215
- } catch (error) {
216
- return fail(error, { filePath, outputPath })
217
- }
218
- }
219
-
220
- /**
221
- * 对图片进行锐化
222
- */
223
- async function sharpenImage(filePath, outputPath, sigma) {
224
- try {
225
- const fullInput = resolvePath(filePath)
226
- const fullOutput = resolvePath(outputPath)
227
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
228
- ensureOutputDir(fullOutput)
229
- await sharp(fullInput).sharpen({ sigma: sigma || 1 }).toFile(fullOutput)
230
- return ok({ filePath: fullInput, outputPath: fullOutput, sigma: sigma || 1 })
231
- } catch (error) {
232
- return fail(error, { filePath, outputPath })
233
- }
234
- }
235
-
236
- /**
237
- * 生成缩略图(限制最长边)
238
- */
239
- async function thumbnailImage(filePath, outputPath, size) {
240
- try {
241
- const fullInput = resolvePath(filePath)
242
- const fullOutput = resolvePath(outputPath)
243
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
244
- ensureOutputDir(fullOutput)
245
- const s = size || 200
246
- await sharp(fullInput)
247
- .resize(s, s, { fit: 'inside', withoutEnlargement: true })
248
- .toFile(fullOutput)
249
- const meta = await sharp(fullOutput).metadata()
250
- return ok({ filePath: fullInput, outputPath: fullOutput, width: meta.width, height: meta.height })
251
- } catch (error) {
252
- return fail(error, { filePath, outputPath })
253
- }
254
- }
255
-
256
- /**
257
- * 叠加图片水印(将 overlayPath 图片合成到底图上)
258
- */
259
- async function overlayImage(filePath, overlayPath, outputPath, options = {}) {
260
- try {
261
- const fullInput = resolvePath(filePath)
262
- const fullOverlay = resolvePath(overlayPath)
263
- const fullOutput = resolvePath(outputPath)
264
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
265
- if (!fs.existsSync(fullOverlay)) return fail(`Overlay file does not exist: ${fullOverlay}`, { overlayPath: fullOverlay })
266
- ensureOutputDir(fullOutput)
267
- const gravity = options.gravity || 'southeast'
268
- await sharp(fullInput)
269
- .composite([{ input: fullOverlay, gravity, blend: options.blend || 'over' }])
270
- .toFile(fullOutput)
271
- return ok({ filePath: fullInput, overlayPath: fullOverlay, outputPath: fullOutput, gravity })
272
- } catch (error) {
273
- return fail(error, { filePath, overlayPath, outputPath })
274
- }
275
- }
276
-
277
- /**
278
- * 调整图片亮度、饱和度、色相
279
- */
280
- async function adjustImage(filePath, outputPath, options = {}) {
281
- try {
282
- const fullInput = resolvePath(filePath)
283
- const fullOutput = resolvePath(outputPath)
284
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
285
- ensureOutputDir(fullOutput)
286
- let inst = sharp(fullInput)
287
- if (options.brightness !== undefined || options.saturation !== undefined || options.hue !== undefined) {
288
- inst = inst.modulate({
289
- brightness: options.brightness !== undefined ? options.brightness : 1,
290
- saturation: options.saturation !== undefined ? options.saturation : 1,
291
- hue: options.hue !== undefined ? options.hue : 0,
292
- })
293
- }
294
- if (options.gamma !== undefined) inst = inst.gamma(options.gamma)
295
- if (options.negate) inst = inst.negate()
296
- await inst.toFile(fullOutput)
297
- return ok({ filePath: fullInput, outputPath: fullOutput, options })
298
- } catch (error) {
299
- return fail(error, { filePath, outputPath })
300
- }
301
- }
302
-
303
- /**
304
- * 为图片添加 padding(边框/背景延伸)
305
- */
306
- async function padImage(filePath, outputPath, padding, background) {
307
- try {
308
- const fullInput = resolvePath(filePath)
309
- const fullOutput = resolvePath(outputPath)
310
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
311
- ensureOutputDir(fullOutput)
312
- const p = typeof padding === 'number' ? padding : 20
313
- const bg = background || { r: 255, g: 255, b: 255, alpha: 1 }
314
- await sharp(fullInput).extend({ top: p, bottom: p, left: p, right: p, background: bg }).toFile(fullOutput)
315
- const meta = await sharp(fullOutput).metadata()
316
- return ok({ filePath: fullInput, outputPath: fullOutput, padding: p, width: meta.width, height: meta.height })
317
- } catch (error) {
318
- return fail(error, { filePath, outputPath })
319
- }
320
- }
321
-
322
- /**
323
- * 批量调整目录中的图片尺寸
324
- */
325
- async function batchResizeImages(inputDir, outputDir, width, height, options = {}) {
326
- try {
327
- const fullInput = resolvePath(inputDir)
328
- const fullOutput = resolvePath(outputDir)
329
- if (!fs.existsSync(fullInput)) return fail(`Directory does not exist: ${fullInput}`, { inputDir: fullInput })
330
- fs.ensureDirSync(fullOutput)
331
- const exts = new Set(['.jpg', '.jpeg', '.png', '.webp', '.gif', '.tiff', '.avif'])
332
- const files = fs.readdirSync(fullInput).filter((f) => exts.has(path.extname(f).toLowerCase()))
333
- const results = []
334
- for (const file of files) {
335
- const res = await resizeImage(
336
- path.join(fullInput, file),
337
- path.join(fullOutput, file),
338
- width,
339
- height,
340
- options,
341
- )
342
- results.push({ file, success: res.success, error: res.error || null })
343
- }
344
- const succeeded = results.filter((r) => r.success).length
345
- return ok({ inputDir: fullInput, outputDir: fullOutput, total: results.length, succeeded, results })
346
- } catch (error) {
347
- return fail(error, { inputDir, outputDir })
348
- }
349
- }
350
-
351
- /**
352
- * 批量转换目录中图片的格式
353
- */
354
- async function batchConvertImages(inputDir, outputDir, format, options = {}) {
355
- try {
356
- const fullInput = resolvePath(inputDir)
357
- const fullOutput = resolvePath(outputDir)
358
- if (!fs.existsSync(fullInput)) return fail(`Directory does not exist: ${fullInput}`, { inputDir: fullInput })
359
- fs.ensureDirSync(fullOutput)
360
- const exts = new Set(['.jpg', '.jpeg', '.png', '.webp', '.gif', '.tiff', '.avif'])
361
- const files = fs.readdirSync(fullInput).filter((f) => exts.has(path.extname(f).toLowerCase()))
362
- const results = []
363
- for (const file of files) {
364
- const outFile = path.basename(file, path.extname(file)) + '.' + format
365
- const res = await convertImage(
366
- path.join(fullInput, file),
367
- path.join(fullOutput, outFile),
368
- format,
369
- options,
370
- )
371
- results.push({ file, output: outFile, success: res.success, error: res.error || null })
372
- }
373
- const succeeded = results.filter((r) => r.success).length
374
- return ok({ inputDir: fullInput, outputDir: fullOutput, format, total: results.length, succeeded, results })
375
- } catch (error) {
376
- return fail(error, { inputDir, outputDir })
377
- }
378
- }
379
-
380
- /**
381
- * 将多张图片按页合并为一个 PDF 文件
382
- */
383
- async function imagesToPdf(imagePaths, outputPath, options = {}) {
384
- try {
385
- const fullOutput = path.resolve(process.cwd(), outputPath)
386
- fs.ensureDirSync(path.dirname(fullOutput))
387
- if (!Array.isArray(imagePaths) || imagePaths.length === 0) {
388
- return fail('imagePaths must be a non-empty array', { outputPath })
389
- }
390
- return await new Promise((resolve, reject) => {
391
- const doc = new PDFKit({ autoFirstPage: false, margin: 0 })
392
- const stream = fs.createWriteStream(fullOutput)
393
- doc.pipe(stream)
394
- const addPages = async () => {
395
- for (const imgPath of imagePaths) {
396
- const fullImg = path.resolve(process.cwd(), imgPath)
397
- if (!fs.existsSync(fullImg)) {
398
- return resolve(fail(`Image file does not exist: ${fullImg}`, { imagePath: fullImg }))
399
- }
400
- const meta = await sharp(fullImg).metadata()
401
- const imgW = meta.width || 595
402
- const imgH = meta.height || 842
403
- const pageW = options.pageWidth || imgW
404
- const pageH = options.pageHeight || imgH
405
- doc.addPage({ size: [pageW, pageH], margin: 0 })
406
- doc.image(fullImg, 0, 0, { width: pageW, height: pageH, fit: [pageW, pageH], align: 'center', valign: 'center' })
407
- }
408
- doc.end()
409
- }
410
- addPages().catch(reject)
411
- stream.on('finish', () =>
412
- resolve(ok({ outputPath: fullOutput, pageCount: imagePaths.length, imagePaths }))
413
- )
414
- stream.on('error', reject)
415
- })
416
- } catch (error) {
417
- return fail(error, { outputPath })
418
- }
419
- }
420
-
421
- // ─── 工具描述 ─────────────────────────────────────────────────────────────────
422
-
423
-
424
- // ─── 使用说明 ─────────────────────────────────────────────────────────────────
425
-
426
- function imgReadme() {
427
- return `【IMG 工具使用说明】
428
- 1. 优先使用本工具内置函数完成任务(元数据读取、缩放、裁剪、旋转、格式转换、压缩、水印等)。
429
- 2. 如果内置函数无法满足需求(如复杂滤镜处理、特殊格式转换、高级图像合成),再尝试使用 ImageMagick 命令行。
430
- 3. 在调用 ImageMagick 前,先检测系统是否已安装 ImageMagick:
431
- - 已安装:直接使用 ImageMagick 命令行继续处理。
432
- - 未安装:询问用户是否允许安装。
433
- 4. 若用户同意安装:引导完成安装后继续执行原任务。
434
- 5. 若用户拒绝安装:明确告知当前能力限制,并终止该操作。
435
-
436
- 建议:
437
- - 常规图像处理优先使用内置函数,速度更快且依赖更少。
438
- - 仅在确实需要高级图像处理能力时才启用 ImageMagick 路径。`
439
- }
440
-
441
- const descriptions = [
442
- {
443
- type: 'function',
444
- function: {
445
- name: 'imgReadme',
446
- description: '获取 IMG 工具集的使用说明, 调用函数前必须先查看本说明。',
447
- parameters: {},
448
- }
449
- },
450
- {
451
- type: 'function',
452
- function: {
453
- name: 'getImageInfo',
454
- description: '获取图片的元数据信息。参数:filePath 为图片路径。返回值:对象,包含 success、data(含 filePath、format、width、height、channels、space、hasAlpha、density、size、mtime)、error。',
455
- parameters: {
456
- type: 'object',
457
- properties: {
458
- filePath: { type: 'string', description: '图片文件路径(支持 jpg/png/webp/gif/tiff/avif 等)。' },
459
- },
460
- required: ['filePath'],
461
- },
462
- },
463
- },
464
- {
465
- type: 'function',
466
- function: {
467
- name: 'resizeImage',
468
- description: '调整图片尺寸。参数:filePath 为源图路径;outputPath 为输出路径;width 为目标宽度(像素);height 为目标高度(像素);options 为可选项(fit: contain/cover/fill/inside/outside,withoutEnlargement: boolean,background: {r,g,b,alpha})。返回值:对象,包含 success、data(含 outputPath、width、height)、error。',
469
- parameters: {
470
- type: 'object',
471
- properties: {
472
- filePath: { type: 'string', description: '源图片文件路径。' },
473
- outputPath: { type: 'string', description: '输出图片文件路径。' },
474
- width: { type: 'number', description: '目标宽度(像素),可省略(仅按高度缩放)。' },
475
- height: { type: 'number', description: '目标高度(像素),可省略(仅按宽度缩放)。' },
476
- options: { type: 'object', description: '可选:{ fit, withoutEnlargement, background }。' },
477
- },
478
- required: ['filePath', 'outputPath'],
479
- },
480
- },
481
- },
482
- {
483
- type: 'function',
484
- function: {
485
- name: 'cropImage',
486
- description: '裁剪图片,从指定坐标截取矩形区域。参数:filePath 为源图路径;outputPath 为输出路径;left/top 为起点坐标;width/height 为裁剪区域尺寸。返回值:对象,包含 success、data(含 outputPath、left、top、width、height)、error。',
487
- parameters: {
488
- type: 'object',
489
- properties: {
490
- filePath: { type: 'string', description: '源图片文件路径。' },
491
- outputPath: { type: 'string', description: '输出图片文件路径。' },
492
- left: { type: 'number', description: '裁剪起点 X 坐标(像素)。' },
493
- top: { type: 'number', description: '裁剪起点 Y 坐标(像素)。' },
494
- width: { type: 'number', description: '裁剪区域宽度(像素)。' },
495
- height: { type: 'number', description: '裁剪区域高度(像素)。' },
496
- },
497
- required: ['filePath', 'outputPath', 'left', 'top', 'width', 'height'],
498
- },
499
- },
500
- },
501
- {
502
- type: 'function',
503
- function: {
504
- name: 'rotateImage',
505
- description: '旋转图片。参数:filePath 为源图路径;outputPath 为输出路径;angle 为旋转角度(度,正值顺时针)。返回值:对象,包含 success、data(含 outputPath、angle)、error。',
506
- parameters: {
507
- type: 'object',
508
- properties: {
509
- filePath: { type: 'string', description: '源图片文件路径。' },
510
- outputPath: { type: 'string', description: '输出图片文件路径。' },
511
- angle: { type: 'number', description: '旋转角度(度),如 90、180、270,正值顺时针。' },
512
- },
513
- required: ['filePath', 'outputPath', 'angle'],
514
- },
515
- },
516
- },
517
- {
518
- type: 'function',
519
- function: {
520
- name: 'flipImage',
521
- description: '翻转图片(水平镜像或垂直翻转)。参数:filePath 为源图路径;outputPath 为输出路径;direction 为翻转方向(horizontal 或 vertical)。返回值:对象,包含 success、data(含 outputPath、direction)、error。',
522
- parameters: {
523
- type: 'object',
524
- properties: {
525
- filePath: { type: 'string', description: '源图片文件路径。' },
526
- outputPath: { type: 'string', description: '输出图片文件路径。' },
527
- direction: { type: 'string', description: '翻转方向:horizontal(水平镜像)或 vertical(垂直翻转)。' },
528
- },
529
- required: ['filePath', 'outputPath', 'direction'],
530
- },
531
- },
532
- },
533
- {
534
- type: 'function',
535
- function: {
536
- name: 'convertImage',
537
- description: '转换图片格式。参数:filePath 为源图路径;outputPath 为输出路径;format 为目标格式(jpeg/png/webp/avif/gif/tiff);options 为可选({ quality })。返回值:对象,包含 success、data(含 outputPath、format)、error。',
538
- parameters: {
539
- type: 'object',
540
- properties: {
541
- filePath: { type: 'string', description: '源图片文件路径。' },
542
- outputPath: { type: 'string', description: '输出图片文件路径。' },
543
- format: { type: 'string', description: '目标格式,如 jpeg、png、webp、avif、gif、tiff。' },
544
- options: { type: 'object', description: '可选:{ quality: 1-100 }。' },
545
- },
546
- required: ['filePath', 'outputPath', 'format'],
547
- },
548
- },
549
- },
550
- {
551
- type: 'function',
552
- function: {
553
- name: 'compressImage',
554
- description: '压缩图片文件大小。参数:filePath 为源图路径;outputPath 为输出路径;quality 为质量(1-100,默认 75)。返回值:对象,包含 success、data(含 outputPath、quality、sizeBefore、sizeAfter、ratio)、error。',
555
- parameters: {
556
- type: 'object',
557
- properties: {
558
- filePath: { type: 'string', description: '源图片文件路径。' },
559
- outputPath: { type: 'string', description: '输出图片文件路径。' },
560
- quality: { type: 'number', description: '压缩质量 1-100,默认 75。' },
561
- },
562
- required: ['filePath', 'outputPath'],
563
- },
564
- },
565
- },
566
- {
567
- type: 'function',
568
- function: {
569
- name: 'grayscaleImage',
570
- description: '将图片转换为灰度图。参数:filePath 为源图路径;outputPath 为输出路径。返回值:对象,包含 success、data(含 outputPath)、error。',
571
- parameters: {
572
- type: 'object',
573
- properties: {
574
- filePath: { type: 'string', description: '源图片文件路径。' },
575
- outputPath: { type: 'string', description: '输出图片文件路径。' },
576
- },
577
- required: ['filePath', 'outputPath'],
578
- },
579
- },
580
- },
581
- {
582
- type: 'function',
583
- function: {
584
- name: 'blurImage',
585
- description: '对图片进行高斯模糊。参数:filePath 为源图路径;outputPath 为输出路径;sigma 为模糊半径(默认 3,值越大越模糊)。返回值:对象,包含 success、data(含 outputPath、sigma)、error。',
586
- parameters: {
587
- type: 'object',
588
- properties: {
589
- filePath: { type: 'string', description: '源图片文件路径。' },
590
- outputPath: { type: 'string', description: '输出图片文件路径。' },
591
- sigma: { type: 'number', description: '模糊强度(0.3-1000,默认 3)。' },
592
- },
593
- required: ['filePath', 'outputPath'],
594
- },
595
- },
596
- },
597
- {
598
- type: 'function',
599
- function: {
600
- name: 'sharpenImage',
601
- description: '对图片进行锐化处理。参数:filePath 为源图路径;outputPath 为输出路径;sigma 为锐化强度(默认 1)。返回值:对象,包含 success、data(含 outputPath、sigma)、error。',
602
- parameters: {
603
- type: 'object',
604
- properties: {
605
- filePath: { type: 'string', description: '源图片文件路径。' },
606
- outputPath: { type: 'string', description: '输出图片文件路径。' },
607
- sigma: { type: 'number', description: '锐化强度,默认 1。' },
608
- },
609
- required: ['filePath', 'outputPath'],
610
- },
611
- },
612
- },
613
- {
614
- type: 'function',
615
- function: {
616
- name: 'thumbnailImage',
617
- description: '生成图片缩略图(等比缩放,最长边不超过 size 像素)。参数:filePath 为源图路径;outputPath 为输出路径;size 为最长边限制(默认 200)。返回值:对象,包含 success、data(含 outputPath、width、height)、error。',
618
- parameters: {
619
- type: 'object',
620
- properties: {
621
- filePath: { type: 'string', description: '源图片文件路径。' },
622
- outputPath: { type: 'string', description: '输出缩略图文件路径。' },
623
- size: { type: 'number', description: '缩略图最长边最大像素数,默认 200。' },
624
- },
625
- required: ['filePath', 'outputPath'],
626
- },
627
- },
628
- },
629
- {
630
- type: 'function',
631
- function: {
632
- name: 'overlayImage',
633
- description: '将水印图片叠加到底图上。参数:filePath 为底图路径;overlayPath 为水印图路径;outputPath 为输出路径;options 为可选项(gravity: northwest/north/northeast/west/center/east/southwest/south/southeast,blend: over/multiply 等)。返回值:对象,包含 success、data(含 outputPath、gravity)、error。',
634
- parameters: {
635
- type: 'object',
636
- properties: {
637
- filePath: { type: 'string', description: '底图文件路径。' },
638
- overlayPath: { type: 'string', description: '水印/叠加图片文件路径。' },
639
- outputPath: { type: 'string', description: '输出图片文件路径。' },
640
- options: { type: 'object', description: '可选:{ gravity, blend },gravity 默认 southeast。' },
641
- },
642
- required: ['filePath', 'overlayPath', 'outputPath'],
643
- },
644
- },
645
- },
646
- {
647
- type: 'function',
648
- function: {
649
- name: 'adjustImage',
650
- description: '调整图片亮度、饱和度、色相及特效。参数:filePath 为源图路径;outputPath 为输出路径;options 为调整参数(brightness: 倍数,1 为原始;saturation: 倍数;hue: 角度 0-360;gamma: 1-3;negate: 布尔)。返回值:对象,包含 success、data(含 outputPath)、error。',
651
- parameters: {
652
- type: 'object',
653
- properties: {
654
- filePath: { type: 'string', description: '源图片文件路径。' },
655
- outputPath: { type: 'string', description: '输出图片文件路径。' },
656
- options: {
657
- type: 'object',
658
- description: '调整参数:{ brightness, saturation, hue, gamma, negate }。',
659
- },
660
- },
661
- required: ['filePath', 'outputPath', 'options'],
662
- },
663
- },
664
- },
665
- {
666
- type: 'function',
667
- function: {
668
- name: 'padImage',
669
- description: '为图片四周添加等宽 padding(背景延伸)。参数:filePath 为源图路径;outputPath 为输出路径;padding 为边距像素数(默认 20);background 为背景色({ r, g, b, alpha },默认白色)。返回值:对象,包含 success、data(含 outputPath、padding、width、height)、error。',
670
- parameters: {
671
- type: 'object',
672
- properties: {
673
- filePath: { type: 'string', description: '源图片文件路径。' },
674
- outputPath: { type: 'string', description: '输出图片文件路径。' },
675
- padding: { type: 'number', description: '四周边距像素数,默认 20。' },
676
- background: { type: 'object', description: '背景色对象 { r, g, b, alpha },默认白色。' },
677
- },
678
- required: ['filePath', 'outputPath'],
679
- },
680
- },
681
- },
682
- {
683
- type: 'function',
684
- function: {
685
- name: 'batchResizeImages',
686
- description: '批量调整目录中所有图片的尺寸。参数:inputDir 为源目录;outputDir 为输出目录;width 为目标宽度;height 为目标高度;options 同 resizeImage。返回值:对象,包含 success、data(含 total、succeeded、results 数组)、error。',
687
- parameters: {
688
- type: 'object',
689
- properties: {
690
- inputDir: { type: 'string', description: '源图片目录路径。' },
691
- outputDir: { type: 'string', description: '输出目录路径。' },
692
- width: { type: 'number', description: '目标宽度(像素)。' },
693
- height: { type: 'number', description: '目标高度(像素)。' },
694
- options: { type: 'object', description: '可选:{ fit, withoutEnlargement }。' },
695
- },
696
- required: ['inputDir', 'outputDir'],
697
- },
698
- },
699
- },
700
- {
701
- type: 'function',
702
- function: {
703
- name: 'batchConvertImages',
704
- description: '批量转换目录中所有图片的格式。参数:inputDir 为源目录;outputDir 为输出目录;format 为目标格式(jpeg/png/webp/avif/gif/tiff);options 为可选({ quality })。返回值:对象,包含 success、data(含 format、total、succeeded、results 数组)、error。',
705
- parameters: {
706
- type: 'object',
707
- properties: {
708
- inputDir: { type: 'string', description: '源图片目录路径。' },
709
- outputDir: { type: 'string', description: '输出目录路径。' },
710
- format: { type: 'string', description: '目标格式,如 jpeg、png、webp、avif。' },
711
- options: { type: 'object', description: '可选:{ quality: 1-100 }。' },
712
- },
713
- required: ['inputDir', 'outputDir', 'format'],
714
- },
715
- },
716
- }, {
717
- type: 'function',
718
- function: {
719
- name: 'imagesToPdf',
720
- description: '将多张图片按顺序合并为一个 PDF 文件,每张图片占一页。参数:imagePaths 为图片路径数组(支持 jpg/png/webp 等);outputPath 为输出 PDF 路径;options 可选({ pageWidth, pageHeight },省略则自动适配图片尺寸)。返回值:对象,包含 success、data(含 outputPath、pageCount、imagePaths)、error。',
721
- parameters: {
722
- type: 'object',
723
- properties: {
724
- imagePaths: { type: 'array', items: { type: 'string' }, description: '图片路径数组,按顺序排列。' },
725
- outputPath: { type: 'string', description: '输出 PDF 文件路径。' },
726
- options: { type: 'object', description: '可选:{ pageWidth, pageHeight },单位像素。' },
727
- },
728
- required: ['imagePaths', 'outputPath'],
729
- },
730
- },
731
- },]
732
-
733
- // ─── 导出 ──────────────────────────────────────────────────────────────────────
734
-
735
- const functions = {
736
- imgReadme,
737
- getImageInfo,
738
- resizeImage,
739
- cropImage,
740
- rotateImage,
741
- flipImage,
742
- convertImage,
743
- compressImage,
744
- grayscaleImage,
745
- blurImage,
746
- sharpenImage,
747
- thumbnailImage,
748
- overlayImage,
749
- adjustImage,
750
- padImage,
751
- batchResizeImages,
752
- batchConvertImages,
753
- imagesToPdf,
754
- }
755
-
756
- const ImgTool = {
757
- name: 'ImgTool',
758
- description: '提供图片的元数据读取、缩放、裁剪、旋转、翻转、格式转换、压缩、灰度、模糊、锐化、缩略图、水印叠加、图片转 PDF、批量处理等全面图像处理能力',
759
- platform: 'all',
760
- descriptions,
761
- functions,
762
- isSystem: true
763
- }
764
-
765
- module.exports = ImgTool