aimyapi 1.0.8 → 1.0.10
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/LICENSE +21 -21
- package/README.md +221 -195
- package/dist/index.cjs +233 -110
- package/dist/index.d.cts +16 -8
- package/dist/index.d.mts +16 -8
- package/dist/index.d.ts +16 -8
- package/dist/index.js +233 -110
- package/dist/index.mjs +235 -112
- package/example/example1.ts +41 -30
- package/example/example2.ts +58 -58
- package/example/example3.ts +69 -69
- package/example/ordering_api.md +94 -94
- package/example/ordering_api.ts +191 -191
- package/example/ordering_api_impl.ts +207 -207
- package/example/sales_api.md +1 -5
- package/example/sales_api.ts +31 -29
- package/example/sales_api_impl.ts +74 -60
- package/package.json +2 -3
- package/prompts/generate-code-prompt.md +37 -0
- package/src/index.ts +79 -55
- package/src/log-tester-inject.ts +233 -0
- package/src/log-tester.ts +185 -0
- package/src/logger.ts +113 -0
- package/src/sandbox-wrappers.ts +296 -249
- package/src/sandbox.ts +35 -58
- package/src/utils.ts +33 -3
- package/tsconfig.json +12 -12
- package/prompts/create-task-prompt.md +0 -37
package/dist/index.cjs
CHANGED
|
@@ -6,7 +6,7 @@ var openai$1 = require('openai');
|
|
|
6
6
|
var quickjsEmscripten = require('quickjs-emscripten');
|
|
7
7
|
var ts = require('typescript');
|
|
8
8
|
var zod = require('zod');
|
|
9
|
-
var
|
|
9
|
+
var path = require('path');
|
|
10
10
|
|
|
11
11
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
12
12
|
function _interopNamespaceDefault(e) {
|
|
@@ -34,23 +34,104 @@ var require$1 = (
|
|
|
34
34
|
: require
|
|
35
35
|
);
|
|
36
36
|
|
|
37
|
+
class Logger {
|
|
38
|
+
constructor(debug = false) {
|
|
39
|
+
this.logs = [];
|
|
40
|
+
this.debug = false;
|
|
41
|
+
this.debug = debug;
|
|
42
|
+
}
|
|
43
|
+
getLogs() {
|
|
44
|
+
return this.logs;
|
|
45
|
+
}
|
|
46
|
+
addEntry(type, args, source) {
|
|
47
|
+
if (Array.isArray(args)) {
|
|
48
|
+
this.logs.push({ type, args, source });
|
|
49
|
+
} else {
|
|
50
|
+
this.logs.push({ type, args: [args], source });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
log(args, source) {
|
|
54
|
+
this.addEntry("log", args, source);
|
|
55
|
+
if (this.debug) {
|
|
56
|
+
console.log(`[${source}]:`, ...args);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
trace(fnName, fnArgs, result) {
|
|
60
|
+
this.logs.push({ type: "trace", fnName, fnArgs, result });
|
|
61
|
+
if (this.debug) {
|
|
62
|
+
console.debug(`[sandbox]: ${fnName}(${fnArgs.map((arg) => JSON.stringify(Logger.limitObjectForLogs(arg))).join(",")}) -> ${JSON.stringify(Logger.limitObjectForLogs(result))}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
error(args, source) {
|
|
66
|
+
this.addEntry("error", args, source);
|
|
67
|
+
if (this.debug) {
|
|
68
|
+
console.error(`[${source}]:`, ...args);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
clear() {
|
|
72
|
+
this.logs = [];
|
|
73
|
+
}
|
|
74
|
+
getPrettyLogs() {
|
|
75
|
+
return this.logs.map((entry) => Logger.limitObjectForLogs(entry));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Returns a trimmed copy of `value` that is safe to log.
|
|
79
|
+
* - Objects/arrays nested deeper than `maxDepth` become "[Object]" / "[Array(n)]".
|
|
80
|
+
* - Arrays longer than `maxArrayItems` keep the first items plus a "+N more items" string.
|
|
81
|
+
* - Circular references become "[Circular]".
|
|
82
|
+
*/
|
|
83
|
+
static limitObjectForLogs(value, maxDepth = 3, maxArrayItems = 5) {
|
|
84
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
85
|
+
const trim = (val, depth) => {
|
|
86
|
+
if (val === null || typeof val !== "object") {
|
|
87
|
+
if (typeof val === "function") return `[Function${val.name ? `: ${val.name}` : ""}]`;
|
|
88
|
+
if (typeof val === "bigint") return `${val}n`;
|
|
89
|
+
if (typeof val === "symbol") return val.toString();
|
|
90
|
+
return val;
|
|
91
|
+
}
|
|
92
|
+
if (val instanceof Date) return val.toISOString();
|
|
93
|
+
if (val instanceof Error) {
|
|
94
|
+
return { name: val.name, message: val.message, stack: val.stack };
|
|
95
|
+
}
|
|
96
|
+
if (seen.has(val)) return "[Circular]";
|
|
97
|
+
if (depth >= maxDepth) {
|
|
98
|
+
return Array.isArray(val) ? `[Array(${val.length})]` : "[Object]";
|
|
99
|
+
}
|
|
100
|
+
seen.add(val);
|
|
101
|
+
let result;
|
|
102
|
+
if (Array.isArray(val)) {
|
|
103
|
+
result = val.slice(0, maxArrayItems).map((item) => trim(item, depth + 1));
|
|
104
|
+
if (val.length > maxArrayItems) {
|
|
105
|
+
result.push(`+${val.length - maxArrayItems} more items`);
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
result = {};
|
|
109
|
+
for (const key of Object.keys(val)) {
|
|
110
|
+
result[key] = trim(val[key], depth + 1);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
seen.delete(val);
|
|
114
|
+
return result;
|
|
115
|
+
};
|
|
116
|
+
return trim(value, 0);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
37
120
|
let promiseId = 0;
|
|
38
121
|
let openPromises = {};
|
|
39
|
-
function wrapPromise(vm, promise, beginAsyncProcess, endAsyncProcess) {
|
|
122
|
+
function wrapPromise(vm, promise, beginAsyncProcess, endAsyncProcess, logger) {
|
|
40
123
|
promiseId += 1;
|
|
41
124
|
const vmPromise = vm.newPromise();
|
|
42
125
|
vmPromise._promiseId = promiseId;
|
|
43
126
|
beginAsyncProcess();
|
|
44
127
|
promise.then((...args) => {
|
|
45
128
|
endAsyncProcess();
|
|
46
|
-
const wrappedArgs = args.map((arg) => wrap(vm, arg, void 0, beginAsyncProcess, endAsyncProcess));
|
|
129
|
+
const wrappedArgs = args.map((arg) => wrap(vm, arg, void 0, beginAsyncProcess, endAsyncProcess, logger));
|
|
47
130
|
openPromises[vmPromise._promiseId] = null;
|
|
48
131
|
vmPromise.resolve(...wrappedArgs);
|
|
49
132
|
wrappedArgs.forEach((arg) => arg.dispose());
|
|
50
|
-
}).catch((
|
|
51
|
-
|
|
52
|
-
vmPromise.reject(...wrappedArgs);
|
|
53
|
-
wrappedArgs.forEach((arg) => arg.dispose());
|
|
133
|
+
}).catch((error) => {
|
|
134
|
+
vmPromise.reject(vm.newError(error?.message || "An error occurred"));
|
|
54
135
|
openPromises[vmPromise._promiseId] = null;
|
|
55
136
|
});
|
|
56
137
|
vmPromise.settled.then(() => {
|
|
@@ -69,19 +150,25 @@ function rejectOpenPromises(vm) {
|
|
|
69
150
|
}
|
|
70
151
|
vm.runtime.executePendingJobs();
|
|
71
152
|
}
|
|
72
|
-
|
|
153
|
+
const isPromise = (value) => {
|
|
154
|
+
return typeof value === "object" && typeof value.then === "function";
|
|
155
|
+
};
|
|
156
|
+
function wrap(vm, value, context, beginAsyncProcess, endAsyncProcess, logger) {
|
|
73
157
|
if (value === null) {
|
|
74
158
|
return null;
|
|
75
|
-
} else if (
|
|
76
|
-
return wrapPromise(vm, value, beginAsyncProcess, endAsyncProcess);
|
|
159
|
+
} else if (isPromise(value)) {
|
|
160
|
+
return wrapPromise(vm, value, beginAsyncProcess, endAsyncProcess, logger);
|
|
77
161
|
} else if (typeof value === "function") {
|
|
78
|
-
return wrapGenericFunction(vm, value, context, beginAsyncProcess, endAsyncProcess);
|
|
162
|
+
return wrapGenericFunction(vm, value, context, beginAsyncProcess, endAsyncProcess, logger);
|
|
79
163
|
} else if (Array.isArray(value)) {
|
|
80
|
-
return wrapArray(vm, value, beginAsyncProcess, endAsyncProcess);
|
|
164
|
+
return wrapArray(vm, value, beginAsyncProcess, endAsyncProcess, logger);
|
|
81
165
|
} else if (value === null) {
|
|
82
166
|
return vm.null;
|
|
167
|
+
} else if (value instanceof Date) {
|
|
168
|
+
const res = vm.evalCode(`new Date(${value.getTime()})`);
|
|
169
|
+
return quickjsEmscripten.isSuccess(res) ? res.value : null;
|
|
83
170
|
} else if (typeof value === "object") {
|
|
84
|
-
return wrapObject(vm, value, beginAsyncProcess, endAsyncProcess);
|
|
171
|
+
return wrapObject(vm, value, beginAsyncProcess, endAsyncProcess, logger);
|
|
85
172
|
} else if (typeof value === "string") {
|
|
86
173
|
return vm.newString(value);
|
|
87
174
|
} else if (typeof value === "number") {
|
|
@@ -89,17 +176,19 @@ function wrap(vm, value, context, beginAsyncProcess, endAsyncProcess) {
|
|
|
89
176
|
} else if (typeof value === "bigint") {
|
|
90
177
|
return vm.newBigInt(value);
|
|
91
178
|
} else if (typeof value === "boolean") {
|
|
92
|
-
|
|
179
|
+
const res = vm.evalCode(value ? "true" : "false");
|
|
180
|
+
return quickjsEmscripten.isSuccess(res) ? res.value : null;
|
|
93
181
|
} else if (typeof value === "undefined") {
|
|
94
182
|
return vm.undefined;
|
|
95
183
|
} else {
|
|
184
|
+
console.error("Unknown type", value);
|
|
96
185
|
return null;
|
|
97
186
|
}
|
|
98
187
|
}
|
|
99
|
-
function wrapObject(vm, obj, beginAsyncProcess, endAsyncProcess) {
|
|
188
|
+
function wrapObject(vm, obj, beginAsyncProcess, endAsyncProcess, logger) {
|
|
100
189
|
const vmObject = vm.newObject();
|
|
101
190
|
for (const [key, value] of Object.entries(obj)) {
|
|
102
|
-
let wrappedValue = wrap(vm, value, obj, beginAsyncProcess, endAsyncProcess);
|
|
191
|
+
let wrappedValue = wrap(vm, value, obj, beginAsyncProcess, endAsyncProcess, logger);
|
|
103
192
|
if (wrappedValue !== null) {
|
|
104
193
|
vm.setProp(vmObject, key, wrappedValue);
|
|
105
194
|
if (wrappedValue != vm.undefined && wrappedValue != vm.null && wrappedValue.dispose) {
|
|
@@ -109,11 +198,11 @@ function wrapObject(vm, obj, beginAsyncProcess, endAsyncProcess) {
|
|
|
109
198
|
}
|
|
110
199
|
return vmObject;
|
|
111
200
|
}
|
|
112
|
-
function wrapObjectWhitelist(vm, obj, whitelist, beginAsyncProcess, endAsyncProcess) {
|
|
201
|
+
function wrapObjectWhitelist(vm, obj, whitelist, beginAsyncProcess, endAsyncProcess, logger) {
|
|
113
202
|
const vmObject = vm.newObject();
|
|
114
203
|
whitelist.forEach((key) => {
|
|
115
204
|
const value = obj[key];
|
|
116
|
-
const wrappedValue = wrap(vm, value, obj, beginAsyncProcess, endAsyncProcess);
|
|
205
|
+
const wrappedValue = wrap(vm, value, obj, beginAsyncProcess, endAsyncProcess, logger);
|
|
117
206
|
if (wrappedValue !== null) {
|
|
118
207
|
vm.setProp(vmObject, key, wrappedValue);
|
|
119
208
|
if (wrappedValue != vm.undefined && wrappedValue != vm.null && wrappedValue.dispose) {
|
|
@@ -123,10 +212,10 @@ function wrapObjectWhitelist(vm, obj, whitelist, beginAsyncProcess, endAsyncProc
|
|
|
123
212
|
});
|
|
124
213
|
return vmObject;
|
|
125
214
|
}
|
|
126
|
-
function wrapArray(vm, arr, beginAsyncProcess, endAsyncProcess) {
|
|
215
|
+
function wrapArray(vm, arr, beginAsyncProcess, endAsyncProcess, logger) {
|
|
127
216
|
const vmArray = vm.newArray();
|
|
128
217
|
for (let i = 0; i < arr.length; i++) {
|
|
129
|
-
let wrappedValue = wrap(vm, arr[i], arr, beginAsyncProcess, endAsyncProcess);
|
|
218
|
+
let wrappedValue = wrap(vm, arr[i], arr, beginAsyncProcess, endAsyncProcess, logger);
|
|
130
219
|
vm.setProp(vmArray, i, wrappedValue);
|
|
131
220
|
if (wrappedValue != vm.undefined && wrappedValue != vm.null) {
|
|
132
221
|
wrappedValue.dispose();
|
|
@@ -134,15 +223,47 @@ function wrapArray(vm, arr, beginAsyncProcess, endAsyncProcess) {
|
|
|
134
223
|
}
|
|
135
224
|
return vmArray;
|
|
136
225
|
}
|
|
137
|
-
function
|
|
226
|
+
function validationDecorator(schema) {
|
|
227
|
+
return function(...args) {
|
|
228
|
+
let argumentObject = {};
|
|
229
|
+
const params = Object.keys(schema.def.shape);
|
|
230
|
+
args.forEach((value, index) => {
|
|
231
|
+
if (index < params.length) {
|
|
232
|
+
argumentObject[params[index]] = value;
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
schema.parse(argumentObject);
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function wrapGenericFunction(vm, fn, context = void 0, beginAsyncProcess, endAsyncProcess, logger) {
|
|
138
239
|
const vmFn = vm.newFunction(fn.name, (...args) => {
|
|
139
240
|
const unwrappedArgs = args.map(vm.dump);
|
|
140
241
|
try {
|
|
242
|
+
const validatorName = `_params_${fn.name}`;
|
|
243
|
+
const hasValidator = context != void 0 && validatorName in context && "parse" in context[validatorName];
|
|
244
|
+
if (hasValidator) {
|
|
245
|
+
const schema = context[validatorName];
|
|
246
|
+
try {
|
|
247
|
+
const validator = validationDecorator(schema);
|
|
248
|
+
validator(...unwrappedArgs);
|
|
249
|
+
} catch (e) {
|
|
250
|
+
if (e instanceof zod.ZodError) {
|
|
251
|
+
throw new Error(`Parameter validation failed for function "${fn.name}". Expected Parameters: [${Object.keys(schema.def.shape).join(",")}]. Errors:
|
|
252
|
+
${zod.z.prettifyError(e)}`);
|
|
253
|
+
}
|
|
254
|
+
throw new Error(`Parameter validation error calling ${fn.name}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
141
257
|
const result = fn.call(context, ...unwrappedArgs);
|
|
142
|
-
|
|
258
|
+
logger.trace(fn.name, unwrappedArgs, result);
|
|
259
|
+
const wrappedResult = wrap(vm, result, void 0, beginAsyncProcess, endAsyncProcess, logger);
|
|
143
260
|
return wrappedResult;
|
|
144
261
|
} catch (e) {
|
|
145
|
-
|
|
262
|
+
logger.error([e], "sandbox");
|
|
263
|
+
if (e instanceof Error) {
|
|
264
|
+
throw e;
|
|
265
|
+
}
|
|
266
|
+
throw new Error("An exception occurred calling " + fn.name);
|
|
146
267
|
}
|
|
147
268
|
});
|
|
148
269
|
return vmFn;
|
|
@@ -230,34 +351,6 @@ function tsCompile(source, options) {
|
|
|
230
351
|
}
|
|
231
352
|
return ts__namespace.transpileModule(source, options).outputText;
|
|
232
353
|
}
|
|
233
|
-
class Logger {
|
|
234
|
-
constructor(debug = false) {
|
|
235
|
-
this.logs = [];
|
|
236
|
-
this.debug = false;
|
|
237
|
-
this.debug = debug;
|
|
238
|
-
}
|
|
239
|
-
log(args, source) {
|
|
240
|
-
if (Array.isArray(args)) {
|
|
241
|
-
this.logs.push({ type: "log", args, source });
|
|
242
|
-
} else {
|
|
243
|
-
this.logs.push({ type: "log", args: [args], source });
|
|
244
|
-
}
|
|
245
|
-
if (this.debug) {
|
|
246
|
-
console.log(`[${source}]:`, ...args);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
error(args, source) {
|
|
250
|
-
if (Array.isArray(args)) {
|
|
251
|
-
this.logs.push({ type: "error", args, source });
|
|
252
|
-
} else {
|
|
253
|
-
this.logs.push({ type: "error", args: [args], source });
|
|
254
|
-
}
|
|
255
|
-
console.error(`[${source}]:`, ...args);
|
|
256
|
-
}
|
|
257
|
-
clear() {
|
|
258
|
-
this.logs = [];
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
354
|
async function createSandbox(QuickJS, requireLookup = {}, globals = {}, debug = false) {
|
|
262
355
|
const vm = QuickJS.newContext();
|
|
263
356
|
let errorState = false;
|
|
@@ -299,8 +392,9 @@ async function createSandbox(QuickJS, requireLookup = {}, globals = {}, debug =
|
|
|
299
392
|
globalOption.value,
|
|
300
393
|
globalOption.whitelist,
|
|
301
394
|
beginAsyncProcess,
|
|
302
|
-
endAsyncProcess
|
|
303
|
-
|
|
395
|
+
endAsyncProcess,
|
|
396
|
+
logger
|
|
397
|
+
) : wrap(vm, globalOption.value, globalOption, beginAsyncProcess, endAsyncProcess, logger);
|
|
304
398
|
vm.setProp(vm.global, globalNames[i], globalObj);
|
|
305
399
|
globalObj.dispose();
|
|
306
400
|
}
|
|
@@ -308,7 +402,7 @@ async function createSandbox(QuickJS, requireLookup = {}, globals = {}, debug =
|
|
|
308
402
|
const requireHandle = vm.newFunction("require", (...args) => {
|
|
309
403
|
const nativeArgs = args.map(vm.dump);
|
|
310
404
|
if (requireLookup[nativeArgs[0]]) {
|
|
311
|
-
const returnObj = wrapObject(vm, requireLookup[nativeArgs[0]], beginAsyncProcess, endAsyncProcess);
|
|
405
|
+
const returnObj = wrapObject(vm, requireLookup[nativeArgs[0]], beginAsyncProcess, endAsyncProcess, logger);
|
|
312
406
|
return returnObj;
|
|
313
407
|
} else {
|
|
314
408
|
return vm.undefined;
|
|
@@ -339,22 +433,22 @@ async function createSandbox(QuickJS, requireLookup = {}, globals = {}, debug =
|
|
|
339
433
|
logger.error(["Could not compile:", code], "compiler");
|
|
340
434
|
return {
|
|
341
435
|
success: false,
|
|
342
|
-
logs: logger.
|
|
436
|
+
logs: logger.getLogs()
|
|
343
437
|
};
|
|
344
438
|
}
|
|
345
439
|
} catch (e) {
|
|
346
440
|
logger.error(["Error testing code:", e], "compiler");
|
|
347
441
|
return {
|
|
348
442
|
success: false,
|
|
349
|
-
logs: logger.
|
|
443
|
+
logs: logger.getLogs()
|
|
350
444
|
};
|
|
351
445
|
}
|
|
352
446
|
return {
|
|
353
447
|
success: true,
|
|
354
|
-
logs: logger.
|
|
448
|
+
logs: logger.getLogs()
|
|
355
449
|
};
|
|
356
450
|
},
|
|
357
|
-
runCode: (code) => {
|
|
451
|
+
runCode: async (code) => {
|
|
358
452
|
try {
|
|
359
453
|
logger.clear();
|
|
360
454
|
const compiled = tsCompile(code);
|
|
@@ -362,7 +456,7 @@ async function createSandbox(QuickJS, requireLookup = {}, globals = {}, debug =
|
|
|
362
456
|
logger.error(["Could not compile:", code], "compiler");
|
|
363
457
|
return {
|
|
364
458
|
success: false,
|
|
365
|
-
logs: logger.
|
|
459
|
+
logs: logger.getLogs()
|
|
366
460
|
};
|
|
367
461
|
}
|
|
368
462
|
errorState = false;
|
|
@@ -373,23 +467,37 @@ async function createSandbox(QuickJS, requireLookup = {}, globals = {}, debug =
|
|
|
373
467
|
result.error.dispose();
|
|
374
468
|
return {
|
|
375
469
|
success: false,
|
|
376
|
-
logs: logger.
|
|
470
|
+
logs: logger.getPrettyLogs()
|
|
377
471
|
};
|
|
378
472
|
} else if ("value" in result) {
|
|
473
|
+
const settled = vm.resolvePromise(result.value);
|
|
379
474
|
result.value.dispose();
|
|
475
|
+
vm.runtime.executePendingJobs();
|
|
476
|
+
const promiseResult = await settled;
|
|
477
|
+
if (promiseResult.error) {
|
|
478
|
+
const err = vm.dump(promiseResult.error);
|
|
479
|
+
promiseResult.error.dispose();
|
|
480
|
+
const lines = compiled.split("\n").map((l, i) => `${i + 1}: ${l}`);
|
|
481
|
+
logger.error(["Uncaught exception:", err, "\n", lines.join("\n")], "runner");
|
|
482
|
+
return {
|
|
483
|
+
success: false,
|
|
484
|
+
logs: logger.getPrettyLogs()
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
promiseResult.value.dispose();
|
|
380
488
|
if (errorState) {
|
|
381
489
|
const lines = compiled.split("\n").map((line, index) => `${index + 1}: ${line}`);
|
|
382
490
|
logger.error(["An error was reported during execution. Compiled code with line numbers:\n", lines.join("\n")], "runner");
|
|
383
491
|
}
|
|
384
492
|
return {
|
|
385
493
|
success: !errorState,
|
|
386
|
-
logs: logger.
|
|
494
|
+
logs: logger.getPrettyLogs()
|
|
387
495
|
};
|
|
388
496
|
} else {
|
|
389
497
|
logger.error(["Unknown execution result:", result], "runner");
|
|
390
498
|
return {
|
|
391
499
|
success: false,
|
|
392
|
-
logs: logger.
|
|
500
|
+
logs: logger.getPrettyLogs()
|
|
393
501
|
};
|
|
394
502
|
}
|
|
395
503
|
} catch (e) {
|
|
@@ -397,7 +505,7 @@ async function createSandbox(QuickJS, requireLookup = {}, globals = {}, debug =
|
|
|
397
505
|
}
|
|
398
506
|
return {
|
|
399
507
|
success: false,
|
|
400
|
-
logs: logger.
|
|
508
|
+
logs: logger.getLogs()
|
|
401
509
|
};
|
|
402
510
|
}
|
|
403
511
|
};
|
|
@@ -406,13 +514,12 @@ async function createSandbox(QuickJS, requireLookup = {}, globals = {}, debug =
|
|
|
406
514
|
require$1("dotenv").config();
|
|
407
515
|
const openai = new openai$1.OpenAI({ baseURL: process.env.OPENAI_API_BASE_URL || void 0, apiKey: process.env.OPENAI_API_KEY || void 0 });
|
|
408
516
|
let QuickJS = null;
|
|
517
|
+
function createLog(message, source) {
|
|
518
|
+
return { type: "log", args: [message], source };
|
|
519
|
+
}
|
|
409
520
|
const wrapCode = (apiGlobalName, apiFileDefPath, code) => `
|
|
410
521
|
(async () => {
|
|
411
|
-
|
|
412
|
-
${code}
|
|
413
|
-
} catch(err) {
|
|
414
|
-
console.error(err);
|
|
415
|
-
}
|
|
522
|
+
${code}
|
|
416
523
|
})();
|
|
417
524
|
`;
|
|
418
525
|
const wrapCodeBlock = (code, codeType = "") => `
|
|
@@ -426,13 +533,13 @@ function zodParseJSON(schema) {
|
|
|
426
533
|
function createBasePrompt(apiFilePath, apiGlobalName, documentationPath) {
|
|
427
534
|
const apiText = fs.readFileSync(apiFilePath, "utf8");
|
|
428
535
|
const documentationText = documentationPath ? fs.readFileSync(documentationPath, "utf8") : "";
|
|
429
|
-
const createTaskPrompt = fs.readFileSync("
|
|
536
|
+
const createTaskPrompt = fs.readFileSync(path.resolve(__dirname, "../prompts/generate-code-prompt.md"), "utf8").replace("{{DOCUMENTATION}}", documentationText).replace("{{API}}", apiText).replace("{{API_GLOBAL_NAME}}", apiGlobalName || "");
|
|
430
537
|
return createTaskPrompt;
|
|
431
538
|
}
|
|
432
539
|
const runCodeSchema = zod.z.object({
|
|
433
540
|
code: zod.z.string()
|
|
434
541
|
});
|
|
435
|
-
|
|
542
|
+
zod.z.object({
|
|
436
543
|
code: zod.z.string()
|
|
437
544
|
});
|
|
438
545
|
const submitCodeSchema = zod.z.object({
|
|
@@ -454,34 +561,42 @@ const generateCode = async function(instance, queryText, userChatHistory, create
|
|
|
454
561
|
if (debug) {
|
|
455
562
|
console.log("Running code...", code);
|
|
456
563
|
}
|
|
564
|
+
const checkRes = await instance.checkCode(code);
|
|
565
|
+
if (!checkRes.success) {
|
|
566
|
+
return {
|
|
567
|
+
success: false,
|
|
568
|
+
reason: "Code check failed",
|
|
569
|
+
logs: checkRes.logs
|
|
570
|
+
};
|
|
571
|
+
}
|
|
457
572
|
const res = await instance.runCode(code);
|
|
458
573
|
if (hideLogsFromAgent) {
|
|
459
574
|
res.logs = [];
|
|
460
575
|
}
|
|
461
576
|
return res;
|
|
462
577
|
},
|
|
463
|
-
description: "
|
|
578
|
+
description: "Check and run the provided code in a sandboxed environment. The code will have access to the API object. Returns the result of the code execution. Use this for testing and experimentation.",
|
|
464
579
|
parse: zodParseJSON(runCodeSchema),
|
|
465
|
-
parameters:
|
|
466
|
-
}
|
|
467
|
-
},
|
|
468
|
-
{
|
|
469
|
-
type: "function",
|
|
470
|
-
function: {
|
|
471
|
-
name: "checkCode",
|
|
472
|
-
// @ts-ignore
|
|
473
|
-
function: async ({ code }) => {
|
|
474
|
-
if (debug) {
|
|
475
|
-
console.log("Checking code...", code);
|
|
476
|
-
}
|
|
477
|
-
const res = await instance.checkCode(code);
|
|
478
|
-
return res;
|
|
479
|
-
},
|
|
480
|
-
description: "Check the provided code for errors or issues without running it. Returns the result of the code check.",
|
|
481
|
-
parse: zodParseJSON(checkCodeSchema),
|
|
482
|
-
parameters: zodToJsonSchema.zodToJsonSchema(checkCodeSchema)
|
|
580
|
+
parameters: runCodeSchema.toJSONSchema()
|
|
483
581
|
}
|
|
484
582
|
},
|
|
583
|
+
// {
|
|
584
|
+
// type: "function",
|
|
585
|
+
// function: {
|
|
586
|
+
// name: "checkCode",
|
|
587
|
+
// // @ts-ignore
|
|
588
|
+
// function: async ({code}: {code: string}) => {
|
|
589
|
+
// if(debug) {
|
|
590
|
+
// console.log("Checking code...", code);
|
|
591
|
+
// }
|
|
592
|
+
// const res = await instance.checkCode(code);
|
|
593
|
+
// return res;
|
|
594
|
+
// },
|
|
595
|
+
// description: "Check the provided code for errors or issues without running it. Returns the result of the code check.",
|
|
596
|
+
// parse: zodParseJSON(checkCodeSchema),
|
|
597
|
+
// parameters: checkCodeSchema.toJSONSchema(),
|
|
598
|
+
// }
|
|
599
|
+
// },
|
|
485
600
|
{
|
|
486
601
|
type: "function",
|
|
487
602
|
function: {
|
|
@@ -496,14 +611,18 @@ const generateCode = async function(instance, queryText, userChatHistory, create
|
|
|
496
611
|
logs: checkRes.logs
|
|
497
612
|
};
|
|
498
613
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
}
|
|
614
|
+
const res = await instance.runCode(code);
|
|
615
|
+
if (hideLogsFromAgent) {
|
|
616
|
+
res.logs = [];
|
|
617
|
+
}
|
|
618
|
+
if (res.success) {
|
|
619
|
+
finalSubmittedCode = code;
|
|
620
|
+
}
|
|
621
|
+
return res;
|
|
503
622
|
},
|
|
504
|
-
description: "Submit the provided code as the final code
|
|
623
|
+
description: "Submit the provided code as a candidate for the final code. The code will be checked and run and output logs and traces will be provided. Check the logs, if satisifed, respond to the user otherwise submit again.",
|
|
505
624
|
parse: zodParseJSON(submitCodeSchema),
|
|
506
|
-
parameters:
|
|
625
|
+
parameters: submitCodeSchema.toJSONSchema()
|
|
507
626
|
}
|
|
508
627
|
}
|
|
509
628
|
];
|
|
@@ -525,17 +644,13 @@ const generateCode = async function(instance, queryText, userChatHistory, create
|
|
|
525
644
|
...additionalModelOptions
|
|
526
645
|
}).on("message", async (message) => {
|
|
527
646
|
if (debug) {
|
|
528
|
-
|
|
647
|
+
if ("reasoning_content" in message) {
|
|
648
|
+
console.log(message.reasoning_content);
|
|
649
|
+
}
|
|
529
650
|
}
|
|
530
651
|
newHistoryItems.push(message);
|
|
531
652
|
}).on("functionToolCall", (functionCall) => {
|
|
532
|
-
if (debug) {
|
|
533
|
-
console.log("Function Call:", JSON.stringify(functionCall, null, 2));
|
|
534
|
-
}
|
|
535
653
|
}).on("functionToolCallResult", (functionCall) => {
|
|
536
|
-
if (debug) {
|
|
537
|
-
console.log("Function Call Result:", JSON.stringify(functionCall, null, 2));
|
|
538
|
-
}
|
|
539
654
|
});
|
|
540
655
|
const finalContent = await runner.finalContent();
|
|
541
656
|
if (debug) {
|
|
@@ -639,7 +754,7 @@ async function createWithAPI(options) {
|
|
|
639
754
|
console.error("Unknown failure checking code");
|
|
640
755
|
return {
|
|
641
756
|
success: false,
|
|
642
|
-
logs: []
|
|
757
|
+
logs: [createLog("Unknown failure checking code", "compiler")]
|
|
643
758
|
};
|
|
644
759
|
}
|
|
645
760
|
if (debug) {
|
|
@@ -680,7 +795,7 @@ async function createWithAPI(options) {
|
|
|
680
795
|
};
|
|
681
796
|
}
|
|
682
797
|
}
|
|
683
|
-
const { vm, runCode:
|
|
798
|
+
const { vm, runCode: sandbox_runCode, isAsyncProcessRunning } = await createSandbox(QuickJS, apiExports ? {
|
|
684
799
|
[apiDefFilePath]: apiExports
|
|
685
800
|
} : void 0, {
|
|
686
801
|
...apiGlobals,
|
|
@@ -693,7 +808,7 @@ async function createWithAPI(options) {
|
|
|
693
808
|
if (debug) {
|
|
694
809
|
console.log("Running Code:\n", code);
|
|
695
810
|
}
|
|
696
|
-
const res = await
|
|
811
|
+
const res = await sandbox_runCode(wrapCode(apiGlobalName, apiDefFilePath, code));
|
|
697
812
|
if (!res) {
|
|
698
813
|
console.error("Unknown failure running task");
|
|
699
814
|
return {
|
|
@@ -724,27 +839,35 @@ async function createWithAPI(options) {
|
|
|
724
839
|
// generates code and runs it in one step
|
|
725
840
|
processRequest: async function(userQuery, currentContext = void 0) {
|
|
726
841
|
if (debug) {
|
|
727
|
-
console.log("Query:", userQuery);
|
|
842
|
+
console.log("[debug] Query:", userQuery);
|
|
728
843
|
}
|
|
729
844
|
console.time("Generate Task");
|
|
845
|
+
const prompt = createTaskPrompt.replace("{{CONTEXT}}", currentContext ? JSON.stringify(currentContext, null, 2) : "");
|
|
730
846
|
const generatedCode = await generateCode(
|
|
731
847
|
instance,
|
|
732
848
|
userQuery,
|
|
733
849
|
[],
|
|
734
|
-
|
|
850
|
+
prompt,
|
|
735
851
|
debug,
|
|
736
852
|
hideLogsFromAgent,
|
|
737
853
|
model,
|
|
738
854
|
additionalModelOptions
|
|
739
855
|
);
|
|
740
856
|
console.timeEnd("Generate Task");
|
|
741
|
-
console.
|
|
857
|
+
console.log(`generated code result
|
|
858
|
+
Success?: ${generatedCode?.success}
|
|
859
|
+
Comments: ${generatedCode?.comments}
|
|
860
|
+
Running Code...`);
|
|
861
|
+
console.time("Run Code took");
|
|
742
862
|
if (generatedCode?.code) {
|
|
743
|
-
await instance.runCode(generatedCode.code);
|
|
863
|
+
const codeRunResult = await instance.runCode(generatedCode.code);
|
|
864
|
+
if (!codeRunResult.success) {
|
|
865
|
+
console.error("Error running generated code");
|
|
866
|
+
}
|
|
744
867
|
} else {
|
|
745
868
|
console.error("No code generated", generatedCode);
|
|
746
869
|
}
|
|
747
|
-
console.timeEnd("Run Code");
|
|
870
|
+
console.timeEnd("Run Code took");
|
|
748
871
|
return generatedCode;
|
|
749
872
|
}
|
|
750
873
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { ChatCompletionMessageParam } from 'openai/resources/index.mjs';
|
|
2
2
|
import { QuickJSWASMModule } from 'quickjs-emscripten';
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
type LogSource = "sandbox" | "compiler" | "runner";
|
|
5
|
+
type SandboxLog = {
|
|
6
|
+
type: "log" | "error";
|
|
7
|
+
args: any[];
|
|
8
|
+
source: LogSource;
|
|
9
|
+
} | {
|
|
10
|
+
type: "trace";
|
|
11
|
+
fnName: string;
|
|
12
|
+
fnArgs: any[];
|
|
13
|
+
result: any;
|
|
14
|
+
};
|
|
4
15
|
|
|
5
16
|
interface GlobalOption {
|
|
6
17
|
value: any;
|
|
@@ -9,11 +20,6 @@ interface GlobalOption {
|
|
|
9
20
|
interface Globals {
|
|
10
21
|
[key: string]: GlobalOption;
|
|
11
22
|
}
|
|
12
|
-
type SandboxLog = {
|
|
13
|
-
type: "log" | "error";
|
|
14
|
-
args: any[];
|
|
15
|
-
source: string;
|
|
16
|
-
};
|
|
17
23
|
type CodeRunResult = {
|
|
18
24
|
success: boolean;
|
|
19
25
|
logs: SandboxLog[];
|
|
@@ -44,7 +50,9 @@ interface GenerateCodeResult {
|
|
|
44
50
|
code?: string;
|
|
45
51
|
comments?: string;
|
|
46
52
|
}
|
|
47
|
-
declare function zodParseJSON<T>(schema:
|
|
53
|
+
declare function zodParseJSON<T>(schema: {
|
|
54
|
+
parse: any;
|
|
55
|
+
}): (input: string) => T;
|
|
48
56
|
declare function createBasePrompt(apiFilePath: string, apiGlobalName: string, documentationPath?: string): string;
|
|
49
57
|
declare const generateCode: (instance: AIMyAPIInstance, queryText: string, userChatHistory: ChatCompletionMessageParam[], createTaskPrompt: string, debug?: boolean, hideLogsFromAgent?: boolean, model?: string, additionalModelOptions?: object, attempt?: number) => Promise<GenerateCodeResult | null>;
|
|
50
58
|
interface AIMyAPIModuleExports {
|
|
@@ -55,4 +63,4 @@ interface AIMyAPIModuleExports {
|
|
|
55
63
|
}
|
|
56
64
|
declare const AIMyAPI: AIMyAPIModuleExports;
|
|
57
65
|
|
|
58
|
-
export { AIMyAPI, type AIMyAPIInstance, type AIMyAPIModuleExports, type AIMyAPIOptions, type CodeRunResult, type GenerateCodeResult, type GlobalOption, type Globals,
|
|
66
|
+
export { AIMyAPI, type AIMyAPIInstance, type AIMyAPIModuleExports, type AIMyAPIOptions, type CodeRunResult, type GenerateCodeResult, type GlobalOption, type Globals, createBasePrompt, generateCode, zodParseJSON };
|