@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.4
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/README.md +44 -54
- package/bin/cli.js +1 -115
- package/bin/loxia-terminal-v2.js +3 -0
- package/bin/loxia-terminal.js +3 -0
- package/bin/start-with-terminal.js +3 -0
- package/package.json +15 -15
- package/scripts/install-scanners.js +1 -235
- package/src/analyzers/CSSAnalyzer.js +1 -297
- package/src/analyzers/ConfigValidator.js +1 -690
- package/src/analyzers/ESLintAnalyzer.js +1 -320
- package/src/analyzers/JavaScriptAnalyzer.js +1 -261
- package/src/analyzers/PrettierFormatter.js +1 -247
- package/src/analyzers/PythonAnalyzer.js +1 -266
- package/src/analyzers/SecurityAnalyzer.js +1 -729
- package/src/analyzers/TypeScriptAnalyzer.js +1 -247
- package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
- package/src/analyzers/codeCloneDetector/detector.js +1 -203
- package/src/analyzers/codeCloneDetector/index.js +1 -160
- package/src/analyzers/codeCloneDetector/parser.js +1 -199
- package/src/analyzers/codeCloneDetector/reporter.js +1 -148
- package/src/analyzers/codeCloneDetector/scanner.js +1 -59
- package/src/core/agentPool.js +1 -1474
- package/src/core/agentScheduler.js +1 -2147
- package/src/core/contextManager.js +1 -709
- package/src/core/messageProcessor.js +1 -732
- package/src/core/orchestrator.js +1 -548
- package/src/core/stateManager.js +1 -877
- package/src/index.js +1 -631
- package/src/interfaces/cli.js +1 -549
- package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
- package/src/interfaces/terminal/api/apiClient.js +1 -0
- package/src/interfaces/terminal/api/messageRouter.js +1 -0
- package/src/interfaces/terminal/api/session.js +1 -0
- package/src/interfaces/terminal/api/websocket.js +1 -0
- package/src/interfaces/terminal/components/AgentCreator.js +1 -0
- package/src/interfaces/terminal/components/AgentEditor.js +1 -0
- package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
- package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
- package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
- package/src/interfaces/terminal/components/Header.js +1 -0
- package/src/interfaces/terminal/components/HelpPanel.js +1 -0
- package/src/interfaces/terminal/components/InputBox.js +1 -0
- package/src/interfaces/terminal/components/Layout.js +1 -0
- package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
- package/src/interfaces/terminal/components/MessageList.js +1 -0
- package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
- package/src/interfaces/terminal/components/SearchPanel.js +1 -0
- package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
- package/src/interfaces/terminal/components/StatusBar.js +1 -0
- package/src/interfaces/terminal/components/TextInput.js +1 -0
- package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
- package/src/interfaces/terminal/config/constants.js +1 -0
- package/src/interfaces/terminal/index.js +1 -0
- package/src/interfaces/terminal/state/useAgentControl.js +1 -0
- package/src/interfaces/terminal/state/useAgents.js +1 -0
- package/src/interfaces/terminal/state/useConnection.js +1 -0
- package/src/interfaces/terminal/state/useMessages.js +1 -0
- package/src/interfaces/terminal/state/useTools.js +1 -0
- package/src/interfaces/terminal/utils/debugLogger.js +1 -0
- package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
- package/src/interfaces/terminal/utils/theme.js +1 -0
- package/src/interfaces/webServer.js +1 -2162
- package/src/modules/fileExplorer/controller.js +1 -280
- package/src/modules/fileExplorer/index.js +1 -37
- package/src/modules/fileExplorer/middleware.js +1 -92
- package/src/modules/fileExplorer/routes.js +1 -125
- package/src/modules/fileExplorer/types.js +1 -44
- package/src/services/aiService.js +1 -1232
- package/src/services/apiKeyManager.js +1 -164
- package/src/services/benchmarkService.js +1 -366
- package/src/services/budgetService.js +1 -539
- package/src/services/contextInjectionService.js +1 -247
- package/src/services/conversationCompactionService.js +1 -637
- package/src/services/errorHandler.js +1 -810
- package/src/services/fileAttachmentService.js +1 -544
- package/src/services/modelRouterService.js +1 -366
- package/src/services/modelsService.js +1 -322
- package/src/services/qualityInspector.js +1 -796
- package/src/services/tokenCountingService.js +1 -536
- package/src/tools/agentCommunicationTool.js +1 -1344
- package/src/tools/agentDelayTool.js +1 -485
- package/src/tools/asyncToolManager.js +1 -604
- package/src/tools/baseTool.js +1 -800
- package/src/tools/browserTool.js +1 -920
- package/src/tools/cloneDetectionTool.js +1 -621
- package/src/tools/dependencyResolverTool.js +1 -1215
- package/src/tools/fileContentReplaceTool.js +1 -875
- package/src/tools/fileSystemTool.js +1 -1107
- package/src/tools/fileTreeTool.js +1 -853
- package/src/tools/imageTool.js +1 -901
- package/src/tools/importAnalyzerTool.js +1 -1060
- package/src/tools/jobDoneTool.js +1 -248
- package/src/tools/seekTool.js +1 -956
- package/src/tools/staticAnalysisTool.js +1 -1778
- package/src/tools/taskManagerTool.js +1 -2873
- package/src/tools/terminalTool.js +1 -2304
- package/src/tools/webTool.js +1 -1430
- package/src/types/agent.js +1 -519
- package/src/types/contextReference.js +1 -972
- package/src/types/conversation.js +1 -730
- package/src/types/toolCommand.js +1 -747
- package/src/utilities/attachmentValidator.js +1 -292
- package/src/utilities/configManager.js +1 -582
- package/src/utilities/constants.js +1 -722
- package/src/utilities/directoryAccessManager.js +1 -535
- package/src/utilities/fileProcessor.js +1 -307
- package/src/utilities/logger.js +1 -436
- package/src/utilities/tagParser.js +1 -1246
- package/src/utilities/toolConstants.js +1 -317
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
- package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
|
@@ -1,1246 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TagParser - Utility for parsing XML-style tags and JSON tool commands
|
|
3
|
-
*
|
|
4
|
-
* Purpose:
|
|
5
|
-
* - Parse XML-style tool commands from agent messages
|
|
6
|
-
* - Extract parameters from tag-based format
|
|
7
|
-
* - Support for nested tags and attributes
|
|
8
|
-
* - JSON tool command parsing
|
|
9
|
-
* - Agent redirect parsing
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import {
|
|
13
|
-
AGENT_REDIRECT_ATTRIBUTES
|
|
14
|
-
} from './constants.js';
|
|
15
|
-
import {
|
|
16
|
-
TOOL_IDS,
|
|
17
|
-
COMMAND_FORMATS,
|
|
18
|
-
JSON_STRUCTURES,
|
|
19
|
-
identifyJsonStructure,
|
|
20
|
-
getToolIdFromAction,
|
|
21
|
-
isValidToolId
|
|
22
|
-
} from './toolConstants.js';
|
|
23
|
-
|
|
24
|
-
class TagParser {
|
|
25
|
-
constructor() {
|
|
26
|
-
// Tag parsing patterns
|
|
27
|
-
this.patterns = {
|
|
28
|
-
toolCommand: /<tool-command>(.*?)<\/tool-command>/gs,
|
|
29
|
-
tool: /<tool\s+([^>]*)>(.*?)<\/tool>/gs,
|
|
30
|
-
parameter: /<([^>\s]+)(?:\s+([^>]*))?>(((?!<\/\1>)[\s\S])*)<\/\1>/g,
|
|
31
|
-
attribute: /([\w-]+)=["']([^"']*)["']/g,
|
|
32
|
-
agentRedirect: /\[agent-redirect\s+([^\]]*)\](.*?)\[\/agent-redirect\]/gs,
|
|
33
|
-
jsonBlock: /```json\s*(\{[\s\S]*?\})\s*```/g,
|
|
34
|
-
// Also match plain JSON objects on their own line(s) as fallback
|
|
35
|
-
plainJson: /^(\{(?:[^{}]|(?:\{[^{}]*\}))*\})$/gm
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Decode HTML entities that might be present in tool content
|
|
41
|
-
* @param {string} text - Text that might contain HTML entities
|
|
42
|
-
* @returns {string} Decoded text
|
|
43
|
-
*/
|
|
44
|
-
decodeHtmlEntities(text) {
|
|
45
|
-
const entityMap = {
|
|
46
|
-
'<': '<',
|
|
47
|
-
'>': '>',
|
|
48
|
-
'&': '&',
|
|
49
|
-
'"': '"',
|
|
50
|
-
''': "'",
|
|
51
|
-
'/': '/',
|
|
52
|
-
''': "'",
|
|
53
|
-
'/': '/'
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
return text.replace(/&(?:lt|gt|amp|quot|#x27|#x2F|#39|#47);/g, match => entityMap[match] || match);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Extract tool commands from message content
|
|
61
|
-
* @param {string} content - Message content to parse
|
|
62
|
-
* @returns {Array} Array of parsed tool commands
|
|
63
|
-
*/
|
|
64
|
-
extractToolCommands(content) {
|
|
65
|
-
const commands = [];
|
|
66
|
-
|
|
67
|
-
// Decode HTML entities that might be present in the content
|
|
68
|
-
const decodedContent = this.decodeHtmlEntities(content);
|
|
69
|
-
|
|
70
|
-
// PHASE 1: Extract explicit tool invocations (OUTER layer identification)
|
|
71
|
-
// These use explicit markers: <toolname>, [tool id=""], or ```json
|
|
72
|
-
const xmlCommands = this.extractXMLToolCommands(decodedContent);
|
|
73
|
-
commands.push(...xmlCommands);
|
|
74
|
-
|
|
75
|
-
// PHASE 2: Extract JSON code blocks (also OUTER layer, explicit)
|
|
76
|
-
// Extract these BEFORE sanitization so we don't lose them
|
|
77
|
-
const jsonCodeBlockCommands = this.extractJSONCodeBlocks(decodedContent);
|
|
78
|
-
commands.push(...jsonCodeBlockCommands);
|
|
79
|
-
|
|
80
|
-
// PHASE 3: Sanitize content by removing already-extracted invocations
|
|
81
|
-
// This prevents INNER payload from being misinterpreted as new tool invocations
|
|
82
|
-
const sanitizedContent = this.removeToolInvocationBlocks(decodedContent);
|
|
83
|
-
|
|
84
|
-
// PHASE 4: Extract plain JSON (fallback, only from sanitized content)
|
|
85
|
-
// This should rarely find anything if agents follow the ```json block convention
|
|
86
|
-
const plainJsonCommands = this.extractPlainJSON(sanitizedContent);
|
|
87
|
-
commands.push(...plainJsonCommands);
|
|
88
|
-
|
|
89
|
-
return commands;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Remove content inside tool invocation blocks to prevent false JSON detection
|
|
94
|
-
*
|
|
95
|
-
* ARCHITECTURAL PRINCIPLE (OUTER-INNER HIERARCHY):
|
|
96
|
-
* - OUTER layer (message level): Tool identification
|
|
97
|
-
* - INNER layer (payload level): Action/data for the tool
|
|
98
|
-
*
|
|
99
|
-
* Tool invocations appear at MESSAGE LEVEL using explicit markers:
|
|
100
|
-
* - XML: <toolname>...</toolname> or [tool id="..."]...[/tool]
|
|
101
|
-
* - JSON: ```json {"toolId": "..."} ```
|
|
102
|
-
*
|
|
103
|
-
* Content INSIDE these markers is PAYLOAD, not new tool invocations.
|
|
104
|
-
*
|
|
105
|
-
* This method removes:
|
|
106
|
-
* - Direct tool tags: <taskmanager>...</taskmanager>, <filesystem>...</filesystem>, etc.
|
|
107
|
-
* - Bracket notation: [tool id="filesystem"]...[/tool]
|
|
108
|
-
* - JSON code blocks: ```json ... ```
|
|
109
|
-
*
|
|
110
|
-
* This prevents:
|
|
111
|
-
* - File content like {"type": "image/png"} inside <write> tags from being detected
|
|
112
|
-
* - Duplicate extraction of the same JSON block
|
|
113
|
-
*
|
|
114
|
-
* @param {string} content - Content to sanitize
|
|
115
|
-
* @returns {string} Content with tool invocation blocks removed/replaced with placeholders
|
|
116
|
-
* @private
|
|
117
|
-
*/
|
|
118
|
-
removeToolInvocationBlocks(content) {
|
|
119
|
-
let sanitized = content;
|
|
120
|
-
|
|
121
|
-
// Remove JSON code blocks first (to prevent duplicate extraction)
|
|
122
|
-
let jsonBlockPosition = 0;
|
|
123
|
-
while (jsonBlockPosition < sanitized.length) {
|
|
124
|
-
const startMarker = '```json';
|
|
125
|
-
const endMarker = '```';
|
|
126
|
-
|
|
127
|
-
const startIndex = sanitized.indexOf(startMarker, jsonBlockPosition);
|
|
128
|
-
if (startIndex === -1) break;
|
|
129
|
-
|
|
130
|
-
const contentStart = startIndex + startMarker.length;
|
|
131
|
-
const endIndex = sanitized.indexOf(endMarker, contentStart);
|
|
132
|
-
if (endIndex === -1) break;
|
|
133
|
-
|
|
134
|
-
// Replace JSON code block with placeholder
|
|
135
|
-
const before = sanitized.substring(0, startIndex);
|
|
136
|
-
const after = sanitized.substring(endIndex + endMarker.length);
|
|
137
|
-
sanitized = before + '[JSON_CODE_BLOCK_REMOVED]' + after;
|
|
138
|
-
|
|
139
|
-
jsonBlockPosition = startIndex + '[JSON_CODE_BLOCK_REMOVED]'.length;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// List of known tool names (matches extractDirectToolTags)
|
|
143
|
-
const toolNames = [
|
|
144
|
-
'taskmanager', 'filesystem', 'terminal', 'browser',
|
|
145
|
-
'agentcommunication', 'jobdone', 'agentdelay', 'image-gen'
|
|
146
|
-
];
|
|
147
|
-
|
|
148
|
-
// Remove direct tool tags like <filesystem>...</filesystem>
|
|
149
|
-
for (const toolName of toolNames) {
|
|
150
|
-
const openTag = `<${toolName}>`;
|
|
151
|
-
const closeTag = `</${toolName}>`;
|
|
152
|
-
|
|
153
|
-
let position = 0;
|
|
154
|
-
while (position < sanitized.length) {
|
|
155
|
-
const openIndex = sanitized.indexOf(openTag, position);
|
|
156
|
-
if (openIndex === -1) break;
|
|
157
|
-
|
|
158
|
-
const closeIndex = sanitized.indexOf(closeTag, openIndex + openTag.length);
|
|
159
|
-
if (closeIndex === -1) break;
|
|
160
|
-
|
|
161
|
-
// Replace the entire tool block with a placeholder to preserve message structure
|
|
162
|
-
// This allows JSON outside tool blocks to still be detected
|
|
163
|
-
const before = sanitized.substring(0, openIndex);
|
|
164
|
-
const after = sanitized.substring(closeIndex + closeTag.length);
|
|
165
|
-
sanitized = before + `[XML_TOOL_REMOVED:${toolName}]` + after;
|
|
166
|
-
|
|
167
|
-
position = openIndex + `[XML_TOOL_REMOVED:${toolName}]`.length;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Remove bracket notation tool blocks: [tool id="..."]...[/tool]
|
|
172
|
-
// Use a simple loop to avoid regex complexity
|
|
173
|
-
let bracketPosition = 0;
|
|
174
|
-
while (bracketPosition < sanitized.length) {
|
|
175
|
-
const openMarker = '[tool id="';
|
|
176
|
-
const openIndex = sanitized.indexOf(openMarker, bracketPosition);
|
|
177
|
-
if (openIndex === -1) break;
|
|
178
|
-
|
|
179
|
-
// Find the closing quote to extract tool ID
|
|
180
|
-
const quoteStart = openIndex + openMarker.length;
|
|
181
|
-
const quoteEnd = sanitized.indexOf('"', quoteStart);
|
|
182
|
-
if (quoteEnd === -1) break;
|
|
183
|
-
|
|
184
|
-
const toolId = sanitized.substring(quoteStart, quoteEnd);
|
|
185
|
-
|
|
186
|
-
// Find the closing ] of the opening tag
|
|
187
|
-
const openTagEnd = sanitized.indexOf(']', quoteEnd);
|
|
188
|
-
if (openTagEnd === -1) break;
|
|
189
|
-
|
|
190
|
-
// Find the closing [/tool]
|
|
191
|
-
const closeMarker = '[/tool]';
|
|
192
|
-
const closeIndex = sanitized.indexOf(closeMarker, openTagEnd);
|
|
193
|
-
if (closeIndex === -1) break;
|
|
194
|
-
|
|
195
|
-
// Replace the bracket tool block with placeholder
|
|
196
|
-
const before = sanitized.substring(0, openIndex);
|
|
197
|
-
const after = sanitized.substring(closeIndex + closeMarker.length);
|
|
198
|
-
sanitized = before + `[BRACKET_TOOL_REMOVED:${toolId}]` + after;
|
|
199
|
-
|
|
200
|
-
bracketPosition = openIndex + `[BRACKET_TOOL_REMOVED:${toolId}]`.length;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return sanitized;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Extract XML-style tool commands
|
|
208
|
-
* @param {string} content - Content to parse
|
|
209
|
-
* @returns {Array} Array of parsed XML tool commands
|
|
210
|
-
*/
|
|
211
|
-
extractXMLToolCommands(content) {
|
|
212
|
-
const commands = [];
|
|
213
|
-
|
|
214
|
-
// Find all tool-command blocks
|
|
215
|
-
const toolCommandBlocks = this.matchAll(content, this.patterns.toolCommand);
|
|
216
|
-
|
|
217
|
-
for (const block of toolCommandBlocks) {
|
|
218
|
-
const blockContent = block.groups[1];
|
|
219
|
-
|
|
220
|
-
// Extract individual tool elements within the block
|
|
221
|
-
const tools = this.matchAll(blockContent, this.patterns.tool);
|
|
222
|
-
|
|
223
|
-
for (const tool of tools) {
|
|
224
|
-
const attributes = this.parseAttributes(tool.groups[1]);
|
|
225
|
-
const toolContent = tool.groups[2];
|
|
226
|
-
|
|
227
|
-
const command = {
|
|
228
|
-
type: COMMAND_FORMATS.XML,
|
|
229
|
-
toolId: attributes.id,
|
|
230
|
-
attributes,
|
|
231
|
-
parameters: this.parseXMLParameters(toolContent),
|
|
232
|
-
rawContent: tool.match.trim(),
|
|
233
|
-
blockContent: block.match.trim()
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
commands.push(command);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Extract direct tool tags (e.g., <taskmanager>, <filesystem>)
|
|
241
|
-
const directToolTags = this.extractDirectToolTags(content);
|
|
242
|
-
commands.push(...directToolTags);
|
|
243
|
-
|
|
244
|
-
// Extract bracket notation (e.g., [tool id="filesystem"]...[/tool])
|
|
245
|
-
const bracketNotationTools = this.extractBracketNotationTools(content);
|
|
246
|
-
commands.push(...bracketNotationTools);
|
|
247
|
-
|
|
248
|
-
return commands;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Extract direct tool tags like <taskmanager>, <filesystem>, etc.
|
|
253
|
-
* @param {string} content - Content to parse
|
|
254
|
-
* @returns {Array} Array of parsed direct tool commands
|
|
255
|
-
*/
|
|
256
|
-
extractDirectToolTags(content) {
|
|
257
|
-
const commands = [];
|
|
258
|
-
const toolNames = ['taskmanager', 'filesystem', 'terminal', 'browser', 'agentcommunication', 'jobdone', 'agentdelay', 'image-gen'];
|
|
259
|
-
|
|
260
|
-
for (const toolName of toolNames) {
|
|
261
|
-
const toolCommands = this.extractToolByName(content, toolName);
|
|
262
|
-
commands.push(...toolCommands);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return commands;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Extract bracket notation tool commands like [tool id="filesystem"]...[/tool]
|
|
270
|
-
* @param {string} content - Content to parse
|
|
271
|
-
* @returns {Array} Array of parsed bracket notation tool commands
|
|
272
|
-
*/
|
|
273
|
-
extractBracketNotationTools(content) {
|
|
274
|
-
const commands = [];
|
|
275
|
-
const openMarker = '[tool id="';
|
|
276
|
-
const closeMarker = '[/tool]';
|
|
277
|
-
|
|
278
|
-
let position = 0;
|
|
279
|
-
|
|
280
|
-
while (position < content.length) {
|
|
281
|
-
// Find opening marker
|
|
282
|
-
const openIndex = content.indexOf(openMarker, position);
|
|
283
|
-
if (openIndex === -1) break;
|
|
284
|
-
|
|
285
|
-
// Find the closing quote to extract tool ID
|
|
286
|
-
const quoteStart = openIndex + openMarker.length;
|
|
287
|
-
const quoteEnd = content.indexOf('"', quoteStart);
|
|
288
|
-
if (quoteEnd === -1) break;
|
|
289
|
-
|
|
290
|
-
const toolId = content.substring(quoteStart, quoteEnd);
|
|
291
|
-
|
|
292
|
-
// Find the closing ] of the opening tag
|
|
293
|
-
const openTagEnd = content.indexOf(']', quoteEnd);
|
|
294
|
-
if (openTagEnd === -1) break;
|
|
295
|
-
|
|
296
|
-
// Find the closing [/tool]
|
|
297
|
-
const closeIndex = content.indexOf(closeMarker, openTagEnd);
|
|
298
|
-
if (closeIndex === -1) break;
|
|
299
|
-
|
|
300
|
-
// Extract tool content between the tags
|
|
301
|
-
const toolContent = content.substring(openTagEnd + 1, closeIndex);
|
|
302
|
-
const fullMatch = content.substring(openIndex, closeIndex + closeMarker.length);
|
|
303
|
-
|
|
304
|
-
console.log(`TagParser DEBUG: extractBracketNotationTools - found ${toolId} tool`);
|
|
305
|
-
|
|
306
|
-
const command = {
|
|
307
|
-
type: COMMAND_FORMATS.XML,
|
|
308
|
-
toolId: toolId,
|
|
309
|
-
attributes: {},
|
|
310
|
-
parameters: this.parseXMLParameters(toolContent),
|
|
311
|
-
rawContent: fullMatch.trim(),
|
|
312
|
-
blockContent: fullMatch.trim()
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
commands.push(command);
|
|
316
|
-
position = closeIndex + closeMarker.length;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
return commands;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Extract tool tags by name using string functions
|
|
324
|
-
* @param {string} content - Content to search
|
|
325
|
-
* @param {string} toolName - Tool name to extract (e.g., 'taskmanager')
|
|
326
|
-
* @returns {Array} Array of extracted tool commands
|
|
327
|
-
*/
|
|
328
|
-
extractToolByName(content, toolName) {
|
|
329
|
-
const commands = [];
|
|
330
|
-
const openTag = `<${toolName}>`;
|
|
331
|
-
const closeTag = `</${toolName}>`;
|
|
332
|
-
|
|
333
|
-
let position = 0;
|
|
334
|
-
|
|
335
|
-
while (position < content.length) {
|
|
336
|
-
const openTagStart = content.indexOf(openTag, position);
|
|
337
|
-
if (openTagStart === -1) break;
|
|
338
|
-
|
|
339
|
-
const openTagEnd = openTagStart + openTag.length;
|
|
340
|
-
const closeTagStart = content.indexOf(closeTag, openTagEnd);
|
|
341
|
-
|
|
342
|
-
if (closeTagStart === -1) {
|
|
343
|
-
position = openTagEnd;
|
|
344
|
-
continue;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
const toolContent = content.substring(openTagEnd, closeTagStart);
|
|
348
|
-
const fullMatch = content.substring(openTagStart, closeTagStart + closeTag.length);
|
|
349
|
-
|
|
350
|
-
console.log(`TagParser DEBUG: extractToolByName - found ${toolName} tool`);
|
|
351
|
-
|
|
352
|
-
const command = {
|
|
353
|
-
type: COMMAND_FORMATS.XML,
|
|
354
|
-
toolId: toolName,
|
|
355
|
-
attributes: {},
|
|
356
|
-
parameters: this.parseXMLParameters(toolContent),
|
|
357
|
-
rawContent: fullMatch.trim(),
|
|
358
|
-
blockContent: fullMatch.trim()
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
commands.push(command);
|
|
362
|
-
position = closeTagStart + closeTag.length;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
return commands;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Extract JSON-style tool commands
|
|
370
|
-
* @param {string} content - Content to parse
|
|
371
|
-
* @returns {Array} Array of parsed JSON tool commands
|
|
372
|
-
*/
|
|
373
|
-
extractJSONToolCommands(content) {
|
|
374
|
-
const commands = [];
|
|
375
|
-
|
|
376
|
-
// Method 1: Find JSON in markdown code blocks (preferred format)
|
|
377
|
-
commands.push(...this.extractJSONCodeBlocks(content));
|
|
378
|
-
|
|
379
|
-
// Method 2: Find plain JSON objects (fallback for agents that don't use code blocks)
|
|
380
|
-
commands.push(...this.extractPlainJSON(content));
|
|
381
|
-
|
|
382
|
-
return commands;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Extract JSON from markdown code blocks using string functions
|
|
387
|
-
* @private
|
|
388
|
-
*/
|
|
389
|
-
extractJSONCodeBlocks(content) {
|
|
390
|
-
const commands = [];
|
|
391
|
-
let searchIndex = 0;
|
|
392
|
-
|
|
393
|
-
while (true) {
|
|
394
|
-
// Find opening marker
|
|
395
|
-
const startMarker = '```json';
|
|
396
|
-
const endMarker = '```';
|
|
397
|
-
|
|
398
|
-
const startIndex = content.indexOf(startMarker, searchIndex);
|
|
399
|
-
if (startIndex === -1) break;
|
|
400
|
-
|
|
401
|
-
// Find closing marker
|
|
402
|
-
const contentStart = startIndex + startMarker.length;
|
|
403
|
-
const endIndex = content.indexOf(endMarker, contentStart);
|
|
404
|
-
if (endIndex === -1) break;
|
|
405
|
-
|
|
406
|
-
// Extract JSON content
|
|
407
|
-
const jsonString = content.substring(contentStart, endIndex).trim();
|
|
408
|
-
|
|
409
|
-
try {
|
|
410
|
-
const jsonData = JSON.parse(jsonString);
|
|
411
|
-
|
|
412
|
-
if (this.isToolCommandJSON(jsonData)) {
|
|
413
|
-
// ARCHITECTURAL PRINCIPLE: Use OUTER layer (toolId) for tool identification
|
|
414
|
-
const toolId = jsonData.toolId || jsonData.tool;
|
|
415
|
-
|
|
416
|
-
// Skip if no explicit outer tool identifier
|
|
417
|
-
if (!toolId || toolId === 'unknown') {
|
|
418
|
-
console.log('TagParser DEBUG: Skipping JSON block - missing explicit toolId');
|
|
419
|
-
searchIndex = endIndex + endMarker.length;
|
|
420
|
-
continue;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
const command = {
|
|
424
|
-
type: COMMAND_FORMATS.JSON,
|
|
425
|
-
toolId: toolId,
|
|
426
|
-
parameters: jsonData.parameters || jsonData.actions || {},
|
|
427
|
-
actions: jsonData.actions,
|
|
428
|
-
rawContent: content.substring(startIndex, endIndex + endMarker.length),
|
|
429
|
-
jsonData
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
commands.push(command);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// Handle toolCommands array format
|
|
436
|
-
if (jsonData.toolCommands && Array.isArray(jsonData.toolCommands)) {
|
|
437
|
-
for (const toolCommand of jsonData.toolCommands) {
|
|
438
|
-
if (this.isToolCommandJSON(toolCommand)) {
|
|
439
|
-
// ARCHITECTURAL PRINCIPLE: Use OUTER layer (toolId) for tool identification
|
|
440
|
-
const toolId = toolCommand.toolId || toolCommand.tool;
|
|
441
|
-
|
|
442
|
-
// Skip if no explicit outer tool identifier
|
|
443
|
-
if (!toolId || toolId === 'unknown') {
|
|
444
|
-
console.log('TagParser DEBUG: Skipping toolCommand - missing explicit toolId');
|
|
445
|
-
continue;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
const command = {
|
|
449
|
-
type: COMMAND_FORMATS.JSON,
|
|
450
|
-
toolId: toolId,
|
|
451
|
-
parameters: toolCommand.parameters || toolCommand.actions || {},
|
|
452
|
-
actions: toolCommand.actions,
|
|
453
|
-
rawContent: JSON.stringify(toolCommand, null, 2),
|
|
454
|
-
jsonData: toolCommand
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
commands.push(command);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
} catch (error) {
|
|
463
|
-
// Invalid JSON, skip this block
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
searchIndex = endIndex + endMarker.length;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
return commands;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* Extract plain JSON objects using string functions
|
|
474
|
-
* @private
|
|
475
|
-
*/
|
|
476
|
-
extractPlainJSON(content) {
|
|
477
|
-
const commands = [];
|
|
478
|
-
const lines = content.split('\n');
|
|
479
|
-
|
|
480
|
-
for (let i = 0; i < lines.length; i++) {
|
|
481
|
-
const line = lines[i].trim();
|
|
482
|
-
|
|
483
|
-
// Skip if line doesn't start with {
|
|
484
|
-
if (!line.startsWith('{')) continue;
|
|
485
|
-
|
|
486
|
-
// Try to find complete JSON object
|
|
487
|
-
let jsonString = '';
|
|
488
|
-
let braceCount = 0;
|
|
489
|
-
let foundComplete = false;
|
|
490
|
-
|
|
491
|
-
// Start from current line and look for complete JSON
|
|
492
|
-
for (let j = i; j < lines.length; j++) {
|
|
493
|
-
const currentLine = lines[j].trim();
|
|
494
|
-
jsonString += (j > i ? '\n' : '') + currentLine;
|
|
495
|
-
|
|
496
|
-
// Count braces to find complete object
|
|
497
|
-
for (const char of currentLine) {
|
|
498
|
-
if (char === '{') braceCount++;
|
|
499
|
-
if (char === '}') braceCount--;
|
|
500
|
-
if (braceCount === 0 && char === '}') {
|
|
501
|
-
foundComplete = true;
|
|
502
|
-
break;
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
if (foundComplete) break;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
if (!foundComplete) continue;
|
|
510
|
-
|
|
511
|
-
try {
|
|
512
|
-
const jsonData = JSON.parse(jsonString);
|
|
513
|
-
|
|
514
|
-
// ARCHITECTURAL PRINCIPLE: Use OUTER layer for tool identification
|
|
515
|
-
// Only parse INNER content (actions, type) if OUTER identifier missing
|
|
516
|
-
// This follows the layered invocation hierarchy:
|
|
517
|
-
// OUTER (message level): Tool identification via "toolId"
|
|
518
|
-
// INNER (payload level): Action specification via "type"
|
|
519
|
-
|
|
520
|
-
// Check if this JSON looks like a tool command
|
|
521
|
-
if (this.isToolCommandJSON(jsonData) ||
|
|
522
|
-
(jsonData.actions && Array.isArray(jsonData.actions)) ||
|
|
523
|
-
(jsonData.type && typeof jsonData.type === 'string')) {
|
|
524
|
-
|
|
525
|
-
// CRITICAL: Use OUTER identifier first, only infer from INNER as fallback
|
|
526
|
-
const toolId = jsonData.toolId || jsonData.tool || this.inferToolFromActions(jsonData);
|
|
527
|
-
|
|
528
|
-
// Skip if we couldn't determine a valid tool
|
|
529
|
-
if (!toolId || toolId === 'unknown') {
|
|
530
|
-
console.log('TagParser DEBUG: Skipping plain JSON - could not determine valid toolId');
|
|
531
|
-
continue;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
const command = {
|
|
535
|
-
type: COMMAND_FORMATS.JSON_PLAIN,
|
|
536
|
-
toolId: toolId,
|
|
537
|
-
parameters: jsonData.parameters || jsonData,
|
|
538
|
-
actions: jsonData.actions,
|
|
539
|
-
rawContent: jsonString,
|
|
540
|
-
jsonData,
|
|
541
|
-
warning: 'Plain JSON detected - should use ```json blocks'
|
|
542
|
-
};
|
|
543
|
-
|
|
544
|
-
commands.push(command);
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
} catch (error) {
|
|
548
|
-
// Invalid JSON, skip
|
|
549
|
-
continue;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
return commands;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
/**
|
|
557
|
-
* Infer tool ID from JSON structure
|
|
558
|
-
* Uses the constants-based approach for deterministic tool identification
|
|
559
|
-
* @private
|
|
560
|
-
*/
|
|
561
|
-
inferToolFromActions(jsonData) {
|
|
562
|
-
const structure = identifyJsonStructure(jsonData);
|
|
563
|
-
|
|
564
|
-
switch (structure) {
|
|
565
|
-
case JSON_STRUCTURES.STANDARD:
|
|
566
|
-
// Already has toolId
|
|
567
|
-
return jsonData.toolId || 'unknown';
|
|
568
|
-
|
|
569
|
-
case JSON_STRUCTURES.ACTIONS_ARRAY:
|
|
570
|
-
// Get tool from first action type
|
|
571
|
-
if (jsonData.actions && jsonData.actions.length > 0) {
|
|
572
|
-
const firstAction = jsonData.actions[0];
|
|
573
|
-
const toolId = getToolIdFromAction(firstAction.type);
|
|
574
|
-
return toolId || 'unknown';
|
|
575
|
-
}
|
|
576
|
-
break;
|
|
577
|
-
|
|
578
|
-
case JSON_STRUCTURES.DIRECT_ACTION:
|
|
579
|
-
// Get tool from type field
|
|
580
|
-
const toolId = getToolIdFromAction(jsonData.type);
|
|
581
|
-
return toolId || 'unknown';
|
|
582
|
-
|
|
583
|
-
case JSON_STRUCTURES.TOOL_COMMANDS:
|
|
584
|
-
// Get from first command
|
|
585
|
-
if (jsonData.toolCommands && jsonData.toolCommands.length > 0) {
|
|
586
|
-
return this.inferToolFromActions(jsonData.toolCommands[0]);
|
|
587
|
-
}
|
|
588
|
-
break;
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
return 'unknown';
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
/**
|
|
595
|
-
* Extract agent redirects from content
|
|
596
|
-
* @param {string} content - Content to parse
|
|
597
|
-
* @returns {Array} Array of parsed agent redirects
|
|
598
|
-
*/
|
|
599
|
-
extractAgentRedirects(content) {
|
|
600
|
-
const redirects = [];
|
|
601
|
-
|
|
602
|
-
const matches = this.matchAll(content, this.patterns.agentRedirect);
|
|
603
|
-
|
|
604
|
-
for (const match of matches) {
|
|
605
|
-
const attributeString = match.groups[1];
|
|
606
|
-
const messageContent = match.groups[2].trim();
|
|
607
|
-
|
|
608
|
-
const attributes = this.parseAttributes(attributeString);
|
|
609
|
-
|
|
610
|
-
const redirect = {
|
|
611
|
-
to: attributes.to,
|
|
612
|
-
content: messageContent,
|
|
613
|
-
urgent: attributes[AGENT_REDIRECT_ATTRIBUTES.URGENT] === 'true',
|
|
614
|
-
requiresResponse: attributes[AGENT_REDIRECT_ATTRIBUTES.REQUIRES_RESPONSE] === 'true',
|
|
615
|
-
context: attributes[AGENT_REDIRECT_ATTRIBUTES.CONTEXT],
|
|
616
|
-
rawMatch: match.match
|
|
617
|
-
};
|
|
618
|
-
|
|
619
|
-
// Add any additional attributes
|
|
620
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
621
|
-
if (!['to', AGENT_REDIRECT_ATTRIBUTES.URGENT, AGENT_REDIRECT_ATTRIBUTES.REQUIRES_RESPONSE, AGENT_REDIRECT_ATTRIBUTES.CONTEXT].includes(key)) {
|
|
622
|
-
redirect[key] = value;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
redirects.push(redirect);
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
return redirects;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
/**
|
|
633
|
-
* Parse XML parameters from tool content
|
|
634
|
-
* @param {string} content - Tool content to parse
|
|
635
|
-
* @returns {Object} Parsed parameters
|
|
636
|
-
*/
|
|
637
|
-
parseXMLParameters(content) {
|
|
638
|
-
const parameters = {};
|
|
639
|
-
|
|
640
|
-
console.log('TagParser DEBUG: parseXMLParameters - content length:', content.length);
|
|
641
|
-
|
|
642
|
-
let position = 0;
|
|
643
|
-
let foundCount = 0;
|
|
644
|
-
|
|
645
|
-
// Look for opening tags like <write>, <read>, etc.
|
|
646
|
-
while (position < content.length) {
|
|
647
|
-
const openTagStart = content.indexOf('<', position);
|
|
648
|
-
if (openTagStart === -1) break;
|
|
649
|
-
|
|
650
|
-
const openTagEnd = content.indexOf('>', openTagStart);
|
|
651
|
-
if (openTagEnd === -1) break;
|
|
652
|
-
|
|
653
|
-
// Extract the full opening tag
|
|
654
|
-
const openTag = content.substring(openTagStart, openTagEnd + 1);
|
|
655
|
-
|
|
656
|
-
// Parse tag name and attributes from the opening tag
|
|
657
|
-
const spaceIndex = openTag.indexOf(' ');
|
|
658
|
-
const tagName = spaceIndex > 0
|
|
659
|
-
? openTag.substring(1, spaceIndex)
|
|
660
|
-
: openTag.substring(1, openTag.length - 1);
|
|
661
|
-
|
|
662
|
-
const isValid = this.isValidXmlTagName(tagName);
|
|
663
|
-
|
|
664
|
-
// Skip malformed tags or content that looks like code
|
|
665
|
-
if (tagName.includes('/') || !tagName || !this.isValidXmlTagName(tagName)) {
|
|
666
|
-
position = openTagEnd + 1;
|
|
667
|
-
continue;
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
// Check if this is a self-closing tag (ends with />)
|
|
671
|
-
const isSelfClosing = openTag.endsWith('/>');
|
|
672
|
-
|
|
673
|
-
let tagContent = '';
|
|
674
|
-
let closingTagStart = openTagEnd;
|
|
675
|
-
|
|
676
|
-
if (isSelfClosing) {
|
|
677
|
-
// Self-closing tag has no content
|
|
678
|
-
tagContent = '';
|
|
679
|
-
closingTagStart = openTagEnd; // Position right after the self-closing tag
|
|
680
|
-
} else {
|
|
681
|
-
// Look for the closing tag
|
|
682
|
-
const closingTag = `</${tagName}>`;
|
|
683
|
-
closingTagStart = content.indexOf(closingTag, openTagEnd + 1);
|
|
684
|
-
|
|
685
|
-
if (closingTagStart === -1) {
|
|
686
|
-
position = openTagEnd + 1;
|
|
687
|
-
continue;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
// Extract the content between tags
|
|
691
|
-
tagContent = content.substring(openTagEnd + 1, closingTagStart);
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
// Extract attributes from the opening tag
|
|
695
|
-
let attributeString = spaceIndex > 0
|
|
696
|
-
? openTag.substring(spaceIndex + 1, openTag.length - 1).trim()
|
|
697
|
-
: '';
|
|
698
|
-
|
|
699
|
-
// For self-closing tags, remove the trailing '/' from attributes
|
|
700
|
-
if (isSelfClosing && attributeString.endsWith('/')) {
|
|
701
|
-
attributeString = attributeString.substring(0, attributeString.length - 1).trim();
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
const attributes = this.parseAttributes(attributeString);
|
|
705
|
-
|
|
706
|
-
console.log('TagParser DEBUG: parseXMLParameters - found match:', {
|
|
707
|
-
paramName: tagName,
|
|
708
|
-
attributeString,
|
|
709
|
-
valueLength: tagContent.length,
|
|
710
|
-
valuePreview: tagContent.substring(0, 50) + (tagContent.length > 50 ? '...' : '')
|
|
711
|
-
});
|
|
712
|
-
|
|
713
|
-
// CRITICAL FIX: Handle multiple tags with same name (e.g., multiple <write> tags)
|
|
714
|
-
// Convert to array if duplicate detected
|
|
715
|
-
const paramValue = {
|
|
716
|
-
value: tagContent.trim(),
|
|
717
|
-
attributes
|
|
718
|
-
};
|
|
719
|
-
|
|
720
|
-
if (parameters[tagName]) {
|
|
721
|
-
// Tag already exists - convert to array or append to existing array
|
|
722
|
-
if (Array.isArray(parameters[tagName])) {
|
|
723
|
-
// Already an array, append
|
|
724
|
-
parameters[tagName].push(paramValue);
|
|
725
|
-
console.log('TagParser DEBUG: appended to existing array for tag:', tagName, 'count:', parameters[tagName].length);
|
|
726
|
-
} else {
|
|
727
|
-
// First duplicate - convert to array
|
|
728
|
-
const existingValue = parameters[tagName];
|
|
729
|
-
parameters[tagName] = [existingValue, paramValue];
|
|
730
|
-
console.log('TagParser DEBUG: converted to array for duplicate tag:', tagName);
|
|
731
|
-
}
|
|
732
|
-
} else {
|
|
733
|
-
// First occurrence - store as single object
|
|
734
|
-
parameters[tagName] = paramValue;
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
// For convenience, also store direct access to value (deprecated, kept for backward compatibility)
|
|
738
|
-
// Only define if it doesn't exist (handles multiple tags with same name)
|
|
739
|
-
const valuePropertyName = tagName + '_value';
|
|
740
|
-
if (!Object.prototype.hasOwnProperty.call(parameters, valuePropertyName)) {
|
|
741
|
-
Object.defineProperty(parameters, valuePropertyName, {
|
|
742
|
-
value: tagContent.trim(),
|
|
743
|
-
enumerable: false
|
|
744
|
-
});
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
foundCount++;
|
|
748
|
-
|
|
749
|
-
// Update position based on whether it's self-closing or paired tags
|
|
750
|
-
if (isSelfClosing) {
|
|
751
|
-
position = openTagEnd + 1;
|
|
752
|
-
} else {
|
|
753
|
-
const closingTag = `</${tagName}>`;
|
|
754
|
-
position = closingTagStart + closingTag.length;
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
console.log('TagParser DEBUG: parseXMLParameters - matches found:', foundCount);
|
|
759
|
-
console.log('TagParser DEBUG: parseXMLParameters - final parameters:', Object.keys(parameters));
|
|
760
|
-
return parameters;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
/**
|
|
764
|
-
* Parse attributes from attribute string
|
|
765
|
-
* @param {string} attributeString - Attribute string to parse
|
|
766
|
-
* @returns {Object} Parsed attributes
|
|
767
|
-
*/
|
|
768
|
-
parseAttributes(attributeString) {
|
|
769
|
-
const attributes = {};
|
|
770
|
-
|
|
771
|
-
if (!attributeString) return attributes;
|
|
772
|
-
|
|
773
|
-
const attrMatches = this.matchAll(attributeString, this.patterns.attribute);
|
|
774
|
-
|
|
775
|
-
for (const match of attrMatches) {
|
|
776
|
-
const attrName = match.groups[0];
|
|
777
|
-
const attrValue = match.groups[1];
|
|
778
|
-
|
|
779
|
-
attributes[attrName] = attrValue;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
return attributes;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
/**
|
|
786
|
-
* Extract content from tags
|
|
787
|
-
* @param {string} content - Content to search
|
|
788
|
-
* @param {string} tagName - Tag name to extract
|
|
789
|
-
* @returns {Array} Array of extracted content strings
|
|
790
|
-
*/
|
|
791
|
-
static extractContent(content, tagName) {
|
|
792
|
-
const pattern = new RegExp(`<${tagName}[^>]*>([^<]*)<\\/${tagName}>`, 'g');
|
|
793
|
-
const matches = [];
|
|
794
|
-
let match;
|
|
795
|
-
|
|
796
|
-
while ((match = pattern.exec(content)) !== null) {
|
|
797
|
-
matches.push(match[1].trim());
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
return matches;
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
/**
|
|
804
|
-
* Extract tag with attributes
|
|
805
|
-
* @param {string} content - Content to search
|
|
806
|
-
* @param {string} tagName - Tag name to extract
|
|
807
|
-
* @returns {Array} Array of extracted tag objects with content and attributes
|
|
808
|
-
*/
|
|
809
|
-
static extractTagsWithAttributes(content, tagName) {
|
|
810
|
-
const pattern = new RegExp(`<${tagName}\\s*([^>]*)>([^<]*)<\\/${tagName}>`, 'g');
|
|
811
|
-
const tags = [];
|
|
812
|
-
let match;
|
|
813
|
-
|
|
814
|
-
while ((match = pattern.exec(content)) !== null) {
|
|
815
|
-
const attributeString = match[1];
|
|
816
|
-
const tagContent = match[2].trim();
|
|
817
|
-
|
|
818
|
-
const parser = new TagParser();
|
|
819
|
-
const attributes = parser.parseAttributes(attributeString);
|
|
820
|
-
|
|
821
|
-
tags.push({
|
|
822
|
-
content: tagContent,
|
|
823
|
-
attributes,
|
|
824
|
-
rawMatch: match[0]
|
|
825
|
-
});
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
return tags;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
/**
|
|
832
|
-
* Check if JSON object represents a tool command
|
|
833
|
-
* @private
|
|
834
|
-
*/
|
|
835
|
-
isToolCommandJSON(obj) {
|
|
836
|
-
return obj &&
|
|
837
|
-
typeof obj === 'object' &&
|
|
838
|
-
(obj.toolId || obj.tool) &&
|
|
839
|
-
(obj.parameters || obj.actions);
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
/**
|
|
843
|
-
* Match all occurrences of a pattern
|
|
844
|
-
* @private
|
|
845
|
-
*/
|
|
846
|
-
matchAll(content, pattern) {
|
|
847
|
-
const matches = [];
|
|
848
|
-
let match;
|
|
849
|
-
|
|
850
|
-
// Reset pattern lastIndex to ensure clean matching
|
|
851
|
-
pattern.lastIndex = 0;
|
|
852
|
-
|
|
853
|
-
while ((match = pattern.exec(content)) !== null) {
|
|
854
|
-
matches.push({
|
|
855
|
-
match: match[0],
|
|
856
|
-
groups: match.slice(1),
|
|
857
|
-
index: match.index
|
|
858
|
-
});
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
return matches;
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
/**
|
|
865
|
-
* Validate tool command structure
|
|
866
|
-
* @param {Object} command - Tool command to validate
|
|
867
|
-
* @returns {Object} Validation result
|
|
868
|
-
*/
|
|
869
|
-
validateToolCommand(command) {
|
|
870
|
-
const errors = [];
|
|
871
|
-
|
|
872
|
-
if (!command.toolId) {
|
|
873
|
-
errors.push('Missing toolId');
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
if (!command.parameters && !command.actions) {
|
|
877
|
-
errors.push('Missing parameters or actions');
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
if (command.type === 'xml') {
|
|
881
|
-
if (!command.rawContent) {
|
|
882
|
-
errors.push('Missing rawContent for XML command');
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
// Validate XML parameter structure
|
|
886
|
-
if (command.parameters) {
|
|
887
|
-
for (const [paramName, paramData] of Object.entries(command.parameters)) {
|
|
888
|
-
if (typeof paramData !== 'object' || !('value' in paramData)) {
|
|
889
|
-
errors.push(`Invalid parameter structure for ${paramName}`);
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
if (command.type === 'json') {
|
|
896
|
-
if (!command.jsonData) {
|
|
897
|
-
errors.push('Missing jsonData for JSON command');
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
return {
|
|
902
|
-
valid: errors.length === 0,
|
|
903
|
-
errors
|
|
904
|
-
};
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
/**
|
|
908
|
-
* Normalize tool command to consistent format
|
|
909
|
-
* @param {Object} command - Tool command to normalize
|
|
910
|
-
* @returns {Object} Normalized command
|
|
911
|
-
*/
|
|
912
|
-
normalizeToolCommand(command) {
|
|
913
|
-
const normalized = {
|
|
914
|
-
toolId: command.toolId,
|
|
915
|
-
type: command.type,
|
|
916
|
-
parameters: {},
|
|
917
|
-
rawContent: command.rawContent
|
|
918
|
-
};
|
|
919
|
-
|
|
920
|
-
if (command.type === COMMAND_FORMATS.XML) {
|
|
921
|
-
console.log('TagParser DEBUG: normalizing XML command with parameters:', Object.keys(command.parameters || {}));
|
|
922
|
-
|
|
923
|
-
// SPECIAL CASE: AgentDelay tool expects flat object {duration, reason}, not actions array
|
|
924
|
-
if (command.toolId === 'agentdelay') {
|
|
925
|
-
const params = command.parameters || {};
|
|
926
|
-
|
|
927
|
-
// Extract duration and reason
|
|
928
|
-
if (params['pause-duration']) {
|
|
929
|
-
const durationStr = params['pause-duration'].value;
|
|
930
|
-
normalized.parameters.duration = parseInt(durationStr, 10);
|
|
931
|
-
}
|
|
932
|
-
if (params['reason']) {
|
|
933
|
-
normalized.parameters.reason = params['reason'].value.trim();
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
console.log('TagParser DEBUG: delay tool - flat parameters:', normalized.parameters);
|
|
937
|
-
return normalized;
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
// SPECIAL CASE: ImageGen tool has its own XML parser, pass raw content directly
|
|
941
|
-
if (command.toolId === 'image-gen') {
|
|
942
|
-
const params = command.parameters || {};
|
|
943
|
-
|
|
944
|
-
// Extract the inner XML content (without the <image-gen> wrapper)
|
|
945
|
-
// ImageTool.parseParameters() expects just the inner tags
|
|
946
|
-
let xmlContent = '';
|
|
947
|
-
for (const [key, paramData] of Object.entries(params)) {
|
|
948
|
-
xmlContent += `<${key}>${paramData.value}</${key}>\n`;
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
// Store the raw XML for ImageTool to parse
|
|
952
|
-
normalized.parameters = xmlContent.trim();
|
|
953
|
-
|
|
954
|
-
console.log('TagParser DEBUG: image-gen tool - passing raw XML to ImageTool:', xmlContent.substring(0, 100) + '...');
|
|
955
|
-
return normalized;
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
// NORMAL CASE: Convert XML parameters to actions array format for most tools
|
|
959
|
-
const actions = [];
|
|
960
|
-
|
|
961
|
-
for (const [key, paramData] of Object.entries(command.parameters || {})) {
|
|
962
|
-
console.log('TagParser DEBUG: processing XML parameter:', key, 'with data:', paramData);
|
|
963
|
-
|
|
964
|
-
// CRITICAL FIX: Handle both single object and array of objects (for duplicate tags)
|
|
965
|
-
const paramDataArray = Array.isArray(paramData) ? paramData : [paramData];
|
|
966
|
-
|
|
967
|
-
for (const singleParamData of paramDataArray) {
|
|
968
|
-
// Convert XML tags to action objects
|
|
969
|
-
const action = {
|
|
970
|
-
type: key, // e.g., "write", "read", "delete", "run-command"
|
|
971
|
-
...singleParamData.attributes // e.g., output-path, file-path, etc.
|
|
972
|
-
};
|
|
973
|
-
|
|
974
|
-
// Add content if it exists
|
|
975
|
-
if (singleParamData.value && singleParamData.value.trim()) {
|
|
976
|
-
action.content = singleParamData.value.trim();
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
console.log('TagParser DEBUG: created action before normalization:', action);
|
|
980
|
-
|
|
981
|
-
// Convert attribute names to camelCase for consistency
|
|
982
|
-
const normalizedAction = {};
|
|
983
|
-
for (const [attrKey, attrValue] of Object.entries(action)) {
|
|
984
|
-
const normalizedKey = this._toCamelCase(attrKey);
|
|
985
|
-
normalizedAction[normalizedKey] = attrValue;
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
// CRITICAL FIX: Map 'content' field to tool-specific field names based on action type
|
|
989
|
-
if (normalizedAction.content !== undefined) {
|
|
990
|
-
const contentFieldMapping = {
|
|
991
|
-
// Terminal tool mappings
|
|
992
|
-
'run-command': 'command',
|
|
993
|
-
'create-directory': 'directory',
|
|
994
|
-
'change-directory': 'directory',
|
|
995
|
-
'list-directory': 'directory',
|
|
996
|
-
'get-working-directory': null, // No content field needed
|
|
997
|
-
|
|
998
|
-
// FileSystem tool mappings
|
|
999
|
-
'write': null, // Uses content for file content (keep as-is)
|
|
1000
|
-
'read': 'filePath',
|
|
1001
|
-
'delete': 'filePath',
|
|
1002
|
-
'copy': null, // Uses attributes (source, destination)
|
|
1003
|
-
'move': null, // Uses attributes (source, destination)
|
|
1004
|
-
'append': 'filePath',
|
|
1005
|
-
'create-dir': 'directory',
|
|
1006
|
-
'list': 'directory',
|
|
1007
|
-
'exists': 'path',
|
|
1008
|
-
'stats': 'path',
|
|
1009
|
-
|
|
1010
|
-
// TaskManager tool mappings
|
|
1011
|
-
'action': null, // Keep as content
|
|
1012
|
-
'title': null,
|
|
1013
|
-
'description': null,
|
|
1014
|
-
'priority': null,
|
|
1015
|
-
'taskId': null,
|
|
1016
|
-
'status': null
|
|
1017
|
-
};
|
|
1018
|
-
|
|
1019
|
-
const mappedFieldName = contentFieldMapping[normalizedAction.type];
|
|
1020
|
-
|
|
1021
|
-
if (mappedFieldName) {
|
|
1022
|
-
// Map content to the specific field name
|
|
1023
|
-
normalizedAction[mappedFieldName] = normalizedAction.content;
|
|
1024
|
-
delete normalizedAction.content;
|
|
1025
|
-
console.log(`TagParser DEBUG: mapped 'content' to '${mappedFieldName}' for action type '${normalizedAction.type}'`);
|
|
1026
|
-
} else if (mappedFieldName === null) {
|
|
1027
|
-
// Explicitly keep as content or remove if not needed
|
|
1028
|
-
console.log(`TagParser DEBUG: keeping action type '${normalizedAction.type}' as-is`);
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
console.log('TagParser DEBUG: final normalized action:', normalizedAction);
|
|
1033
|
-
actions.push(normalizedAction);
|
|
1034
|
-
} // End inner loop for paramDataArray
|
|
1035
|
-
|
|
1036
|
-
// Preserve original format for backward compatibility (use first value if array)
|
|
1037
|
-
const backwardCompatValue = Array.isArray(paramData) ? paramData[0] : paramData;
|
|
1038
|
-
normalized.parameters[key] = backwardCompatValue.value;
|
|
1039
|
-
if (backwardCompatValue.attributes && Object.keys(backwardCompatValue.attributes).length > 0) {
|
|
1040
|
-
normalized.parameters[`${key}_attributes`] = backwardCompatValue.attributes;
|
|
1041
|
-
}
|
|
1042
|
-
} // End outer loop for parameters
|
|
1043
|
-
|
|
1044
|
-
console.log('TagParser DEBUG: total actions created:', actions.length);
|
|
1045
|
-
|
|
1046
|
-
// Add actions array if we found any XML actions
|
|
1047
|
-
if (actions.length > 0) {
|
|
1048
|
-
normalized.parameters.actions = actions;
|
|
1049
|
-
console.log('TagParser DEBUG: added actions array to parameters');
|
|
1050
|
-
} else {
|
|
1051
|
-
console.log('TagParser DEBUG: WARNING - no actions created, this will cause "actions is not iterable" error');
|
|
1052
|
-
}
|
|
1053
|
-
} else if (command.type === COMMAND_FORMATS.JSON || command.type === COMMAND_FORMATS.JSON_PLAIN) {
|
|
1054
|
-
// JSON parameters are already in simple format
|
|
1055
|
-
normalized.parameters = { ...command.parameters };
|
|
1056
|
-
|
|
1057
|
-
// Handle actions array format (common in agentcommunication tool)
|
|
1058
|
-
if (command.actions && Array.isArray(command.actions)) {
|
|
1059
|
-
normalized.parameters.actions = command.actions;
|
|
1060
|
-
|
|
1061
|
-
// For agentcommunication tool, extract the action from the first item
|
|
1062
|
-
if (command.toolId === TOOL_IDS.AGENT_COMMUNICATION && command.actions.length > 0) {
|
|
1063
|
-
const firstAction = command.actions[0];
|
|
1064
|
-
normalized.parameters.action = firstAction.type || firstAction.action;
|
|
1065
|
-
// Spread the rest of the action properties
|
|
1066
|
-
Object.assign(normalized.parameters, firstAction);
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
return normalized;
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
/**
|
|
1075
|
-
* Check if a string is a valid XML tag name for tool commands
|
|
1076
|
-
* @param {string} tagName - Tag name to validate
|
|
1077
|
-
* @returns {boolean} True if valid
|
|
1078
|
-
* @private
|
|
1079
|
-
*/
|
|
1080
|
-
isValidXmlTagName(tagName) {
|
|
1081
|
-
// Valid tool command tag names: write, read, delete, copy, move, etc.
|
|
1082
|
-
const validTagNames = [
|
|
1083
|
-
'write', 'read', 'delete', 'copy', 'move', 'append',
|
|
1084
|
-
'create-dir', 'list', 'exists', 'stats',
|
|
1085
|
-
'run-command', 'cd', 'pwd',
|
|
1086
|
-
// Terminal tool tags
|
|
1087
|
-
'create-directory', 'change-directory', 'list-directory', 'get-working-directory',
|
|
1088
|
-
// Agent delay tool tags
|
|
1089
|
-
'pause-duration', 'reason',
|
|
1090
|
-
// TaskManager tool tags
|
|
1091
|
-
'action', 'title', 'description', 'priority', 'taskId', 'status',
|
|
1092
|
-
'dependsOn', 'dependencyType', 'relatedTo', 'parentTaskId',
|
|
1093
|
-
'timeframe', 'templateId', 'stage', 'milestone', 'notes',
|
|
1094
|
-
// Browser tool tags
|
|
1095
|
-
'url', 'selector', 'text', 'screenshot', 'element',
|
|
1096
|
-
// Agent communication tags
|
|
1097
|
-
'recipient', 'message', 'conversation-id',
|
|
1098
|
-
// Image generation tool tags
|
|
1099
|
-
'prompt', 'output-path', 'size', 'quality', 'model', 'batch', 'image',
|
|
1100
|
-
// General parameter tags
|
|
1101
|
-
'command', 'path', 'content', 'name', 'value', 'type', 'target'
|
|
1102
|
-
];
|
|
1103
|
-
|
|
1104
|
-
// Must be a known tag name and contain only letters, numbers, and hyphens
|
|
1105
|
-
return validTagNames.includes(tagName) && this.containsOnlyValidChars(tagName);
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
/**
|
|
1109
|
-
* Check if tag name contains only valid characters (letters, numbers, hyphens)
|
|
1110
|
-
* @param {string} tagName - Tag name to check
|
|
1111
|
-
* @returns {boolean} True if valid
|
|
1112
|
-
* @private
|
|
1113
|
-
*/
|
|
1114
|
-
containsOnlyValidChars(tagName) {
|
|
1115
|
-
if (!tagName || tagName.length === 0) return false;
|
|
1116
|
-
|
|
1117
|
-
// First character must be a letter
|
|
1118
|
-
const firstChar = tagName.charAt(0);
|
|
1119
|
-
const firstIsLetter = (firstChar >= 'a' && firstChar <= 'z') || (firstChar >= 'A' && firstChar <= 'Z');
|
|
1120
|
-
if (!firstIsLetter) {
|
|
1121
|
-
return false;
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
// Rest can be letters, numbers, or hyphens
|
|
1125
|
-
for (let i = 1; i < tagName.length; i++) {
|
|
1126
|
-
const char = tagName.charAt(i);
|
|
1127
|
-
const isLetter = (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z');
|
|
1128
|
-
const isNumber = char >= '0' && char <= '9';
|
|
1129
|
-
const isHyphen = char === '-';
|
|
1130
|
-
|
|
1131
|
-
if (!isLetter && !isNumber && !isHyphen) {
|
|
1132
|
-
return false;
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
return true;
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
/**
|
|
1140
|
-
* Check if tag name is in the valid tag list (for debugging)
|
|
1141
|
-
* @param {string} tagName - Tag name to check
|
|
1142
|
-
* @returns {boolean} True if in list
|
|
1143
|
-
* @private
|
|
1144
|
-
*/
|
|
1145
|
-
isTagInValidList(tagName) {
|
|
1146
|
-
const validTagNames = [
|
|
1147
|
-
'write', 'read', 'delete', 'copy', 'move', 'append',
|
|
1148
|
-
'create-dir', 'list', 'exists', 'stats',
|
|
1149
|
-
'run-command', 'cd', 'pwd',
|
|
1150
|
-
// Terminal tool tags
|
|
1151
|
-
'create-directory', 'change-directory', 'list-directory', 'get-working-directory',
|
|
1152
|
-
// Agent delay tool tags
|
|
1153
|
-
'pause-duration', 'reason',
|
|
1154
|
-
// TaskManager tool tags
|
|
1155
|
-
'action', 'title', 'description', 'priority', 'taskId', 'status',
|
|
1156
|
-
'dependsOn', 'dependencyType', 'relatedTo', 'parentTaskId',
|
|
1157
|
-
'timeframe', 'templateId', 'stage', 'milestone', 'notes',
|
|
1158
|
-
// Browser tool tags
|
|
1159
|
-
'url', 'selector', 'text', 'screenshot', 'element',
|
|
1160
|
-
// Agent communication tags
|
|
1161
|
-
'recipient', 'message', 'conversation-id',
|
|
1162
|
-
// Image generation tool tags
|
|
1163
|
-
'prompt', 'output-path', 'size', 'quality', 'model', 'batch', 'image',
|
|
1164
|
-
// General parameter tags
|
|
1165
|
-
'command', 'path', 'content', 'name', 'value', 'type', 'target'
|
|
1166
|
-
];
|
|
1167
|
-
return validTagNames.includes(tagName);
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
/**
|
|
1171
|
-
* Convert kebab-case or snake_case to camelCase
|
|
1172
|
-
* @private
|
|
1173
|
-
*/
|
|
1174
|
-
_toCamelCase(str) {
|
|
1175
|
-
return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase());
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
/**
|
|
1179
|
-
* Extract all content between tags, including nested tags
|
|
1180
|
-
* @param {string} content - Content to search
|
|
1181
|
-
* @param {string} startTag - Opening tag
|
|
1182
|
-
* @param {string} endTag - Closing tag
|
|
1183
|
-
* @returns {Array} Array of extracted content blocks
|
|
1184
|
-
*/
|
|
1185
|
-
static extractBetweenTags(content, startTag, endTag) {
|
|
1186
|
-
const blocks = [];
|
|
1187
|
-
let startIndex = 0;
|
|
1188
|
-
|
|
1189
|
-
while (true) {
|
|
1190
|
-
const start = content.indexOf(startTag, startIndex);
|
|
1191
|
-
if (start === -1) break;
|
|
1192
|
-
|
|
1193
|
-
const end = content.indexOf(endTag, start + startTag.length);
|
|
1194
|
-
if (end === -1) break;
|
|
1195
|
-
|
|
1196
|
-
const blockContent = content.substring(start + startTag.length, end);
|
|
1197
|
-
blocks.push({
|
|
1198
|
-
content: blockContent,
|
|
1199
|
-
fullMatch: content.substring(start, end + endTag.length),
|
|
1200
|
-
startIndex: start,
|
|
1201
|
-
endIndex: end + endTag.length
|
|
1202
|
-
});
|
|
1203
|
-
|
|
1204
|
-
startIndex = end + endTag.length;
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
return blocks;
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
/**
|
|
1211
|
-
* Clean content by removing all tool commands and agent redirects
|
|
1212
|
-
* @param {string} content - Content to clean
|
|
1213
|
-
* @returns {string} Cleaned content
|
|
1214
|
-
*/
|
|
1215
|
-
cleanContent(content) {
|
|
1216
|
-
let cleaned = content;
|
|
1217
|
-
|
|
1218
|
-
// Remove tool command blocks
|
|
1219
|
-
cleaned = cleaned.replace(this.patterns.toolCommand, '');
|
|
1220
|
-
|
|
1221
|
-
// Remove agent redirects
|
|
1222
|
-
cleaned = cleaned.replace(this.patterns.agentRedirect, '');
|
|
1223
|
-
|
|
1224
|
-
// Remove JSON tool command blocks
|
|
1225
|
-
cleaned = cleaned.replace(this.patterns.jsonBlock, (match, jsonContent) => {
|
|
1226
|
-
try {
|
|
1227
|
-
const jsonData = JSON.parse(jsonContent);
|
|
1228
|
-
if (this.isToolCommandJSON(jsonData) ||
|
|
1229
|
-
(jsonData.toolCommands && Array.isArray(jsonData.toolCommands))) {
|
|
1230
|
-
return '';
|
|
1231
|
-
}
|
|
1232
|
-
} catch {
|
|
1233
|
-
// Not a tool command JSON block, keep it
|
|
1234
|
-
}
|
|
1235
|
-
return match;
|
|
1236
|
-
});
|
|
1237
|
-
|
|
1238
|
-
// Clean up excessive whitespace
|
|
1239
|
-
cleaned = cleaned.replace(/\n\s*\n\s*\n/g, '\n\n');
|
|
1240
|
-
cleaned = cleaned.trim();
|
|
1241
|
-
|
|
1242
|
-
return cleaned;
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
export default TagParser;
|
|
1
|
+
const a0_0x66c400=a0_0x1f69;(function(_0x11bdc1,_0x1270f1){const _0xd66dc8=a0_0x1f69,_0x57c32e=_0x11bdc1();while(!![]){try{const _0x15bc30=parseInt(_0xd66dc8(0x22d))/0x1+-parseInt(_0xd66dc8(0x1f5))/0x2*(-parseInt(_0xd66dc8(0x1b8))/0x3)+-parseInt(_0xd66dc8(0x22b))/0x4+parseInt(_0xd66dc8(0x1e7))/0x5*(parseInt(_0xd66dc8(0x214))/0x6)+parseInt(_0xd66dc8(0x1fa))/0x7*(-parseInt(_0xd66dc8(0x22a))/0x8)+-parseInt(_0xd66dc8(0x213))/0x9*(-parseInt(_0xd66dc8(0x1ec))/0xa)+parseInt(_0xd66dc8(0x1ed))/0xb*(-parseInt(_0xd66dc8(0x19b))/0xc);if(_0x15bc30===_0x1270f1)break;else _0x57c32e['push'](_0x57c32e['shift']());}catch(_0x2f2a9d){_0x57c32e['push'](_0x57c32e['shift']());}}}(a0_0x138f,0x34807));import{AGENT_REDIRECT_ATTRIBUTES}from'./constants.js';function a0_0x138f(){const _0x562d64=['CgfYyw1LDgvYCW','BgfZDeLUzgv4','zwXLBwvUDa','zgvJB2rLshrTBevUDgL0AwvZ','vgfNugfYC2vYierfqLvhoIbxqvjosu5hic0GBM8Gywn0Aw9UCYbJCMvHDgvKlcb0AgLZihDPBgWGy2f1C2uGiMfJDgLVBNmGAxmGBM90igL0zxjHyMXLiIbLCNjVCG','Cgf0DgvYBNm','ygbG','x2f0DhjPyNv0zxm','z3jVDxbZ','zxH0CMfJDfrHz3nxAxrOqxr0CMLIDxrLCW','Dgv4Da','mZKZm3DvAK90qW','nMjrCxHLDW','w0Ptt05Fq09erv9cte9ds19sru1pvKvexq','DgvTCgXHDgvjza','w0jsqunlrvrFve9ptf9sru1pvKveoG','zxH0CMfJDePtt05uB29Sq29TBwfUzhm','Bw9KzwW','DgvYBwLUywW','twLZC2LUzYbQC29Urgf0ysbMB3iGsLnptIbJB21Tyw5K','DhLWzq','Aw1Hz2u','zxH0CMfJDePtt05dB2rLqMXVy2TZ','BMfTzq','Dw5RBM93BG','Aw5KzxG','AxnuB29Sq29TBwfUzePtt04','CMvHC29U','A2v5CW','zxH0CMfJDfHntfrVB2XdB21Tyw5KCW','Aw1Hz2uTz2vU','zw50CMLLCW','ve9ptf9dt01nqu5euW','Aw5MzxjuB29SrNjVBufJDgLVBNm','mtiYnJr6rNHnDLe','mZa0odi0q2f4EeDj','Aw5JBhvKzxm','mJy5nZGWB3bOyun6','ChjPB3jPDhK','BM90zxm','q09ovevyva','zhvYyxrPB24','xhmQkfTEpL0Qkt4Ow148xsOPpfWV','Bw92zq','ntGYntG4EMrsvMfM','zgvZy3jPChrPB24','twLZC2LUzYbWyxjHBwv0zxjZig9YigfJDgLVBNm','lI4U','DgfZA21HBMfNzxi','zMLSzvbHDgG','C3rHDhm','yxr0CMLIDxrLCW','C2L6zq','sLnptG','zgLYzwn0B3j5','vgfNugfYC2vYierfqLvhoIbLEhrYywn0qNjHy2TLDe5VDgf0Aw9Uvg9VBhmGlsbMB3vUzca','yNjVD3nLCG','ihrVB2W','AxnuywDjBLzHBgLKtgLZDa','ywn0Aw9UCW','DgfYz2v0','x3rVq2fTzwXdyxnL','Bg9N','uKvrvuLsrvnFuKvtue9ou0u','CgfYzw50vgfZA0LK','CMf3q29UDgvUDa','Aw5KzxHpzG','CgfYC2vbDhrYAwj1DgvZ','DMfSDwu','z2v0lxDVCMTPBMCTzgLYzwn0B3j5','CgfYC2vytuXqyxjHBwv0zxjZ','C3rHz2u','C3bSAxq','mZe3mJu5AK5JChnW','AxnwywXPzfHTBfrHz05HBwu','BgLZDa','w14+xsO+kfTEpf0QktXClW','DhjPBq','ANnVBKjSB2nR','CNvUlwnVBw1HBMq','zxH0CMfJDefNzw50uMvKAxjLy3rZ','ChvZAa','BwLSzxn0B25L','ywn0Aw9U','Dg9VBeLK','zxH0CMfJDerPCMvJDfrVB2XuywDZ','y3jLyxrLlwrPCG','zxHLyW','vgfNugfYC2vYierfqLvhoIbtA2LWCgLUzYb0B29Sq29TBwfUzcaTig1PC3nPBMCGzxHWBgLJAxqGDg9VBeLK','DgfZA0LK','Dhj1zq','Cgf0Aa','DgL0Bgu','C2vSzwn0B3i','AxnbCNjHEq','BgvUz3rO','vgfNugfYC2vYierfqLvhoIbPBwfNzs1Nzw4GDg9VBcaTihbHC3nPBMCGCMf3ifHntcb0BYbjBwfNzvrVB2W6','D2L0AcbKyxrHoG','ugXHAw4GsLnptIbKzxrLy3rLzcaTihnOB3vSzcb1C2uGygbGANnVBIbIBg9JA3m','BgLZDc1KAxjLy3rVCNK','Dg9VBa','vgfNugfYC2vYierfqLvhoIbRzwvWAw5NigfJDgLVBIb0ExbLicC','zxH0CMfJDfbSywLUsLnptG','CMvTB3zLvg9VBeLUDM9JyxrPB25cBg9JA3m','CMvSyxrLzfrV','y29TBwfUza','CMvJAxbPzw50','D3jPDgu','Dg9VBenVBw1HBMrZ','zgvMAw5LuhjVCgvYDhK','vgfNugfYC2vYierfqLvhoIbWyxjZzvHntfbHCMfTzxrLCNmGlsbTyxrJAgvZigzVDw5KoG','y2HHCKf0','y3jLyxrLlwrPCMvJDg9YEq','vgfNugfYC2vYierfqLvhoIbHChbLBMrLzcb0BYbLEgLZDgLUzYbHCNjHEsbMB3iGDgfNoG','vgfNugfYC2vYierfqLvhoIbKzwXHEsb0B29Sic0GzMXHDcbWyxjHBwv0zxjZoG','twLZC2LUzYb0B29Sswq','vvjhru5u','zxH0CMfJDejLDhDLzw5uywDZ','zxH0CMfJDfrVB2XdB21Tyw5KCW','yxnZAwDU','nZC4nZq1zgTwzeX0','vgfNugfYC2vYierfqLvhoIbLEhrYywn0vg9VBej5tMfTzsaTigzVDw5Kia','Dg9vChbLCKnHC2u','BwvZC2fNzq','C3rHDhvZ','mJeYmg9nCeXgzW','mZnjsvvqzMW','zgvSzxrL','Cgf1C2uTzhvYyxrPB24','zgvWzw5Kzw5JEvr5Cgu','vgfNugfYC2vYierfqLvhoIbWyxjZzvHntfbHCMfTzxrLCNmGlsbMAw5HBcbWyxjHBwv0zxjZoG','Dg9VBenVBw1HBMq','jYbHCY1PCW','y29UDgvUDa','mMHvAfnrDW','CMvWBgfJzq','y2XLyw5dB250zw50','zw5KC1DPDgG','Bwf0y2G','odu0D0fuugHn','u1rbtKrbuKq','Bwf0y2HbBgW','vgfNugfYC2vYierfqLvhoIbWCM9JzxnZAw5NifHntcbWyxjHBwv0zxi6','ywDLBNrKzwXHEq','yxr0CMLIDxrL','C3vIC3rYAw5N','y2HHBMDLlwrPCMvJDg9YEq','AgfZt3DUuhjVCgvYDhK','vgfNugfYC2vYierfqLvhoIbJCMvHDgvKigfJDgLVBIbIzwzVCMuGBM9YBwfSAxPHDgLVBJO','w3rVB2WGAwq9iG','w1Hntf9ut09mx1jftu9wruq6','AM9Izg9Uzq','ANnVBG'];a0_0x138f=function(){return _0x562d64;};return a0_0x138f();}import{TOOL_IDS,COMMAND_FORMATS,JSON_STRUCTURES,identifyJsonStructure,getToolIdFromAction,isValidToolId}from'./toolConstants.js';class TagParser{constructor(){this['patterns']={'toolCommand':/<tool-command>(.*?)<\/tool-command>/gs,'tool':/<tool\s+([^>]*)>(.*?)<\/tool>/gs,'parameter':/<([^>\s]+)(?:\s+([^>]*))?>(((?!<\/\1>)[\s\S])*)<\/\1>/g,'attribute':/([\w-]+)=["']([^"']*)["']/g,'agentRedirect':/\[agent-redirect\s+([^\]]*)\](.*?)\[\/agent-redirect\]/gs,'jsonBlock':/```json\s*(\{[\s\S]*?\})\s*```/g,'plainJson':/^(\{(?:[^{}]|(?:\{[^{}]*\}))*\})$/gm};}[a0_0x66c400(0x20b)](_0x44f6db){const _0x559e57=a0_0x66c400,_0x301294={'<':'<','>':'>','&':'&','"':'\x22',''':'\x27','/':'/',''':'\x27','/':'/'};return _0x44f6db[_0x559e57(0x1f6)](/&(?:lt|gt|amp|quot|#x27|#x2F|#39|#47);/g,_0x518c14=>_0x301294[_0x518c14]||_0x518c14);}[a0_0x66c400(0x1e5)](_0x371ad1){const _0x286af0=a0_0x66c400,_0x46a9e9=[],_0x177235=this['decodeHtmlEntities'](_0x371ad1),_0x47d0af=this['extractXMLToolCommands'](_0x177235);_0x46a9e9['push'](..._0x47d0af);const _0x2ac2c7=this[_0x286af0(0x21e)](_0x177235);_0x46a9e9[_0x286af0(0x1c0)](..._0x2ac2c7);const _0x4cd38c=this[_0x286af0(0x1d6)](_0x177235),_0xb57e40=this['extractPlainJSON'](_0x4cd38c);return _0x46a9e9[_0x286af0(0x1c0)](..._0xb57e40),_0x46a9e9;}['removeToolInvocationBlocks'](_0x263ca4){const _0x51ea2f=a0_0x66c400;let _0x16d2ab=_0x263ca4,_0x29ffdc=0x0;while(_0x29ffdc<_0x16d2ab[_0x51ea2f(0x1ce)]){const _0xaf9025='```json',_0xf5f3d8=_0x51ea2f(0x20e),_0x67c6c2=_0x16d2ab[_0x51ea2f(0x1b1)](_0xaf9025,_0x29ffdc);if(_0x67c6c2===-0x1)break;const _0x115557=_0x67c6c2+_0xaf9025[_0x51ea2f(0x1ce)],_0x503d43=_0x16d2ab['indexOf'](_0xf5f3d8,_0x115557);if(_0x503d43===-0x1)break;const _0x15f731=_0x16d2ab['substring'](0x0,_0x67c6c2),_0x4cd984=_0x16d2ab['substring'](_0x503d43+_0xf5f3d8['length']);_0x16d2ab=_0x15f731+'[JSON_CODE_BLOCK_REMOVED]'+_0x4cd984,_0x29ffdc=_0x67c6c2+_0x51ea2f(0x215)[_0x51ea2f(0x1ce)];}const _0x27279d=['taskmanager','filesystem',_0x51ea2f(0x21a),_0x51ea2f(0x1a7),'agentcommunication','jobdone',_0x51ea2f(0x1fe),_0x51ea2f(0x226)];for(const _0x3a38bc of _0x27279d){const _0x1431bf='<'+_0x3a38bc+'>',_0x29fb90='</'+_0x3a38bc+'>';let _0x5b7695=0x0;while(_0x5b7695<_0x16d2ab[_0x51ea2f(0x1ce)]){const _0x407e1c=_0x16d2ab[_0x51ea2f(0x1b1)](_0x1431bf,_0x5b7695);if(_0x407e1c===-0x1)break;const _0x2022cc=_0x16d2ab['indexOf'](_0x29fb90,_0x407e1c+_0x1431bf[_0x51ea2f(0x1ce)]);if(_0x2022cc===-0x1)break;const _0x33625f=_0x16d2ab['substring'](0x0,_0x407e1c),_0xcd8b4c=_0x16d2ab['substring'](_0x2022cc+_0x29fb90['length']);_0x16d2ab=_0x33625f+(_0x51ea2f(0x205)+_0x3a38bc+']')+_0xcd8b4c,_0x5b7695=_0x407e1c+('[XML_TOOL_REMOVED:'+_0x3a38bc+']')['length'];}}let _0x4130ca=0x0;while(_0x4130ca<_0x16d2ab[_0x51ea2f(0x1ce)]){const _0x48c30f=_0x51ea2f(0x204),_0x35872a=_0x16d2ab['indexOf'](_0x48c30f,_0x4130ca);if(_0x35872a===-0x1)break;const _0x411b32=_0x35872a+_0x48c30f['length'],_0x57ba1e=_0x16d2ab['indexOf']('\x22',_0x411b32);if(_0x57ba1e===-0x1)break;const _0x3ebe4a=_0x16d2ab[_0x51ea2f(0x200)](_0x411b32,_0x57ba1e),_0x4e5f47=_0x16d2ab[_0x51ea2f(0x1b1)](']',_0x57ba1e);if(_0x4e5f47===-0x1)break;const _0x511f69='[/tool]',_0x244b03=_0x16d2ab[_0x51ea2f(0x1b1)](_0x511f69,_0x4e5f47);if(_0x244b03===-0x1)break;const _0x37b961=_0x16d2ab[_0x51ea2f(0x200)](0x0,_0x35872a),_0x4f8f0d=_0x16d2ab[_0x51ea2f(0x200)](_0x244b03+_0x511f69['length']);_0x16d2ab=_0x37b961+(_0x51ea2f(0x217)+_0x3ebe4a+']')+_0x4f8f0d,_0x4130ca=_0x35872a+('[BRACKET_TOOL_REMOVED:'+_0x3ebe4a+']')[_0x51ea2f(0x1ce)];}return _0x16d2ab;}[a0_0x66c400(0x225)](_0x4a9891){const _0x4b818b=a0_0x66c400,_0x543691=[],_0xae836e=this['matchAll'](_0x4a9891,this[_0x4b818b(0x20d)][_0x4b818b(0x1f2)]);for(const _0x2abb65 of _0xae836e){const _0x31afec=_0x2abb65[_0x4b818b(0x210)][0x1],_0x2c30ba=this['matchAll'](_0x31afec,this[_0x4b818b(0x20d)][_0x4b818b(0x1d3)]);for(const _0x290fe5 of _0x2c30ba){const _0x23a37d=this[_0x4b818b(0x1b2)](_0x290fe5['groups'][0x1]),_0x25f49b=_0x290fe5['groups'][0x2],_0x476220={'type':COMMAND_FORMATS['XML'],'toolId':_0x23a37d['id'],'attributes':_0x23a37d,'parameters':this[_0x4b818b(0x1b5)](_0x25f49b),'rawContent':_0x290fe5['match'][_0x4b818b(0x1bc)](),'blockContent':_0x2abb65[_0x4b818b(0x1f9)][_0x4b818b(0x1bc)]()};_0x543691['push'](_0x476220);}}const _0x2c12e2=this[_0x4b818b(0x1c4)](_0x4a9891);_0x543691['push'](..._0x2c12e2);const _0x309359=this['extractBracketNotationTools'](_0x4a9891);return _0x543691[_0x4b818b(0x1c0)](..._0x309359),_0x543691;}['extractDirectToolTags'](_0x253398){const _0x1a31c2=a0_0x66c400,_0x177443=[],_0x5ef170=[_0x1a31c2(0x19f),'filesystem','terminal','browser','agentcommunication',_0x1a31c2(0x206),'agentdelay',_0x1a31c2(0x226)];for(const _0x5aaf7d of _0x5ef170){const _0x52e618=this['extractToolByName'](_0x253398,_0x5aaf7d);_0x177443['push'](..._0x52e618);}return _0x177443;}['extractBracketNotationTools'](_0x2ae00a){const _0x2c1f7b=a0_0x66c400,_0x53c83c=[],_0xb9cf95='[tool\x20id=\x22',_0x13e355='[/tool]';let _0x83d5db=0x0;while(_0x83d5db<_0x2ae00a['length']){const _0x13f50e=_0x2ae00a[_0x2c1f7b(0x1b1)](_0xb9cf95,_0x83d5db);if(_0x13f50e===-0x1)break;const _0x1efd0f=_0x13f50e+_0xb9cf95[_0x2c1f7b(0x1ce)],_0x229f6f=_0x2ae00a['indexOf']('\x22',_0x1efd0f);if(_0x229f6f===-0x1)break;const _0xda1bc5=_0x2ae00a[_0x2c1f7b(0x200)](_0x1efd0f,_0x229f6f),_0x5f0740=_0x2ae00a[_0x2c1f7b(0x1b1)](']',_0x229f6f);if(_0x5f0740===-0x1)break;const _0x45707f=_0x2ae00a['indexOf'](_0x13e355,_0x5f0740);if(_0x45707f===-0x1)break;const _0x23038d=_0x2ae00a['substring'](_0x5f0740+0x1,_0x45707f),_0x37fb9e=_0x2ae00a['substring'](_0x13f50e,_0x45707f+_0x13e355[_0x2c1f7b(0x1ce)]);console[_0x2c1f7b(0x1ad)](_0x2c1f7b(0x1a6)+_0xda1bc5+_0x2c1f7b(0x1a8));const _0x5f5684={'type':COMMAND_FORMATS['XML'],'toolId':_0xda1bc5,'attributes':{},'parameters':this[_0x2c1f7b(0x1b5)](_0x23038d),'rawContent':_0x37fb9e['trim'](),'blockContent':_0x37fb9e['trim']()};_0x53c83c['push'](_0x5f5684),_0x83d5db=_0x45707f+_0x13e355['length'];}return _0x53c83c;}['extractToolByName'](_0xff3d02,_0x56bf2a){const _0x486a45=a0_0x66c400,_0x8e7c60=[],_0x2d049e='<'+_0x56bf2a+'>',_0x36f5fe='</'+_0x56bf2a+'>';let _0x3546b9=0x0;while(_0x3546b9<_0xff3d02['length']){const _0x38192e=_0xff3d02['indexOf'](_0x2d049e,_0x3546b9);if(_0x38192e===-0x1)break;const _0x100a34=_0x38192e+_0x2d049e['length'],_0x32a1f5=_0xff3d02['indexOf'](_0x36f5fe,_0x100a34);if(_0x32a1f5===-0x1){_0x3546b9=_0x100a34;continue;}const _0x1cbb46=_0xff3d02[_0x486a45(0x200)](_0x100a34,_0x32a1f5),_0x1f7544=_0xff3d02[_0x486a45(0x200)](_0x38192e,_0x32a1f5+_0x36f5fe['length']);console['log'](_0x486a45(0x1e8)+_0x56bf2a+'\x20tool');const _0x38c081={'type':COMMAND_FORMATS['XML'],'toolId':_0x56bf2a,'attributes':{},'parameters':this[_0x486a45(0x1b5)](_0x1cbb46),'rawContent':_0x1f7544[_0x486a45(0x1bc)](),'blockContent':_0x1f7544[_0x486a45(0x1bc)]()};_0x8e7c60[_0x486a45(0x1c0)](_0x38c081),_0x3546b9=_0x32a1f5+_0x36f5fe[_0x486a45(0x1ce)];}return _0x8e7c60;}[a0_0x66c400(0x218)](_0x1b307d){const _0x27aaa7=a0_0x66c400,_0x4e766a=[];return _0x4e766a['push'](...this[_0x27aaa7(0x21e)](_0x1b307d)),_0x4e766a['push'](...this[_0x27aaa7(0x1d5)](_0x1b307d)),_0x4e766a;}['extractJSONCodeBlocks'](_0x14485c){const _0xd7bf34=a0_0x66c400,_0x28a830=[];let _0x9a35dd=0x0;while(!![]){const _0x42c502='```json',_0x5e0c3f='```',_0x7c4def=_0x14485c[_0xd7bf34(0x1b1)](_0x42c502,_0x9a35dd);if(_0x7c4def===-0x1)break;const _0x1e100f=_0x7c4def+_0x42c502[_0xd7bf34(0x1ce)],_0x33cfc4=_0x14485c['indexOf'](_0x5e0c3f,_0x1e100f);if(_0x33cfc4===-0x1)break;const _0x372d71=_0x14485c['substring'](_0x1e100f,_0x33cfc4)[_0xd7bf34(0x1bc)]();try{const _0x1d113c=JSON['parse'](_0x372d71);if(this[_0xd7bf34(0x222)](_0x1d113c)){const _0x267cc7=_0x1d113c[_0xd7bf34(0x1c3)]||_0x1d113c['tool'];if(!_0x267cc7||_0x267cc7==='unknown'){console[_0xd7bf34(0x1ad)]('TagParser\x20DEBUG:\x20Skipping\x20JSON\x20block\x20-\x20missing\x20explicit\x20toolId'),_0x9a35dd=_0x33cfc4+_0x5e0c3f['length'];continue;}const _0x44d492={'type':COMMAND_FORMATS['JSON'],'toolId':_0x267cc7,'parameters':_0x1d113c[_0xd7bf34(0x208)]||_0x1d113c['actions']||{},'actions':_0x1d113c[_0xd7bf34(0x1aa)],'rawContent':_0x14485c['substring'](_0x7c4def,_0x33cfc4+_0x5e0c3f[_0xd7bf34(0x1ce)]),'jsonData':_0x1d113c};_0x28a830[_0xd7bf34(0x1c0)](_0x44d492);}if(_0x1d113c[_0xd7bf34(0x1db)]&&Array['isArray'](_0x1d113c['toolCommands']))for(const _0x37ef13 of _0x1d113c['toolCommands']){if(this['isToolCommandJSON'](_0x37ef13)){const _0x1d975b=_0x37ef13['toolId']||_0x37ef13[_0xd7bf34(0x1d3)];if(!_0x1d975b||_0x1d975b===_0xd7bf34(0x220)){console['log'](_0xd7bf34(0x1c7));continue;}const _0x3249bc={'type':COMMAND_FORMATS['JSON'],'toolId':_0x1d975b,'parameters':_0x37ef13[_0xd7bf34(0x208)]||_0x37ef13['actions']||{},'actions':_0x37ef13[_0xd7bf34(0x1aa)],'rawContent':JSON['stringify'](_0x37ef13,null,0x2),'jsonData':_0x37ef13};_0x28a830['push'](_0x3249bc);}}}catch(_0xea20d7){}_0x9a35dd=_0x33cfc4+_0x5e0c3f['length'];}return _0x28a830;}['extractPlainJSON'](_0x234a88){const _0x54b93f=a0_0x66c400,_0xe4cd9a=[],_0x427759=_0x234a88[_0x54b93f(0x1b7)]('\x0a');for(let _0x1b4271=0x0;_0x1b4271<_0x427759[_0x54b93f(0x1ce)];_0x1b4271++){const _0x8f06bc=_0x427759[_0x1b4271][_0x54b93f(0x1bc)]();if(!_0x8f06bc['startsWith']('{'))continue;let _0x47cb51='',_0x41ab9f=0x0,_0x7f14f0=![];for(let _0x354ade=_0x1b4271;_0x354ade<_0x427759[_0x54b93f(0x1ce)];_0x354ade++){const _0x5295b6=_0x427759[_0x354ade]['trim']();_0x47cb51+=(_0x354ade>_0x1b4271?'\x0a':'')+_0x5295b6;for(const _0x17fdf3 of _0x5295b6){if(_0x17fdf3==='{')_0x41ab9f++;if(_0x17fdf3==='}')_0x41ab9f--;if(_0x41ab9f===0x0&&_0x17fdf3==='}'){_0x7f14f0=!![];break;}}if(_0x7f14f0)break;}if(!_0x7f14f0)continue;try{const _0x3062c9=JSON['parse'](_0x47cb51);if(this['isToolCommandJSON'](_0x3062c9)||_0x3062c9[_0x54b93f(0x1aa)]&&Array[_0x54b93f(0x1cd)](_0x3062c9[_0x54b93f(0x1aa)])||_0x3062c9[_0x54b93f(0x21c)]&&typeof _0x3062c9[_0x54b93f(0x21c)]==='string'){const _0x4d2ee1=_0x3062c9['toolId']||_0x3062c9[_0x54b93f(0x1d3)]||this['inferToolFromActions'](_0x3062c9);if(!_0x4d2ee1||_0x4d2ee1==='unknown'){console['log']('TagParser\x20DEBUG:\x20Skipping\x20plain\x20JSON\x20-\x20could\x20not\x20determine\x20valid\x20toolId');continue;}const _0x420563={'type':COMMAND_FORMATS['JSON_PLAIN'],'toolId':_0x4d2ee1,'parameters':_0x3062c9['parameters']||_0x3062c9,'actions':_0x3062c9[_0x54b93f(0x1aa)],'rawContent':_0x47cb51,'jsonData':_0x3062c9,'warning':_0x54b93f(0x1d1)};_0xe4cd9a[_0x54b93f(0x1c0)](_0x420563);}}catch(_0x7477b0){continue;}}return _0xe4cd9a;}['inferToolFromActions'](_0x1077fe){const _0x38a978=a0_0x66c400,_0x52d2f1=identifyJsonStructure(_0x1077fe);switch(_0x52d2f1){case JSON_STRUCTURES[_0x38a978(0x1fb)]:return _0x1077fe[_0x38a978(0x1c3)]||_0x38a978(0x220);case JSON_STRUCTURES['ACTIONS_ARRAY']:if(_0x1077fe[_0x38a978(0x1aa)]&&_0x1077fe['actions']['length']>0x0){const _0x1ff835=_0x1077fe['actions'][0x0],_0x2f6a6b=getToolIdFromAction(_0x1ff835[_0x38a978(0x21c)]);return _0x2f6a6b||'unknown';}break;case JSON_STRUCTURES['DIRECT_ACTION']:const _0x2a5e8d=getToolIdFromAction(_0x1077fe['type']);return _0x2a5e8d||_0x38a978(0x220);case JSON_STRUCTURES[_0x38a978(0x228)]:if(_0x1077fe['toolCommands']&&_0x1077fe[_0x38a978(0x1db)][_0x38a978(0x1ce)]>0x0)return this[_0x38a978(0x229)](_0x1077fe[_0x38a978(0x1db)][0x0]);break;}return'unknown';}[a0_0x66c400(0x1bf)](_0x356fe2){const _0x59e641=a0_0x66c400,_0x3cb65f=[],_0x314059=this['matchAll'](_0x356fe2,this[_0x59e641(0x20d)]['agentRedirect']);for(const _0x16d7dd of _0x314059){const _0x47f0ea=_0x16d7dd['groups'][0x1],_0x5a41c4=_0x16d7dd['groups'][0x2]['trim'](),_0xfa8db0=this[_0x59e641(0x1b2)](_0x47f0ea),_0x3fcf86={'to':_0xfa8db0['to'],'content':_0x5a41c4,'urgent':_0xfa8db0[AGENT_REDIRECT_ATTRIBUTES[_0x59e641(0x1e3)]]===_0x59e641(0x1c9),'requiresResponse':_0xfa8db0[AGENT_REDIRECT_ATTRIBUTES[_0x59e641(0x1ae)]]===_0x59e641(0x1c9),'context':_0xfa8db0[AGENT_REDIRECT_ATTRIBUTES[_0x59e641(0x230)]],'rawMatch':_0x16d7dd[_0x59e641(0x1f9)]};for(const [_0x9dfd83,_0x31e443]of Object[_0x59e641(0x227)](_0xfa8db0)){!['to',AGENT_REDIRECT_ATTRIBUTES[_0x59e641(0x1e3)],AGENT_REDIRECT_ATTRIBUTES[_0x59e641(0x1ae)],AGENT_REDIRECT_ATTRIBUTES['CONTEXT']]['includes'](_0x9dfd83)&&(_0x3fcf86[_0x9dfd83]=_0x31e443);}_0x3cb65f['push'](_0x3fcf86);}return _0x3cb65f;}[a0_0x66c400(0x1b5)](_0x2c5cf8){const _0x327f44=a0_0x66c400,_0x3e23b0={};console[_0x327f44(0x1ad)]('TagParser\x20DEBUG:\x20parseXMLParameters\x20-\x20content\x20length:',_0x2c5cf8[_0x327f44(0x1ce)]);let _0x1da359=0x0,_0x5ec974=0x0;while(_0x1da359<_0x2c5cf8[_0x327f44(0x1ce)]){const _0x4d5e9c=_0x2c5cf8['indexOf']('<',_0x1da359);if(_0x4d5e9c===-0x1)break;const _0x2665ed=_0x2c5cf8['indexOf']('>',_0x4d5e9c);if(_0x2665ed===-0x1)break;const _0xa4470c=_0x2c5cf8['substring'](_0x4d5e9c,_0x2665ed+0x1),_0x2e934d=_0xa4470c[_0x327f44(0x1b1)]('\x20'),_0x392fc4=_0x2e934d>0x0?_0xa4470c['substring'](0x1,_0x2e934d):_0xa4470c[_0x327f44(0x200)](0x1,_0xa4470c[_0x327f44(0x1ce)]-0x1),_0x3c0650=this['isValidXmlTagName'](_0x392fc4);if(_0x392fc4[_0x327f44(0x22c)]('/')||!_0x392fc4||!this[_0x327f44(0x1b9)](_0x392fc4)){_0x1da359=_0x2665ed+0x1;continue;}const _0x763155=_0xa4470c['endsWith']('/>');let _0xb0bf3='',_0x124a97=_0x2665ed;if(_0x763155)_0xb0bf3='',_0x124a97=_0x2665ed;else{const _0x2faa53='</'+_0x392fc4+'>';_0x124a97=_0x2c5cf8[_0x327f44(0x1b1)](_0x2faa53,_0x2665ed+0x1);if(_0x124a97===-0x1){_0x1da359=_0x2665ed+0x1;continue;}_0xb0bf3=_0x2c5cf8['substring'](_0x2665ed+0x1,_0x124a97);}let _0x42019d=_0x2e934d>0x0?_0xa4470c[_0x327f44(0x200)](_0x2e934d+0x1,_0xa4470c['length']-0x1)['trim']():'';_0x763155&&_0x42019d[_0x327f44(0x1f8)]('/')&&(_0x42019d=_0x42019d[_0x327f44(0x200)](0x0,_0x42019d['length']-0x1)['trim']());const _0x4805ec=this[_0x327f44(0x1b2)](_0x42019d);console[_0x327f44(0x1ad)]('TagParser\x20DEBUG:\x20parseXMLParameters\x20-\x20found\x20match:',{'paramName':_0x392fc4,'attributeString':_0x42019d,'valueLength':_0xb0bf3[_0x327f44(0x1ce)],'valuePreview':_0xb0bf3['substring'](0x0,0x32)+(_0xb0bf3['length']>0x32?_0x327f44(0x19e):'')});const _0x46ae32={'value':_0xb0bf3['trim'](),'attributes':_0x4805ec};if(_0x3e23b0[_0x392fc4]){if(Array['isArray'](_0x3e23b0[_0x392fc4]))_0x3e23b0[_0x392fc4][_0x327f44(0x1c0)](_0x46ae32),console['log'](_0x327f44(0x1e0),_0x392fc4,'count:',_0x3e23b0[_0x392fc4]['length']);else{const _0x12898d=_0x3e23b0[_0x392fc4];_0x3e23b0[_0x392fc4]=[_0x12898d,_0x46ae32],console[_0x327f44(0x1ad)]('TagParser\x20DEBUG:\x20converted\x20to\x20array\x20for\x20duplicate\x20tag:',_0x392fc4);}}else _0x3e23b0[_0x392fc4]=_0x46ae32;const _0x2419a7=_0x392fc4+'_value';!Object['prototype'][_0x327f44(0x202)]['call'](_0x3e23b0,_0x2419a7)&&Object[_0x327f44(0x1dc)](_0x3e23b0,_0x2419a7,{'value':_0xb0bf3['trim'](),'enumerable':![]});_0x5ec974++;if(_0x763155)_0x1da359=_0x2665ed+0x1;else{const _0x10ee34='</'+_0x392fc4+'>';_0x1da359=_0x124a97+_0x10ee34['length'];}}return console[_0x327f44(0x1ad)](_0x327f44(0x1dd),_0x5ec974),console[_0x327f44(0x1ad)](_0x327f44(0x1f1),Object['keys'](_0x3e23b0)),_0x3e23b0;}['parseAttributes'](_0x13b15c){const _0x137857=a0_0x66c400,_0x380bf5={};if(!_0x13b15c)return _0x380bf5;const _0x1fb489=this[_0x137857(0x1fc)](_0x13b15c,this[_0x137857(0x20d)][_0x137857(0x1ff)]);for(const _0x14ef2b of _0x1fb489){const _0x2415a9=_0x14ef2b[_0x137857(0x210)][0x0],_0x1a546f=_0x14ef2b['groups'][0x1];_0x380bf5[_0x2415a9]=_0x1a546f;}return _0x380bf5;}static['extractContent'](_0x4fb6b5,_0x4289aa){const _0x154fb4=a0_0x66c400,_0x38b0c1=new RegExp('<'+_0x4289aa+_0x154fb4(0x1bb)+_0x4289aa+'>','g'),_0x406f46=[];let _0x905946;while((_0x905946=_0x38b0c1[_0x154fb4(0x1c6)](_0x4fb6b5))!==null){_0x406f46[_0x154fb4(0x1c0)](_0x905946[0x1]['trim']());}return _0x406f46;}static[a0_0x66c400(0x211)](_0x1b1466,_0x51b07c){const _0x924a07=a0_0x66c400,_0x24979f=new RegExp('<'+_0x51b07c+_0x924a07(0x199)+_0x51b07c+'>','g'),_0x3dc53c=[];let _0x497a5a;while((_0x497a5a=_0x24979f['exec'](_0x1b1466))!==null){const _0x130a46=_0x497a5a[0x1],_0x3b6d8f=_0x497a5a[0x2]['trim'](),_0xe49ec=new TagParser(),_0x2486a7=_0xe49ec[_0x924a07(0x1b2)](_0x130a46);_0x3dc53c[_0x924a07(0x1c0)]({'content':_0x3b6d8f,'attributes':_0x2486a7,'rawMatch':_0x497a5a[0x0]});}return _0x3dc53c;}[a0_0x66c400(0x222)](_0x595e5d){const _0x16c7a2=a0_0x66c400;return _0x595e5d&&typeof _0x595e5d==='object'&&(_0x595e5d[_0x16c7a2(0x1c3)]||_0x595e5d[_0x16c7a2(0x1d3)])&&(_0x595e5d['parameters']||_0x595e5d['actions']);}[a0_0x66c400(0x1fc)](_0x5ca037,_0x8f7a96){const _0x1ba3c9=a0_0x66c400,_0x350d06=[];let _0x815043;_0x8f7a96[_0x1ba3c9(0x209)]=0x0;while((_0x815043=_0x8f7a96['exec'](_0x5ca037))!==null){_0x350d06[_0x1ba3c9(0x1c0)]({'match':_0x815043[0x0],'groups':_0x815043['slice'](0x1),'index':_0x815043[_0x1ba3c9(0x221)]});}return _0x350d06;}['validateToolCommand'](_0x109f0d){const _0x146bbe=a0_0x66c400,_0x4b39da=[];!_0x109f0d['toolId']&&_0x4b39da[_0x146bbe(0x1c0)](_0x146bbe(0x1e2));!_0x109f0d[_0x146bbe(0x208)]&&!_0x109f0d[_0x146bbe(0x1aa)]&&_0x4b39da['push'](_0x146bbe(0x19d));if(_0x109f0d[_0x146bbe(0x21c)]==='xml'){!_0x109f0d[_0x146bbe(0x1b0)]&&_0x4b39da[_0x146bbe(0x1c0)]('Missing\x20rawContent\x20for\x20XML\x20command');if(_0x109f0d[_0x146bbe(0x208)])for(const [_0x3583bd,_0x40fd68]of Object[_0x146bbe(0x227)](_0x109f0d[_0x146bbe(0x208)])){(typeof _0x40fd68!=='object'||!('value'in _0x40fd68))&&_0x4b39da['push']('Invalid\x20parameter\x20structure\x20for\x20'+_0x3583bd);}}return _0x109f0d['type']===_0x146bbe(0x207)&&(!_0x109f0d['jsonData']&&_0x4b39da['push'](_0x146bbe(0x21b))),{'valid':_0x4b39da[_0x146bbe(0x1ce)]===0x0,'errors':_0x4b39da};}['normalizeToolCommand'](_0x126610){const _0x3ca32a=a0_0x66c400,_0x549cf3={'toolId':_0x126610[_0x3ca32a(0x1c3)],'type':_0x126610['type'],'parameters':{},'rawContent':_0x126610[_0x3ca32a(0x1b0)]};if(_0x126610['type']===COMMAND_FORMATS['XML']){console[_0x3ca32a(0x1ad)]('TagParser\x20DEBUG:\x20normalizing\x20XML\x20command\x20with\x20parameters:',Object[_0x3ca32a(0x224)](_0x126610[_0x3ca32a(0x208)]||{}));if(_0x126610[_0x3ca32a(0x1c3)]===_0x3ca32a(0x1fe)){const _0x51de4a=_0x126610[_0x3ca32a(0x208)]||{};if(_0x51de4a[_0x3ca32a(0x1ef)]){const _0x3342f1=_0x51de4a['pause-duration']['value'];_0x549cf3['parameters'][_0x3ca32a(0x231)]=parseInt(_0x3342f1,0xa);}return _0x51de4a['reason']&&(_0x549cf3[_0x3ca32a(0x208)][_0x3ca32a(0x223)]=_0x51de4a['reason'][_0x3ca32a(0x1b3)]['trim']()),console['log'](_0x3ca32a(0x1e1),_0x549cf3['parameters']),_0x549cf3;}if(_0x126610['toolId']==='image-gen'){const _0xde334=_0x126610['parameters']||{};let _0x30c8f8='';for(const [_0x4f7e98,_0xe98694]of Object[_0x3ca32a(0x227)](_0xde334)){_0x30c8f8+='<'+_0x4f7e98+'>'+_0xe98694['value']+'</'+_0x4f7e98+'>\x0a';}return _0x549cf3[_0x3ca32a(0x208)]=_0x30c8f8[_0x3ca32a(0x1bc)](),console[_0x3ca32a(0x1ad)](_0x3ca32a(0x1cf),_0x30c8f8['substring'](0x0,0x64)+'...'),_0x549cf3;}const _0x531e1d=[];for(const [_0x44379f,_0x376236]of Object['entries'](_0x126610['parameters']||{})){console[_0x3ca32a(0x1ad)](_0x3ca32a(0x1fd),_0x44379f,_0x3ca32a(0x1d0),_0x376236);const _0x1691ce=Array[_0x3ca32a(0x1cd)](_0x376236)?_0x376236:[_0x376236];for(const _0x5035e3 of _0x1691ce){const _0x4af5db={'type':_0x44379f,..._0x5035e3[_0x3ca32a(0x1a2)]};_0x5035e3[_0x3ca32a(0x1b3)]&&_0x5035e3[_0x3ca32a(0x1b3)][_0x3ca32a(0x1bc)]()&&(_0x4af5db[_0x3ca32a(0x1f4)]=_0x5035e3['value'][_0x3ca32a(0x1bc)]());console[_0x3ca32a(0x1ad)](_0x3ca32a(0x203),_0x4af5db);const _0x2e2db8={};for(const [_0x3f6a71,_0x46e36a]of Object['entries'](_0x4af5db)){const _0xe596c2=this[_0x3ca32a(0x1ac)](_0x3f6a71);_0x2e2db8[_0xe596c2]=_0x46e36a;}if(_0x2e2db8['content']!==undefined){const _0x5c2b82={'run-command':_0x3ca32a(0x1d8),'create-directory':_0x3ca32a(0x1a5),'change-directory':_0x3ca32a(0x1a5),'list-directory':'directory','get-working-directory':null,'write':null,'read':'filePath','delete':_0x3ca32a(0x1a0),'copy':null,'move':null,'append':_0x3ca32a(0x1a0),'create-dir':_0x3ca32a(0x1a5),'list':'directory','exists':'path','stats':'path','action':null,'title':null,'description':null,'priority':null,'taskId':null,'status':null},_0x612c51=_0x5c2b82[_0x2e2db8['type']];if(_0x612c51)_0x2e2db8[_0x612c51]=_0x2e2db8['content'],delete _0x2e2db8['content'],console['log']('TagParser\x20DEBUG:\x20mapped\x20\x27content\x27\x20to\x20\x27'+_0x612c51+'\x27\x20for\x20action\x20type\x20\x27'+_0x2e2db8[_0x3ca32a(0x21c)]+'\x27');else _0x612c51===null&&console[_0x3ca32a(0x1ad)](_0x3ca32a(0x1d4)+_0x2e2db8['type']+_0x3ca32a(0x1f3));}console['log']('TagParser\x20DEBUG:\x20final\x20normalized\x20action:',_0x2e2db8),_0x531e1d['push'](_0x2e2db8);}const _0x35a902=Array[_0x3ca32a(0x1cd)](_0x376236)?_0x376236[0x0]:_0x376236;_0x549cf3[_0x3ca32a(0x208)][_0x44379f]=_0x35a902[_0x3ca32a(0x1b3)],_0x35a902['attributes']&&Object['keys'](_0x35a902['attributes'])['length']>0x0&&(_0x549cf3['parameters'][_0x44379f+_0x3ca32a(0x20f)]=_0x35a902[_0x3ca32a(0x1a2)]);}console['log']('TagParser\x20DEBUG:\x20total\x20actions\x20created:',_0x531e1d['length']),_0x531e1d[_0x3ca32a(0x1ce)]>0x0?(_0x549cf3['parameters']['actions']=_0x531e1d,console['log']('TagParser\x20DEBUG:\x20added\x20actions\x20array\x20to\x20parameters')):console[_0x3ca32a(0x1ad)](_0x3ca32a(0x20c));}else{if(_0x126610['type']===COMMAND_FORMATS[_0x3ca32a(0x1a4)]||_0x126610['type']===COMMAND_FORMATS['JSON_PLAIN']){_0x549cf3[_0x3ca32a(0x208)]={..._0x126610[_0x3ca32a(0x208)]};if(_0x126610['actions']&&Array[_0x3ca32a(0x1cd)](_0x126610['actions'])){_0x549cf3[_0x3ca32a(0x208)][_0x3ca32a(0x1aa)]=_0x126610[_0x3ca32a(0x1aa)];if(_0x126610[_0x3ca32a(0x1c3)]===TOOL_IDS['AGENT_COMMUNICATION']&&_0x126610['actions'][_0x3ca32a(0x1ce)]>0x0){const _0x277f4d=_0x126610['actions'][0x0];_0x549cf3['parameters'][_0x3ca32a(0x1c2)]=_0x277f4d[_0x3ca32a(0x21c)]||_0x277f4d['action'],Object[_0x3ca32a(0x1e6)](_0x549cf3[_0x3ca32a(0x208)],_0x277f4d);}}}}return _0x549cf3;}['isValidXmlTagName'](_0x967e0f){const _0x14cc65=a0_0x66c400,_0x39dda7=['write','read',_0x14cc65(0x1ee),'copy',_0x14cc65(0x19a),'append','create-dir','list','exists',_0x14cc65(0x1a1),_0x14cc65(0x1be),'cd','pwd',_0x14cc65(0x1df),'change-directory','list-directory',_0x14cc65(0x1b4),_0x14cc65(0x1ef),_0x14cc65(0x223),_0x14cc65(0x1c2),_0x14cc65(0x1cb),_0x14cc65(0x19c),'priority','taskId',_0x14cc65(0x1eb),'dependsOn',_0x14cc65(0x1f0),'relatedTo',_0x14cc65(0x1af),'timeframe',_0x14cc65(0x216),_0x14cc65(0x1b6),'milestone','notes','url','selector',_0x14cc65(0x212),'screenshot',_0x14cc65(0x20a),_0x14cc65(0x1d9),'message','conversation-id','prompt','output-path',_0x14cc65(0x1a3),'quality','model','batch',_0x14cc65(0x21d),_0x14cc65(0x1d8),_0x14cc65(0x1ca),_0x14cc65(0x1f4),'name',_0x14cc65(0x1b3),_0x14cc65(0x21c),_0x14cc65(0x1ab)];return _0x39dda7['includes'](_0x967e0f)&&this['containsOnlyValidChars'](_0x967e0f);}['containsOnlyValidChars'](_0x3cb5fa){const _0x34f508=a0_0x66c400;if(!_0x3cb5fa||_0x3cb5fa['length']===0x0)return![];const _0x1c210f=_0x3cb5fa['charAt'](0x0),_0x560072=_0x1c210f>='a'&&_0x1c210f<='z'||_0x1c210f>='A'&&_0x1c210f<='Z';if(!_0x560072)return![];for(let _0x2e3a09=0x1;_0x2e3a09<_0x3cb5fa[_0x34f508(0x1ce)];_0x2e3a09++){const _0x52e304=_0x3cb5fa[_0x34f508(0x1de)](_0x2e3a09),_0x4ec8d1=_0x52e304>='a'&&_0x52e304<='z'||_0x52e304>='A'&&_0x52e304<='Z',_0x18fa67=_0x52e304>='0'&&_0x52e304<='9',_0x3ccb56=_0x52e304==='-';if(!_0x4ec8d1&&!_0x18fa67&&!_0x3ccb56)return![];}return!![];}[a0_0x66c400(0x1a9)](_0x16f5a8){const _0x9ba8f3=a0_0x66c400,_0x329ae4=[_0x9ba8f3(0x1da),'read','delete','copy','move','append',_0x9ba8f3(0x1c5),_0x9ba8f3(0x1ba),'exists',_0x9ba8f3(0x1a1),'run-command','cd','pwd','create-directory',_0x9ba8f3(0x201),_0x9ba8f3(0x1d2),'get-working-directory','pause-duration','reason',_0x9ba8f3(0x1c2),_0x9ba8f3(0x1cb),_0x9ba8f3(0x19c),_0x9ba8f3(0x22e),_0x9ba8f3(0x1c8),'status','dependsOn','dependencyType',_0x9ba8f3(0x1d7),_0x9ba8f3(0x1af),'timeframe','templateId',_0x9ba8f3(0x1b6),_0x9ba8f3(0x1c1),_0x9ba8f3(0x22f),'url',_0x9ba8f3(0x1cc),_0x9ba8f3(0x212),'screenshot',_0x9ba8f3(0x20a),'recipient',_0x9ba8f3(0x1ea),'conversation-id','prompt','output-path','size','quality',_0x9ba8f3(0x219),'batch','image',_0x9ba8f3(0x1d8),'path','content',_0x9ba8f3(0x21f),'value',_0x9ba8f3(0x21c),_0x9ba8f3(0x1ab)];return _0x329ae4['includes'](_0x16f5a8);}['_toCamelCase'](_0x1992a9){const _0x538ee7=a0_0x66c400;return _0x1992a9['replace'](/[-_](.)/g,(_0x165774,_0xe0bd22)=>_0xe0bd22[_0x538ee7(0x1e9)]());}static[a0_0x66c400(0x1e4)](_0x5e1603,_0x354434,_0x4acc6f){const _0xf85e38=a0_0x66c400,_0xfa5351=[];let _0x29e2a1=0x0;while(!![]){const _0x179e6a=_0x5e1603['indexOf'](_0x354434,_0x29e2a1);if(_0x179e6a===-0x1)break;const _0x280a9d=_0x5e1603['indexOf'](_0x4acc6f,_0x179e6a+_0x354434[_0xf85e38(0x1ce)]);if(_0x280a9d===-0x1)break;const _0x44a2d4=_0x5e1603['substring'](_0x179e6a+_0x354434['length'],_0x280a9d);_0xfa5351[_0xf85e38(0x1c0)]({'content':_0x44a2d4,'fullMatch':_0x5e1603['substring'](_0x179e6a,_0x280a9d+_0x4acc6f[_0xf85e38(0x1ce)]),'startIndex':_0x179e6a,'endIndex':_0x280a9d+_0x4acc6f[_0xf85e38(0x1ce)]}),_0x29e2a1=_0x280a9d+_0x4acc6f[_0xf85e38(0x1ce)];}return _0xfa5351;}[a0_0x66c400(0x1f7)](_0x18cbc1){const _0x3ac270=a0_0x66c400;let _0xd03ddb=_0x18cbc1;return _0xd03ddb=_0xd03ddb[_0x3ac270(0x1f6)](this['patterns']['toolCommand'],''),_0xd03ddb=_0xd03ddb['replace'](this[_0x3ac270(0x20d)]['agentRedirect'],''),_0xd03ddb=_0xd03ddb['replace'](this['patterns'][_0x3ac270(0x1bd)],(_0x278fc6,_0x51a14c)=>{const _0x448634=_0x3ac270;try{const _0xca9600=JSON['parse'](_0x51a14c);if(this['isToolCommandJSON'](_0xca9600)||_0xca9600[_0x448634(0x1db)]&&Array['isArray'](_0xca9600['toolCommands']))return'';}catch{}return _0x278fc6;}),_0xd03ddb=_0xd03ddb[_0x3ac270(0x1f6)](/\n\s*\n\s*\n/g,'\x0a\x0a'),_0xd03ddb=_0xd03ddb[_0x3ac270(0x1bc)](),_0xd03ddb;}}function a0_0x1f69(_0x3f226c,_0xe3579f){_0x3f226c=_0x3f226c-0x199;const _0x138f1f=a0_0x138f();let _0x1f694a=_0x138f1f[_0x3f226c];if(a0_0x1f69['XHGBFr']===undefined){var _0xc9cc9c=function(_0x38d9b0){const _0x219d18='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x44f6db='',_0x301294='';for(let _0x518c14=0x0,_0x371ad1,_0x46a9e9,_0x177235=0x0;_0x46a9e9=_0x38d9b0['charAt'](_0x177235++);~_0x46a9e9&&(_0x371ad1=_0x518c14%0x4?_0x371ad1*0x40+_0x46a9e9:_0x46a9e9,_0x518c14++%0x4)?_0x44f6db+=String['fromCharCode'](0xff&_0x371ad1>>(-0x2*_0x518c14&0x6)):0x0){_0x46a9e9=_0x219d18['indexOf'](_0x46a9e9);}for(let _0x47d0af=0x0,_0x2ac2c7=_0x44f6db['length'];_0x47d0af<_0x2ac2c7;_0x47d0af++){_0x301294+='%'+('00'+_0x44f6db['charCodeAt'](_0x47d0af)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x301294);};a0_0x1f69['UhfTHi']=_0xc9cc9c,a0_0x1f69['ovSmFC']={},a0_0x1f69['XHGBFr']=!![];}const _0x59a831=_0x138f1f[0x0],_0x840a5f=_0x3f226c+_0x59a831,_0x4060e0=a0_0x1f69['ovSmFC'][_0x840a5f];return!_0x4060e0?(_0x1f694a=a0_0x1f69['UhfTHi'](_0x1f694a),a0_0x1f69['ovSmFC'][_0x840a5f]=_0x1f694a):_0x1f694a=_0x4060e0,_0x1f694a;}export default TagParser;
|