@openclaw/lobster 2026.8.1-beta.3 → 2026.8.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.
- package/dist/index.js +130 -112
- package/node_modules/typebox/build/format/date.d.mts +1 -1
- package/node_modules/typebox/build/format/date.mjs +1 -1
- package/node_modules/typebox/build/format/date_time.d.mts +2 -2
- package/node_modules/typebox/build/format/date_time.mjs +3 -3
- package/node_modules/typebox/build/format/email.d.mts +1 -1
- package/node_modules/typebox/build/format/email.mjs +2 -2
- package/node_modules/typebox/build/format/hostname.mjs +2 -10
- package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
- package/node_modules/typebox/build/format/idn_email.mjs +3 -3
- package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
- package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
- package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
- package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
- package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
- package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
- package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/idn-hostname.mjs +23 -0
- package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
- package/node_modules/typebox/build/format/idna/index.mjs +2 -0
- package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
- package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
- package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
- package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
- package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
- package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
- package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
- package/node_modules/typebox/build/format/ipv4.mjs +2 -32
- package/node_modules/typebox/build/format/ipv6.mjs +2 -61
- package/node_modules/typebox/build/format/iri.d.mts +2 -2
- package/node_modules/typebox/build/format/iri.mjs +26 -8
- package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
- package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
- package/node_modules/typebox/build/format/regex.d.mts +1 -2
- package/node_modules/typebox/build/format/regex.mjs +2 -6
- package/node_modules/typebox/build/format/time.d.mts +2 -2
- package/node_modules/typebox/build/format/time.mjs +19 -14
- package/node_modules/typebox/build/format/uri.d.mts +1 -1
- package/node_modules/typebox/build/format/uri.mjs +3 -130
- package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
- package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
- package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
- package/node_modules/typebox/build/format/uri_template.mjs +4 -5
- package/node_modules/typebox/build/format/url.d.mts +3 -3
- package/node_modules/typebox/build/format/url.mjs +4 -5
- package/node_modules/typebox/build/guard/emit.d.mts +3 -1
- package/node_modules/typebox/build/guard/emit.mjs +12 -5
- package/node_modules/typebox/build/guard/guard.d.mts +8 -2
- package/node_modules/typebox/build/guard/guard.mjs +25 -4
- package/node_modules/typebox/build/guard/string.d.mts +2 -2
- package/node_modules/typebox/build/guard/string.mjs +7 -7
- package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
- package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
- package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
- package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
- package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
- package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
- package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
- package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
- package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
- package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
- package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
- package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
- package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
- package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
- package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
- package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
- package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
- package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
- package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
- package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
- package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
- package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
- package/node_modules/typebox/build/schema/types/index.mjs +0 -2
- package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
- package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
- package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
- package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
- package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
- package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
- package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
- package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
- package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
- package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
- package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
- package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
- package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
- package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
- package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
- package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
- package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
- package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
- package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
- package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
- package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
- package/node_modules/typebox/build/type/script/parser.mjs +27 -23
- package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
- package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
- package/node_modules/typebox/package.json +27 -27
- package/node_modules/typebox/readme.md +79 -82
- package/package.json +5 -5
- package/node_modules/typebox/build/format/_idna.d.mts +0 -2
- package/node_modules/typebox/build/format/_idna.mjs +0 -246
- package/node_modules/typebox/build/format/_puny.d.mts +0 -1
- package/node_modules/typebox/build/format/_puny.mjs +0 -77
- package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
- package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
- package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
- package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
- package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
- package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
package/dist/index.js
CHANGED
|
@@ -35,10 +35,10 @@ function createLimitedSink(maxBytes, label) {
|
|
|
35
35
|
callback();
|
|
36
36
|
} });
|
|
37
37
|
}
|
|
38
|
-
function normalizeEnvelope(envelope) {
|
|
38
|
+
function normalizeEnvelope(envelope, maxStdoutBytes) {
|
|
39
39
|
if (!envelope.ok) throw new Error(envelope.error?.message ?? "lobster runtime failed");
|
|
40
40
|
if (envelope.status === "needs_input") throw new Error("Lobster input requests are not supported by the OpenClaw Lobster tool yet");
|
|
41
|
-
|
|
41
|
+
const normalized = {
|
|
42
42
|
ok: true,
|
|
43
43
|
status: envelope.status ?? "ok",
|
|
44
44
|
output: Array.isArray(envelope.output) ? envelope.output : [],
|
|
@@ -50,6 +50,8 @@ function normalizeEnvelope(envelope) {
|
|
|
50
50
|
...envelope.requiresApproval.approvalId ? { approvalId: envelope.requiresApproval.approvalId } : {}
|
|
51
51
|
} : null
|
|
52
52
|
};
|
|
53
|
+
if (Buffer.byteLength(JSON.stringify(normalized, null, 2), "utf8") > maxStdoutBytes) throw new Error("lobster runtime result exceeded maxStdoutBytes");
|
|
54
|
+
return normalized;
|
|
53
55
|
}
|
|
54
56
|
function isMissingPathError(error) {
|
|
55
57
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
@@ -112,6 +114,7 @@ function createEmbeddedLobsterRunner(options) {
|
|
|
112
114
|
const runtime = await runtimePromise;
|
|
113
115
|
return await withTimeout(params.timeoutMs, async (signal) => {
|
|
114
116
|
const ctx = createEmbeddedToolContext(params, signal);
|
|
117
|
+
let envelope;
|
|
115
118
|
if (params.action === "run") {
|
|
116
119
|
const pipeline = params.pipeline?.trim() ?? "";
|
|
117
120
|
if (!pipeline) throw new Error("pipeline required");
|
|
@@ -124,27 +127,28 @@ function createEmbeddedLobsterRunner(options) {
|
|
|
124
127
|
} catch {
|
|
125
128
|
throw new Error("run --args-json must be valid JSON");
|
|
126
129
|
}
|
|
127
|
-
|
|
130
|
+
envelope = await runtime.runToolRequest({
|
|
128
131
|
filePath,
|
|
129
132
|
args,
|
|
130
133
|
ctx
|
|
131
|
-
})
|
|
132
|
-
}
|
|
133
|
-
return normalizeEnvelope(await runtime.runToolRequest({
|
|
134
|
+
});
|
|
135
|
+
} else envelope = await runtime.runToolRequest({
|
|
134
136
|
pipeline,
|
|
135
137
|
ctx
|
|
136
|
-
})
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
const token = params.token?.trim() ?? "";
|
|
141
|
+
const approvalId = params.approvalId?.trim() ?? "";
|
|
142
|
+
if (!token && !approvalId) throw new Error("token or approvalId required");
|
|
143
|
+
if (typeof params.approve !== "boolean") throw new Error("approve required");
|
|
144
|
+
envelope = await runtime.resumeToolRequest({
|
|
145
|
+
...token ? { token } : {},
|
|
146
|
+
...approvalId ? { approvalId } : {},
|
|
147
|
+
approved: params.approve,
|
|
148
|
+
ctx
|
|
149
|
+
});
|
|
137
150
|
}
|
|
138
|
-
|
|
139
|
-
const approvalId = params.approvalId?.trim() ?? "";
|
|
140
|
-
if (!token && !approvalId) throw new Error("token or approvalId required");
|
|
141
|
-
if (typeof params.approve !== "boolean") throw new Error("approve required");
|
|
142
|
-
return normalizeEnvelope(await runtime.resumeToolRequest({
|
|
143
|
-
...token ? { token } : {},
|
|
144
|
-
...approvalId ? { approvalId } : {},
|
|
145
|
-
approved: params.approve,
|
|
146
|
-
ctx
|
|
147
|
-
}));
|
|
151
|
+
return normalizeEnvelope(envelope, Math.max(1024, params.maxStdoutBytes));
|
|
148
152
|
});
|
|
149
153
|
} };
|
|
150
154
|
}
|
|
@@ -152,29 +156,25 @@ function createEmbeddedLobsterRunner(options) {
|
|
|
152
156
|
//#region extensions/lobster/src/lobster-taskflow.ts
|
|
153
157
|
function toJsonLike(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
154
158
|
if (value === null) return null;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
jsonObject[key] = toJsonLike(entry, seen);
|
|
172
|
-
}
|
|
173
|
-
seen.delete(value);
|
|
174
|
-
return jsonObject;
|
|
175
|
-
}
|
|
159
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : String(value);
|
|
160
|
+
if (typeof value === "bigint") return value.toString();
|
|
161
|
+
if (typeof value === "boolean" || typeof value === "string") return value;
|
|
162
|
+
if (typeof value !== "object") return null;
|
|
163
|
+
if (value instanceof Date) return value.toISOString();
|
|
164
|
+
if (seen.has(value)) return "[Circular]";
|
|
165
|
+
seen.add(value);
|
|
166
|
+
if (Array.isArray(value)) {
|
|
167
|
+
const jsonArray = value.map((item) => toJsonLike(item, seen));
|
|
168
|
+
seen.delete(value);
|
|
169
|
+
return jsonArray;
|
|
170
|
+
}
|
|
171
|
+
const jsonObject = {};
|
|
172
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
173
|
+
if (entry === void 0 || typeof entry === "function" || typeof entry === "symbol") continue;
|
|
174
|
+
jsonObject[key] = toJsonLike(entry, seen);
|
|
176
175
|
}
|
|
177
|
-
|
|
176
|
+
seen.delete(value);
|
|
177
|
+
return jsonObject;
|
|
178
178
|
}
|
|
179
179
|
function buildApprovalWaitState(envelope) {
|
|
180
180
|
const approval = envelope.requiresApproval;
|
|
@@ -186,40 +186,51 @@ function buildApprovalWaitState(envelope) {
|
|
|
186
186
|
...approval?.approvalId ? { approvalId: approval.approvalId } : {}
|
|
187
187
|
};
|
|
188
188
|
}
|
|
189
|
-
function
|
|
190
|
-
const { taskFlow, flow, envelope, waitingStep } = params;
|
|
191
|
-
const flowMutation = {
|
|
192
|
-
flowId: flow.flowId,
|
|
193
|
-
expectedRevision: flow.revision
|
|
194
|
-
};
|
|
195
|
-
if (!envelope.ok) return taskFlow.fail(flowMutation);
|
|
196
|
-
if (envelope.status === "needs_approval") return taskFlow.setWaiting({
|
|
197
|
-
...flowMutation,
|
|
198
|
-
currentStep: waitingStep,
|
|
199
|
-
waitJson: buildApprovalWaitState(envelope)
|
|
200
|
-
});
|
|
201
|
-
return taskFlow.finish(flowMutation);
|
|
202
|
-
}
|
|
203
|
-
async function executeManagedLobsterFlow(params, flow, failureFlowId = flow.flowId) {
|
|
189
|
+
async function executeManagedLobsterFlow(params, flow) {
|
|
204
190
|
try {
|
|
205
191
|
const envelope = await params.runner.run(params.runnerParams);
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
192
|
+
if (envelope.ok && envelope.status === "cancelled") try {
|
|
193
|
+
const mutation = await params.taskFlow.cancel({
|
|
194
|
+
flowId: flow.flowId,
|
|
195
|
+
cfg: params.config
|
|
196
|
+
});
|
|
197
|
+
return mutation.cancelled ? {
|
|
198
|
+
ok: true,
|
|
199
|
+
envelope,
|
|
200
|
+
flow,
|
|
201
|
+
mutation
|
|
202
|
+
} : {
|
|
203
|
+
ok: false,
|
|
204
|
+
flow,
|
|
205
|
+
mutation,
|
|
206
|
+
error: /* @__PURE__ */ new Error(`TaskFlow cancellation failed: ${mutation.reason ?? "unknown"}`)
|
|
207
|
+
};
|
|
208
|
+
} catch (error) {
|
|
209
|
+
return {
|
|
210
|
+
ok: false,
|
|
211
|
+
flow,
|
|
212
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
const flowMutation = {
|
|
216
|
+
flowId: flow.flowId,
|
|
217
|
+
expectedRevision: flow.revision
|
|
218
|
+
};
|
|
212
219
|
if (!envelope.ok) return {
|
|
213
220
|
ok: false,
|
|
214
221
|
flow,
|
|
215
|
-
mutation,
|
|
222
|
+
mutation: params.taskFlow.fail(flowMutation),
|
|
216
223
|
error: new Error(envelope.error.message)
|
|
217
224
|
};
|
|
218
225
|
return {
|
|
219
226
|
ok: true,
|
|
220
227
|
envelope,
|
|
221
228
|
flow,
|
|
222
|
-
mutation
|
|
229
|
+
mutation: envelope.status === "needs_approval" ? params.taskFlow.setWaiting({
|
|
230
|
+
...flowMutation,
|
|
231
|
+
currentStep: params.waitingStep ?? "await_lobster_approval",
|
|
232
|
+
waitJson: buildApprovalWaitState(envelope)
|
|
233
|
+
}) : params.taskFlow.finish(flowMutation)
|
|
223
234
|
};
|
|
224
235
|
} catch (error) {
|
|
225
236
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -228,7 +239,7 @@ async function executeManagedLobsterFlow(params, flow, failureFlowId = flow.flow
|
|
|
228
239
|
ok: false,
|
|
229
240
|
flow,
|
|
230
241
|
mutation: params.taskFlow.fail({
|
|
231
|
-
flowId:
|
|
242
|
+
flowId: flow.flowId,
|
|
232
243
|
expectedRevision: flow.revision
|
|
233
244
|
}),
|
|
234
245
|
error: err
|
|
@@ -268,7 +279,7 @@ async function resumeManagedLobsterFlow(params) {
|
|
|
268
279
|
mutation: resumed,
|
|
269
280
|
error: /* @__PURE__ */ new Error(`TaskFlow resume failed: ${resumed.code}`)
|
|
270
281
|
};
|
|
271
|
-
return await executeManagedLobsterFlow(params, resumed.flow
|
|
282
|
+
return await executeManagedLobsterFlow(params, resumed.flow);
|
|
272
283
|
}
|
|
273
284
|
//#endregion
|
|
274
285
|
//#region extensions/lobster/src/lobster-tool.ts
|
|
@@ -300,28 +311,29 @@ function parseOptionalFlowStateJson(value) {
|
|
|
300
311
|
function isEmptyJsonObject(value) {
|
|
301
312
|
return value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
|
|
302
313
|
}
|
|
303
|
-
function
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
|
|
314
|
+
function parseManagedFlowParams(action, params, runnerParams) {
|
|
315
|
+
if (action === "run") {
|
|
316
|
+
const controllerId = readOptionalTrimmedString(params.flowControllerId, "flowControllerId");
|
|
317
|
+
const goal = readOptionalTrimmedString(params.flowGoal, "flowGoal");
|
|
318
|
+
const currentStep = readOptionalTrimmedString(params.flowCurrentStep, "flowCurrentStep");
|
|
319
|
+
const waitingStep = readOptionalTrimmedString(params.flowWaitingStep, "flowWaitingStep");
|
|
320
|
+
const stateJson = parseOptionalFlowStateJson(params.flowStateJson);
|
|
321
|
+
const resumeFlowId = readOptionalTrimmedString(params.flowId, "flowId");
|
|
322
|
+
const resumeRevision = readOptionalNumber(params.flowExpectedRevision, "flowExpectedRevision");
|
|
323
|
+
const stateJsonSignalsRunMode = stateJson !== void 0 && !isEmptyJsonObject(stateJson);
|
|
324
|
+
if (resumeFlowId !== void 0 || resumeRevision !== void 0 && resumeRevision !== 0) throw new Error("run action does not accept flowId or flowExpectedRevision");
|
|
325
|
+
if (controllerId === void 0 && goal === void 0 && currentStep === void 0 && waitingStep === void 0 && !stateJsonSignalsRunMode) return null;
|
|
326
|
+
if (!controllerId) throw new Error("flowControllerId required when using managed TaskFlow run mode");
|
|
327
|
+
if (!goal) throw new Error("flowGoal required when using managed TaskFlow run mode");
|
|
328
|
+
return {
|
|
329
|
+
action,
|
|
330
|
+
controllerId,
|
|
331
|
+
goal,
|
|
332
|
+
...currentStep ? { currentStep } : {},
|
|
333
|
+
...waitingStep ? { waitingStep } : {},
|
|
334
|
+
...stateJson !== void 0 ? { stateJson } : {}
|
|
335
|
+
};
|
|
336
|
+
}
|
|
325
337
|
const flowId = readOptionalTrimmedString(params.flowId, "flowId");
|
|
326
338
|
const expectedRevision = readOptionalNumber(params.flowExpectedRevision, "flowExpectedRevision");
|
|
327
339
|
const currentStep = readOptionalTrimmedString(params.flowCurrentStep, "flowCurrentStep");
|
|
@@ -337,13 +349,21 @@ function parseResumeFlowParams(params) {
|
|
|
337
349
|
if (!(flowId !== void 0 || expectedRevision !== void 0 && expectedRevision !== 0 || currentStep !== void 0 || waitingStep !== void 0)) return null;
|
|
338
350
|
if (!flowId) throw new Error("flowId required when using managed TaskFlow resume mode");
|
|
339
351
|
if (expectedRevision === void 0) throw new Error("flowExpectedRevision required when using managed TaskFlow resume mode");
|
|
340
|
-
|
|
352
|
+
const credentialParams = token ? { token: runnerParams.token ?? token } : approvalId ? { approvalId: runnerParams.approvalId ?? approvalId } : null;
|
|
353
|
+
if (!credentialParams) throw new Error("token or approvalId required when using managed TaskFlow resume mode");
|
|
341
354
|
if (approve === void 0) throw new Error("approve required when using managed TaskFlow resume mode");
|
|
342
355
|
return {
|
|
356
|
+
action,
|
|
343
357
|
flowId,
|
|
344
358
|
expectedRevision,
|
|
345
359
|
...currentStep ? { currentStep } : {},
|
|
346
|
-
...waitingStep ? { waitingStep } : {}
|
|
360
|
+
...waitingStep ? { waitingStep } : {},
|
|
361
|
+
runnerParams: {
|
|
362
|
+
...runnerParams,
|
|
363
|
+
...credentialParams,
|
|
364
|
+
action,
|
|
365
|
+
approve
|
|
366
|
+
}
|
|
347
367
|
};
|
|
348
368
|
}
|
|
349
369
|
function resolveManagedFlowToolResult(result) {
|
|
@@ -402,30 +422,28 @@ function createLobsterTool(api, options) {
|
|
|
402
422
|
maxStdoutBytes
|
|
403
423
|
};
|
|
404
424
|
const taskFlow = options?.taskFlow;
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
}));
|
|
428
|
-
}
|
|
425
|
+
const flowParams = parseManagedFlowParams(action, params, runnerParams);
|
|
426
|
+
if (flowParams?.action === "run") return resolveManagedFlowToolResult(await runManagedLobsterFlow({
|
|
427
|
+
taskFlow: requireTaskFlowRuntime(taskFlow, "run"),
|
|
428
|
+
config: api.config,
|
|
429
|
+
runner,
|
|
430
|
+
runnerParams,
|
|
431
|
+
controllerId: flowParams.controllerId,
|
|
432
|
+
goal: flowParams.goal,
|
|
433
|
+
...flowParams.stateJson !== void 0 ? { stateJson: flowParams.stateJson } : {},
|
|
434
|
+
...flowParams.currentStep ? { currentStep: flowParams.currentStep } : {},
|
|
435
|
+
...flowParams.waitingStep ? { waitingStep: flowParams.waitingStep } : {}
|
|
436
|
+
}));
|
|
437
|
+
if (flowParams?.action === "resume") return resolveManagedFlowToolResult(await resumeManagedLobsterFlow({
|
|
438
|
+
taskFlow: requireTaskFlowRuntime(taskFlow, "resume"),
|
|
439
|
+
config: api.config,
|
|
440
|
+
runner,
|
|
441
|
+
runnerParams: flowParams.runnerParams,
|
|
442
|
+
flowId: flowParams.flowId,
|
|
443
|
+
expectedRevision: flowParams.expectedRevision,
|
|
444
|
+
...flowParams.currentStep ? { currentStep: flowParams.currentStep } : {},
|
|
445
|
+
...flowParams.waitingStep ? { waitingStep: flowParams.waitingStep } : {}
|
|
446
|
+
}));
|
|
429
447
|
const envelope = await runner.run(runnerParams);
|
|
430
448
|
if (!envelope.ok) throw new Error(envelope.error.message);
|
|
431
449
|
return jsonResult(envelope);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Returns true if the value is a ISO8601 DateTime string
|
|
3
|
-
* @
|
|
3
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc3339
|
|
4
4
|
* @example `2020-12-12T20:20:40+00:00`
|
|
5
5
|
*/
|
|
6
|
-
export declare function IsDateTime(value: string
|
|
6
|
+
export declare function IsDateTime(value: string): boolean;
|
|
@@ -2,10 +2,10 @@ import { IsDate } from './date.mjs';
|
|
|
2
2
|
import { IsTime } from './time.mjs';
|
|
3
3
|
/**
|
|
4
4
|
* Returns true if the value is a ISO8601 DateTime string
|
|
5
|
-
* @
|
|
5
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc3339
|
|
6
6
|
* @example `2020-12-12T20:20:40+00:00`
|
|
7
7
|
*/
|
|
8
|
-
export function IsDateTime(value
|
|
8
|
+
export function IsDateTime(value) {
|
|
9
9
|
const dateTime = value.split(/T/i);
|
|
10
|
-
return dateTime.length === 2 && IsDate(dateTime[0]) && IsTime(dateTime[1]
|
|
10
|
+
return dateTime.length === 2 && IsDate(dateTime[0]) && IsTime(dateTime[1]);
|
|
11
11
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const Email = /^(
|
|
1
|
+
const Email = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[^"\\]|\\.)*")@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*|\[(?:IPv6:[a-f0-9:]+|(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})\])$/i;
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is an Email
|
|
4
|
-
* @specification
|
|
4
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc5322
|
|
5
5
|
*/
|
|
6
6
|
export function IsEmail(value) {
|
|
7
7
|
return Email.test(value);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as Idna from './
|
|
1
|
+
import * as Idna from './idna/index.mjs';
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is a valid hostname.
|
|
4
4
|
* @specification https://tools.ietf.org/html/rfc1123
|
|
@@ -6,13 +6,5 @@ import * as Idna from './_idna.mjs';
|
|
|
6
6
|
* @specification https://tools.ietf.org/html/rfc5892
|
|
7
7
|
*/
|
|
8
8
|
export function IsHostname(value) {
|
|
9
|
-
|
|
10
|
-
return false;
|
|
11
|
-
if (value.charCodeAt(value.length - 1) === 46)
|
|
12
|
-
return false;
|
|
13
|
-
for (const label of value.split('.')) {
|
|
14
|
-
if (!Idna.IsLabel(label))
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
return true;
|
|
9
|
+
return Idna.IsHostname(value);
|
|
18
10
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const IdnEmail = /^(
|
|
1
|
+
const IdnEmail = /^(?:[A-Za-z0-9!#$%&'*+\/=?^_`{|}~\u{0080}-\u{10FFFF}-]+(?:\.[A-Za-z0-9!#$%&'*+\/=?^_`{|}~\u{0080}-\u{10FFFF}-]+)*|"(?:[^"\\]|\\.)*")@[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,62})(?<!-)(?:\.[\p{L}\p{N}](?:[\p{L}\p{N}-]{0,62})(?<!-))*$/iu;
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is an IdnEmail
|
|
4
|
-
* @specification
|
|
4
|
+
* @specification https://datatracker.ietf.org/doc/html/rfc4952
|
|
5
5
|
*/
|
|
6
6
|
export function IsIdnEmail(value) {
|
|
7
|
-
return IdnEmail.test(value);
|
|
7
|
+
return IdnEmail.test(value.normalize('NFC'));
|
|
8
8
|
}
|
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
* @specification https://tools.ietf.org/html/rfc3490
|
|
4
4
|
* @specification https://tools.ietf.org/html/rfc5891
|
|
5
5
|
* @specification https://tools.ietf.org/html/rfc5892
|
|
6
|
+
* @specification https://tools.ietf.org/html/rfc5893
|
|
6
7
|
*/
|
|
7
8
|
export declare function IsIdnHostname(value: string): boolean;
|
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Idna from './idna/index.mjs';
|
|
2
2
|
/**
|
|
3
3
|
* Returns true if the value is a valid internationalized (IDN) hostname.
|
|
4
4
|
* @specification https://tools.ietf.org/html/rfc3490
|
|
5
5
|
* @specification https://tools.ietf.org/html/rfc5891
|
|
6
6
|
* @specification https://tools.ietf.org/html/rfc5892
|
|
7
|
+
* @specification https://tools.ietf.org/html/rfc5893
|
|
7
8
|
*/
|
|
8
9
|
export function IsIdnHostname(value) {
|
|
9
|
-
|
|
10
|
-
return false;
|
|
11
|
-
const canonical = value.normalize('NFC').replace(/[\u002E\u3002\uFF0E\uFF61]/g, '.');
|
|
12
|
-
if (canonical.length > 253)
|
|
13
|
-
return false;
|
|
14
|
-
for (const label of canonical.split('.')) {
|
|
15
|
-
if (!IsIdnLabel(label))
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
return true;
|
|
10
|
+
return Idna.IsIdnHostname(value);
|
|
19
11
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// deno-fmt-ignore-file
|
|
2
|
+
import * as FormatPuny from './puny.mjs';
|
|
3
|
+
import * as Pattern from '../pattern/pattern.mjs';
|
|
4
|
+
// ------------------------------------------------------------------
|
|
5
|
+
// LOCAL REGEX: Allowed Bidi classes per direction (RFC 5893)
|
|
6
|
+
// ------------------------------------------------------------------
|
|
7
|
+
const RE_RTL_ALLOWED = /^(?:R|AL|AN|EN|ES|CS|ET|ON|BN|NSM)$/;
|
|
8
|
+
const RE_LTR_ALLOWED = /^(?:L|EN|ES|CS|ET|ON|BN|NSM)$/;
|
|
9
|
+
const RE_RTL_CLASSES = /^(?:R|AL|AN)$/;
|
|
10
|
+
// ------------------------------------------------------------------
|
|
11
|
+
// HasBidiChars
|
|
12
|
+
//
|
|
13
|
+
// Decodes a punycode label to its Unicode form (if it is one) and
|
|
14
|
+
// checks whether the result is an RTL label per RFC 5893 §1.4.
|
|
15
|
+
// ------------------------------------------------------------------
|
|
16
|
+
export function HasBidiChars(value) {
|
|
17
|
+
if (FormatPuny.IsAcePrefixed(value)) {
|
|
18
|
+
try {
|
|
19
|
+
return HasRightToLeftCharacters(FormatPuny.Decode(value.slice(4).toLowerCase()));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return HasRightToLeftCharacters(value);
|
|
26
|
+
}
|
|
27
|
+
// ------------------------------------------------------------------
|
|
28
|
+
// GetBidiClass
|
|
29
|
+
// ------------------------------------------------------------------
|
|
30
|
+
function GetBidiClass(codePoint) {
|
|
31
|
+
const char = String.fromCodePoint(codePoint);
|
|
32
|
+
return (Pattern.RE_EUROPEAN_NUMBER.test(char) ? 'EN' :
|
|
33
|
+
Pattern.RE_ARABIC_INDIC_DIGIT.test(char) ? 'AN' :
|
|
34
|
+
// Pattern.RE_EUROPEAN_SEPARATOR.test(char) ? 'ES' : // (no-spec-coverage)
|
|
35
|
+
// Pattern.RE_COMMON_SEPARATOR.test(char) ? 'CS' : // (no-spec-coverage)
|
|
36
|
+
Pattern.RE_MARK_NONSPACING.test(char) ? 'NSM' :
|
|
37
|
+
Pattern.RE_SCRIPT_HEBREW.test(char) ? 'R' :
|
|
38
|
+
Pattern.RE_SCRIPT_ARABIC_LETTER.test(char) ? 'AL' :
|
|
39
|
+
Pattern.RE_LETTER.test(char) ? 'L' :
|
|
40
|
+
'ON');
|
|
41
|
+
}
|
|
42
|
+
// ------------------------------------------------------------------
|
|
43
|
+
// HasRightToLeftCharacters
|
|
44
|
+
//
|
|
45
|
+
// Per RFC 5893 §1.4: "An RTL label is a label that contains at least
|
|
46
|
+
// one character of type R, AL, or AN." Used to determine whether a
|
|
47
|
+
// domain name is a "Bidi domain name" (RFC 5893 §1.4), in which case
|
|
48
|
+
// the Bidi Rule applies to every label in the domain.
|
|
49
|
+
// ------------------------------------------------------------------
|
|
50
|
+
export function HasRightToLeftCharacters(value) {
|
|
51
|
+
for (const ch of value)
|
|
52
|
+
if (RE_RTL_CLASSES.test(GetBidiClass(ch.codePointAt(0))))
|
|
53
|
+
return true;
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
// ------------------------------------------------------------------
|
|
57
|
+
// SatisfiesBidiRule
|
|
58
|
+
// ------------------------------------------------------------------
|
|
59
|
+
export function SatisfiesBidiRule(value) {
|
|
60
|
+
let isRtl = false;
|
|
61
|
+
let allowed = RE_LTR_ALLOWED;
|
|
62
|
+
let sawEN = false;
|
|
63
|
+
let sawAN = false;
|
|
64
|
+
let isFirst = true;
|
|
65
|
+
// let lastClass: string | null = null // (no-spec-coverage)
|
|
66
|
+
for (const ch of value) {
|
|
67
|
+
const bidiClass = GetBidiClass(ch.codePointAt(0));
|
|
68
|
+
if (isFirst) {
|
|
69
|
+
// 1. The first character must be a character with Bidi property L, R, or AL.
|
|
70
|
+
if (bidiClass !== 'L' && bidiClass !== 'R' && bidiClass !== 'AL')
|
|
71
|
+
return false;
|
|
72
|
+
isRtl = bidiClass === 'R' || bidiClass === 'AL';
|
|
73
|
+
allowed = isRtl ? RE_RTL_ALLOWED : RE_LTR_ALLOWED;
|
|
74
|
+
isFirst = false;
|
|
75
|
+
}
|
|
76
|
+
// 2 / 5. Only characters in the allowed set for this direction may appear.
|
|
77
|
+
if (!allowed.test(bidiClass))
|
|
78
|
+
return false;
|
|
79
|
+
if (bidiClass === 'EN')
|
|
80
|
+
sawEN = true;
|
|
81
|
+
else if (bidiClass === 'AN')
|
|
82
|
+
sawAN = true;
|
|
83
|
+
// if (bidiClass !== 'NSM') lastClass = bidiClass // (no-spec-coverage)
|
|
84
|
+
}
|
|
85
|
+
if (isRtl && sawEN && sawAN)
|
|
86
|
+
return false; // spec coverage path
|
|
87
|
+
// (no-spec-coverage)
|
|
88
|
+
// if (isRtl) {
|
|
89
|
+
// // 3. The end of the label must be R, AL, EN, or AN (ignoring trailing NSM).
|
|
90
|
+
// // if (lastClass !== 'R' && lastClass !== 'AL' && lastClass !== 'EN' && lastClass !== 'AN') return false
|
|
91
|
+
// // 4. If an EN is present, no AN may be present, and vice versa.
|
|
92
|
+
// if (sawEN && sawAN) return false
|
|
93
|
+
// } else {
|
|
94
|
+
// // 6. The end of the label must be L or EN (ignoring trailing NSM).
|
|
95
|
+
// // if (lastClass !== 'L' && lastClass !== 'EN') return false
|
|
96
|
+
// }
|
|
97
|
+
return true;
|
|
98
|
+
}
|