deepfish-ai 1.0.29 → 2.0.3

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 (65) hide show
  1. package/README.md +195 -344
  2. package/dist/generate-skill.md +104 -0
  3. package/dist/generate-tool.md +88 -0
  4. package/dist/index.js +26831 -0
  5. package/dist/serve/client/assets/index-DUHYC91l.js +1 -0
  6. package/dist/serve/client/assets/index-zcrdNLZs.css +1 -0
  7. package/dist/serve/client/index.html +14 -0
  8. package/dist/serve/pm2-server.js +24405 -0
  9. package/dist/serve/server/entry-server.mjs +224 -0
  10. package/dist/view-learn-cache.md +65 -0
  11. package/package.json +77 -83
  12. package/LICENSE +0 -21
  13. package/README_CN.md +0 -460
  14. package/src/AgentRobot/AgentRobotFactory/MainAgentRobot.js +0 -88
  15. package/src/AgentRobot/AgentRobotFactory/SubAgentRobot.js +0 -45
  16. package/src/AgentRobot/AgentRobotFactory/SubSkillAgentRobot.js +0 -45
  17. package/src/AgentRobot/AgentRobotFactory/index.js +0 -48
  18. package/src/AgentRobot/BaseAgentRobot/Brain.js +0 -210
  19. package/src/AgentRobot/BaseAgentRobot/BrainEvent.js +0 -17
  20. package/src/AgentRobot/BaseAgentRobot/Hand.js +0 -119
  21. package/src/AgentRobot/BaseAgentRobot/Heart.js +0 -0
  22. package/src/AgentRobot/BaseAgentRobot/Logger.js +0 -114
  23. package/src/AgentRobot/BaseAgentRobot/ScreenPrinter.js +0 -49
  24. package/src/AgentRobot/BaseAgentRobot/index.js +0 -266
  25. package/src/AgentRobot/BaseAgentRobot/lazy-tools/AliBailian.js +0 -997
  26. package/src/AgentRobot/BaseAgentRobot/lazy-tools/doc-transform.js +0 -204
  27. package/src/AgentRobot/BaseAgentRobot/lazy-tools/docx.js +0 -1286
  28. package/src/AgentRobot/BaseAgentRobot/lazy-tools/img.js +0 -765
  29. package/src/AgentRobot/BaseAgentRobot/lazy-tools/pdf.js +0 -736
  30. package/src/AgentRobot/BaseAgentRobot/lazy-tools/pptx.js +0 -567
  31. package/src/AgentRobot/BaseAgentRobot/lazy-tools/video.js +0 -36
  32. package/src/AgentRobot/BaseAgentRobot/lazy-tools/xlsx.js +0 -611
  33. package/src/AgentRobot/BaseAgentRobot/tools/BaseTools.js +0 -13
  34. package/src/AgentRobot/BaseAgentRobot/tools/CreateAgentTools.js +0 -158
  35. package/src/AgentRobot/BaseAgentRobot/tools/FileTools.js +0 -768
  36. package/src/AgentRobot/BaseAgentRobot/tools/GenerateTools.js +0 -441
  37. package/src/AgentRobot/BaseAgentRobot/tools/InquirerTools.js +0 -244
  38. package/src/AgentRobot/BaseAgentRobot/tools/SystemTools.js +0 -424
  39. package/src/AgentRobot/BaseAgentRobot/tools/TaskTools.js +0 -211
  40. package/src/AgentRobot/BaseAgentRobot/tools/TestTools.js +0 -100
  41. package/src/AgentRobot/BaseAgentRobot/tools/UserTool.js +0 -87
  42. package/src/AgentRobot/BaseAgentRobot/tools/WebTools.js +0 -257
  43. package/src/AgentRobot/BaseAgentRobot/utils/AIRequest.js +0 -297
  44. package/src/AgentRobot/BaseAgentRobot/utils/AIToolManager.js +0 -131
  45. package/src/AgentRobot/BaseAgentRobot/utils/AgentTree.js +0 -66
  46. package/src/AgentRobot/BaseAgentRobot/utils/AttachmentToolScanner.js +0 -235
  47. package/src/AgentRobot/BaseAgentRobot/utils/MessageCompresser.js +0 -236
  48. package/src/AgentRobot/BaseAgentRobot/utils/aiConsole.js +0 -74
  49. package/src/AgentRobot/BaseAgentRobot/utils/aiInquirer.js +0 -78
  50. package/src/AgentRobot/BaseAgentRobot/utils/analyzeReturn.test.js +0 -104
  51. package/src/AgentRobot/BaseAgentRobot/utils/copilot.js +0 -117
  52. package/src/AgentRobot/BaseAgentRobot/utils/node-root.js +0 -138
  53. package/src/AgentRobot/BaseAgentRobot/utils/normal.js +0 -399
  54. package/src/cli/ConfigManager.js +0 -283
  55. package/src/cli/DefaultConfig.js +0 -98
  56. package/src/cli/GlobalVariable.js +0 -8
  57. package/src/cli/MemoryManager.js +0 -53
  58. package/src/cli/SkillConfigManager.js +0 -354
  59. package/src/cli/SkillParser.js +0 -58
  60. package/src/cli/ai-auth.js +0 -231
  61. package/src/cli/ai-config.js +0 -225
  62. package/src/cli/ai-memory.js +0 -22
  63. package/src/cli/ai-skill.js +0 -65
  64. package/src/cli/index.js +0 -77
  65. package/src/index.js +0 -54
