aimyapi 1.0.6 → 1.0.8

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.js CHANGED
@@ -438,11 +438,12 @@ const checkCodeSchema = zod.z.object({
438
438
  const submitCodeSchema = zod.z.object({
439
439
  code: zod.z.string()
440
440
  });
441
- const generateCode = async function(instance, queryText, userChatHistory, createTaskPrompt, debug = false, hideLogsFromAgent = false, model = "gpt-5-mini", additionalModelOptions) {
441
+ const generateCode = async function(instance, queryText, userChatHistory, createTaskPrompt, debug = false, hideLogsFromAgent = false, model = "gpt-5-mini", additionalModelOptions, attempt = 0) {
442
442
  let finalSubmittedCode = "";
443
443
  if (debug) {
444
444
  console.log("Generating code for query:", queryText);
445
445
  }
446
+ const newHistoryItems = [];
446
447
  const codingTools = [
447
448
  {
448
449
  type: "function",
@@ -487,6 +488,14 @@ const generateCode = async function(instance, queryText, userChatHistory, create
487
488
  name: "submitCode",
488
489
  // @ts-ignore
489
490
  function: async ({ code }) => {
491
+ const checkRes = await instance.checkCode(code);
492
+ if (!checkRes.success) {
493
+ return {
494
+ success: false,
495
+ reason: "Code check failed",
496
+ logs: checkRes.logs
497
+ };
498
+ }
490
499
  finalSubmittedCode = code;
491
500
  return {
492
501
  success: true
@@ -504,12 +513,12 @@ const generateCode = async function(instance, queryText, userChatHistory, create
504
513
  messages: [
505
514
  {
506
515
  role: "system",
507
- content: "You will assist with writing code to perform the user's request."
516
+ content: "You will assist with writing or modifying code based on the user's request."
508
517
  },
509
518
  ...userChatHistory,
510
519
  {
511
520
  role: "user",
512
- content: createTaskPrompt.replace("{{USER_QUERY}}", queryText)
521
+ content: attempt == 0 ? createTaskPrompt.replace("{{USER_QUERY}}", queryText) : queryText
513
522
  }
514
523
  ],
515
524
  tools: codingTools,
@@ -518,6 +527,7 @@ const generateCode = async function(instance, queryText, userChatHistory, create
518
527
  if (debug) {
519
528
  console.log("Message:", JSON.stringify(message, null, 2));
520
529
  }
530
+ newHistoryItems.push(message);
521
531
  }).on("functionToolCall", (functionCall) => {
522
532
  if (debug) {
523
533
  console.log("Function Call:", JSON.stringify(functionCall, null, 2));
@@ -529,15 +539,37 @@ const generateCode = async function(instance, queryText, userChatHistory, create
529
539
  });
530
540
  const finalContent = await runner.finalContent();
531
541
  if (debug) {
532
- console.log("Final Content:", finalContent);
542
+ console.log("Generate code final response:", finalContent);
543
+ }
544
+ if (!finalSubmittedCode) {
545
+ console.error("No code was submitted by the agent.");
546
+ if (attempt < 3) {
547
+ return generateCode(instance, `You must call submitCode with valid code before proceeding. Attempt ${attempt + 1} of 3.`, [
548
+ ...userChatHistory,
549
+ {
550
+ role: "user",
551
+ content: attempt == 0 ? createTaskPrompt.replace("{{USER_QUERY}}", queryText) : queryText
552
+ },
553
+ ...newHistoryItems
554
+ ], createTaskPrompt, debug, hideLogsFromAgent, model, additionalModelOptions, attempt + 1);
555
+ } else {
556
+ return {
557
+ success: false,
558
+ comments: "No code was submitted by the agent after multiple attempts. Final comment: " + finalContent
559
+ };
560
+ }
533
561
  }
534
562
  return {
563
+ success: true,
535
564
  code: finalSubmittedCode,
536
565
  comments: finalContent || void 0
537
566
  };
538
567
  } catch (err) {
539
568
  console.error(err);
540
- return null;
569
+ return {
570
+ success: false,
571
+ comments: `Error generating code: ${err}`
572
+ };
541
573
  }
542
574
  };
543
575
  async function createWithAPI(options) {
package/dist/index.mjs CHANGED
@@ -416,11 +416,12 @@ const checkCodeSchema = z.object({
416
416
  const submitCodeSchema = z.object({
417
417
  code: z.string()
418
418
  });
419
- const generateCode = async function(instance, queryText, userChatHistory, createTaskPrompt, debug = false, hideLogsFromAgent = false, model = "gpt-5-mini", additionalModelOptions) {
419
+ const generateCode = async function(instance, queryText, userChatHistory, createTaskPrompt, debug = false, hideLogsFromAgent = false, model = "gpt-5-mini", additionalModelOptions, attempt = 0) {
420
420
  let finalSubmittedCode = "";
421
421
  if (debug) {
422
422
  console.log("Generating code for query:", queryText);
423
423
  }
424
+ const newHistoryItems = [];
424
425
  const codingTools = [
425
426
  {
426
427
  type: "function",
@@ -465,6 +466,14 @@ const generateCode = async function(instance, queryText, userChatHistory, create
465
466
  name: "submitCode",
466
467
  // @ts-ignore
467
468
  function: async ({ code }) => {
469
+ const checkRes = await instance.checkCode(code);
470
+ if (!checkRes.success) {
471
+ return {
472
+ success: false,
473
+ reason: "Code check failed",
474
+ logs: checkRes.logs
475
+ };
476
+ }
468
477
  finalSubmittedCode = code;
469
478
  return {
470
479
  success: true
@@ -482,12 +491,12 @@ const generateCode = async function(instance, queryText, userChatHistory, create
482
491
  messages: [
483
492
  {
484
493
  role: "system",
485
- content: "You will assist with writing code to perform the user's request."
494
+ content: "You will assist with writing or modifying code based on the user's request."
486
495
  },
487
496
  ...userChatHistory,
488
497
  {
489
498
  role: "user",
490
- content: createTaskPrompt.replace("{{USER_QUERY}}", queryText)
499
+ content: attempt == 0 ? createTaskPrompt.replace("{{USER_QUERY}}", queryText) : queryText
491
500
  }
492
501
  ],
493
502
  tools: codingTools,
@@ -496,6 +505,7 @@ const generateCode = async function(instance, queryText, userChatHistory, create
496
505
  if (debug) {
497
506
  console.log("Message:", JSON.stringify(message, null, 2));
498
507
  }
508
+ newHistoryItems.push(message);
499
509
  }).on("functionToolCall", (functionCall) => {
500
510
  if (debug) {
501
511
  console.log("Function Call:", JSON.stringify(functionCall, null, 2));
@@ -507,15 +517,37 @@ const generateCode = async function(instance, queryText, userChatHistory, create
507
517
  });
508
518
  const finalContent = await runner.finalContent();
509
519
  if (debug) {
510
- console.log("Final Content:", finalContent);
520
+ console.log("Generate code final response:", finalContent);
521
+ }
522
+ if (!finalSubmittedCode) {
523
+ console.error("No code was submitted by the agent.");
524
+ if (attempt < 3) {
525
+ return generateCode(instance, `You must call submitCode with valid code before proceeding. Attempt ${attempt + 1} of 3.`, [
526
+ ...userChatHistory,
527
+ {
528
+ role: "user",
529
+ content: attempt == 0 ? createTaskPrompt.replace("{{USER_QUERY}}", queryText) : queryText
530
+ },
531
+ ...newHistoryItems
532
+ ], createTaskPrompt, debug, hideLogsFromAgent, model, additionalModelOptions, attempt + 1);
533
+ } else {
534
+ return {
535
+ success: false,
536
+ comments: "No code was submitted by the agent after multiple attempts. Final comment: " + finalContent
537
+ };
538
+ }
511
539
  }
512
540
  return {
541
+ success: true,
513
542
  code: finalSubmittedCode,
514
543
  comments: finalContent || void 0
515
544
  };
516
545
  } catch (err) {
517
546
  console.error(err);
518
- return null;
547
+ return {
548
+ success: false,
549
+ comments: `Error generating code: ${err}`
550
+ };
519
551
  }
520
552
  };
521
553
  async function createWithAPI(options) {
@@ -1,31 +1,31 @@
1
- import { AIMyAPI } from "../src";
2
- import { API } from "./sales_api_impl";
3
-
4
- // Simpler example using no support for chat history;
5
-
6
- (async () => {
7
- const api = new API();
8
-
9
- const aimyapi = await AIMyAPI.createWithAPI({
10
- apiObject: api,
11
- apiGlobalName: "salesApi", // Should match whatever you declared as your global in your api.
12
- apiDefFilePath: "./example/sales_api.ts",
13
- apiDocsPath: "./example/sales_api.md",
14
- debug: false,
15
- })
16
-
17
- aimyapi.runCode(`console.log("Hello from the sandbox! Here is some sales data:", salesApi.getSalesData())`);
18
-
19
- console.log("Print 'hello' three times.")
20
- await aimyapi.processRequest("Print 'hello' three times.");
21
-
22
- console.log("What month had the highest sales in 2020 for any business unit?")
23
- await aimyapi.processRequest("What was our best month in 2020");
24
-
25
- console.log("Which business unit had the highest sales in 2020? Print the totals for each")
26
- await aimyapi.processRequest("Which business unit had the highest sales in 2020? Print the totals for each");
27
- // Note: this is a bit of a trick question because two of them are tied for first. The agent usually doesn't realize this edge case. Should we instruct it to look for edge cases?
28
-
29
- console.log("Compute the total sales for each month in 2020 then email the top 3 to test@email.com")
30
- await aimyapi.processRequest("Compute the total sales for each month in 2020 then email the top 3 to test@email.com");
1
+ import { AIMyAPI } from "../src";
2
+ import { API } from "./sales_api_impl";
3
+
4
+ // Simpler example using no support for chat history;
5
+
6
+ (async () => {
7
+ const api = new API();
8
+
9
+ const aimyapi = await AIMyAPI.createWithAPI({
10
+ apiObject: api,
11
+ apiGlobalName: "salesApi", // Should match whatever you declared as your global in your api.
12
+ apiDefFilePath: "./example/sales_api.ts",
13
+ apiDocsPath: "./example/sales_api.md",
14
+ debug: false,
15
+ })
16
+
17
+ aimyapi.runCode(`console.log("Hello from the sandbox! Here is some sales data:", salesApi.getSalesData())`);
18
+
19
+ console.log("Print 'hello' three times.")
20
+ await aimyapi.processRequest("Print 'hello' three times.");
21
+
22
+ console.log("What month had the highest sales in 2020 for any business unit?")
23
+ await aimyapi.processRequest("What was our best month in 2020");
24
+
25
+ console.log("Which business unit had the highest sales in 2020? Print the totals for each")
26
+ await aimyapi.processRequest("Which business unit had the highest sales in 2020? Print the totals for each");
27
+ // Note: this is a bit of a trick question because two of them are tied for first. The agent usually doesn't realize this edge case. Should we instruct it to look for edge cases?
28
+
29
+ console.log("Compute the total sales for each month in 2020 then email the top 3 to test@email.com")
30
+ await aimyapi.processRequest("Compute the total sales for each month in 2020 then email the top 3 to test@email.com");
31
31
  })();
@@ -1,59 +1,59 @@
1
- // Note: This example is quite stupid and slow and you'd be better off using Tool calling for something like this, but I'm leaving it for demonstration purposes
2
-
3
- import { AIMyAPI } from "../src";
4
- import { Menu } from "./ordering_api";
5
- import { OrderingAPI } from "./ordering_api_impl";
6
-
7
- // More complex fast food ordering example that uses chat history.
8
- // Fast food ordering example.
9
-
10
- (async () => {
11
- const orderingApi = new OrderingAPI();
12
-
13
- const options = {
14
- apiObject: orderingApi,
15
- apiGlobalName: "orderingApi", // Should match whatever you declared as your global in your ordering api.
16
- apiGlobals: {
17
- Menu: Menu,
18
- },
19
- apiDefFilePath: "./example/ordering_api.ts",
20
- apiDocsPath: "./example/ordering_api.md",
21
- debug: false,
22
- };
23
- const aimyapi = await AIMyAPI.createWithAPI(options)
24
-
25
- async function runQuery(query:string) {
26
- console.log(`Query: ${query}`)
27
-
28
- // generate the code for this query
29
- const codeResult = await aimyapi.generateCode(query, orderingApi._getHistory());
30
-
31
- if(codeResult) {
32
- orderingApi._addMessageToHistory({
33
- content: query,
34
- role: "user",
35
- name: "user",
36
- });
37
-
38
- orderingApi._addMessageToHistory({
39
- content: codeResult.comments || "done",
40
- role: "assistant",
41
- name: "assistant",
42
- });
43
-
44
- // run the code in the sandbox
45
- if(codeResult.code) {
46
- await aimyapi.runCode(codeResult.code);
47
- }
48
- } else {
49
- console.error("No code generated for this query.");
50
- }
51
-
52
- }
53
-
54
- await runQuery("How's the burger here?");
55
- await runQuery("I'd like a plain hamburger (no cheese) and a large fries, a pizza with anchovies and a cola. I'd also like a cheese burger with bacon and avocado.");
56
- await runQuery("I changed my mind, instead of anchovies, can I get a large gluten free pizza with pineapple instead.");
57
- await runQuery("email me the total at myemail@test.com and complete the order");
58
-
1
+ // Note: This example is quite stupid and slow and you'd be better off using Tool calling for something like this, but I'm leaving it for demonstration purposes
2
+
3
+ import { AIMyAPI } from "../src";
4
+ import { Menu } from "./ordering_api";
5
+ import { OrderingAPI } from "./ordering_api_impl";
6
+
7
+ // More complex fast food ordering example that uses chat history.
8
+ // Fast food ordering example.
9
+
10
+ (async () => {
11
+ const orderingApi = new OrderingAPI();
12
+
13
+ const options = {
14
+ apiObject: orderingApi,
15
+ apiGlobalName: "orderingApi", // Should match whatever you declared as your global in your ordering api.
16
+ apiGlobals: {
17
+ Menu: Menu,
18
+ },
19
+ apiDefFilePath: "./example/ordering_api.ts",
20
+ apiDocsPath: "./example/ordering_api.md",
21
+ debug: false,
22
+ };
23
+ const aimyapi = await AIMyAPI.createWithAPI(options)
24
+
25
+ async function runQuery(query:string) {
26
+ console.log(`Query: ${query}`)
27
+
28
+ // generate the code for this query
29
+ const codeResult = await aimyapi.generateCode(query, orderingApi._getHistory());
30
+
31
+ if(codeResult) {
32
+ orderingApi._addMessageToHistory({
33
+ content: query,
34
+ role: "user",
35
+ name: "user",
36
+ });
37
+
38
+ orderingApi._addMessageToHistory({
39
+ content: codeResult.comments || "done",
40
+ role: "assistant",
41
+ name: "assistant",
42
+ });
43
+
44
+ // run the code in the sandbox
45
+ if(codeResult.code) {
46
+ await aimyapi.runCode(codeResult.code);
47
+ }
48
+ } else {
49
+ console.error("No code generated for this query.");
50
+ }
51
+
52
+ }
53
+
54
+ await runQuery("How's the burger here?");
55
+ await runQuery("I'd like a plain hamburger (no cheese) and a large fries, a pizza with anchovies and a cola. I'd also like a cheese burger with bacon and avocado.");
56
+ await runQuery("I changed my mind, instead of anchovies, can I get a large gluten free pizza with pineapple instead.");
57
+ await runQuery("email me the total at myemail@test.com and complete the order");
58
+
59
59
  })();
@@ -1,70 +1,70 @@
1
-
2
- import { AIMyAPI } from "../src";
3
- import { Menu } from "./ordering_api";
4
- import { OrderingAPI } from "./ordering_api_impl";
5
-
6
- import readline from 'readline';
7
-
8
- function getInput(query: string): Promise<string> {
9
- const rl = readline.createInterface({
10
- input: process.stdin,
11
- output: process.stdout,
12
- });
13
-
14
- return new Promise(resolve => rl.question(query, ans => {
15
- rl.close();
16
- resolve(ans);
17
- }))
18
- }
19
-
20
- // More complex fast food ordering example that uses chat history.
21
- // Fast food ordering example.
22
- // -- Interactive version
23
- (async () => {
24
- const orderingApi = new OrderingAPI();
25
-
26
- const options = {
27
- apiObject: orderingApi,
28
- apiGlobalName: "orderingApi", // Should match whatever you declared as your global in your ordering api.
29
- apiGlobals: {
30
- Menu: Menu,
31
- },
32
- apiDefFilePath: "./example/ordering_api.ts",
33
- apiDocsPath: "./example/ordering_api.md",
34
- debug: false,
35
- };
36
- const aimyapi = await AIMyAPI.createWithAPI(options)
37
-
38
- async function runQuery(query:string) {
39
- console.log(`Query: ${query}`)
40
-
41
- // generate the code for this query
42
- const result = await aimyapi.generateCode(query, orderingApi._getHistory());
43
-
44
- if(result) {
45
- orderingApi._addMessageToHistory({
46
- content: query,
47
- role: "user",
48
- name: "user",
49
- });
50
-
51
- orderingApi._addMessageToHistory({
52
- content: result.comments || "done",
53
- role: "assistant",
54
- name: "assistant",
55
- });
56
-
57
- // run the code in the sandbox
58
- if(result.code) {
59
- await aimyapi.runCode(result.code);
60
- }
61
- }
62
- }
63
-
64
- console.log("Welcome to the restaurant. You can ask to hear the menu or order something. What would you like to do?");
65
- while (!orderingApi._isCompleted) {
66
- const query:string = await getInput("Your query: ");
67
- await runQuery(query);
68
- }
69
-
1
+
2
+ import { AIMyAPI } from "../src";
3
+ import { Menu } from "./ordering_api";
4
+ import { OrderingAPI } from "./ordering_api_impl";
5
+
6
+ import readline from 'readline';
7
+
8
+ function getInput(query: string): Promise<string> {
9
+ const rl = readline.createInterface({
10
+ input: process.stdin,
11
+ output: process.stdout,
12
+ });
13
+
14
+ return new Promise(resolve => rl.question(query, ans => {
15
+ rl.close();
16
+ resolve(ans);
17
+ }))
18
+ }
19
+
20
+ // More complex fast food ordering example that uses chat history.
21
+ // Fast food ordering example.
22
+ // -- Interactive version
23
+ (async () => {
24
+ const orderingApi = new OrderingAPI();
25
+
26
+ const options = {
27
+ apiObject: orderingApi,
28
+ apiGlobalName: "orderingApi", // Should match whatever you declared as your global in your ordering api.
29
+ apiGlobals: {
30
+ Menu: Menu,
31
+ },
32
+ apiDefFilePath: "./example/ordering_api.ts",
33
+ apiDocsPath: "./example/ordering_api.md",
34
+ debug: false,
35
+ };
36
+ const aimyapi = await AIMyAPI.createWithAPI(options)
37
+
38
+ async function runQuery(query:string) {
39
+ console.log(`Query: ${query}`)
40
+
41
+ // generate the code for this query
42
+ const result = await aimyapi.generateCode(query, orderingApi._getHistory());
43
+
44
+ if(result) {
45
+ orderingApi._addMessageToHistory({
46
+ content: query,
47
+ role: "user",
48
+ name: "user",
49
+ });
50
+
51
+ orderingApi._addMessageToHistory({
52
+ content: result.comments || "done",
53
+ role: "assistant",
54
+ name: "assistant",
55
+ });
56
+
57
+ // run the code in the sandbox
58
+ if(result.code) {
59
+ await aimyapi.runCode(result.code);
60
+ }
61
+ }
62
+ }
63
+
64
+ console.log("Welcome to the restaurant. You can ask to hear the menu or order something. What would you like to do?");
65
+ while (!orderingApi._isCompleted) {
66
+ const query:string = await getInput("Your query: ");
67
+ await runQuery(query);
68
+ }
69
+
70
70
  })();