onbuzz 4.9.13 → 4.10.0
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/node_modules/glob/README.md +31 -5
- package/node_modules/glob/dist/commonjs/glob.d.ts +8 -0
- package/node_modules/glob/dist/commonjs/glob.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/glob.js +2 -1
- package/node_modules/glob/dist/commonjs/glob.js.map +1 -1
- package/node_modules/glob/dist/commonjs/index.min.js +3 -3
- package/node_modules/glob/dist/commonjs/index.min.js.map +4 -4
- package/node_modules/glob/dist/commonjs/pattern.d.ts +3 -0
- package/node_modules/glob/dist/commonjs/pattern.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/pattern.js +4 -0
- package/node_modules/glob/dist/commonjs/pattern.js.map +1 -1
- package/node_modules/glob/dist/esm/glob.d.ts +8 -0
- package/node_modules/glob/dist/esm/glob.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/glob.js +2 -1
- package/node_modules/glob/dist/esm/glob.js.map +1 -1
- package/node_modules/glob/dist/esm/index.min.js +3 -3
- package/node_modules/glob/dist/esm/index.min.js.map +4 -4
- package/node_modules/glob/dist/esm/pattern.d.ts +3 -0
- package/node_modules/glob/dist/esm/pattern.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/pattern.js +4 -0
- package/node_modules/glob/dist/esm/pattern.js.map +1 -1
- package/node_modules/{@isaacs → glob/node_modules}/balanced-match/README.md +7 -10
- package/node_modules/{@isaacs → glob/node_modules}/balanced-match/package.json +7 -18
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/README.md +3 -6
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.js +6 -4
- package/node_modules/glob/node_modules/brace-expansion/dist/commonjs/index.js.map +1 -0
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.js +6 -4
- package/node_modules/glob/node_modules/brace-expansion/dist/esm/index.js.map +1 -0
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/package.json +11 -7
- package/node_modules/glob/node_modules/minimatch/README.md +76 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts +4 -2
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js +309 -55
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js +2 -4
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js +4 -4
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts +81 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js +232 -134
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js +8 -8
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts +4 -2
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js +309 -55
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js +2 -4
- package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js +4 -4
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts +81 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.js +232 -134
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js +8 -8
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/package.json +17 -11
- package/node_modules/glob/package.json +10 -13
- package/node_modules/minipass/LICENSE.md +55 -0
- package/node_modules/minipass/dist/commonjs/index.d.ts +12 -16
- package/node_modules/minipass/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/minipass/dist/commonjs/index.js +13 -3
- package/node_modules/minipass/dist/commonjs/index.js.map +1 -1
- package/node_modules/minipass/dist/esm/index.d.ts +12 -16
- package/node_modules/minipass/dist/esm/index.d.ts.map +1 -1
- package/node_modules/minipass/dist/esm/index.js +3 -1
- package/node_modules/minipass/dist/esm/index.js.map +1 -1
- package/node_modules/minipass/package.json +9 -14
- package/node_modules/path-scurry/node_modules/lru-cache/README.md +96 -10
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.cjs.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts +109 -32
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js +334 -197
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js.map +4 -4
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +4 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.mjs.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.js +19 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts +109 -32
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js +333 -196
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js.map +4 -4
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +6 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/package.json +71 -18
- package/node_modules/path-scurry/package.json +8 -24
- package/package.json +1 -1
- package/scripts/debug-balance-probe.mjs +35 -35
- package/scripts/push-image.sh +43 -43
- package/scripts/setup-acr.sh +65 -65
- package/scripts/verify-optional-deps.js +96 -1
- package/src/__tests__/composioCliFlags.test.js +239 -239
- package/src/analyzers/CSSAnalyzer.js +298 -297
- package/src/analyzers/ConfigValidator.js +691 -690
- package/src/analyzers/ESLintAnalyzer.js +320 -320
- package/src/analyzers/JavaScriptAnalyzer.js +260 -261
- package/src/analyzers/PrettierFormatter.js +246 -247
- package/src/analyzers/PythonAnalyzer.js +283 -283
- package/src/analyzers/SecurityAnalyzer.js +729 -729
- package/src/analyzers/SparrowAnalyzer.js +341 -341
- package/src/analyzers/TypeScriptAnalyzer.js +247 -247
- package/src/analyzers/__tests__/CSSAnalyzer.test.js +41 -41
- package/src/analyzers/__tests__/ConfigValidator.test.js +362 -362
- package/src/analyzers/__tests__/JavaScriptAnalyzer.test.js +40 -40
- package/src/analyzers/__tests__/PythonAnalyzer.test.js +205 -208
- package/src/analyzers/__tests__/SecurityAnalyzer.test.js +303 -303
- package/src/analyzers/__tests__/TypeScriptAnalyzer.test.js +187 -187
- package/src/analyzers/codeCloneDetector/analyzer.js +344 -344
- package/src/analyzers/codeCloneDetector/detector.js +250 -250
- package/src/analyzers/codeCloneDetector/index.js +194 -192
- package/src/analyzers/codeCloneDetector/parser.js +199 -199
- package/src/core/__tests__/agentPool.test.js +866 -866
- package/src/core/__tests__/agentPoolAutoResume.test.js +209 -209
- package/src/core/__tests__/agentPoolWakeOnMessage.test.js +315 -315
- package/src/core/__tests__/agentScheduler.emptyResponseChatStall.test.js +213 -213
- package/src/core/__tests__/agentScheduler.errorCategorisation.test.js +246 -246
- package/src/core/__tests__/agentScheduler.firstChunkTimeout.test.js +138 -138
- package/src/core/__tests__/agentScheduler.modeTransitions.test.js +233 -233
- package/src/core/__tests__/agentScheduler.nativePromptPick.test.js +319 -319
- package/src/core/__tests__/agentScheduler.taskLifecycleInstruction.test.js +78 -78
- package/src/core/__tests__/agentScheduler.visualizer.test.js +258 -258
- package/src/core/__tests__/flowCheckpointStore.test.js +140 -140
- package/src/core/__tests__/flowEndToEnd.test.js +565 -565
- package/src/core/__tests__/flowFieldMapping.test.js +188 -189
- package/src/core/__tests__/flowLintClientMirror.test.js +96 -98
- package/src/core/__tests__/flowSavePayload.test.js +170 -169
- package/src/core/__tests__/flowTemplates.test.js +311 -311
- package/src/core/__tests__/flowVersionStore.test.js +123 -123
- package/src/core/__tests__/messageProcessor.test.js +669 -669
- package/src/core/__tests__/stateManager.test.js +0 -1
- package/src/core/agentPool.js +2474 -2475
- package/src/core/agentScheduler.js +1 -4
- package/src/core/contextManager.js +708 -708
- package/src/core/flowExecutor.js +1510 -1510
- package/src/core/flowFieldMapping.js +136 -138
- package/src/core/messageProcessor.js +953 -954
- package/src/core/orchestrator.js +593 -595
- package/src/core/stateManager.js +1765 -1752
- package/src/index.js +1221 -1221
- package/src/interfaces/__tests__/archivedAgentDelete.test.js +207 -207
- package/src/interfaces/__tests__/bulkAgentRoute.test.js +361 -361
- package/src/interfaces/__tests__/imageServing.test.js +228 -228
- package/src/interfaces/__tests__/remoteSessionAuth.test.js +308 -308
- package/src/interfaces/__tests__/videoJobsRoutes.test.js +178 -179
- package/src/interfaces/__tests__/webServer.marketplace.test.js +629 -629
- package/src/interfaces/schedulerRoutes.js +50 -50
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +341 -350
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +156 -156
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +325 -330
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +385 -388
- package/src/interfaces/terminal/api/session.js +265 -266
- package/src/interfaces/terminal/api/websocket.js +496 -497
- package/src/interfaces/terminal/components/AgentCreator.js +691 -705
- package/src/interfaces/terminal/components/AgentEditor.js +676 -678
- package/src/interfaces/terminal/components/AgentSwitcher.js +331 -330
- package/src/interfaces/terminal/components/ErrorPanel.js +263 -264
- package/src/interfaces/terminal/components/Header.js +28 -28
- package/src/interfaces/terminal/components/Layout.js +598 -603
- package/src/interfaces/terminal/components/MessageList.js +280 -281
- package/src/interfaces/terminal/components/SettingsPanel.js +410 -415
- package/src/interfaces/terminal/components/StatusBar.js +2 -0
- package/src/interfaces/terminal/index.js +168 -168
- package/src/interfaces/terminal/state/useAgentControl.js +496 -496
- package/src/interfaces/terminal/state/useAgents.js +537 -537
- package/src/interfaces/terminal/state/useMessages.js +629 -630
- package/src/interfaces/terminal/state/useTools.js +554 -554
- package/src/interfaces/terminal/utils/debugLogger.js +44 -44
- package/src/interfaces/terminal/utils/settingsStorage.js +232 -232
- package/src/interfaces/webServer.js +7578 -7579
- package/src/interfaces/webServer.js.bak +7046 -7046
- package/src/modules/fileExplorer/__tests__/zipDownload.test.js +237 -237
- package/src/modules/fileExplorer/controller.js +470 -469
- package/src/modules/fileExplorer/routes.js +285 -286
- package/src/modules/widget/__tests__/isDisabled.test.js +41 -41
- package/src/modules/widget/__tests__/routes.test.js +677 -678
- package/src/modules/widget/__tests__/runtime.test.js +401 -401
- package/src/modules/widget/__tests__/versioning.test.js +309 -309
- package/src/modules/widget/__tests__/webComponentRuntime.test.js +565 -565
- package/src/modules/widget/__tests__/widgetTool.test.js +316 -316
- package/src/modules/widget/routes.js +435 -435
- package/src/modules/widget/runtime/bundle.js +640 -640
- package/src/modules/widget/runtime/webComponentBundle.js +470 -470
- package/src/modules/widget/schema.js +182 -181
- package/src/modules/widget/widgetTool.js +1389 -1389
- package/src/services/__tests__/agentActivityService.test.js +401 -402
- package/src/services/__tests__/benchmarkService.test.js +184 -184
- package/src/services/__tests__/contextInjectionService.test.js +246 -246
- package/src/services/__tests__/conversationQuery.test.js +721 -723
- package/src/services/__tests__/credentialVault.test.js +469 -469
- package/src/services/__tests__/discordService.integration.test.js +638 -639
- package/src/services/__tests__/flowContextService.test.js +590 -590
- package/src/services/__tests__/memoryService.test.js +1 -1
- package/src/services/__tests__/messageSource.test.js +380 -380
- package/src/services/__tests__/modelRouterNaming.test.js +111 -111
- package/src/services/__tests__/projectDetector.test.js +34 -34
- package/src/services/__tests__/promptService.test.js +242 -242
- package/src/services/__tests__/telegramService.test.js +941 -941
- package/src/services/__tests__/tokenCountingService.test.js +48 -48
- package/src/services/agentActivityService.js +419 -420
- package/src/services/aiService.js +2997 -3001
- package/src/services/apiKeyManager.js +359 -359
- package/src/services/benchmarkService.js +196 -196
- package/src/services/codebaseKnowledgeService.js +2 -2
- package/src/services/composioService.js +738 -738
- package/src/services/conversationCompactionService.js +1258 -1257
- package/src/services/credentialVault.js +685 -685
- package/src/services/discordService.js +792 -793
- package/src/services/embeddings/__tests__/azureCustomProvider.test.js +232 -232
- package/src/services/embeddings/__tests__/embeddingService.test.js +417 -417
- package/src/services/embeddings/__tests__/localProvider.test.js +263 -263
- package/src/services/embeddings/autoRecall.js +218 -219
- package/src/services/embeddings/indexers/__tests__/agentIndexer.test.js +232 -232
- package/src/services/embeddings/indexers/__tests__/memoryIndexer.test.js +418 -418
- package/src/services/embeddings/indexers/__tests__/reminisceIndexer.test.js +356 -357
- package/src/services/embeddings/indexers/__tests__/skillsIndexer.test.js +145 -145
- package/src/services/embeddings/indexers/__tests__/taskIndexer.test.js +146 -146
- package/src/services/embeddings/indexers/composioIndexer.js +279 -279
- package/src/services/embeddings/providerInterface.js +206 -206
- package/src/services/embeddings/providers/localProvider.js +11 -7
- package/src/services/embeddings/providers/openaiProvider.js +101 -101
- package/src/services/embeddings/vectorStore/inMemoryJsonStore.js +356 -356
- package/src/services/errorHandler.js +809 -809
- package/src/services/flowContextService.js +586 -586
- package/src/services/grounding/MockAdapter.js +125 -125
- package/src/services/modelRouterService.js +26 -31
- package/src/services/modelsService.js +322 -322
- package/src/services/ollamaService.js +452 -452
- package/src/services/projectDetector.js +403 -404
- package/src/services/promptService.js +418 -418
- package/src/services/qualityInspector.js +795 -795
- package/src/services/scheduleService.js +726 -726
- package/src/services/serviceRegistry.js +386 -386
- package/src/services/telegrafBot.js +174 -174
- package/src/services/telegramService.js +1972 -1972
- package/src/services/visualEditorBridge.js +1033 -1033
- package/src/services/visualEditorServer.js +1769 -1774
- package/src/services/whatsappService.js +667 -668
- package/src/tools/__tests__/agentCommunicationTool.findAgent.test.js +226 -226
- package/src/tools/__tests__/agentCommunicationTool.test.js +3 -3
- package/src/tools/__tests__/agentDelayTool.test.js +342 -342
- package/src/tools/__tests__/baseTool.test.js +3 -3
- package/src/tools/__tests__/codeMapTool.test.js +915 -915
- package/src/tools/__tests__/fileContentReplaceTool.test.js +309 -309
- package/src/tools/__tests__/fileTreeTool.test.js +274 -274
- package/src/tools/__tests__/filesystemTool.test.js +815 -815
- package/src/tools/__tests__/foundryWebSearchTool.test.js +252 -252
- package/src/tools/__tests__/imageTool.validator.test.js +194 -194
- package/src/tools/__tests__/jobDoneTool.test.js +580 -581
- package/src/tools/__tests__/memoryTool.forgetStale.test.js +272 -272
- package/src/tools/__tests__/memoryTool.reminisce.test.js +2 -2
- package/src/tools/__tests__/memoryTool.reminisceSemanticSearch.test.js +301 -301
- package/src/tools/__tests__/memoryTool.semanticSearch.test.js +405 -405
- package/src/tools/__tests__/memoryTool.teamPool.test.js +293 -293
- package/src/tools/__tests__/memoryTool.test.js +1 -1
- package/src/tools/__tests__/seekTool.test.js +282 -282
- package/src/tools/__tests__/skillsTool.search.test.js +164 -164
- package/src/tools/__tests__/skillsTool.test.js +226 -226
- package/src/tools/__tests__/staticAnalysisTool.test.js +509 -509
- package/src/tools/__tests__/taskManagerTool.discipline.test.js +137 -137
- package/src/tools/__tests__/taskManagerTool.search.test.js +143 -143
- package/src/tools/__tests__/taskManagerTool.test.js +866 -866
- package/src/tools/__tests__/terminalTool.test.js +448 -448
- package/src/tools/__tests__/toolShapeForgiveness.test.js +259 -260
- package/src/tools/__tests__/userPromptTool.test.js +297 -297
- package/src/tools/__tests__/videoTool.jobs.test.js +147 -147
- package/src/tools/__tests__/webTool.e2e.test.js +609 -603
- package/src/tools/__tests__/webTool.unit.test.js +195 -195
- package/src/tools/__tests__/webTool.visionModel.test.js +75 -75
- package/src/tools/agentCommunicationTool.js +8 -10
- package/src/tools/agentDelayTool.js +496 -497
- package/src/tools/asyncToolManager.js +602 -603
- package/src/tools/baseTool.js +12 -11
- package/src/tools/cloneDetectionTool.js +576 -581
- package/src/tools/codeMapTool.js +0 -6
- package/src/tools/composioTool.js +617 -617
- package/src/tools/dependencyResolverTool.js +1211 -1212
- package/src/tools/desktop/DesktopTool.js +629 -638
- package/src/tools/desktop/__tests__/DesktopTool.e2e.test.js +306 -306
- package/src/tools/desktop/__tests__/DesktopTool.test.js +507 -507
- package/src/tools/desktop/__tests__/osController.test.js +364 -364
- package/src/tools/desktop/osController.js +491 -491
- package/src/tools/docxTool.js +623 -623
- package/src/tools/excelTool.js +636 -636
- package/src/tools/fileContentReplaceTool.js +5 -7
- package/src/tools/fileSystemTool.js +12 -19
- package/src/tools/fileTreeTool.js +840 -840
- package/src/tools/foundryWebSearchTool.js +273 -273
- package/src/tools/helpTool.js +198 -198
- package/src/tools/imageTool.js +1397 -1397
- package/src/tools/importAnalyzerTool.js +1056 -1056
- package/src/tools/jobDoneTool.js +495 -495
- package/src/tools/memoryTool.js +1 -1
- package/src/tools/office/pres/__tests__/presSystem.test.js +365 -365
- package/src/tools/office/pres/archetypes/agenda.js +61 -61
- package/src/tools/office/pres/archetypes/bentoGrid.js +218 -219
- package/src/tools/office/pres/archetypes/bigStat.js +140 -142
- package/src/tools/office/pres/archetypes/closing.js +70 -70
- package/src/tools/office/pres/archetypes/hero.js +70 -70
- package/src/tools/office/pres/archetypes/productHero.js +93 -94
- package/src/tools/office/pres/archetypes/table.js +73 -74
- package/src/tools/office/pres/backgrounds/orb.js +66 -66
- package/src/tools/office/pres/components.js +422 -423
- package/src/tools/officeTool.js +441 -441
- package/src/tools/pdfTool.js +625 -627
- package/src/tools/platformControlTool.js +1081 -1081
- package/src/tools/seekTool.js +917 -918
- package/src/tools/skillsTool.js +1 -1
- package/src/tools/staticAnalysisTool.js +2143 -2146
- package/src/tools/taskManagerTool.js +3324 -3324
- package/src/tools/terminalTool.js +2615 -2618
- package/src/tools/videoTool.js +1303 -1303
- package/src/tools/visionTool.js +508 -508
- package/src/tools/visualEditorTool.js +1289 -1290
- package/src/tools/webTool.js +3368 -3368
- package/src/tools/whatsappTool.js +464 -464
- package/src/types/__tests__/agent.test.js +499 -499
- package/src/types/__tests__/contextReference.test.js +606 -606
- package/src/types/__tests__/conversation.test.js +555 -555
- package/src/types/__tests__/toolCommand.test.js +584 -584
- package/src/types/contextReference.js +974 -971
- package/src/types/conversation.js +729 -729
- package/src/types/toolCommand.js +746 -746
- package/src/utilities/__tests__/attachmentValidator.test.js +80 -80
- package/src/utilities/__tests__/auditReport.test.js +328 -328
- package/src/utilities/__tests__/directoryAccessManager.test.js +388 -388
- package/src/utilities/__tests__/jsonRepair.test.js +103 -104
- package/src/utilities/__tests__/modeTransitionReasons.test.js +105 -105
- package/src/utilities/__tests__/platformUtils.test.js +80 -87
- package/src/utilities/__tests__/structuredFileValidator.test.js +261 -263
- package/src/utilities/__tests__/toolConstants.test.js +92 -94
- package/src/utilities/__tests__/useIsTouchDevice.detect.test.js +114 -114
- package/src/utilities/__tests__/webUiUtilSync.test.js +117 -117
- package/src/utilities/attachmentValidator.js +284 -288
- package/src/utilities/authCache.js.backup-1779570472481 +121 -121
- package/src/utilities/browserStealth.js +631 -630
- package/src/utilities/configManager.js +616 -617
- package/src/utilities/directoryAccessManager.js +564 -565
- package/src/utilities/fileProcessor.js +308 -307
- package/src/utilities/humanBehavior.js +454 -453
- package/src/utilities/logger.js +479 -479
- package/src/utilities/structuredFileValidator.js +696 -699
- package/src/utilities/tagParser.js +5 -10
- package/src/utilities/userDataDir.js +308 -308
- package/node_modules/@isaacs/brace-expansion/dist/commonjs/index.js.map +0 -1
- package/node_modules/@isaacs/brace-expansion/dist/esm/index.js.map +0 -1
- package/node_modules/minipass/LICENSE +0 -15
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/LICENSE.md +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.js +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.js.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/package.json +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.js +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.js.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/package.json +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/LICENSE +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/package.json +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/package.json +0 -0
package/src/tools/docxTool.js
CHANGED
|
@@ -1,623 +1,623 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Document (DOCX) Tool - Read and create Word documents
|
|
3
|
-
*
|
|
4
|
-
* Purpose:
|
|
5
|
-
* - Get document metadata and word count
|
|
6
|
-
* - Extract text or HTML from DOCX files
|
|
7
|
-
* - Create DOCX documents from structured JSON content
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { BaseTool } from './baseTool.js';
|
|
11
|
-
import TagParser from '../utilities/tagParser.js';
|
|
12
|
-
import fs from 'fs/promises';
|
|
13
|
-
import path from 'path';
|
|
14
|
-
|
|
15
|
-
// Lazy-loaded dependencies
|
|
16
|
-
let docxModule = null;
|
|
17
|
-
let mammothModule = null;
|
|
18
|
-
|
|
19
|
-
class DocxTool extends BaseTool {
|
|
20
|
-
constructor(config = {}, logger = null) {
|
|
21
|
-
super(config, logger);
|
|
22
|
-
this.id = 'doc';
|
|
23
|
-
this.name = 'Document Tool';
|
|
24
|
-
this.description = 'Read and create Word (DOCX) documents';
|
|
25
|
-
this.version = '1.0.0';
|
|
26
|
-
this.requiresProject = false;
|
|
27
|
-
this.isAsync = false;
|
|
28
|
-
this.docxLoaded = false;
|
|
29
|
-
this.docxError = null;
|
|
30
|
-
this.mammothLoaded = false;
|
|
31
|
-
this.mammothError = null;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Lazily load the docx module (for creation)
|
|
36
|
-
* @returns {Promise<boolean>}
|
|
37
|
-
*/
|
|
38
|
-
async loadDocx() {
|
|
39
|
-
if (this.docxLoaded) return true;
|
|
40
|
-
if (this.docxError) return false;
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
docxModule = await import('docx');
|
|
44
|
-
this.docxLoaded = true;
|
|
45
|
-
return true;
|
|
46
|
-
} catch (error) {
|
|
47
|
-
this.docxError = error.message;
|
|
48
|
-
this.logger?.error('Failed to load docx module', { error: error.message });
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Lazily load the mammoth module (for reading)
|
|
55
|
-
* @returns {Promise<boolean>}
|
|
56
|
-
*/
|
|
57
|
-
async loadMammoth() {
|
|
58
|
-
if (this.mammothLoaded) return true;
|
|
59
|
-
if (this.mammothError) return false;
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
const mod = await import('mammoth');
|
|
63
|
-
mammothModule = mod.default || mod;
|
|
64
|
-
this.mammothLoaded = true;
|
|
65
|
-
return true;
|
|
66
|
-
} catch (error) {
|
|
67
|
-
this.mammothError = error.message;
|
|
68
|
-
this.logger?.error('Failed to load mammoth module', { error: error.message });
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Get tool description for LLM consumption
|
|
75
|
-
* @returns {string}
|
|
76
|
-
*/
|
|
77
|
-
getDescription() {
|
|
78
|
-
return `
|
|
79
|
-
Document Tool: Read and create Word (DOCX) documents.
|
|
80
|
-
|
|
81
|
-
USAGE:
|
|
82
|
-
\`\`\`json
|
|
83
|
-
{
|
|
84
|
-
"toolId": "doc",
|
|
85
|
-
"actions": [{
|
|
86
|
-
"action": "get-info",
|
|
87
|
-
"filePath": "documents/report.docx"
|
|
88
|
-
}]
|
|
89
|
-
}
|
|
90
|
-
\`\`\`
|
|
91
|
-
|
|
92
|
-
ACTIONS:
|
|
93
|
-
|
|
94
|
-
1. **get-info** - Get document metadata and word count
|
|
95
|
-
- filePath: Path to DOCX file (required)
|
|
96
|
-
|
|
97
|
-
2. **read** - Extract text or HTML content from a DOCX file
|
|
98
|
-
- filePath: Path to DOCX file (required)
|
|
99
|
-
- format: "text" (default) or "html"
|
|
100
|
-
|
|
101
|
-
3. **create** - Create a new DOCX document from structured content
|
|
102
|
-
- outputPath: Output file path (required)
|
|
103
|
-
- content: Document content object (required):
|
|
104
|
-
- title: Document title (optional)
|
|
105
|
-
- author: Document author (optional)
|
|
106
|
-
- sections: Array of sections, each with:
|
|
107
|
-
- children: Array of content elements:
|
|
108
|
-
- { type: "heading", level: 1-6, text: "..." }
|
|
109
|
-
- { type: "paragraph", text: "...", bold: false, italic: false, fontSize: 24, alignment: "left" }
|
|
110
|
-
- { type: "table", headers: ["Col1", "Col2"], rows: [["val1", "val2"]], widths: [50, 50] }
|
|
111
|
-
- { type: "list", ordered: false, items: ["Item 1", "Item 2"] }
|
|
112
|
-
- { type: "pageBreak" }
|
|
113
|
-
|
|
114
|
-
EXAMPLES:
|
|
115
|
-
|
|
116
|
-
1. Get document info:
|
|
117
|
-
\`\`\`json
|
|
118
|
-
{
|
|
119
|
-
"toolId": "doc",
|
|
120
|
-
"actions": [{
|
|
121
|
-
"action": "get-info",
|
|
122
|
-
"filePath": "documents/report.docx"
|
|
123
|
-
}]
|
|
124
|
-
}
|
|
125
|
-
\`\`\`
|
|
126
|
-
|
|
127
|
-
2. Read document as text:
|
|
128
|
-
\`\`\`json
|
|
129
|
-
{
|
|
130
|
-
"toolId": "doc",
|
|
131
|
-
"actions": [{
|
|
132
|
-
"action": "read",
|
|
133
|
-
"filePath": "documents/report.docx",
|
|
134
|
-
"format": "text"
|
|
135
|
-
}]
|
|
136
|
-
}
|
|
137
|
-
\`\`\`
|
|
138
|
-
|
|
139
|
-
3. Create a document:
|
|
140
|
-
\`\`\`json
|
|
141
|
-
{
|
|
142
|
-
"toolId": "doc",
|
|
143
|
-
"actions": [{
|
|
144
|
-
"action": "create",
|
|
145
|
-
"outputPath": "output/report.docx",
|
|
146
|
-
"content": {
|
|
147
|
-
"title": "Project Report",
|
|
148
|
-
"author": "Loxia Agent",
|
|
149
|
-
"sections": [{
|
|
150
|
-
"children": [
|
|
151
|
-
{ "type": "heading", "level": 1, "text": "Introduction" },
|
|
152
|
-
{ "type": "paragraph", "text": "This is the introduction paragraph." },
|
|
153
|
-
{ "type": "heading", "level": 2, "text": "Data Summary" },
|
|
154
|
-
{ "type": "table", "headers": ["Metric", "Value"], "rows": [["Users", "1000"], ["Revenue", "$50K"]] },
|
|
155
|
-
{ "type": "list", "ordered": true, "items": ["First point", "Second point", "Third point"] }
|
|
156
|
-
]
|
|
157
|
-
}]
|
|
158
|
-
}
|
|
159
|
-
}]
|
|
160
|
-
}
|
|
161
|
-
\`\`\`
|
|
162
|
-
|
|
163
|
-
NOTES:
|
|
164
|
-
- For reading, mammoth provides clean text/HTML extraction
|
|
165
|
-
- For creation, the docx package supports rich formatting
|
|
166
|
-
- fontSize is in half-points (24 = 12pt, 28 = 14pt, etc.)
|
|
167
|
-
- alignment options: "left", "center", "right", "justified"
|
|
168
|
-
- Table widths are percentages that should sum to 100
|
|
169
|
-
`.trim();
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Parse parameters from tool command content
|
|
174
|
-
* @param {string} content
|
|
175
|
-
* @returns {Object}
|
|
176
|
-
*/
|
|
177
|
-
parseParameters(content) {
|
|
178
|
-
try {
|
|
179
|
-
const actionMatches = TagParser.extractContent(content, 'action');
|
|
180
|
-
const filePathMatches = TagParser.extractContent(content, 'filePath');
|
|
181
|
-
const formatMatches = TagParser.extractContent(content, 'format');
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
actions: [{
|
|
185
|
-
action: actionMatches.length > 0 ? actionMatches[0].trim() : 'get-info',
|
|
186
|
-
filePath: filePathMatches.length > 0 ? filePathMatches[0].trim() : '',
|
|
187
|
-
format: formatMatches.length > 0 ? formatMatches[0].trim() : 'text'
|
|
188
|
-
}]
|
|
189
|
-
};
|
|
190
|
-
} catch (error) {
|
|
191
|
-
throw new Error(`Failed to parse Document tool parameters: ${error.message}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Get supported actions
|
|
197
|
-
* @returns {Array<string>}
|
|
198
|
-
*/
|
|
199
|
-
getSupportedActions() {
|
|
200
|
-
return ['get-info', 'read', 'create'];
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Execute document tool action
|
|
205
|
-
* @param {Object} params
|
|
206
|
-
* @param {Object} context
|
|
207
|
-
* @returns {Promise<Object>}
|
|
208
|
-
*/
|
|
209
|
-
async execute(params, context) {
|
|
210
|
-
const { actions } = params;
|
|
211
|
-
|
|
212
|
-
if (!actions || actions.length === 0) {
|
|
213
|
-
return {
|
|
214
|
-
success: false,
|
|
215
|
-
error: 'No actions provided',
|
|
216
|
-
output: 'Please specify an action (get-info, read, or create)'
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const action = actions[0];
|
|
221
|
-
|
|
222
|
-
// Handle create action (no existing file required)
|
|
223
|
-
if (action.action === 'create') {
|
|
224
|
-
try {
|
|
225
|
-
return await this.createDocument(action, context);
|
|
226
|
-
} catch (error) {
|
|
227
|
-
this.logger?.error('DOCX creation error', { error: error.message });
|
|
228
|
-
return {
|
|
229
|
-
success: false,
|
|
230
|
-
error: error.message,
|
|
231
|
-
output: `Failed to create document: ${error.message}`
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Read-oriented actions require file path
|
|
237
|
-
const { projectDir } = context;
|
|
238
|
-
let filePath = action.filePath;
|
|
239
|
-
|
|
240
|
-
if (!filePath) {
|
|
241
|
-
return {
|
|
242
|
-
success: false,
|
|
243
|
-
error: 'File path is required',
|
|
244
|
-
output: 'Please provide a filePath parameter'
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (!path.isAbsolute(filePath)) {
|
|
249
|
-
filePath = path.resolve(projectDir || process.cwd(), filePath);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Check file exists
|
|
253
|
-
try {
|
|
254
|
-
await fs.access(filePath);
|
|
255
|
-
} catch {
|
|
256
|
-
return {
|
|
257
|
-
success: false,
|
|
258
|
-
error: `File not found: ${filePath}`,
|
|
259
|
-
output: `The DOCX file does not exist: ${filePath}`
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Check extension
|
|
264
|
-
if (!filePath.toLowerCase().endsWith('.docx') && !filePath.toLowerCase().endsWith('.doc')) {
|
|
265
|
-
return {
|
|
266
|
-
success: false,
|
|
267
|
-
error: 'Not a DOCX file',
|
|
268
|
-
output: `The file must have a .docx or .doc extension: ${filePath}`
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
try {
|
|
273
|
-
switch (action.action) {
|
|
274
|
-
case 'get-info':
|
|
275
|
-
return await this.getInfo(filePath);
|
|
276
|
-
case 'read':
|
|
277
|
-
return await this.readDocument(filePath, action.format || 'text');
|
|
278
|
-
default:
|
|
279
|
-
return {
|
|
280
|
-
success: false,
|
|
281
|
-
error: `Unknown action: ${action.action}`,
|
|
282
|
-
output: 'Supported actions: get-info, read, create'
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
} catch (error) {
|
|
286
|
-
this.logger?.error('DOCX tool error', { action: action.action, filePath, error: error.message });
|
|
287
|
-
return {
|
|
288
|
-
success: false,
|
|
289
|
-
error: error.message,
|
|
290
|
-
output: `Failed to process document: ${error.message}`
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Get document info (file stats + word count)
|
|
297
|
-
* @param {string} filePath
|
|
298
|
-
* @returns {Promise<Object>}
|
|
299
|
-
*/
|
|
300
|
-
async getInfo(filePath) {
|
|
301
|
-
const loaded = await this.loadMammoth();
|
|
302
|
-
if (!loaded) {
|
|
303
|
-
return {
|
|
304
|
-
success: false,
|
|
305
|
-
error: 'mammoth module not available',
|
|
306
|
-
output: `Document reading module could not be loaded: ${this.mammothError}`
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const stats = await fs.stat(filePath);
|
|
311
|
-
const buffer = await fs.readFile(filePath);
|
|
312
|
-
const result = await mammothModule.extractRawText({ buffer });
|
|
313
|
-
const text = result.value || '';
|
|
314
|
-
const wordCount = text.split(/\s+/).filter(w => w.length > 0).length;
|
|
315
|
-
|
|
316
|
-
const info = {
|
|
317
|
-
fileName: path.basename(filePath),
|
|
318
|
-
fileSize: stats.size,
|
|
319
|
-
modified: stats.mtime.toISOString(),
|
|
320
|
-
wordCount
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
let output = `Document Info: ${info.fileName}\n`;
|
|
324
|
-
output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
|
|
325
|
-
output += `File size: ${(info.fileSize / 1024).toFixed(1)} KB\n`;
|
|
326
|
-
output += `Word count: ${info.wordCount}\n`;
|
|
327
|
-
output += `Last modified: ${info.modified}\n`;
|
|
328
|
-
|
|
329
|
-
return {
|
|
330
|
-
success: true,
|
|
331
|
-
action: 'get-info',
|
|
332
|
-
filePath,
|
|
333
|
-
info,
|
|
334
|
-
output,
|
|
335
|
-
message: `Document: ${info.fileName} (${info.wordCount} words)`
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Read document content as text or HTML
|
|
341
|
-
* @param {string} filePath
|
|
342
|
-
* @param {string} format - "text" or "html"
|
|
343
|
-
* @returns {Promise<Object>}
|
|
344
|
-
*/
|
|
345
|
-
async readDocument(filePath, format = 'text') {
|
|
346
|
-
const loaded = await this.loadMammoth();
|
|
347
|
-
if (!loaded) {
|
|
348
|
-
return {
|
|
349
|
-
success: false,
|
|
350
|
-
error: 'mammoth module not available',
|
|
351
|
-
output: `Document reading module could not be loaded: ${this.mammothError}`
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
const buffer = await fs.readFile(filePath);
|
|
356
|
-
let result;
|
|
357
|
-
|
|
358
|
-
if (format === 'html') {
|
|
359
|
-
result = await mammothModule.convertToHtml({ buffer });
|
|
360
|
-
} else {
|
|
361
|
-
result = await mammothModule.extractRawText({ buffer });
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
const content = result.value || '';
|
|
365
|
-
const warnings = result.messages?.filter(m => m.type === 'warning').map(m => m.message) || [];
|
|
366
|
-
|
|
367
|
-
let output = `Document Content: ${path.basename(filePath)} (${format})\n`;
|
|
368
|
-
output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n`;
|
|
369
|
-
output += content;
|
|
370
|
-
|
|
371
|
-
if (warnings.length > 0) {
|
|
372
|
-
output += `\n\n⚠️ Warnings:\n${warnings.map(w => `- ${w}`).join('\n')}`;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
return {
|
|
376
|
-
success: true,
|
|
377
|
-
action: 'read',
|
|
378
|
-
filePath,
|
|
379
|
-
format,
|
|
380
|
-
content,
|
|
381
|
-
warnings,
|
|
382
|
-
output,
|
|
383
|
-
message: `Read ${path.basename(filePath)} as ${format} (${content.length} chars)`
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* Create a DOCX document from structured content
|
|
389
|
-
* @param {Object} action - Action parameters
|
|
390
|
-
* @param {Object} context - Execution context
|
|
391
|
-
* @returns {Promise<Object>}
|
|
392
|
-
*/
|
|
393
|
-
async createDocument(action, context) {
|
|
394
|
-
const { projectDir } = context;
|
|
395
|
-
const { outputPath, content } = action;
|
|
396
|
-
|
|
397
|
-
if (!outputPath) {
|
|
398
|
-
return {
|
|
399
|
-
success: false,
|
|
400
|
-
error: 'Output path is required',
|
|
401
|
-
output: 'Please provide an outputPath parameter'
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
if (!content || !content.sections || !Array.isArray(content.sections)) {
|
|
406
|
-
return {
|
|
407
|
-
success: false,
|
|
408
|
-
error: 'Content with sections array is required',
|
|
409
|
-
output: 'Please provide content with a "sections" array containing document elements'
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// Resolve output path
|
|
414
|
-
let resolvedPath = outputPath;
|
|
415
|
-
if (!path.isAbsolute(resolvedPath)) {
|
|
416
|
-
resolvedPath = path.resolve(projectDir || process.cwd(), resolvedPath);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
// Security: prevent path traversal
|
|
420
|
-
const baseDir = projectDir || process.cwd();
|
|
421
|
-
const normalizedPath = path.normalize(resolvedPath);
|
|
422
|
-
if (!normalizedPath.startsWith(path.normalize(baseDir))) {
|
|
423
|
-
return {
|
|
424
|
-
success: false,
|
|
425
|
-
error: 'Path traversal detected',
|
|
426
|
-
output: 'Output path must be within the project directory'
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
// Ensure output directory exists
|
|
431
|
-
const outputDir = path.dirname(resolvedPath);
|
|
432
|
-
await fs.mkdir(outputDir, { recursive: true });
|
|
433
|
-
|
|
434
|
-
// Ensure .docx extension
|
|
435
|
-
if (!resolvedPath.toLowerCase().endsWith('.docx')) {
|
|
436
|
-
resolvedPath += '.docx';
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// Load docx module
|
|
440
|
-
const loaded = await this.loadDocx();
|
|
441
|
-
if (!loaded) {
|
|
442
|
-
return {
|
|
443
|
-
success: false,
|
|
444
|
-
error: 'docx module not available',
|
|
445
|
-
output: `Document creation module could not be loaded: ${this.docxError}`
|
|
446
|
-
};
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
const { Document, Packer, Paragraph, TextRun, HeadingLevel, Table, TableRow, TableCell, WidthType, AlignmentType,
|
|
450
|
-
|
|
451
|
-
// Map alignment strings to AlignmentType
|
|
452
|
-
const alignmentMap = {
|
|
453
|
-
'left': AlignmentType.LEFT,
|
|
454
|
-
'center': AlignmentType.CENTER,
|
|
455
|
-
'right': AlignmentType.RIGHT,
|
|
456
|
-
'justified': AlignmentType.JUSTIFIED
|
|
457
|
-
};
|
|
458
|
-
|
|
459
|
-
// Map heading levels
|
|
460
|
-
const headingMap = {
|
|
461
|
-
1: HeadingLevel.HEADING_1,
|
|
462
|
-
2: HeadingLevel.HEADING_2,
|
|
463
|
-
3: HeadingLevel.HEADING_3,
|
|
464
|
-
4: HeadingLevel.HEADING_4,
|
|
465
|
-
5: HeadingLevel.HEADING_5,
|
|
466
|
-
6: HeadingLevel.HEADING_6
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
// Build sections
|
|
470
|
-
const docSections = [];
|
|
471
|
-
|
|
472
|
-
for (const section of content.sections) {
|
|
473
|
-
const children = [];
|
|
474
|
-
|
|
475
|
-
if (!section.children || !Array.isArray(section.children)) continue;
|
|
476
|
-
|
|
477
|
-
for (const element of section.children) {
|
|
478
|
-
switch (element.type) {
|
|
479
|
-
case 'heading': {
|
|
480
|
-
children.push(new Paragraph({
|
|
481
|
-
text: element.text || '',
|
|
482
|
-
heading: headingMap[element.level] || HeadingLevel.HEADING_1,
|
|
483
|
-
alignment: alignmentMap[element.alignment] || undefined
|
|
484
|
-
}));
|
|
485
|
-
break;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
case 'paragraph': {
|
|
489
|
-
const runs = [new TextRun({
|
|
490
|
-
text: element.text || '',
|
|
491
|
-
bold: element.bold || false,
|
|
492
|
-
italics: element.italic || false,
|
|
493
|
-
size: element.fontSize || undefined
|
|
494
|
-
})];
|
|
495
|
-
children.push(new Paragraph({
|
|
496
|
-
children: runs,
|
|
497
|
-
alignment: alignmentMap[element.alignment] || undefined
|
|
498
|
-
}));
|
|
499
|
-
break;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
case 'table': {
|
|
503
|
-
const rows = [];
|
|
504
|
-
|
|
505
|
-
// Header row
|
|
506
|
-
if (element.headers && Array.isArray(element.headers)) {
|
|
507
|
-
rows.push(new TableRow({
|
|
508
|
-
children: element.headers.map((header, i) => new TableCell({
|
|
509
|
-
children: [new Paragraph({
|
|
510
|
-
children: [new TextRun({ text: String(header), bold: true })]
|
|
511
|
-
})],
|
|
512
|
-
width: element.widths?.[i]
|
|
513
|
-
? { size: element.widths[i], type: WidthType.PERCENTAGE }
|
|
514
|
-
: undefined
|
|
515
|
-
}))
|
|
516
|
-
}));
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
// Data rows
|
|
520
|
-
if (element.rows && Array.isArray(element.rows)) {
|
|
521
|
-
for (const row of element.rows) {
|
|
522
|
-
rows.push(new TableRow({
|
|
523
|
-
children: (Array.isArray(row) ? row : []).map((cell, i) => new TableCell({
|
|
524
|
-
children: [new Paragraph({ text: String(cell) })],
|
|
525
|
-
width: element.widths?.[i]
|
|
526
|
-
? { size: element.widths[i], type: WidthType.PERCENTAGE }
|
|
527
|
-
: undefined
|
|
528
|
-
}))
|
|
529
|
-
}));
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
if (rows.length > 0) {
|
|
534
|
-
children.push(new Table({ rows }));
|
|
535
|
-
}
|
|
536
|
-
break;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
case 'list': {
|
|
540
|
-
const items = element.items || [];
|
|
541
|
-
for (let i = 0; i < items.length; i++) {
|
|
542
|
-
children.push(new Paragraph({
|
|
543
|
-
text: String(items[i]),
|
|
544
|
-
numbering: element.ordered
|
|
545
|
-
? { reference: 'ordered-list', level: 0 }
|
|
546
|
-
: { reference: 'bullet-list', level: 0 }
|
|
547
|
-
}));
|
|
548
|
-
}
|
|
549
|
-
break;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
case 'pageBreak': {
|
|
553
|
-
children.push(new Paragraph({
|
|
554
|
-
children: [new PageBreak()]
|
|
555
|
-
}));
|
|
556
|
-
break;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
default:
|
|
560
|
-
// Unknown element type, skip
|
|
561
|
-
break;
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
docSections.push({ children });
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
// Create document
|
|
569
|
-
const doc = new Document({
|
|
570
|
-
title: content.title || undefined,
|
|
571
|
-
creator: content.author || 'Loxia Agent',
|
|
572
|
-
numbering: {
|
|
573
|
-
config: [
|
|
574
|
-
{
|
|
575
|
-
reference: 'bullet-list',
|
|
576
|
-
levels: [{
|
|
577
|
-
level: 0,
|
|
578
|
-
format: LevelFormat.BULLET,
|
|
579
|
-
text: '\u2022',
|
|
580
|
-
alignment: AlignmentType.LEFT,
|
|
581
|
-
style: { paragraph: { indent: { left: 720, hanging: 360 } } }
|
|
582
|
-
}]
|
|
583
|
-
},
|
|
584
|
-
{
|
|
585
|
-
reference: 'ordered-list',
|
|
586
|
-
levels: [{
|
|
587
|
-
level: 0,
|
|
588
|
-
format: LevelFormat.DECIMAL,
|
|
589
|
-
text: '%1.',
|
|
590
|
-
alignment: AlignmentType.LEFT,
|
|
591
|
-
style: { paragraph: { indent: { left: 720, hanging: 360 } } }
|
|
592
|
-
}]
|
|
593
|
-
}
|
|
594
|
-
]
|
|
595
|
-
},
|
|
596
|
-
sections: docSections
|
|
597
|
-
});
|
|
598
|
-
|
|
599
|
-
// Generate and write file
|
|
600
|
-
const buffer = await Packer.toBuffer(doc);
|
|
601
|
-
await fs.writeFile(resolvedPath, buffer);
|
|
602
|
-
|
|
603
|
-
const stats = await fs.stat(resolvedPath);
|
|
604
|
-
|
|
605
|
-
const output = `Document created successfully!\n` +
|
|
606
|
-
`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
|
|
607
|
-
`File: ${resolvedPath}\n` +
|
|
608
|
-
`Size: ${(stats.size / 1024).toFixed(1)} KB\n` +
|
|
609
|
-
(content.title ? `Title: ${content.title}\n` : '') +
|
|
610
|
-
`Sections: ${content.sections.length}`;
|
|
611
|
-
|
|
612
|
-
return {
|
|
613
|
-
success: true,
|
|
614
|
-
action: 'create',
|
|
615
|
-
outputPath: resolvedPath,
|
|
616
|
-
fileSize: stats.size,
|
|
617
|
-
output,
|
|
618
|
-
message: `Document created: ${resolvedPath} (${(stats.size / 1024).toFixed(1)} KB)`
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
export default DocxTool;
|
|
1
|
+
/**
|
|
2
|
+
* Document (DOCX) Tool - Read and create Word documents
|
|
3
|
+
*
|
|
4
|
+
* Purpose:
|
|
5
|
+
* - Get document metadata and word count
|
|
6
|
+
* - Extract text or HTML from DOCX files
|
|
7
|
+
* - Create DOCX documents from structured JSON content
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { BaseTool } from './baseTool.js';
|
|
11
|
+
import TagParser from '../utilities/tagParser.js';
|
|
12
|
+
import fs from 'fs/promises';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
|
|
15
|
+
// Lazy-loaded dependencies
|
|
16
|
+
let docxModule = null;
|
|
17
|
+
let mammothModule = null;
|
|
18
|
+
|
|
19
|
+
class DocxTool extends BaseTool {
|
|
20
|
+
constructor(config = {}, logger = null) {
|
|
21
|
+
super(config, logger);
|
|
22
|
+
this.id = 'doc';
|
|
23
|
+
this.name = 'Document Tool';
|
|
24
|
+
this.description = 'Read and create Word (DOCX) documents';
|
|
25
|
+
this.version = '1.0.0';
|
|
26
|
+
this.requiresProject = false;
|
|
27
|
+
this.isAsync = false;
|
|
28
|
+
this.docxLoaded = false;
|
|
29
|
+
this.docxError = null;
|
|
30
|
+
this.mammothLoaded = false;
|
|
31
|
+
this.mammothError = null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Lazily load the docx module (for creation)
|
|
36
|
+
* @returns {Promise<boolean>}
|
|
37
|
+
*/
|
|
38
|
+
async loadDocx() {
|
|
39
|
+
if (this.docxLoaded) return true;
|
|
40
|
+
if (this.docxError) return false;
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
docxModule = await import('docx');
|
|
44
|
+
this.docxLoaded = true;
|
|
45
|
+
return true;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
this.docxError = error.message;
|
|
48
|
+
this.logger?.error('Failed to load docx module', { error: error.message });
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Lazily load the mammoth module (for reading)
|
|
55
|
+
* @returns {Promise<boolean>}
|
|
56
|
+
*/
|
|
57
|
+
async loadMammoth() {
|
|
58
|
+
if (this.mammothLoaded) return true;
|
|
59
|
+
if (this.mammothError) return false;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const mod = await import('mammoth');
|
|
63
|
+
mammothModule = mod.default || mod;
|
|
64
|
+
this.mammothLoaded = true;
|
|
65
|
+
return true;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
this.mammothError = error.message;
|
|
68
|
+
this.logger?.error('Failed to load mammoth module', { error: error.message });
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get tool description for LLM consumption
|
|
75
|
+
* @returns {string}
|
|
76
|
+
*/
|
|
77
|
+
getDescription() {
|
|
78
|
+
return `
|
|
79
|
+
Document Tool: Read and create Word (DOCX) documents.
|
|
80
|
+
|
|
81
|
+
USAGE:
|
|
82
|
+
\`\`\`json
|
|
83
|
+
{
|
|
84
|
+
"toolId": "doc",
|
|
85
|
+
"actions": [{
|
|
86
|
+
"action": "get-info",
|
|
87
|
+
"filePath": "documents/report.docx"
|
|
88
|
+
}]
|
|
89
|
+
}
|
|
90
|
+
\`\`\`
|
|
91
|
+
|
|
92
|
+
ACTIONS:
|
|
93
|
+
|
|
94
|
+
1. **get-info** - Get document metadata and word count
|
|
95
|
+
- filePath: Path to DOCX file (required)
|
|
96
|
+
|
|
97
|
+
2. **read** - Extract text or HTML content from a DOCX file
|
|
98
|
+
- filePath: Path to DOCX file (required)
|
|
99
|
+
- format: "text" (default) or "html"
|
|
100
|
+
|
|
101
|
+
3. **create** - Create a new DOCX document from structured content
|
|
102
|
+
- outputPath: Output file path (required)
|
|
103
|
+
- content: Document content object (required):
|
|
104
|
+
- title: Document title (optional)
|
|
105
|
+
- author: Document author (optional)
|
|
106
|
+
- sections: Array of sections, each with:
|
|
107
|
+
- children: Array of content elements:
|
|
108
|
+
- { type: "heading", level: 1-6, text: "..." }
|
|
109
|
+
- { type: "paragraph", text: "...", bold: false, italic: false, fontSize: 24, alignment: "left" }
|
|
110
|
+
- { type: "table", headers: ["Col1", "Col2"], rows: [["val1", "val2"]], widths: [50, 50] }
|
|
111
|
+
- { type: "list", ordered: false, items: ["Item 1", "Item 2"] }
|
|
112
|
+
- { type: "pageBreak" }
|
|
113
|
+
|
|
114
|
+
EXAMPLES:
|
|
115
|
+
|
|
116
|
+
1. Get document info:
|
|
117
|
+
\`\`\`json
|
|
118
|
+
{
|
|
119
|
+
"toolId": "doc",
|
|
120
|
+
"actions": [{
|
|
121
|
+
"action": "get-info",
|
|
122
|
+
"filePath": "documents/report.docx"
|
|
123
|
+
}]
|
|
124
|
+
}
|
|
125
|
+
\`\`\`
|
|
126
|
+
|
|
127
|
+
2. Read document as text:
|
|
128
|
+
\`\`\`json
|
|
129
|
+
{
|
|
130
|
+
"toolId": "doc",
|
|
131
|
+
"actions": [{
|
|
132
|
+
"action": "read",
|
|
133
|
+
"filePath": "documents/report.docx",
|
|
134
|
+
"format": "text"
|
|
135
|
+
}]
|
|
136
|
+
}
|
|
137
|
+
\`\`\`
|
|
138
|
+
|
|
139
|
+
3. Create a document:
|
|
140
|
+
\`\`\`json
|
|
141
|
+
{
|
|
142
|
+
"toolId": "doc",
|
|
143
|
+
"actions": [{
|
|
144
|
+
"action": "create",
|
|
145
|
+
"outputPath": "output/report.docx",
|
|
146
|
+
"content": {
|
|
147
|
+
"title": "Project Report",
|
|
148
|
+
"author": "Loxia Agent",
|
|
149
|
+
"sections": [{
|
|
150
|
+
"children": [
|
|
151
|
+
{ "type": "heading", "level": 1, "text": "Introduction" },
|
|
152
|
+
{ "type": "paragraph", "text": "This is the introduction paragraph." },
|
|
153
|
+
{ "type": "heading", "level": 2, "text": "Data Summary" },
|
|
154
|
+
{ "type": "table", "headers": ["Metric", "Value"], "rows": [["Users", "1000"], ["Revenue", "$50K"]] },
|
|
155
|
+
{ "type": "list", "ordered": true, "items": ["First point", "Second point", "Third point"] }
|
|
156
|
+
]
|
|
157
|
+
}]
|
|
158
|
+
}
|
|
159
|
+
}]
|
|
160
|
+
}
|
|
161
|
+
\`\`\`
|
|
162
|
+
|
|
163
|
+
NOTES:
|
|
164
|
+
- For reading, mammoth provides clean text/HTML extraction
|
|
165
|
+
- For creation, the docx package supports rich formatting
|
|
166
|
+
- fontSize is in half-points (24 = 12pt, 28 = 14pt, etc.)
|
|
167
|
+
- alignment options: "left", "center", "right", "justified"
|
|
168
|
+
- Table widths are percentages that should sum to 100
|
|
169
|
+
`.trim();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Parse parameters from tool command content
|
|
174
|
+
* @param {string} content
|
|
175
|
+
* @returns {Object}
|
|
176
|
+
*/
|
|
177
|
+
parseParameters(content) {
|
|
178
|
+
try {
|
|
179
|
+
const actionMatches = TagParser.extractContent(content, 'action');
|
|
180
|
+
const filePathMatches = TagParser.extractContent(content, 'filePath');
|
|
181
|
+
const formatMatches = TagParser.extractContent(content, 'format');
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
actions: [{
|
|
185
|
+
action: actionMatches.length > 0 ? actionMatches[0].trim() : 'get-info',
|
|
186
|
+
filePath: filePathMatches.length > 0 ? filePathMatches[0].trim() : '',
|
|
187
|
+
format: formatMatches.length > 0 ? formatMatches[0].trim() : 'text'
|
|
188
|
+
}]
|
|
189
|
+
};
|
|
190
|
+
} catch (error) {
|
|
191
|
+
throw new Error(`Failed to parse Document tool parameters: ${error.message}`, { cause: error });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Get supported actions
|
|
197
|
+
* @returns {Array<string>}
|
|
198
|
+
*/
|
|
199
|
+
getSupportedActions() {
|
|
200
|
+
return ['get-info', 'read', 'create'];
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Execute document tool action
|
|
205
|
+
* @param {Object} params
|
|
206
|
+
* @param {Object} context
|
|
207
|
+
* @returns {Promise<Object>}
|
|
208
|
+
*/
|
|
209
|
+
async execute(params, context) {
|
|
210
|
+
const { actions } = params;
|
|
211
|
+
|
|
212
|
+
if (!actions || actions.length === 0) {
|
|
213
|
+
return {
|
|
214
|
+
success: false,
|
|
215
|
+
error: 'No actions provided',
|
|
216
|
+
output: 'Please specify an action (get-info, read, or create)'
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const action = actions[0];
|
|
221
|
+
|
|
222
|
+
// Handle create action (no existing file required)
|
|
223
|
+
if (action.action === 'create') {
|
|
224
|
+
try {
|
|
225
|
+
return await this.createDocument(action, context);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
this.logger?.error('DOCX creation error', { error: error.message });
|
|
228
|
+
return {
|
|
229
|
+
success: false,
|
|
230
|
+
error: error.message,
|
|
231
|
+
output: `Failed to create document: ${error.message}`
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Read-oriented actions require file path
|
|
237
|
+
const { projectDir } = context;
|
|
238
|
+
let filePath = action.filePath;
|
|
239
|
+
|
|
240
|
+
if (!filePath) {
|
|
241
|
+
return {
|
|
242
|
+
success: false,
|
|
243
|
+
error: 'File path is required',
|
|
244
|
+
output: 'Please provide a filePath parameter'
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (!path.isAbsolute(filePath)) {
|
|
249
|
+
filePath = path.resolve(projectDir || process.cwd(), filePath);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Check file exists
|
|
253
|
+
try {
|
|
254
|
+
await fs.access(filePath);
|
|
255
|
+
} catch {
|
|
256
|
+
return {
|
|
257
|
+
success: false,
|
|
258
|
+
error: `File not found: ${filePath}`,
|
|
259
|
+
output: `The DOCX file does not exist: ${filePath}`
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Check extension
|
|
264
|
+
if (!filePath.toLowerCase().endsWith('.docx') && !filePath.toLowerCase().endsWith('.doc')) {
|
|
265
|
+
return {
|
|
266
|
+
success: false,
|
|
267
|
+
error: 'Not a DOCX file',
|
|
268
|
+
output: `The file must have a .docx or .doc extension: ${filePath}`
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
try {
|
|
273
|
+
switch (action.action) {
|
|
274
|
+
case 'get-info':
|
|
275
|
+
return await this.getInfo(filePath);
|
|
276
|
+
case 'read':
|
|
277
|
+
return await this.readDocument(filePath, action.format || 'text');
|
|
278
|
+
default:
|
|
279
|
+
return {
|
|
280
|
+
success: false,
|
|
281
|
+
error: `Unknown action: ${action.action}`,
|
|
282
|
+
output: 'Supported actions: get-info, read, create'
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
} catch (error) {
|
|
286
|
+
this.logger?.error('DOCX tool error', { action: action.action, filePath, error: error.message });
|
|
287
|
+
return {
|
|
288
|
+
success: false,
|
|
289
|
+
error: error.message,
|
|
290
|
+
output: `Failed to process document: ${error.message}`
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Get document info (file stats + word count)
|
|
297
|
+
* @param {string} filePath
|
|
298
|
+
* @returns {Promise<Object>}
|
|
299
|
+
*/
|
|
300
|
+
async getInfo(filePath) {
|
|
301
|
+
const loaded = await this.loadMammoth();
|
|
302
|
+
if (!loaded) {
|
|
303
|
+
return {
|
|
304
|
+
success: false,
|
|
305
|
+
error: 'mammoth module not available',
|
|
306
|
+
output: `Document reading module could not be loaded: ${this.mammothError}`
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const stats = await fs.stat(filePath);
|
|
311
|
+
const buffer = await fs.readFile(filePath);
|
|
312
|
+
const result = await mammothModule.extractRawText({ buffer });
|
|
313
|
+
const text = result.value || '';
|
|
314
|
+
const wordCount = text.split(/\s+/).filter(w => w.length > 0).length;
|
|
315
|
+
|
|
316
|
+
const info = {
|
|
317
|
+
fileName: path.basename(filePath),
|
|
318
|
+
fileSize: stats.size,
|
|
319
|
+
modified: stats.mtime.toISOString(),
|
|
320
|
+
wordCount
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
let output = `Document Info: ${info.fileName}\n`;
|
|
324
|
+
output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
|
|
325
|
+
output += `File size: ${(info.fileSize / 1024).toFixed(1)} KB\n`;
|
|
326
|
+
output += `Word count: ${info.wordCount}\n`;
|
|
327
|
+
output += `Last modified: ${info.modified}\n`;
|
|
328
|
+
|
|
329
|
+
return {
|
|
330
|
+
success: true,
|
|
331
|
+
action: 'get-info',
|
|
332
|
+
filePath,
|
|
333
|
+
info,
|
|
334
|
+
output,
|
|
335
|
+
message: `Document: ${info.fileName} (${info.wordCount} words)`
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Read document content as text or HTML
|
|
341
|
+
* @param {string} filePath
|
|
342
|
+
* @param {string} format - "text" or "html"
|
|
343
|
+
* @returns {Promise<Object>}
|
|
344
|
+
*/
|
|
345
|
+
async readDocument(filePath, format = 'text') {
|
|
346
|
+
const loaded = await this.loadMammoth();
|
|
347
|
+
if (!loaded) {
|
|
348
|
+
return {
|
|
349
|
+
success: false,
|
|
350
|
+
error: 'mammoth module not available',
|
|
351
|
+
output: `Document reading module could not be loaded: ${this.mammothError}`
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const buffer = await fs.readFile(filePath);
|
|
356
|
+
let result;
|
|
357
|
+
|
|
358
|
+
if (format === 'html') {
|
|
359
|
+
result = await mammothModule.convertToHtml({ buffer });
|
|
360
|
+
} else {
|
|
361
|
+
result = await mammothModule.extractRawText({ buffer });
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const content = result.value || '';
|
|
365
|
+
const warnings = result.messages?.filter(m => m.type === 'warning').map(m => m.message) || [];
|
|
366
|
+
|
|
367
|
+
let output = `Document Content: ${path.basename(filePath)} (${format})\n`;
|
|
368
|
+
output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n`;
|
|
369
|
+
output += content;
|
|
370
|
+
|
|
371
|
+
if (warnings.length > 0) {
|
|
372
|
+
output += `\n\n⚠️ Warnings:\n${warnings.map(w => `- ${w}`).join('\n')}`;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
return {
|
|
376
|
+
success: true,
|
|
377
|
+
action: 'read',
|
|
378
|
+
filePath,
|
|
379
|
+
format,
|
|
380
|
+
content,
|
|
381
|
+
warnings,
|
|
382
|
+
output,
|
|
383
|
+
message: `Read ${path.basename(filePath)} as ${format} (${content.length} chars)`
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Create a DOCX document from structured content
|
|
389
|
+
* @param {Object} action - Action parameters
|
|
390
|
+
* @param {Object} context - Execution context
|
|
391
|
+
* @returns {Promise<Object>}
|
|
392
|
+
*/
|
|
393
|
+
async createDocument(action, context) {
|
|
394
|
+
const { projectDir } = context;
|
|
395
|
+
const { outputPath, content } = action;
|
|
396
|
+
|
|
397
|
+
if (!outputPath) {
|
|
398
|
+
return {
|
|
399
|
+
success: false,
|
|
400
|
+
error: 'Output path is required',
|
|
401
|
+
output: 'Please provide an outputPath parameter'
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (!content || !content.sections || !Array.isArray(content.sections)) {
|
|
406
|
+
return {
|
|
407
|
+
success: false,
|
|
408
|
+
error: 'Content with sections array is required',
|
|
409
|
+
output: 'Please provide content with a "sections" array containing document elements'
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Resolve output path
|
|
414
|
+
let resolvedPath = outputPath;
|
|
415
|
+
if (!path.isAbsolute(resolvedPath)) {
|
|
416
|
+
resolvedPath = path.resolve(projectDir || process.cwd(), resolvedPath);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Security: prevent path traversal
|
|
420
|
+
const baseDir = projectDir || process.cwd();
|
|
421
|
+
const normalizedPath = path.normalize(resolvedPath);
|
|
422
|
+
if (!normalizedPath.startsWith(path.normalize(baseDir))) {
|
|
423
|
+
return {
|
|
424
|
+
success: false,
|
|
425
|
+
error: 'Path traversal detected',
|
|
426
|
+
output: 'Output path must be within the project directory'
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Ensure output directory exists
|
|
431
|
+
const outputDir = path.dirname(resolvedPath);
|
|
432
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
433
|
+
|
|
434
|
+
// Ensure .docx extension
|
|
435
|
+
if (!resolvedPath.toLowerCase().endsWith('.docx')) {
|
|
436
|
+
resolvedPath += '.docx';
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Load docx module
|
|
440
|
+
const loaded = await this.loadDocx();
|
|
441
|
+
if (!loaded) {
|
|
442
|
+
return {
|
|
443
|
+
success: false,
|
|
444
|
+
error: 'docx module not available',
|
|
445
|
+
output: `Document creation module could not be loaded: ${this.docxError}`
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const { Document, Packer, Paragraph, TextRun, HeadingLevel, Table, TableRow, TableCell, WidthType, AlignmentType, PageBreak, LevelFormat } = docxModule;
|
|
450
|
+
|
|
451
|
+
// Map alignment strings to AlignmentType
|
|
452
|
+
const alignmentMap = {
|
|
453
|
+
'left': AlignmentType.LEFT,
|
|
454
|
+
'center': AlignmentType.CENTER,
|
|
455
|
+
'right': AlignmentType.RIGHT,
|
|
456
|
+
'justified': AlignmentType.JUSTIFIED
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
// Map heading levels
|
|
460
|
+
const headingMap = {
|
|
461
|
+
1: HeadingLevel.HEADING_1,
|
|
462
|
+
2: HeadingLevel.HEADING_2,
|
|
463
|
+
3: HeadingLevel.HEADING_3,
|
|
464
|
+
4: HeadingLevel.HEADING_4,
|
|
465
|
+
5: HeadingLevel.HEADING_5,
|
|
466
|
+
6: HeadingLevel.HEADING_6
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
// Build sections
|
|
470
|
+
const docSections = [];
|
|
471
|
+
|
|
472
|
+
for (const section of content.sections) {
|
|
473
|
+
const children = [];
|
|
474
|
+
|
|
475
|
+
if (!section.children || !Array.isArray(section.children)) continue;
|
|
476
|
+
|
|
477
|
+
for (const element of section.children) {
|
|
478
|
+
switch (element.type) {
|
|
479
|
+
case 'heading': {
|
|
480
|
+
children.push(new Paragraph({
|
|
481
|
+
text: element.text || '',
|
|
482
|
+
heading: headingMap[element.level] || HeadingLevel.HEADING_1,
|
|
483
|
+
alignment: alignmentMap[element.alignment] || undefined
|
|
484
|
+
}));
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
case 'paragraph': {
|
|
489
|
+
const runs = [new TextRun({
|
|
490
|
+
text: element.text || '',
|
|
491
|
+
bold: element.bold || false,
|
|
492
|
+
italics: element.italic || false,
|
|
493
|
+
size: element.fontSize || undefined
|
|
494
|
+
})];
|
|
495
|
+
children.push(new Paragraph({
|
|
496
|
+
children: runs,
|
|
497
|
+
alignment: alignmentMap[element.alignment] || undefined
|
|
498
|
+
}));
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
case 'table': {
|
|
503
|
+
const rows = [];
|
|
504
|
+
|
|
505
|
+
// Header row
|
|
506
|
+
if (element.headers && Array.isArray(element.headers)) {
|
|
507
|
+
rows.push(new TableRow({
|
|
508
|
+
children: element.headers.map((header, i) => new TableCell({
|
|
509
|
+
children: [new Paragraph({
|
|
510
|
+
children: [new TextRun({ text: String(header), bold: true })]
|
|
511
|
+
})],
|
|
512
|
+
width: element.widths?.[i]
|
|
513
|
+
? { size: element.widths[i], type: WidthType.PERCENTAGE }
|
|
514
|
+
: undefined
|
|
515
|
+
}))
|
|
516
|
+
}));
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Data rows
|
|
520
|
+
if (element.rows && Array.isArray(element.rows)) {
|
|
521
|
+
for (const row of element.rows) {
|
|
522
|
+
rows.push(new TableRow({
|
|
523
|
+
children: (Array.isArray(row) ? row : []).map((cell, i) => new TableCell({
|
|
524
|
+
children: [new Paragraph({ text: String(cell) })],
|
|
525
|
+
width: element.widths?.[i]
|
|
526
|
+
? { size: element.widths[i], type: WidthType.PERCENTAGE }
|
|
527
|
+
: undefined
|
|
528
|
+
}))
|
|
529
|
+
}));
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (rows.length > 0) {
|
|
534
|
+
children.push(new Table({ rows }));
|
|
535
|
+
}
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
case 'list': {
|
|
540
|
+
const items = element.items || [];
|
|
541
|
+
for (let i = 0; i < items.length; i++) {
|
|
542
|
+
children.push(new Paragraph({
|
|
543
|
+
text: String(items[i]),
|
|
544
|
+
numbering: element.ordered
|
|
545
|
+
? { reference: 'ordered-list', level: 0 }
|
|
546
|
+
: { reference: 'bullet-list', level: 0 }
|
|
547
|
+
}));
|
|
548
|
+
}
|
|
549
|
+
break;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
case 'pageBreak': {
|
|
553
|
+
children.push(new Paragraph({
|
|
554
|
+
children: [new PageBreak()]
|
|
555
|
+
}));
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
default:
|
|
560
|
+
// Unknown element type, skip
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
docSections.push({ children });
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// Create document
|
|
569
|
+
const doc = new Document({
|
|
570
|
+
title: content.title || undefined,
|
|
571
|
+
creator: content.author || 'Loxia Agent',
|
|
572
|
+
numbering: {
|
|
573
|
+
config: [
|
|
574
|
+
{
|
|
575
|
+
reference: 'bullet-list',
|
|
576
|
+
levels: [{
|
|
577
|
+
level: 0,
|
|
578
|
+
format: LevelFormat.BULLET,
|
|
579
|
+
text: '\u2022',
|
|
580
|
+
alignment: AlignmentType.LEFT,
|
|
581
|
+
style: { paragraph: { indent: { left: 720, hanging: 360 } } }
|
|
582
|
+
}]
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
reference: 'ordered-list',
|
|
586
|
+
levels: [{
|
|
587
|
+
level: 0,
|
|
588
|
+
format: LevelFormat.DECIMAL,
|
|
589
|
+
text: '%1.',
|
|
590
|
+
alignment: AlignmentType.LEFT,
|
|
591
|
+
style: { paragraph: { indent: { left: 720, hanging: 360 } } }
|
|
592
|
+
}]
|
|
593
|
+
}
|
|
594
|
+
]
|
|
595
|
+
},
|
|
596
|
+
sections: docSections
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
// Generate and write file
|
|
600
|
+
const buffer = await Packer.toBuffer(doc);
|
|
601
|
+
await fs.writeFile(resolvedPath, buffer);
|
|
602
|
+
|
|
603
|
+
const stats = await fs.stat(resolvedPath);
|
|
604
|
+
|
|
605
|
+
const output = `Document created successfully!\n` +
|
|
606
|
+
`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n` +
|
|
607
|
+
`File: ${resolvedPath}\n` +
|
|
608
|
+
`Size: ${(stats.size / 1024).toFixed(1)} KB\n` +
|
|
609
|
+
(content.title ? `Title: ${content.title}\n` : '') +
|
|
610
|
+
`Sections: ${content.sections.length}`;
|
|
611
|
+
|
|
612
|
+
return {
|
|
613
|
+
success: true,
|
|
614
|
+
action: 'create',
|
|
615
|
+
outputPath: resolvedPath,
|
|
616
|
+
fileSize: stats.size,
|
|
617
|
+
output,
|
|
618
|
+
message: `Document created: ${resolvedPath} (${(stats.size / 1024).toFixed(1)} KB)`
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
export default DocxTool;
|