@halfagiraf/clawx 0.2.8 → 0.2.10
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 +63 -0
- package/dist/cli/forge.d.ts +4 -0
- package/dist/cli/forge.d.ts.map +1 -0
- package/dist/cli/forge.js +205 -0
- package/dist/cli/forge.js.map +1 -0
- package/dist/cli/main.js +3 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -1
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +5 -2
- package/dist/core/agent.js.map +1 -1
- package/dist/forge/community.d.ts +25 -0
- package/dist/forge/community.d.ts.map +1 -0
- package/dist/forge/community.js +126 -0
- package/dist/forge/community.js.map +1 -0
- package/dist/forge/discover.d.ts +14 -0
- package/dist/forge/discover.d.ts.map +1 -0
- package/dist/forge/discover.js +134 -0
- package/dist/forge/discover.js.map +1 -0
- package/dist/forge/forge.test.d.ts +2 -0
- package/dist/forge/forge.test.d.ts.map +1 -0
- package/dist/forge/forge.test.js +202 -0
- package/dist/forge/forge.test.js.map +1 -0
- package/dist/forge/hardware.d.ts +8 -0
- package/dist/forge/hardware.d.ts.map +1 -0
- package/dist/forge/hardware.js +31 -0
- package/dist/forge/hardware.js.map +1 -0
- package/dist/forge/hf-client.d.ts +9 -0
- package/dist/forge/hf-client.d.ts.map +1 -0
- package/dist/forge/hf-client.js +101 -0
- package/dist/forge/hf-client.js.map +1 -0
- package/dist/forge/index.d.ts +13 -0
- package/dist/forge/index.d.ts.map +1 -0
- package/dist/forge/index.js +13 -0
- package/dist/forge/index.js.map +1 -0
- package/dist/forge/loader.d.ts +10 -0
- package/dist/forge/loader.d.ts.map +1 -0
- package/dist/forge/loader.js +385 -0
- package/dist/forge/loader.js.map +1 -0
- package/dist/forge/loader.test.d.ts +5 -0
- package/dist/forge/loader.test.d.ts.map +1 -0
- package/dist/forge/loader.test.js +15 -0
- package/dist/forge/loader.test.js.map +1 -0
- package/dist/forge/pipeline-builder.d.ts +9 -0
- package/dist/forge/pipeline-builder.d.ts.map +1 -0
- package/dist/forge/pipeline-builder.js +125 -0
- package/dist/forge/pipeline-builder.js.map +1 -0
- package/dist/forge/pipeline.d.ts +28 -0
- package/dist/forge/pipeline.d.ts.map +1 -0
- package/dist/forge/pipeline.js +206 -0
- package/dist/forge/pipeline.js.map +1 -0
- package/dist/forge/rank.d.ts +3 -0
- package/dist/forge/rank.d.ts.map +1 -0
- package/dist/forge/rank.js +138 -0
- package/dist/forge/rank.js.map +1 -0
- package/dist/forge/reasoner.d.ts +10 -0
- package/dist/forge/reasoner.d.ts.map +1 -0
- package/dist/forge/reasoner.js +312 -0
- package/dist/forge/reasoner.js.map +1 -0
- package/dist/forge/registry.d.ts +15 -0
- package/dist/forge/registry.d.ts.map +1 -0
- package/dist/forge/registry.js +149 -0
- package/dist/forge/registry.js.map +1 -0
- package/dist/forge/scaffold.d.ts +10 -0
- package/dist/forge/scaffold.d.ts.map +1 -0
- package/dist/forge/scaffold.js +412 -0
- package/dist/forge/scaffold.js.map +1 -0
- package/dist/forge/scaffolder.d.ts +9 -0
- package/dist/forge/scaffolder.d.ts.map +1 -0
- package/dist/forge/scaffolder.js +118 -0
- package/dist/forge/scaffolder.js.map +1 -0
- package/dist/forge/tester.d.ts +9 -0
- package/dist/forge/tester.d.ts.map +1 -0
- package/dist/forge/tester.js +103 -0
- package/dist/forge/tester.js.map +1 -0
- package/dist/forge/types.d.ts +54 -0
- package/dist/forge/types.d.ts.map +1 -0
- package/dist/forge/types.js +3 -0
- package/dist/forge/types.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
// Forge v1: Scaffolding engine
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { mkdirSync, writeFileSync } from 'fs';
|
|
4
|
+
export function createScaffoldPlan(opportunity, options) {
|
|
5
|
+
const { outputType, outputName } = options;
|
|
6
|
+
if (outputType === 'tool') {
|
|
7
|
+
return createToolScaffoldPlan(opportunity, outputName);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
return createAppScaffoldPlan(opportunity, outputName);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function createToolScaffoldPlan(opportunity, toolName) {
|
|
14
|
+
const model = opportunity.primaryModel;
|
|
15
|
+
const dataset = opportunity.supportingDataset;
|
|
16
|
+
const files = [
|
|
17
|
+
{
|
|
18
|
+
path: 'README.md',
|
|
19
|
+
content: generateToolReadme(opportunity, toolName)
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
path: 'tool.json',
|
|
23
|
+
content: generateToolManifest(opportunity, toolName)
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
path: 'tool.ts',
|
|
27
|
+
content: generateToolCode(opportunity, toolName)
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
path: 'package.json',
|
|
31
|
+
content: generatePackageJson(toolName)
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
path: 'test-data/example.txt',
|
|
35
|
+
content: generateExampleData(opportunity)
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
const integrationNotes = `To use this tool with Clawx:
|
|
39
|
+
1. Build the tool: npm install && npm run build
|
|
40
|
+
2. Copy the generated .js file to ~/.clawx/forge/tools/
|
|
41
|
+
3. Restart Clawx or reload tools
|
|
42
|
+
|
|
43
|
+
The tool will appear as "${toolName}" in Clawx's available tools.`;
|
|
44
|
+
return {
|
|
45
|
+
opportunityId: opportunity.id,
|
|
46
|
+
outputType: 'tool',
|
|
47
|
+
outputName: toolName,
|
|
48
|
+
files,
|
|
49
|
+
integrationNotes
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function createAppScaffoldPlan(opportunity, appName) {
|
|
53
|
+
const model = opportunity.primaryModel;
|
|
54
|
+
const dataset = opportunity.supportingDataset;
|
|
55
|
+
const files = [
|
|
56
|
+
{
|
|
57
|
+
path: 'README.md',
|
|
58
|
+
content: generateAppReadme(opportunity, appName)
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
path: 'app.py',
|
|
62
|
+
content: generatePythonApp(opportunity, appName)
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
path: 'requirements.txt',
|
|
66
|
+
content: generateRequirements(opportunity)
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
path: 'config.yaml',
|
|
70
|
+
content: generateConfig(opportunity)
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
path: 'examples/example_usage.py',
|
|
74
|
+
content: generateExampleUsage(opportunity)
|
|
75
|
+
}
|
|
76
|
+
];
|
|
77
|
+
return {
|
|
78
|
+
opportunityId: opportunity.id,
|
|
79
|
+
outputType: 'app',
|
|
80
|
+
outputName: appName,
|
|
81
|
+
files
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export function executeScaffoldPlan(plan, outputDir) {
|
|
85
|
+
console.log(`🏗️ Scaffolding ${plan.outputType}: ${plan.outputName}`);
|
|
86
|
+
console.log(`📁 Output directory: ${outputDir}`);
|
|
87
|
+
// Create output directory
|
|
88
|
+
mkdirSync(outputDir, { recursive: true });
|
|
89
|
+
// Create all files
|
|
90
|
+
for (const file of plan.files) {
|
|
91
|
+
const filePath = join(outputDir, file.path);
|
|
92
|
+
// Create subdirectories if needed
|
|
93
|
+
const dirPath = join(outputDir, file.path.split('/').slice(0, -1).join('/'));
|
|
94
|
+
if (dirPath !== outputDir) {
|
|
95
|
+
mkdirSync(dirPath, { recursive: true });
|
|
96
|
+
}
|
|
97
|
+
writeFileSync(filePath, file.content, 'utf8');
|
|
98
|
+
console.log(` 📄 Created: ${file.path}`);
|
|
99
|
+
}
|
|
100
|
+
// Show integration notes if tool
|
|
101
|
+
if (plan.integrationNotes) {
|
|
102
|
+
console.log('\n🔧 Integration notes:');
|
|
103
|
+
console.log(plan.integrationNotes);
|
|
104
|
+
}
|
|
105
|
+
console.log(`\n✅ Scaffolding complete!`);
|
|
106
|
+
console.log(`Next steps: cd ${outputDir} and follow the README`);
|
|
107
|
+
}
|
|
108
|
+
// Content generators
|
|
109
|
+
function generateToolReadme(opportunity, toolName) {
|
|
110
|
+
const model = opportunity.primaryModel;
|
|
111
|
+
const dataset = opportunity.supportingDataset;
|
|
112
|
+
return `# ${toolName}
|
|
113
|
+
|
|
114
|
+
${opportunity.description}
|
|
115
|
+
|
|
116
|
+
## Model
|
|
117
|
+
- **Name**: ${model.name}
|
|
118
|
+
- **Author**: ${model.author}
|
|
119
|
+
- **Task**: ${model.task || 'N/A'}
|
|
120
|
+
- **Modality**: ${model.modality || 'N/A'}
|
|
121
|
+
- **License**: ${model.license || 'N/A'}
|
|
122
|
+
|
|
123
|
+
${dataset ? `## Dataset
|
|
124
|
+
- **Name**: ${dataset.name}
|
|
125
|
+
- **Author**: ${dataset.author}
|
|
126
|
+
- **Task**: ${dataset.task || 'N/A'}
|
|
127
|
+
` : ''}
|
|
128
|
+
|
|
129
|
+
## Setup
|
|
130
|
+
\`\`\`bash
|
|
131
|
+
npm install
|
|
132
|
+
npm run build
|
|
133
|
+
\`\`\`
|
|
134
|
+
|
|
135
|
+
## Usage with Clawx
|
|
136
|
+
1. Copy the generated \`tool.js\` to \`~/.clawx/forge/tools/\`
|
|
137
|
+
2. Restart Clawx
|
|
138
|
+
3. The tool will be available as "${toolName}"
|
|
139
|
+
|
|
140
|
+
## Development
|
|
141
|
+
- Edit \`tool.ts\` to customize the implementation
|
|
142
|
+
- Update \`tool.json\` to modify the tool definition
|
|
143
|
+
- Add tests in \`test-data/\`
|
|
144
|
+
|
|
145
|
+
## Notes
|
|
146
|
+
- This is a starter project generated by Clawx Forge
|
|
147
|
+
- You may need to install additional dependencies
|
|
148
|
+
- Consider hardware requirements: ${model.hardware?.gpu ? 'GPU recommended' : 'CPU only'}
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
function generateToolManifest(opportunity, toolName) {
|
|
152
|
+
const model = opportunity.primaryModel;
|
|
153
|
+
return JSON.stringify({
|
|
154
|
+
name: toolName.toLowerCase().replace(/\s+/g, '_'),
|
|
155
|
+
label: toolName,
|
|
156
|
+
description: opportunity.description,
|
|
157
|
+
parameters: {
|
|
158
|
+
input: {
|
|
159
|
+
type: "string",
|
|
160
|
+
description: `Input ${model.modality || 'data'} to process`
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
implementation: {
|
|
164
|
+
type: "custom",
|
|
165
|
+
file: "./tool.js"
|
|
166
|
+
},
|
|
167
|
+
metadata: {
|
|
168
|
+
model: model.id,
|
|
169
|
+
task: model.task,
|
|
170
|
+
generatedBy: "clawx-forge",
|
|
171
|
+
generatedAt: new Date().toISOString()
|
|
172
|
+
}
|
|
173
|
+
}, null, 2);
|
|
174
|
+
}
|
|
175
|
+
function generateToolCode(opportunity, toolName) {
|
|
176
|
+
const model = opportunity.primaryModel;
|
|
177
|
+
return `// ${toolName} - Generated by Clawx Forge
|
|
178
|
+
// Model: ${model.id}
|
|
179
|
+
// Task: ${model.task || 'N/A'}
|
|
180
|
+
|
|
181
|
+
import { AgentTool } from '@mariozechner/pi-agent-core';
|
|
182
|
+
|
|
183
|
+
export function createTool(): AgentTool<any> {
|
|
184
|
+
return {
|
|
185
|
+
name: '${toolName.toLowerCase().replace(/\s+/g, '_')}',
|
|
186
|
+
label: '${toolName}',
|
|
187
|
+
description: \`${opportunity.description}\`,
|
|
188
|
+
|
|
189
|
+
parameters: {
|
|
190
|
+
type: 'object',
|
|
191
|
+
properties: {
|
|
192
|
+
input: {
|
|
193
|
+
type: 'string',
|
|
194
|
+
description: 'Input to process'
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
required: ['input']
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
async execute(toolCallId, args, context) {
|
|
201
|
+
const input = args.input;
|
|
202
|
+
|
|
203
|
+
// TODO: Implement actual model inference
|
|
204
|
+
// For now, return a simulated result
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
toolCallId,
|
|
208
|
+
content: [{
|
|
209
|
+
type: 'text',
|
|
210
|
+
text: \`Processed input using ${model.name}\\n\\nInput: "\${input}"\\n\\nResult: Simulated output (replace with real inference)\`
|
|
211
|
+
}],
|
|
212
|
+
details: {
|
|
213
|
+
model: '${model.id}',
|
|
214
|
+
simulated: true,
|
|
215
|
+
note: 'Replace with actual model inference'
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
`;
|
|
222
|
+
}
|
|
223
|
+
function generatePackageJson(toolName) {
|
|
224
|
+
return JSON.stringify({
|
|
225
|
+
name: toolName.toLowerCase().replace(/\s+/g, '-'),
|
|
226
|
+
version: "0.1.0",
|
|
227
|
+
description: `Clawx tool: ${toolName}`,
|
|
228
|
+
main: "tool.js",
|
|
229
|
+
scripts: {
|
|
230
|
+
build: "tsc tool.ts --outDir . --module commonjs --target es2020",
|
|
231
|
+
test: "echo 'No tests yet'"
|
|
232
|
+
},
|
|
233
|
+
dependencies: {
|
|
234
|
+
"@mariozechner/pi-agent-core": "^0.1.0"
|
|
235
|
+
},
|
|
236
|
+
devDependencies: {
|
|
237
|
+
"typescript": "^5.0.0"
|
|
238
|
+
}
|
|
239
|
+
}, null, 2);
|
|
240
|
+
}
|
|
241
|
+
function generateExampleData(opportunity) {
|
|
242
|
+
const model = opportunity.primaryModel;
|
|
243
|
+
if (model.modality === 'text') {
|
|
244
|
+
return "This is example text to classify or process.\nReplace with your own data.";
|
|
245
|
+
}
|
|
246
|
+
else if (model.modality === 'image') {
|
|
247
|
+
return "# Example image data would go here\n# Use actual image files for testing";
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
return `Example data for ${model.modality || 'unknown'} modality`;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function generateAppReadme(opportunity, appName) {
|
|
254
|
+
const model = opportunity.primaryModel;
|
|
255
|
+
const dataset = opportunity.supportingDataset;
|
|
256
|
+
return `# ${appName}
|
|
257
|
+
|
|
258
|
+
${opportunity.description}
|
|
259
|
+
|
|
260
|
+
## Quick Start
|
|
261
|
+
\`\`\`bash
|
|
262
|
+
# Install dependencies
|
|
263
|
+
pip install -r requirements.txt
|
|
264
|
+
|
|
265
|
+
# Run the app
|
|
266
|
+
python app.py
|
|
267
|
+
\`\`\`
|
|
268
|
+
|
|
269
|
+
## Model Details
|
|
270
|
+
- **Name**: ${model.name}
|
|
271
|
+
- **Author**: ${model.author}
|
|
272
|
+
- **Task**: ${model.task || 'N/A'}
|
|
273
|
+
- **Downloads**: ${model.downloads.toLocaleString()}
|
|
274
|
+
|
|
275
|
+
${dataset ? `## Dataset
|
|
276
|
+
- **Name**: ${dataset.name}
|
|
277
|
+
- **Downloads**: ${dataset.downloads.toLocaleString()}
|
|
278
|
+
` : ''}
|
|
279
|
+
|
|
280
|
+
## Configuration
|
|
281
|
+
Edit \`config.yaml\` to customize:
|
|
282
|
+
- Model parameters
|
|
283
|
+
- Input/output settings
|
|
284
|
+
- Hardware preferences
|
|
285
|
+
|
|
286
|
+
## Examples
|
|
287
|
+
See \`examples/\` directory for usage examples.
|
|
288
|
+
|
|
289
|
+
## Hardware Requirements
|
|
290
|
+
${model.hardware?.gpu ? '⚠️ GPU recommended for best performance' : '✅ CPU should work fine'}
|
|
291
|
+
${model.hardware?.memory === 'high' ? '⚠️ High memory required (>8GB RAM)' : ''}
|
|
292
|
+
|
|
293
|
+
## License
|
|
294
|
+
${model.license ? `Model license: ${model.license}` : 'Check model license on Hugging Face Hub'}
|
|
295
|
+
`;
|
|
296
|
+
}
|
|
297
|
+
function generatePythonApp(opportunity, appName) {
|
|
298
|
+
const model = opportunity.primaryModel;
|
|
299
|
+
const modelTask = model.task || 'N/A';
|
|
300
|
+
return `#!/usr/bin/env python3
|
|
301
|
+
"""
|
|
302
|
+
${appName} - Generated by Clawx Forge
|
|
303
|
+
Model: ${model.id}
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
import yaml
|
|
307
|
+
import argparse
|
|
308
|
+
from pathlib import Path
|
|
309
|
+
|
|
310
|
+
def load_config():
|
|
311
|
+
"""Load configuration from config.yaml"""
|
|
312
|
+
config_path = Path(__file__).parent / 'config.yaml'
|
|
313
|
+
with open(config_path, 'r') as f:
|
|
314
|
+
return yaml.safe_load(f)
|
|
315
|
+
|
|
316
|
+
def main():
|
|
317
|
+
"""Main application entry point"""
|
|
318
|
+
parser = argparse.ArgumentParser(description='${opportunity.description}')
|
|
319
|
+
parser.add_argument('--input', type=str, help='Input to process')
|
|
320
|
+
parser.add_argument('--output', type=str, help='Output file path')
|
|
321
|
+
args = parser.parse_args()
|
|
322
|
+
|
|
323
|
+
config = load_config()
|
|
324
|
+
|
|
325
|
+
print(f"Starting ${appName}")
|
|
326
|
+
print(f"Model: ${model.id}")
|
|
327
|
+
print(f"Task: ${modelTask}")
|
|
328
|
+
|
|
329
|
+
if args.input:
|
|
330
|
+
print(f"Processing input: {args.input}")
|
|
331
|
+
# TODO: Add actual model inference here
|
|
332
|
+
result = f"Simulated result for: {args.input}"
|
|
333
|
+
|
|
334
|
+
if args.output:
|
|
335
|
+
with open(args.output, 'w') as f:
|
|
336
|
+
f.write(result)
|
|
337
|
+
print(f"Result saved to: {args.output}")
|
|
338
|
+
else:
|
|
339
|
+
print(f"Result: {result}")
|
|
340
|
+
else:
|
|
341
|
+
print("No input provided. Use --input <text> to process data.")
|
|
342
|
+
print("Example: python app.py --input 'Hello world'")
|
|
343
|
+
|
|
344
|
+
if __name__ == '__main__':
|
|
345
|
+
main()
|
|
346
|
+
`;
|
|
347
|
+
}
|
|
348
|
+
function generateRequirements(opportunity) {
|
|
349
|
+
const model = opportunity.primaryModel;
|
|
350
|
+
let requirements = [
|
|
351
|
+
"PyYAML>=6.0",
|
|
352
|
+
"argparse"
|
|
353
|
+
];
|
|
354
|
+
// Add model-specific requirements
|
|
355
|
+
if (model.task === 'text-classification' || model.task === 'text-generation') {
|
|
356
|
+
requirements.push("transformers>=4.30.0");
|
|
357
|
+
requirements.push("torch>=2.0.0");
|
|
358
|
+
}
|
|
359
|
+
if (model.modality === 'image') {
|
|
360
|
+
requirements.push("Pillow>=9.0.0");
|
|
361
|
+
}
|
|
362
|
+
return requirements.join('\n');
|
|
363
|
+
}
|
|
364
|
+
function generateConfig(opportunity) {
|
|
365
|
+
const model = opportunity.primaryModel;
|
|
366
|
+
return `# ${opportunity.title}
|
|
367
|
+
# Generated by Clawx Forge
|
|
368
|
+
|
|
369
|
+
model:
|
|
370
|
+
id: "${model.id}"
|
|
371
|
+
name: "${model.name}"
|
|
372
|
+
task: "${model.task || 'N/A'}"
|
|
373
|
+
|
|
374
|
+
inference:
|
|
375
|
+
device: "auto" # auto, cpu, cuda
|
|
376
|
+
batch_size: 1
|
|
377
|
+
max_length: 512
|
|
378
|
+
|
|
379
|
+
output:
|
|
380
|
+
format: "text" # text, json, yaml
|
|
381
|
+
save_to_file: true
|
|
382
|
+
|
|
383
|
+
logging:
|
|
384
|
+
level: "INFO"
|
|
385
|
+
file: "app.log"
|
|
386
|
+
`;
|
|
387
|
+
}
|
|
388
|
+
function generateExampleUsage(opportunity) {
|
|
389
|
+
const model = opportunity.primaryModel;
|
|
390
|
+
return `# Example usage for ${opportunity.title}
|
|
391
|
+
|
|
392
|
+
import sys
|
|
393
|
+
sys.path.append('..')
|
|
394
|
+
|
|
395
|
+
from app import main
|
|
396
|
+
|
|
397
|
+
# Example 1: Basic usage
|
|
398
|
+
print("Example 1: Process text")
|
|
399
|
+
# python app.py --input "Your text here"
|
|
400
|
+
|
|
401
|
+
# Example 2: Save to file
|
|
402
|
+
print("Example 2: Save output to file")
|
|
403
|
+
# python app.py --input "Your text" --output result.txt
|
|
404
|
+
|
|
405
|
+
# Example 3: Batch processing (conceptual)
|
|
406
|
+
print("Example 3: Batch processing")
|
|
407
|
+
# for text in texts:
|
|
408
|
+
# result = process(text)
|
|
409
|
+
# print(result)
|
|
410
|
+
`;
|
|
411
|
+
}
|
|
412
|
+
//# sourceMappingURL=scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/forge/scaffold.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forge capability scaffolder.
|
|
3
|
+
*
|
|
4
|
+
* Builds discovered capabilities into working Clawx tools.
|
|
5
|
+
*/
|
|
6
|
+
import type { ClawxConfig } from "../types/index.js";
|
|
7
|
+
import type { BuildOptions } from "./types.js";
|
|
8
|
+
export declare function buildCapability(config: ClawxConfig, capabilityId: string, options?: BuildOptions): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=scaffolder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffolder.d.ts","sourceRoot":"","sources":["../../src/forge/scaffolder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAA4C,MAAM,YAAY,CAAC;AAKzF,wBAAsB,eAAe,CACnC,MAAM,EAAE,WAAW,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CAgEf"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forge capability scaffolder.
|
|
3
|
+
*
|
|
4
|
+
* Builds discovered capabilities into working Clawx tools.
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { loadCapability, saveCapability, getForgeToolsDir } from "./registry.js";
|
|
9
|
+
import { testCapability } from "./tester.js";
|
|
10
|
+
import { log } from "../utils/logger.js";
|
|
11
|
+
export async function buildCapability(config, capabilityId, options = {}) {
|
|
12
|
+
console.log(`\n🔨 Building capability: ${capabilityId}\n`);
|
|
13
|
+
// Load the capability
|
|
14
|
+
const capability = await loadCapability(capabilityId);
|
|
15
|
+
if (!capability) {
|
|
16
|
+
console.error(` ❌ Capability not found: ${capabilityId}`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
if (capability.status === "built" && !options.force) {
|
|
20
|
+
console.log(` ℹ️ Capability already built. Use --force to rebuild.`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// Update status
|
|
24
|
+
capability.status = "building";
|
|
25
|
+
await saveCapability(capability);
|
|
26
|
+
try {
|
|
27
|
+
// Generate JSON tool definition
|
|
28
|
+
const toolDef = generateJsonToolDefinition(capability);
|
|
29
|
+
const toolPath = path.join(getForgeToolsDir(), `${capability.implementation.toolName}.json`);
|
|
30
|
+
// Check if tool already exists
|
|
31
|
+
if (fs.existsSync(toolPath) && !options.force) {
|
|
32
|
+
console.error(` ❌ Tool already exists: ${capability.implementation.toolName}`);
|
|
33
|
+
console.error(` Use --force to overwrite.`);
|
|
34
|
+
capability.status = "failed";
|
|
35
|
+
await saveCapability(capability);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
// Create directory if needed
|
|
39
|
+
fs.mkdirSync(getForgeToolsDir(), { recursive: true });
|
|
40
|
+
// Write JSON tool definition
|
|
41
|
+
fs.writeFileSync(toolPath, JSON.stringify(toolDef, null, 2), "utf-8");
|
|
42
|
+
console.log(` ✅ Generated tool: ${toolPath}`);
|
|
43
|
+
// Update capability status
|
|
44
|
+
capability.status = "built";
|
|
45
|
+
capability.builtAt = new Date().toISOString();
|
|
46
|
+
await saveCapability(capability);
|
|
47
|
+
// Run tests
|
|
48
|
+
console.log(`\n🧪 Running tests...\n`);
|
|
49
|
+
const passed = await testCapability(config, capability);
|
|
50
|
+
if (!passed) {
|
|
51
|
+
console.error(` ❌ Tests failed`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
console.log(`\n✨ Capability built successfully!`);
|
|
55
|
+
console.log(`\n📋 Tool ready to use in Clawx sessions`);
|
|
56
|
+
console.log(` Tool name: ${capability.implementation.toolName}`);
|
|
57
|
+
console.log(` Example: ${capability.implementation.exampleUsage}`);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
log.error("Build failed:", error);
|
|
61
|
+
capability.status = "failed";
|
|
62
|
+
await saveCapability(capability);
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function generateJsonToolDefinition(capability) {
|
|
67
|
+
const toolName = capability.implementation.toolName;
|
|
68
|
+
// Determine implementation type based on capability
|
|
69
|
+
let implementationType = "simulated";
|
|
70
|
+
if (toolName.includes('classify'))
|
|
71
|
+
implementationType = "classification";
|
|
72
|
+
if (toolName.includes('generate'))
|
|
73
|
+
implementationType = "generation";
|
|
74
|
+
if (toolName.includes('summarize'))
|
|
75
|
+
implementationType = "summarization";
|
|
76
|
+
if (toolName.includes('qa'))
|
|
77
|
+
implementationType = "qa";
|
|
78
|
+
// Convert parameters to JSON schema format
|
|
79
|
+
const parameters = {};
|
|
80
|
+
for (const [key, type] of Object.entries(capability.implementation.parameters)) {
|
|
81
|
+
let paramType = "string";
|
|
82
|
+
if (type === "number")
|
|
83
|
+
paramType = "number";
|
|
84
|
+
if (type === "array")
|
|
85
|
+
paramType = "array";
|
|
86
|
+
if (type === "boolean")
|
|
87
|
+
paramType = "boolean";
|
|
88
|
+
parameters[key] = {
|
|
89
|
+
type: paramType,
|
|
90
|
+
description: key,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
name: toolName,
|
|
95
|
+
label: capability.name,
|
|
96
|
+
description: capability.description,
|
|
97
|
+
parameters,
|
|
98
|
+
implementation: {
|
|
99
|
+
type: implementationType,
|
|
100
|
+
models: capability.models.map(m => ({
|
|
101
|
+
id: m.id,
|
|
102
|
+
classificationType: m.classificationType,
|
|
103
|
+
supportedLabels: m.supportedLabels,
|
|
104
|
+
verified: m.verified
|
|
105
|
+
})),
|
|
106
|
+
config: {
|
|
107
|
+
simulated: true,
|
|
108
|
+
exampleOutput: `This is a simulated ${implementationType} tool. To make it real, implement actual model inference.`
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
metadata: {
|
|
112
|
+
capabilityId: capability.id,
|
|
113
|
+
builtAt: new Date().toISOString(),
|
|
114
|
+
version: "1.0.0"
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=scaffolder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffolder.js","sourceRoot":"","sources":["../../src/forge/scaffolder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forge capability tester.
|
|
3
|
+
*
|
|
4
|
+
* Tests built capabilities to ensure they work correctly.
|
|
5
|
+
*/
|
|
6
|
+
import type { ClawxConfig } from "../types/index.js";
|
|
7
|
+
import type { DiscoveredCapability } from "./types.js";
|
|
8
|
+
export declare function testCapability(config: ClawxConfig, capability: DiscoveredCapability): Promise<boolean>;
|
|
9
|
+
//# sourceMappingURL=tester.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tester.d.ts","sourceRoot":"","sources":["../../src/forge/tester.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIvD,wBAAsB,cAAc,CAClC,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,OAAO,CAAC,CAiDlB"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forge capability tester.
|
|
3
|
+
*
|
|
4
|
+
* Tests built capabilities to ensure they work correctly.
|
|
5
|
+
*/
|
|
6
|
+
import { saveCapability } from "./registry.js";
|
|
7
|
+
import { log } from "../utils/logger.js";
|
|
8
|
+
export async function testCapability(config, capability) {
|
|
9
|
+
console.log(`Testing: ${capability.name}`);
|
|
10
|
+
// Update status
|
|
11
|
+
capability.status = "tested";
|
|
12
|
+
try {
|
|
13
|
+
// For now, run simple validation tests
|
|
14
|
+
// In a real implementation, this would:
|
|
15
|
+
// 1. Load the generated tool
|
|
16
|
+
// 2. Execute it with sample inputs
|
|
17
|
+
// 3. Verify outputs
|
|
18
|
+
// 4. Test edge cases
|
|
19
|
+
const tests = [
|
|
20
|
+
validateToolStructure(capability),
|
|
21
|
+
validateParameters(capability),
|
|
22
|
+
// Add more tests as needed
|
|
23
|
+
];
|
|
24
|
+
const allPassed = tests.every(test => test.passed);
|
|
25
|
+
capability.testResults = {
|
|
26
|
+
passed: allPassed,
|
|
27
|
+
details: tests.map(t => t.message).join('\n'),
|
|
28
|
+
timestamp: new Date().toISOString(),
|
|
29
|
+
};
|
|
30
|
+
await saveCapability(capability);
|
|
31
|
+
if (allPassed) {
|
|
32
|
+
console.log(` ✅ All tests passed`);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.log(` ❌ Some tests failed:`);
|
|
37
|
+
tests.filter(t => !t.passed).forEach(t => console.log(` - ${t.message}`));
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
log.error("Test failed:", error);
|
|
43
|
+
capability.testResults = {
|
|
44
|
+
passed: false,
|
|
45
|
+
details: `Test error: ${error instanceof Error ? error.message : String(error)}`,
|
|
46
|
+
timestamp: new Date().toISOString(),
|
|
47
|
+
};
|
|
48
|
+
await saveCapability(capability);
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function validateToolStructure(capability) {
|
|
53
|
+
const requiredFields = ['id', 'name', 'description', 'models', 'implementation'];
|
|
54
|
+
const missing = requiredFields.filter(field => !(field in capability));
|
|
55
|
+
if (missing.length > 0) {
|
|
56
|
+
return {
|
|
57
|
+
passed: false,
|
|
58
|
+
message: `Missing required fields: ${missing.join(', ')}`
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (!capability.implementation.toolName) {
|
|
62
|
+
return {
|
|
63
|
+
passed: false,
|
|
64
|
+
message: 'Implementation missing toolName'
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
passed: true,
|
|
69
|
+
message: 'Tool structure valid'
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function validateParameters(capability) {
|
|
73
|
+
const params = capability.implementation.parameters;
|
|
74
|
+
if (!params || typeof params !== 'object') {
|
|
75
|
+
return {
|
|
76
|
+
passed: false,
|
|
77
|
+
message: 'No parameters defined'
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const paramCount = Object.keys(params).length;
|
|
81
|
+
if (paramCount === 0) {
|
|
82
|
+
return {
|
|
83
|
+
passed: false,
|
|
84
|
+
message: 'At least one parameter required'
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// Check for valid parameter types
|
|
88
|
+
const validTypes = ['string', 'number', 'array', 'boolean', 'object'];
|
|
89
|
+
const invalidTypes = Object.entries(params)
|
|
90
|
+
.filter(([_, type]) => !validTypes.includes(type))
|
|
91
|
+
.map(([name]) => name);
|
|
92
|
+
if (invalidTypes.length > 0) {
|
|
93
|
+
return {
|
|
94
|
+
passed: false,
|
|
95
|
+
message: `Invalid parameter types: ${invalidTypes.join(', ')}. Valid types: ${validTypes.join(', ')}`
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
passed: true,
|
|
100
|
+
message: `Parameters valid (${paramCount} parameters)`
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=tester.js.map
|