@openclaw/lobster 2026.10.10-beta.5 → 2026.11.5-beta.1

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 (98) hide show
  1. package/README.md +8 -0
  2. package/dist/.setup/lobster-schema-compiler-T2XZzavY.mjs +32 -0
  3. package/dist/.source-module-urls/00dc8c474cfa3e6e755374b6a78ce42a8dcd5a5a37a90df29d7baaef767292a6.json +1 -1
  4. package/dist/index.js +20 -17
  5. package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/llm_invoke.js +1 -82
  6. package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/llm_invoke_schemas.js +79 -0
  7. package/node_modules/@clawdbot/lobster/dist/src/commands/stdlib/llm_invoke_validators.generated.js +1008 -0
  8. package/node_modules/@clawdbot/lobster/dist/src/core/index.js +1 -1
  9. package/node_modules/@clawdbot/lobster/dist/src/validation.js +25 -4
  10. package/node_modules/@clawdbot/lobster/node_modules/fast-uri/.github/workflows/release.yml +1 -11
  11. package/node_modules/@clawdbot/lobster/node_modules/fast-uri/README.md +0 -8
  12. package/node_modules/@clawdbot/lobster/node_modules/fast-uri/index.js +17 -93
  13. package/node_modules/@clawdbot/lobster/node_modules/fast-uri/lib/utils.js +0 -52
  14. package/node_modules/@clawdbot/lobster/node_modules/fast-uri/package.json +1 -1
  15. package/node_modules/@clawdbot/lobster/node_modules/fast-uri/test/reserved-path-normalization.test.js +4 -32
  16. package/node_modules/@clawdbot/lobster/node_modules/fast-uri/test/scheme-validation.test.js +12 -51
  17. package/node_modules/typebox/build/format/duration.d.mts +2 -2
  18. package/node_modules/typebox/build/format/duration.mjs +2 -2
  19. package/node_modules/typebox/build/format/idn_email.d.mts +1 -0
  20. package/node_modules/typebox/build/format/idn_email.mjs +1 -0
  21. package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -1
  22. package/node_modules/typebox/build/format/idn_hostname.mjs +1 -1
  23. package/node_modules/typebox/build/format/ipv4.d.mts +2 -2
  24. package/node_modules/typebox/build/format/ipv4.mjs +2 -2
  25. package/node_modules/typebox/build/format/ipv6.d.mts +1 -1
  26. package/node_modules/typebox/build/format/ipv6.mjs +1 -1
  27. package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
  28. package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
  29. package/node_modules/typebox/build/schema/build.mjs +1 -0
  30. package/node_modules/typebox/build/schema/engine/_unique.d.mts +4 -2
  31. package/node_modules/typebox/build/schema/engine/_unique.mjs +7 -3
  32. package/node_modules/typebox/build/schema/engine/additionalItems.mjs +3 -3
  33. package/node_modules/typebox/build/schema/engine/additionalProperties.d.mts +0 -3
  34. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +15 -17
  35. package/node_modules/typebox/build/schema/engine/contains.mjs +3 -3
  36. package/node_modules/typebox/build/schema/engine/index.d.mts +1 -0
  37. package/node_modules/typebox/build/schema/engine/index.mjs +1 -0
  38. package/node_modules/typebox/build/schema/engine/items.mjs +7 -4
  39. package/node_modules/typebox/build/schema/engine/maxContains.mjs +2 -2
  40. package/node_modules/typebox/build/schema/engine/minContains.mjs +3 -3
  41. package/node_modules/typebox/build/schema/engine/oneOf.mjs +2 -2
  42. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +2 -2
  43. package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -2
  44. package/node_modules/typebox/build/schema/engine/unevaluatedItems.mjs +2 -2
  45. package/node_modules/typebox/build/schema/engine/unevaluatedProperties.mjs +2 -2
  46. package/node_modules/typebox/build/system/hashing/hash.mjs +63 -34
  47. package/node_modules/typebox/build/system/locale/en_US.mjs +2 -1
  48. package/node_modules/typebox/build/system/memory/assign.d.mts +2 -8
  49. package/node_modules/typebox/build/system/memory/assign.mjs +13 -6
  50. package/node_modules/typebox/build/system/memory/clone.d.mts +4 -5
  51. package/node_modules/typebox/build/system/memory/clone.mjs +8 -96
  52. package/node_modules/typebox/build/system/memory/create.d.mts +1 -5
  53. package/node_modules/typebox/build/system/memory/create.mjs +18 -13
  54. package/node_modules/typebox/build/system/memory/deep.d.mts +2 -0
  55. package/node_modules/typebox/build/system/memory/deep.mjs +108 -0
  56. package/node_modules/typebox/build/system/memory/discard.d.mts +1 -1
  57. package/node_modules/typebox/build/system/memory/discard.mjs +9 -8
  58. package/node_modules/typebox/build/system/memory/finalize.d.mts +4 -0
  59. package/node_modules/typebox/build/system/memory/finalize.mjs +30 -0
  60. package/node_modules/typebox/build/system/memory/keys.d.mts +2 -0
  61. package/node_modules/typebox/build/system/memory/keys.mjs +8 -0
  62. package/node_modules/typebox/build/system/memory/update.d.mts +1 -4
  63. package/node_modules/typebox/build/system/memory/update.mjs +43 -16
  64. package/node_modules/typebox/build/type/engine/call/index.d.mts +1 -0
  65. package/node_modules/typebox/build/type/engine/call/index.mjs +1 -0
  66. package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +2 -24
  67. package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +2 -29
  68. package/node_modules/typebox/build/type/engine/evaluate/index.d.mts +1 -0
  69. package/node_modules/typebox/build/type/engine/evaluate/index.mjs +1 -0
  70. package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +5 -1
  71. package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +6 -1
  72. package/node_modules/typebox/build/type/engine/evaluate/property.d.mts +30 -0
  73. package/node_modules/typebox/build/type/engine/evaluate/property.mjs +29 -0
  74. package/node_modules/typebox/build/type/engine/immutable/instantiate_add.d.mts +1 -3
  75. package/node_modules/typebox/build/type/engine/immutable/instantiate_add.mjs +1 -4
  76. package/node_modules/typebox/build/type/engine/object/from_intersect.d.mts +2 -2
  77. package/node_modules/typebox/build/type/engine/object/from_intersect.mjs +2 -2
  78. package/node_modules/typebox/build/type/engine/object/from_union.d.mts +2 -2
  79. package/node_modules/typebox/build/type/engine/object/from_union.mjs +2 -2
  80. package/node_modules/typebox/build/type/engine/optional/instantiate_add.d.mts +1 -3
  81. package/node_modules/typebox/build/type/engine/optional/instantiate_add.mjs +1 -4
  82. package/node_modules/typebox/build/type/engine/readonly/instantiate_add.d.mts +1 -3
  83. package/node_modules/typebox/build/type/engine/readonly/instantiate_add.mjs +1 -4
  84. package/node_modules/typebox/build/type/engine/this/index.d.mts +1 -0
  85. package/node_modules/typebox/build/type/engine/this/index.mjs +1 -0
  86. package/node_modules/typebox/build/value/clone/clone.d.mts +4 -3
  87. package/node_modules/typebox/build/value/clone/clone.mjs +5 -7
  88. package/node_modules/typebox/build/value/repair/from_cyclic.d.mts +2 -0
  89. package/node_modules/typebox/build/value/repair/from_cyclic.mjs +6 -0
  90. package/node_modules/typebox/build/value/shared/union_priority_sort.mjs +25 -14
  91. package/node_modules/typebox/package.json +1 -1
  92. package/node_modules/typebox/readme.md +1 -1
  93. package/package.json +5 -5
  94. package/node_modules/@clawdbot/lobster/dist/src/workflows/types.js +0 -2
  95. package/node_modules/@clawdbot/lobster/node_modules/fast-uri/test/host-delimiter-security.test.js +0 -94
  96. package/node_modules/@clawdbot/lobster/node_modules/fast-uri/test/relative-normalization-security.test.js +0 -152
  97. package/node_modules/typebox/build/system/memory/freeze.d.mts +0 -4
  98. package/node_modules/typebox/build/system/memory/freeze.mjs +0 -6
