@oddington/sdk 0.1.43 → 0.1.45
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/README.md +24 -12
- package/dist/browser.js +236 -76
- package/dist/index.js +5 -5
- package/dist/types/packages/sdk/src/public.d.ts +9 -6
- package/dist/types/shared/connections.d.ts +81 -0
- package/dist/types/shared/data-repositories.d.ts +23 -0
- package/dist/types/shared/inbox-contract.d.ts +15 -3
- package/dist/types/shared/inbox-member-contract.d.ts +14 -3
- package/dist/types/shared/inbox-member-types.d.ts +7 -2
- package/dist/types/shared/record-selection.d.ts +11 -1
- package/dist/types/shared/routine-step-output.d.ts +36 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -171,13 +171,22 @@ finite numbers and safe integers with optional inclusive bounds, and Files.
|
|
|
171
171
|
Omitting `maxItems` imposes no item-count ceiling; the complete serialized input
|
|
172
172
|
still shares the Run's byte bound, including every File descriptor and other field.
|
|
173
173
|
Definitions allow at most 64 steps, 64 total object properties across their schemas,
|
|
174
|
-
and eight schema levels. Run input,
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
174
|
+
and eight schema levels. Run input, the result, and each step summary accept at
|
|
175
|
+
most 256 KiB of compact UTF-8 JSON. Each step accepts at most 1 MiB across its
|
|
176
|
+
summary and data together, measured as the sum of their compact UTF-8 JSON sizes
|
|
177
|
+
(including JSON quotes and escapes, excluding transport envelopes), without
|
|
178
|
+
truncation. Step inputs remain closed, immutable JSON but have no separate byte
|
|
179
|
+
ceiling because they are transient in-process values rather than transported or
|
|
180
|
+
retained Run evidence.
|
|
181
|
+
Across 64 steps, retained summary plus data is at most 64 MiB without a separate
|
|
182
|
+
aggregate output limit, plus 512 KiB for Run input and result. An oversized output
|
|
183
|
+
fails the step and Run once, even if routine code catches the rejection; later
|
|
184
|
+
steps do not execute and customer code is not automatically retried. The rejected
|
|
185
|
+
summary and data are not retained. The safe `step_output_too_large` failure keeps
|
|
186
|
+
only `step`, `sizeBytes`, `limitBytes`, `summaryBytes`, and `dataBytes` and explains
|
|
187
|
+
how to return fewer fields or process a smaller batch. `limitBytes` identifies
|
|
188
|
+
the violated summary or combined bound. Schema defaults share the input bound.
|
|
189
|
+
Titles contain at most 256 UTF-16 code units;
|
|
181
190
|
access dimensions and response handlers each have at most 64 entries. Functions,
|
|
182
191
|
accessors, sparse arrays, cycles and non-JSON values reject. The canonical routine
|
|
183
192
|
ID is a bounded lowercase alphanumeric/hyphen name, independent of its directory.
|
|
@@ -186,8 +195,9 @@ No entry, workspace, credentials or placement are authored in this definition.
|
|
|
186
195
|
Local Run history returns the newest 20 summaries per canonical routine, without
|
|
187
196
|
deleting older Runs or unpublished changes. Step titles and bounded summary/detail
|
|
188
197
|
values are saved with the accepted Run, so later source edits cannot rewrite them.
|
|
189
|
-
|
|
190
|
-
|
|
198
|
+
Checkout-private execution JSON has a 128 MiB read envelope for up to 64 MiB
|
|
199
|
+
of step output plus existing evidence; other local state files keep their 64 MiB
|
|
200
|
+
envelope, including private diagnostics; app summaries never include those diagnostics.
|
|
191
201
|
Publication reads the existing confirmed-receipt journal independently from the
|
|
192
202
|
successful execution status. Refresh reads materialized state; watching provides
|
|
193
203
|
connected updates without replay or interrupted-execution recovery.
|
|
@@ -349,9 +359,11 @@ the current remote Run owner through the same bindings. Operations reject with
|
|
|
349
359
|
`AppRoutineError.reason`: `authority_unavailable`, `execution_unavailable`, or
|
|
350
360
|
`invalid_input`. Starts are not automatically retried. A
|
|
351
361
|
disconnected watch ends and requires `current()`. History returns at most 20
|
|
352
|
-
summaries without deleting older Runs.
|
|
353
|
-
|
|
354
|
-
|
|
362
|
+
summaries without deleting older Runs. Input, result and each step summary are
|
|
363
|
+
bounded to 256 KiB; each step's summary plus on-demand data is bounded to 1 MiB.
|
|
364
|
+
Transport envelopes allow 17 MiB per summary, 1 MiB plus 4 KiB per detail and
|
|
365
|
+
20 summaries per list. Local child reports allow 1 MiB plus 64 KiB of framing;
|
|
366
|
+
non-output report evidence retains its 10 MiB bound independently of step output. Raw process
|
|
355
367
|
output and private authority stay private.
|
|
356
368
|
|
|
357
369
|
The exact-origin browser credential survives document disposal, reload and tab
|
package/dist/browser.js
CHANGED
|
@@ -319,6 +319,52 @@ function validateRoutineSchemaValue(schema2, value, rejected) {
|
|
|
319
319
|
check(schema2, value, "$");
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
+
function validDropboxRootPath(value) {
|
|
323
|
+
return typeof value == "string" && value.length <= 2048 && value.startsWith("/") && !/[\\\x00-\x1f\x7f]/.test(value) && value.slice(1).split("/").every((segment) => segment.length > 0 && segment.trim() === segment && segment !== "." && segment !== "..");
|
|
324
|
+
}
|
|
325
|
+
function validMicrosoftId(value) {
|
|
326
|
+
return typeof value == "string" && /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(value);
|
|
327
|
+
}
|
|
328
|
+
function validMicrosoftMailbox(value) {
|
|
329
|
+
return typeof value == "string" && value.length <= 254 && /^[^\s@/?#\\\x00-\x1f\x7f]+@[^\s@/?#\\\x00-\x1f\x7f]+\.[^\s@/?#\\\x00-\x1f\x7f]+$/.test(value);
|
|
330
|
+
}
|
|
331
|
+
function sharePointHost(value) {
|
|
332
|
+
return /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.sharepoint\.com$/.test(value);
|
|
333
|
+
}
|
|
334
|
+
function canonicalSharePointSiteUrl(value) {
|
|
335
|
+
if (!(typeof value != "string" || value.length > 2048 || /[\s\\?#\x00-\x1f\x7f]/.test(value) || !/^https:\/\/[^/:@]+(?:\/|$)/i.test(value)))
|
|
336
|
+
try {
|
|
337
|
+
let url = new URL(value);
|
|
338
|
+
if (url.protocol !== "https:" || !sharePointHost(url.hostname) || url.username || url.password || url.port) return;
|
|
339
|
+
let rawPath = value.replace(/^https:\/\/[^/]+/i, "") || "/", path = rawPath.endsWith("/") ? rawPath.slice(0, -1) : rawPath, segments = path.slice(1).split("/");
|
|
340
|
+
if (path && segments.some((segment) => !segment)) return;
|
|
341
|
+
let encoded = path ? segments.map((segment) => {
|
|
342
|
+
let decoded = decodeURIComponent(segment);
|
|
343
|
+
if (decoded === "." || decoded === ".." || /[/%\\?#\x00-\x1f\x7f]/.test(decoded)) throw new Error();
|
|
344
|
+
return encodeURIComponent(decoded);
|
|
345
|
+
}).join("/") : "", canonical = `https://${url.hostname}/${encoded}`;
|
|
346
|
+
return canonical.length <= 2048 ? canonical : void 0;
|
|
347
|
+
} catch {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
function validSharePointSiteId(value, siteUrl) {
|
|
352
|
+
if (typeof value != "string" || value.length > 512) return !1;
|
|
353
|
+
let [host, collection, site, extra] = value.split(",");
|
|
354
|
+
return extra === void 0 && host === new URL(siteUrl).hostname && validMicrosoftId(collection) && validMicrosoftId(site);
|
|
355
|
+
}
|
|
356
|
+
function validGoogleScopes(value) {
|
|
357
|
+
return Array.isArray(value) && value.length > 0 && value.length <= 32 && value.every((scope) => typeof scope == "string" && scope.length <= 256 && /^(https:\/\/www\.googleapis\.com\/auth\/[A-Za-z0-9._-]+|https:\/\/mail\.google\.com\/|openid|email|profile)$/.test(scope)) && new Set(value).size === value.length;
|
|
358
|
+
}
|
|
359
|
+
var DROPBOX_FILE_SCOPES = ["account_info.read", "files.metadata.read", "files.content.read", "files.content.write"];
|
|
360
|
+
function validDropboxFileScopes(value) {
|
|
361
|
+
return Array.isArray(value) && value.length === DROPBOX_FILE_SCOPES.length && new Set(value).size === value.length && DROPBOX_FILE_SCOPES.every((scope) => value.includes(scope));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function validDataRepositoryName(value) {
|
|
365
|
+
return typeof value == "string" && /^[a-z0-9][a-z0-9._-]{0,127}$/.test(value) && !value.includes("..");
|
|
366
|
+
}
|
|
367
|
+
|
|
322
368
|
var InboxContractError = class extends Error {
|
|
323
369
|
constructor(message2) {
|
|
324
370
|
super(message2), this.name = "InboxContractError";
|
|
@@ -575,9 +621,26 @@ function defineHandler(value) {
|
|
|
575
621
|
function respond(handler, input) {
|
|
576
622
|
return defineHandler(handler), handlerReference({ id: handler.id, input });
|
|
577
623
|
}
|
|
624
|
+
function recordRequirements(value) {
|
|
625
|
+
let source2 = object(value, "Record requirements");
|
|
626
|
+
keys(source2, ["repository", "records"], "Record requirements"), validDataRepositoryName(source2.repository) || fail("Invalid requirements repository");
|
|
627
|
+
let repository = source2.repository, records = array(source2.records, "required Records").map((entry) => {
|
|
628
|
+
let row = object(entry, "required Record");
|
|
629
|
+
keys(row, ["ref", "version"], "required Record");
|
|
630
|
+
let { ref } = validateRecordReference({ repository, ref: row.ref });
|
|
631
|
+
return (typeof row.version != "string" || !row.version.length || row.version.length > 512) && fail("Invalid required Record version"), { ref, version: row.version };
|
|
632
|
+
});
|
|
633
|
+
return new Set(records.map((record4) => record4.ref)).size !== records.length && fail("Duplicate required Record"), { repository, records };
|
|
634
|
+
}
|
|
635
|
+
function requireRecords(repository, records) {
|
|
636
|
+
return recordRequirements({ repository, records: array(records, "required Records").map((entry) => {
|
|
637
|
+
let record4 = object(entry, "Data Record");
|
|
638
|
+
return { ref: record4.$ref, version: record4.$version };
|
|
639
|
+
}) });
|
|
640
|
+
}
|
|
578
641
|
function question(value) {
|
|
579
642
|
let source2 = object(value, "question");
|
|
580
|
-
keys(source2, ["id", "to", "allowedResponders", "prompt", "instructions", "response", "handler"], "question");
|
|
643
|
+
keys(source2, ["id", "to", "allowedResponders", "prompt", "instructions", "response", "handler", "requirements"], "question");
|
|
581
644
|
let to = personReference(source2.to, "question assignee"), allowedResponders = source2.allowedResponders === void 0 ? [to] : distinctPeople(source2.allowedResponders, "allowed responders");
|
|
582
645
|
return allowedResponders.includes(to) || fail("Allowed responders must include the assignee"), {
|
|
583
646
|
id: id(source2.id, "question ID"),
|
|
@@ -586,7 +649,8 @@ function question(value) {
|
|
|
586
649
|
prompt: text(source2.prompt, "question prompt"),
|
|
587
650
|
...source2.instructions === void 0 ? {} : { instructions: text(source2.instructions, "instructions") },
|
|
588
651
|
response: validateResponseDefinition(source2.response),
|
|
589
|
-
...Object.hasOwn(source2, "handler") ? { handler: handlerReference(source2.handler) } : {}
|
|
652
|
+
...Object.hasOwn(source2, "handler") ? { handler: handlerReference(source2.handler) } : {},
|
|
653
|
+
...Object.hasOwn(source2, "requirements") ? { requirements: recordRequirements(source2.requirements) } : {}
|
|
590
654
|
};
|
|
591
655
|
}
|
|
592
656
|
function presentation(source2) {
|
|
@@ -998,6 +1062,42 @@ function acceptText(request2, text5) {
|
|
|
998
1062
|
return validateObject(request2.schema, object5, text5), capture({ object: object5 }, "invalid_output", "output_too_large");
|
|
999
1063
|
}
|
|
1000
1064
|
|
|
1065
|
+
var ROUTINE_STEP_SUMMARY_BYTES = 256 * 1024, ROUTINE_STEP_OUTPUT_BYTES = 1024 * 1024;
|
|
1066
|
+
function parseRoutineStepOutputDetail(value) {
|
|
1067
|
+
let invalid9 = () => {
|
|
1068
|
+
throw new AppRoutineContractError("invalid_value");
|
|
1069
|
+
};
|
|
1070
|
+
assertRoutineFields(value, ["step", "sizeBytes", "limitBytes", "summaryBytes", "dataBytes"]);
|
|
1071
|
+
let { step, sizeBytes, limitBytes, summaryBytes, dataBytes } = value;
|
|
1072
|
+
return !isAppRoutineName(step) || ![sizeBytes, limitBytes, summaryBytes, dataBytes].every((bytes) => Number.isSafeInteger(bytes) && bytes > 0) || sizeBytes !== summaryBytes + dataBytes || limitBytes !== (summaryBytes > ROUTINE_STEP_SUMMARY_BYTES ? ROUTINE_STEP_SUMMARY_BYTES : ROUTINE_STEP_OUTPUT_BYTES) || (limitBytes === ROUTINE_STEP_SUMMARY_BYTES ? summaryBytes : sizeBytes) <= limitBytes ? invalid9() : freezeRoutineMetadata({ step, sizeBytes, limitBytes, summaryBytes, dataBytes });
|
|
1073
|
+
}
|
|
1074
|
+
function routineStepOutputMessage(value) {
|
|
1075
|
+
let detail = parseRoutineStepOutputDetail(value), size = `${(detail.sizeBytes / (1024 * 1024)).toFixed(1)} MB`, bound = detail.limitBytes === ROUTINE_STEP_SUMMARY_BYTES ? `, including ${(detail.summaryBytes / 1024).toFixed(1)} KB of summary. Each step's summary can return up to 256 KB.` : ". Each step can return up to 1 MB across its summary and data.";
|
|
1076
|
+
return `Step ${detail.step} returned ${size} of output${bound} Return fewer fields or process a smaller batch, then try again.`;
|
|
1077
|
+
}
|
|
1078
|
+
var RoutineStepOutputError = class extends Error {
|
|
1079
|
+
code = "step_output_too_large";
|
|
1080
|
+
detail;
|
|
1081
|
+
constructor(detail) {
|
|
1082
|
+
let captured = parseRoutineStepOutputDetail(detail);
|
|
1083
|
+
super(routineStepOutputMessage(captured)), this.detail = captured, Object.freeze(this);
|
|
1084
|
+
}
|
|
1085
|
+
};
|
|
1086
|
+
function captureRoutineStepOutput(step, summary2, data3) {
|
|
1087
|
+
assertRoutineJson(summary2), assertRoutineJson(data3);
|
|
1088
|
+
let summaryJson = JSON.stringify(summary2), dataJson = JSON.stringify(data3), summaryBytes = new TextEncoder().encode(summaryJson).byteLength, dataBytes = new TextEncoder().encode(dataJson).byteLength, sizeBytes = summaryBytes + dataBytes, limitBytes = summaryBytes > ROUTINE_STEP_SUMMARY_BYTES ? ROUTINE_STEP_SUMMARY_BYTES : ROUTINE_STEP_OUTPUT_BYTES;
|
|
1089
|
+
if (summaryBytes > ROUTINE_STEP_SUMMARY_BYTES || sizeBytes > ROUTINE_STEP_OUTPUT_BYTES)
|
|
1090
|
+
throw new RoutineStepOutputError({ step, sizeBytes, limitBytes, summaryBytes, dataBytes });
|
|
1091
|
+
return freezeRoutineMetadata({ summary: JSON.parse(summaryJson), data: JSON.parse(dataJson) });
|
|
1092
|
+
}
|
|
1093
|
+
function captureRetainedStepOutput(step, value) {
|
|
1094
|
+
let hasSummary = Object.hasOwn(value, "summary"), hasData = Object.hasOwn(value, "data");
|
|
1095
|
+
if (hasSummary && hasData) return captureRoutineStepOutput(step, value.summary, value.data);
|
|
1096
|
+
for (let key of ["summary", "data"]) if (Object.hasOwn(value, key) && (assertRoutineJson(value[key]), new TextEncoder().encode(JSON.stringify(value[key])).byteLength > (key === "summary" ? ROUTINE_STEP_SUMMARY_BYTES : ROUTINE_STEP_OUTPUT_BYTES)))
|
|
1097
|
+
throw new AppRoutineContractError("invalid_value");
|
|
1098
|
+
return freezeRoutineMetadata(JSON.parse(JSON.stringify(value)));
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1001
1101
|
var LIMIT = 256 * 1024, invalid3 = () => {
|
|
1002
1102
|
throw new AppRoutineContractError("invalid_value");
|
|
1003
1103
|
}, invalidContract3 = () => {
|
|
@@ -1122,7 +1222,7 @@ function captureRoutineInput(definition, input) {
|
|
|
1122
1222
|
return capture2(contract.input, input === void 0 && Object.hasOwn(contract, "inputDefault") ? contract.inputDefault : input);
|
|
1123
1223
|
}
|
|
1124
1224
|
async function executeRoutineDefinition(definition, input, runtime) {
|
|
1125
|
-
let captured = captureRoutineInput(definition, input), { contract, steps, run } = definitions.get(definition), active2 = !0, accepting = !0, broken = !1, work = Promise.resolve(), aiWork = /* @__PURE__ */ new Set(), generate = (kind, value) => {
|
|
1225
|
+
let captured = captureRoutineInput(definition, input), { contract, steps, run } = definitions.get(definition), active2 = !0, accepting = !0, broken = !1, outputFailure, work = Promise.resolve(), aiWork = /* @__PURE__ */ new Set(), generate = (kind, value) => {
|
|
1126
1226
|
let operation2 = (async () => {
|
|
1127
1227
|
if (!active2 || broken || contract.access.ai !== !0) throw new AIError("access_denied");
|
|
1128
1228
|
if (!runtime.ai) throw new AIError("capability_unavailable");
|
|
@@ -1192,10 +1292,10 @@ async function executeRoutineDefinition(definition, input, runtime) {
|
|
|
1192
1292
|
await runtime.step(id3, { status: "running" }), activeStep = id3;
|
|
1193
1293
|
let output = await steps[id3].run(saved, os2);
|
|
1194
1294
|
if (assertRoutineFields(output, ["summary", "data"]), !Object.hasOwn(output, "summary") || !Object.hasOwn(output, "data")) return invalid3();
|
|
1195
|
-
let summary2 =
|
|
1295
|
+
let { summary: summary2, data: data3 } = captureRoutineStepOutput(id3, output.summary, output.data);
|
|
1196
1296
|
return await runtime.step(id3, { status: "completed", summary: summary2, data: data3 }), activeStep = void 0, freezeRoutineMetadata({ summary: summary2, data: data3 });
|
|
1197
1297
|
} catch (error) {
|
|
1198
|
-
throw broken = !0, activeStep = void 0, await runtime.step(id3, { status: "failed" }), error;
|
|
1298
|
+
throw error instanceof RoutineStepOutputError && (outputFailure ??= error), broken = !0, activeStep = void 0, await runtime.step(id3, { status: "failed" }), error;
|
|
1199
1299
|
}
|
|
1200
1300
|
});
|
|
1201
1301
|
return work = next.then(() => {
|
|
@@ -1211,8 +1311,12 @@ async function executeRoutineDefinition(definition, input, runtime) {
|
|
|
1211
1311
|
}
|
|
1212
1312
|
for (accepting = !1, await work; aiWork.size; ) await Promise.allSettled([...aiWork]);
|
|
1213
1313
|
active2 = !1;
|
|
1214
|
-
|
|
1215
|
-
|
|
1314
|
+
try {
|
|
1315
|
+
for (let step of contract.steps) reached.has(step.id) || await runtime.step(step.id, { status: "skipped" });
|
|
1316
|
+
} catch (error) {
|
|
1317
|
+
throw outputFailure ?? error;
|
|
1318
|
+
}
|
|
1319
|
+
if (broken) throw outputFailure ?? failure ?? new AppRoutineContractError("invalid_value");
|
|
1216
1320
|
if (contract.result !== void 0) return capture2(contract.result, result2);
|
|
1217
1321
|
if (result2 !== void 0) return invalid3();
|
|
1218
1322
|
}
|
|
@@ -2334,48 +2438,6 @@ var files = {
|
|
|
2334
2438
|
read
|
|
2335
2439
|
};
|
|
2336
2440
|
|
|
2337
|
-
function validDropboxRootPath(value) {
|
|
2338
|
-
return typeof value == "string" && value.length <= 2048 && value.startsWith("/") && !/[\\\x00-\x1f\x7f]/.test(value) && value.slice(1).split("/").every((segment) => segment.length > 0 && segment.trim() === segment && segment !== "." && segment !== "..");
|
|
2339
|
-
}
|
|
2340
|
-
function validMicrosoftId(value) {
|
|
2341
|
-
return typeof value == "string" && /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(value);
|
|
2342
|
-
}
|
|
2343
|
-
function validMicrosoftMailbox(value) {
|
|
2344
|
-
return typeof value == "string" && value.length <= 254 && /^[^\s@/?#\\\x00-\x1f\x7f]+@[^\s@/?#\\\x00-\x1f\x7f]+\.[^\s@/?#\\\x00-\x1f\x7f]+$/.test(value);
|
|
2345
|
-
}
|
|
2346
|
-
function sharePointHost(value) {
|
|
2347
|
-
return /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.sharepoint\.com$/.test(value);
|
|
2348
|
-
}
|
|
2349
|
-
function canonicalSharePointSiteUrl(value) {
|
|
2350
|
-
if (!(typeof value != "string" || value.length > 2048 || /[\s\\?#\x00-\x1f\x7f]/.test(value) || !/^https:\/\/[^/:@]+(?:\/|$)/i.test(value)))
|
|
2351
|
-
try {
|
|
2352
|
-
let url = new URL(value);
|
|
2353
|
-
if (url.protocol !== "https:" || !sharePointHost(url.hostname) || url.username || url.password || url.port) return;
|
|
2354
|
-
let rawPath = value.replace(/^https:\/\/[^/]+/i, "") || "/", path = rawPath.endsWith("/") ? rawPath.slice(0, -1) : rawPath, segments = path.slice(1).split("/");
|
|
2355
|
-
if (path && segments.some((segment) => !segment)) return;
|
|
2356
|
-
let encoded = path ? segments.map((segment) => {
|
|
2357
|
-
let decoded = decodeURIComponent(segment);
|
|
2358
|
-
if (decoded === "." || decoded === ".." || /[/%\\?#\x00-\x1f\x7f]/.test(decoded)) throw new Error();
|
|
2359
|
-
return encodeURIComponent(decoded);
|
|
2360
|
-
}).join("/") : "", canonical = `https://${url.hostname}/${encoded}`;
|
|
2361
|
-
return canonical.length <= 2048 ? canonical : void 0;
|
|
2362
|
-
} catch {
|
|
2363
|
-
return;
|
|
2364
|
-
}
|
|
2365
|
-
}
|
|
2366
|
-
function validSharePointSiteId(value, siteUrl) {
|
|
2367
|
-
if (typeof value != "string" || value.length > 512) return !1;
|
|
2368
|
-
let [host, collection, site, extra] = value.split(",");
|
|
2369
|
-
return extra === void 0 && host === new URL(siteUrl).hostname && validMicrosoftId(collection) && validMicrosoftId(site);
|
|
2370
|
-
}
|
|
2371
|
-
function validGoogleScopes(value) {
|
|
2372
|
-
return Array.isArray(value) && value.length > 0 && value.length <= 32 && value.every((scope) => typeof scope == "string" && scope.length <= 256 && /^(https:\/\/www\.googleapis\.com\/auth\/[A-Za-z0-9._-]+|https:\/\/mail\.google\.com\/|openid|email|profile)$/.test(scope)) && new Set(value).size === value.length;
|
|
2373
|
-
}
|
|
2374
|
-
var DROPBOX_FILE_SCOPES = ["account_info.read", "files.metadata.read", "files.content.read", "files.content.write"];
|
|
2375
|
-
function validDropboxFileScopes(value) {
|
|
2376
|
-
return Array.isArray(value) && value.length === DROPBOX_FILE_SCOPES.length && new Set(value).size === value.length && DROPBOX_FILE_SCOPES.every((scope) => value.includes(scope));
|
|
2377
|
-
}
|
|
2378
|
-
|
|
2379
2441
|
var ROUTINE_CONNECTION_CREDENTIALS_ENV = "OS_ROUTINE_CONNECTION_CREDENTIALS";
|
|
2380
2442
|
function parseRoutineConnectionNames(value) {
|
|
2381
2443
|
if (!Array.isArray(value) || value.some((name2) => typeof name2 != "string" || !/^(gmail|airtable|dropbox|outlook|sharepoint)\/[a-z0-9][a-z0-9-]{0,62}$/.test(name2)) || new Set(value).size !== value.length)
|
|
@@ -2769,8 +2831,6 @@ function runtimeConnections() {
|
|
|
2769
2831
|
}
|
|
2770
2832
|
var connections = /* @__PURE__ */ runtimeConnections();
|
|
2771
2833
|
|
|
2772
|
-
var LOCAL_ROUTINE_VALUE_BYTES = 256 * 1024;
|
|
2773
|
-
|
|
2774
2834
|
function locationIdentity(location) {
|
|
2775
2835
|
let coordinates = location.provider === "os" ? [location.file] : location.provider === "gmail" ? [location.connection, location.message, location.attachment] : location.provider === "dropbox" ? [location.connection, location.file] : location.provider === "outlook" ? [
|
|
2776
2836
|
location.connection,
|
|
@@ -2865,14 +2925,41 @@ var source = {
|
|
|
2865
2925
|
};
|
|
2866
2926
|
|
|
2867
2927
|
var InboxOperationError = class extends Error {
|
|
2868
|
-
constructor(status, reason) {
|
|
2869
|
-
super(reason === "conflict" ? "This question already has an accepted answer" : reason === "unavailable" ? "Inbox request unavailable. Retry the same action." : reason === "invalid_input" ? "Invalid Inbox request" : "Inbox access unavailable");
|
|
2928
|
+
constructor(status, reason, requirementsRepository) {
|
|
2929
|
+
super(reason === "records_need_attention" ? "Records need to be pushed or reviewed." : reason === "records_unavailable" ? "Records temporarily unavailable. Try again shortly." : reason === "handler_unavailable" ? "Deploy the routine that owns this question\u2019s response handler." : reason === "conflict" ? "This question already has an accepted answer" : reason === "unavailable" ? "Inbox request unavailable. Retry the same action." : reason === "invalid_input" ? "Invalid Inbox request" : "Inbox access unavailable");
|
|
2870
2930
|
this.status = status;
|
|
2871
2931
|
this.reason = reason;
|
|
2932
|
+
this.requirementsRepository = requirementsRepository;
|
|
2872
2933
|
}
|
|
2873
2934
|
status;
|
|
2874
2935
|
reason;
|
|
2875
|
-
|
|
2936
|
+
requirementsRepository;
|
|
2937
|
+
};
|
|
2938
|
+
function parseQuestionAvailability(value, available = !1) {
|
|
2939
|
+
let state = object4(value);
|
|
2940
|
+
return keys3(state, ["unavailableReason", "requirementsRepository"], []), "unavailableReason" in state ? (assert(!available && typeof state.unavailableReason == "string" && ["handler_unavailable", "records_need_attention", "records_unavailable"].includes(String(state.unavailableReason))), state.unavailableReason === "records_need_attention" ? assert(validDataRepositoryName(state.requirementsRepository)) : assert(!("requirementsRepository" in state)), {
|
|
2941
|
+
unavailableReason: state.unavailableReason,
|
|
2942
|
+
...state.unavailableReason === "records_need_attention" ? { requirementsRepository: state.requirementsRepository } : {}
|
|
2943
|
+
}) : (assert(!("requirementsRepository" in state)), {});
|
|
2944
|
+
}
|
|
2945
|
+
function questionAvailability(value, available = !1) {
|
|
2946
|
+
return parseQuestionAvailability({
|
|
2947
|
+
..."unavailableReason" in value ? { unavailableReason: value.unavailableReason } : {},
|
|
2948
|
+
..."requirementsRepository" in value ? { requirementsRepository: value.requirementsRepository } : {}
|
|
2949
|
+
}, available);
|
|
2950
|
+
}
|
|
2951
|
+
function parseInboxUnavailableFailure(value, status) {
|
|
2952
|
+
try {
|
|
2953
|
+
if (status !== 503) return;
|
|
2954
|
+
let envelope = object4(value);
|
|
2955
|
+
keys3(envelope, ["error", "unavailableReason", "requirementsRepository"], ["error", "unavailableReason"]), assert(text4(envelope.error));
|
|
2956
|
+
let state = questionAvailability(envelope);
|
|
2957
|
+
return new InboxOperationError(503, state.unavailableReason, state.requirementsRepository);
|
|
2958
|
+
} catch {
|
|
2959
|
+
return;
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
var INBOX_RESULT_BYTES = 8 * 1024 * 1024, INBOX_INPUT_BYTES = 8192, INBOX_LOCAL_INPUT_BYTES = 256 * 1024, INBOX_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
2876
2963
|
function isAppQuestionOperation(operation2) {
|
|
2877
2964
|
return operation2 === "questions.list" || operation2 === "questions.answer" || operation2 === "questions.searchRecords";
|
|
2878
2965
|
}
|
|
@@ -3052,7 +3139,7 @@ function parseInboxItem(value) {
|
|
|
3052
3139
|
assert(id2(person.id) && text4(person.name));
|
|
3053
3140
|
}), array2(item.questions).forEach((value2) => {
|
|
3054
3141
|
let question2 = object4(value2);
|
|
3055
|
-
if (assert(text4(question2.id) && id2(question2.to) && text4(question2.prompt) && (question2.instructions === null || text4(question2.instructions, !0)) && typeof question2.available == "boolean"), responseDefinition(question2.response), assert(array2(question2.allowedResponders).every(id2)), question2.acceptedResponse !== null) {
|
|
3142
|
+
if (assert(text4(question2.id) && id2(question2.to) && text4(question2.prompt) && (question2.instructions === null || text4(question2.instructions, !0)) && typeof question2.available == "boolean"), questionAvailability(question2, question2.available), assert(!("requirements" in question2) && !("handler" in question2)), responseDefinition(question2.response), assert(array2(question2.allowedResponders).every(id2)), question2.acceptedResponse !== null) {
|
|
3056
3143
|
let accepted = object4(question2.acceptedResponse);
|
|
3057
3144
|
assert(id2(accepted.id) && id2(accepted.userId) && date(accepted.acceptedAt)), response(accepted.response), accepted.label === null ? delete accepted.label : "label" in accepted && assert(text4(accepted.label)), "acceptanceOrder" in accepted && assert(integer(accepted.acceptanceOrder));
|
|
3058
3145
|
}
|
|
@@ -3085,11 +3172,11 @@ function parseAnswerableQuestion(value) {
|
|
|
3085
3172
|
let entry = object4(json(value));
|
|
3086
3173
|
keys3(
|
|
3087
3174
|
entry,
|
|
3088
|
-
["itemId", "number", "revision", "title", "inboxUrl", "questionId", "routine", "prompt", "response", "answerable", "tags", "recordRefs", "instructions"],
|
|
3175
|
+
["itemId", "number", "revision", "title", "inboxUrl", "questionId", "routine", "prompt", "response", "answerable", "tags", "recordRefs", "instructions", "unavailableReason", "requirementsRepository"],
|
|
3089
3176
|
["itemId", "number", "revision", "title", "inboxUrl", "questionId", "routine", "prompt", "response", "answerable"]
|
|
3090
3177
|
), assert(id2(entry.itemId) && integer(entry.number) && integer(entry.revision) && text4(entry.title) && text4(entry.inboxUrl));
|
|
3091
3178
|
let link = new URL(entry.inboxUrl), slug = link.hostname.slice(0, -13);
|
|
3092
|
-
return assert(link.hostname.endsWith(".oddington.ai") && slug.length <= 63 && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug) && !["auth", "www", "api", "os"].includes(slug) && entry.inboxUrl === `https://${slug}.oddington.ai/inbox/${entry.itemId}`), assert(isAppRoutineName(entry.routine) && text4(entry.questionId) && entry.questionId === entry.questionId.trim() && text4(entry.prompt) && (!("instructions" in entry) || text4(entry.instructions, !0)) && typeof entry.answerable == "boolean"), responseDefinition(entry.response), askMetadata(entry), entry;
|
|
3179
|
+
return assert(link.hostname.endsWith(".oddington.ai") && slug.length <= 63 && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug) && !["auth", "www", "api", "os"].includes(slug) && entry.inboxUrl === `https://${slug}.oddington.ai/inbox/${entry.itemId}`), assert(isAppRoutineName(entry.routine) && text4(entry.questionId) && entry.questionId === entry.questionId.trim() && text4(entry.prompt) && (!("instructions" in entry) || text4(entry.instructions, !0)) && typeof entry.answerable == "boolean"), questionAvailability(entry, entry.answerable), responseDefinition(entry.response), askMetadata(entry), entry;
|
|
3093
3180
|
}
|
|
3094
3181
|
function askMetadata(entry) {
|
|
3095
3182
|
let tags = array2(entry.tags === void 0 ? [] : entry.tags);
|
|
@@ -3398,7 +3485,7 @@ function appContext(origin, active2) {
|
|
|
3398
3485
|
observation === observed && (observation = void 0);
|
|
3399
3486
|
}
|
|
3400
3487
|
}
|
|
3401
|
-
async function renew() {
|
|
3488
|
+
async function renew(initialConnection = !1) {
|
|
3402
3489
|
if (renewal) return renewal;
|
|
3403
3490
|
if (!binding || !pair || !alive()) throw new Error();
|
|
3404
3491
|
renewal = (async () => {
|
|
@@ -3424,7 +3511,7 @@ function appContext(origin, active2) {
|
|
|
3424
3511
|
await synchronize(requestController.signal);
|
|
3425
3512
|
return;
|
|
3426
3513
|
}
|
|
3427
|
-
if (!response2.ok) throw new Error();
|
|
3514
|
+
if (!response2.ok) throw response2.status === 401 || response2.status === 403 ? new AppContextDenied() : new Error();
|
|
3428
3515
|
if (!alive() || !validPair(value) || !bounded3(value.context) || (/* @__PURE__ */ new Set([value.credential, value.renewalCredential, pair.credential, pair.renewalCredential])).size !== 4) throw new Error();
|
|
3429
3516
|
if (stored() !== previous) {
|
|
3430
3517
|
await synchronize(requestController.signal);
|
|
@@ -3433,6 +3520,7 @@ function appContext(origin, active2) {
|
|
|
3433
3520
|
let raw = JSON.stringify(value);
|
|
3434
3521
|
globalThis.localStorage.setItem(sessionKey, raw), install(value.context, value, raw);
|
|
3435
3522
|
} catch (error) {
|
|
3523
|
+
if (initialConnection && error instanceof AppContextDenied) throw error;
|
|
3436
3524
|
try {
|
|
3437
3525
|
if (alive() && stored() && stored() !== previous) {
|
|
3438
3526
|
await synchronize(requestController.signal);
|
|
@@ -3561,8 +3649,32 @@ function appContext(origin, active2) {
|
|
|
3561
3649
|
try {
|
|
3562
3650
|
if (!alive()) throw new Error();
|
|
3563
3651
|
if (!pair) {
|
|
3564
|
-
let candidate2 = stored()
|
|
3565
|
-
|
|
3652
|
+
let candidate2 = stored();
|
|
3653
|
+
if (candidate2)
|
|
3654
|
+
try {
|
|
3655
|
+
let retained3 = readPair(candidate2);
|
|
3656
|
+
if (retained3.context.expiresAt <= Date.now()) {
|
|
3657
|
+
if (pair = retained3, binding = { ...retained3.context }, credential = retained3.credential, serialized = candidate2, await renew(!0), !current2()) throw new AppRenewalUnavailable();
|
|
3658
|
+
return context();
|
|
3659
|
+
}
|
|
3660
|
+
let value3 = await proof(retained3.credential);
|
|
3661
|
+
return stored() !== candidate2 ? resolveOnce() : (install(value3, retained3, candidate2), context());
|
|
3662
|
+
} catch (error) {
|
|
3663
|
+
if (error instanceof AppRenewalUnavailable || error instanceof AppResponseReadError || !(error instanceof AppContextDenied) || !alive() || expiry) throw error;
|
|
3664
|
+
pair = void 0, binding = void 0, credential = void 0, serialized = void 0;
|
|
3665
|
+
}
|
|
3666
|
+
let response2 = await untilAborted(fetch(`${origin}/_os/app/connect`, {
|
|
3667
|
+
method: "POST",
|
|
3668
|
+
credentials: "omit",
|
|
3669
|
+
redirect: "error",
|
|
3670
|
+
cache: "no-store",
|
|
3671
|
+
referrerPolicy: "no-referrer",
|
|
3672
|
+
signal: controller.signal
|
|
3673
|
+
}), controller.signal), value2 = await appResponse(response2, 4096, controller.signal);
|
|
3674
|
+
if (!response2.ok || response2.redirected || response2.url && response2.url !== `${origin}/_os/app/connect` || !alive() || !validPair(value2) || !bounded3(value2.context)) throw new Error();
|
|
3675
|
+
if (stored() !== candidate2 && stored()) return resolveOnce();
|
|
3676
|
+
let raw = JSON.stringify(value2);
|
|
3677
|
+
return globalThis.localStorage.setItem(sessionKey, raw), install(value2.context, value2, raw), context();
|
|
3566
3678
|
}
|
|
3567
3679
|
if (expireAccess(), binding.expiresAt <= Date.now()) {
|
|
3568
3680
|
if (await renew(), !current2()) throw new AppRenewalUnavailable();
|
|
@@ -3592,7 +3704,7 @@ function appContext(origin, active2) {
|
|
|
3592
3704
|
resolution2 = void 0;
|
|
3593
3705
|
}), resolution2);
|
|
3594
3706
|
return { resolve, retained: async () => {
|
|
3595
|
-
if (!expiry && alive() && (binding ? current2() && resolution2 : readPair(stored()).context.expiresAt > Date.now()))
|
|
3707
|
+
if (!expiry && alive() && (binding ? current2() && resolution2 : !stored() || readPair(stored()).context.expiresAt > Date.now()))
|
|
3596
3708
|
return resolve();
|
|
3597
3709
|
if (!expiry || !current2()) throw new Error("Local app context unavailable.");
|
|
3598
3710
|
return context();
|
|
@@ -3643,7 +3755,7 @@ async function send2(operation2, input, resolved) {
|
|
|
3643
3755
|
};
|
|
3644
3756
|
try {
|
|
3645
3757
|
let response2 = await context.requestInbox(operation2, envelope.input), value = await appResponse(response2, INBOX_RESULT_BYTES, context.signal);
|
|
3646
|
-
if (check2(), !response2.ok) throw new InboxOperationError(
|
|
3758
|
+
if (check2(), !response2.ok) throw parseInboxUnavailableFailure(value, response2.status) ?? new InboxOperationError(
|
|
3647
3759
|
[400, 401, 403, 409].includes(response2.status) ? response2.status : 503,
|
|
3648
3760
|
response2.status === 400 ? "invalid_input" : response2.status === 401 ? "authority_unavailable" : response2.status === 403 ? "access_denied" : response2.status === 409 ? "conflict" : "unavailable"
|
|
3649
3761
|
);
|
|
@@ -3685,12 +3797,20 @@ async function send2(operation2, input, resolved) {
|
|
|
3685
3797
|
throw response2.body?.cancel().catch(() => {
|
|
3686
3798
|
}), error;
|
|
3687
3799
|
}
|
|
3688
|
-
if (!response2.ok)
|
|
3689
|
-
|
|
3690
|
-
|
|
3800
|
+
if (!response2.ok) {
|
|
3801
|
+
let value2;
|
|
3802
|
+
try {
|
|
3803
|
+
let bytes2 = await limitedBody(response2, 8192);
|
|
3804
|
+
check(), bytes2 && (value2 = JSON.parse(new TextDecoder().decode(bytes2)));
|
|
3805
|
+
} catch {
|
|
3806
|
+
check();
|
|
3807
|
+
}
|
|
3808
|
+
let refusal = parseInboxUnavailableFailure(value2, response2.status);
|
|
3809
|
+
throw refusal || new InboxOperationError(
|
|
3691
3810
|
[400, 401, 403, 409].includes(response2.status) ? response2.status : 503,
|
|
3692
3811
|
response2.status === 400 ? "invalid_input" : response2.status === 401 ? "authority_unavailable" : response2.status === 403 ? "access_denied" : response2.status === 409 ? "conflict" : "unavailable"
|
|
3693
3812
|
);
|
|
3813
|
+
}
|
|
3694
3814
|
if (response2.status !== 200)
|
|
3695
3815
|
throw response2.body?.cancel().catch(() => {
|
|
3696
3816
|
}), unavailable3();
|
|
@@ -3929,6 +4049,7 @@ function createBrowserAuth(runtime) {
|
|
|
3929
4049
|
let revision = c.revision;
|
|
3930
4050
|
try {
|
|
3931
4051
|
if (!allowedOrigin(origin)) throw runtime.failure("unavailable");
|
|
4052
|
+
runtime.prepare?.();
|
|
3932
4053
|
let response2 = await fetch(`${origin}/api/auth`, { method: "GET", credentials: "same-origin", redirect: "error", cache: "no-store" });
|
|
3933
4054
|
if (!response2.ok) throw runtime.failure("unavailable");
|
|
3934
4055
|
let configuration = validateConfiguration(await response2.json());
|
|
@@ -4198,9 +4319,9 @@ var BrowserAuthError = class extends Error {
|
|
|
4198
4319
|
this.name = "BrowserAuthError";
|
|
4199
4320
|
}
|
|
4200
4321
|
reason;
|
|
4201
|
-
};
|
|
4322
|
+
}, providerModule, prepareProvider = () => providerModule ??= import("./auth-provider.js");
|
|
4202
4323
|
async function provider(configuration, guard) {
|
|
4203
|
-
let { AuthClient } = await
|
|
4324
|
+
let { AuthClient } = await prepareProvider();
|
|
4204
4325
|
if (!guard.current(guard.revision())) throw new BrowserAuthError("stale");
|
|
4205
4326
|
let provenance = /* @__PURE__ */ new Map(), removalRevision, authorizationRequest, authorizationQueue = Promise.resolve(), storage = globalThis.localStorage, client = new AuthClient({
|
|
4206
4327
|
url: `${configuration.providerUrl}/auth/v1`,
|
|
@@ -4282,7 +4403,16 @@ async function provider(configuration, guard) {
|
|
|
4282
4403
|
}
|
|
4283
4404
|
};
|
|
4284
4405
|
}
|
|
4285
|
-
var auth = /* @__PURE__ */ createBrowserAuth({
|
|
4406
|
+
var auth = /* @__PURE__ */ createBrowserAuth({
|
|
4407
|
+
// Preloading is opportunistic. Construction below still observes and
|
|
4408
|
+
// normalizes a failed import, without leaving an unhandled preload promise.
|
|
4409
|
+
prepare: () => {
|
|
4410
|
+
prepareProvider().catch(() => {
|
|
4411
|
+
});
|
|
4412
|
+
},
|
|
4413
|
+
provider,
|
|
4414
|
+
failure: (reason) => new BrowserAuthError(reason)
|
|
4415
|
+
});
|
|
4286
4416
|
|
|
4287
4417
|
function routineRunHandle(operations2) {
|
|
4288
4418
|
return Object.freeze({
|
|
@@ -4321,14 +4451,19 @@ function progress(value) {
|
|
|
4321
4451
|
}
|
|
4322
4452
|
function parseRunStep(value, expected) {
|
|
4323
4453
|
let v = record3(value);
|
|
4324
|
-
|
|
4454
|
+
if (typeof v.id != "string" || !name.test(v.id) || expected !== void 0 && v.id !== expected || typeof v.title != "string" || !v.title.trim() || v.title.length > 256 || !["pending", "running", "completed", "failed", "skipped"].includes(v.status)) return invalid8();
|
|
4455
|
+
let output = captureRetainedStepOutput(v.id, {
|
|
4456
|
+
...Object.hasOwn(v, "summary") ? { summary: v.summary } : {},
|
|
4457
|
+
...Object.hasOwn(v, "data") ? { data: v.data } : {}
|
|
4458
|
+
});
|
|
4459
|
+
return {
|
|
4325
4460
|
id: v.id,
|
|
4326
4461
|
title: v.title,
|
|
4327
4462
|
status: v.status,
|
|
4328
4463
|
...times(v),
|
|
4329
4464
|
...progress(v.progress),
|
|
4330
4465
|
...Object.hasOwn(v, "summary") ? { summary: bounded(v.summary) } : {},
|
|
4331
|
-
...Object.hasOwn(
|
|
4466
|
+
...Object.hasOwn(output, "data") ? { data: output.data } : {}
|
|
4332
4467
|
};
|
|
4333
4468
|
}
|
|
4334
4469
|
function parseRemoteRun(value, expected = {}) {
|
|
@@ -4343,7 +4478,11 @@ function parseRemoteRun(value, expected = {}) {
|
|
|
4343
4478
|
if (v.failure !== void 0) {
|
|
4344
4479
|
let f = record3(v.failure);
|
|
4345
4480
|
if (v.status !== "failed" || typeof f.message != "string" || !f.message || f.message.length > 512) return invalid8();
|
|
4346
|
-
|
|
4481
|
+
if (f.code === "step_output_too_large") {
|
|
4482
|
+
let { code, message: message2, ...facts } = f, detail = parseRoutineStepOutputDetail(facts);
|
|
4483
|
+
if (!steps.some((step) => step.id === detail.step && step.status === "failed") || message2 !== routineStepOutputMessage(detail)) return invalid8();
|
|
4484
|
+
failure = { code, message: message2, ...detail };
|
|
4485
|
+
} else failure = { message: f.message };
|
|
4347
4486
|
}
|
|
4348
4487
|
return Object.hasOwn(v, "result") && v.status !== "succeeded" ? invalid8() : {
|
|
4349
4488
|
id: v.id,
|
|
@@ -4430,12 +4569,23 @@ async function request(key, suffix, init2, maximum = SUMMARY_BYTES, retained, re
|
|
|
4430
4569
|
function summary(value, key, context, id3) {
|
|
4431
4570
|
if (context.kind !== "local")
|
|
4432
4571
|
try {
|
|
4433
|
-
return (!only(value, "id,routine,placement,status,createdAt,startedAt,finishedAt,steps,result,failure") || !Array.isArray(value.steps) || value.steps.some((step) => !only(step, "id,title,status,startedAt,finishedAt,progress,summary,detailAvailable")) || value.failure !== void 0 && !
|
|
4572
|
+
return (!only(value, "id,routine,placement,status,createdAt,startedAt,finishedAt,steps,result,failure") || !Array.isArray(value.steps) || value.steps.some((step) => !only(step, "id,title,status,startedAt,finishedAt,progress,summary,detailAvailable")) || value.failure !== void 0 && !validFailure(value.failure, value.steps)) && fail3("execution_unavailable"), parseRemoteRun(value, { routine: key, id: id3 });
|
|
4434
4573
|
} catch {
|
|
4435
4574
|
return fail3("execution_unavailable");
|
|
4436
4575
|
}
|
|
4437
4576
|
let run = value;
|
|
4438
|
-
return (!only(run, "id,routine,placement,status,createdAt,startedAt,finishedAt,steps,result,failure,local") || typeof run.id != "string" || !uuid2.test(run.id) || id3 !== void 0 && run.id !== id3 || run.routine !== key || run.placement !== "local" || !["queued", "running", "succeeded", "failed"].includes(run.status) || !timestamp(run.createdAt) || !optionalTimes(run) || !Array.isArray(run.steps) || run.steps.length > 64 || run.steps.some((step) => !only(step, "id,title,status,startedAt,finishedAt,progress,summary,detailAvailable") || typeof step.detailAvailable != "boolean" || !validStep(step)) || new Set(run.steps.map((step) => step.id)).size !== run.steps.length || Object.hasOwn(run, "result") && (run.status !== "succeeded" || !bounded2(run.result)) || run.failure !== void 0 && (run.status !== "failed" || !
|
|
4577
|
+
return (!only(run, "id,routine,placement,status,createdAt,startedAt,finishedAt,steps,result,failure,local") || typeof run.id != "string" || !uuid2.test(run.id) || id3 !== void 0 && run.id !== id3 || run.routine !== key || run.placement !== "local" || !["queued", "running", "succeeded", "failed"].includes(run.status) || !timestamp(run.createdAt) || !optionalTimes(run) || !Array.isArray(run.steps) || run.steps.length > 64 || run.steps.some((step) => !only(step, "id,title,status,startedAt,finishedAt,progress,summary,detailAvailable") || typeof step.detailAvailable != "boolean" || !validStep(step)) || new Set(run.steps.map((step) => step.id)).size !== run.steps.length || Object.hasOwn(run, "result") && (run.status !== "succeeded" || !bounded2(run.result)) || run.failure !== void 0 && (run.status !== "failed" || !validFailure(run.failure, run.steps)) || run.local !== void 0 && !validLocalActivity(run.local)) && fail3("execution_unavailable"), run;
|
|
4578
|
+
}
|
|
4579
|
+
function validFailure(value, steps) {
|
|
4580
|
+
if (!only(value, "message,code,step,sizeBytes,limitBytes,summaryBytes,dataBytes") || !message(value.message)) return !1;
|
|
4581
|
+
if (value.code === void 0) return only(value, "message");
|
|
4582
|
+
if (value.code !== "step_output_too_large") return !1;
|
|
4583
|
+
try {
|
|
4584
|
+
let { code: _, message: message2, ...facts } = value, detail = parseRoutineStepOutputDetail(facts);
|
|
4585
|
+
return message2 === routineStepOutputMessage(detail) && steps.some((step) => step.id === detail.step && step.status === "failed");
|
|
4586
|
+
} catch {
|
|
4587
|
+
return !1;
|
|
4588
|
+
}
|
|
4439
4589
|
}
|
|
4440
4590
|
function only(value, allowed) {
|
|
4441
4591
|
return !!value && typeof value == "object" && !Array.isArray(value) && Object.keys(value).every((key) => allowed.split(",").includes(key));
|
|
@@ -4445,7 +4595,16 @@ function optionalTimes(value) {
|
|
|
4445
4595
|
return (value.startedAt === void 0 || timestamp(value.startedAt)) && (value.finishedAt === void 0 || timestamp(value.finishedAt));
|
|
4446
4596
|
}
|
|
4447
4597
|
function validStep(step) {
|
|
4448
|
-
return typeof step.id == "string" && identifier.test(step.id) && typeof step.title == "string" && step.title.length > 0 && step.title.length <= 256 && ["pending", "running", "completed", "failed", "skipped"].includes(step.status) && optionalTimes(step) && (step.progress === void 0 || only(step.progress, "completed,total") && Number.isSafeInteger(step.progress.completed) && Number.isSafeInteger(step.progress.total) && step.progress.completed > 0 && step.progress.completed <= step.progress.total) && (
|
|
4598
|
+
return typeof step.id == "string" && identifier.test(step.id) && typeof step.title == "string" && step.title.length > 0 && step.title.length <= 256 && ["pending", "running", "completed", "failed", "skipped"].includes(step.status) && optionalTimes(step) && (step.progress === void 0 || only(step.progress, "completed,total") && Number.isSafeInteger(step.progress.completed) && Number.isSafeInteger(step.progress.total) && step.progress.completed > 0 && step.progress.completed <= step.progress.total) && (() => {
|
|
4599
|
+
try {
|
|
4600
|
+
return captureRetainedStepOutput(step.id, {
|
|
4601
|
+
...Object.hasOwn(step, "summary") ? { summary: step.summary } : {},
|
|
4602
|
+
...Object.hasOwn(step, "data") ? { data: step.data } : {}
|
|
4603
|
+
}), !0;
|
|
4604
|
+
} catch {
|
|
4605
|
+
return !1;
|
|
4606
|
+
}
|
|
4607
|
+
})();
|
|
4449
4608
|
}
|
|
4450
4609
|
function validLocalActivity(value) {
|
|
4451
4610
|
let paths = (value2) => Array.isArray(value2) && value2.every((path) => typeof path == "string" && path.length > 0 && path.length <= 4096 && !path.startsWith("/") && !path.includes("\\") && !path.split("/").some((part) => !part || part === "." || part === "..") && !/[\x00-\x1f\x7f]/.test(path));
|
|
@@ -4483,7 +4642,7 @@ function handle(key, id3, context) {
|
|
|
4483
4642
|
},
|
|
4484
4643
|
async step(step) {
|
|
4485
4644
|
(typeof step != "string" || !identifier.test(step)) && fail3("invalid_input");
|
|
4486
|
-
let value = await request(key, `runs/${id3}/steps/${step}`, void 0,
|
|
4645
|
+
let value = await request(key, `runs/${id3}/steps/${step}`, void 0, ROUTINE_STEP_OUTPUT_BYTES + 4096, context, !0);
|
|
4487
4646
|
if (context.kind !== "local")
|
|
4488
4647
|
try {
|
|
4489
4648
|
return only(value, "id,title,status,startedAt,finishedAt,progress,summary,data") || fail3("execution_unavailable"), parseRunStep(value, step);
|
|
@@ -4651,6 +4810,7 @@ export {
|
|
|
4651
4810
|
question,
|
|
4652
4811
|
recordBlock,
|
|
4653
4812
|
recordsBlock,
|
|
4813
|
+
requireRecords,
|
|
4654
4814
|
resolveAsk,
|
|
4655
4815
|
respond,
|
|
4656
4816
|
richTextBlock,
|