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,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
-