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/src/sandbox.ts
CHANGED
|
@@ -2,6 +2,7 @@ import "quickjs-emscripten";
|
|
|
2
2
|
|
|
3
3
|
import { QuickJSWASMModule } from "quickjs-emscripten";
|
|
4
4
|
import * as ts from "typescript";
|
|
5
|
+
import { Logger, SandboxLog } from "./logger";
|
|
5
6
|
import {
|
|
6
7
|
injectTimingFunctions,
|
|
7
8
|
wrap,
|
|
@@ -34,51 +35,10 @@ export interface GlobalOption {
|
|
|
34
35
|
export interface Globals {
|
|
35
36
|
[key: string]: GlobalOption;
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
-
export type SandboxLog = {
|
|
39
|
-
type: "log" | "error";
|
|
40
|
-
args: any[];
|
|
41
|
-
source: string
|
|
42
|
-
};
|
|
43
38
|
export type CodeRunResult = {
|
|
44
39
|
success: boolean;
|
|
45
40
|
logs: SandboxLog[];
|
|
46
41
|
}
|
|
47
|
-
type LogSource = "sandbox" | "compiler" | "runner";
|
|
48
|
-
class Logger {
|
|
49
|
-
logs: SandboxLog[] = [];
|
|
50
|
-
debug: boolean = false;
|
|
51
|
-
|
|
52
|
-
constructor(debug: boolean = false) {
|
|
53
|
-
this.debug = debug;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
log(args: any, source: LogSource) {
|
|
57
|
-
if(Array.isArray(args)) {
|
|
58
|
-
this.logs.push({ type: "log", args, source });
|
|
59
|
-
} else {
|
|
60
|
-
this.logs.push({ type: "log", args: [args], source });
|
|
61
|
-
}
|
|
62
|
-
if (this.debug) {
|
|
63
|
-
console.log(`[${source}]:`, ...args);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
error(args: any, source: LogSource) {
|
|
68
|
-
if(Array.isArray(args)) {
|
|
69
|
-
this.logs.push({ type: "error", args, source });
|
|
70
|
-
} else {
|
|
71
|
-
this.logs.push({ type: "error", args: [args], source });
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
console.error(`[${source}]:`, ...args);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
clear() {
|
|
78
|
-
this.logs = [];
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
42
|
|
|
83
43
|
|
|
84
44
|
// function whitelist can be produced using something like:
|
|
@@ -147,9 +107,10 @@ export default async function createSandbox(QuickJS: QuickJSWASMModule, requireL
|
|
|
147
107
|
globalOption.value,
|
|
148
108
|
globalOption.whitelist,
|
|
149
109
|
beginAsyncProcess,
|
|
150
|
-
endAsyncProcess
|
|
110
|
+
endAsyncProcess,
|
|
111
|
+
logger
|
|
151
112
|
)
|
|
152
|
-
: wrap(vm, globalOption.value, globalOption, beginAsyncProcess, endAsyncProcess);
|
|
113
|
+
: wrap(vm, globalOption.value, globalOption, beginAsyncProcess, endAsyncProcess, logger);
|
|
153
114
|
|
|
154
115
|
vm.setProp(vm.global, globalNames[i], globalObj);
|
|
155
116
|
globalObj.dispose();
|
|
@@ -160,7 +121,7 @@ export default async function createSandbox(QuickJS: QuickJSWASMModule, requireL
|
|
|
160
121
|
const requireHandle = vm.newFunction("require", (...args) => {
|
|
161
122
|
const nativeArgs = args.map(vm.dump);
|
|
162
123
|
if(requireLookup[nativeArgs[0] as string]) {
|
|
163
|
-
const returnObj = wrapObject(vm, requireLookup[nativeArgs[0] as string], beginAsyncProcess, endAsyncProcess);
|
|
124
|
+
const returnObj = wrapObject(vm, requireLookup[nativeArgs[0] as string], beginAsyncProcess, endAsyncProcess, logger);
|
|
164
125
|
return returnObj;
|
|
165
126
|
} else {
|
|
166
127
|
return vm.undefined;
|
|
@@ -194,23 +155,23 @@ export default async function createSandbox(QuickJS: QuickJSWASMModule, requireL
|
|
|
194
155
|
logger.error(["Could not compile:", code], "compiler");
|
|
195
156
|
return {
|
|
196
157
|
success: false,
|
|
197
|
-
logs: logger.
|
|
158
|
+
logs: logger.getLogs(),
|
|
198
159
|
};
|
|
199
160
|
}
|
|
200
161
|
} catch (e) {
|
|
201
162
|
logger.error(["Error testing code:", e], "compiler");
|
|
202
163
|
return {
|
|
203
164
|
success: false,
|
|
204
|
-
logs: logger.
|
|
165
|
+
logs: logger.getLogs(),
|
|
205
166
|
};
|
|
206
167
|
}
|
|
207
168
|
|
|
208
169
|
return {
|
|
209
170
|
success: true,
|
|
210
|
-
logs: logger.
|
|
171
|
+
logs: logger.getLogs(),
|
|
211
172
|
}
|
|
212
173
|
},
|
|
213
|
-
runCode: (code: string): CodeRunResult => {
|
|
174
|
+
runCode: async (code: string): Promise<CodeRunResult> => {
|
|
214
175
|
try {
|
|
215
176
|
logger.clear();
|
|
216
177
|
const compiled = tsCompile(code);
|
|
@@ -219,7 +180,7 @@ export default async function createSandbox(QuickJS: QuickJSWASMModule, requireL
|
|
|
219
180
|
logger.error(["Could not compile:", code], "compiler");
|
|
220
181
|
return {
|
|
221
182
|
success: false,
|
|
222
|
-
logs: logger.
|
|
183
|
+
logs: logger.getLogs()
|
|
223
184
|
};
|
|
224
185
|
}
|
|
225
186
|
|
|
@@ -234,20 +195,36 @@ export default async function createSandbox(QuickJS: QuickJSWASMModule, requireL
|
|
|
234
195
|
// log out the compiled program with line numbers
|
|
235
196
|
const lines = compiled.split("\n").map((line, index) => `${index + 1}: ${line}`);
|
|
236
197
|
|
|
237
|
-
|
|
238
198
|
logger.error(["Execution failed:", lines.join("\n"), vm.dump(result.error)], "runner");
|
|
239
199
|
|
|
240
200
|
result.error.dispose();
|
|
241
201
|
return {
|
|
242
202
|
success: false,
|
|
243
|
-
logs: logger.
|
|
203
|
+
logs: logger.getPrettyLogs(),
|
|
244
204
|
};
|
|
245
|
-
} else if("value" in result){
|
|
246
|
-
//console.log("Task Result:", vm.dump(result.value));
|
|
247
|
-
|
|
205
|
+
} else if("value" in result) {
|
|
206
|
+
//console.log("Task Result:", vm.dump(result.value), errorState);
|
|
207
|
+
// The wrapped code returns a promise; wait for it to settle.
|
|
208
|
+
const settled = vm.resolvePromise(result.value);
|
|
248
209
|
result.value.dispose();
|
|
249
|
-
|
|
210
|
+
vm.runtime.executePendingJobs(); // start the async function running
|
|
211
|
+
const promiseResult = await settled;
|
|
212
|
+
|
|
213
|
+
if (promiseResult.error) {
|
|
214
|
+
const err = vm.dump(promiseResult.error);
|
|
215
|
+
promiseResult.error.dispose();
|
|
216
|
+
const lines = compiled.split("\n").map((l, i) => `${i + 1}: ${l}`);
|
|
217
|
+
logger.error(["Uncaught exception:", err, "\n", lines.join("\n")], "runner");
|
|
218
|
+
return {
|
|
219
|
+
success: false,
|
|
220
|
+
logs: logger.getPrettyLogs(),
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
// @ts-ignore this is a success response
|
|
224
|
+
promiseResult.value.dispose();
|
|
250
225
|
|
|
226
|
+
|
|
227
|
+
|
|
251
228
|
if (errorState) {
|
|
252
229
|
const lines = compiled.split("\n").map((line, index) => `${index + 1}: ${line}`);
|
|
253
230
|
logger.error(["An error was reported during execution. Compiled code with line numbers:\n", lines.join("\n")], "runner");
|
|
@@ -255,13 +232,13 @@ export default async function createSandbox(QuickJS: QuickJSWASMModule, requireL
|
|
|
255
232
|
|
|
256
233
|
return {
|
|
257
234
|
success: !errorState,
|
|
258
|
-
logs: logger.
|
|
235
|
+
logs: logger.getPrettyLogs(),
|
|
259
236
|
};
|
|
260
237
|
} else {
|
|
261
238
|
logger.error(["Unknown execution result:", result], "runner");
|
|
262
239
|
return {
|
|
263
240
|
success: false,
|
|
264
|
-
logs: logger.
|
|
241
|
+
logs: logger.getPrettyLogs(),
|
|
265
242
|
};
|
|
266
243
|
}
|
|
267
244
|
} catch (e) {
|
|
@@ -270,7 +247,7 @@ export default async function createSandbox(QuickJS: QuickJSWASMModule, requireL
|
|
|
270
247
|
|
|
271
248
|
return {
|
|
272
249
|
success: false,
|
|
273
|
-
logs: logger.
|
|
250
|
+
logs: logger.getLogs(),
|
|
274
251
|
};
|
|
275
252
|
},
|
|
276
253
|
};
|
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
-
export function delay(time):Promise<void> {
|
|
2
|
-
return new Promise<void>(resolve => setTimeout(resolve, time));
|
|
3
|
-
}
|
|
1
|
+
export function delay(time):Promise<void> {
|
|
2
|
+
return new Promise<void>(resolve => setTimeout(resolve, time));
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
const has = Object.prototype.hasOwnProperty;
|
|
6
|
+
|
|
7
|
+
export function dequal(foo: any, bar: any) {
|
|
8
|
+
let ctor, len;
|
|
9
|
+
if (foo === bar) return true;
|
|
10
|
+
|
|
11
|
+
if (foo && bar && (ctor=foo.constructor) === bar.constructor) {
|
|
12
|
+
if (ctor === Date) return foo.getTime() === bar.getTime();
|
|
13
|
+
if (ctor === RegExp) return foo.toString() === bar.toString();
|
|
14
|
+
|
|
15
|
+
if (ctor === Array) {
|
|
16
|
+
if ((len=foo.length) === bar.length) {
|
|
17
|
+
while (len-- && dequal(foo[len], bar[len]));
|
|
18
|
+
}
|
|
19
|
+
return len === -1;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!ctor || typeof foo === 'object') {
|
|
23
|
+
len = 0;
|
|
24
|
+
for (ctor in foo) {
|
|
25
|
+
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
|
|
26
|
+
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
|
|
27
|
+
}
|
|
28
|
+
return Object.keys(bar).length === len;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return foo !== foo && bar !== bar;
|
|
33
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"rootDir": "./src",
|
|
4
|
-
"target": "ES2021" /* Node 16+ per https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping */,
|
|
5
|
-
"module": "nodenext" /* Some imports are really imports: https://www.typescriptlang.org/docs/handbook/esm-node.html */,
|
|
6
|
-
"moduleResolution": "nodenext" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
|
|
7
|
-
"lib": ["ES2021", "dom"] /* Specify library files to be included in the compilation. */,
|
|
8
|
-
"outDir": "./dist" /* Redirect output structure to the directory. */,
|
|
9
|
-
"declaration": true
|
|
10
|
-
},
|
|
11
|
-
"include": ["**/src/*.ts"],
|
|
12
|
-
"exclude": ["**/node_modules, **/dist"]
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"rootDir": "./src",
|
|
4
|
+
"target": "ES2021" /* Node 16+ per https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping */,
|
|
5
|
+
"module": "nodenext" /* Some imports are really imports: https://www.typescriptlang.org/docs/handbook/esm-node.html */,
|
|
6
|
+
"moduleResolution": "nodenext" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
|
|
7
|
+
"lib": ["ES2021", "dom"] /* Specify library files to be included in the compilation. */,
|
|
8
|
+
"outDir": "./dist" /* Redirect output structure to the directory. */,
|
|
9
|
+
"declaration": true
|
|
10
|
+
},
|
|
11
|
+
"include": ["**/src/*.ts"],
|
|
12
|
+
"exclude": ["**/node_modules, **/dist"]
|
|
13
13
|
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
Most recent user query:
|
|
3
|
-
{{USER_QUERY}}
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Based on the prior conversation, write a typescript script that performs the operation requested by the user and call the `submitCode` tool with the script.
|
|
8
|
-
|
|
9
|
-
## API documentation
|
|
10
|
-
|
|
11
|
-
You can make use of this global API object:
|
|
12
|
-
|
|
13
|
-
`api.ts`:
|
|
14
|
-
```typescript
|
|
15
|
-
{{API}}
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Instructions
|
|
19
|
-
|
|
20
|
-
Use the global api object to make calls to the API.
|
|
21
|
-
|
|
22
|
-
You may use top level `await`.
|
|
23
|
-
|
|
24
|
-
If needed, you may use `runCode` to run any non-destructive API calls to gather data for your script. Nothing will be visible to you unless you `console.log` it.
|
|
25
|
-
|
|
26
|
-
You may use the `checkCode` tool to confirm that your code passes typescript compilation and doesn't have errors before submitting.
|
|
27
|
-
|
|
28
|
-
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 (errors can stay).
|
|
29
|
-
|
|
30
|
-
When finished, you must call `submitCode` to submit the final version of the code, then respond with "Successfully submitted code" on success. On failure, correct any errors and submit again.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
{{DOCUMENTATION}}
|
|
35
|
-
|
|
36
|
-
{{CONTEXT}}
|
|
37
|
-
|