tarsk 0.0.9 → 0.0.11

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.
@@ -0,0 +1,17 @@
1
+ {
2
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
3
+ "version": "0.2.0",
4
+ "configurations": [
5
+ {
6
+ "type": "node",
7
+ "request": "launch",
8
+ "name": "Debug Tests",
9
+ "autoAttachChildProcesses": true,
10
+ "skipFiles": ["<node_internals>/**", "**/node_modules/**"],
11
+ "program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
12
+ "args": ["run", "${relativeFile}"],
13
+ "smartStep": true,
14
+ "console": "integratedTerminal"
15
+ }
16
+ ]
17
+ }
@@ -1,5 +1,8 @@
1
- // Searches for books in the Project Gutenberg library based on provided search terms
2
- // @param @array @required searchTerms List of search terms to find books in the Gutenberg library (e.g. ['dickens', 'great'] to search for books by Dickens with 'great' in the title)
1
+ /**
2
+ * Searches for books in the Project Gutenberg library based on provided search terms
3
+ * @param @array @required searchTerms - List of search terms to find books in the Gutenberg library (e.g. ['dickens', 'great'] to search for books by Dickens with 'great' in the title)
4
+ * @returns {Promise<Book[]>} A promise that resolves to an array of books matching the search terms
5
+ */
3
6
  export async function searchGutenbergBooks(searchTerms ) {
4
7
  const searchQuery = searchTerms.join(' ');
5
8
  const url = 'https://gutendex.com/books';
@@ -11,45 +14,3 @@ export async function searchGutenbergBooks(searchTerms )
11
14
  authors: book.authors,
12
15
  }));
13
16
  }
14
-
15
- export default function tools() {
16
- return booksTools;
17
- }
18
-
19
- // Automate via TS Morph?
20
- const booksTools = [
21
- {
22
- type: 'function',
23
- function: {
24
- name: 'searchGutenbergBooks',
25
- description:
26
- 'Search for books in the Project Gutenberg library based on specified search terms',
27
- parameters: {
28
- type: 'object',
29
- properties: {
30
- searchTerms: { // Must match argument name in function
31
- type: 'array',
32
- items: {
33
- type: 'string',
34
- },
35
- description:
36
- "List of search terms to find books in the Gutenberg library (e.g. ['dickens', 'great'] to search for books by Dickens with 'great' in the title)",
37
- },
38
- },
39
- required: ['searchTerms'],
40
- },
41
- },
42
- },
43
- ];
44
-
45
- ;
46
-
47
-
48
-
49
-
50
-
51
- ;
52
-
53
-
54
-
55
-
@@ -0,0 +1,24 @@
1
+ [
2
+ {
3
+ "type": "function",
4
+ "function": {
5
+ "name": "searchGutenbergBooks",
6
+ "description": "Searches for books in the Project Gutenberg library based on provided search terms",
7
+ "parameters": {
8
+ "type": "object",
9
+ "properties": {
10
+ "searchTerms": {
11
+ "type": "array",
12
+ "description": "List of search terms to find books in the Gutenberg library (e.g. ['dickens', 'great'] to search for books by Dickens with 'great' in the title)",
13
+ "items": {
14
+ "type": "string"
15
+ }
16
+ }
17
+ },
18
+ "required": [
19
+ "searchTerms"
20
+ ]
21
+ }
22
+ }
23
+ }
24
+ ]
@@ -1,4 +1,4 @@
1
- import {searchGutenbergBooks} from "./books";
1
+ import {searchGutenbergBooks} from "./books.js";
2
2
 
3
3
  // ToDo - run all functions regardles of if its called test
4
4
  // ToDO - dynamically load properly
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Searches for burns based on provided search terms.
3
+ * @param {string[]} searchTerms - List of search terms to find burns.
4
+ * @returns {Promise<Burn[]>} A promise that resolves with an array of Burn objects.
5
+ */
1
6
  export async function searchBurns(searchTerms ) {
2
7
  const searchQuery = searchTerms.join(' ');
3
8
  const url = 'https://api.dust.events/data/festivals.json';
@@ -18,35 +23,6 @@ export async function searchBurns(searchTerms ) {
18
23
  }));
19
24
  }
20
25
 
