@arcteninc/core 0.0.22 → 0.0.23
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/package.json +1 -1
- package/scripts/cli-extract-types-auto.ts +136 -16
package/package.json
CHANGED
|
@@ -57,11 +57,136 @@ async function findToolUsageFiles(projectRoot: string): Promise<string[]> {
|
|
|
57
57
|
return files;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Extract tool names from an expression (handles arrays, variables, useMemo, etc.)
|
|
62
|
+
*/
|
|
63
|
+
function extractToolNamesFromExpression(
|
|
64
|
+
expr: ts.Expression,
|
|
65
|
+
sourceFile: ts.SourceFile,
|
|
66
|
+
variableMap: Map<string, ts.Expression>
|
|
67
|
+
): Set<string> {
|
|
68
|
+
const toolNames = new Set<string>();
|
|
69
|
+
const visited = new Set<ts.Node>();
|
|
70
|
+
|
|
71
|
+
function extractFromExpr(node: ts.Node): void {
|
|
72
|
+
if (visited.has(node)) return;
|
|
73
|
+
visited.add(node);
|
|
74
|
+
|
|
75
|
+
// Direct array literal: [tool1, tool2]
|
|
76
|
+
if (ts.isArrayLiteralExpression(node)) {
|
|
77
|
+
for (const element of node.elements) {
|
|
78
|
+
if (ts.isSpreadElement(element)) {
|
|
79
|
+
// Handle spread: [...someArray]
|
|
80
|
+
extractFromExpr(element.expression);
|
|
81
|
+
} else {
|
|
82
|
+
const name = element.getText(sourceFile).trim();
|
|
83
|
+
// Remove any object property access (e.g., tools.getOrders -> getOrders)
|
|
84
|
+
const simpleName = name.split('.').pop() || name;
|
|
85
|
+
if (simpleName && simpleName !== 'undefined' && simpleName !== 'null') {
|
|
86
|
+
toolNames.add(simpleName);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Variable reference: toolsList
|
|
94
|
+
if (ts.isIdentifier(node)) {
|
|
95
|
+
const varName = node.getText(sourceFile);
|
|
96
|
+
const varExpr = variableMap.get(varName);
|
|
97
|
+
if (varExpr) {
|
|
98
|
+
extractFromExpr(varExpr);
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Property access: wrappedTools.getRAGInfo
|
|
104
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
105
|
+
const propName = node.name.getText(sourceFile);
|
|
106
|
+
toolNames.add(propName);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// useMemo(() => [...], [])
|
|
111
|
+
if (ts.isCallExpression(node)) {
|
|
112
|
+
const callExpr = node.expression;
|
|
113
|
+
if (ts.isIdentifier(callExpr)) {
|
|
114
|
+
const funcName = callExpr.getText(sourceFile);
|
|
115
|
+
if (funcName === 'useMemo' && node.arguments.length > 0) {
|
|
116
|
+
const firstArg = node.arguments[0];
|
|
117
|
+
// Arrow function: () => [...]
|
|
118
|
+
if (ts.isArrowFunction(firstArg) && firstArg.body) {
|
|
119
|
+
if (ts.isBlock(firstArg.body)) {
|
|
120
|
+
// Block body: () => { return [...] }
|
|
121
|
+
for (const stmt of firstArg.body.statements) {
|
|
122
|
+
if (ts.isReturnStatement(stmt) && stmt.expression) {
|
|
123
|
+
extractFromExpr(stmt.expression);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
// Expression body: () => [...]
|
|
128
|
+
extractFromExpr(firstArg.body);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Regular function call: useMemo(fn, [])
|
|
132
|
+
else if (ts.isFunctionExpression(firstArg) || ts.isArrowFunction(firstArg)) {
|
|
133
|
+
// Can't easily extract from function body without more analysis
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Parenthesized: (toolsList)
|
|
141
|
+
if (ts.isParenthesizedExpression(node)) {
|
|
142
|
+
extractFromExpr(node.expression);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
extractFromExpr(expr);
|
|
148
|
+
return toolNames;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Build a map of variable declarations in the file
|
|
153
|
+
*/
|
|
154
|
+
function buildVariableMap(sourceFile: ts.SourceFile): Map<string, ts.Expression> {
|
|
155
|
+
const variableMap = new Map<string, ts.Expression>();
|
|
156
|
+
|
|
157
|
+
function visit(node: ts.Node) {
|
|
158
|
+
// const toolsList = [...] or const { tools } = something
|
|
159
|
+
if (ts.isVariableStatement(node)) {
|
|
160
|
+
for (const declaration of node.declarationList.declarations) {
|
|
161
|
+
if (ts.isIdentifier(declaration.name)) {
|
|
162
|
+
const varName = declaration.name.getText(sourceFile);
|
|
163
|
+
if (declaration.initializer) {
|
|
164
|
+
variableMap.set(varName, declaration.initializer);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Handle destructuring: const { tools } = something
|
|
168
|
+
else if (ts.isObjectBindingPattern(declaration.name)) {
|
|
169
|
+
// For now, skip destructuring - can be enhanced later
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
ts.forEachChild(node, visit);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
visit(sourceFile);
|
|
178
|
+
return variableMap;
|
|
179
|
+
}
|
|
180
|
+
|
|
60
181
|
/**
|
|
61
182
|
* Extract tool names from ArctenAgent or useAgent usage
|
|
62
183
|
*/
|
|
63
|
-
function extractToolNamesFromFile(
|
|
184
|
+
function extractToolNamesFromFile(
|
|
185
|
+
sourceFile: ts.SourceFile,
|
|
186
|
+
program?: ts.Program
|
|
187
|
+
): ToolUsage[] {
|
|
64
188
|
const usages: ToolUsage[] = [];
|
|
189
|
+
const variableMap = buildVariableMap(sourceFile);
|
|
65
190
|
|
|
66
191
|
function visit(node: ts.Node) {
|
|
67
192
|
// Check for <ArctenAgent tools={[...]} safeTools={[...]} />
|
|
@@ -82,13 +207,9 @@ function extractToolNamesFromFile(sourceFile: ts.SourceFile): ToolUsage[] {
|
|
|
82
207
|
if (attrName === 'tools' || attrName === 'safeTools') {
|
|
83
208
|
if (attr.initializer && ts.isJsxExpression(attr.initializer)) {
|
|
84
209
|
const expr = attr.initializer.expression;
|
|
85
|
-
if (expr
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// Remove any object property access (e.g., tools.getOrders -> getOrders)
|
|
89
|
-
const simpleName = name.split('.').pop() || name;
|
|
90
|
-
toolNames.add(simpleName);
|
|
91
|
-
}
|
|
210
|
+
if (expr) {
|
|
211
|
+
const extracted = extractToolNamesFromExpression(expr, sourceFile, variableMap);
|
|
212
|
+
extracted.forEach(name => toolNames.add(name));
|
|
92
213
|
}
|
|
93
214
|
}
|
|
94
215
|
}
|
|
@@ -118,13 +239,12 @@ function extractToolNamesFromFile(sourceFile: ts.SourceFile): ToolUsage[] {
|
|
|
118
239
|
if (ts.isPropertyAssignment(prop)) {
|
|
119
240
|
const propName = prop.name.getText(sourceFile);
|
|
120
241
|
if (propName === 'tools' || propName === 'safeTools') {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
242
|
+
const extracted = extractToolNamesFromExpression(
|
|
243
|
+
prop.initializer,
|
|
244
|
+
sourceFile,
|
|
245
|
+
variableMap
|
|
246
|
+
);
|
|
247
|
+
extracted.forEach(name => toolNames.add(name));
|
|
128
248
|
}
|
|
129
249
|
}
|
|
130
250
|
}
|
|
@@ -512,7 +632,7 @@ async function autoDiscoverAndExtract(projectRoot: string, outputPath: string) {
|
|
|
512
632
|
for (const file of files) {
|
|
513
633
|
const sourceFile = program.getSourceFile(file);
|
|
514
634
|
if (sourceFile) {
|
|
515
|
-
const usages = extractToolNamesFromFile(sourceFile);
|
|
635
|
+
const usages = extractToolNamesFromFile(sourceFile, program);
|
|
516
636
|
if (usages.length > 0) {
|
|
517
637
|
allToolUsages.push(...usages);
|
|
518
638
|
usages.forEach(u => u.toolNames.forEach(name => allToolNames.add(name)));
|