diff --git a/index.ts b/index.ts
index 66c8143..f7e3d3d 100644
--- a/index.ts
+++ b/index.ts
@@ -367,14 +367,36 @@ async function runPlugin(ctx: any, options: any, dataDir: string) {
// Tool calls
if (step.tools.length > 0) {
for (const tool of step.tools) {
- parts.push(`\n🔧 ${tool.name}
\n\n`)
- parts.push(`Args:\n\`\`\`\n${tool.args}\n\`\`\`\n\n`)
- if (tool.failed) {
- parts.push(`Failed: ${tool.result}\n\n`)
+ // Check if this is an execute tool with child tool calls
+ // Child tools have toolID like "parentID/toolName"
+ const isExecuteWithChildren = tool.name === "execute" && tool.toolID.includes("/")
+ const childTools = isExecuteWithChildren ? step.tools.filter(t => t.toolID.startsWith(tool.toolID + "/")) : []
+
+ if (isExecuteWithChildren && childTools.length > 0) {
+ // Expand execute → individual spoilers for each child tool
+ for (const child of childTools) {
+ // Extract args from the code for this child tool
+ const childArgs = extractChildToolArgs(tool.args, child.name)
+ parts.push(`\n🔧 ${child.name}
\n\n`)
+ parts.push(`Args:\n\`\`\`\n${childArgs}\n\`\`\`\n\n`)
+ if (child.failed) {
+ parts.push(`Failed: ${child.result}\n\n`)
+ } else if (child.result) {
+ parts.push(`Result:\n\`\`\`\n${child.result}\n\`\`\`\n\n`)
+ }
+ parts.push(` `)
+ }
} else {
- parts.push(`Result:\n\`\`\`\n${tool.result}\n\`\`\`\n\n`)
+ // Normal tool (or execute without children)
+ parts.push(`\n🔧 ${tool.name}
\n\n`)
+ parts.push(`Args:\n\`\`\`\n${tool.args}\n\`\`\`\n\n`)
+ if (tool.failed) {
+ parts.push(`Failed: ${tool.result}\n\n`)
+ } else {
+ parts.push(`Result:\n\`\`\`\n${tool.result}\n\`\`\`\n\n`)
+ }
+ parts.push(` `)
}
- parts.push(` `)
}
}
@@ -387,6 +409,28 @@ async function runPlugin(ctx: any, options: any, dataDir: string) {
return parts.join("\n")
}
+ // Extract args for a child tool from the execute code
+ function extractChildToolArgs(code: string, toolName: string): string {
+ try {
+ const args = JSON.parse(code)
+ const codeStr = args?.code || ""
+ // Match tools..(...) and extract the arguments
+ const regex = new RegExp(`tools\\.\\w+\\.${escapeRegex(toolName.replace("_", "."))}\\s*\\(([^)]*)\\)`, "g")
+ const matches: string[] = []
+ let match
+ while ((match = regex.exec(codeStr)) !== null) {
+ matches.push(match[1].trim())
+ }
+ return matches.join("\n") || "(parsed from code)"
+ } catch {
+ return "(parsed from code)"
+ }
+ }
+
+ function escapeRegex(str: string): string {
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
+ }
+
// =============================================================================
// Send message to Matrix (reuses existing sendReply/sendNotice)
// =============================================================================