21
- export default function tools() {
22
- return burnTools;
23
- }
24
-
25
- const burnTools = [
26
- {
27
- type: 'function',
28
- function: {
29
- name: 'searchBurns',
30
- description:
31
- "Search for regional burning man events based on specified search terms",
32
- parameters: {
33
- type: 'object',
34
- properties: {
35
- searchTerms: { // Must match argument name in function
36
- type: 'array',
37
- items: {
38
- type: 'string',
39
- },
40
- description:
41
- "List of search terms (e.g. ['snrg', 'soak'] to search for regional burns with 'snrg' or 'soak' in the title",
42
- },
43
- },
44
- required: ['searchTerms'],
45
- },
46
- },
47
- },
48
- ];
49
-
50
26
  ;
51
27
 
52
28
 
@@ -0,0 +1,24 @@
1
+ [
2
+ {
3
+ "type": "function",
4
+ "function": {
5
+ "name": "searchBurns",
6
+ "description": "Searches for burns based on provided search terms.",
7
+ "parameters": {
8
+ "type": "object",
9
+ "properties": {
10
+ "searchTerms": {
11
+ "type": "array",
12
+ "description": "",
13
+ "items": {
14
+ "type": "string"
15
+ }
16
+ }
17
+ },
18
+ "required": [
19
+ "searchTerms"
20
+ ]
21
+ }
22
+ }
23
+ }
24
+ ]
@@ -1,4 +1,4 @@
1
- import { searchBurns } from './dust';
1
+ import { searchBurns } from './dust.js';
2
2
 
3
3
  export async function test() {
4
4
  const burns = await searchBurns(['']);
@@ -1,4 +1,4 @@
1
- import {searchGutenbergBooks} from "./books";
1
+ import {searchGutenbergBooks} from "./books.js";
2
2
 
3
3
  // ToDo - run all functions regardles of if its called test
4
4
  // ToDO - dynamically load properly
@@ -1,5 +1,8 @@
1
- // Searches for books in the Project Gutenberg library based on provided search terms
2
- // @param @array @required searchTerms List of search terms to find books in the Gutenberg library (e.g. ['dickens', 'great'] to search for books by Dickens with 'great' in the title)
1
+ /**
2
+ * Searches for books in the Project Gutenberg library based on provided search terms
3
+ * @param @array @required searchTerms - List of search terms to find books in the Gutenberg library (e.g. ['dickens', 'great'] to search for books by Dickens with 'great' in the title)
4
+ * @returns {Promise<Book[]>} A promise that resolves to an array of books matching the search terms
5
+ */
3
6
  export async function searchGutenbergBooks(searchTerms: string[]): Promise<Book[]> {
4
7
  const searchQuery = searchTerms.join(' ');
5
8
  const url = 'https://gutendex.com/books';
@@ -11,45 +14,3 @@ export async function searchGutenbergBooks(searchTerms: string[]): Promise<Book[
11
14
  authors: book.authors,
12
15
  }));
13
16
  }
14
-
15
- export default function tools() {
16
- return booksTools;
17
- }
18
-
19
- // Automate via TS Morph?
20
- const booksTools = [
21
- {
22
- type: 'function',
23
- function: {
24
- name: 'searchGutenbergBooks',
25
- description:
26
- 'Search for books in the Project Gutenberg library based on specified search terms',
27
- parameters: {
28
- type: 'object',
29
- properties: {
30
- searchTerms: { // Must match argument name in function
31
- type: 'array',
32
- items: {
33
- type: 'string',
34
- },
35
- description:
36
- "List of search terms to find books in the Gutenberg library (e.g. ['dickens', 'great'] to search for books by Dickens with 'great' in the title)",
37
- },
38
- },
39
- required: ['searchTerms'],
40
- },
41
- },
42
- },
43
- ];
44
-
45
- interface Book {
46
- id: string;
47
- title: string;
48
- authors: Person[];
49
- }
50
-
51
- interface Person {
52
- birth_year?: number;
53
- death_year?: number;
54
- name: string;
55
- }
@@ -1,4 +1,4 @@
1
- import { searchBurns } from './dust';
1
+ import { searchBurns } from './dust.js';
2
2
 
