aimyapi 0.1.13 → 0.1.15

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
@@ -1,176 +1,492 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generateCode = exports.createBasePrompt = void 0;
7
- require('dotenv').config();
8
- const fs_1 = __importDefault(require("fs"));
9
- const openai_1 = require("openai");
10
- const path_1 = __importDefault(require("path"));
11
- const sandbox_1 = __importDefault(require("./sandbox"));
12
- const sandbox_wrappers_1 = require("./sandbox-wrappers");
13
- const quickjs_emscripten_1 = require("quickjs-emscripten");
14
- const configuration = new openai_1.Configuration({
15
- apiKey: process.env.OPENAI_API_KEY,
16
- });
17
- const openai = new openai_1.OpenAIApi(configuration);
18
- // function formatObject(obj: any): string {
19
- // return Object.keys(obj).reduce((acc, key) => {
20
- // return `${acc}${key}:\n${obj[key]}\n\n`;
21
- // }, "");
22
- // }
23
- function createBasePrompt(apiFilePath, documentationPath) {
24
- const apiText = fs_1.default.readFileSync(apiFilePath, 'utf8');
25
- const documentationText = documentationPath ? fs_1.default.readFileSync(documentationPath, 'utf8') : '';
26
- //console.time("Loading templates");
27
- const createTaskPrompt = fs_1.default.readFileSync(path_1.default.join(__dirname, '../prompts/create-task-prompt.md'), 'utf8').replace("{{DOCUMENTATION}}", documentationText).replace("{{API}}", apiText);
28
- //console.timeEnd("Loading templates")
29
- return createTaskPrompt;
1
+ 'use strict';
2
+
3
+ var module$1 = require('module');
4
+ var fs = require('fs');
5
+ var openai$1 = require('openai');
6
+ var path = require('path');
7
+ var quickjsEmscripten = require('quickjs-emscripten');
8
+ var ts = require('typescript');
9
+
10
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
11
+ function _interopNamespaceDefault(e) {
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ n.default = e;
25
+ return Object.freeze(n);
30
26
  }
31
- exports.createBasePrompt = createBasePrompt;
32
- // FIXME: add an options parameter and allow specifying the token limit
33
- const generateCode = async function (queryText, userChatHistory, createTaskPrompt, apiPath, debug = false, model = "gpt-4o") {
34
- if (!queryText)
35
- return { code: '', loggableCode: '' };
36
- let generatedCode = '';
37
- const prompt = createTaskPrompt.replace("{{QUERY_TEXT}}", queryText);
38
- const messages = [
39
- {
40
- role: "system",
41
- content: prompt,
42
- },
43
- ...userChatHistory,
44
- {
45
- role: "user",
46
- content: `${queryText}.\nRespond only with code enclosed in \`\`\`.`,
47
- name: "user"
48
- }
49
- ];
27
+
28
+ var ts__namespace = /*#__PURE__*/_interopNamespaceDefault(ts);
29
+
30
+ var require$1 = (
31
+ false
32
+ ? /* @__PURE__ */ module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)))
33
+ : require
34
+ );
35
+
36
+ let promiseId = 0;
37
+ let openPromises = {};
38
+ function wrapPromise(vm, promise, beginAsyncProcess, endAsyncProcess) {
39
+ promiseId += 1;
40
+ const vmPromise = vm.newPromise();
41
+ vmPromise._promiseId = promiseId;
42
+ beginAsyncProcess();
43
+ promise.then((...args) => {
44
+ endAsyncProcess();
45
+ const wrappedArgs = args.map((arg) => wrap(vm, arg, void 0, beginAsyncProcess, endAsyncProcess));
46
+ openPromises[vmPromise._promiseId] = null;
47
+ vmPromise.resolve(...wrappedArgs);
48
+ wrappedArgs.forEach((arg) => arg.dispose());
49
+ }).catch((...args) => {
50
+ const wrappedArgs = args.map((arg) => wrap(vm, arg, void 0, beginAsyncProcess, endAsyncProcess));
51
+ vmPromise.reject(...wrappedArgs);
52
+ wrappedArgs.forEach((arg) => arg.dispose());
53
+ openPromises[vmPromise._promiseId] = null;
54
+ });
55
+ vmPromise.settled.then(() => {
56
+ endAsyncProcess();
57
+ vm.runtime.executePendingJobs();
58
+ });
59
+ openPromises[promiseId] = vmPromise;
60
+ return vmPromise.handle;
61
+ }
62
+ function rejectOpenPromises(vm) {
63
+ for (const [id, promise] of Object.entries(openPromises)) {
64
+ if (promise !== null) {
65
+ promise.reject(vm.newError("Shutting down"));
66
+ openPromises[id] = null;
67
+ }
68
+ }
69
+ vm.runtime.executePendingJobs();
70
+ }
71
+ function wrap(vm, value, context, beginAsyncProcess, endAsyncProcess) {
72
+ if (value === null) {
73
+ return null;
74
+ } else if (typeof value === "object" && typeof value.then === "function") {
75
+ return wrapPromise(vm, value, beginAsyncProcess, endAsyncProcess);
76
+ } else if (typeof value === "function") {
77
+ return wrapGenericFunction(vm, value, context, beginAsyncProcess, endAsyncProcess);
78
+ } else if (Array.isArray(value)) {
79
+ return wrapArray(vm, value, beginAsyncProcess, endAsyncProcess);
80
+ } else if (value === null) {
81
+ return vm.null;
82
+ } else if (typeof value === "object") {
83
+ return wrapObject(vm, value, beginAsyncProcess, endAsyncProcess);
84
+ } else if (typeof value === "string") {
85
+ return vm.newString(value);
86
+ } else if (typeof value === "number") {
87
+ return vm.newNumber(value);
88
+ } else if (typeof value === "bigint") {
89
+ return vm.newBigInt(value);
90
+ } else if (typeof value === "boolean") {
91
+ return vm.evalCode(value ? "true" : "false").value;
92
+ } else if (typeof value === "undefined") {
93
+ return vm.undefined;
94
+ } else {
95
+ return null;
96
+ }
97
+ }
98
+ function wrapObject(vm, obj, beginAsyncProcess, endAsyncProcess) {
99
+ const vmObject = vm.newObject();
100
+ for (const [key, value] of Object.entries(obj)) {
101
+ let wrappedValue = wrap(vm, value, obj, beginAsyncProcess, endAsyncProcess);
102
+ if (wrappedValue !== null) {
103
+ vm.setProp(vmObject, key, wrappedValue);
104
+ if (wrappedValue != vm.undefined && wrappedValue != vm.null && wrappedValue.dispose) {
105
+ wrappedValue.dispose();
106
+ }
107
+ }
108
+ }
109
+ return vmObject;
110
+ }
111
+ function wrapObjectWhitelist(vm, obj, whitelist, beginAsyncProcess, endAsyncProcess) {
112
+ const vmObject = vm.newObject();
113
+ whitelist.forEach((key) => {
114
+ const value = obj[key];
115
+ const wrappedValue = wrap(vm, value, obj, beginAsyncProcess, endAsyncProcess);
116
+ if (wrappedValue !== null) {
117
+ vm.setProp(vmObject, key, wrappedValue);
118
+ if (wrappedValue != vm.undefined && wrappedValue != vm.null && wrappedValue.dispose) {
119
+ wrappedValue.dispose();
120
+ }
121
+ }
122
+ });
123
+ return vmObject;
124
+ }
125
+ function wrapArray(vm, arr, beginAsyncProcess, endAsyncProcess) {
126
+ const vmArray = vm.newArray();
127
+ for (let i = 0; i < arr.length; i++) {
128
+ let wrappedValue = wrap(vm, arr[i], arr, beginAsyncProcess, endAsyncProcess);
129
+ vm.setProp(vmArray, i, wrappedValue);
130
+ if (wrappedValue != vm.undefined && wrappedValue != vm.null) {
131
+ wrappedValue.dispose();
132
+ }
133
+ }
134
+ return vmArray;
135
+ }
136
+ function wrapGenericFunction(vm, fn, context = void 0, beginAsyncProcess, endAsyncProcess) {
137
+ const vmFn = vm.newFunction(fn.name, (...args) => {
138
+ const unwrappedArgs = args.map(vm.dump);
50
139
  try {
51
- const results = await openai.createChatCompletion({
52
- model,
53
- messages: messages,
54
- temperature: 0.1,
55
- max_tokens: 700,
56
- });
57
- if (debug)
58
- console.log(results.data.usage);
59
- const response = results.data.choices[0].message.content;
60
- if (debug)
61
- console.log(response);
62
- // Return only the code between ``` and ``` (usually at the end of the completion)
63
- const codeStart = response.indexOf('```');
64
- const codeEnd = response.lastIndexOf('```');
65
- // error, no code detected inside the response
66
- if (codeStart === -1 || codeEnd === -1 || codeStart === codeEnd) {
67
- return { code: '', loggableCode: '', rawResponse: response };
140
+ const result = fn.call(context, ...unwrappedArgs);
141
+ const wrappedResult = wrap(vm, result, void 0, beginAsyncProcess, endAsyncProcess);
142
+ return wrappedResult;
143
+ } catch (e) {
144
+ console.log("Error", e);
145
+ }
146
+ });
147
+ return vmFn;
148
+ }
149
+ function injectTimingFunctions(vm, cbAddedTimer, cbRemovedTimer, maxTimeout = 6e5) {
150
+ const timeoutFunctionHandles = {};
151
+ const _setTimeout = vm.newFunction("setTimeout", (vmFnHandle, timeoutHandle) => {
152
+ const vmFnHandleCopy = vmFnHandle.dup();
153
+ let timeout = vm.dump(timeoutHandle);
154
+ if (timeout > maxTimeout) {
155
+ timeout = maxTimeout;
156
+ }
157
+ cbAddedTimer();
158
+ const timeoutID = setTimeout(() => {
159
+ timeoutFunctionHandles[timeoutID.toString()] = null;
160
+ cbRemovedTimer();
161
+ vm.callFunction(vmFnHandleCopy, vm.undefined);
162
+ vmFnHandleCopy.dispose();
163
+ vm.runtime.executePendingJobs();
164
+ }, timeout);
165
+ timeoutFunctionHandles[timeoutID.toString()] = vmFnHandleCopy;
166
+ return vm.newNumber(timeoutID);
167
+ });
168
+ vm.setProp(vm.global, "setTimeout", _setTimeout);
169
+ _setTimeout.dispose();
170
+ const intervalFunctionHandles = {};
171
+ const _setInterval = vm.newFunction("setInterval", (vmFnHandle, timeoutHandle) => {
172
+ const vmFnHandleCopy = vmFnHandle.dup();
173
+ let timeout = vm.dump(timeoutHandle);
174
+ if (timeout > maxTimeout) {
175
+ timeout = maxTimeout;
176
+ }
177
+ const maxRepetitions = 99;
178
+ let repetitions = 0;
179
+ cbAddedTimer();
180
+ const intervalId = setInterval(() => {
181
+ repetitions += 1;
182
+ intervalFunctionHandles[intervalId.toString()] = null;
183
+ vm.callFunction(vmFnHandleCopy, vm.undefined);
184
+ vm.runtime.executePendingJobs();
185
+ if (repetitions > maxRepetitions) {
186
+ console.log("Sandbox interval exceeded max repetitions");
187
+ clearInterval(intervalId);
188
+ cbRemovedTimer();
189
+ return;
190
+ }
191
+ }, timeout);
192
+ intervalFunctionHandles[intervalId.toString()] = vmFnHandleCopy;
193
+ return vm.newNumber(intervalId);
194
+ });
195
+ vm.setProp(vm.global, "setInterval", _setInterval);
196
+ _setInterval.dispose();
197
+ const _clearTimeout = vm.newFunction("clearTimeout", (timeoutIdHandle) => {
198
+ const timeoutId = vm.dump(timeoutIdHandle);
199
+ const timeoutHandle = timeoutFunctionHandles[timeoutId.toString()];
200
+ if (timeoutHandle) {
201
+ cbRemovedTimer();
202
+ timeoutHandle.dispose();
203
+ clearTimeout(timeoutId);
204
+ }
205
+ });
206
+ vm.setProp(vm.global, "clearTimeout", _clearTimeout);
207
+ _clearTimeout.dispose();
208
+ const _clearInterval = vm.newFunction("clearInterval", (intervalIdHandle) => {
209
+ const intervalId = vm.dump(intervalIdHandle);
210
+ const intervalHandle = intervalFunctionHandles[intervalId.toString()];
211
+ if (intervalId) {
212
+ cbRemovedTimer();
213
+ intervalHandle.dispose();
214
+ clearInterval(intervalId);
215
+ }
216
+ });
217
+ vm.setProp(vm.global, "clearInterval", _clearInterval);
218
+ _clearInterval.dispose();
219
+ }
220
+
221
+ function tsCompile(source, options = null) {
222
+ if (null === options) {
223
+ options = {
224
+ compilerOptions: {
225
+ target: ts__namespace.ScriptTarget.ES2020,
226
+ module: ts__namespace.ModuleKind.None
227
+ }
228
+ };
229
+ }
230
+ return ts__namespace.transpileModule(source, options).outputText;
231
+ }
232
+ async function createSandbox(QuickJS, requireLookup = {}, globals = {}, debug = false) {
233
+ const vm = QuickJS.newContext();
234
+ let errorState = false;
235
+ let lastError = "";
236
+ let asyncProcessesRunning = 0;
237
+ let beginAsyncProcess = () => {
238
+ asyncProcessesRunning++;
239
+ };
240
+ let endAsyncProcess = () => {
241
+ if (asyncProcessesRunning > 0) {
242
+ asyncProcessesRunning--;
243
+ }
244
+ };
245
+ let isAsyncProcessRunning = () => {
246
+ return asyncProcessesRunning > 0;
247
+ };
248
+ const logHandle = vm.newFunction("log", (...args) => {
249
+ const nativeArgs = args.map(vm.dump);
250
+ console.log("QuickJS Log:", ...nativeArgs);
251
+ });
252
+ const consoleHandle = vm.newObject();
253
+ const exportsHandle = vm.newObject();
254
+ const errorHandle = vm.newFunction("error", (...args) => {
255
+ try {
256
+ const nativeArgs = args.map(vm.dump);
257
+ console.log("QuickJS console.error:", ...nativeArgs);
258
+ lastError = JSON.stringify(nativeArgs);
259
+ errorState = true;
260
+ } catch (e) {
261
+ console.log("Error in error:", e);
262
+ }
263
+ });
264
+ const globalNames = Object.getOwnPropertyNames(globals);
265
+ for (let i = 0; i < globalNames.length; i++) {
266
+ const globalOption = globals[globalNames[i]];
267
+ const globalObj = globalOption.whitelist ? wrapObjectWhitelist(
268
+ vm,
269
+ globalOption.value,
270
+ globalOption.whitelist,
271
+ beginAsyncProcess,
272
+ endAsyncProcess
273
+ ) : wrap(vm, globalOption.value, globalOption, beginAsyncProcess, endAsyncProcess);
274
+ vm.setProp(vm.global, globalNames[i], globalObj);
275
+ globalObj.dispose();
276
+ }
277
+ injectTimingFunctions(vm, beginAsyncProcess, endAsyncProcess);
278
+ const requireHandle = vm.newFunction("require", (...args) => {
279
+ const nativeArgs = args.map(vm.dump);
280
+ if (requireLookup[nativeArgs[0]]) {
281
+ const returnObj = wrapObject(vm, requireLookup[nativeArgs[0]], beginAsyncProcess, endAsyncProcess);
282
+ return returnObj;
283
+ } else {
284
+ return vm.undefined;
285
+ }
286
+ });
287
+ vm.setProp(consoleHandle, "log", logHandle);
288
+ vm.setProp(consoleHandle, "error", errorHandle);
289
+ vm.setProp(vm.global, "require", requireHandle);
290
+ vm.setProp(vm.global, "console", consoleHandle);
291
+ vm.setProp(vm.global, "exports", exportsHandle);
292
+ consoleHandle.dispose();
293
+ logHandle.dispose();
294
+ exportsHandle.dispose();
295
+ errorHandle.dispose();
296
+ requireHandle.dispose();
297
+ return {
298
+ vm,
299
+ getLastError: () => {
300
+ return lastError;
301
+ },
302
+ isAsyncProcessRunning,
303
+ runTask: (task) => {
304
+ try {
305
+ const compiled = tsCompile(task);
306
+ if (!compiled || compiled.length === 0) {
307
+ console.error("Could not compile", task);
308
+ return false;
68
309
  }
69
- generatedCode = response.substring(codeStart + 3, codeEnd).replace('typescript', '');
70
- const codeHeader = `import * as ApiDefs from '${apiPath}'\n(async() {\n\ttry {`;
71
- const codeFooter = `\n\t} catch(err) {\n\t\tconsole.error(err);\n\t}\n})();`;
72
- return { code: codeHeader + generatedCode + codeFooter, loggableCode: generatedCode };
310
+ errorState = false;
311
+ const result = vm.evalCode(compiled);
312
+ if (result.error) {
313
+ const lines = compiled.split("\n");
314
+ for (let i = 0; i < lines.length; i++) {
315
+ console.log(`${i + 1}: ${lines[i]}`);
316
+ }
317
+ console.log("Execution failed:", vm.dump(result.error));
318
+ result.error.dispose();
319
+ return false;
320
+ } else {
321
+ result.value.dispose();
322
+ if (errorState) {
323
+ const lines = compiled.split("\n");
324
+ for (let i = 0; i < lines.length; i++) {
325
+ console.log(`${i + 1}: ${lines[i]}`);
326
+ }
327
+ }
328
+ return !errorState;
329
+ }
330
+ } catch (e) {
331
+ console.log(e);
332
+ }
333
+ return false;
334
+ }
335
+ };
336
+ }
337
+
338
+ require$1("dotenv").config();
339
+ const openai = new openai$1.OpenAI({
340
+ apiKey: process.env.OPENAI_API_KEY
341
+ // This is also the default, can be omitted
342
+ });
343
+ function createBasePrompt(apiFilePath, documentationPath) {
344
+ const apiText = fs.readFileSync(apiFilePath, "utf8");
345
+ const documentationText = documentationPath ? fs.readFileSync(documentationPath, "utf8") : "";
346
+ const createTaskPrompt = fs.readFileSync(path.join(__dirname, "../prompts/create-task-prompt.md"), "utf8").replace("{{DOCUMENTATION}}", documentationText).replace("{{API}}", apiText);
347
+ return createTaskPrompt;
348
+ }
349
+ const generateCode = async function(queryText, userChatHistory, createTaskPrompt, apiPath, debug = false, model = "gpt-4o") {
350
+ if (!queryText)
351
+ return { code: "", loggableCode: "" };
352
+ let generatedCode = "";
353
+ const prompt = createTaskPrompt.replace("{{QUERY_TEXT}}", queryText);
354
+ const messages = [
355
+ {
356
+ role: "system",
357
+ content: prompt
358
+ },
359
+ ...userChatHistory,
360
+ {
361
+ role: "user",
362
+ content: `${queryText}.
363
+ Respond only with code enclosed in \`\`\`.`,
364
+ name: "user"
73
365
  }
74
- catch (err) {
75
- console.error(err);
76
- return { code: '', loggableCode: '' };
366
+ ];
367
+ try {
368
+ const results = await openai.chat.completions.create(
369
+ {
370
+ model,
371
+ messages,
372
+ temperature: 0,
373
+ max_tokens: 700
374
+ }
375
+ );
376
+ if (debug)
377
+ console.log(results.usage);
378
+ const response = results.choices[0].message.content;
379
+ if (debug)
380
+ 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 };
77
385
  }
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
+ } catch (err) {
397
+ console.error(err);
398
+ return { code: "", loggableCode: "" };
399
+ }
78
400
  };
