aimyapi 0.1.15 → 0.2.0

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/dist/index.cjs CHANGED
@@ -346,10 +346,9 @@ function createBasePrompt(apiFilePath, documentationPath) {
346
346
  const createTaskPrompt = fs.readFileSync(path.join(__dirname, "../prompts/create-task-prompt.md"), "utf8").replace("{{DOCUMENTATION}}", documentationText).replace("{{API}}", apiText);
347
347
  return createTaskPrompt;
348
348
  }
349
- const generateCode = async function(queryText, userChatHistory, createTaskPrompt, apiPath, debug = false, model = "gpt-4o") {
349
+ const generateCode = async function(queryText, userChatHistory, createTaskPrompt, debug = false, model = "gpt-4o-mini") {
350
350
  if (!queryText)
351
351
  return { code: "", loggableCode: "" };
352
- let generatedCode = "";
353
352
  const prompt = createTaskPrompt.replace("{{QUERY_TEXT}}", queryText);
354
353
  const messages = [
355
354
  {
@@ -359,8 +358,7 @@ const generateCode = async function(queryText, userChatHistory, createTaskPrompt
359
358
  ...userChatHistory,
360
359
  {
361
360
  role: "user",
362
- content: `${queryText}.
363
- Respond only with code enclosed in \`\`\`.`,
361
+ content: `${queryText}. Respond with json`,
364
362
  name: "user"
365
363
  }
366
364
  ];
@@ -370,7 +368,23 @@ Respond only with code enclosed in \`\`\`.`,
370
368
  model,
371
369
  messages,
372
370
  temperature: 0,
373
- max_tokens: 700
371
+ max_tokens: 2e3,
372
+ response_format: {
373
+ json_schema: {
374
+ name: "codeResponse",
375
+ description: "The code generated by the AI",
376
+ schema: {
377
+ type: "object",
378
+ properties: {
379
+ yourCode: {
380
+ type: "string",
381
+ description: "The code generated by the AI"
382
+ }
383
+ }
384
+ }
385
+ },
386
+ type: "json_schema"
387
+ }
374
388
  }
375
389
  );
376
390
  if (debug)
@@ -378,21 +392,14 @@ Respond only with code enclosed in \`\`\`.`,
378
392
  const response = results.choices[0].message.content;
379
393
  if (debug)
380
394
  console.log(response);
381
- const codeStart = response.indexOf("```");
382
- const codeEnd = response.lastIndexOf("```");
383
- if (codeStart === -1 || codeEnd === -1 || codeStart === codeEnd) {
384
- return { code: "", loggableCode: "", rawResponse: response };
395
+ try {
396
+ const json = JSON.parse(response);
397
+ const code = json.yourCode.replaceAll("```", "");
398
+ return { code, loggableCode: code };
399
+ } catch (err) {
400
+ console.error("Error parsing response", err);
401
+ return { code: "", loggableCode: "" };
385
402
  }
386
- generatedCode = response.substring(codeStart + 3, codeEnd).replace("typescript", "");
387
- const codeHeader = `import * as ApiDefs from '${apiPath}'
388
- (async() {
389
- try {`;
390
- const codeFooter = `
391
- } catch(err) {
392
- console.error(err);
393
- }
394
- })();`;
395
- return { code: codeHeader + generatedCode + codeFooter, loggableCode: generatedCode };
396
403
  } catch (err) {
397
404
  console.error(err);
398
405
  return { code: "", loggableCode: "" };
@@ -405,7 +412,7 @@ async function createWithAPI(options) {
405
412
  apiGlobals: {},
406
413
  apiWhitelist: Object.getOwnPropertyNames(Object.getPrototypeOf(options.apiObject)).filter((f) => f !== "constructor" && !f.startsWith("_")),
407
414
  debug: false,
408
- model: "gpt-4o",
415
+ model: "gpt-4o-mini",
409
416
  ...options
410
417
  };
411
418
  if (!options.apiObject || !options.apiDefFilePath) {
@@ -418,7 +425,7 @@ async function createWithAPI(options) {
418
425
  generateCode: async function(queryText, userChatHistory, currentContext = void 0) {
419
426
  if (!queryText)
420
427
  return { code: "", loggableCode: "" };
421
- return await generateCode(queryText, userChatHistory, createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath, debug, model);
428
+ return await generateCode(queryText, userChatHistory, createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), debug, model);
422
429
  },
423
430
  runCode: async function(generatedCode) {
424
431
  if (!QuickJS) {
@@ -445,7 +452,7 @@ async function createWithAPI(options) {
445
452
  if (debug) {
446
453
  console.log("Running Code:\n", generatedCode);
447
454
  }
448
- const res = await runTask(generatedCode);
455
+ const res = await runTask(generatedCode.replace("'api.ts'", `'${options.apiDefFilePath}'`));
449
456
  if (!res) {
450
457
  console.error("Task unsuccessful");
451
458
  }
@@ -469,10 +476,10 @@ async function createWithAPI(options) {
469
476
  console.log("Query:", userQuery);
470
477
  }
471
478
  console.time("Generate Task");
472
- const generatedCode = await generateCode(userQuery, [], createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath);
479
+ const generatedCode = await generateCode(userQuery, [], createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""));
473
480
  console.timeEnd("Generate Task");
474
481
  console.time("Run Code");
475
- await this.runCode(generatedCode.code);
482
+ await this.runCode(generatedCode.code.replace("'api.ts'", `'${options.apiDefFilePath}'`));
476
483
  console.timeEnd("Run Code");
477
484
  return generatedCode;
478
485
  }
package/dist/index.d.cts CHANGED
@@ -7,7 +7,7 @@ interface GenerateCodeResult {
7
7
  loggableCode: string;
8
8
  rawResponse?: string;
9
9
  }
10
- declare const generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, apiPath: string, debug?: boolean, model?: string) => Promise<GenerateCodeResult>;
10
+ declare const generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, debug?: boolean, model?: string) => Promise<GenerateCodeResult>;
11
11
  interface AIMyAPIOptions {
12
12
  apiObject: object;
13
13
  apiExports: object;
@@ -28,7 +28,7 @@ interface AIMyAPIInstance {
28
28
  interface AIMyAPIModuleExports {
29
29
  createWithAPI: (options: AIMyAPIOptions) => Promise<AIMyAPIInstance>;
30
30
  createBasePrompt: (apiFilePath: string, documentationPath: string) => string;
31
- generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, apiPath: string, debug: boolean) => Promise<GenerateCodeResult>;
31
+ generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, debug: boolean) => Promise<GenerateCodeResult>;
32
32
  createSandbox: (QuickJS: QuickJSWASMModule, globals: any) => Promise<any>;
33
33
  }
34
34
  declare const AIMyAPI: AIMyAPIModuleExports;
package/dist/index.d.mts CHANGED
@@ -7,7 +7,7 @@ interface GenerateCodeResult {
7
7
  loggableCode: string;
8
8
  rawResponse?: string;
9
9
  }
10
- declare const generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, apiPath: string, debug?: boolean, model?: string) => Promise<GenerateCodeResult>;
10
+ declare const generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, debug?: boolean, model?: string) => Promise<GenerateCodeResult>;
11
11
  interface AIMyAPIOptions {
12
12
  apiObject: object;
13
13
  apiExports: object;
@@ -28,7 +28,7 @@ interface AIMyAPIInstance {
28
28
  interface AIMyAPIModuleExports {
29
29
  createWithAPI: (options: AIMyAPIOptions) => Promise<AIMyAPIInstance>;
30
30
  createBasePrompt: (apiFilePath: string, documentationPath: string) => string;
31
- generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, apiPath: string, debug: boolean) => Promise<GenerateCodeResult>;
31
+ generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, debug: boolean) => Promise<GenerateCodeResult>;
32
32
  createSandbox: (QuickJS: QuickJSWASMModule, globals: any) => Promise<any>;
33
33
  }
34
34
  declare const AIMyAPI: AIMyAPIModuleExports;
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ interface GenerateCodeResult {
7
7
  loggableCode: string;
8
8
  rawResponse?: string;
9
9
  }
10
- declare const generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, apiPath: string, debug?: boolean, model?: string) => Promise<GenerateCodeResult>;
10
+ declare const generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, debug?: boolean, model?: string) => Promise<GenerateCodeResult>;
11
11
  interface AIMyAPIOptions {
12
12
  apiObject: object;
13
13
  apiExports: object;
@@ -28,7 +28,7 @@ interface AIMyAPIInstance {
28
28
  interface AIMyAPIModuleExports {
29
29
  createWithAPI: (options: AIMyAPIOptions) => Promise<AIMyAPIInstance>;
30
30
  createBasePrompt: (apiFilePath: string, documentationPath: string) => string;
31
- generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, apiPath: string, debug: boolean) => Promise<GenerateCodeResult>;
31
+ generateCode: (queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, debug: boolean) => Promise<GenerateCodeResult>;
32
32
  createSandbox: (QuickJS: QuickJSWASMModule, globals: any) => Promise<any>;
33
33
  }
34
34
  declare const AIMyAPI: AIMyAPIModuleExports;
package/dist/index.js CHANGED
@@ -346,10 +346,9 @@ function createBasePrompt(apiFilePath, documentationPath) {
346
346
  const createTaskPrompt = fs.readFileSync(path.join(__dirname, "../prompts/create-task-prompt.md"), "utf8").replace("{{DOCUMENTATION}}", documentationText).replace("{{API}}", apiText);
347
347
  return createTaskPrompt;
348
348
  }
349
- const generateCode = async function(queryText, userChatHistory, createTaskPrompt, apiPath, debug = false, model = "gpt-4o") {
349
+ const generateCode = async function(queryText, userChatHistory, createTaskPrompt, debug = false, model = "gpt-4o-mini") {
350
350
  if (!queryText)
351
351
  return { code: "", loggableCode: "" };
352
- let generatedCode = "";
353
352
  const prompt = createTaskPrompt.replace("{{QUERY_TEXT}}", queryText);
354
353
  const messages = [
355
354
  {
@@ -359,8 +358,7 @@ const generateCode = async function(queryText, userChatHistory, createTaskPrompt
359
358
  ...userChatHistory,
360
359
  {
361
360
  role: "user",
362
- content: `${queryText}.
363
- Respond only with code enclosed in \`\`\`.`,
361
+ content: `${queryText}. Respond with json`,
364
362
  name: "user"
365
363
  }
366
364
  ];
@@ -370,7 +368,23 @@ Respond only with code enclosed in \`\`\`.`,
370
368
  model,
371
369
  messages,
372
370
  temperature: 0,
373
- max_tokens: 700
371
+ max_tokens: 2e3,
372
+ response_format: {
373
+ json_schema: {
374
+ name: "codeResponse",
375
+ description: "The code generated by the AI",
376
+ schema: {
377
+ type: "object",
378
+ properties: {
379
+ yourCode: {
380
+ type: "string",
381
+ description: "The code generated by the AI"
382
+ }
383
+ }
384
+ }
385
+ },
386
+ type: "json_schema"
387
+ }
374
388
  }
375
389
  );
376
390
  if (debug)
@@ -378,21 +392,14 @@ Respond only with code enclosed in \`\`\`.`,
378
392
  const response = results.choices[0].message.content;
379
393
  if (debug)
380
394
  console.log(response);
381
- const codeStart = response.indexOf("```");
382
- const codeEnd = response.lastIndexOf("```");
383
- if (codeStart === -1 || codeEnd === -1 || codeStart === codeEnd) {
384
- return { code: "", loggableCode: "", rawResponse: response };
395
+ try {
396
+ const json = JSON.parse(response);
397
+ const code = json.yourCode.replaceAll("```", "");
398
+ return { code, loggableCode: code };
399
+ } catch (err) {
400
+ console.error("Error parsing response", err);
401
+ return { code: "", loggableCode: "" };
385
402
  }
386
- generatedCode = response.substring(codeStart + 3, codeEnd).replace("typescript", "");
387
- const codeHeader = `import * as ApiDefs from '${apiPath}'
388
- (async() {
389
- try {`;
390
- const codeFooter = `
391
- } catch(err) {
392
- console.error(err);
393
- }
394
- })();`;
395
- return { code: codeHeader + generatedCode + codeFooter, loggableCode: generatedCode };
396
403
  } catch (err) {
397
404
  console.error(err);
398
405
  return { code: "", loggableCode: "" };
@@ -405,7 +412,7 @@ async function createWithAPI(options) {
405
412
  apiGlobals: {},
406
413
  apiWhitelist: Object.getOwnPropertyNames(Object.getPrototypeOf(options.apiObject)).filter((f) => f !== "constructor" && !f.startsWith("_")),
407
414
  debug: false,
408
- model: "gpt-4o",
415
+ model: "gpt-4o-mini",
409
416
  ...options
410
417
  };
411
418
  if (!options.apiObject || !options.apiDefFilePath) {
@@ -418,7 +425,7 @@ async function createWithAPI(options) {
418
425
  generateCode: async function(queryText, userChatHistory, currentContext = void 0) {
419
426
  if (!queryText)
420
427
  return { code: "", loggableCode: "" };
421
- return await generateCode(queryText, userChatHistory, createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath, debug, model);
428
+ return await generateCode(queryText, userChatHistory, createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), debug, model);
422
429
  },
423
430
  runCode: async function(generatedCode) {
424
431
  if (!QuickJS) {
@@ -445,7 +452,7 @@ async function createWithAPI(options) {
445
452
  if (debug) {
446
453
  console.log("Running Code:\n", generatedCode);
447
454
  }
448
- const res = await runTask(generatedCode);
455
+ const res = await runTask(generatedCode.replace("'api.ts'", `'${options.apiDefFilePath}'`));
449
456
  if (!res) {
450
457
  console.error("Task unsuccessful");
451
458
  }
@@ -469,10 +476,10 @@ async function createWithAPI(options) {
469
476
  console.log("Query:", userQuery);
470
477
  }
471
478
  console.time("Generate Task");
472
- const generatedCode = await generateCode(userQuery, [], createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath);
479
+ const generatedCode = await generateCode(userQuery, [], createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""));
473
480
  console.timeEnd("Generate Task");
474
481
  console.time("Run Code");
475
- await this.runCode(generatedCode.code);
482
+ await this.runCode(generatedCode.code.replace("'api.ts'", `'${options.apiDefFilePath}'`));
476
483
  console.timeEnd("Run Code");
477
484
  return generatedCode;
478
485
  }
package/dist/index.mjs CHANGED
@@ -324,10 +324,9 @@ function createBasePrompt(apiFilePath, documentationPath) {
324
324
  const createTaskPrompt = fs.readFileSync(path.join(__dirname, "../prompts/create-task-prompt.md"), "utf8").replace("{{DOCUMENTATION}}", documentationText).replace("{{API}}", apiText);
325
325
  return createTaskPrompt;
326
326
  }
327
- const generateCode = async function(queryText, userChatHistory, createTaskPrompt, apiPath, debug = false, model = "gpt-4o") {
327
+ const generateCode = async function(queryText, userChatHistory, createTaskPrompt, debug = false, model = "gpt-4o-mini") {
328
328
  if (!queryText)
329
329
  return { code: "", loggableCode: "" };
330
- let generatedCode = "";
331
330
  const prompt = createTaskPrompt.replace("{{QUERY_TEXT}}", queryText);
332
331
  const messages = [
333
332
  {
@@ -337,8 +336,7 @@ const generateCode = async function(queryText, userChatHistory, createTaskPrompt
337
336
  ...userChatHistory,
338
337
  {
339
338
  role: "user",
340
- content: `${queryText}.
341
- Respond only with code enclosed in \`\`\`.`,
339
+ content: `${queryText}. Respond with json`,
342
340
  name: "user"
343
341
  }
344
342
  ];
@@ -348,7 +346,23 @@ Respond only with code enclosed in \`\`\`.`,
348
346
  model,
349
347
  messages,
350
348
  temperature: 0,
351
- max_tokens: 700
349
+ max_tokens: 2e3,
350
+ response_format: {
351
+ json_schema: {
352
+ name: "codeResponse",
353
+ description: "The code generated by the AI",
354
+ schema: {
355
+ type: "object",
356
+ properties: {
357
+ yourCode: {
358
+ type: "string",
359
+ description: "The code generated by the AI"
360
+ }
361
+ }
362
+ }
363
+ },
364
+ type: "json_schema"
365
+ }
352
366
  }
353
367
  );
354
368
  if (debug)
@@ -356,21 +370,14 @@ Respond only with code enclosed in \`\`\`.`,
356
370
  const response = results.choices[0].message.content;
357
371
  if (debug)
358
372
  console.log(response);
359
- const codeStart = response.indexOf("```");
360
- const codeEnd = response.lastIndexOf("```");
361
- if (codeStart === -1 || codeEnd === -1 || codeStart === codeEnd) {
362
- return { code: "", loggableCode: "", rawResponse: response };
373
+ try {
374
+ const json = JSON.parse(response);
375
+ const code = json.yourCode.replaceAll("```", "");
376
+ return { code, loggableCode: code };
377
+ } catch (err) {
378
+ console.error("Error parsing response", err);
379
+ return { code: "", loggableCode: "" };
363
380
  }
364
- generatedCode = response.substring(codeStart + 3, codeEnd).replace("typescript", "");
365
- const codeHeader = `import * as ApiDefs from '${apiPath}'
366
- (async() {
367
- try {`;
368
- const codeFooter = `
369
- } catch(err) {
370
- console.error(err);
371
- }
372
- })();`;
373
- return { code: codeHeader + generatedCode + codeFooter, loggableCode: generatedCode };
374
381
  } catch (err) {
375
382
  console.error(err);
376
383
  return { code: "", loggableCode: "" };
@@ -383,7 +390,7 @@ async function createWithAPI(options) {
383
390
  apiGlobals: {},
384
391
  apiWhitelist: Object.getOwnPropertyNames(Object.getPrototypeOf(options.apiObject)).filter((f) => f !== "constructor" && !f.startsWith("_")),
385
392
  debug: false,
386
- model: "gpt-4o",
393
+ model: "gpt-4o-mini",
387
394
  ...options
388
395
  };
389
396
  if (!options.apiObject || !options.apiDefFilePath) {
@@ -396,7 +403,7 @@ async function createWithAPI(options) {
396
403
  generateCode: async function(queryText, userChatHistory, currentContext = void 0) {
397
404
  if (!queryText)
398
405
  return { code: "", loggableCode: "" };
399
- return await generateCode(queryText, userChatHistory, createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath, debug, model);
406
+ return await generateCode(queryText, userChatHistory, createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), debug, model);
400
407
  },
401
408
  runCode: async function(generatedCode) {
402
409
  if (!QuickJS) {
@@ -423,7 +430,7 @@ async function createWithAPI(options) {
423
430
  if (debug) {
424
431
  console.log("Running Code:\n", generatedCode);
425
432
  }
426
- const res = await runTask(generatedCode);
433
+ const res = await runTask(generatedCode.replace("'api.ts'", `'${options.apiDefFilePath}'`));
427
434
  if (!res) {
428
435
  console.error("Task unsuccessful");
429
436
  }
@@ -447,10 +454,10 @@ async function createWithAPI(options) {
447
454
  console.log("Query:", userQuery);
448
455
  }
449
456
  console.time("Generate Task");
450
- const generatedCode = await generateCode(userQuery, [], createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath);
457
+ const generatedCode = await generateCode(userQuery, [], createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""));
451
458
  console.timeEnd("Generate Task");
452
459
  console.time("Run Code");
453
- await this.runCode(generatedCode.code);
460
+ await this.runCode(generatedCode.code.replace("'api.ts'", `'${options.apiDefFilePath}'`));
454
461
  console.timeEnd("Run Code");
455
462
  return generatedCode;
456
463
  }
@@ -10,21 +10,37 @@ user: How are you today?
10
10
 
11
11
  assistant:
12
12
  ```
13
- orderingApi.respondToUser("I'm great, thanks for asking!");
13
+ import * as ApiDefs from 'api.ts'
14
+
15
+ (async() {
16
+ try {
17
+ orderingApi.respondToUser("I'm great, thanks for asking!");
18
+ } catch(err) {
19
+ console.error(err);
20
+ }
21
+ })();
14
22
  ```
15
23
 
16
24
  user: Add a hamburger with no cheese to my order
17
25
 
18
26
  assistant:
19
27
  ```
20
- const itemName = "Hamburger";
21
- const item = ApiDefs.Menu.find((item) => item.name === itemName);
22
- if (!item) {
23
- throw new Error(`Item with name "${itemName}" not found`);
24
- }
25
-
26
- orderingApi.addItemToOrder(itemName, undefined, item.toppings.filter( topping => topping.name != "cheese") );
27
- orderingApi.respondToUser("Ok, I added a Hamburger. What else would you like?");
28
+ import * as ApiDefs from 'api.ts'
29
+
30
+ (async() {
31
+ try {
32
+ const itemName = "Hamburger";
33
+ const item = ApiDefs.Menu.find((item) => item.name === itemName);
34
+ if (!item) {
35
+ throw new Error(`Item with name "${itemName}" not found`);
36
+ }
37
+
38
+ orderingApi.addItemToOrder(itemName, undefined, item.toppings.filter( topping => topping.name != "cheese") );
39
+ orderingApi.respondToUser("Ok, I added a Hamburger. What else would you like?");
40
+ } catch(err) {
41
+ console.error(err);
42
+ }
43
+ })();
28
44
  ```
29
45
 
30
46
  log: Added Hamburger with id 1
@@ -33,22 +49,39 @@ user: I'd like a large pizza with mushrooms
33
49
 
34
50
  assistant:
35
51
  ```
36
- orderingApi.addItemToOrder("Pizza", ["Large"], ["mushrooms"]);
37
- orderingApi.respondToUser("Ok, I added a Large Pizza with mushrooms");
52
+
53
+ import * as ApiDefs from 'api.ts'
54
+
55
+ (async() {
56
+ try {
57
+ orderingApi.addItemToOrder("Pizza", ["Large"], ["mushrooms"]);
58
+ orderingApi.respondToUser("Ok, I added a Large Pizza with mushrooms");
59
+ } catch(err) {
60
+ console.error(err);
61
+ }
62
+ })();
38
63
  ```
39
64
 
40
65
  user: Add a hamburger with bacon
41
66
 
42
67
  assistant:
43
68
  ```
44
- const itemName = "Hamburger";
45
- const item = ApiDefs.Menu.find((item) => item.name === itemName);
46
- if (!item) {
47
- throw new Error(`Item with name "${itemName}" not found`);
48
- }
49
-
50
- orderingApi.addItemToOrder(itemName, undefined, [...item.toppings, "bacon"]);
51
- orderingApi.respondToUser("Ok, I added a Hamburger with no cheese or onions. What else would you like?");
69
+ import * as ApiDefs from 'api.ts'
70
+
71
+ (async() {
72
+ try {
73
+ const itemName = "Hamburger";
74
+ const item = ApiDefs.Menu.find((item) => item.name === itemName);
75
+ if (!item) {
76
+ throw new Error(`Item with name "${itemName}" not found`);
77
+ }
78
+
79
+ orderingApi.addItemToOrder(itemName, undefined, [...item.toppings, "bacon"]);
80
+ orderingApi.respondToUser("Ok, I added a Hamburger with no cheese or onions. What else would you like?");
81
+ } catch(err) {
82
+ console.error(err);
83
+ }
84
+ })();
52
85
  ```
53
86
 
54
87
  log: Added Hamburger with id 2
@@ -57,28 +90,44 @@ user: Add jalapenos to that
57
90
 
58
91
  assistant:
59
92
  ```
60
- const existingItem = orderingApi.getItemInOrder("2");
61
-
62
- if(existingItem) {
63
- orderingApi.modifyItemInOrder("2", existingItem.customizations.map(item => item.name), [...existingItem.toppings, "jalapenos"]);
64
- orderingApi.respondToUser("Ok, I added jalapenos to your Hamburger");
65
- } else {
66
- orderingApi.respondToUser("Hmm, I can't find that item.");
67
- }
93
+ import * as ApiDefs from 'api.ts'
94
+
95
+ (async() {
96
+ try {
97
+ const existingItem = orderingApi.getItemInOrder("2");
98
+
99
+ if(existingItem) {
100
+ orderingApi.modifyItemInOrder("2", existingItem.customizations.map(item => item.name), [...existingItem.toppings, "jalapenos"]);
101
+ orderingApi.respondToUser("Ok, I added jalapenos to your Hamburger");
102
+ } else {
103
+ orderingApi.respondToUser("Hmm, I can't find that item.");
104
+ }
105
+ } catch(err) {
106
+ console.error(err);
107
+ }
108
+ })();
68
109
  ```
69
110
 
70
111
  user: Add a hamburger with no lettuce
71
112
 
72
113
  assistant:
73
114
  ```
74
- const itemName = "Hamburger";
75
- const item = ApiDefs.Menu.find((item) => item.name === itemName);
76
- if (!item) {
77
- throw new Error(`Item with name "${itemName}" not found`);
78
- }
79
-
80
- orderingApi.addItemToOrder(itemName, undefined, [...item.toppings.filter(topping => topping != "lettuce")]);
81
- orderingApi.respondToUser("Ok, I added a Hamburger with no cheese or onions. What else would you like?");
115
+ import * as ApiDefs from 'api.ts'
116
+
117
+ (async() {
118
+ try {
119
+ const itemName = "Hamburger";
120
+ const item = ApiDefs.Menu.find((item) => item.name === itemName);
121
+ if (!item) {
122
+ throw new Error(`Item with name "${itemName}" not found`);
123
+ }
124
+
125
+ orderingApi.addItemToOrder(itemName, undefined, [...item.toppings.filter(topping => topping != "lettuce")]);
126
+ orderingApi.respondToUser("Ok, I added a Hamburger with no cheese or onions. What else would you like?");
127
+ } catch(err) {
128
+ console.error(err);
129
+ }
130
+ })();
82
131
  ```
83
132
 
84
133
  log: Added Hamburger with id 2
@@ -88,5 +137,13 @@ user: I want an elephant.
88
137
 
89
138
  assistant:
90
139
  ```
91
- orderingApi.respondToUser("I'm sorry, but that isn't on our menu.");
140
+ import * as ApiDefs from 'api.ts'
141
+
142
+ (async() {
143
+ try {
144
+ orderingApi.respondToUser("I'm sorry, but that isn't on our menu.");
145
+ } catch(err) {
146
+ console.error(err);
147
+ }
148
+ })();
92
149
  ```
@@ -6,5 +6,13 @@ user: How are you today?
6
6
 
7
7
  assistant:
8
8
  ```
9
- api.print("I'm great, thanks for asking!");
9
+ import * as ApiDefs from 'api.ts'
10
+
11
+ (async() {
12
+ try {
13
+ api.print("I'm great, thanks for asking!");
14
+ } catch(err) {
15
+ console.error(err);
16
+ }
17
+ })();
10
18
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aimyapi",
3
- "version": "0.1.15",
3
+ "version": "0.2.0",
4
4
  "description": "AI My API! Use LLMs to create small programs that safely* run and make calls against your API. Similar to ChatGPT's Code Interpreter.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,11 +11,22 @@ Here is the API that you will use:
11
11
 
12
12
  Documentation:
13
13
 
14
- Note: the api definitions are available as `ApiDefs`.
14
+ Write your code in this format:
15
+ ```
16
+ import * as ApiDefs from 'api.ts'
17
+
18
+ (async() {
19
+ try {
20
+ // ... your code here
21
+ } catch(err) {
22
+ console.error(err);
23
+ }
24
+ })();
25
+ ```
15
26
 
16
27
  {{DOCUMENTATION}}
17
28
 
18
- Current Context:
29
+ Contextual data:
19
30
  ```
20
31
  {{CONTEXT}}
21
32
  ```
package/src/index.ts CHANGED
@@ -38,11 +38,10 @@ export interface GenerateCodeResult {
38
38
  }
39
39
 
40
40
  // FIXME: add an options parameter and allow specifying the token limit
41
- export const generateCode = async function(queryText:string, userChatHistory:ChatCompletionMessageParam[], createTaskPrompt:string, apiPath:string, debug:boolean = false, model="gpt-4o"): Promise<GenerateCodeResult> {
41
+ export const generateCode = async function(queryText:string, userChatHistory:ChatCompletionMessageParam[], createTaskPrompt:string, debug:boolean = false, model="gpt-4o-mini"): Promise<GenerateCodeResult> {
42
42
  if(!queryText)
43
43
  return { code: '', loggableCode: '' };
44
44
 
45
- let generatedCode = '';
46
45
  const prompt = createTaskPrompt.replace("{{QUERY_TEXT}}", queryText);
47
46
  const messages:ChatCompletionMessageParam[] = [
48
47
  {
@@ -52,16 +51,33 @@ export const generateCode = async function(queryText:string, userChatHistory:Cha
52
51
  ...userChatHistory,
53
52
  {
54
53
  role: "user",
55
- content: `${queryText}.\nRespond only with code enclosed in \`\`\`.`,
54
+ content: `${queryText}. Respond with json`,
56
55
  name: "user"
57
56
  }
58
57
  ];
58
+
59
59
  try {
60
60
  const results = await openai.chat.completions.create({
61
61
  model,
62
62
  messages: messages,
63
63
  temperature: 0.0,
64
- max_tokens: 700,
64
+ max_tokens: 2000,
65
+ response_format: {
66
+ json_schema: {
67
+ name: "codeResponse",
68
+ description: "The code generated by the AI",
69
+ schema: {
70
+ type: 'object',
71
+ properties: {
72
+ yourCode: {
73
+ type: 'string',
74
+ description: 'The code generated by the AI',
75
+ }
76
+ },
77
+ },
78
+ },
79
+ type: 'json_schema',
80
+ }
65
81
  }
66
82
  );
67
83
 
@@ -72,21 +88,16 @@ export const generateCode = async function(queryText:string, userChatHistory:Cha
72
88
 
73
89
  if(debug)
74
90
  console.log(response);
75
-
76
- // Return only the code between ``` and ``` (usually at the end of the completion)
77
- const codeStart = response.indexOf('```');
78
- const codeEnd = response.lastIndexOf('```');
79
-
80
- // error, no code detected inside the response
81
- if(codeStart === -1 || codeEnd === -1 || codeStart === codeEnd) {
82
- return { code: '', loggableCode: '', rawResponse: response };
91
+
92
+ try {
93
+ const json = JSON.parse(response);
94
+ const code = json.yourCode.replaceAll('```', '');
95
+
96
+ return { code, loggableCode: code };
97
+ } catch(err) {
98
+ console.error("Error parsing response", err);
99
+ return { code: '', loggableCode: '' };
83
100
  }
84
-
85
- generatedCode = response.substring(codeStart + 3, codeEnd).replace('typescript', '');
86
-
87
- const codeHeader = `import * as ApiDefs from '${apiPath}'\n(async() {\n\ttry {`;
88
- const codeFooter = `\n\t} catch(err) {\n\t\tconsole.error(err);\n\t}\n})();`;
89
- return { code: codeHeader + generatedCode + codeFooter, loggableCode: generatedCode };
90
101
  } catch(err) {
91
102
  console.error(err);
92
103
  return { code: '', loggableCode: '' };
@@ -124,7 +135,7 @@ async function createWithAPI(options:AIMyAPIOptions): Promise<AIMyAPIInstance> {
124
135
  apiGlobals: {},
125
136
  apiWhitelist: Object.getOwnPropertyNames(Object.getPrototypeOf(options.apiObject)).filter((f) => f !== "constructor" && !f.startsWith("_")),
126
137
  debug: false,
127
- model: "gpt-4o",
138
+ model: "gpt-4o-mini",
128
139
  ...options
129
140
  } as AIMyAPIOptions;
130
141
 
@@ -142,7 +153,7 @@ async function createWithAPI(options:AIMyAPIOptions): Promise<AIMyAPIInstance> {
142
153
  if(!queryText)
143
154
  return { code: '', loggableCode: '' };
144
155
 
145
- return await generateCode(queryText, userChatHistory, createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath, debug, model);
156
+ return await generateCode(queryText, userChatHistory, createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), debug, model);
146
157
  },
147
158
  runCode: async function(generatedCode:string) {
148
159
  if(!QuickJS) {
@@ -177,7 +188,7 @@ async function createWithAPI(options:AIMyAPIOptions): Promise<AIMyAPIInstance> {
177
188
  console.log("Running Code:\n", generatedCode);
178
189
  }
179
190
 
180
- const res = await runTask(generatedCode);
191
+ const res = await runTask(generatedCode.replace("'api.ts'", `'${options.apiDefFilePath}'`));
181
192
 
182
193
  if(!res) {
183
194
  console.error("Task unsuccessful");
@@ -211,11 +222,11 @@ async function createWithAPI(options:AIMyAPIOptions): Promise<AIMyAPIInstance> {
211
222
 
212
223
  // Generate Code
213
224
  console.time("Generate Task")
214
- const generatedCode:GenerateCodeResult = await generateCode(userQuery, [], createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : "" ), apiDefFilePath);
225
+ const generatedCode:GenerateCodeResult = await generateCode(userQuery, [], createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : "" ));
215
226
  console.timeEnd("Generate Task")
216
227
 
217
228
  console.time("Run Code")
218
- await this.runCode(generatedCode.code);
229
+ await this.runCode(generatedCode.code.replace("'api.ts'", `'${options.apiDefFilePath}'`));
219
230
  console.timeEnd("Run Code")
220
231
 
221
232
  return generatedCode;
@@ -228,7 +239,7 @@ export interface AIMyAPIModuleExports {
228
239
  createWithAPI: (options:AIMyAPIOptions) => Promise<AIMyAPIInstance>;
229
240
 
230
241
  createBasePrompt: (apiFilePath:string, documentationPath: string) => string;
231
- generateCode: (queryText:string, userChatHistory:ChatCompletionMessageParam[], createTaskPrompt:string, apiPath:string, debug:boolean) => Promise<GenerateCodeResult>;
242
+ generateCode: (queryText:string, userChatHistory:ChatCompletionMessageParam[], createTaskPrompt:string, debug:boolean) => Promise<GenerateCodeResult>;
232
243
  createSandbox: (QuickJS:QuickJSWASMModule, globals: any) => Promise<any>;
233
244
  }
234
245