3
3
  export async function test() {
4
4
  const burns = await searchBurns(['']);
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Searches for burns based on provided search terms.
3
+ * @param {string[]} searchTerms - List of search terms to find burns.
4
+ * @returns {Promise<Burn[]>} A promise that resolves with an array of Burn objects.
5
+ */
1
6
  export async function searchBurns(searchTerms: string[]): Promise<Burn[]> {
2
7
  const searchQuery = searchTerms.join(' ');
3
8
  const url = 'https://api.dust.events/data/festivals.json';
@@ -18,35 +23,6 @@ export async function searchBurns(searchTerms: string[]): Promise<Burn[]> {
18
23
  }));
19
24
  }
20
25
 
21
- export default function tools() {
22
- return burnTools;
23
- }
24
-
25
- const burnTools = [
26
- {
27
- type: 'function',
28
- function: {
29
- name: 'searchBurns',
30
- description:
31
- "Search for regional burning man events based on specified search terms",
32
- parameters: {
33
- type: 'object',
34
- properties: {
35
- searchTerms: { // Must match argument name in function
36
- type: 'array',
37
- items: {
38
- type: 'string',
39
- },
40
- description:
41
- "List of search terms (e.g. ['snrg', 'soak'] to search for regional burns with 'snrg' or 'soak' in the title",
42
- },
43
- },
44
- required: ['searchTerms'],
45
- },
46
- },
47
- },
48
- ];
49
-
50
26
  export interface Burn {
51
27
  name: string
52
28
  title: string
package/dist/api/tools.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import { existsSync, mkdirSync, promises, readdirSync, writeFileSync, } from "fs";
2
2
  import { extname, join } from "path";
3
- import { extensionLess, tarskFolder } from "./utils.js";
3
+ import { extensionLess, isEmpty, tarskFolder } from "./utils.js";
4
4
  import { logError, logWrite } from "../log/log.js";
5
5
  import tsBlankSpace from "ts-blank-space";
6
6
  import { loadTools } from "../tools.js";
7
7
  import { callFunction } from "../agent/agent.js";
8
8
  import { readAsJSONIfExists } from "../utils/files.js";
9
+ import ts, { SyntaxKind } from "typescript";
9
10
  export async function api_run_tool(c) {
10
11
  const tool = await c.req.json();
11
12
  logWrite({ type: "api_run_tool", args: { toolName: tool.name } });
@@ -56,6 +57,7 @@ export async function api_save_tool(c) {
56
57
  const filename = name.replace(/\s+/g, "_").toLowerCase();
57
58
  const srcPath = join(toolsSrcFolder(), `${filename}.ts`);
58
59
  const jsCodePath = join(toolsJSFolder(), `${filename}.js`);
60
+ const defPath = join(toolsJSFolder(), `${filename}.js.definition.json`);
59
61
  const testPath = join(toolsSrcFolder(), `${filename}.test.ts`);
60
62
  const jsTestPath = join(toolsJSFolder(), `${filename}.test.js`);
61
63
  const metaPath = join(toolsSrcFolder(), `${filename}.json`);
@@ -63,9 +65,16 @@ export async function api_save_tool(c) {
63
65
  if (currentMeta) {
64
66
  meta.revision = (meta.revision ?? 1) + 1;
65
67
  }
68
+ const missingData = {
69
+ missingParameters: [],
70
+ missingFunctions: []
71
+ };
72
+ const definition = await inspectCode(srcPath, missingData);
66
73
  // Save the Typescript
67
74
  writeFileSync(srcPath, code, "utf-8");
68
75
  writeFileSync(metaPath, JSON.stringify(meta, null, 2), "utf-8");
76
+ // Write the function definition
77
+ writeFileSync(defPath, JSON.stringify(definition, null, 2), "utf-8");
69
78
  // Save the Test
70
79
  writeFileSync(testPath, test, "utf-8");
71
80
  // Save the Javascript Code
@@ -73,7 +82,10 @@ export async function api_save_tool(c) {
73
82
  // Save the Javascript Test
74
83
  writeFileSync(jsTestPath, testCode, "utf-8");
75
84
  logWrite({ type: "api_save_tool", args: { test: testPath, code: srcPath, meta: metaPath } });
76
- return c.json({ message: `Tool saved successfully (${jsCodePath})` });
85
+ return c.json({ message: `Tool saved successfully (${jsCodePath})`,
86
+ missingParameters: missingData.missingParameters,
87
+ missingFunctions: missingData.missingFunctions,
88
+ });
77
89
  }
78
90
  // Get the tool with code
79
91
  export async function api_get_tool(c) {
@@ -166,3 +178,110 @@ async function readOrEmpty(filename) {
166
178
  }
167
179
  return await promises.readFile(filename, "utf-8");
168
180
  }
181
+ export async function inspectCode(filename, missingData) {
182
+ const code = await readOrEmpty(filename);
183
+ const tools = [];
184
+ const sourceFile = ts.createSourceFile('temp.ts', code, ts.ScriptTarget.Latest, true);
185
+ function visit(node) {
186
+ if ((ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) && node.name) {
187
+ const parsed = parseJSDoc(node);
188
+ console.log("Parsed function", parsed);
189
+ const properties = {};
190
+ const required = [];
191
+ node.parameters.forEach(param => {
192
+ const isOptional = !!param.questionToken || !!param.initializer;
193
+ if (!isOptional) {
194
+ required.push(param.name.getText());
195
+ }
196
+ let type = typeName(param.type?.getText());
197
+ if (param.type?.kind == SyntaxKind.TypeReference) {
198
+ type = 'object';
199
+ }
200
+ parsed.params;
201
+ const hasDescription = Object.keys(parsed.params).includes(param.name.getText());
202
+ const description = hasDescription ? parsed.params[param.name.getText()] : '';
203
+ if (!hasDescription) {
204
+ missingData.missingParameters.push(param.name.escapedText);
205
+ }
206
+ properties[param.name.getText()] = {
207
+ type,
208
+ description
209
+ };
210
+ if (type == 'array') {
211
+ properties[param.name.getText()].items = {
212
+ type: arrayType(param.type?.getText()),
213
+ };
214
+ }
215
+ });
216
+ const functionDescription = parsed.description;
217
+ if (isEmpty(functionDescription)) {
218
+ missingData.missingFunctions.push(node.name.getText());
219
+ }
220
+ tools.push({
221
+ type: 'function',
222
+ function: {
223
+ name: node.name?.text ?? '',
224
+ description: functionDescription,
225
+ parameters: {
226
+ type: 'object',
227
+ properties,
228
+ required,
229
+ }
230
+ }
231
+ });
232
+ }
233
+ ts.forEachChild(node, visit);
234
+ }
235
+ visit(sourceFile);
236
+ return tools;
237
+ }
238
+ function parseJSDoc(node) {
239
+ const functionName = node.name?.getText();
240
+ const jsDoc = ts.getJSDocCommentsAndTags(node);
241
+ const parsed = {
242
+ functionName,
243
+ description: "",
244
+ params: {},
245
+ };
246
+ let info = '';
247
+ for (const doc of jsDoc) {
248
+ if (ts.isJSDoc(doc)) {
249
+ if (doc.comment) {
250
+ parsed.description = doc.comment.toString();
251
+ }
252
+ if (doc.tags) {
253
+ for (const tag of doc.tags) {
254
+ info += ' ' + tag.comment;
255
+ // if (ts.isJSDocPropertyTag(tag)) {
256
+ if (tag.kind == 327) {
257
+ let txt = tag.comment ? tag.comment.toString() : "";
258
+ const lines = txt.split(' ');
259
+ const paramName = lines[0];
260
+ if (txt.startsWith(paramName)) {
261
+ txt = txt.substring(paramName.length).trim();
262
+ if (txt.startsWith('-')) {
263
+ txt = txt.substring(1).trim();
264
+ }
265
+ }
266
+ //parsed.params[paramName] = paramDesc;
267
+ parsed.params[paramName] = txt;
268
+ }
269
+ }
270
+ }
271
+ }
272
+ }
273
+ return parsed;
274
+ }
275
+ function typeName(name) {
276
+ if (!name)
277
+ return 'any';
278
+ if (name.endsWith('[]')) {
279
+ return 'array';
280
+ }
281
+ return name;
282
+ }
283
+ function arrayType(name) {
284
+ if (!name)
285
+ return 'any';
286
+ return name.replace('[]', '');
287
+ }
package/dist/tools.js CHANGED
@@ -19,24 +19,6 @@ export async function loadTools(modulePaths) {
19
19
  }
20
20
  return tools;
21
21
  }
22
- // async function importFromMemory(moduleCode: string) {
23
- // const module = new Function(
24
- // "exports",
25
- // "module",
26
- // "require",
27
- // "__filename",
28
- // "__dirname",
29
- // moduleCode
30
- // );
31
- // const exports = {};
32
- // const moduleObj = { exports: exports };
33
- // module(exports, moduleObj, require, null, null);
34
- // return moduleObj.exports;
35
- // }
36
- // async function importModule(code: string) {
37
- // const myModule = await importFromMemory(code);
38
- // //console.log(myModule.hello()); // Output: Hello from memory!
39
- // }
40
22
  function findMetaData(modulePath) {
41
23
  // Load the meta data: its in the toolsfolder not the .tools folder
42
24
  let metaPath = (getPathWithoutExtension(modulePath) + ".json").replace('.tools', 'tools');
@@ -61,9 +43,6 @@ async function inspectTool(modulePath) {
61
43
  path: modulePath,
62
44
  revision: undefined
63
45
  };
64
- // When 'key' is no longer referenced and garbage collected,
65
- // the module './myModule.js' associated with it in 'weakModules'
66
- // will also be eligible for garbage collection.
67
46
  logStart({ type: "load_tool", args: { modulePath } }, `The modulePath is "${modulePath}"`);
68
47
  try {
69
48
  const meta = findMetaData(modulePath);
@@ -89,7 +68,7 @@ async function inspectTool(modulePath) {
89
68
  try {
90
69
  // This is the definition needed for the tool for the agent (TODO: Generate this)
91
70
  if (!isTest) {
92
- result.definition = myModule.default();
71
+ result.definition = getDefinition(modulePath);
93
72
  }
94
73
  }
95
74
  catch (e) {
@@ -99,10 +78,14 @@ async function inspectTool(modulePath) {
99
78
  }
100
79
  catch (e) {
101
80
  logError({ type: "load_tool_error", args: e });
81
+ throw new Error(`load_tool_error ${modulePath}: ${e}`);
102
82
  }
103
83
  finally {
104
84
  logEnd("load_tool");
105
85
  logWrite({ type: 'load_tool', args: { result } });
106
86
  }
107
- throw new Error(`Error loading tool from ${modulePath}`);
87
+ }
88
+ function getDefinition(modulePath) {
89
+ const filename = modulePath + '.definition.json';
90
+ return readAsJSONIfExists(filename);
108
91
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tarsk",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "author": "WebNative LLC",
5
5
  "description": "Tarsk is a AI tool available at https://tarsk.io",
6
6
  "license": "MIT",
@@ -10,6 +10,8 @@
10
10
  "start": "npm run build && npm link && tarsk",
11
11
  "restart": "npm unlink tarsk && rm -rf dist && npm run build && npm link && tarsk",
12
12
  "publish": "npm run build && npm publish",
13
+ "test": "vitest",
14
+ "test2": "bun test/test-get-definition.ts",
13
15
  "dev": "tsx watch src/index.ts"
14
16
  },
15
17
  "bin": {
@@ -23,6 +25,7 @@
23
25
  },
24
26
  "devDependencies": {
25
27
  "@types/node": "^20.11.17",
26
- "tsx": "^4.7.1"
28
+ "tsx": "^4.7.1",
29
+ "vitest": "^3.1.2"
27
30
  }
28
31
  }
@@ -0,0 +1,25 @@
1
+ // Automate via TS Morph?
2
+ const booksTools = [
3
+ {
4
+ type: 'function',
5
+ function: {
6
+ name: 'searchGutenbergBooks',
7
+ description:
8
+ 'Search for books in the Project Gutenberg library based on specified search terms',
9
+ parameters: {
10
+ type: 'object',
11
+ properties: {
12
+ searchTerms: { // Must match argument name in function
13
+ type: 'array',
14
+ items: {
15
+ type: 'string',
16
+ },
17
+ description:
18
+ "List of search terms to find books in the Gutenberg library (e.g. ['dickens', 'great'] to search for books by Dickens with 'great' in the title)",
19
+ },
20
+ },
21
+ required: ['searchTerms'],
22
+ },
23
+ },
24
+ },
25
+ ];
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Searches for books in the Project Gutenberg library based on provided search terms
3
+ * @param @array @required searchTerms - List of search terms to find books in the Gutenberg library (e.g. ['dickens', 'great'] to search for books by Dickens with 'great' in the title)
4
+ * @param @object @required book - The book object to search for
5
+ * @returns {Promise<Book[]>} A promise that resolves to an array of books matching the search terms
6
+ */
7
+ export async function searchGutenbergBooks(searchTerms: string[], count: number, book: Book): Promise<Book[]> {
8
+ const searchQuery = searchTerms ? searchTerms.join(' ') : '';
9
+ const url = 'https://gutendex.com/books';
10
+ const response = await fetch(`${url}?search=${searchQuery}`);
11
+ const data = await response.json();
12
+ return data.results.map((book: any) => ({
13
+ id: book.id,
14
+ title: book.title,
15
+ authors: book.authors,
16
+ }));
17
+ }
18
+
19
+ interface Book {
20
+ id: string;
21
+ title: string;
22
+ authors: Person[];
23
+ }
24
+
25
+ interface Person {
26
+ birth_year?: number;
27
+ death_year?: number;
28
+ name: string;
29
+ }
30
+
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Searches for burns based on provided search terms.
3
+ * @param {string[]} searchTerms - List of search terms to find burns.
4
+ * @returns {Promise<Burn[]>} A promise that resolves with an array of Burn objects.
5
+ */
6
+ export async function searchBurns(searchTerms: string[]): Promise<Burn[]> {
7
+ const searchQuery = searchTerms.join(' ');
8
+ const url = 'https://api.dust.events/data/festivals.json';
9
+ const response = await fetch(`${url}`);
10
+ let data = await response.json();
11
+ data = data.filter((b) => b.active);
12
+ return data.map((burn: any) => ({
13
+ name: burn.name,
14
+ title: burn.title,
15
+ year: burn.year,
16
+ startDate: burn.start,
17
+ endDate: burn.end,
18
+ lat: burn.lat,
19
+ long: burn.long,
20
+ timeZone: burn.timeZone,
21
+ region: burn.region,
22
+ website: burn.website
23
+ }));
24
+ }
25
+
26
+ export interface Burn {
27
+ name: string
28
+ title: string
29
+ year: string
30
+ active: boolean
31
+ id: string
32
+ uid: number
33
+ start: string
34
+ end: string
35
+ lat: any
36
+ long: any
37
+ imageUrl?: string
38
+ timeZone: string
39
+ mapDirection: number
40
+ mastodonHandle: string
41
+ rssFeed: string
42
+ inboxEmail: string
43
+ region: string
44
+ website: string
45
+ unknownDates: boolean
46
+ volunteeripateSubdomain: string
47
+ volunteeripateIdentifier: string
48
+ pin_size_multiplier: number
49
+ camp_registration: boolean
50
+ event_registration: boolean
51
+ pin: string
52
+ directions?: string
53
+ }
54
+
55
+
@@ -0,0 +1,33 @@
1
+ import { expect, test } from 'vitest'
2
+ import { inspectCode, MissingData } from "../src/api/tools.js";
3
+ import { Tool } from '../src/agent/interfaces.js';
4
+
5
+ test('function definition generation works', async () => {
6
+ const missingData: MissingData = {
7
+ missingFunctions: [],
8
+ missingParameters: [],
9
+ };
10
+
11
+ const tools: Tool[] = await inspectCode('./test/test-fn.ts', missingData);
12
+
13
+ // One comment is missing
14
+ expect(missingData.missingParameters.length).toBe(1);
15
+ // One comment is missing
16
+ expect(missingData.missingParameters[0]).toBe('count');
17
+ expect(tools[0].function.description).toBe('Searches for books in the Project Gutenberg library based on provided search terms');
18
+ });
19
+
20
+ test('function definition generation works style 2', async () => {
21
+ const missingData: MissingData = {
22
+ missingFunctions: [],
23
+ missingParameters: [],
24
+ };
25
+
26
+ const tools: Tool[] = await inspectCode('./test/test-fn2.ts', missingData);
27
+
28
+ // One comment is missing
29
+ expect(missingData.missingParameters.length).toBe(1);
30
+ // One comment is missing
31
+ expect(missingData.missingParameters[0]).toBe('count');
32
+ expect(tools[0].function.description).toBe('');
33
+ });
@@ -0,0 +1,9 @@
1
+ import { inspectCode } from "../src/api/tools";
2
+
3
+ async function test() {
4
+ const tools = await inspectCode('./test/test-fn.ts', { missingFunctions: [], missingParameters: [] });
5
+ const txt = JSON.stringify(tools, null, 2);
6
+ console.log();
7
+ }
8
+
9
+ test();