79
- exports.generateCode = generateCode;
80
401
  let QuickJS = null;
81
- ;
82
402
  async function createWithAPI(options) {
83
- // extend options with defaults
84
- options = {
85
- apiGlobalName: "api",
86
- apiGlobals: {},
87
- apiWhitelist: Object.getOwnPropertyNames(Object.getPrototypeOf(options.apiObject)).filter((f) => f !== "constructor" && !f.startsWith("_")),
88
- debug: false,
89
- model: "gpt-4o",
90
- ...options
91
- };
92
- if (!options.apiObject || !options.apiDefFilePath) {
93
- throw new Error("apiObject and apiFilePath are required");
94
- }
95
- const { apiObject, apiWhitelist, apiGlobalName, apiExports, apiDefFilePath, apiDocsPath, debug, model } = options;
96
- const createTaskPrompt = createBasePrompt(apiDefFilePath, apiDocsPath);
97
- return {
98
- options,
99
- generateCode: async function (queryText, userChatHistory, currentContext = undefined) {
100
- if (!queryText)
101
- return { code: '', loggableCode: '' };
102
- return await (0, exports.generateCode)(queryText, userChatHistory, createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath, debug, model);
103
- },
104
- runCode: async function (generatedCode) {
105
- if (!QuickJS) {
106
- // Create QuickJS
107
- if (debug)
108
- console.log("Creating quick.js");
109
- QuickJS = await (0, quickjs_emscripten_1.getQuickJS)();
110
- }
111
- let apiGlobals = {};
112
- for (const key in options.apiGlobals) {
113
- apiGlobals[key] = {
114
- value: options.apiGlobals[key],
115
- };
116
- }
117
- // Create sandbox
118
- // NOTE: not sure why I have to replace the backslash here
119
- const { vm, runTask, isAsyncProcessRunning } = await (0, sandbox_1.default)(QuickJS, {
120
- [apiDefFilePath.replaceAll("\\", "")]: apiExports,
121
- }, {
122
- ...apiGlobals,
123
- [apiGlobalName]: {
124
- value: apiObject,
125
- whitelist: apiWhitelist
126
- }
127
- }, options.debug);
128
- try {
129
- if (debug) {
130
- console.log("Running Code:\n", generatedCode);
131
- }
132
- const res = await runTask(generatedCode);
133
- if (!res) {
134
- console.error("Task unsuccessful");
135
- }
136
- while (isAsyncProcessRunning()) {
137
- await new Promise((resolve) => setTimeout(resolve, 100));
138
- }
139
- if (debug) {
140
- console.log("Completed");
141
- }
142
- }
143
- catch (err) {
144
- if (debug) {
145
- console.error("Error running task:", err);
146
- }
147
- }
148
- await new Promise((resolve) => setTimeout(resolve, 100));
149
- (0, sandbox_wrappers_1.rejectOpenPromises)(vm);
150
- vm.dispose();
151
- },
152
- processRequest: async function (userQuery, currentContext = undefined) {
153
- // Create prompt
154
- if (debug) {
155
- console.log("Query:", userQuery);
156
- }
157
- // Generate Code
158
- console.time("Generate Task");
159
- const generatedCode = await (0, exports.generateCode)(userQuery, [], createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath);
160
- console.timeEnd("Generate Task");
161
- console.time("Run Code");
162
- await this.runCode(generatedCode.code);
163
- console.timeEnd("Run Code");
164
- return generatedCode;
403
+ options = {
404
+ apiGlobalName: "api",
405
+ apiGlobals: {},
406
+ apiWhitelist: Object.getOwnPropertyNames(Object.getPrototypeOf(options.apiObject)).filter((f) => f !== "constructor" && !f.startsWith("_")),
407
+ debug: false,
408
+ model: "gpt-4o",
409
+ ...options
410
+ };
411
+ if (!options.apiObject || !options.apiDefFilePath) {
412
+ throw new Error("apiObject and apiFilePath are required");
413
+ }
414
+ const { apiObject, apiWhitelist, apiGlobalName, apiExports, apiDefFilePath, apiDocsPath, debug, model } = options;
415
+ const createTaskPrompt = createBasePrompt(apiDefFilePath, apiDocsPath);
416
+ return {
417
+ options,
418
+ generateCode: async function(queryText, userChatHistory, currentContext = void 0) {
419
+ if (!queryText)
420
+ return { code: "", loggableCode: "" };
421
+ return await generateCode(queryText, userChatHistory, createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath, debug, model);
422
+ },
423
+ runCode: async function(generatedCode) {
424
+ if (!QuickJS) {
425
+ if (debug)
426
+ console.log("Creating quick.js");
427
+ QuickJS = await quickjsEmscripten.getQuickJS();
428
+ }
429
+ let apiGlobals = {};
430
+ for (const key in options.apiGlobals) {
431
+ apiGlobals[key] = {
432
+ value: options.apiGlobals[key]
433
+ };
434
+ }
435
+ const { vm, runTask, isAsyncProcessRunning } = await createSandbox(QuickJS, {
436
+ [apiDefFilePath.replaceAll("\\", "")]: apiExports
437
+ }, {
438
+ ...apiGlobals,
439
+ [apiGlobalName]: {
440
+ value: apiObject,
441
+ whitelist: apiWhitelist
165
442
  }
166
- };
443
+ }, options.debug);
444
+ try {
445
+ if (debug) {
446
+ console.log("Running Code:\n", generatedCode);
447
+ }
448
+ const res = await runTask(generatedCode);
449
+ if (!res) {
450
+ console.error("Task unsuccessful");
451
+ }
452
+ while (isAsyncProcessRunning()) {
453
+ await new Promise((resolve) => setTimeout(resolve, 100));
454
+ }
455
+ if (debug) {
456
+ console.log("Completed");
457
+ }
458
+ } catch (err) {
459
+ if (debug) {
460
+ console.error("Error running task:", err);
461
+ }
462
+ }
463
+ await new Promise((resolve) => setTimeout(resolve, 100));
464
+ rejectOpenPromises(vm);
465
+ vm.dispose();
466
+ },
467
+ processRequest: async function(userQuery, currentContext = void 0) {
468
+ if (debug) {
469
+ console.log("Query:", userQuery);
470
+ }
471
+ console.time("Generate Task");
472
+ const generatedCode = await generateCode(userQuery, [], createTaskPrompt.replace("{{CONTEXT}}", currentContext ? "```" + JSON.stringify(currentContext, null, 2) + "```" : ""), apiDefFilePath);
473
+ console.timeEnd("Generate Task");
474
+ console.time("Run Code");
475
+ await this.runCode(generatedCode.code);
476
+ console.timeEnd("Run Code");
477
+ return generatedCode;
478
+ }
479
+ };
167
480
  }
168
- const aimyapi = {
169
- // Standard way of using the library
170
- createWithAPI,
171
- // functions for customized usage
172
- createBasePrompt,
173
- generateCode: exports.generateCode,
174
- createSandbox: sandbox_1.default,
481
+ const AIMyAPI = {
482
+ // Standard way of using the library
483
+ createWithAPI,
484
+ // functions for customized usage
485
+ createBasePrompt,
486
+ generateCode,
487
+ createSandbox
175
488
  };
176
- exports.default = aimyapi;
489
+
490
+ exports.AIMyAPI = AIMyAPI;
491
+ exports.createBasePrompt = createBasePrompt;
492
+ exports.generateCode = generateCode;