aimyapi 0.2.0 → 1.0.2

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.
@@ -6,7 +6,7 @@ import { OrderingAPI } from "./ordering_api_impl";
6
6
 
7
7
  import readline from 'readline';
8
8
 
9
- function getInput(query): Promise<string> {
9
+ function getInput(query: string): Promise<string> {
10
10
  const rl = readline.createInterface({
11
11
  input: process.stdin,
12
12
  output: process.stdout,
@@ -20,13 +20,16 @@ function getInput(query): Promise<string> {
20
20
 
21
21
  // More complex fast food ordering example that uses chat history.
22
22
  // Fast food ordering example.
23
- // Interactive version
23
+ // -- Interactive version
24
24
  (async () => {
25
- const api = new OrderingAPI();
25
+ const orderingApi = new OrderingAPI();
26
26
 
27
27
  const options = {
28
- apiObject: api,
28
+ apiObject: orderingApi,
29
29
  apiGlobalName: "orderingApi", // Should match whatever you declared as your global in your ordering api.
30
+ apiGlobals: {
31
+ Menu: APIExports.Menu,
32
+ },
30
33
  apiExports: APIExports,
31
34
  apiDefFilePath: path.join(__dirname, "./ordering_api.ts"),
32
35
  apiDocsPath: path.join(__dirname, "./ordering_api.md"),
@@ -38,26 +41,30 @@ function getInput(query): Promise<string> {
38
41
  console.log(`Query: ${query}`)
39
42
 
40
43
  // generate the code for this query
41
- const result = await aimyapi.generateCode(query, api._getHistory());
44
+ const result = await aimyapi.generateCode(query, orderingApi._getHistory());
42
45
 
43
- api._addMessageToHistory({
44
- content: query,
45
- role: "user",
46
- name: "user",
47
- });
46
+ if(result) {
47
+ orderingApi._addMessageToHistory({
48
+ content: query,
49
+ role: "user",
50
+ name: "user",
51
+ });
48
52
 
49
- api._addMessageToHistory({
50
- content: '```\n' + result.code.replace(options.apiDefFilePath, "./api.ts") + '\n```',
51
- role: "assistant",
52
- name: "assistant",
53
- });
53
+ orderingApi._addMessageToHistory({
54
+ content: result.comments || "done",
55
+ role: "assistant",
56
+ name: "assistant",
57
+ });
54
58
 
55
- // run the code in the sandbox
56
- await aimyapi.runCode(result.code);
59
+ // run the code in the sandbox
60
+ if(result.code) {
61
+ await aimyapi.runCode(result.code);
62
+ }
63
+ }
57
64
  }
58
65
 
59
66
  console.log("Welcome to the restaurant. You can ask to hear the menu or order something. What would you like to do?");
60
- while (!api._isCompleted) {
67
+ while (!orderingApi._isCompleted) {
61
68
  const query:string = await getInput("Your query: ");
62
69
  await runQuery(query);
63
70
  }
@@ -1,133 +1,86 @@
1
- You are an order taking assistant at a restaurant.
1
+ # Documentation
2
+
3
+ You work at a restaurant.
2
4
  Your responses should be energetic, positive and polite.
3
5
  Help the customer with whatever questions they may have and ring up their orders.
4
6
  Do not complete the order until the user says they are finished ordering.
5
7
  Your code should check for errors or for cases where items may not be found.
6
8
 
7
- Examples of how you should respond:
9
+ ## Examples of how you should respond:
8
10
 
9
11
  user: How are you today?
10
12
 
11
- assistant:
12
- ```
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
- })();
13
+ code:
14
+ ```typescript
15
+ orderingApi.respondToUser("I'm great, thanks for asking!");
22
16
  ```
23
17
 
24
18
  user: Add a hamburger with no cheese to my order
25
19
 
26
- assistant:
27
- ```
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
- })();
20
+ code:
21
+ ```typescript
22
+ const itemName = "Hamburger";
23
+ const item = Menu.find((item) => item.name === itemName);
24
+ if (!item) {
25
+ throw new Error(`Item with name "${itemName}" not found`);
26
+ }
27
+
28
+ orderingApi.addItemToOrder(itemName, undefined, item.toppings.filter( topping => topping.name != "cheese") );
29
+ orderingApi.respondToUser("Ok, I added a Hamburger. What else would you like?");
44
30
  ```
45
31
 
46
32
  log: Added Hamburger with id 1
47
33
 
48
34
  user: I'd like a large pizza with mushrooms
49
35
 
50
- assistant:
51
- ```
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
- })();
36
+ code:
37
+ ```typescript
38
+ orderingApi.addItemToOrder("Pizza", ["Large"], ["mushrooms"]);
39
+ orderingApi.respondToUser("Ok, I added a Large Pizza with mushrooms");
63
40
  ```
64
41
 
65
42
  user: Add a hamburger with bacon
66
43
 
67
- assistant:
68
- ```
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
- })();
44
+ code:
45
+ ```typescript
46
+ const itemName = "Hamburger";
47
+ const item = Menu.find((item) => item.name === itemName);
48
+ if (!item) {
49
+ throw new Error(`Item with name "${itemName}" not found`);
50
+ }
51
+
52
+ orderingApi.addItemToOrder(itemName, undefined, [...item.toppings, "bacon"]);
53
+ orderingApi.respondToUser("Ok, I added a Hamburger with no cheese or onions. What else would you like?");
85
54
  ```
86
55
 
87
56
  log: Added Hamburger with id 2
88
57
 
89
58
  user: Add jalapenos to that
90
59
 
91
- assistant:
92
- ```
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
- })();
60
+ code:
61
+ ```typescript
62
+ const existingItem = orderingApi.getItemInOrder("2");
63
+
64
+ if(existingItem) {
65
+ orderingApi.modifyItemInOrder("2", existingItem.customizations.map(item => item.name), [...existingItem.toppings, "jalapenos"]);
66
+ orderingApi.respondToUser("Ok, I added jalapenos to your Hamburger");
67
+ } else {
68
+ orderingApi.respondToUser("Hmm, I can't find that item.");
69
+ }
109
70
  ```
110
71
 
111
72
  user: Add a hamburger with no lettuce
112
73
 
113
- assistant:
114
- ```
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
- })();
74
+ code:
75
+ ```typescript
76
+ const itemName = "Hamburger";
77
+ const item = Menu.find((item) => item.name === itemName);
78
+ if (!item) {
79
+ throw new Error(`Item with name "${itemName}" not found`);
80
+ }
81
+
82
+ orderingApi.addItemToOrder(itemName, undefined, [...item.toppings.filter(topping => topping != "lettuce")]);
83
+ orderingApi.respondToUser("Ok, I added a Hamburger with no cheese or onions. What else would you like?");
131
84
  ```
132
85
 
133
86
  log: Added Hamburger with id 2
@@ -135,15 +88,7 @@ log: Added Hamburger with id 2
135
88
 
136
89
  user: I want an elephant.
137
90
 
138
- assistant:
139
- ```
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
- })();
91
+ code:
92
+ ```typescript
93
+ orderingApi.respondToUser("I'm sorry, but that isn't on our menu.");
149
94
  ```
@@ -184,7 +184,8 @@ export interface OrderingAPIInterface {
184
184
 
185
185
  };
186
186
 
187
- // Global object you will use for accessing the APIInterface
187
+ // Global object for accessing the OrderingAPIInterface
188
188
  declare global {
189
- var orderingApi: OrderingAPIInterface;
189
+ const orderingApi: OrderingAPIInterface;
190
+ const Menu: MenuItemBase[];
190
191
  }
@@ -7,7 +7,7 @@ import {
7
7
  OrderingAPIInterface,
8
8
  } from "./ordering_api";
9
9
 
10
- // TODO: make functions to print out an item, and print out the current order with the price totals.
10
+ // TODO: Typescript typing could be better on this API and it would probably benefit the agent.
11
11
 
12
12
  export class OrderingAPI implements OrderingAPIInterface {
13
13
  private _order: MenuItemBase[] = [];
@@ -66,6 +66,7 @@ export class OrderingAPI implements OrderingAPIInterface {
66
66
  throw new Error(`Item with name "${itemName}" not found`);
67
67
  }
68
68
 
69
+ // FIXME: we shouldn't allow adding an item with customizations that aren't in the allowedCustomizations list for that item
69
70
  const customizations = customizationNames ? customizationNames
70
71
  .map((customizationName) => {
71
72
  return this.getCustomizationByName(itemName, customizationName);
@@ -1,18 +1,5 @@
1
- Use `api.getSalesData()` to get the sales data array.
1
+ ## Examples:
2
2
 
3
- Examples of how you should respond:
3
+ to print hello:
4
4
 
5
- user: How are you today?
6
-
7
- assistant:
8
- ```
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
- })();
18
- ```
5
+ submitCode("salesApi.print(\"Hello\")");
@@ -23,7 +23,7 @@ export interface APIInterface {
23
23
 
24
24
  };
25
25
 
26
- // Global object you will use for accessing the APIInterface
26
+ // Global object for accessing the APIInterface
27
27
  declare global {
28
- var api: APIInterface;
28
+ const salesApi: APIInterface;
29
29
  }
@@ -51,7 +51,7 @@ export class API implements APIInterface {
51
51
  };
52
52
 
53
53
  print(text: string): void {
54
- console.log(text);
54
+ console.log(`[API]: ${text}`);
55
55
  }
56
56
  delay(milliseconds: number): Promise<void> {
57
57
  return delay(milliseconds);
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "aimyapi",
3
- "version": "0.2.0",
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.",
3
+ "version": "1.0.2",
4
+ "description": "AI My API! Typescript sandbox for AI agents to interact with your API in a safe way.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
- "module": "./dist/index.mjs",
7
+ "module": "./dist/index.mjs",
8
8
  "exports": {
9
9
  "require": {
10
- "types": "./dist/index.d.cts",
11
- "default": "./dist/index.cjs"
10
+ "types": "./dist/index.d.cts",
11
+ "default": "./dist/index.cjs"
12
12
  },
13
13
  "import": {
14
- "types": "./dist/index.d.mts",
15
- "default": "./dist/index.mjs"
14
+ "types": "./dist/index.d.mts",
15
+ "default": "./dist/index.mjs"
16
16
  }
17
17
  },
18
18
  "directories": {
@@ -35,9 +35,11 @@
35
35
  ],
36
36
  "dependencies": {
37
37
  "dotenv": "^16.0.3",
38
- "openai": "^4.61.0",
38
+ "openai": "^6.33.0",
39
39
  "quickjs-emscripten": "^0.22.0",
40
- "typescript": "^5.0.3"
40
+ "typescript": "^5.0.3",
41
+ "zod": "^3.23.8",
42
+ "zod-to-json-schema": "^3.23.3"
41
43
  },
42
44
  "author": "David Wallin",
43
45
  "license": "MIT",
@@ -46,7 +48,7 @@
46
48
  },
47
49
  "homepage": "https://github.com/WhiteNoise/aimyapi#readme",
48
50
  "devDependencies": {
49
- "@types/node": "^18.16.2",
51
+ "@types/node": "^18.19.130",
50
52
  "pkgroll": "^2.5.0",
51
53
  "tsx": "^4.19.1"
52
54
  }
@@ -1,32 +1,30 @@
1
- You are a helpful assistant who speaks only in Typescript.
2
- You work just like a regular assistant, but you fulfill user requests by writing code.
3
- You comment your code and are sure to properly escape your strings and follow good programming practices.
4
1
 
5
- Here is the API that you will use:
2
+ Most recent user query:
3
+ ```
4
+ {{USER_QUERY}}
5
+ ```
6
+
7
+ Based on the above conversation, write a typescript script that performs the next operation requested by the user.
8
+
9
+ Here's the typescript API to use for your script.
6
10
 
7
11
  `api.ts`:
8
- ```
12
+ ```typescript
9
13
  {{API}}
10
14
  ```
11
15
 
12
- Documentation:
16
+ Use the global api object to make calls to the API.
17
+ You may use top level `await`.
13
18
 
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
- ```
19
+ If needed, gather any information you need to complete the request.
20
+ You may use `runCode` to run any non-destructive API calls to understand what you need to do. Nothing will be returned unless you `console.log` it.
21
+ In your code, `console.log` and `console.error` can be used to understand the execution or indicate that an error happened, but debug logs should be removed in the final version.
22
+ You can use the `checkCode` tool to confirm that the code passes the typescript compilation and doesn't have errors
23
+ You can call `submitCode` to submit the final version of the code.
24
+
25
+ ---
26
26
 
27
27
  {{DOCUMENTATION}}
28
28
 
29
- Contextual data:
30
- ```
31
29
  {{CONTEXT}}
32
- ```
30
+