@@ -1,567 +0,0 @@
1
- /**
2
- * @Author: Roman 306863030@qq.com
3
- * @Description: PowerPoint 文档处理工具集(pptxgenjs)
4
- */
5
- const path = require('path')
6
- const fs = require('fs-extra')
7
- const PptxGenJS = require('pptxgenjs')
8
- const AdmZip = require('adm-zip')
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
- // ─── 内部辅助 ─────────────────────────────────────────────────────────────────
25
-
26
- /**
27
- * 从 PPTX ZIP 中提取所有幻灯片 XML 内的纯文本
28
- */
29
- function extractTextFromPptx(fullPath) {
30
- const zip = new AdmZip(fullPath)
31
- const entries = zip.getEntries()
32
- const slideEntries = entries
33
- .filter((e) => /^ppt\/slides\/slide\d+\.xml$/.test(e.entryName))
34
- .sort((a, b) => {
35
- const numA = parseInt(a.entryName.match(/\d+/)[0])
36
- const numB = parseInt(b.entryName.match(/\d+/)[0])
37
- return numA - numB
38
- })
39
- const slides = []
40
- for (const entry of slideEntries) {
41
- const xml = entry.getData().toString('utf8')
42
- const texts = []
43
- const regex = /<a:t>([\s\S]*?)<\/a:t>/g
44
- let m
45
- while ((m = regex.exec(xml)) !== null) {
46
- const t = m[1].trim()
47
- if (t) texts.push(t)
48
- }
49
- slides.push(texts.join(' '))
50
- }
51
- return slides
52
- }
53
-
54
- /**
55
- * 解析颜色:支持 hex 字符串(不含 #)或 { r, g, b } 对象
56
- */
57
- function parseColor(color, defaultColor = '000000') {
58
- if (!color) return defaultColor
59
- if (typeof color === 'string') return color.replace('#', '')
60
- if (typeof color === 'object' && color.r !== undefined) {
61
- return (
62
- color.r.toString(16).padStart(2, '0') +
63
- color.g.toString(16).padStart(2, '0') +
64
- color.b.toString(16).padStart(2, '0')
65
- ).toUpperCase()
66
- }
67
- return defaultColor
68
- }
69
-
70
- // ─── 工具函数 ─────────────────────────────────────────────────────────────────
71
-
72
- /**
73
- * 获取 PPTX 文件基本信息(幻灯片数、文件大小等)
74
- */
75
- async function getPptxInfo(filePath) {
76
- try {
77
- const fullPath = resolvePath(filePath)
78
- if (!fs.existsSync(fullPath)) return fail(`File does not exist: ${fullPath}`, { filePath: fullPath })
79
- const zip = new AdmZip(fullPath)
80
- const slideCount = zip.getEntries().filter((e) => /^ppt\/slides\/slide\d+\.xml$/.test(e.entryName)).length
81
- const stat = fs.statSync(fullPath)
82
- // 读取 core.xml 获取元信息
83
- const coreEntry = zip.getEntry('docProps/core.xml')
84
- let title = '', creator = '', lastModifiedBy = '', created = '', modified = ''
85
- if (coreEntry) {
86
- const coreXml = coreEntry.getData().toString('utf8')
87
- const match = (tag) => { const m = coreXml.match(new RegExp(`<[^>]*:?${tag}[^>]*>([\\s\\S]*?)<\\/[^>]*:?${tag}>`)); return m ? m[1] : '' }
88
- title = match('title')
89
- creator = match('creator')
90
- lastModifiedBy = match('lastModifiedBy')
91
- created = match('created')
92
- modified = match('modified')
93
- }
94
- return ok({ filePath: fullPath, slideCount, size: stat.size, mtime: stat.mtime, title, creator, lastModifiedBy, created, modified })
95
- } catch (error) {
96
- return fail(error, { filePath })
97
- }
98
- }
99
-
100
- /**
101
- * 提取 PPTX 中所有幻灯片的纯文本(按页返回数组)
102
- */
103
- async function readPptxText(filePath) {
104
- try {
105
- const fullPath = resolvePath(filePath)
106
- if (!fs.existsSync(fullPath)) return fail(`File does not exist: ${fullPath}`, { filePath: fullPath })
107
- const slides = extractTextFromPptx(fullPath)
108
- const allText = slides.join('\n')
109
- return ok({
110
- filePath: fullPath,
111
- slideCount: slides.length,
112
- slides,
113
- text: allText,
114
- wordCount: allText.trim().split(/\s+/).filter(Boolean).length,
115
- })
116
- } catch (error) {
117
- return fail(error, { filePath })
118
- }
119
- }
120
-
121
- /**
122
- * 在 PPTX 中搜索关键词,返回匹配的幻灯片页码与摘要
123
- */
124
- async function searchPptxText(filePath, keyword) {
125
- try {
126
- const fullPath = resolvePath(filePath)
127
- if (!fs.existsSync(fullPath)) return fail(`File does not exist: ${fullPath}`, { filePath: fullPath })
128
- const slides = extractTextFromPptx(fullPath)
129
- const matches = slides
130
- .map((text, idx) => ({ slide: idx + 1, text }))
131
- .filter(({ text }) => text.includes(keyword))
132
- return ok({ filePath: fullPath, keyword, matchCount: matches.length, matches })
133
- } catch (error) {
134
- return fail(error, { filePath, keyword })
135
- }
136
- }
137
-
138
- /**
139
- * 创建新的 PPTX 演示文稿
140
- * slides 数组每项:{ title, content, notes, layout, background, items[] }
141
- * items 每项:{ type:'text'|'image'|'table'|'shape', ... }
142
- */
143
- async function createPptx(outputPath, slides = [], options = {}) {
144
- try {
145
- const fullOutput = resolvePath(outputPath)
146
- fs.ensureDirSync(path.dirname(fullOutput))
147
- const pptx = new PptxGenJS()
148
-
149
- // 设置全局属性
150
- if (options.title) pptx.title = options.title
151
- if (options.subject) pptx.subject = options.subject
152
- if (options.author) pptx.author = options.author
153
- if (options.company) pptx.company = options.company
154
- pptx.layout = options.layout || 'LAYOUT_16x9'
155
-
156
- for (const slideDef of slides) {
157
- const slide = pptx.addSlide({ sectionTitle: slideDef.sectionTitle })
158
-
159
- // 背景颜色
160
- if (slideDef.background) {
161
- slide.background = { color: parseColor(slideDef.background) }
162
- }
163
-
164
- // 标题
165
- if (slideDef.title !== undefined) {
166
- slide.addText(String(slideDef.title), {
167
- x: 0.5, y: 0.25, w: '90%', h: 1.0,
168
- fontSize: slideDef.titleFontSize || 28,
169
- bold: true,
170
- color: parseColor(slideDef.titleColor, '363636'),
171
- align: slideDef.titleAlign || 'left',
172
- })
173
- }
174
-
175
- // 正文内容
176
- if (slideDef.content !== undefined) {
177
- slide.addText(String(slideDef.content), {
178
- x: 0.5, y: 1.5, w: '90%', h: 4.0,
179
- fontSize: slideDef.contentFontSize || 18,
180
- color: parseColor(slideDef.contentColor, '444444'),
181
- align: slideDef.contentAlign || 'left',
182
- valign: 'top',
183
- wrap: true,
184
- })
185
- }
186
-
187
- // 备注
188
- if (slideDef.notes) {
189
- slide.addNotes(String(slideDef.notes))
190
- }
191
-
192
- // 自定义 items
193
- for (const item of (slideDef.items || [])) {
194
- const x = item.x !== undefined ? item.x : 0.5
195
- const y = item.y !== undefined ? item.y : 1.5
196
- const w = item.w || '90%'
197
- const h = item.h || 1.5
198
-
199
- switch (item.type) {
200
- case 'text':
201
- slide.addText(String(item.text || ''), {
202
- x, y, w, h,
203
- fontSize: item.fontSize || 16,
204
- bold: item.bold || false,
205
- italic: item.italic || false,
206
- underline: item.underline ? { style: 'sng' } : undefined,
207
- color: parseColor(item.color, '000000'),
208
- align: item.align || 'left',
209
- valign: item.valign || 'top',
210
- wrap: true,
211
- })
212
- break
213
-
214
- case 'image':
215
- if (item.path && fs.existsSync(resolvePath(item.path))) {
216
- slide.addImage({ path: resolvePath(item.path), x, y, w, h })
217
- } else if (item.url) {
218
- slide.addImage({ hyperlink: { url: item.url }, x, y, w, h })
219
- }
220
- break
221
-
222
- case 'table': {
223
- if (!Array.isArray(item.rows) || item.rows.length === 0) break
224
- const tableData = item.rows.map((row) =>
225
- (row || []).map((cell) => ({
226
- text: String(cell ?? ''),
227
- options: { fontSize: item.fontSize || 14, align: item.cellAlign || 'left' },
228
- })),
229
- )
230
- slide.addTable(tableData, {
231
- x, y, w,
232
- colW: item.colWidths,
233
- border: { pt: 0.5, color: 'CFCFCF' },
234
- fill: { color: 'FFFFFF' },
235
- fontFace: 'Arial',
236
- fontSize: item.fontSize || 14,
237
- })
238
- break
239
- }
240
-
241
- case 'shape': {
242
- const shapeType = item.shapeType || pptx.ShapeType?.rect || 'rect'
243
- slide.addShape(shapeType, {
244
- x, y, w, h,
245
- fill: { color: parseColor(item.fillColor, 'E8E8E8') },
246
- line: { color: parseColor(item.lineColor, 'AAAAAA'), pt: item.lineWidth || 1 },
247
- })
248
- break
249
- }
250
-
251
- default:
252
- break
253
- }
254
- }
255
- }
256
-
257
- await pptx.writeFile({ fileName: fullOutput })
258
- return ok({ outputPath: fullOutput, slideCount: slides.length })
259
- } catch (error) {
260
- return fail(error, { outputPath })
261
- }
262
- }
263
-
264
- /**
265
- * 向已有 PPTX 末尾追加幻灯片(读取现有文本页 + 新增页后重建)
266
- */
267
- async function appendSlidesToPptx(filePath, newSlides = []) {
268
- try {
269
- const fullPath = resolvePath(filePath)
270
- if (!fs.existsSync(fullPath)) return fail(`File does not exist: ${fullPath}`, { filePath: fullPath })
271
- const existingSlides = extractTextFromPptx(fullPath).map((text) => ({ content: text }))
272
- return await createPptx(filePath, [...existingSlides, ...newSlides])
273
- } catch (error) {
274
- return fail(error, { filePath })
275
- }
276
- }
277
-
278
- /**
279
- * 替换 PPTX 中所有幻灯片的文本(XML 直接替换)
280
- */
281
- async function replacePptxText(filePath, searchText, replaceText) {
282
- try {
283
- const fullPath = resolvePath(filePath)
284
- if (!fs.existsSync(fullPath)) return fail(`File does not exist: ${fullPath}`, { filePath: fullPath })
285
- const zip = new AdmZip(fullPath)
286
- const entries = zip.getEntries().filter((e) => /^ppt\/slides\/slide\d+\.xml$/.test(e.entryName))
287
- let replaceCount = 0
288
- for (const entry of entries) {
289
- let xml = entry.getData().toString('utf8')
290
- const before = xml.split(searchText).length - 1
291
- if (before > 0) {
292
- xml = xml.split(searchText).join(replaceText)
293
- replaceCount += before
294
- zip.updateFile(entry.entryName, Buffer.from(xml, 'utf8'))
295
- }
296
- }
297
- zip.writeZip(fullPath)
298
- return ok({ filePath: fullPath, searchText, replaceText, replaceCount })
299
- } catch (error) {
300
- return fail(error, { filePath, searchText, replaceText })
301
- }
302
- }
303
-
304
- /**
305
- * 合并多个 PPTX 文件(将所有幻灯片的文本提取后重建为新 PPTX)
306
- */
307
- async function mergePptx(inputPaths, outputPath) {
308
- try {
309
- const allSlides = []
310
- for (const inputPath of inputPaths) {
311
- const fullInput = resolvePath(inputPath)
312
- if (!fs.existsSync(fullInput)) return fail(`File does not exist: ${fullInput}`, { filePath: fullInput })
313
- const slides = extractTextFromPptx(fullInput).map((text) => ({ content: text }))
314
- allSlides.push(...slides)
315
- }
316
- return await createPptx(outputPath, allSlides)
317
- } catch (error) {
318
- return fail(error, { outputPath })
319
- }
320
- }
321
-
322
- /**
323
- * 提取 PPTX 中嵌入的图片到指定目录
324
- */
325
- async function extractPptxImages(filePath, outputDir) {
326
- try {
327
- const fullPath = resolvePath(filePath)
328
- const fullOutputDir = resolvePath(outputDir)
329
- if (!fs.existsSync(fullPath)) return fail(`File does not exist: ${fullPath}`, { filePath: fullPath })
330
- fs.ensureDirSync(fullOutputDir)
331
- const zip = new AdmZip(fullPath)
332
- const imageEntries = zip.getEntries().filter((e) =>
333
- /^ppt\/media\//.test(e.entryName) && !e.isDirectory,
334
- )
335
- const files = []
336
- for (const entry of imageEntries) {
337
- const outFile = path.join(fullOutputDir, path.basename(entry.entryName))
338
- fs.writeFileSync(outFile, entry.getData())
339
- files.push(outFile)
340
- }
341
- return ok({ filePath: fullPath, outputDir: fullOutputDir, count: files.length, files })
342
- } catch (error) {
343
- return fail(error, { filePath, outputDir })
344
- }
345
- }
346
-
347
- /**
348
- * 统计 PPTX 各幻灯片字数
349
- */
350
- async function getPptxTextStats(filePath) {
351
- try {
352
- const fullPath = resolvePath(filePath)
353
- if (!fs.existsSync(fullPath)) return fail(`File does not exist: ${fullPath}`, { filePath: fullPath })
354
- const slides = extractTextFromPptx(fullPath)
355
- const stats = slides.map((text, idx) => ({
356
- slide: idx + 1,
357
- wordCount: text.trim().split(/\s+/).filter(Boolean).length,
358
- charCount: text.length,
359
- preview: text.substring(0, 60) + (text.length > 60 ? '...' : ''),
360
- }))
361
- return ok({
362
- filePath: fullPath,
363
- slideCount: slides.length,
364
- totalWordCount: stats.reduce((s, p) => s + p.wordCount, 0),
365
- totalCharCount: stats.reduce((s, p) => s + p.charCount, 0),
366
- slides: stats,
367
- })
368
- } catch (error) {
369
- return fail(error, { filePath })
370
- }
371
- }
372
-
373
- // ─── 工具描述 ─────────────────────────────────────────────────────────────────
374
-
375
-
376
- // ─── 使用说明 ─────────────────────────────────────────────────────────────────
377
-
378
- function pptxReadme() {
379
- return `【PPTX 工具使用说明】
380
- 1. 优先使用本工具内置函数完成任务(信息读取、文本提取、搜索、创建演示文稿、追加幻灯片、文本替换、合并、图片提取等)。
381
- 2. 如果内置函数无法满足需求(如复杂动画保真、特殊版式处理、跨格式高级转换),再尝试使用 LibreOffice 命令行。
382
- 3. 在调用 LibreOffice 前,先检测系统是否已安装 LibreOffice:
383
- - 已安装:直接使用 LibreOffice 命令行继续处理。
384
- - 未安装:询问用户是否允许安装。
385
- 4. 若用户同意安装:引导完成安装后继续执行原任务。
386
- 5. 若用户拒绝安装:明确告知当前能力限制,并终止该操作。
387
-
388
- 建议:
389
- - 常规演示文稿处理优先使用内置函数,速度更快且依赖更少。
390
- - 仅在确实需要高保真格式转换或复杂版式时才启用 LibreOffice 路径。`
391
- }
392
-
393
- const descriptions = [
394
- {
395
- type: 'function',
396
- function: {
397
- name: 'pptxReadme',
398
- description: '获取 PPTX 工具集的使用说明, 调用函数前必须先查看本说明。',
399
- parameters: {},
400
- }
401
- },
402
- {
403
- type: 'function',
404
- function: {
405
- name: 'getPptxInfo',
406
- description: '获取 PPTX 文件的基本信息(幻灯片数、文件大小、标题、创建者等)。参数:filePath 为 .pptx 文件路径。返回值:对象,包含 success、data(含 slideCount、size、mtime、title、creator)、error。',
407
- parameters: {
408
- type: 'object',
409
- properties: {
410
- filePath: { type: 'string', description: 'PPTX 文件路径。' },
411
- },
412
- required: ['filePath'],
413
- },
414
- },
415
- },
416
- {
417
- type: 'function',
418
- function: {
419
- name: 'readPptxText',
420
- description: '提取 PPTX 演示文稿中所有幻灯片的纯文本内容。参数:filePath 为 .pptx 文件路径。返回值:对象,包含 success、data(含 slideCount、slides 数组、text 全文、wordCount)、error。',
421
- parameters: {
422
- type: 'object',
423
- properties: {
424
- filePath: { type: 'string', description: 'PPTX 文件路径。' },
425
- },
426
- required: ['filePath'],
427
- },
428
- },
429
- },
430
- {
431
- type: 'function',
432
- function: {
433
- name: 'searchPptxText',
434
- description: '在 PPTX 中搜索关键词,返回包含该词的幻灯片页码。参数:filePath 为 .pptx 路径;keyword 为搜索关键词。返回值:对象,包含 success、data(含 keyword、matchCount、matches 数组)、error。',
435
- parameters: {
436
- type: 'object',
437
- properties: {
438
- filePath: { type: 'string', description: 'PPTX 文件路径。' },
439
- keyword: { type: 'string', description: '搜索关键词。' },
440
- },
441
- required: ['filePath', 'keyword'],
442
- },
443
- },
444
- },
445
- {
446
- type: 'function',
447
- function: {
448
- name: 'createPptx',
449
- description: `创建新的 PPTX 演示文稿,支持多种内容类型。
450
- 参数:outputPath 为输出路径;slides 为幻灯片数组,每项可含:
451
- title(标题文字)、content(正文文字)、notes(备注)、background(背景色)、
452
- items(自定义元素数组,每项 type: 'text'|'image'|'table'|'shape',含 x/y/w/h 坐标);
453
- options 可选:{ title, subject, author, company, layout }。
454
- 返回值:对象,包含 success、data(含 outputPath、slideCount)、error。`,
455
- parameters: {
456
- type: 'object',
457
- properties: {
458
- outputPath: { type: 'string', description: '输出 .pptx 文件路径。' },
459
- slides: { type: 'array', description: '幻灯片定义数组。', items: { type: 'object' } },
460
- options: { type: 'object', description: '可选:{ title, subject, author, company, layout }。' },
461
- },
462
- required: ['outputPath'],
463
- },
464
- },
465
- },
466
- {
467
- type: 'function',
468
- function: {
469
- name: 'appendSlidesToPptx',
470
- description: '向已有 PPTX 末尾追加新幻灯片。参数:filePath 为目标 .pptx 路径;newSlides 为要追加的幻灯片数组(格式同 createPptx 的 slides)。返回值:对象,包含 success、data(含 outputPath、slideCount)、error。',
471
- parameters: {
472
- type: 'object',
473
- properties: {
474
- filePath: { type: 'string', description: '目标 PPTX 文件路径。' },
475
- newSlides: { type: 'array', description: '要追加的幻灯片数组。', items: { type: 'object' } },
476
- },
477
- required: ['filePath', 'newSlides'],
478
- },
479
- },
480
- },
481
- {
482
- type: 'function',
483
- function: {
484
- name: 'replacePptxText',
485
- description: '替换 PPTX 所有幻灯片中的指定文本。参数:filePath 为 .pptx 路径;searchText 为查找文本;replaceText 为替换文本。返回值:对象,包含 success、data(含 filePath、replaceCount)、error。',
486
- parameters: {
487
- type: 'object',
488
- properties: {
489
- filePath: { type: 'string', description: '目标 PPTX 文件路径。' },
490
- searchText: { type: 'string', description: '要查找的文本。' },
491
- replaceText: { type: 'string', description: '替换后的文本。' },
492
- },
493
- required: ['filePath', 'searchText', 'replaceText'],
494
- },
495
- },
496
- },
497
- {
498
- type: 'function',
499
- function: {
500
- name: 'mergePptx',
501
- description: '将多个 PPTX 文件合并为一个(按顺序合并所有幻灯片)。参数:inputPaths 为源文件路径数组;outputPath 为输出路径。返回值:对象,包含 success、data(含 outputPath、slideCount)、error。',
502
- parameters: {
503
- type: 'object',
504
- properties: {
505
- inputPaths: { type: 'array', items: { type: 'string' }, description: '要合并的 PPTX 文件路径数组。' },
506
- outputPath: { type: 'string', description: '合并后输出的 PPTX 文件路径。' },
507
- },
508
- required: ['inputPaths', 'outputPath'],
509
- },
510
- },
511
- },
512
- {
513
- type: 'function',
514
- function: {
515
- name: 'extractPptxImages',
516
- description: '提取 PPTX 中所有嵌入的图片到指定目录。参数:filePath 为 .pptx 路径;outputDir 为输出目录。返回值:对象,包含 success、data(含 outputDir、count、files 数组)、error。',
517
- parameters: {
518
- type: 'object',
519
- properties: {
520
- filePath: { type: 'string', description: 'PPTX 文件路径。' },
521
- outputDir: { type: 'string', description: '图片输出目录。' },
522
- },
523
- required: ['filePath', 'outputDir'],
524
- },
525
- },
526
- },
527
- {
528
- type: 'function',
529
- function: {
530
- name: 'getPptxTextStats',
531
- description: '统计 PPTX 各幻灯片的字数与字符数。参数:filePath 为 .pptx 路径。返回值:对象,包含 success、data(含 slideCount、totalWordCount、totalCharCount、slides 统计数组)、error。',
532
- parameters: {
533
- type: 'object',
534
- properties: {
535
- filePath: { type: 'string', description: 'PPTX 文件路径。' },
536
- },
537
- required: ['filePath'],
538
- },
539
- },
540
- },
541
- ]
542
-
543
- // ─── 导出 ──────────────────────────────────────────────────────────────────────
544
-
545
- const functions = {
546
- pptxReadme,
547
- getPptxInfo,
548
- readPptxText,
549
- searchPptxText,
550
- createPptx,
551
- appendSlidesToPptx,
552
- replacePptxText,
553
- mergePptx,
554
- extractPptxImages,
555
- getPptxTextStats,
556
- }
557
-
558
- const PptxTool = {
559
- name: 'PptxTool',
560
- description: '提供 PowerPoint(.pptx)文件的信息读取、文本提取、搜索、创建演示文稿(含文本/图片/表格/形状)、追加幻灯片、文本替换、合并、图片提取等全面处理能力',
561
- platform: 'all',
562
- descriptions,
563
- functions,
564
- isSystem: true
565
- }
566
-
567
- module.exports = PptxTool
@@ -1,36 +0,0 @@
1
- function videoReadme() {
2
- return `【VIDEO 工具使用说明】
3
- 1. 优先尝试使用 FFmpeg 命令行。
4
- 3. 在调用 FFmpeg 前,先检测系统是否已安装 FFmpeg:
5
- - 已安装:直接使用 FFmpeg 命令行继续处理。
6
- - 未安装:询问用户是否允许安装。
7
- 4. 若用户同意安装:引导完成安装后继续执行原任务。
8
- 5. 若用户拒绝安装:明确告知当前能力限制,并终止该操作。`
9
- }
10
-
11
- const descriptions = [
12
- {
13
- type: 'function',
14
- function: {
15
- name: 'videoReadme',
16
- description: '获取 VIDEO 工具集的使用说明, 在处理音频、视频文件前必须先查看本说明。',
17
- parameters: {},
18
- },
19
- },
20
- ]
21
-
22
- const functions = {
23
- videoReadme,
24
- }
25
-
26
- const VideoTool = {
27
- name: 'VideoTool',
28
- description: '提供音频、视频处理能力说明',
29
- platform: 'all',
30
- descriptions,
31
- functions,
32
- isSystem: true
33
- }
34
-
35
- module.exports = VideoTool
36
-