@openpond/evals 0.7.5 → 0.8.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 (89) hide show
  1. package/JAVASCRIPT_ENVIRONMENTS.md +47 -0
  2. package/LEARNING.md +30 -0
  3. package/dist/environment-execution-services-contract.js +27 -0
  4. package/dist/environment-execution-services.js +100 -0
  5. package/dist/javascript-environment-contract.js +13 -0
  6. package/dist/javascript-environment-node.js +4 -2
  7. package/dist/javascript-environment.js +4 -2
  8. package/dist/javascript-isolate-process-entry.js +2 -2
  9. package/dist/javascript-isolate-process-source.js +1 -1
  10. package/dist/javascript-isolate-process.js +6 -4
  11. package/dist/javascript-isolate.js +39 -30
  12. package/dist/javascript-verifier-worker-source.js +1 -1
  13. package/dist/learning/authoring-service.js +1 -1
  14. package/dist/learning/authoring.js +9 -0
  15. package/dist/learning/index.js +4 -0
  16. package/dist/learning/operations.js +3 -1
  17. package/dist/learning/repository.js +2 -0
  18. package/dist/learning/reward-authoring.js +120 -0
  19. package/dist/learning/reward-check-service.js +31 -0
  20. package/dist/learning/reward-check-worker.js +114 -0
  21. package/dist/learning/reward-checks.js +81 -0
  22. package/dist/learning/reward-fixture-executor.js +29 -0
  23. package/dist/learning/service.js +7 -0
  24. package/dist/rewards.js +3 -0
  25. package/dist/sql-execution-contract.js +52 -0
  26. package/dist/sql-execution-engine.js +135 -0
  27. package/dist/sql-execution-node.js +58 -0
  28. package/dist/sql-execution-process-entry.js +3 -0
  29. package/dist/sql-execution-process-source.js +1 -0
  30. package/dist/sql-wasm-binary.js +1 -0
  31. package/dist/types/environment-execution-services-contract.d.ts +74 -0
  32. package/dist/types/environment-execution-services-contract.d.ts.map +1 -0
  33. package/dist/types/environment-execution-services.d.ts +17 -0
  34. package/dist/types/environment-execution-services.d.ts.map +1 -0
  35. package/dist/types/evidence/conformance.d.ts +4 -4
  36. package/dist/types/evidence/contracts.d.ts +4 -4
  37. package/dist/types/javascript-environment-contract.d.ts +121 -0
  38. package/dist/types/javascript-environment-contract.d.ts.map +1 -1
  39. package/dist/types/javascript-environment-node.d.ts.map +1 -1
  40. package/dist/types/javascript-environment.d.ts +36 -0
  41. package/dist/types/javascript-environment.d.ts.map +1 -1
  42. package/dist/types/javascript-isolate-process.d.ts.map +1 -1
  43. package/dist/types/javascript-isolate.d.ts +4 -1
  44. package/dist/types/javascript-isolate.d.ts.map +1 -1
  45. package/dist/types/learning/admission.d.ts +12 -0
  46. package/dist/types/learning/admission.d.ts.map +1 -1
  47. package/dist/types/learning/authoring-service.d.ts +172 -0
  48. package/dist/types/learning/authoring-service.d.ts.map +1 -1
  49. package/dist/types/learning/authoring.d.ts +121 -0
  50. package/dist/types/learning/authoring.d.ts.map +1 -1
  51. package/dist/types/learning/contracts.d.ts +23 -11
  52. package/dist/types/learning/contracts.d.ts.map +1 -1
  53. package/dist/types/learning/index.d.ts +4 -0
  54. package/dist/types/learning/index.d.ts.map +1 -1
  55. package/dist/types/learning/operations.d.ts +134 -6
  56. package/dist/types/learning/operations.d.ts.map +1 -1
  57. package/dist/types/learning/repository.d.ts +114 -5
  58. package/dist/types/learning/repository.d.ts.map +1 -1
  59. package/dist/types/learning/reward-authoring.d.ts +18 -0
  60. package/dist/types/learning/reward-authoring.d.ts.map +1 -0
  61. package/dist/types/learning/reward-check-service.d.ts +17 -0
  62. package/dist/types/learning/reward-check-service.d.ts.map +1 -0
  63. package/dist/types/learning/reward-check-worker.d.ts +27 -0
  64. package/dist/types/learning/reward-check-worker.d.ts.map +1 -0
  65. package/dist/types/learning/reward-checks.d.ts +177 -0
  66. package/dist/types/learning/reward-checks.d.ts.map +1 -0
  67. package/dist/types/learning/reward-fixture-executor.d.ts +9 -0
  68. package/dist/types/learning/reward-fixture-executor.d.ts.map +1 -0
  69. package/dist/types/learning/service.d.ts.map +1 -1
  70. package/dist/types/learning/transport.d.ts +200 -28
  71. package/dist/types/learning/transport.d.ts.map +1 -1
  72. package/dist/types/rewards.d.ts +24 -0
  73. package/dist/types/rewards.d.ts.map +1 -1
  74. package/dist/types/sql-execution-contract.d.ts +72 -0
  75. package/dist/types/sql-execution-contract.d.ts.map +1 -0
  76. package/dist/types/sql-execution-engine.d.ts +4 -0
  77. package/dist/types/sql-execution-engine.d.ts.map +1 -0
  78. package/dist/types/sql-execution-node.d.ts +9 -0
  79. package/dist/types/sql-execution-node.d.ts.map +1 -0
  80. package/dist/types/sql-execution-process-entry.d.ts +2 -0
  81. package/dist/types/sql-execution-process-entry.d.ts.map +1 -0
  82. package/dist/types/sql-execution-process-source.d.ts +1 -0
  83. package/dist/types/sql-wasm-binary.d.ts +1 -0
  84. package/package.json +10 -1
  85. package/schemas/learning/v1/command-request.schema.json +412 -248
  86. package/schemas/learning/v1/draft.schema.json +96 -0
  87. package/schemas/learning/v1/read-request.schema.json +1 -0
  88. package/schemas/learning/v1/reward.schema.json +3 -0
  89. package/schemas/learning/v1/reward_check.schema.json +343 -0
