File size: 3,245 Bytes
bfc7d04
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Extract tool schemas from RTMP for training data
//
// This script extracts tool definitions from the RTMP codebase
// and adds them to stack-2.9's training data catalog.

import { readdir, readFile, writeFile } from 'fs/promises'
import { join, basename } from 'path'

const RTMP_TOOLS_DIR = '/Users/walidsobhi/.openclaw/workspace/RTMP/tools'
const STACK_CATALOG = '/Users/walidsobhi/.openclaw/workspace/stack-2.9/training-data/tools/catalog.json'

interface ToolSchema {
  tool: string
  description: string
  hasPrompt: boolean
  hasImplementation: boolean
  inputSchema: Record<string, unknown>
}

async function extractToolSchemas(): Promise<ToolSchema[]> {
  const tools: ToolSchema[] = []
  const toolDirs = await readdir(RTMP_TOOLS_DIR)

  for (const toolDir of toolDirs) {
    const toolPath = join(RTMP_TOOLS_DIR, toolDir)
    const stat = await readdir(toolPath).then(() => true).catch(() => false)

    if (!stat) continue

    // Try to extract tool name and description from tool files
    let description = ''
    let hasPrompt = false
    let hasImplementation = false

    try {
      // Check for prompt.ts
      const promptPath = join(toolPath, 'prompt.ts')
      const promptContent = await readFile(promptPath, 'utf-8')
      hasPrompt = true

      // Extract first meaningful comment as description
      const comments = promptContent.match(/\/\*\*[\s\S]*?\*\//g)
      if (comments && comments.length > 0) {
        const comment = comments[0]
        description = comment
          .replace(/\/\*\*|\*\//g, '')
          .replace(/^\s*\*\s?/gm, '')
          .trim()
          .slice(0, 200)
      }
    } catch {
      // No prompt.ts
    }

    try {
      // Check for implementation files
      const toolFiles = await readdir(toolPath)
      hasImplementation = toolFiles.some(f =>
        f.endsWith('.ts') || f.endsWith('.tsx')
      )
    } catch {
      // Ignore
    }

    // Format tool name (remove Tool suffix for cleaner names)
    const toolName = toolDir.replace(/Tool$/, '')

    tools.push({
      tool: toolDir,
      description: description || `${toolName} tool`,
      hasPrompt,
      hasImplementation,
      inputSchema: {}
    })
  }

  return tools
}

async function main() {
  console.log('Extracting tool schemas from RTMP...')

  const tools = await extractToolSchemas()
  console.log(`Found ${tools.length} tools`)

  // Read existing catalog
  let existingTools: ToolSchema[] = []
  try {
    const existingContent = await readFile(STACK_CATALOG, 'utf-8')
    existingTools = JSON.parse(existingContent)
  } catch {
    console.log('No existing catalog found')
  }

  // Merge with existing (avoid duplicates)
  const existingNames = new Set(existingTools.map(t => t.tool))
  const newTools = tools.filter(t => !existingNames.has(t.tool))

  console.log(`Adding ${newTools.length} new tools`)

  // Combine
  const allTools = [...existingTools, ...newTools]

  // Write updated catalog
  await writeFile(STACK_CATALOG, JSON.stringify(allTools, null, 2))
  console.log(`Updated catalog with ${allTools.length} tools`)

  // Also print summary
  console.log('\nNew tools added:')
  for (const tool of newTools) {
    console.log(`  - ${tool.tool}`)
  }
}

main().catch(console.error)