aimyapi 0.2.1 → 1.0.3

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.
@@ -1,19 +1,22 @@
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
+
1
3
  import path from "path";
2
- import { AIMyAPI, GenerateCodeResult } from "../src";
3
- import * as APIExports from "./ordering_api";
4
+ import { AIMyAPI } from "../src";
5
+ import { Menu } from "./ordering_api";
4
6
  import { OrderingAPI } from "./ordering_api_impl";
5
7
 
6
8
  // More complex fast food ordering example that uses chat history.
7
9
  // Fast food ordering example.
8
10
 
9
- // IDEA: If the order history becomes too long, we could summarize it by listing the current order state and remove the rest.
10
11
  (async () => {
11
- const api = new OrderingAPI();
12
+ const orderingApi = new OrderingAPI();
12
13
 
13
14
  const options = {
14
- apiObject: api,
15
+ apiObject: orderingApi,
15
16
  apiGlobalName: "orderingApi", // Should match whatever you declared as your global in your ordering api.
16
- apiExports: APIExports,
17
+ apiGlobals: {
18
+ Menu: Menu,
19
+ },
17
20
  apiDefFilePath: path.join(__dirname, "./ordering_api.ts"),
18
21
  apiDocsPath: path.join(__dirname, "./ordering_api.md"),
19
22
  debug: false,
@@ -24,22 +27,29 @@ import { OrderingAPI } from "./ordering_api_impl";
24
27
  console.log(`Query: ${query}`)
25
28
 
26
29
  // generate the code for this query
27
- const codeResult:GenerateCodeResult = await aimyapi.generateCode(query, api._getHistory());
28
-
29
- api._addMessageToHistory({
30
- content: query,
31
- role: "user",
32
- name: "user",
33
- });
34
-
35
- api._addMessageToHistory({
36
- content: '```\n' + codeResult.loggableCode + '\n```',
37
- role: "assistant",
38
- name: "assistant",
39
- });
40
-
41
- // run the code in the sandbox
42
- await aimyapi.runCode(codeResult.code);
30
+ const codeResult = await aimyapi.generateCode(query, orderingApi._getHistory());
31
+
32
+ if(codeResult) {
33
+ orderingApi._addMessageToHistory({
34
+ content: query,
35
+ role: "user",
36
+ name: "user",
37
+ });
38
+
39
+ orderingApi._addMessageToHistory({
40
+ content: codeResult.comments || "done",
41
+ role: "assistant",
42
+ name: "assistant",
43
+ });
44
+
45
+ // run the code in the sandbox
46
+ if(codeResult.code) {
47
+ await aimyapi.runCode(codeResult.code);
48
+ }
49
+ } else {
50
+ console.error("No code generated for this query.");
51
+ }
52
+
43
53
  }
44
54
 
45
55
  await runQuery("How's the burger here?");
@@ -1,12 +1,12 @@
1
1
 
2
2
  import path from "path";
3
3
  import { AIMyAPI } from "../src";
4
- import * as APIExports from "./ordering_api";
4
+ import { Menu } from "./ordering_api";
5
5
  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,14 +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
- apiExports: APIExports,
30
+ apiGlobals: {
31
+ Menu: Menu,
32
+ },
31
33
  apiDefFilePath: path.join(__dirname, "./ordering_api.ts"),
32
34
  apiDocsPath: path.join(__dirname, "./ordering_api.md"),
33
35
  debug: false,
@@ -38,26 +40,30 @@ function getInput(query): Promise<string> {
38
40
  console.log(`Query: ${query}`)
39
41
 
40
42
  // generate the code for this query
41
- const result = await aimyapi.generateCode(query, api._getHistory());
43
+ const result = await aimyapi.generateCode(query, orderingApi._getHistory());
42
44
 
43
- api._addMessageToHistory({
44
- content: query,
45
- role: "user",
46
- name: "user",
47
- });
45
+ if(result) {
46
+ orderingApi._addMessageToHistory({
47
+ content: query,
48
+ role: "user",
49
+ name: "user",
50
+ });
48
51
 
49
- api._addMessageToHistory({
50
- content: '```\n' + result.code.replace(options.apiDefFilePath, "./api.ts") + '\n```',
51
- role: "assistant",
52
- name: "assistant",
53
- });
52
+ orderingApi._addMessageToHistory({
53
+ content: result.comments || "done",
54
+ role: "assistant",
55
+ name: "assistant",
56
+ });
54
57
 
55
- // run the code in the sandbox
56
- await aimyapi.runCode(result.code);
58
+ // run the code in the sandbox
59
+ if(result.code) {
60
+ await aimyapi.runCode(result.code);
61
+ }
62
+ }
57
63
  }
58
64
 
59
65
  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) {
66
+ while (!orderingApi._isCompleted) {
61
67
  const query:string = await getInput("Your query: ");
62
68
  await runQuery(query);
63
69
  }
@@ -1,24 +1,26 @@
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
+ code:
14
+ ```typescript
13
15
  orderingApi.respondToUser("I'm great, thanks for asking!");
14
16
  ```
15
17
 
16
18
  user: Add a hamburger with no cheese to my order
17
19
 
18
- assistant:
19
- ```
20
+ code:
21
+ ```typescript
20
22
  const itemName = "Hamburger";
21
- const item = ApiDefs.Menu.find((item) => item.name === itemName);
23
+ const item = Menu.find((item) => item.name === itemName);
22
24
  if (!item) {
23
25
  throw new Error(`Item with name "${itemName}" not found`);
24
26
  }
@@ -31,18 +33,18 @@ log: Added Hamburger with id 1
31
33
 
32
34
  user: I'd like a large pizza with mushrooms
33
35
 
34
- assistant:
35
- ```
36
+ code:
37
+ ```typescript
36
38
  orderingApi.addItemToOrder("Pizza", ["Large"], ["mushrooms"]);
37
39
  orderingApi.respondToUser("Ok, I added a Large Pizza with mushrooms");
38
40
  ```
39
41
 
40
42
  user: Add a hamburger with bacon
41
43
 
42
- assistant:
43
- ```
44
+ code:
45
+ ```typescript
44
46
  const itemName = "Hamburger";
45
- const item = ApiDefs.Menu.find((item) => item.name === itemName);
47
+ const item = Menu.find((item) => item.name === itemName);
46
48
  if (!item) {
47
49
  throw new Error(`Item with name "${itemName}" not found`);
48
50
  }
@@ -55,8 +57,8 @@ log: Added Hamburger with id 2
55
57
 
56
58
  user: Add jalapenos to that
57
59
 
58
- assistant:
59
- ```
60
+ code:
61
+ ```typescript
60
62
  const existingItem = orderingApi.getItemInOrder("2");
61
63
 
62
64
  if(existingItem) {
@@ -69,10 +71,10 @@ if(existingItem) {
69
71
 
70
72
  user: Add a hamburger with no lettuce
71
73
 
72
- assistant:
73
- ```
74
+ code:
75
+ ```typescript
74
76
  const itemName = "Hamburger";
75
- const item = ApiDefs.Menu.find((item) => item.name === itemName);
77
+ const item = Menu.find((item) => item.name === itemName);
76
78
  if (!item) {
77
79
  throw new Error(`Item with name "${itemName}" not found`);
78
80
  }
@@ -86,7 +88,7 @@ log: Added Hamburger with id 2
86
88
 
87
89
  user: I want an elephant.
88
90
 
89
- assistant:
90
- ```
91
+ code:
92
+ ```typescript
91
93
  orderingApi.respondToUser("I'm sorry, but that isn't on our menu.");
92
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,10 +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
- api.print("I'm great, thanks for asking!");
10
- ```
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.1",
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.3",
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
+