@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,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forge community sharing.
|
|
3
|
+
*
|
|
4
|
+
* Enables sharing discovered capabilities with other Clawx users.
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { getCapabilitiesDir, getForgeToolsDir } from "./registry.js";
|
|
9
|
+
import { log } from "../utils/logger.js";
|
|
10
|
+
export async function exportCapability(capabilityId, exportPath) {
|
|
11
|
+
const capabilitiesDir = getCapabilitiesDir();
|
|
12
|
+
const capabilityFile = path.join(capabilitiesDir, `${capabilityId}.json`);
|
|
13
|
+
if (!fs.existsSync(capabilityFile)) {
|
|
14
|
+
throw new Error(`Capability not found: ${capabilityId}`);
|
|
15
|
+
}
|
|
16
|
+
// Load the capability
|
|
17
|
+
const capabilityContent = fs.readFileSync(capabilityFile, "utf-8");
|
|
18
|
+
const capability = JSON.parse(capabilityContent);
|
|
19
|
+
// Create shared capability format
|
|
20
|
+
const sharedCapability = {
|
|
21
|
+
id: capability.id,
|
|
22
|
+
name: capability.name,
|
|
23
|
+
description: capability.description,
|
|
24
|
+
author: process.env.USER || "anonymous",
|
|
25
|
+
version: "1.0.0",
|
|
26
|
+
models: capability.models.map(m => m.id),
|
|
27
|
+
tags: extractTags(capability),
|
|
28
|
+
createdAt: capability.discoveredAt,
|
|
29
|
+
downloads: 0,
|
|
30
|
+
};
|
|
31
|
+
// Check for tool implementation
|
|
32
|
+
const toolsDir = getForgeToolsDir();
|
|
33
|
+
const toolFile = path.join(toolsDir, `${capability.implementation.toolName}.ts`);
|
|
34
|
+
const testFile = path.join(toolsDir, `${capability.implementation.toolName}.test.ts`);
|
|
35
|
+
const exportData = {
|
|
36
|
+
metadata: sharedCapability,
|
|
37
|
+
capability: capability,
|
|
38
|
+
tool: fs.existsSync(toolFile) ? fs.readFileSync(toolFile, "utf-8") : null,
|
|
39
|
+
test: fs.existsSync(testFile) ? fs.readFileSync(testFile, "utf-8") : null,
|
|
40
|
+
};
|
|
41
|
+
// Determine export path
|
|
42
|
+
const finalExportPath = exportPath || path.join(process.cwd(), `${capabilityId}.clawx-forge.json`);
|
|
43
|
+
// Write export file
|
|
44
|
+
fs.writeFileSync(finalExportPath, JSON.stringify(exportData, null, 2), "utf-8");
|
|
45
|
+
log.info(`Exported capability to: ${finalExportPath}`);
|
|
46
|
+
return finalExportPath;
|
|
47
|
+
}
|
|
48
|
+
export async function importCapability(importPath, options = {}) {
|
|
49
|
+
if (!fs.existsSync(importPath)) {
|
|
50
|
+
throw new Error(`Import file not found: ${importPath}`);
|
|
51
|
+
}
|
|
52
|
+
const importContent = fs.readFileSync(importPath, "utf-8");
|
|
53
|
+
const importData = JSON.parse(importContent);
|
|
54
|
+
if (!importData.metadata || !importData.capability) {
|
|
55
|
+
throw new Error("Invalid forge export format");
|
|
56
|
+
}
|
|
57
|
+
const sharedCapability = importData.metadata;
|
|
58
|
+
const capability = importData.capability;
|
|
59
|
+
// Check if already exists
|
|
60
|
+
const capabilitiesDir = getCapabilitiesDir();
|
|
61
|
+
const capabilityFile = path.join(capabilitiesDir, `${capability.id}.json`);
|
|
62
|
+
if (fs.existsSync(capabilityFile) && !options.force) {
|
|
63
|
+
throw new Error(`Capability already exists: ${capability.id}. Use --force to overwrite.`);
|
|
64
|
+
}
|
|
65
|
+
// Save capability
|
|
66
|
+
fs.mkdirSync(capabilitiesDir, { recursive: true });
|
|
67
|
+
fs.writeFileSync(capabilityFile, JSON.stringify(capability, null, 2), "utf-8");
|
|
68
|
+
// Save tool implementation if included
|
|
69
|
+
if (importData.tool) {
|
|
70
|
+
const toolsDir = getForgeToolsDir();
|
|
71
|
+
const toolFile = path.join(toolsDir, `${capability.implementation.toolName}.ts`);
|
|
72
|
+
fs.mkdirSync(toolsDir, { recursive: true });
|
|
73
|
+
fs.writeFileSync(toolFile, importData.tool, "utf-8");
|
|
74
|
+
if (importData.test) {
|
|
75
|
+
const testFile = path.join(toolsDir, `${capability.implementation.toolName}.test.ts`);
|
|
76
|
+
fs.writeFileSync(testFile, importData.test, "utf-8");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
log.info(`Imported capability: ${capability.name} (${capability.id})`);
|
|
80
|
+
return capability;
|
|
81
|
+
}
|
|
82
|
+
export function generateShareableLink(capabilityId) {
|
|
83
|
+
// In a full implementation, this would upload to a community server
|
|
84
|
+
// For now, return instructions
|
|
85
|
+
return `To share capability ${capabilityId}:
|
|
86
|
+
1. Export it: clawx forge export ${capabilityId}
|
|
87
|
+
2. Share the .clawx-forge.json file
|
|
88
|
+
3. Others can import it: clawx forge import <file>
|
|
89
|
+
|
|
90
|
+
Future: Community server integration for automatic sharing.`;
|
|
91
|
+
}
|
|
92
|
+
function extractTags(capability) {
|
|
93
|
+
const tags = new Set();
|
|
94
|
+
// Add from capability name
|
|
95
|
+
const nameWords = capability.name.toLowerCase().split(/[^a-z0-9]+/);
|
|
96
|
+
nameWords.forEach(word => word.length > 2 && tags.add(word));
|
|
97
|
+
// Add from description
|
|
98
|
+
const descWords = capability.description.toLowerCase().split(/[^a-z0-9]+/);
|
|
99
|
+
descWords.forEach(word => word.length > 3 && tags.add(word));
|
|
100
|
+
// Add model tasks
|
|
101
|
+
capability.models.forEach(model => {
|
|
102
|
+
tags.add(model.task);
|
|
103
|
+
model.capabilities?.forEach(cap => tags.add(cap));
|
|
104
|
+
});
|
|
105
|
+
// Add common tags
|
|
106
|
+
if (capability.feasibility === "high")
|
|
107
|
+
tags.add("easy");
|
|
108
|
+
if (capability.implementation.estimatedComplexity === "simple")
|
|
109
|
+
tags.add("beginner");
|
|
110
|
+
return Array.from(tags).slice(0, 10); // Limit to 10 tags
|
|
111
|
+
}
|
|
112
|
+
export async function listCommunityCapabilities() {
|
|
113
|
+
console.log("\n🌐 Community Capabilities (Future Feature)\n");
|
|
114
|
+
console.log(" This feature will connect to a community server where users");
|
|
115
|
+
console.log(" can share and discover capabilities created by others.\n");
|
|
116
|
+
console.log(" Planned features:");
|
|
117
|
+
console.log(" • Browse capabilities by category/tag");
|
|
118
|
+
console.log(" • Search for specific tools");
|
|
119
|
+
console.log(" • Rate and review capabilities");
|
|
120
|
+
console.log(" • Automatic updates");
|
|
121
|
+
console.log(" • Popular/trending capabilities\n");
|
|
122
|
+
console.log(" For now, use export/import to share capabilities:");
|
|
123
|
+
console.log(" clawx forge export <id>");
|
|
124
|
+
console.log(" clawx forge import <file>\n");
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=community.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"community.js","sourceRoot":"","sources":["../../src/forge/community.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Opportunity } from './types.js';
|
|
2
|
+
export interface DiscoverOptions {
|
|
3
|
+
query: string;
|
|
4
|
+
limit?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function discoverOpportunities(options: DiscoverOptions): Promise<Opportunity[]>;
|
|
7
|
+
export declare function loadOpportunities(): Opportunity[];
|
|
8
|
+
export declare function findOpportunity(id: string): Opportunity | undefined;
|
|
9
|
+
export declare function listOpportunities(options?: {
|
|
10
|
+
sort?: 'overall' | 'usefulness' | 'novelty' | 'feasibility' | 'fit';
|
|
11
|
+
minScore?: number;
|
|
12
|
+
limit?: number;
|
|
13
|
+
}): Opportunity[];
|
|
14
|
+
//# sourceMappingURL=discover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/forge/discover.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,WAAW,EAAgB,MAAM,YAAY,CAAC;AAS9D,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CA2C5F;AAmED,wBAAgB,iBAAiB,IAAI,WAAW,EAAE,CAcjD;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAGnE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE;IAC1C,IAAI,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,GAAG,KAAK,CAAC;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,WAAW,EAAE,CAuBhB"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Forge v1: Discovery engine (models + datasets only)
|
|
2
|
+
import { searchModels, searchDatasets } from './hf-client.js';
|
|
3
|
+
import { createOpportunity } from './rank.js';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
6
|
+
const FORGE_DIR = join(process.env.HOME || process.env.USERPROFILE || '.', '.clawx', 'forge');
|
|
7
|
+
const STORAGE_FILE = join(FORGE_DIR, 'storage.json');
|
|
8
|
+
export async function discoverOpportunities(options) {
|
|
9
|
+
const { query, limit = 20 } = options;
|
|
10
|
+
console.log(`🔍 Searching HF Hub for: "${query}"`);
|
|
11
|
+
// Search for models and datasets
|
|
12
|
+
const [models, datasets] = await Promise.all([
|
|
13
|
+
searchModels(query, Math.ceil(limit * 0.7)), // 70% models
|
|
14
|
+
searchDatasets(query, Math.ceil(limit * 0.3)) // 30% datasets
|
|
15
|
+
]);
|
|
16
|
+
console.log(`📊 Found ${models.length} models and ${datasets.length} datasets`);
|
|
17
|
+
// Create opportunities from combinations
|
|
18
|
+
const opportunities = [];
|
|
19
|
+
// 1. Model-only opportunities
|
|
20
|
+
for (const model of models.slice(0, 10)) {
|
|
21
|
+
opportunities.push(createOpportunity(model, undefined, query));
|
|
22
|
+
}
|
|
23
|
+
// 2. Model + dataset opportunities (if we have datasets)
|
|
24
|
+
if (datasets.length > 0) {
|
|
25
|
+
for (const model of models.slice(0, 5)) {
|
|
26
|
+
for (const dataset of datasets.slice(0, 3)) {
|
|
27
|
+
// Only pair if they share modality or task
|
|
28
|
+
if (shouldPair(model, dataset)) {
|
|
29
|
+
opportunities.push(createOpportunity(model, dataset, query));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Sort by overall score
|
|
35
|
+
opportunities.sort((a, b) => b.scores.overall - a.scores.overall);
|
|
36
|
+
// Take top N
|
|
37
|
+
const topOpportunities = opportunities.slice(0, limit);
|
|
38
|
+
// Save to storage
|
|
39
|
+
saveOpportunities(topOpportunities, query);
|
|
40
|
+
return topOpportunities;
|
|
41
|
+
}
|
|
42
|
+
function shouldPair(model, dataset) {
|
|
43
|
+
// Pair if they share modality
|
|
44
|
+
if (model.modality && dataset.modality && model.modality === dataset.modality) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
// Pair if they share task
|
|
48
|
+
if (model.task && dataset.task && model.task === dataset.task) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
// Pair if dataset tags mention model's task
|
|
52
|
+
if (model.task && dataset.tags.some(tag => tag.includes(model.task))) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
function saveOpportunities(opportunities, query) {
|
|
58
|
+
try {
|
|
59
|
+
// Ensure directory exists
|
|
60
|
+
if (!existsSync(FORGE_DIR)) {
|
|
61
|
+
mkdirSync(FORGE_DIR, { recursive: true });
|
|
62
|
+
}
|
|
63
|
+
// Load existing storage or create new
|
|
64
|
+
let storage = { opportunities: [] };
|
|
65
|
+
if (existsSync(STORAGE_FILE)) {
|
|
66
|
+
try {
|
|
67
|
+
const content = readFileSync(STORAGE_FILE, 'utf8');
|
|
68
|
+
storage = JSON.parse(content);
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
console.warn('Could not parse existing storage, creating new');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Add new opportunities (avoid duplicates)
|
|
75
|
+
const existingIds = new Set(storage.opportunities.map(o => o.id));
|
|
76
|
+
const newOpportunities = opportunities.filter(o => !existingIds.has(o.id));
|
|
77
|
+
storage.opportunities = [...newOpportunities, ...storage.opportunities];
|
|
78
|
+
// Keep only last 100 opportunities
|
|
79
|
+
if (storage.opportunities.length > 100) {
|
|
80
|
+
storage.opportunities = storage.opportunities.slice(0, 100);
|
|
81
|
+
}
|
|
82
|
+
// Update last discovery
|
|
83
|
+
storage.lastDiscovery = {
|
|
84
|
+
query,
|
|
85
|
+
timestamp: new Date().toISOString(),
|
|
86
|
+
count: opportunities.length
|
|
87
|
+
};
|
|
88
|
+
// Save to file
|
|
89
|
+
writeFileSync(STORAGE_FILE, JSON.stringify(storage, null, 2), 'utf8');
|
|
90
|
+
console.log(`💾 Saved ${newOpportunities.length} new opportunities to ${STORAGE_FILE}`);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error('Failed to save opportunities:', error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export function loadOpportunities() {
|
|
97
|
+
try {
|
|
98
|
+
if (!existsSync(STORAGE_FILE)) {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
const content = readFileSync(STORAGE_FILE, 'utf8');
|
|
102
|
+
const storage = JSON.parse(content);
|
|
103
|
+
return storage.opportunities || [];
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error('Failed to load opportunities:', error);
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function findOpportunity(id) {
|
|
111
|
+
const opportunities = loadOpportunities();
|
|
112
|
+
return opportunities.find(o => o.id === id);
|
|
113
|
+
}
|
|
114
|
+
export function listOpportunities(options) {
|
|
115
|
+
let opportunities = loadOpportunities();
|
|
116
|
+
// Filter by minimum score
|
|
117
|
+
if (options?.minScore !== undefined) {
|
|
118
|
+
opportunities = opportunities.filter(o => o.scores.overall >= options.minScore);
|
|
119
|
+
}
|
|
120
|
+
// Sort
|
|
121
|
+
const sortField = options?.sort || 'overall';
|
|
122
|
+
opportunities.sort((a, b) => {
|
|
123
|
+
if (sortField === 'overall') {
|
|
124
|
+
return b.scores.overall - a.scores.overall;
|
|
125
|
+
}
|
|
126
|
+
return b.scores[sortField] - a.scores[sortField];
|
|
127
|
+
});
|
|
128
|
+
// Limit
|
|
129
|
+
if (options?.limit !== undefined) {
|
|
130
|
+
opportunities = opportunities.slice(0, options.limit);
|
|
131
|
+
}
|
|
132
|
+
return opportunities;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=discover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/forge/discover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forge.test.d.ts","sourceRoot":"","sources":["../../src/forge/forge.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// Forge v1 tests
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import { createOpportunity } from './rank.js';
|
|
4
|
+
import { createScaffoldPlan } from './scaffold.js';
|
|
5
|
+
// Mock data
|
|
6
|
+
const mockModel = {
|
|
7
|
+
id: 'test/model',
|
|
8
|
+
type: 'model',
|
|
9
|
+
name: 'Test Model',
|
|
10
|
+
author: 'test',
|
|
11
|
+
downloads: 1000,
|
|
12
|
+
tags: ['text-classification', 'pytorch'],
|
|
13
|
+
task: 'text-classification',
|
|
14
|
+
modality: 'text',
|
|
15
|
+
license: 'mit',
|
|
16
|
+
hardware: { gpu: false, memory: 'low' }
|
|
17
|
+
};
|
|
18
|
+
const mockDataset = {
|
|
19
|
+
id: 'test/dataset',
|
|
20
|
+
type: 'dataset',
|
|
21
|
+
name: 'Test Dataset',
|
|
22
|
+
author: 'test',
|
|
23
|
+
downloads: 500,
|
|
24
|
+
tags: ['text-classification'],
|
|
25
|
+
task: 'text-classification',
|
|
26
|
+
modality: 'text',
|
|
27
|
+
license: 'cc-by-4.0',
|
|
28
|
+
hardware: { gpu: false, memory: 'low' }
|
|
29
|
+
};
|
|
30
|
+
describe('Forge v1', () => {
|
|
31
|
+
describe('opportunity ranking', () => {
|
|
32
|
+
it('creates opportunity with correct shape', () => {
|
|
33
|
+
const opportunity = createOpportunity(mockModel, mockDataset, 'test query');
|
|
34
|
+
expect(opportunity).toHaveProperty('id');
|
|
35
|
+
expect(opportunity.id).toMatch(/^opp_/);
|
|
36
|
+
expect(opportunity.title).toBeTypeOf('string');
|
|
37
|
+
expect(opportunity.description).toBeTypeOf('string');
|
|
38
|
+
expect(opportunity.primaryModel).toEqual(mockModel);
|
|
39
|
+
expect(opportunity.supportingDataset).toEqual(mockDataset);
|
|
40
|
+
expect(opportunity.query).toBe('test query');
|
|
41
|
+
expect(opportunity.createdAt).toBeTypeOf('string');
|
|
42
|
+
// Scores
|
|
43
|
+
expect(opportunity.scores).toEqual({
|
|
44
|
+
usefulness: expect.any(Number),
|
|
45
|
+
novelty: expect.any(Number),
|
|
46
|
+
feasibility: expect.any(Number),
|
|
47
|
+
fit: expect.any(Number),
|
|
48
|
+
overall: expect.any(Number)
|
|
49
|
+
});
|
|
50
|
+
// All scores between 0 and 1
|
|
51
|
+
Object.values(opportunity.scores).forEach(score => {
|
|
52
|
+
expect(score).toBeGreaterThanOrEqual(0);
|
|
53
|
+
expect(score).toBeLessThanOrEqual(1);
|
|
54
|
+
});
|
|
55
|
+
// Possible outputs
|
|
56
|
+
expect(opportunity.possibleOutputs).toBeInstanceOf(Array);
|
|
57
|
+
expect(opportunity.possibleOutputs.length).toBeGreaterThan(0);
|
|
58
|
+
opportunity.possibleOutputs.forEach(output => {
|
|
59
|
+
expect(['tool', 'app']).toContain(output.type);
|
|
60
|
+
expect(['low', 'medium', 'high']).toContain(output.complexity);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
it('creates opportunity without dataset', () => {
|
|
64
|
+
const opportunity = createOpportunity(mockModel, undefined, 'test query');
|
|
65
|
+
expect(opportunity.primaryModel).toEqual(mockModel);
|
|
66
|
+
expect(opportunity.supportingDataset).toBeUndefined();
|
|
67
|
+
expect(opportunity.description).toContain(mockModel.name);
|
|
68
|
+
});
|
|
69
|
+
it('scores are reasonable for test model', () => {
|
|
70
|
+
const opportunity = createOpportunity(mockModel, mockDataset, 'test query');
|
|
71
|
+
// Text classification with low hardware should have good feasibility
|
|
72
|
+
expect(opportunity.scores.feasibility).toBeGreaterThan(0.5);
|
|
73
|
+
// Text tasks should fit Clawx well
|
|
74
|
+
expect(opportunity.scores.fit).toBeGreaterThan(0.5);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe('scaffold plan generation', () => {
|
|
78
|
+
const mockOpportunity = {
|
|
79
|
+
id: 'opp_test123',
|
|
80
|
+
title: 'Test Opportunity',
|
|
81
|
+
description: 'Test description',
|
|
82
|
+
primaryModel: mockModel,
|
|
83
|
+
supportingDataset: mockDataset,
|
|
84
|
+
scores: {
|
|
85
|
+
usefulness: 0.8,
|
|
86
|
+
novelty: 0.6,
|
|
87
|
+
feasibility: 0.9,
|
|
88
|
+
fit: 0.7,
|
|
89
|
+
overall: 0.75
|
|
90
|
+
},
|
|
91
|
+
possibleOutputs: [
|
|
92
|
+
{ type: 'tool', complexity: 'low' },
|
|
93
|
+
{ type: 'app', complexity: 'medium' }
|
|
94
|
+
],
|
|
95
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
96
|
+
query: 'test query'
|
|
97
|
+
};
|
|
98
|
+
it('creates tool scaffold plan', () => {
|
|
99
|
+
const plan = createScaffoldPlan(mockOpportunity, {
|
|
100
|
+
opportunityId: 'opp_test123',
|
|
101
|
+
outputType: 'tool',
|
|
102
|
+
outputName: 'test-tool',
|
|
103
|
+
outputDir: './test-tool'
|
|
104
|
+
});
|
|
105
|
+
expect(plan.opportunityId).toBe('opp_test123');
|
|
106
|
+
expect(plan.outputType).toBe('tool');
|
|
107
|
+
expect(plan.outputName).toBe('test-tool');
|
|
108
|
+
expect(plan.files).toBeInstanceOf(Array);
|
|
109
|
+
expect(plan.files.length).toBeGreaterThan(0);
|
|
110
|
+
expect(plan.integrationNotes).toBeTypeOf('string');
|
|
111
|
+
// Check file structure
|
|
112
|
+
const filePaths = plan.files.map(f => f.path);
|
|
113
|
+
expect(filePaths).toContain('README.md');
|
|
114
|
+
expect(filePaths).toContain('tool.json');
|
|
115
|
+
expect(filePaths).toContain('tool.ts');
|
|
116
|
+
expect(filePaths).toContain('package.json');
|
|
117
|
+
// Check content contains opportunity data
|
|
118
|
+
const readme = plan.files.find(f => f.path === 'README.md').content;
|
|
119
|
+
expect(readme).toContain('test-tool');
|
|
120
|
+
expect(readme).toContain(mockModel.name);
|
|
121
|
+
expect(readme).toContain('Setup');
|
|
122
|
+
const toolTs = plan.files.find(f => f.path === 'tool.ts').content;
|
|
123
|
+
expect(toolTs).toContain('test-tool');
|
|
124
|
+
expect(toolTs).toContain(mockModel.id);
|
|
125
|
+
});
|
|
126
|
+
it('creates app scaffold plan', () => {
|
|
127
|
+
const plan = createScaffoldPlan(mockOpportunity, {
|
|
128
|
+
opportunityId: 'opp_test123',
|
|
129
|
+
outputType: 'app',
|
|
130
|
+
outputName: 'test-app',
|
|
131
|
+
outputDir: './test-app'
|
|
132
|
+
});
|
|
133
|
+
expect(plan.opportunityId).toBe('opp_test123');
|
|
134
|
+
expect(plan.outputType).toBe('app');
|
|
135
|
+
expect(plan.outputName).toBe('test-app');
|
|
136
|
+
expect(plan.files).toBeInstanceOf(Array);
|
|
137
|
+
expect(plan.files.length).toBeGreaterThan(0);
|
|
138
|
+
expect(plan.integrationNotes).toBeUndefined();
|
|
139
|
+
// Check file structure
|
|
140
|
+
const filePaths = plan.files.map(f => f.path);
|
|
141
|
+
expect(filePaths).toContain('README.md');
|
|
142
|
+
expect(filePaths).toContain('app.py');
|
|
143
|
+
expect(filePaths).toContain('requirements.txt');
|
|
144
|
+
expect(filePaths).toContain('config.yaml');
|
|
145
|
+
// Check content contains opportunity data
|
|
146
|
+
const readme = plan.files.find(f => f.path === 'README.md').content;
|
|
147
|
+
expect(readme).toContain('test-app');
|
|
148
|
+
expect(readme).toContain(mockModel.name);
|
|
149
|
+
const appPy = plan.files.find(f => f.path === 'app.py').content;
|
|
150
|
+
expect(appPy).toContain('test-app');
|
|
151
|
+
expect(appPy).toContain(mockModel.id);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
describe('scaffold file writing', () => {
|
|
155
|
+
it('tool scaffold creates expected files', async () => {
|
|
156
|
+
const fs = await import('fs');
|
|
157
|
+
const path = await import('path');
|
|
158
|
+
const { executeScaffoldPlan } = await import('./scaffold.js');
|
|
159
|
+
const mockOpportunity = {
|
|
160
|
+
id: 'opp_test123',
|
|
161
|
+
title: 'Test Opportunity',
|
|
162
|
+
description: 'Test description',
|
|
163
|
+
primaryModel: mockModel,
|
|
164
|
+
supportingDataset: mockDataset,
|
|
165
|
+
scores: {
|
|
166
|
+
usefulness: 0.8,
|
|
167
|
+
novelty: 0.6,
|
|
168
|
+
feasibility: 0.9,
|
|
169
|
+
fit: 0.7,
|
|
170
|
+
overall: 0.75
|
|
171
|
+
},
|
|
172
|
+
possibleOutputs: [
|
|
173
|
+
{ type: 'tool', complexity: 'low' }
|
|
174
|
+
],
|
|
175
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
176
|
+
query: 'test query'
|
|
177
|
+
};
|
|
178
|
+
const plan = createScaffoldPlan(mockOpportunity, {
|
|
179
|
+
opportunityId: 'opp_test123',
|
|
180
|
+
outputType: 'tool',
|
|
181
|
+
outputName: 'test-tool',
|
|
182
|
+
outputDir: './test-scaffold-output'
|
|
183
|
+
});
|
|
184
|
+
// Clean up if exists
|
|
185
|
+
if (fs.existsSync('./test-scaffold-output')) {
|
|
186
|
+
fs.rmSync('./test-scaffold-output', { recursive: true });
|
|
187
|
+
}
|
|
188
|
+
// Execute scaffold
|
|
189
|
+
executeScaffoldPlan(plan, './test-scaffold-output');
|
|
190
|
+
// Check files exist
|
|
191
|
+
expect(fs.existsSync('./test-scaffold-output')).toBe(true);
|
|
192
|
+
expect(fs.existsSync('./test-scaffold-output/README.md')).toBe(true);
|
|
193
|
+
expect(fs.existsSync('./test-scaffold-output/tool.json')).toBe(true);
|
|
194
|
+
expect(fs.existsSync('./test-scaffold-output/tool.ts')).toBe(true);
|
|
195
|
+
expect(fs.existsSync('./test-scaffold-output/package.json')).toBe(true);
|
|
196
|
+
expect(fs.existsSync('./test-scaffold-output/test-data/example.txt')).toBe(true);
|
|
197
|
+
// Clean up
|
|
198
|
+
fs.rmSync('./test-scaffold-output', { recursive: true });
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
//# sourceMappingURL=forge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forge.test.js","sourceRoot":"","sources":["../../src/forge/forge.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface HardwareInfo {
|
|
2
|
+
gpu: boolean;
|
|
3
|
+
memory: 'low' | 'medium' | 'high';
|
|
4
|
+
feasibility: 'likely' | 'maybe' | 'probably heavy';
|
|
5
|
+
}
|
|
6
|
+
export declare function analyzeHardwareFeasibility(gpuRequired: boolean, memoryRequired: 'low' | 'medium' | 'high'): HardwareInfo;
|
|
7
|
+
export declare function getHardwareDescription(info: HardwareInfo): string;
|
|
8
|
+
//# sourceMappingURL=hardware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardware.d.ts","sourceRoot":"","sources":["../../src/forge/hardware.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClC,WAAW,EAAE,QAAQ,GAAG,OAAO,GAAG,gBAAgB,CAAC;CACpD;AAED,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,OAAO,EACpB,cAAc,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GACxC,YAAY,CAmBd;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAYjE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Forge v1: Simple hardware analysis
|
|
2
|
+
export function analyzeHardwareFeasibility(gpuRequired, memoryRequired) {
|
|
3
|
+
// Simple feasibility assessment
|
|
4
|
+
let feasibility = 'likely';
|
|
5
|
+
if (gpuRequired) {
|
|
6
|
+
feasibility = 'maybe'; // GPU not guaranteed
|
|
7
|
+
}
|
|
8
|
+
if (memoryRequired === 'high') {
|
|
9
|
+
feasibility = 'probably heavy';
|
|
10
|
+
}
|
|
11
|
+
else if (memoryRequired === 'medium' && gpuRequired) {
|
|
12
|
+
feasibility = 'maybe';
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
gpu: gpuRequired,
|
|
16
|
+
memory: memoryRequired,
|
|
17
|
+
feasibility
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function getHardwareDescription(info) {
|
|
21
|
+
const parts = [];
|
|
22
|
+
if (info.gpu) {
|
|
23
|
+
parts.push('GPU');
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
parts.push('CPU');
|
|
27
|
+
}
|
|
28
|
+
parts.push(info.memory, 'memory');
|
|
29
|
+
return `${parts.join(' ')} (${info.feasibility} locally)`;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=hardware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardware.js","sourceRoot":"","sources":["../../src/forge/hardware.ts"],"names":[],"mappings":"AAAA,qCAAqC;AAQrC,MAAM,UAAU,0BAA0B,CACxC,WAAoB,EACpB,cAAyC;IAEzC,gCAAgC;IAChC,IAAI,WAAW,GAA0C,QAAQ,CAAC;IAElE,IAAI,WAAW,EAAE,CAAC;QAChB,WAAW,GAAG,OAAO,CAAC,CAAC,qBAAqB;IAC9C,CAAC;IAED,IAAI,cAAc,KAAK,MAAM,EAAE,CAAC;QAC9B,WAAW,GAAG,gBAAgB,CAAC;IACjC,CAAC;SAAM,IAAI,cAAc,KAAK,QAAQ,IAAI,WAAW,EAAE,CAAC;QACtD,WAAW,GAAG,OAAO,CAAC;IACxB,CAAC;IAED,OAAO;QACL,GAAG,EAAE,WAAW;QAChB,MAAM,EAAE,cAAc;QACtB,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAkB;IACvD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAElC,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,WAAW,WAAW,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Asset } from './types.js';
|
|
2
|
+
export interface HFSearchParams {
|
|
3
|
+
query: string;
|
|
4
|
+
limit?: number;
|
|
5
|
+
type?: 'model' | 'dataset';
|
|
6
|
+
}
|
|
7
|
+
export declare function searchModels(query: string, limit?: number): Promise<Asset[]>;
|
|
8
|
+
export declare function searchDatasets(query: string, limit?: number): Promise<Asset[]>;
|
|
9
|
+
//# sourceMappingURL=hf-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hf-client.d.ts","sourceRoot":"","sources":["../../src/forge/hf-client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5B;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAoBtF;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAoBxF"}
|