@@ -1,6 +1,6 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import { javascriptIsolateProcessSource } from "./javascript-isolate-process-source.js";
3
- import { validateJavaScriptIsolateInput } from "./javascript-isolate.js";
3
+ import { JavaScriptIsolateExecutionError, validateJavaScriptIsolateInput } from "./javascript-isolate.js";
4
4
  import { assertBoundedTaskJson } from "./task-schema.js";
5
5
  /** A Node subprocess owns the interpreter; completion always waits for its exit. */
6
6
  export async function executeJavaScriptIsolateInProcess(input) {
@@ -25,7 +25,7 @@ export async function executeJavaScriptIsolateInProcess(input) {
25
25
  child.kill("SIGKILL");
26
26
  };
27
27
  const cancel = () => stop(signal?.reason instanceof Error ? signal.reason : error("cancelled"));
28
- const timer = setTimeout(() => stop(error("timeout")), input.timeoutMs);
28
+ const timer = setTimeout(() => stop(input.errorPrefix === "candidate" ? new JavaScriptIsolateExecutionError("candidate_timeout") : error("timeout")), input.timeoutMs);
29
29
  signal?.addEventListener("abort", cancel, { once: true });
30
30
  child.stdout.setEncoding("utf8");
31
31
  child.stdout.on("data", (chunk) => {
@@ -55,8 +55,10 @@ export async function executeJavaScriptIsolateInProcess(input) {
55
55
  const message = JSON.parse(response);
56
56
  if (!message || typeof message !== "object" || !("ok" in message))
57
57
  throw error("process_invalid_response");
58
- if (message.ok !== true)
59
- throw new Error("error" in message && typeof message.error === "string" ? message.error : `${input.errorPrefix}_execution_failed`);
58
+ if (message.ok !== true) {
59
+ const detail = "error" in message && typeof message.error === "string" ? message.error : `${input.errorPrefix}_execution_failed`;
60
+ throw "executionError" in message && message.executionError === true ? new JavaScriptIsolateExecutionError(detail) : new Error(detail);
61
+ }
60
62
  if (!("result" in message))
61
63
  throw error("process_invalid_response");
62
64
  assertBoundedTaskJson(message.result, input.maxResultBytes);
@@ -1,6 +1,9 @@
1
1
  import { newQuickJSWASMModuleFromVariant, Scope } from "quickjs-emscripten-core";
2
2
  import variant from "@jitl/quickjs-singlefile-cjs-release-sync";
3
3
  import { assertBoundedTaskJson } from "./task-schema.js";
4
+ export class JavaScriptIsolateExecutionError extends Error {
5
+ constructor(message) { super(message); this.name = "JavaScriptIsolateExecutionError"; }
6
+ }
4
7
  /** Authored code is interpreter data, with no host functions or module loader. */
5
8
  export async function executeJavaScriptIsolate(input) {
6
9
  validateJavaScriptIsolateInput(input);
@@ -9,37 +12,43 @@ export async function executeJavaScriptIsolate(input) {
9
12
  const deadline = Date.now() + input.timeoutMs;
10
13
  const module = await newQuickJSWASMModuleFromVariant(variant);
11
14
  input.signal?.throwIfAborted();
12
- return Scope.withScope((scope) => {
13
- const runtime = scope.manage(module.newRuntime());
14
- runtime.setMemoryLimit(33_554_432);
15
- runtime.setMaxStackSize(262_144);
16
- runtime.setInterruptHandler(() => Date.now() >= deadline || input.signal?.aborted === true);
17
- const context = scope.manage(runtime.newContext());
18
- if (input.deterministic) {
19
- scope.manage(context.unwrapResult(context.evalCode("globalThis.Date = undefined; Math.random = () => { throw new Error('environment_random_requires_explicit_seed'); };")));
20
- }
21
- const stringify = scope.manage(context.unwrapResult(context.evalCode("JSON.stringify")));
22
- const argument = scope.manage(context.unwrapResult(context.evalCode(`JSON.parse(${JSON.stringify(JSON.stringify(input.value))})`)));
23
- const exported = scope.manage(context.unwrapResult(context.evalCode(input.source, `${input.errorPrefix}.mjs`, { type: "module" })));
24
- const namespace = scope.manage(settle(context, exported, deadline, input.signal, error));
25
- const fn = scope.manage(context.getProp(namespace, input.exportName));
26
- if (context.typeof(fn) !== "function")
27
- throw error("function_export_missing");
28
- const returned = scope.manage(context.unwrapResult(context.callFunction(fn, context.undefined, argument)));
29
- const result = scope.manage(settle(context, returned, deadline, input.signal, error));
30
- const serialized = scope.manage(context.unwrapResult(context.callFunction(stringify, context.undefined, result)));
31
- if (context.typeof(serialized) !== "string")
32
- throw error("result_not_json");
33
- const json = context.getString(serialized);
34
- if (new TextEncoder().encode(json).byteLength > input.maxResultBytes)
35
- throw error("result_too_large");
15
+ try {
16
+ return Scope.withScope((scope) => {
17
+ const runtime = scope.manage(module.newRuntime());
18
+ runtime.setMemoryLimit(33_554_432);
19
+ runtime.setMaxStackSize(262_144);
20
+ runtime.setInterruptHandler(() => Date.now() >= deadline || input.signal?.aborted === true);
21
+ const context = scope.manage(runtime.newContext());
22
+ if (input.deterministic) {
23
+ scope.manage(context.unwrapResult(context.evalCode("globalThis.Date = undefined; Math.random = () => { throw new Error('environment_random_requires_explicit_seed'); };")));
24
+ }
25
+ const stringify = scope.manage(context.unwrapResult(context.evalCode("JSON.stringify")));
26
+ const argument = scope.manage(context.unwrapResult(context.evalCode(`JSON.parse(${JSON.stringify(JSON.stringify(input.value))})`)));
27
+ const exported = scope.manage(context.unwrapResult(context.evalCode(input.source, `${input.errorPrefix}.mjs`, { type: "module" })));
28
+ const namespace = scope.manage(settle(context, exported, deadline, input.signal, error));
29
+ const fn = scope.manage(context.getProp(namespace, input.exportName));
30
+ if (context.typeof(fn) !== "function")
31
+ throw error("function_export_missing");
32
+ const returned = scope.manage(context.unwrapResult(context.callFunction(fn, context.undefined, argument)));
33
+ const result = scope.manage(settle(context, returned, deadline, input.signal, error));
34
+ const serialized = scope.manage(context.unwrapResult(context.callFunction(stringify, context.undefined, result)));
35
+ if (context.typeof(serialized) !== "string")
36
+ throw error("result_not_json");
37
+ const json = context.getString(serialized);
38
+ if (new TextEncoder().encode(json).byteLength > input.maxResultBytes)
39
+ throw error("result_too_large");
40
+ input.signal?.throwIfAborted();
41
+ if (Date.now() >= deadline)
42
+ throw error("timeout");
43
+ const value = JSON.parse(json);
44
+ assertBoundedTaskJson(value, input.maxResultBytes);
45
+ return value;
46
+ });
47
+ }
48
+ catch (cause) {
36
49
  input.signal?.throwIfAborted();
37
- if (Date.now() >= deadline)
38
- throw error("timeout");
39
- const value = JSON.parse(json);
40
- assertBoundedTaskJson(value, input.maxResultBytes);
41
- return value;
42
- });
50
+ throw new JavaScriptIsolateExecutionError(cause instanceof Error ? cause.message : "JavaScript execution failed.");
51
+ }
43
52
  }
44
53
  export function validateJavaScriptIsolateInput(input) {
45
54
  if (!Number.isInteger(input.timeoutMs) || input.timeoutMs < 1 || input.timeoutMs > 300_000)