aimyapi 0.1.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.
Files changed (41) hide show
  1. package/.prettierrc +3 -0
  2. package/LICENSE +21 -0
  3. package/README.md +197 -0
  4. package/dist/example/example1.d.ts +1 -0
  5. package/dist/example/example1.js +52 -0
  6. package/dist/example/example2.d.ts +1 -0
  7. package/dist/example/example2.js +66 -0
  8. package/dist/example/example3.d.ts +1 -0
  9. package/dist/example/example3.js +79 -0
  10. package/dist/example/ordering_api.d.ts +36 -0
  11. package/dist/example/ordering_api.js +125 -0
  12. package/dist/example/ordering_api_impl.d.ts +23 -0
  13. package/dist/example/ordering_api_impl.js +128 -0
  14. package/dist/example/sales_api.d.ts +16 -0
  15. package/dist/example/sales_api.js +5 -0
  16. package/dist/example/sales_api_impl.d.ts +7 -0
  17. package/dist/example/sales_api_impl.js +59 -0
  18. package/dist/lib/index.d.ts +26 -0
  19. package/dist/lib/index.js +179 -0
  20. package/dist/lib/sandbox-wrappers.d.ts +9 -0
  21. package/dist/lib/sandbox-wrappers.js +237 -0
  22. package/dist/lib/sandbox.d.ts +14 -0
  23. package/dist/lib/sandbox.js +161 -0
  24. package/dist/lib/utils.d.ts +1 -0
  25. package/dist/lib/utils.js +7 -0
  26. package/example/example1.ts +33 -0
  27. package/example/example2.ts +50 -0
  28. package/example/example3.ts +64 -0
  29. package/example/ordering_api.md +106 -0
  30. package/example/ordering_api.ts +194 -0
  31. package/example/ordering_api_impl.ts +194 -0
  32. package/example/sales_api.md +15 -0
  33. package/example/sales_api.ts +29 -0
  34. package/example/sales_api_impl.ts +60 -0
  35. package/lib/index.ts +247 -0
  36. package/lib/sandbox-wrappers.ts +250 -0
  37. package/lib/sandbox.ts +184 -0
  38. package/lib/utils.ts +3 -0
  39. package/package.json +41 -0
  40. package/prompts/create-task-prompt.md +21 -0
  41. package/tsconfig.json +12 -0