package/README.md CHANGED
@@ -16,6 +16,14 @@ Restart the Gateway after installing or updating the plugin.
16
16
  - This plugin integrates Lobster with OpenClaw _without core changes_.
17
17
  - Input checkpoints return the question and schema; resume with `responseJson` containing the user's answer as JSON. See [structured input](https://docs.openclaw.ai/tools/lobster#structured-input).
18
18
 
19
+ The tool's optional `cwd` is relative to the Gateway working directory. Nonblank
20
+ values preserve leading and trailing whitespace as part of the directory name;
21
+ blank values use the Gateway working directory.
22
+
23
+ Workflow file paths also preserve their literal spelling, so `" wf.lobster"`
24
+ does not select `wf.lobster`. The embedded runtime still requires a supported
25
+ file extension; a space after `.lobster` is rejected rather than trimmed.
26
+
19
27
  ## Enable
20
28
 
21
29
  Because this tool can trigger side effects (via workflows), it is registered with `optional: true`.
@@ -0,0 +1,32 @@
1
+ import { createJsonSchemaValidatorProvider } from "openclaw/plugin-sdk/json-schema-validator";
2
+ // extensions/lobster/src/lobster-schema-compiler.ts
3
+ const providers = /* @__PURE__ */ new WeakMap();
4
+ const createProvider = () => createJsonSchemaValidatorProvider({
5
+ dialect: "draft7",
6
+ formats: /* @__PURE__ */ new Map(),
7
+ validateSchema: true,
8
+ duplicateIds: "reject"
9
+ });
10
+ /** Keep each dependency-owned Ajv namespace for that engine's module lifetime. */
11
+ const compileLobsterSchema = (schema, options) => {
12
+ let provider = options.addUsedSchema ? providers.get(options.scope) : void 0;
13
+ if (!provider) {
14
+ provider = createProvider();
15
+ if (options.addUsedSchema) providers.set(options.scope, provider);
16
+ }
17
+ const prepared = provider.getValidator(schema);
18
+ const validate = Object.assign((value) => {
19
+ if (prepared.check(value)) {
20
+ validate.errors = null;
21
+ return true;
22
+ }
23
+ const errors = prepared.errors(value);
24
+ validate.errors = (options.allErrors ? errors : errors.slice(0, 1)).map((error) => ({
25
+ instancePath: error.instancePath ?? "",
26
+ message: error.message ?? "schema validation failed"
27
+ }));
28
+ return false;
29
+ }, { errors: null });
30
+ return validate;
31
+ };
32
+ export { compileLobsterSchema };
@@ -1 +1 @@
1
- {"version":3,"entries":[{"output":"index.js","source":"extensions/lobster/index.ts"}],"chunks":[{"output":"index.js","sha256":"2f0522e54f338e6c61ec9741dd883dbced293f62f2839921823682d7e893fc66","facadeSource":"extensions/lobster/index.ts","sources":["extensions/lobster/index.ts","extensions/lobster/src/lobster-runner.ts","extensions/lobster/src/lobster-tool.ts"]}],"unrenderedSources":[]}
1
+ {"version":3,"entries":[{"output":"index.js","source":"extensions/lobster/index.ts"}],"chunks":[{"output":".setup/lobster-schema-compiler-T2XZzavY.mjs","sha256":"b3f3fbb8536c6be50e1c0761257a8d243f2ac811e836c01b98a0033f13e8312d","facadeSource":"extensions/lobster/src/lobster-schema-compiler.ts","sources":["extensions/lobster/src/lobster-schema-compiler.ts"]},{"output":"index.js","sha256":"20c2dc6df86d75791ed9162221ccdcdb3c16929f168687fb0e3ea8f45297964b","facadeSource":"extensions/lobster/index.ts","sources":["extensions/lobster/index.ts","extensions/lobster/src/lobster-runner.ts","extensions/lobster/src/lobster-tool.ts"]}],"unrenderedSources":[]}
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { Readable, Writable } from "node:stream";
9
9
  import { extractErrorCode, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
10
10
  import { isPathInside } from "openclaw/plugin-sdk/file-access-runtime";
11
11
  import { raceWithTimeout } from "openclaw/plugin-sdk/time-runtime";
12
- //#region extensions/lobster/src/lobster-runner.ts
12
+ // extensions/lobster/src/lobster-runner.ts
13
13
  const workflowExts = /* @__PURE__ */ new Set([
14
14
  ".lobster",
15
15
  ".yaml",
@@ -18,7 +18,7 @@ const workflowExts = /* @__PURE__ */ new Set([
18
18
  ]);
19
19
  function resolveLobsterCwd(cwdRaw) {
20
20
  if (typeof cwdRaw !== "string" || !cwdRaw.trim()) return process.cwd();
21
- const cwd = cwdRaw.trim();
21
+ const cwd = cwdRaw;
22
22
  if (path.isAbsolute(cwd)) throw new Error("cwd must be a relative path");
23
23
  const base = process.cwd();
24
24
  const resolved = path.resolve(base, cwd);
@@ -61,7 +61,7 @@ function normalizeEnvelope(envelope, maxStdoutBytes) {
61
61
  async function detectWorkflowFile(candidate, cwd) {
62
62
  const trimmed = candidate.trim();
63
63
  if (!trimmed || trimmed.includes("|") || !workflowExts.has(path.extname(trimmed).toLowerCase())) return null;
64
- const resolved = path.isAbsolute(trimmed) ? trimmed : path.resolve(cwd, trimmed);
64
+ const resolved = path.isAbsolute(candidate) ? candidate : path.resolve(cwd, candidate);
65
65
  try {
66
66
  if (!(await stat(resolved)).isFile()) throw new Error("Workflow path is not a file");
67
67
  return resolved;
@@ -71,17 +71,24 @@ async function detectWorkflowFile(candidate, cwd) {
71
71
  }
72
72
  }
73
73
  async function loadEmbeddedToolRuntimeFromPackage() {
74
- return await import([
74
+ const { getRuntimeExecutionProfile } = await import("openclaw/plugin-sdk/runtime-profile");
75
+ const profile = getRuntimeExecutionProfile();
76
+ const runtime = await import([
75
77
  "@clawdbot",
76
78
  "lobster",
77
79
  "core"
78
80
  ].join("/"));
81
+ if (profile !== "embedded-aot") return runtime;
82
+ const { compileLobsterSchema } = await import("./.setup/lobster-schema-compiler-T2XZzavY.mjs");
83
+ return {
84
+ runToolRequest: (params) => runtime.withSchemaCompiler(compileLobsterSchema, () => runtime.runToolRequest(params)),
85
+ resumeToolRequest: (params) => runtime.withSchemaCompiler(compileLobsterSchema, () => runtime.resumeToolRequest(params))
86
+ };
79
87
  }
80
- function createEmbeddedLobsterRunner(options) {
81
- const loadRuntime = options?.loadRuntime ?? loadEmbeddedToolRuntimeFromPackage;
88
+ function createEmbeddedLobsterRunner() {
82
89
  let runtimePromise;
83
90
  return { async run(params) {
84
- runtimePromise ??= loadRuntime();
91
+ runtimePromise ??= loadEmbeddedToolRuntimeFromPackage();
85
92
  const runtime = await runtimePromise;
86
93
  const controller = new AbortController();
87
94
  return await raceWithTimeout(async () => {
@@ -97,8 +104,8 @@ function createEmbeddedLobsterRunner(options) {
97
104
  };
98
105
  let envelope;
99
106
  if (params.action === "run") {
100
- const pipeline = params.pipeline?.trim() ?? "";
101
- if (!pipeline) throw new Error("pipeline required");
107
+ const pipeline = params.pipeline ?? "";
108
+ if (!pipeline.trim()) throw new Error("pipeline required");
102
109
  const filePath = await detectWorkflowFile(pipeline, params.cwd);
103
110
  if (filePath) {
104
111
  const parsedArgsJson = params.argsJson?.trim() ?? "";
@@ -151,9 +158,8 @@ function createEmbeddedLobsterRunner(options) {
151
158
  });
152
159
  } };
153
160
  }
154
- //#endregion
155
- //#region extensions/lobster/src/lobster-tool.ts
156
- function createLobsterTool(api) {
161
+ // extensions/lobster/src/lobster-tool.ts
162
+ function createLobsterTool() {
157
163
  const runner = createEmbeddedLobsterRunner();
158
164
  return {
159
165
  name: "lobster",
@@ -179,7 +185,6 @@ function createLobsterTool(api) {
179
185
  const cwd = resolveLobsterCwd(params.cwd);
180
186
  const timeoutMs = readPositiveIntegerParam(params, "timeoutMs") ?? 2e4;
181
187
  const maxStdoutBytes = readPositiveIntegerParam(params, "maxStdoutBytes") ?? 512e3;
182
- if (api.runtime?.version && api.logger?.debug) api.logger.debug(`lobster plugin runtime=${api.runtime.version}`);
183
188
  const runnerParams = {
184
189
  action,
185
190
  ...typeof params.pipeline === "string" ? { pipeline: params.pipeline } : {},
@@ -198,8 +203,7 @@ function createLobsterTool(api) {
198
203
  }
199
204
  };
200
205
  }
201
- //#endregion
202
- //#region extensions/lobster/index.ts
206
+ // extensions/lobster/index.ts
203
207
  var lobster_default = definePluginEntry({
204
208
  id: "lobster",
205
209
  name: "Lobster",
@@ -207,12 +211,11 @@ var lobster_default = definePluginEntry({
207
211
  register(api) {
208
212
  api.registerTool((ctx) => {
209
213
  if (ctx.sandboxed) return null;
210
- return createLobsterTool(api);
214
+ return createLobsterTool();
211
215
  }, {
212
216
  optional: true,
213
217
  workspaceAccess: "execute"
214
218
  });
215
219
  }
216
220
  });
217
- //#endregion
218
221
  export { lobster_default as default };
@@ -6,89 +6,9 @@ import { Ajv } from "ajv";
6
6
  import { diffAndStore, ensureDirectory, atomicWriteWasPublished, isJsonSyntaxError, readStateJsonWithLock, stableStringify, withFileLock, writeFileAtomic, } from "../../state/store.js";
7
7
  import { createCompileCached } from "../../validation.js";
8
8
  import { httpResponseLimitFromEnv, readResponseTextCapped } from "../../read_response_text.js";
9
+ import { validatePayload, validateResponseEnvelope } from "./llm_invoke_validators.generated.js";
9
10
  const ajv = new Ajv({ allErrors: true, strict: false });
10
11
  const compileCachedLocal = createCompileCached(ajv);
11
- const artifactSchema = {
12
- type: "object",
13
- properties: {
14
- kind: { type: "string" },
15
- role: { type: "string" },
16
- name: { type: "string" },
17
- mimeType: { type: "string" },
18
- text: { type: "string" },
19
- data: {},
20
- uri: { type: "string" },
21
- },
22
- additionalProperties: true,
23
- };
24
- const payloadSchema = {
25
- type: "object",
26
- properties: {
27
- prompt: { type: "string", minLength: 1 },
28
- model: { type: "string", minLength: 1 },
29
- artifacts: { type: "array", items: artifactSchema },
30
- artifactHashes: { type: "array", items: { type: "string", minLength: 10 } },
31
- schemaVersion: { type: "string" },
32
- metadata: { type: "object", additionalProperties: true },
33
- outputSchema: { type: "object", additionalProperties: true },
34
- temperature: { type: "number" },
35
- maxOutputTokens: { type: "number" },
36
- retryContext: {
37
- type: "object",
38
- properties: {
39
- attempt: { type: "number" },
40
- validationErrors: { type: "array", items: { type: "string" } },
41
- },
42
- additionalProperties: false,
43
- },
44
- },
45
- required: ["prompt", "artifacts", "artifactHashes"],
46
- additionalProperties: false,
47
- };
48
- const responseSchema = {
49
- type: "object",
50
- properties: {
51
- ok: { type: "boolean" },
52
- result: {
53
- type: "object",
54
- properties: {
55
- runId: { type: "string" },
56
- model: { type: "string" },
57
- prompt: { type: "string" },
58
- status: { type: "string" },
59
- output: {
60
- type: "object",
61
- properties: {
62
- text: { type: "string" },
63
- data: {},
64
- format: { type: "string" },
65
- },
66
- required: [],
67
- additionalProperties: true,
68
- },
69
- usage: {
70
- type: "object",
71
- properties: {
72
- inputTokens: { type: "number" },
73
- outputTokens: { type: "number" },
74
- totalTokens: { type: "number" },
75
- },
76
- additionalProperties: true,
77
- },
78
- warnings: { type: "array", items: { type: "string" } },
79
- metadata: { type: "object", additionalProperties: true },
80
- diagnostics: { type: "object", additionalProperties: true },
81
- },
82
- required: ["output"],
83
- additionalProperties: true,
84
- },
85
- error: { type: "object", additionalProperties: true },
86
- },
87
- required: ["ok"],
88
- additionalProperties: true,
89
- };
90
- const validatePayload = ajv.compile(payloadSchema);
91
- const validateResponseEnvelope = ajv.compile(responseSchema);
92
12
  const DEFAULT_MAX_VALIDATION_RETRIES = 1;
93
13
  const STATE_VERSION = 1;
94
14
  // Identity version of the response cache key. See computeCacheKey.
@@ -957,4 +877,3 @@ async function* streamOf(items) {
957
877
  for (const item of items)
958
878
  yield item;
959
879
  }
960
- //# sourceMappingURL=llm_invoke.js.map
@@ -0,0 +1,79 @@
1
+ const artifactSchema = {
2
+ type: "object",
3
+ properties: {
4
+ kind: { type: "string" },
5
+ role: { type: "string" },
6
+ name: { type: "string" },
7
+ mimeType: { type: "string" },
8
+ text: { type: "string" },
9
+ data: {},
10
+ uri: { type: "string" },
11
+ },
12
+ additionalProperties: true,
13
+ };
14
+ export const payloadSchema = {
15
+ type: "object",
16
+ properties: {
17
+ prompt: { type: "string", minLength: 1 },
18
+ model: { type: "string", minLength: 1 },
19
+ artifacts: { type: "array", items: artifactSchema },
20
+ artifactHashes: { type: "array", items: { type: "string", minLength: 10 } },
21
+ schemaVersion: { type: "string" },
22
+ metadata: { type: "object", additionalProperties: true },
23
+ outputSchema: { type: "object", additionalProperties: true },
24
+ temperature: { type: "number" },
25
+ maxOutputTokens: { type: "number" },
26
+ retryContext: {
27
+ type: "object",
28
+ properties: {
29
+ attempt: { type: "number" },
30
+ validationErrors: { type: "array", items: { type: "string" } },
31
+ },
32
+ additionalProperties: false,
33
+ },
34
+ },
35
+ required: ["prompt", "artifacts", "artifactHashes"],
36
+ additionalProperties: false,
37
+ };
38
+ export const responseSchema = {
39
+ type: "object",
40
+ properties: {
41
+ ok: { type: "boolean" },
42
+ result: {
43
+ type: "object",
44
+ properties: {
45
+ runId: { type: "string" },
46
+ model: { type: "string" },
47
+ prompt: { type: "string" },
48
+ status: { type: "string" },
49
+ output: {
50
+ type: "object",
51
+ properties: {
52
+ text: { type: "string" },
53
+ data: {},
54
+ format: { type: "string" },
55
+ },
56
+ required: [],
57
+ additionalProperties: true,
58
+ },
59
+ usage: {
60
+ type: "object",
61
+ properties: {
62
+ inputTokens: { type: "number" },
63
+ outputTokens: { type: "number" },
64
+ totalTokens: { type: "number" },
65
+ },
66
+ additionalProperties: true,
67
+ },
68
+ warnings: { type: "array", items: { type: "string" } },
69
+ metadata: { type: "object", additionalProperties: true },
70
+ diagnostics: { type: "object", additionalProperties: true },
71
+ },
72
+ required: ["output"],
73
+ additionalProperties: true,
74
+ },
75
+ error: { type: "object", additionalProperties: true },
76
+ },
77
+ required: ["ok"],
78
+ additionalProperties: true,
79
+ };