package/.prettierrc ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "useTabs": true
3
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 WhiteNoise
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # AI My API
2
+
3
+ Build AI assistants that use your API's and respond to natural language queries by writing small programs that are executed in a [QuickJS](https://github.com/justjake/quickjs-emscripten) sandbox.
4
+ AIMyAPI writes the glue between your various API functions unlocking new functionality without having to write any code. With the right building blocks, AIMyAPI can even invent new functionality you didn't originally plan for -
5
+ for example, being able to sort or filter your data in new ways, email or text yourself results, or combine the results of different operations and API's.
6
+
7
+ Uses the OpenAI API and requires an API key.
8
+
9
+ ## Quickstart
10
+ Simply define your strongly-typed typescript API:
11
+
12
+ `sales_api.ts`
13
+ ```
14
+ // Sales data for each month, per business unit
15
+ export interface SalesData {
16
+ sales: number;
17
+ month: number; // 1...12
18
+ year: number;
19
+ businessUnit: "Advertising" | "Hardware" | "Software";
20
+ }
21
+
22
+ export interface APIInterface {
23
+ sendEmail(to: string, subject: string, body: string): Promise<void>;
24
+
25
+ getSalesData(): SalesData[];
26
+ // Returns an array of sales data.
27
+
28
+ print(text: string): void;
29
+ // Prints the specified text to the user.
30
+
31
+ delay(milliseconds: number): Promise<void>;
32
+ // waits for the specified number of milliseconds before resolving the promise.
33
+ };
34
+
35
+ // Global object you will use for accessing the APIInterface
36
+ declare global {
37
+ var api: APIInterface;
38
+ }
39
+
40
+ ```
41
+
42
+ Implement it:
43
+ ```
44
+ export class API implements APIInterface {
45
+
46
+ sendEmail(to: string, subject: string, body: string): Promise<void> {
47
+ ...
48
+ ```
49
+
50
+ Instantiate your api and AIMyAPI. AIMyAPI will wrap your API so that it can be called from within the QuickJS sandbox.
51
+
52
+ ```
53
+ const api = new API();
54
+
55
+ const aimyapi = await AIMyAPI.createWithAPI({
56
+ apiObject: api,
57
+ apiExports: APIExports,
58
+ apiDefFilePath: path.join(__dirname, "./sales_api.ts"),
59
+ apiDocsPath: path.join(__dirname, "./sales_api.md"),
60
+ })
61
+ ```
62
+
63
+ And now you can make requests against the API in natural language.
64
+ Any code generated by the LLM will be run within the sandbox. The LLM will ONLY have access to functions provided within your API and cannot use javascript to make http requests etc.
65
+
66
+ ```
67
+ await aimyapi.processRequest("Which business unit had the highest sales in 2020?");
68
+ ```
69
+
70
+ This would produce the following code generated by the LLM prompt, which is run in the sandbox and makes calls on your API object:
71
+
72
+ ```
73
+ import * as ApiDefs from './api.ts'
74
+ (async() => {
75
+ try {
76
+ let salesData = api.getSalesData();
77
+ let maxSales = 0;
78
+ let businessUnitWithMaxSales = "";
79
+ for (let i = 0; i < salesData.length; i++) {
80
+ if (salesData[i].year === 2020 && salesData[i].sales > maxSales) {
81
+ maxSales = salesData[i].sales;
82
+ businessUnitWithMaxSales = salesData[i].businessUnit;
83
+ }
84
+ }
85
+ api.print(\`The business unit with the highest sales in 2020 was ${businessUnitWithMaxSales}.\`);
86
+ } catch(e) {
87
+ console.error(e);
88
+ }
89
+ })();
90
+ ```
91
+
92
+ This example does not take advantage of the chat history and treats every request as a fresh chat. See `example2` for a more complex example that uses the chat history.
93
+
94
+ APIs should be kept simple and understandable. If you have a complicated API you may want to write a facade for it.
95
+
96
+ ## Advantages and disadvantages of generating code
97
+
98
+ Currently there is a lot of hype around "agents" - while agents are extremely cool they have a couple drawbacks vs. the code generation approach that AIMyAPI uses to do some of the same things.
99
+
100
+ **Advantages of AIMyAPI over the Agent (haystack) approach:**
101
+
102
+ - Open AI's LLMs today are already really good at writing code, but not necessarily trained on the 'haystack' approach.
103
+ - Data from your API can be kept private as long as you don't add it to the chat history or the prompt. The LLM is writing the operations to manipulate the data but doesn't need to see the data itself to do that.
104
+ - Writing code means that AIMyAPI can do math and algorithms out of the box - something LLMs by themselves struggle at. For instance, asking it to do a simple calculation will result in it writing code to do the calculation. Agents can do this using 'tools', but that means you need to do the work to implement and explain these tools wheras they come built-in in a programming language.
105
+ - Agents typically only do one thing at a time and require several OpenAI API calls to do a single loop. AIMyAPI can write an entire program that does several things in one shot.
106
+
107
+
108
+ **Disadvantages:**
109
+
110
+ - This is not an iterative approach: AIMyAPI must have a full understanding of the problem and the API in order write code against it.
111
+ - It is not currently set up to be able to troubleshoot or fix it's own code (this may be possible)
112
+ - Limits on the context for OpenAI's LLMs mean you can't have a super big API (maybe GPT4 will make this a non-issue).
113
+
114
+ ## installation
115
+
116
+ ```
117
+ npm install
118
+ ```
119
+
120
+ create a .env file in the root of your project
121
+ add your open ai key:
122
+ ```
123
+ OPENAI_API_KEY=XXXXXXXX
124
+ ```
125
+
126
+ ## Examples
127
+
128
+ A simple api example where the LLM allows you to ask questions and compute things about a dataset
129
+ ```
130
+ npm run example1
131
+ ```
132
+
133
+ A more complex food ordering example which incorporates chat history
134
+
135
+ ```
136
+ npm run example2
137
+ ```
138
+
139
+ Interactive ordering example (same api as example2)
140
+
141
+ ```
142
+ npm run example3
143
+ ```
144
+
145
+ ## Providing examples
146
+
147
+ Providing examples is super important.
148
+ We recommend that you instruct the LLM to return a self executing async function enclosed in \`\`\` with no other commentary. See the `example/ordering_api.md` for reference.
149
+ It's recommended that you provide at least one example and no other commentary from the assistant, otherwise the LLM's responses will vary pretty widely and probably be unusable.
150
+ GPT3.5-turbo also has tendency to respond in words even after being instructed to respond only with code. Examples help alleviate this problem.
151
+
152
+ **Sample example**:
153
+
154
+ ```
155
+ Examples of how you should respond:
156
+
157
+ user: How are you today?
158
+
159
+ assistant:
160
+ \`\`\`
161
+ import * as ApiDefs from './api.ts'
162
+ (async() {
163
+ try {
164
+ api.print("I'm great, thanks for asking!");
165
+ } catch(e) {
166
+ console.error(e);
167
+ }
168
+ })();
169
+ \`\`\`
170
+ ```
171
+
172
+ Aside from the code generation piece, documenting your API with clearly named functions and comments is important so that the LLM understands how it can be used. A big part of using AIMyAPI is testing out usecases and looking at the code that is generated. Problems can be solved by how you name your api, comments in the api, and examples.
173
+
174
+ ## A note about history
175
+
176
+ If you plan to use history, it is vital that you include the generated code in the history. Otherwise, the LLM will start to think that it doesn't need to generate code.
177
+
178
+ In example2, note that responses to the user and relevant information is also added to the history so that the LLM can reference it for future queries.
179
+
180
+ ## Safety notes:
181
+
182
+ - If the user is giving sensitive information in a query, that information isn't private. Refer to the OpenAI policies and plan accordingly.
183
+ - The LLM will do stupid things with your API. You should idiot proof your functions, make sure you sanity check any inputs, etc.
184
+ - Even though we are running the code in sandbox, you should still treat anything coming back from the LLM as untrusted code.
185
+ - You should never give the LLM access to anything mission critical through your API such as live production data or services.
186
+ - Give as few permissions as is necessary - read only access would be preferred.
187
+ - Users can trick the LLM to do things that you may not want or intend. Again, access controls are critical. You shouldn't let users access anything they wouldn't normally be able to access via your API.
188
+ - Any 'dangerous' operations should involve some kind of human oversight and approval.
189
+ - A way to audit and rollback anything the LLM does would be wise. The LLM can misunderstand requests due to false assumptions or incomplete information (or trickery). If you allow it to modify your data it could mess things up.
190
+ - By using this library you acknowledge that you take full responsibility for anything that happens as a result of it's use. We cannot gaurantee what will happen based on your instructions to the LLM or how the LLM interprets them etc.
191
+
192
+ ## Thoughts:
193
+
194
+ Could fine tuning on our API and examples allow us to make the prompt smaller? We can only fine tune on the base models though, so we can't use the cheaper gpt3.5-turbo model.
195
+ Could a smaller / more efficient LLM focused on coding tasks work for this usecase?
196
+
197
+
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const lib_1 = __importDefault(require("../lib"));
30
+ const sales_api_impl_1 = require("./sales_api_impl");
31
+ const APIExports = __importStar(require("./sales_api"));
32
+ const path_1 = __importDefault(require("path"));
33
+ // Simpler example using no support for chat history;
34
+ (async () => {
35
+ const api = new sales_api_impl_1.API();
36
+ const aimyapi = await lib_1.default.createWithAPI({
37
+ apiObject: api,
38
+ apiGlobalName: "api",
39
+ apiExports: APIExports,
40
+ apiDefFilePath: path_1.default.join(__dirname, "./sales_api.ts"),
41
+ apiDocsPath: path_1.default.join(__dirname, "./sales_api.md"),
42
+ debug: false,
43
+ });
44
+ console.log("Print 'hello' three times.");
45
+ await aimyapi.processRequest("Print 'hello' three times.");
46
+ console.log("What was our best month in 2020");
47
+ await aimyapi.processRequest("What was our best month in 2020");
48
+ console.log("Which business unit had the highest sales in 2020?");
49
+ await aimyapi.processRequest("Which business unit had the highest sales in 2020?");
50
+ console.log("Compute the total sales for each month in 2020 then email the top 3 to test@email.com");
51
+ await aimyapi.processRequest("Compute the total sales for each month in 2020 then email the top 3 to test@email.com");
52
+ })();
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const lib_1 = __importDefault(require("../lib"));
30
+ const ordering_api_impl_1 = require("./ordering_api_impl");
31
+ const APIExports = __importStar(require("./ordering_api"));
32
+ const path_1 = __importDefault(require("path"));
33
+ // More complex fast food ordering example that uses chat history.
34
+ // Fast food ordering example.
35
+ (async () => {
36
+ const api = new ordering_api_impl_1.OrderingAPI();
37
+ const aimyapi = await lib_1.default.createWithAPI({
38
+ apiObject: api,
39
+ apiGlobalName: "orderingApi",
40
+ apiExports: APIExports,
41
+ apiDefFilePath: path_1.default.join(__dirname, "./ordering_api.ts"),
42
+ apiDocsPath: path_1.default.join(__dirname, "./ordering_api.md"),
43
+ debug: false,
44
+ });
45
+ async function runQuery(query) {
46
+ console.log(`Query: ${query}`);
47
+ // generate the code for this query
48
+ const code = await aimyapi.generateCode(query, api._getHistory());
49
+ api._addMessageToHistory({
50
+ content: query,
51
+ role: "user",
52
+ name: "user",
53
+ });
54
+ api._addMessageToHistory({
55
+ content: '```\n' + code + '\n```',
56
+ role: "assistant",
57
+ name: "assistant",
58
+ });
59
+ // run the code in the sandbox
60
+ await aimyapi.runCode(code);
61
+ }
62
+ await runQuery("How's the burger here?");
63
+ await runQuery("I'd like a plain hamburger and a large fries, a pizza with anchovies and a cola. I'd also like a cheese burger with bacon and avocado.");
64
+ await runQuery("I changed my mind, instead of anchovies, can I get a large gluten free pizza with pineapple instead.");
65
+ await runQuery("email me the total at myemail@test.com and complete the order");
66
+ })();
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const lib_1 = __importDefault(require("../lib"));
30
+ const ordering_api_impl_1 = require("./ordering_api_impl");
31
+ const APIExports = __importStar(require("./ordering_api"));
32
+ const path_1 = __importDefault(require("path"));
33
+ const readline_1 = __importDefault(require("readline"));
34
+ function getInput(query) {
35
+ const rl = readline_1.default.createInterface({
36
+ input: process.stdin,
37
+ output: process.stdout,
38
+ });
39
+ return new Promise(resolve => rl.question(query, ans => {
40
+ rl.close();
41
+ resolve(ans);
42
+ }));
43
+ }
44
+ // More complex fast food ordering example that uses chat history.
45
+ // Fast food ordering example.
46
+ // Interactive version
47
+ (async () => {
48
+ const api = new ordering_api_impl_1.OrderingAPI();
49
+ const aimyapi = await lib_1.default.createWithAPI({
50
+ apiObject: api,
51
+ apiGlobalName: "orderingApi",
52
+ apiExports: APIExports,
53
+ apiDefFilePath: path_1.default.join(__dirname, "./ordering_api.ts"),
54
+ apiDocsPath: path_1.default.join(__dirname, "./ordering_api.md"),
55
+ debug: false,
56
+ });
57
+ async function runQuery(query) {
58
+ console.log(`Query: ${query}`);
59
+ // generate the code for this query
60
+ const code = await aimyapi.generateCode(query, api._getHistory());
61
+ api._addMessageToHistory({
62
+ content: query,
63
+ role: "user",
64
+ name: "user",
65
+ });
66
+ api._addMessageToHistory({
67
+ content: '```\n' + code + '\n```',
68
+ role: "assistant",
69
+ name: "assistant",
70
+ });
71
+ // run the code in the sandbox
72
+ await aimyapi.runCode(code);
73
+ }
74
+ console.log("Welcome to the restaurant. You can ask to hear the menu or order something. What would you like to do?");
75
+ while (!api._isCompleted) {
76
+ const query = await getInput("Your query: ");
77
+ await runQuery(query);
78
+ }
79
+ })();
@@ -0,0 +1,36 @@
1
+ export declare const API_VERSION = "1.0.1";
2
+ export interface Customization {
3
+ name: string;
4
+ priceAdjustment: number;
5
+ }
6
+ export interface MenuItemBase {
7
+ orderId?: string;
8
+ name: string;
9
+ price: number;
10
+ description: string;
11
+ category: string;
12
+ tags: string[];
13
+ customizations: Customization[];
14
+ readonly allowedCustomizations: Customization[];
15
+ toppings: string[];
16
+ readonly allowedToppings: string[];
17
+ }
18
+ export declare const Menu: MenuItemBase[];
19
+ export interface OrderingAPIInterface {
20
+ sendEmail(to: string, subject: string, body: string): Promise<void>;
21
+ getCurrentOrder(): MenuItemBase[];
22
+ getItemInOrder(itemOrderId: string): MenuItemBase | undefined;
23
+ getCustomizationByName(itemName: string, name: string): Customization | undefined;
24
+ addItemToOrder(itemName: string, customizationNames: string[], toppings: string[]): void;
25
+ removeItemFromOrder(itemOrderId: string): void;
26
+ modifyItemInOrder(itemOrderId: string, customizationNames: string[], toppings: string[]): void;
27
+ getOrderTotal(): number;
28
+ completeOrder(): void;
29
+ respondToUser(text: string): void;
30
+ delay(milliseconds: number): Promise<void>;
31
+ displayItem(item: MenuItemBase): void;
32
+ displayOrder(): void;
33
+ }
34
+ declare global {
35
+ var orderingApi: OrderingAPIInterface;
36
+ }
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Menu = exports.API_VERSION = void 0;
4
+ exports.API_VERSION = "1.0.1";
5
+ exports.Menu = [
6
+ {
7
+ "name": "Pizza",
8
+ "price": 10.99,
9
+ "description": "A classic pizza with your choice of toppings.",
10
+ "category": "Pizza",
11
+ "tags": [
12
+ "cheese",
13
+ "pizza"
14
+ ],
15
+ "customizations": [],
16
+ "allowedCustomizations": [
17
+ {
18
+ "name": "Extra Cheese",
19
+ "priceAdjustment": 1.99
20
+ },
21
+ {
22
+ "name": "Extra Sauce",
23
+ "priceAdjustment": 0.99
24
+ },
25
+ {
26
+ "name": "Gluten Free Crust",
27
+ "priceAdjustment": 2.99
28
+ },
29
+ {
30
+ "name": "Large",
31
+ "priceAdjustment": 3.99
32
+ }
33
+ ],
34
+ "toppings": [],
35
+ "allowedToppings": [
36
+ "pepperoni",
37
+ "sausage",
38
+ "mushrooms",
39
+ "onions",
40
+ "green peppers",
41
+ "black olives",
42
+ "green olives",
43
+ "anchovies",
44
+ "pineapple",
45
+ "ham",
46
+ "bacon",
47
+ "chicken",
48
+ ]
49
+ },
50
+ {
51
+ "name": "Hamburger",
52
+ "price": 8.99,
53
+ "description": "A classic american hamburger with your choice of toppings. Cheese, lettuce, tomato, and onion are included by default. Other toppings available on request.",
54
+ "category": "Burgers",
55
+ "tags": [
56
+ "hamburger",
57
+ "burger"
58
+ ],
59
+ "customizations": [],
60
+ "allowedCustomizations": [
61
+ {
62
+ "name": "Special sauce",
63
+ "priceAdjustment": 1.99
64
+ }
65
+ ],
66
+ "toppings": [],
67
+ "allowedToppings": [
68
+ "cheese",
69
+ "lettuce",
70
+ "tomato",
71
+ "onion",
72
+ "pickles",
73
+ "bacon",
74
+ "mushrooms",
75
+ "avocado",
76
+ "jalapenos",
77
+ ],
78
+ },
79
+ {
80
+ "name": "Fries",
81
+ "price": 2.99,
82
+ "description": "A classic side of fries.",
83
+ "category": "Sides",
84
+ "tags": [
85
+ "fries",
86
+ "french fries"
87
+ ],
88
+ "customizations": [],
89
+ "allowedCustomizations": [
90
+ {
91
+ "name": "Large",
92
+ "priceAdjustment": 1.99
93
+ },
94
+ ],
95
+ "toppings": [],
96
+ "allowedToppings": [
97
+ "old bay",
98
+ ]
99
+ },
100
+ {
101
+ "name": "Fountain Drink",
102
+ "price": 1.99,
103
+ "description": "A classic fountain drink. Choose from Cola, Diet Cola, Dr. Dazzle, or Mountain Rush.",
104
+ "category": "Drinks",
105
+ "tags": [
106
+ "drink",
107
+ "soda",
108
+ "fountain drink"
109
+ ],
110
+ "customizations": [],
111
+ "allowedCustomizations": [
112
+ {
113
+ "name": "Large",
114
+ "priceAdjustment": 0.99
115
+ },
116
+ {
117
+ "name": "Extra Ice",
118
+ "priceAdjustment": 0.99
119
+ },
120
+ ],
121
+ "toppings": [],
122
+ "allowedToppings": []
123
+ }
124
+ ];
125
+ ;
@@ -0,0 +1,23 @@
1
+ import { ChatCompletionRequestMessage } from "openai";
2
+ import { Customization, MenuItemBase, OrderingAPIInterface } from "./ordering_api";
3
+ export declare class OrderingAPI implements OrderingAPIInterface {
4
+ private _order;
5
+ private _lastOrderIdNumber;
6
+ _isCompleted: boolean;
7
+ private _history;
8
+ sendEmail(to: string, subject: string, body: string): Promise<void>;
9
+ respondToUser(text: string): void;
10
+ delay(milliseconds: number): Promise<void>;
11
+ getCurrentOrder(): MenuItemBase[];
12
+ getCustomizationByName(itemName: string, name: string): Customization | undefined;
13
+ addItemToOrder(itemName: string, customizationNames: string[], toppings: string[]): void;
14
+ getItemInOrder(itemOrderId: string): MenuItemBase;
15
+ removeItemFromOrder(itemOrderId: string): void;
16
+ modifyItemInOrder(itemOrderId: string, customizationNames: string[], toppings: string[]): void;
17
+ getOrderTotal(): number;
18
+ completeOrder(): void;
19
+ displayItem(item: MenuItemBase): void;
20
+ displayOrder(): void;
21
+ _addMessageToHistory(message: ChatCompletionRequestMessage): void;
22
+ _getHistory(): ChatCompletionRequestMessage[];
23
+ }