@eigenpal/cli 0.10.4 → 0.10.6
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @eigenpal/cli
|
|
2
2
|
|
|
3
|
+
## 0.10.5
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- d3a8b79: Workflow dataset commands now handle nested file references in example inputs, so local dataset archives can round-trip file-backed examples through the CLI without flattening the input shape.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 9343b8c: Add `eigenpal workflow schema <workflow>` to print a workflow's inferred output schema — the fields and files it returns, typed from its own steps — as JSON Schema, or as a TypeScript or Python type with `--format`.
|
|
12
|
+
- 9343b8c: `workflow validate` gains an `--online` flag that checks cross-workflow `action.invoke-workflow` references against the server (target existence, input type-match, missing/unknown input keys, undeclared output, and invoke cycles). Local validation can only check a workflow's own shape, so these reference errors previously surfaced only at push; run `eigenpal workflow validate --online` to catch them beforehand.
|
|
13
|
+
|
|
3
14
|
## 0.10.2
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/dist/cli.js
CHANGED
|
@@ -17083,6 +17083,251 @@ var require_picocolors = __commonJS((exports, module) => {
|
|
|
17083
17083
|
// ../types/src/core/index.ts
|
|
17084
17084
|
var init_core3 = () => {};
|
|
17085
17085
|
|
|
17086
|
+
// ../types/src/files/legacy-boundary.ts
|
|
17087
|
+
var LEGACY_FILE_REF_COMPATIBILITY;
|
|
17088
|
+
var init_legacy_boundary = __esm(() => {
|
|
17089
|
+
LEGACY_FILE_REF_COMPATIBILITY = [
|
|
17090
|
+
{
|
|
17091
|
+
id: "legacy-workflow-execution-routes",
|
|
17092
|
+
description: "Old workflow execution list/detail routes may hydrate historical { fileId } trigger inputs for display only."
|
|
17093
|
+
},
|
|
17094
|
+
{
|
|
17095
|
+
id: "rerun-old-immutable-runs",
|
|
17096
|
+
description: "Rerun may remap historical immutable { fileId } trigger inputs while copying those bytes into the new run."
|
|
17097
|
+
},
|
|
17098
|
+
{
|
|
17099
|
+
id: "processor-adapter-runtime-handles",
|
|
17100
|
+
description: "Executor/headless/CLI adapters may normalize local, S3, inline, or fileId runtime handles into private ResolvedProcessorFile objects before processor invocation."
|
|
17101
|
+
}
|
|
17102
|
+
];
|
|
17103
|
+
});
|
|
17104
|
+
|
|
17105
|
+
// ../types/src/files/runtime-file-ref.ts
|
|
17106
|
+
function isRuntimeFileRef(input) {
|
|
17107
|
+
return RuntimeFileRefSchema.safeParse(input).success;
|
|
17108
|
+
}
|
|
17109
|
+
function isResolvedProcessorFile(input) {
|
|
17110
|
+
return ResolvedProcessorFileSchema.safeParse(input).success;
|
|
17111
|
+
}
|
|
17112
|
+
function normalizeLegacyFileIdInput(input) {
|
|
17113
|
+
return {
|
|
17114
|
+
kind: "file",
|
|
17115
|
+
fileId: input.fileId,
|
|
17116
|
+
...input.filename ? { filename: input.filename } : {},
|
|
17117
|
+
...input.mimeType ? { mimeType: input.mimeType } : {}
|
|
17118
|
+
};
|
|
17119
|
+
}
|
|
17120
|
+
var DbFileRefSchema, LegacyFileIdInputSchema, LocalFileRefSchema, S3FileRefSchema, InlineFileRefSchema, RuntimeFileRefSchema, FilePathDescriptorSchema, ResolvedProcessorFileSchema, STRING_SCHEMA, WORKFLOW_FILE_REF_JSON_SCHEMA;
|
|
17121
|
+
var init_runtime_file_ref = __esm(() => {
|
|
17122
|
+
init_zod();
|
|
17123
|
+
DbFileRefSchema = exports_external.object({
|
|
17124
|
+
kind: exports_external.literal("file"),
|
|
17125
|
+
fileId: exports_external.string().describe("File ID from files table"),
|
|
17126
|
+
filename: exports_external.string().optional().describe("Original filename"),
|
|
17127
|
+
mimeType: exports_external.string().optional().describe("MIME type")
|
|
17128
|
+
});
|
|
17129
|
+
LegacyFileIdInputSchema = exports_external.object({
|
|
17130
|
+
kind: exports_external.never().optional(),
|
|
17131
|
+
fileId: exports_external.string().describe("File ID from files table"),
|
|
17132
|
+
filename: exports_external.string().optional().describe("Original filename"),
|
|
17133
|
+
mimeType: exports_external.string().optional().describe("MIME type")
|
|
17134
|
+
});
|
|
17135
|
+
LocalFileRefSchema = exports_external.object({
|
|
17136
|
+
kind: exports_external.literal("local"),
|
|
17137
|
+
path: exports_external.string().describe("Absolute path to a file on disk"),
|
|
17138
|
+
filename: exports_external.string().describe("Original filename"),
|
|
17139
|
+
mimeType: exports_external.string().describe("MIME type of the file")
|
|
17140
|
+
});
|
|
17141
|
+
S3FileRefSchema = exports_external.object({
|
|
17142
|
+
kind: exports_external.literal("s3"),
|
|
17143
|
+
ref: exports_external.string().describe("Storage key (suffix-only, prefix added by adapter)"),
|
|
17144
|
+
filename: exports_external.string().describe("Original filename"),
|
|
17145
|
+
mimeType: exports_external.string().describe("MIME type of the file")
|
|
17146
|
+
});
|
|
17147
|
+
InlineFileRefSchema = exports_external.object({
|
|
17148
|
+
kind: exports_external.literal("inline"),
|
|
17149
|
+
base64: exports_external.string().describe("Base64-encoded file bytes"),
|
|
17150
|
+
filename: exports_external.string().describe("Original filename"),
|
|
17151
|
+
mimeType: exports_external.string().describe("MIME type of the file")
|
|
17152
|
+
});
|
|
17153
|
+
RuntimeFileRefSchema = exports_external.discriminatedUnion("kind", [
|
|
17154
|
+
DbFileRefSchema,
|
|
17155
|
+
LocalFileRefSchema,
|
|
17156
|
+
S3FileRefSchema,
|
|
17157
|
+
InlineFileRefSchema
|
|
17158
|
+
]);
|
|
17159
|
+
FilePathDescriptorSchema = exports_external.discriminatedUnion("kind", [
|
|
17160
|
+
LocalFileRefSchema,
|
|
17161
|
+
S3FileRefSchema,
|
|
17162
|
+
InlineFileRefSchema
|
|
17163
|
+
]);
|
|
17164
|
+
ResolvedProcessorFileSchema = exports_external.object({
|
|
17165
|
+
__eigenpalFile: exports_external.literal(true),
|
|
17166
|
+
source: exports_external.enum(["db", "tenant-s3", "local", "inline"]),
|
|
17167
|
+
filename: exports_external.string().describe("Display filename for processor logs and parser routing"),
|
|
17168
|
+
mimeType: exports_external.string().describe("MIME type for processor routing"),
|
|
17169
|
+
fileId: exports_external.string().optional().describe("Legacy files-table id for db-backed handles"),
|
|
17170
|
+
ref: exports_external.string().optional().describe("Tenant-scoped storage key suffix for S3-backed handles"),
|
|
17171
|
+
path: exports_external.string().optional().describe("Local filesystem path for headless/CLI handles"),
|
|
17172
|
+
base64: exports_external.string().optional().describe("Base64 bytes for inline handles")
|
|
17173
|
+
}).strict();
|
|
17174
|
+
STRING_SCHEMA = { type: "string" };
|
|
17175
|
+
WORKFLOW_FILE_REF_JSON_SCHEMA = {
|
|
17176
|
+
"x-eigenpal-type": "file",
|
|
17177
|
+
type: "object",
|
|
17178
|
+
anyOf: [
|
|
17179
|
+
{
|
|
17180
|
+
type: "object",
|
|
17181
|
+
required: ["$file"],
|
|
17182
|
+
additionalProperties: false,
|
|
17183
|
+
properties: {
|
|
17184
|
+
$file: STRING_SCHEMA
|
|
17185
|
+
}
|
|
17186
|
+
},
|
|
17187
|
+
{
|
|
17188
|
+
type: "object",
|
|
17189
|
+
required: ["$fileId"],
|
|
17190
|
+
additionalProperties: false,
|
|
17191
|
+
properties: {
|
|
17192
|
+
$fileId: STRING_SCHEMA
|
|
17193
|
+
}
|
|
17194
|
+
},
|
|
17195
|
+
{
|
|
17196
|
+
type: "object",
|
|
17197
|
+
required: ["$inline"],
|
|
17198
|
+
additionalProperties: false,
|
|
17199
|
+
properties: {
|
|
17200
|
+
$inline: {
|
|
17201
|
+
type: "object",
|
|
17202
|
+
required: ["filename", "mimeType", "base64"],
|
|
17203
|
+
additionalProperties: false,
|
|
17204
|
+
properties: {
|
|
17205
|
+
filename: STRING_SCHEMA,
|
|
17206
|
+
mimeType: STRING_SCHEMA,
|
|
17207
|
+
base64: STRING_SCHEMA
|
|
17208
|
+
}
|
|
17209
|
+
}
|
|
17210
|
+
}
|
|
17211
|
+
}
|
|
17212
|
+
]
|
|
17213
|
+
};
|
|
17214
|
+
});
|
|
17215
|
+
|
|
17216
|
+
// ../types/src/files/scoped-file-ref.ts
|
|
17217
|
+
function isScopedFileRef(value) {
|
|
17218
|
+
return ScopedFileRefSchema.safeParse(value).success;
|
|
17219
|
+
}
|
|
17220
|
+
function isFileIdIngressRef(value) {
|
|
17221
|
+
return FileIdIngressRefSchema.safeParse(value).success;
|
|
17222
|
+
}
|
|
17223
|
+
function isInlineFileIngressRef(value) {
|
|
17224
|
+
return InlineFileIngressRefSchema.safeParse(value).success;
|
|
17225
|
+
}
|
|
17226
|
+
function isFileIngressRef(value) {
|
|
17227
|
+
return FileIngressRefSchema.safeParse(value).success;
|
|
17228
|
+
}
|
|
17229
|
+
function isFileReferenceSentinel(value) {
|
|
17230
|
+
return FileReferenceSentinelSchema.safeParse(value).success;
|
|
17231
|
+
}
|
|
17232
|
+
function fileReferenceKind(ref) {
|
|
17233
|
+
if ("$file" in ref)
|
|
17234
|
+
return "file";
|
|
17235
|
+
if ("$fileId" in ref)
|
|
17236
|
+
return "fileId";
|
|
17237
|
+
return "inline";
|
|
17238
|
+
}
|
|
17239
|
+
function validateScopedArtifactPath(path, options = {}) {
|
|
17240
|
+
if (path.length === 0)
|
|
17241
|
+
return { ok: false, reason: "path is empty" };
|
|
17242
|
+
if (path.startsWith("/"))
|
|
17243
|
+
return { ok: false, reason: "leading slash not allowed" };
|
|
17244
|
+
if (path.includes("\\"))
|
|
17245
|
+
return { ok: false, reason: "backslashes not allowed" };
|
|
17246
|
+
if (path.includes("\x00"))
|
|
17247
|
+
return { ok: false, reason: "null bytes not allowed" };
|
|
17248
|
+
const segments = path.split("/");
|
|
17249
|
+
for (const segment of segments) {
|
|
17250
|
+
if (segment.length === 0)
|
|
17251
|
+
return { ok: false, reason: "empty path segment not allowed" };
|
|
17252
|
+
if (segment === ".")
|
|
17253
|
+
return { ok: false, reason: "current-directory segment not allowed" };
|
|
17254
|
+
if (segment === "..")
|
|
17255
|
+
return { ok: false, reason: "path traversal segment not allowed" };
|
|
17256
|
+
}
|
|
17257
|
+
if (segments[0] === "tenants" || segments[0] === "automations" || segments[0] === "workflows" || segments[0] === "agents") {
|
|
17258
|
+
return { ok: false, reason: "storage prefixes are not allowed in scoped file refs" };
|
|
17259
|
+
}
|
|
17260
|
+
const normalizedRoots = (options.allowedRoots ?? []).map((root) => root.replace(/^\/+|\/+$/g, ""));
|
|
17261
|
+
if (normalizedRoots.length > 0 && !normalizedRoots.some((root) => path === root || path.startsWith(`${root}/`))) {
|
|
17262
|
+
return { ok: false, reason: `path root must be one of: ${normalizedRoots.join(", ")}` };
|
|
17263
|
+
}
|
|
17264
|
+
return { ok: true, value: { path: segments.join("/"), segments, root: segments[0] } };
|
|
17265
|
+
}
|
|
17266
|
+
function collectFileReferenceSentinels(value) {
|
|
17267
|
+
const matches = [];
|
|
17268
|
+
walkFileReferenceSentinels(value, (match) => {
|
|
17269
|
+
matches.push(match);
|
|
17270
|
+
});
|
|
17271
|
+
return matches;
|
|
17272
|
+
}
|
|
17273
|
+
function walkFileReferenceSentinels(value, visit, path = []) {
|
|
17274
|
+
const parsed = FileReferenceSentinelSchema.safeParse(value);
|
|
17275
|
+
if (parsed.success) {
|
|
17276
|
+
visit({ path, ref: parsed.data, kind: fileReferenceKind(parsed.data) });
|
|
17277
|
+
return;
|
|
17278
|
+
}
|
|
17279
|
+
if (Array.isArray(value)) {
|
|
17280
|
+
value.forEach((item, index) => walkFileReferenceSentinels(item, visit, [...path, String(index)]));
|
|
17281
|
+
return;
|
|
17282
|
+
}
|
|
17283
|
+
if (value && typeof value === "object") {
|
|
17284
|
+
for (const [key, item] of Object.entries(value)) {
|
|
17285
|
+
walkFileReferenceSentinels(item, visit, [...path, key]);
|
|
17286
|
+
}
|
|
17287
|
+
}
|
|
17288
|
+
}
|
|
17289
|
+
function mapFileReferenceSentinels(value, mapper, path = []) {
|
|
17290
|
+
const parsed = FileReferenceSentinelSchema.safeParse(value);
|
|
17291
|
+
if (parsed.success) {
|
|
17292
|
+
return mapper({ path, ref: parsed.data, kind: fileReferenceKind(parsed.data) });
|
|
17293
|
+
}
|
|
17294
|
+
if (Array.isArray(value)) {
|
|
17295
|
+
return value.map((item, index) => mapFileReferenceSentinels(item, mapper, [...path, String(index)]));
|
|
17296
|
+
}
|
|
17297
|
+
if (value && typeof value === "object") {
|
|
17298
|
+
const out = {};
|
|
17299
|
+
for (const [key, item] of Object.entries(value)) {
|
|
17300
|
+
out[key] = mapFileReferenceSentinels(item, mapper, [...path, key]);
|
|
17301
|
+
}
|
|
17302
|
+
return out;
|
|
17303
|
+
}
|
|
17304
|
+
return value;
|
|
17305
|
+
}
|
|
17306
|
+
var ScopedFileRefSchema, FileIdIngressRefSchema, InlineFileIngressPayloadSchema, InlineFileIngressRefSchema, FileIngressRefSchema, FileReferenceSentinelSchema;
|
|
17307
|
+
var init_scoped_file_ref = __esm(() => {
|
|
17308
|
+
init_zod();
|
|
17309
|
+
ScopedFileRefSchema = exports_external.object({
|
|
17310
|
+
$file: exports_external.string().min(1).describe("Owner-relative artifact path")
|
|
17311
|
+
}).strict();
|
|
17312
|
+
FileIdIngressRefSchema = exports_external.object({
|
|
17313
|
+
$fileId: exports_external.string().min(1).describe("Reusable file-pool id to materialize")
|
|
17314
|
+
}).strict();
|
|
17315
|
+
InlineFileIngressPayloadSchema = exports_external.object({
|
|
17316
|
+
filename: exports_external.string().min(1).describe("Original filename for the materialized artifact"),
|
|
17317
|
+
mimeType: exports_external.string().min(1).describe("MIME type for the materialized artifact"),
|
|
17318
|
+
base64: exports_external.string().min(1).describe("Base64-encoded file bytes")
|
|
17319
|
+
}).strict();
|
|
17320
|
+
InlineFileIngressRefSchema = exports_external.object({
|
|
17321
|
+
$inline: InlineFileIngressPayloadSchema
|
|
17322
|
+
}).strict();
|
|
17323
|
+
FileIngressRefSchema = exports_external.union([FileIdIngressRefSchema, InlineFileIngressRefSchema]);
|
|
17324
|
+
FileReferenceSentinelSchema = exports_external.union([
|
|
17325
|
+
ScopedFileRefSchema,
|
|
17326
|
+
FileIdIngressRefSchema,
|
|
17327
|
+
InlineFileIngressRefSchema
|
|
17328
|
+
]);
|
|
17329
|
+
});
|
|
17330
|
+
|
|
17086
17331
|
// ../types/src/processor/index.ts
|
|
17087
17332
|
var init_processor = () => {};
|
|
17088
17333
|
|
|
@@ -23915,7 +24160,7 @@ function workflowInputTypeToJsonSchema(def) {
|
|
|
23915
24160
|
case "boolean":
|
|
23916
24161
|
return { type: "boolean" };
|
|
23917
24162
|
case "file":
|
|
23918
|
-
return { ...
|
|
24163
|
+
return { ...WORKFLOW_FILE_REF_JSON_SCHEMA };
|
|
23919
24164
|
case "array":
|
|
23920
24165
|
return { type: "array", items: itemsToJsonSchema(def.items) };
|
|
23921
24166
|
case "object":
|
|
@@ -23928,7 +24173,7 @@ function itemsToJsonSchema(items) {
|
|
|
23928
24173
|
if (!items)
|
|
23929
24174
|
return {};
|
|
23930
24175
|
if (items.type === "file")
|
|
23931
|
-
return { ...
|
|
24176
|
+
return { ...WORKFLOW_FILE_REF_JSON_SCHEMA };
|
|
23932
24177
|
if (items.type === "enum" && items.values && items.values.length > 0) {
|
|
23933
24178
|
return { type: "string", enum: items.values };
|
|
23934
24179
|
}
|
|
@@ -24032,9 +24277,7 @@ function withPendingFileRefs(input, files) {
|
|
|
24032
24277
|
const refsByField = {};
|
|
24033
24278
|
for (const f of files) {
|
|
24034
24279
|
(refsByField[f.fieldName] ??= []).push({
|
|
24035
|
-
|
|
24036
|
-
filename: f.filename,
|
|
24037
|
-
mimeType: f.mimeType
|
|
24280
|
+
$file: `input/${f.fieldName}/${PENDING_FILE_REF}-${f.filename}`
|
|
24038
24281
|
});
|
|
24039
24282
|
}
|
|
24040
24283
|
const merged = { ...input };
|
|
@@ -24089,8 +24332,9 @@ function coerceScalar(value, type) {
|
|
|
24089
24332
|
}
|
|
24090
24333
|
return;
|
|
24091
24334
|
}
|
|
24092
|
-
var INPUT_VALIDATION_CODES,
|
|
24335
|
+
var INPUT_VALIDATION_CODES, PENDING_FILE_REF = "__pending_upload__";
|
|
24093
24336
|
var init_input = __esm(() => {
|
|
24337
|
+
init_runtime_file_ref();
|
|
24094
24338
|
init_ajv();
|
|
24095
24339
|
INPUT_VALIDATION_CODES = [
|
|
24096
24340
|
"missing_required",
|
|
@@ -24100,16 +24344,6 @@ var init_input = __esm(() => {
|
|
|
24100
24344
|
"array_length",
|
|
24101
24345
|
"invalid_value"
|
|
24102
24346
|
];
|
|
24103
|
-
FILE_REF_SCHEMA = {
|
|
24104
|
-
type: "object",
|
|
24105
|
-
required: ["fileId"],
|
|
24106
|
-
"x-eigenpal-type": "file",
|
|
24107
|
-
properties: {
|
|
24108
|
-
fileId: { type: "string" },
|
|
24109
|
-
filename: { type: "string" },
|
|
24110
|
-
mimeType: { type: "string" }
|
|
24111
|
-
}
|
|
24112
|
-
};
|
|
24113
24347
|
});
|
|
24114
24348
|
|
|
24115
24349
|
// ../types/src/validation/output.ts
|
|
@@ -62096,7 +62330,7 @@ var init_step_configs = __esm(() => {
|
|
|
62096
62330
|
text: exports_external.string().describe("Extracted text from the document")
|
|
62097
62331
|
});
|
|
62098
62332
|
TransformXlsxToJsonConfigSchema = exports_external.object({
|
|
62099
|
-
input: exports_external.string().min(1, "Input is required").describe("File input - template expression e.g. {{input.document}} resolving to
|
|
62333
|
+
input: exports_external.string().min(1, "Input is required").describe("File input - template expression e.g. {{input.document}} resolving to a scoped $file artifact at runtime"),
|
|
62100
62334
|
sheet: exports_external.union([exports_external.number().int().min(0), exports_external.string()]).optional().describe("Sheet to read: 0-based index or sheet name. Omit for first sheet."),
|
|
62101
62335
|
outputCsv: exports_external.boolean().default(false).describe("If true, also write CSV to storage and include fileId in output"),
|
|
62102
62336
|
outputFilename: exports_external.string().optional().describe("Output CSV filename when outputCsv is true - supports LiquidJS e.g. {{filename}}.csv")
|
|
@@ -62221,12 +62455,12 @@ var init_step_configs = __esm(() => {
|
|
|
62221
62455
|
});
|
|
62222
62456
|
ActionInvokeWorkflowConfigSchema = exports_external.object({
|
|
62223
62457
|
workflowId: exports_external.string().min(1, "Workflow ID is required").describe("ID of workflow to invoke"),
|
|
62224
|
-
input: exports_external.record(exports_external.string(), exports_external.unknown()).optional().describe("Input
|
|
62225
|
-
wait: exports_external.boolean().optional().describe("
|
|
62226
|
-
timeout: exports_external.number().optional().describe("Max wait time in ms when
|
|
62227
|
-
pollInterval: exports_external.number().optional().describe("How often to poll status in ms when
|
|
62458
|
+
input: exports_external.record(exports_external.string(), exports_external.unknown()).optional().describe("Input record keyed by the invoked workflow's declared inputs"),
|
|
62459
|
+
wait: exports_external.boolean().optional().describe("Wait for the invoked workflow to complete and return its output (default: true). Set false for fire-and-forget."),
|
|
62460
|
+
timeout: exports_external.number().optional().describe("Max wait time in ms when waiting (default: 300000)"),
|
|
62461
|
+
pollInterval: exports_external.number().optional().describe("How often to poll status in ms when waiting (default: 1000)")
|
|
62228
62462
|
});
|
|
62229
|
-
ActionInvokeWorkflowOutputSchema = exports_external.record(exports_external.string(), exports_external.unknown()).describe("
|
|
62463
|
+
ActionInvokeWorkflowOutputSchema = exports_external.record(exports_external.string(), exports_external.unknown()).describe("When wait is true, the invoked workflow's declared output fields are flattened to the top level alongside a `files` array — reference them as {{ steps.<invoke>.output.<field> }} (there is no `.data` or `.result` wrapper). When wait is false, execution metadata. Call get_workflow_output_schema to see the exact resolved fields.");
|
|
62230
62464
|
ActionWebsiteReaderConfigSchema = exports_external.object({
|
|
62231
62465
|
url: exports_external.string().min(1, "URL is required").describe("Website URL to fetch (supports template expressions)"),
|
|
62232
62466
|
timeout: exports_external.number().positive().default(30000).optional().describe("Timeout in milliseconds"),
|
|
@@ -62719,7 +62953,7 @@ var init_workflow = __esm(() => {
|
|
|
62719
62953
|
triggerMethods: exports_external.array(TriggerMethodSchema).default([{ type: "manual" }]),
|
|
62720
62954
|
inputs: exports_external.array(WorkflowInputDefSchema).optional(),
|
|
62721
62955
|
steps: exports_external.array(StepSchema),
|
|
62722
|
-
output: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
62956
|
+
output: exports_external.union([exports_external.record(exports_external.string(), exports_external.string()), exports_external.string()]).optional(),
|
|
62723
62957
|
settings: WorkflowSettingsSchema.optional(),
|
|
62724
62958
|
defaultModel: exports_external.string().optional()
|
|
62725
62959
|
});
|
|
@@ -63032,6 +63266,117 @@ var init_execution2 = __esm(() => {
|
|
|
63032
63266
|
});
|
|
63033
63267
|
});
|
|
63034
63268
|
|
|
63269
|
+
// ../types/src/workflow/invoke-workflow-contract.ts
|
|
63270
|
+
function inputToJsonSchema(input) {
|
|
63271
|
+
switch (input.type) {
|
|
63272
|
+
case "string":
|
|
63273
|
+
return { type: "string" };
|
|
63274
|
+
case "number":
|
|
63275
|
+
return { type: "number" };
|
|
63276
|
+
case "integer":
|
|
63277
|
+
return { type: "integer" };
|
|
63278
|
+
case "boolean":
|
|
63279
|
+
return { type: "boolean" };
|
|
63280
|
+
case "object":
|
|
63281
|
+
return { type: "object" };
|
|
63282
|
+
case "enum":
|
|
63283
|
+
return input.values && input.values.length > 0 ? { type: "string", enum: input.values } : { type: "string" };
|
|
63284
|
+
case "array": {
|
|
63285
|
+
const itemType = input.items?.type;
|
|
63286
|
+
if (itemType === "enum" && input.items?.values?.length) {
|
|
63287
|
+
return { type: "array", items: { type: "string", enum: input.items.values } };
|
|
63288
|
+
}
|
|
63289
|
+
return itemType ? { type: "array", items: { type: itemType } } : { type: "array" };
|
|
63290
|
+
}
|
|
63291
|
+
case "file":
|
|
63292
|
+
return {};
|
|
63293
|
+
default:
|
|
63294
|
+
return {};
|
|
63295
|
+
}
|
|
63296
|
+
}
|
|
63297
|
+
function buildWorkflowInputsJsonSchema(inputs) {
|
|
63298
|
+
const properties = {};
|
|
63299
|
+
const required2 = [];
|
|
63300
|
+
for (const input of inputs ?? []) {
|
|
63301
|
+
properties[input.name] = inputToJsonSchema(input);
|
|
63302
|
+
if (input.required !== false)
|
|
63303
|
+
required2.push(input.name);
|
|
63304
|
+
}
|
|
63305
|
+
return { type: "object", additionalProperties: false, required: required2, properties };
|
|
63306
|
+
}
|
|
63307
|
+
function workflowInputAcceptsType(inputType, resolvedType) {
|
|
63308
|
+
if (resolvedType === "unknown" || resolvedType === "null")
|
|
63309
|
+
return true;
|
|
63310
|
+
switch (inputType) {
|
|
63311
|
+
case "string":
|
|
63312
|
+
case "enum":
|
|
63313
|
+
return resolvedType === "string";
|
|
63314
|
+
case "number":
|
|
63315
|
+
case "integer":
|
|
63316
|
+
return resolvedType === "number" || resolvedType === "integer";
|
|
63317
|
+
case "boolean":
|
|
63318
|
+
return resolvedType === "boolean";
|
|
63319
|
+
case "array":
|
|
63320
|
+
return resolvedType === "array";
|
|
63321
|
+
case "file":
|
|
63322
|
+
return resolvedType === "file" || resolvedType === "object" || resolvedType === "array";
|
|
63323
|
+
case "object":
|
|
63324
|
+
default:
|
|
63325
|
+
return true;
|
|
63326
|
+
}
|
|
63327
|
+
}
|
|
63328
|
+
function buildWorkflowOutputContractSchema(output) {
|
|
63329
|
+
if (typeof output === "string")
|
|
63330
|
+
return;
|
|
63331
|
+
const keys = Object.keys(output ?? {});
|
|
63332
|
+
if (keys.length === 0)
|
|
63333
|
+
return;
|
|
63334
|
+
const properties = {};
|
|
63335
|
+
for (const key of keys)
|
|
63336
|
+
properties[key] = {};
|
|
63337
|
+
return { type: "object", additionalProperties: false, required: keys, properties };
|
|
63338
|
+
}
|
|
63339
|
+
function hasDeclaredOutput(output) {
|
|
63340
|
+
if (typeof output === "string")
|
|
63341
|
+
return output.trim().length > 0;
|
|
63342
|
+
return !!output && Object.keys(output).length > 0;
|
|
63343
|
+
}
|
|
63344
|
+
function* iterateSteps(steps) {
|
|
63345
|
+
if (!Array.isArray(steps))
|
|
63346
|
+
return;
|
|
63347
|
+
for (const raw of steps) {
|
|
63348
|
+
if (!raw || typeof raw !== "object")
|
|
63349
|
+
continue;
|
|
63350
|
+
const step = raw;
|
|
63351
|
+
yield step;
|
|
63352
|
+
for (const value of Object.values(step)) {
|
|
63353
|
+
if (!Array.isArray(value))
|
|
63354
|
+
continue;
|
|
63355
|
+
for (const item of value) {
|
|
63356
|
+
if (!item || typeof item !== "object")
|
|
63357
|
+
continue;
|
|
63358
|
+
const obj = item;
|
|
63359
|
+
if ("type" in obj) {
|
|
63360
|
+
yield* iterateSteps([obj]);
|
|
63361
|
+
} else if (Array.isArray(obj.steps)) {
|
|
63362
|
+
yield* iterateSteps(obj.steps);
|
|
63363
|
+
}
|
|
63364
|
+
}
|
|
63365
|
+
}
|
|
63366
|
+
}
|
|
63367
|
+
}
|
|
63368
|
+
function collectInvokeWorkflowTargetIds(definition) {
|
|
63369
|
+
const ids = new Set;
|
|
63370
|
+
for (const step of iterateSteps(definition?.steps)) {
|
|
63371
|
+
if (step.type === "action.invoke-workflow") {
|
|
63372
|
+
const id = step.with?.workflowId;
|
|
63373
|
+
if (typeof id === "string" && id.length > 0)
|
|
63374
|
+
ids.add(id);
|
|
63375
|
+
}
|
|
63376
|
+
}
|
|
63377
|
+
return [...ids];
|
|
63378
|
+
}
|
|
63379
|
+
|
|
63035
63380
|
// ../types/src/workflow/index.ts
|
|
63036
63381
|
var init_workflow2 = __esm(() => {
|
|
63037
63382
|
init_step_configs();
|
|
@@ -65643,11 +65988,14 @@ __export(exports_src, {
|
|
|
65643
65988
|
workspaceDependencyNameToPackagePath: () => workspaceDependencyNameToPackagePath,
|
|
65644
65989
|
workflowTriggerConfigSchema: () => workflowTriggerConfigSchema,
|
|
65645
65990
|
workflowInputsToJsonSchema: () => workflowInputsToJsonSchema,
|
|
65991
|
+
workflowInputAcceptsType: () => workflowInputAcceptsType,
|
|
65646
65992
|
withPendingFileRefs: () => withPendingFileRefs,
|
|
65993
|
+
walkFileReferenceSentinels: () => walkFileReferenceSentinels,
|
|
65647
65994
|
valuesMatch: () => valuesMatch,
|
|
65648
65995
|
validateWorkspaceSchema: () => validateWorkspaceSchema,
|
|
65649
65996
|
validateStepConfig: () => validateStepConfig,
|
|
65650
65997
|
validateSourcePackageRequiredFiles: () => validateSourcePackageRequiredFiles,
|
|
65998
|
+
validateScopedArtifactPath: () => validateScopedArtifactPath,
|
|
65651
65999
|
validateOutput: () => validateOutput,
|
|
65652
66000
|
validateInput: () => validateInput,
|
|
65653
66001
|
validateFileSourceConfig: () => validateFileSourceConfig,
|
|
@@ -65690,11 +66038,13 @@ __export(exports_src, {
|
|
|
65690
66038
|
parseFailureEnvelope: () => parseFailureEnvelope,
|
|
65691
66039
|
parseAutomationTarget: () => parseAutomationTarget,
|
|
65692
66040
|
parseAgentRerunVersion: () => parseAgentRerunVersion,
|
|
66041
|
+
normalizeLegacyFileIdInput: () => normalizeLegacyFileIdInput,
|
|
65693
66042
|
noopTracingContext: () => noopTracingContext,
|
|
65694
66043
|
mimeTypeForExtension: () => mimeTypeForExtension,
|
|
65695
66044
|
matchS3Path: () => matchS3Path,
|
|
65696
66045
|
mapOCRAttributes: () => mapOCRAttributes,
|
|
65697
66046
|
mapLLMAttributes: () => mapLLMAttributes,
|
|
66047
|
+
mapFileReferenceSentinels: () => mapFileReferenceSentinels,
|
|
65698
66048
|
listStepTypesByCategory: () => listStepTypesByCategory,
|
|
65699
66049
|
listStepTypes: () => listStepTypes,
|
|
65700
66050
|
listProcessorIds: () => listProcessorIds,
|
|
@@ -65703,19 +66053,27 @@ __export(exports_src, {
|
|
|
65703
66053
|
isWorkflowResult: () => isWorkflowResult,
|
|
65704
66054
|
isTerminalExecutionStatus: () => isTerminalExecutionStatus,
|
|
65705
66055
|
isStepCategory: () => isStepCategory,
|
|
66056
|
+
isScopedFileRef: () => isScopedFileRef,
|
|
65706
66057
|
isSchemaFile: () => isSchemaFile,
|
|
66058
|
+
isRuntimeFileRef: () => isRuntimeFileRef,
|
|
65707
66059
|
isRunInSampleRank: () => isRunInSampleRank,
|
|
65708
66060
|
isRunExpandSection: () => isRunExpandSection,
|
|
66061
|
+
isResolvedProcessorFile: () => isResolvedProcessorFile,
|
|
65709
66062
|
isOutputSchemaUnknown: () => isOutputSchemaUnknown,
|
|
65710
66063
|
isNonSuccessTerminalExecutionStatus: () => isNonSuccessTerminalExecutionStatus,
|
|
65711
66064
|
isManualTriggerEnabled: () => isManualTriggerEnabled,
|
|
65712
66065
|
isLocalAgentResourcePath: () => isLocalAgentResourcePath,
|
|
66066
|
+
isInlineFileIngressRef: () => isInlineFileIngressRef,
|
|
66067
|
+
isFileReferenceSentinel: () => isFileReferenceSentinel,
|
|
65713
66068
|
isFilePathDescriptor: () => isFilePathDescriptor,
|
|
65714
66069
|
isFileOutput: () => isFileOutput,
|
|
66070
|
+
isFileIngressRef: () => isFileIngressRef,
|
|
66071
|
+
isFileIdIngressRef: () => isFileIdIngressRef,
|
|
65715
66072
|
isAutomationTriggerEnabled: () => isAutomationTriggerEnabled,
|
|
65716
66073
|
isAgentEmailExplicitlyDisabled: () => isAgentEmailExplicitlyDisabled,
|
|
65717
66074
|
inputsWithSource: () => inputsWithSource,
|
|
65718
66075
|
hasTriggerMethod: () => hasTriggerMethod,
|
|
66076
|
+
hasDeclaredOutput: () => hasDeclaredOutput,
|
|
65719
66077
|
goldenFileSatisfiedInResult: () => goldenFileSatisfiedInResult,
|
|
65720
66078
|
getTriggerMethods: () => getTriggerMethods,
|
|
65721
66079
|
getSupportedFormatsLabel: () => getSupportedFormatsLabel,
|
|
@@ -65739,6 +66097,7 @@ __export(exports_src, {
|
|
|
65739
66097
|
formatReleaseTag: () => formatReleaseTag,
|
|
65740
66098
|
formatHostedSourceExportPath: () => formatHostedSourceExportPath,
|
|
65741
66099
|
formatDiffValue: () => formatDiffValue,
|
|
66100
|
+
fileReferenceKind: () => fileReferenceKind,
|
|
65742
66101
|
fileFieldNamesFromJsonSchema: () => fileFieldNamesFromJsonSchema,
|
|
65743
66102
|
fieldStemFromGoldenName: () => fieldStemFromGoldenName,
|
|
65744
66103
|
extractFieldMetadata: () => extractFieldMetadata,
|
|
@@ -65759,7 +66118,11 @@ __export(exports_src, {
|
|
|
65759
66118
|
compareExpectedValues: () => compareExpectedValues,
|
|
65760
66119
|
compareExpectedError: () => compareExpectedError,
|
|
65761
66120
|
combineEvalScores: () => combineEvalScores,
|
|
66121
|
+
collectInvokeWorkflowTargetIds: () => collectInvokeWorkflowTargetIds,
|
|
66122
|
+
collectFileReferenceSentinels: () => collectFileReferenceSentinels,
|
|
65762
66123
|
coerceInput: () => coerceInput,
|
|
66124
|
+
buildWorkflowOutputContractSchema: () => buildWorkflowOutputContractSchema,
|
|
66125
|
+
buildWorkflowInputsJsonSchema: () => buildWorkflowInputsJsonSchema,
|
|
65763
66126
|
buildS3PathSuffix: () => buildS3PathSuffix,
|
|
65764
66127
|
buildS3Path: () => buildS3Path,
|
|
65765
66128
|
buildDiscreteJudgeSystemPrompt: () => buildDiscreteJudgeSystemPrompt,
|
|
@@ -65788,6 +66151,7 @@ __export(exports_src, {
|
|
|
65788
66151
|
WaitStepSchema: () => WaitStepSchema,
|
|
65789
66152
|
WORKFLOW_TOOL_METADATA: () => WORKFLOW_TOOL_METADATA,
|
|
65790
66153
|
WORKFLOW_NAME_PATTERN: () => WORKFLOW_NAME_PATTERN,
|
|
66154
|
+
WORKFLOW_FILE_REF_JSON_SCHEMA: () => WORKFLOW_FILE_REF_JSON_SCHEMA,
|
|
65791
66155
|
WORKFLOW_EXECUTION_STATUSES: () => WORKFLOW_EXECUTION_STATUSES,
|
|
65792
66156
|
UNSUPPORTED_SOURCE_MANIFEST_FILENAME: () => UNSUPPORTED_SOURCE_MANIFEST_FILENAME,
|
|
65793
66157
|
TriggerTypeValue: () => TriggerTypeValue,
|
|
@@ -65851,6 +66215,7 @@ __export(exports_src, {
|
|
|
65851
66215
|
SharedEvaluatorReferenceSchema: () => SharedEvaluatorReferenceSchema,
|
|
65852
66216
|
SharedEvaluatorCompositionItemSchema: () => SharedEvaluatorCompositionItemSchema,
|
|
65853
66217
|
SecretNameSchema: () => SecretNameSchema,
|
|
66218
|
+
ScopedFileRefSchema: () => ScopedFileRefSchema,
|
|
65854
66219
|
ScopeStackSchema: () => ScopeStackSchema,
|
|
65855
66220
|
ScopeEntryTypeSchema: () => ScopeEntryTypeSchema,
|
|
65856
66221
|
ScopeEntrySchema: () => ScopeEntrySchema,
|
|
@@ -65865,10 +66230,14 @@ __export(exports_src, {
|
|
|
65865
66230
|
SOURCE_COMMIT_SHA_PATTERN: () => SOURCE_COMMIT_SHA_PATTERN,
|
|
65866
66231
|
SCRIPT_FN_MAX_BYTES: () => SCRIPT_FN_MAX_BYTES,
|
|
65867
66232
|
S3_PATH_GRAMMAR: () => S3_PATH_GRAMMAR,
|
|
66233
|
+
S3FileRefSchema: () => S3FileRefSchema,
|
|
66234
|
+
RuntimeFileRefSchema: () => RuntimeFileRefSchema,
|
|
66235
|
+
RuntimeFilePathDescriptorSchema: () => FilePathDescriptorSchema,
|
|
65868
66236
|
RunTargetStringSchema: () => RunTargetStringSchema,
|
|
65869
66237
|
RunTargetSchema: () => RunTargetSchema,
|
|
65870
66238
|
RunTargetObjectSchema: () => RunTargetObjectSchema,
|
|
65871
66239
|
RootSourceManifestSchema: () => RootSourceManifestSchema,
|
|
66240
|
+
ResolvedProcessorFileSchema: () => ResolvedProcessorFileSchema,
|
|
65872
66241
|
ReleaseTagSchema: () => ReleaseTagSchema,
|
|
65873
66242
|
RUN_TARGET_SEGMENT_PATTERN: () => RUN_TARGET_SEGMENT_PATTERN,
|
|
65874
66243
|
RUN_EXPAND_SECTIONS: () => RUN_EXPAND_SECTIONS,
|
|
@@ -65907,16 +66276,22 @@ __export(exports_src, {
|
|
|
65907
66276
|
MergeConfigSchema: () => MergeConfigSchema,
|
|
65908
66277
|
ManualTriggerMethodSchema: () => ManualTriggerMethodSchema,
|
|
65909
66278
|
MAX_PAGE_SIZE: () => MAX_PAGE_SIZE,
|
|
66279
|
+
LocalFileRefSchema: () => LocalFileRefSchema,
|
|
65910
66280
|
LocalEvaluatorReferenceSchema: () => LocalEvaluatorReferenceSchema,
|
|
65911
66281
|
LocalEvaluatorCompositionItemSchema: () => LocalEvaluatorCompositionItemSchema,
|
|
65912
66282
|
LocalAgentResourceDirectorySchema: () => LocalAgentResourceDirectorySchema,
|
|
65913
66283
|
LlmJudgeConfigSchema: () => LlmJudgeConfigSchema,
|
|
66284
|
+
LegacyFileIdInputSchema: () => LegacyFileIdInputSchema,
|
|
65914
66285
|
LayoutElementTypeSchema: () => LayoutElementTypeSchema,
|
|
65915
66286
|
LayoutElementSchema: () => LayoutElementSchema,
|
|
65916
66287
|
LLM_JUDGE_PROMPT_MIN_LENGTH: () => LLM_JUDGE_PROMPT_MIN_LENGTH,
|
|
65917
66288
|
LEGACY_RUN_EXPAND_MIGRATION: () => LEGACY_RUN_EXPAND_MIGRATION,
|
|
66289
|
+
LEGACY_FILE_REF_COMPATIBILITY: () => LEGACY_FILE_REF_COMPATIBILITY,
|
|
65918
66290
|
JudgeModeSchema: () => JudgeModeSchema,
|
|
65919
66291
|
JsonSchemaSchema: () => JsonSchemaSchema,
|
|
66292
|
+
InlineFileRefSchema: () => InlineFileRefSchema,
|
|
66293
|
+
InlineFileIngressRefSchema: () => InlineFileIngressRefSchema,
|
|
66294
|
+
InlineFileIngressPayloadSchema: () => InlineFileIngressPayloadSchema,
|
|
65920
66295
|
IfStepSchema: () => IfStepSchema,
|
|
65921
66296
|
INPUT_VALIDATION_CODES: () => INPUT_VALIDATION_CODES,
|
|
65922
66297
|
INPUT_KINDS: () => INPUT_KINDS,
|
|
@@ -65926,7 +66301,10 @@ __export(exports_src, {
|
|
|
65926
66301
|
GPFS_FILE_SOURCE_NAME: () => GPFS_FILE_SOURCE_NAME,
|
|
65927
66302
|
GPFS_FILE_SOURCE_DESCRIPTOR: () => GPFS_FILE_SOURCE_DESCRIPTOR,
|
|
65928
66303
|
ForeachStepSchema: () => ForeachStepSchema,
|
|
65929
|
-
|
|
66304
|
+
FileReferenceSentinelSchema: () => FileReferenceSentinelSchema,
|
|
66305
|
+
FilePathDescriptorSchema: () => FilePathDescriptorSchema2,
|
|
66306
|
+
FileIngressRefSchema: () => FileIngressRefSchema,
|
|
66307
|
+
FileIdIngressRefSchema: () => FileIdIngressRefSchema,
|
|
65930
66308
|
FailStepSchema: () => FailStepSchema,
|
|
65931
66309
|
ExtractedTableSchema: () => ExtractedTableSchema,
|
|
65932
66310
|
ExtractOutputSchema: () => ExtractOutputSchema,
|
|
@@ -65983,6 +66361,7 @@ __export(exports_src, {
|
|
|
65983
66361
|
DocumentParserInputSchema: () => DocumentParserInputSchema,
|
|
65984
66362
|
DocumentParserConfigSchema: () => DocumentParserConfigSchema,
|
|
65985
66363
|
DocumentMetadataSchema: () => DocumentMetadataSchema,
|
|
66364
|
+
DbFileRefSchema: () => DbFileRefSchema,
|
|
65986
66365
|
DatasetNameSchema: () => DatasetNameSchema,
|
|
65987
66366
|
DatasetMetaSchema: () => DatasetMetaSchema,
|
|
65988
66367
|
DatasetImportRequestSchema: () => DatasetImportRequestSchema,
|
|
@@ -66041,6 +66420,9 @@ __export(exports_src, {
|
|
|
66041
66420
|
});
|
|
66042
66421
|
var init_src = __esm(() => {
|
|
66043
66422
|
init_core3();
|
|
66423
|
+
init_legacy_boundary();
|
|
66424
|
+
init_runtime_file_ref();
|
|
66425
|
+
init_scoped_file_ref();
|
|
66044
66426
|
init_processor();
|
|
66045
66427
|
init_parser();
|
|
66046
66428
|
init_otel();
|
|
@@ -187691,7 +188073,7 @@ import { fileURLToPath as fileURLToPath8 } from "url";
|
|
|
187691
188073
|
// package.json
|
|
187692
188074
|
var package_default = {
|
|
187693
188075
|
name: "@eigenpal/cli",
|
|
187694
|
-
version: "0.10.
|
|
188076
|
+
version: "0.10.6",
|
|
187695
188077
|
description: "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
|
|
187696
188078
|
keywords: [
|
|
187697
188079
|
"eigenpal",
|
|
@@ -194388,6 +194770,7 @@ async function writeExecutionArtifacts(client, exampleDir, payload) {
|
|
|
194388
194770
|
}
|
|
194389
194771
|
|
|
194390
194772
|
// src/lib/payload.ts
|
|
194773
|
+
init_src();
|
|
194391
194774
|
import { existsSync as existsSync14, readdirSync as readdirSync4, readFileSync as readFileSync13, statSync as statSync4 } from "fs";
|
|
194392
194775
|
import { join as join8 } from "path";
|
|
194393
194776
|
var DATASET_EXAMPLES_DIR = ["dataset", "examples"];
|
|
@@ -194423,16 +194806,17 @@ function readCanonicalInput(exampleDir, inputPath) {
|
|
|
194423
194806
|
for (const [key2, value] of Object.entries(raw)) {
|
|
194424
194807
|
const refs = topLevelFileRefs(value);
|
|
194425
194808
|
if (refs.length === 0) {
|
|
194426
|
-
scalars[key2] = value;
|
|
194809
|
+
scalars[key2] = materializeNestedFileRefs(exampleDir, inputPath, value);
|
|
194427
194810
|
continue;
|
|
194428
194811
|
}
|
|
194429
194812
|
for (const ref of refs) {
|
|
194430
|
-
const
|
|
194431
|
-
if (!
|
|
194813
|
+
const validation2 = validateScopedArtifactPath(ref, { allowedRoots: ["input"] });
|
|
194814
|
+
if (!validation2.ok) {
|
|
194432
194815
|
throw new Error(`${inputPath}: ${key2} must reference files under input/ without path traversal.`);
|
|
194433
194816
|
}
|
|
194434
|
-
const
|
|
194435
|
-
const
|
|
194817
|
+
const relative3 = validation2.value.segments.slice(1).join("/");
|
|
194818
|
+
const filePath = join8(exampleDir, validation2.value.path);
|
|
194819
|
+
const filename = validation2.value.segments.at(-1) ?? relative3;
|
|
194436
194820
|
files.push({
|
|
194437
194821
|
argument: key2,
|
|
194438
194822
|
filename,
|
|
@@ -194443,29 +194827,55 @@ function readCanonicalInput(exampleDir, inputPath) {
|
|
|
194443
194827
|
}
|
|
194444
194828
|
return { scalars, files };
|
|
194445
194829
|
}
|
|
194830
|
+
function materializeNestedFileRefs(exampleDir, inputPath, value) {
|
|
194831
|
+
if (isScopedFileRef2(value)) {
|
|
194832
|
+
const validation2 = validateScopedArtifactPath(value.$file, { allowedRoots: ["input"] });
|
|
194833
|
+
if (!validation2.ok) {
|
|
194834
|
+
throw new Error(`${inputPath}: $file refs must reference files under input/.`);
|
|
194835
|
+
}
|
|
194836
|
+
const filename = validation2.value.segments.at(-1) ?? "file";
|
|
194837
|
+
const filePath = join8(exampleDir, validation2.value.path);
|
|
194838
|
+
return {
|
|
194839
|
+
$inline: {
|
|
194840
|
+
filename,
|
|
194841
|
+
mimeType: guessMimeType(filename) ?? "application/octet-stream",
|
|
194842
|
+
base64: readFileSync13(filePath).toString("base64")
|
|
194843
|
+
}
|
|
194844
|
+
};
|
|
194845
|
+
}
|
|
194846
|
+
if (Array.isArray(value)) {
|
|
194847
|
+
return value.map((item) => materializeNestedFileRefs(exampleDir, inputPath, item));
|
|
194848
|
+
}
|
|
194849
|
+
if (value && typeof value === "object") {
|
|
194850
|
+
if (hasFileKey(value)) {
|
|
194851
|
+
throw new Error('file refs must be exact { "$file": "input/..." } objects.');
|
|
194852
|
+
}
|
|
194853
|
+
const out = {};
|
|
194854
|
+
for (const [key2, item] of Object.entries(value)) {
|
|
194855
|
+
out[key2] = materializeNestedFileRefs(exampleDir, inputPath, item);
|
|
194856
|
+
}
|
|
194857
|
+
return out;
|
|
194858
|
+
}
|
|
194859
|
+
return value;
|
|
194860
|
+
}
|
|
194446
194861
|
function topLevelFileRefs(value) {
|
|
194447
|
-
if (
|
|
194862
|
+
if (isScopedFileRef2(value))
|
|
194448
194863
|
return [value.$file];
|
|
194449
|
-
if (
|
|
194864
|
+
if (hasFileKey(value)) {
|
|
194865
|
+
throw new Error('file refs must be exact { "$file": "input/..." } objects.');
|
|
194866
|
+
}
|
|
194867
|
+
if (Array.isArray(value) && value.every(isScopedFileRef2))
|
|
194450
194868
|
return value.map((item) => item.$file);
|
|
194451
|
-
if (Array.isArray(value) && value.some(
|
|
194452
|
-
throw new Error('file arrays must contain only { "$file": "input/..." } entries.');
|
|
194869
|
+
if (Array.isArray(value) && value.some(hasFileKey)) {
|
|
194870
|
+
throw new Error('file arrays must contain only exact { "$file": "input/..." } entries.');
|
|
194453
194871
|
}
|
|
194454
194872
|
return [];
|
|
194455
194873
|
}
|
|
194456
|
-
function
|
|
194457
|
-
return value !== null && typeof value === "object" && !Array.isArray(value) && typeof value.$file === "string";
|
|
194874
|
+
function isScopedFileRef2(value) {
|
|
194875
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 1 && typeof value.$file === "string";
|
|
194458
194876
|
}
|
|
194459
|
-
function
|
|
194460
|
-
|
|
194461
|
-
return null;
|
|
194462
|
-
if (path15.startsWith("/") || path15.includes("\\") || path15.includes("\x00"))
|
|
194463
|
-
return null;
|
|
194464
|
-
const relative3 = path15.slice("input/".length);
|
|
194465
|
-
const parts = relative3.split("/");
|
|
194466
|
-
if (parts.some((part) => !part || part === "." || part === ".."))
|
|
194467
|
-
return null;
|
|
194468
|
-
return parts.join("/");
|
|
194877
|
+
function hasFileKey(value) {
|
|
194878
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && "$file" in value;
|
|
194469
194879
|
}
|
|
194470
194880
|
function readOverrides(exampleDir) {
|
|
194471
194881
|
const metaPath = join8(exampleDir, "meta.json");
|
|
@@ -196336,14 +196746,14 @@ function printIssues(label2, path15, issues) {
|
|
|
196336
196746
|
console.error("");
|
|
196337
196747
|
return false;
|
|
196338
196748
|
}
|
|
196339
|
-
function
|
|
196749
|
+
function isFileRef(value) {
|
|
196340
196750
|
return value !== null && typeof value === "object" && !Array.isArray(value) && typeof value.$file === "string";
|
|
196341
196751
|
}
|
|
196342
196752
|
function isExpectedErrorRef(value) {
|
|
196343
196753
|
return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 1 && Object.prototype.hasOwnProperty.call(value, "$error");
|
|
196344
196754
|
}
|
|
196345
196755
|
function collectDatasetFileRefs(value, jsonPath = "<root>") {
|
|
196346
|
-
if (
|
|
196756
|
+
if (isFileRef(value))
|
|
196347
196757
|
return [{ path: value.$file, jsonPath }];
|
|
196348
196758
|
if (Array.isArray(value)) {
|
|
196349
196759
|
return value.flatMap((item, index) => collectDatasetFileRefs(item, `${jsonPath}.${index}`));
|
|
@@ -196387,29 +196797,50 @@ function parseDatasetFileRef(path15, root2) {
|
|
|
196387
196797
|
function rootDir(opts) {
|
|
196388
196798
|
return resolve6(opts.dir ?? process.cwd());
|
|
196389
196799
|
}
|
|
196800
|
+
async function onlineInvokeIssues(yamlText, opts) {
|
|
196801
|
+
const config2 = resolveConfig(opts);
|
|
196802
|
+
requireApiKey(config2);
|
|
196803
|
+
const client = new ApiClient(config2);
|
|
196804
|
+
const res = await client.post("/api/workflows/validate", { yaml: yamlText });
|
|
196805
|
+
return res.issues ?? [];
|
|
196806
|
+
}
|
|
196390
196807
|
function registerAllValidateCommand(parent) {
|
|
196391
|
-
parent.command("validate [path]").description("Local-only validation. Without [path]: runs the templated three-way check (./workflow.yaml + ./evaluators.yaml + ./dataset/). With [path] pointing at a YAML file: validates that workflow.yaml. For per-noun targeting use `evaluators validate` or `dataset validate`.").option("--dir <path>", "Project root (defaults to cwd; resolves the three default paths from here)").action(
|
|
196808
|
+
const cmd = parent.command("validate [path]").description("Local-only validation. Without [path]: runs the templated three-way check (./workflow.yaml + ./evaluators.yaml + ./dataset/). With [path] pointing at a YAML file: validates that workflow.yaml. For per-noun targeting use `evaluators validate` or `dataset validate`.").option("--dir <path>", "Project root (defaults to cwd; resolves the three default paths from here)").option("--online", "Also validate cross-workflow action.invoke-workflow references against the server (needs auth). Catches target-not-found, input type mismatches, missing/unknown input keys, undeclared output, and invoke cycles that local validation cannot see.").addHelpText("after", `
|
|
196809
|
+
Note
|
|
196810
|
+
` + ` Local validation cannot resolve action.invoke-workflow targets (they live
|
|
196811
|
+
` + ` in the server DB), so invoke reference/type/cycle errors only surface at
|
|
196812
|
+
` + " push — or run `validate --online` to check them before pushing.\n");
|
|
196813
|
+
withBaseUrl(cmd).action(action(async (path15, opts) => {
|
|
196392
196814
|
if (path15) {
|
|
196393
196815
|
const target = resolve6(path15);
|
|
196394
196816
|
const wfResult2 = validateWorkflowYaml(target);
|
|
196395
196817
|
const wfOk2 = printIssues("workflow.yaml", target, wfResult2.issues);
|
|
196396
196818
|
if (wfOk2)
|
|
196397
196819
|
printSchemaQualityWarnings(target, wfResult2.warnings);
|
|
196398
|
-
|
|
196820
|
+
let onlineOk2 = true;
|
|
196821
|
+
if (wfOk2 && opts.online) {
|
|
196822
|
+
onlineOk2 = printIssues("invoke refs (server)", target, await onlineInvokeIssues(readFileSync15(target, "utf-8"), opts));
|
|
196823
|
+
}
|
|
196824
|
+
if (!wfOk2 || !onlineOk2)
|
|
196399
196825
|
process.exit(1);
|
|
196400
196826
|
return;
|
|
196401
196827
|
}
|
|
196402
196828
|
const root2 = rootDir(opts);
|
|
196403
|
-
const
|
|
196404
|
-
const
|
|
196829
|
+
const wfFile = join13(root2, "workflow.yaml");
|
|
196830
|
+
const wfResult = validateWorkflowYaml(wfFile);
|
|
196831
|
+
const wfPath = relPath(root2, wfFile);
|
|
196405
196832
|
const wfOk = printIssues("workflow.yaml", wfPath, wfResult.issues);
|
|
196406
196833
|
if (wfOk)
|
|
196407
196834
|
printSchemaQualityWarnings(wfPath, wfResult.warnings);
|
|
196408
196835
|
const evOk = printIssues("evaluators.yaml", relPath(root2, join13(root2, "evaluators.yaml")), validateEvaluatorsYaml(join13(root2, "evaluators.yaml")));
|
|
196409
196836
|
const dsOk = printIssues("dataset/", relPath(root2, join13(root2, "dataset")), validateDatasetFolder(join13(root2, "dataset")));
|
|
196410
|
-
|
|
196837
|
+
let onlineOk = true;
|
|
196838
|
+
if (wfOk && opts.online && existsSync17(wfFile)) {
|
|
196839
|
+
onlineOk = printIssues("invoke refs (server)", wfPath, await onlineInvokeIssues(readFileSync15(wfFile, "utf-8"), opts));
|
|
196840
|
+
}
|
|
196841
|
+
if (!wfOk || !evOk || !dsOk || !onlineOk)
|
|
196411
196842
|
process.exit(1);
|
|
196412
|
-
});
|
|
196843
|
+
}));
|
|
196413
196844
|
}
|
|
196414
196845
|
function registerEvaluatorsValidateCommand(parent) {
|
|
196415
196846
|
parent.command("validate [path]").description("Validate an evaluators YAML file against the EvalConfig schema. Defaults to ./evaluators.yaml.").action((path15) => {
|
|
@@ -196588,6 +197019,23 @@ function registerWorkflowCoreCommands(parent) {
|
|
|
196588
197019
|
}
|
|
196589
197020
|
await writeOrPrint(opts.out, result.yamlContent);
|
|
196590
197021
|
}));
|
|
197022
|
+
const schemaCmd = parent.command("schema <workflow-id>").description("Show the inferred output schema for a workflow (what it returns).").option("--format <format>", "json | typescript | python", "json").option("--out <path>", "Write to file instead of stdout").addHelpText("after", `
|
|
197023
|
+
Examples
|
|
197024
|
+
` + ` eigenpal workflow schema income-assessment
|
|
197025
|
+
` + ` eigenpal workflow schema wf_123 --format typescript
|
|
197026
|
+
` + ` eigenpal workflow schema wf_123 --format python --out Output.py
|
|
197027
|
+
`);
|
|
197028
|
+
withBaseUrl(schemaCmd).action(action(async (workflow2, opts) => {
|
|
197029
|
+
const { client, workflowId } = await buildClientForWorkflow(workflow2, opts);
|
|
197030
|
+
const format3 = opts.format ?? "json";
|
|
197031
|
+
const result = await client.get(`/api/workflows/${workflowId}/output-schema`, { format: format3 });
|
|
197032
|
+
if (format3 === "json") {
|
|
197033
|
+
await writeOrPrint(opts.out, JSON.stringify(result, null, 2));
|
|
197034
|
+
} else {
|
|
197035
|
+
const text = result instanceof Response ? await result.text() : String(result);
|
|
197036
|
+
await writeOrPrint(opts.out, text);
|
|
197037
|
+
}
|
|
197038
|
+
}));
|
|
196591
197039
|
const pushCmd = parent.command("push").description(descriptionFor("workflow_set_definition")).option("--file <yaml>", "Path to YAML file").option("--workflow-id <id>", "Update existing workflow (default: create new)").option("--bump <level>", "Auto-bump from the server's current version: patch | minor | major. Mutually exclusive with `--version` and with a top-level `version:` in the YAML.").option("--set-version <semver>", "Push at this exact semver (e.g. 1.4.0). Mutually exclusive with `--bump` and with a top-level `version:` in the YAML. (Named `--set-version` to avoid the global `-v, --version` flag.)").addHelpText("after", `
|
|
196592
197040
|
Examples:
|
|
196593
197041
|
$ eigenpal workflow push --file workflow.yaml
|
|
@@ -196967,8 +197415,9 @@ Examples:
|
|
|
196967
197415
|
$ cat expected.json | eigenpal workflow dataset example create wf_abc123 --name piped --input-json '{}' --expected-file -
|
|
196968
197416
|
|
|
196969
197417
|
\`--input-json\` and \`--input-file\` (same for \`--expected-*\`) are mutually
|
|
196970
|
-
exclusive.
|
|
196971
|
-
|
|
197418
|
+
exclusive. To attach files without a dataset folder, pass ingress refs in JSON:
|
|
197419
|
+
\`{"document":{"$fileId":"file_..."}}\` or
|
|
197420
|
+
\`{"document":{"$inline":{"filename":"doc.pdf","mimeType":"application/pdf","base64":"..."}}}\`.
|
|
196972
197421
|
`);
|
|
196973
197422
|
addJsonFlag(withBaseUrl(createCmd)).action(action(async (workflow2, opts) => {
|
|
196974
197423
|
const triggerInput = await readJsonInput(opts.inputJson, opts.inputFile, "input");
|
|
@@ -17,6 +17,7 @@ Manage workflows: push, pull, and evaluate.
|
|
|
17
17
|
- [Details](#details)
|
|
18
18
|
- [`eigenpal workflow list|ls [options]`](#eigenpal-workflow-listls-options)
|
|
19
19
|
- [`eigenpal workflow pull [options] <workflow-id>`](#eigenpal-workflow-pull-options-workflow-id)
|
|
20
|
+
- [`eigenpal workflow schema [options] <workflow-id>`](#eigenpal-workflow-schema-options-workflow-id)
|
|
20
21
|
- [`eigenpal workflow push [options]`](#eigenpal-workflow-push-options)
|
|
21
22
|
- [`eigenpal workflow move [options] <workflow-id>`](#eigenpal-workflow-move-options-workflow-id)
|
|
22
23
|
- [`eigenpal workflow validate [options] [path]`](#eigenpal-workflow-validate-options-path)
|
|
@@ -53,6 +54,7 @@ Manage workflows: push, pull, and evaluate.
|
|
|
53
54
|
workflow
|
|
54
55
|
├── list|ls
|
|
55
56
|
├── pull <workflow-id>
|
|
57
|
+
├── schema <workflow-id>
|
|
56
58
|
├── push
|
|
57
59
|
├── move <workflow-id>
|
|
58
60
|
├── evaluators
|
|
@@ -100,6 +102,7 @@ workflow
|
|
|
100
102
|
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
101
103
|
| `eigenpal workflow list\|ls [options]` | List workflows the caller can read. |
|
|
102
104
|
| `eigenpal workflow pull [options] <workflow-id>` | Download the YAML definition of the workflow at its current version. |
|
|
105
|
+
| `eigenpal workflow schema [options] <workflow-id>` | Show the inferred output schema for a workflow (what it returns). |
|
|
103
106
|
| `eigenpal workflow push [options]` | Create or update a workflow from a YAML file. |
|
|
104
107
|
| `eigenpal workflow move [options] <workflow-id>` | Move a workflow to a folder path, creating folders as needed |
|
|
105
108
|
| `eigenpal workflow validate [options] [path]` | Local-only validation. Without [path]: runs the templated three-way check (./workflow.yaml + ./evaluators.yaml + ./dataset/). With [path] pointing at a YAML file: validates that workflow.yaml. For per-noun targeting use `evaluators validate` or `dataset validate`. |
|
|
@@ -198,6 +201,24 @@ Download the YAML definition of the workflow at its current version.
|
|
|
198
201
|
| `--out <path>` | no | | Write YAML to file instead of stdout |
|
|
199
202
|
| `--base-url <url>` | no | | Server base URL |
|
|
200
203
|
|
|
204
|
+
### `eigenpal workflow schema [options] <workflow-id>`
|
|
205
|
+
|
|
206
|
+
Show the inferred output schema for a workflow (what it returns).
|
|
207
|
+
|
|
208
|
+
### Arguments
|
|
209
|
+
|
|
210
|
+
| Name | Required | Variadic | Description |
|
|
211
|
+
| ------------- | -------- | -------- | ----------- |
|
|
212
|
+
| `workflow-id` | yes | no | |
|
|
213
|
+
|
|
214
|
+
### Options
|
|
215
|
+
|
|
216
|
+
| Flag | Required | Default | Description |
|
|
217
|
+
| ------------------- | -------- | -------- | ------------------------------- |
|
|
218
|
+
| `--format <format>` | no | `"json"` | json \| typescript \| python |
|
|
219
|
+
| `--out <path>` | no | | Write to file instead of stdout |
|
|
220
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
221
|
+
|
|
201
222
|
### `eigenpal workflow push [options]`
|
|
202
223
|
|
|
203
224
|
Create or update a workflow from a YAML file.
|
|
@@ -243,9 +264,11 @@ Local-only validation. Without [path]: runs the templated three-way check (./wor
|
|
|
243
264
|
|
|
244
265
|
### Options
|
|
245
266
|
|
|
246
|
-
| Flag
|
|
247
|
-
|
|
|
248
|
-
| `--dir <path>`
|
|
267
|
+
| Flag | Required | Default | Description |
|
|
268
|
+
| ------------------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
269
|
+
| `--dir <path>` | no | | Project root (defaults to cwd; resolves the three default paths from here) |
|
|
270
|
+
| `--online` | no | | Also validate cross-workflow action.invoke-workflow references against the server (needs auth). Catches target-not-found, input type mismatches, missing/unknown input keys, undeclared output, and invoke cycles that local validation cannot see. |
|
|
271
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
249
272
|
|
|
250
273
|
### `eigenpal workflow clear-local [options] [examples...]`
|
|
251
274
|
|
|
@@ -574,7 +574,7 @@ Convert XLSX spreadsheet to JSON array of row objects for use in scripts or down
|
|
|
574
574
|
|
|
575
575
|
| Field | Type | Required | Default | Description |
|
|
576
576
|
| --- | --- | --- | --- | --- |
|
|
577
|
-
| `input` | string | yes | | File input - template expression e.g. {{input.document}} resolving to
|
|
577
|
+
| `input` | string | yes | | File input - template expression e.g. {{input.document}} resolving to a scoped $file artifact at runtime |
|
|
578
578
|
| `sheet` | integer \| string | no | | Sheet to read: 0-based index or sheet name. Omit for first sheet. |
|
|
579
579
|
| `outputCsv` | boolean | no | `false` | If true, also write CSV to storage and include fileId in output |
|
|
580
580
|
| `outputFilename` | string | no | | Output CSV filename when outputCsv is true - supports LiquidJS e.g. {{filename}}.csv |
|
|
@@ -679,14 +679,14 @@ Execute another workflow and return its output
|
|
|
679
679
|
| Field | Type | Required | Default | Description |
|
|
680
680
|
| --- | --- | --- | --- | --- |
|
|
681
681
|
| `workflowId` | string | yes | | ID of workflow to invoke |
|
|
682
|
-
| `input` | record<string, unknown> | no | | Input
|
|
683
|
-
| `wait` | boolean | no | |
|
|
684
|
-
| `timeout` | number | no | | Max wait time in ms when
|
|
685
|
-
| `pollInterval` | number | no | | How often to poll status in ms when
|
|
682
|
+
| `input` | record<string, unknown> | no | | Input record keyed by the invoked workflow's declared inputs |
|
|
683
|
+
| `wait` | boolean | no | | Wait for the invoked workflow to complete and return its output (default: true). Set false for fire-and-forget. |
|
|
684
|
+
| `timeout` | number | no | | Max wait time in ms when waiting (default: 300000) |
|
|
685
|
+
| `pollInterval` | number | no | | How often to poll status in ms when waiting (default: 1000) |
|
|
686
686
|
|
|
687
687
|
**Output:** `record<string, unknown>`
|
|
688
688
|
|
|
689
|
-
>
|
|
689
|
+
> When wait is true, the invoked workflow's declared output fields are flattened to the top level alongside a `files` array — reference them as {{ steps.<invoke>.output.<field> }} (there is no `.data` or `.result` wrapper). When wait is false, execution metadata. Call get_workflow_output_schema to see the exact resolved fields.
|
|
690
690
|
|
|
691
691
|
#### `action.website-reader` — Website Reader
|
|
692
692
|
|
|
@@ -79,10 +79,14 @@ The materialized shape on `triggerInput` is driven by the YAML, not by
|
|
|
79
79
|
how many files the dataset uploaded. Get this wrong and the worker
|
|
80
80
|
sees the opposite shape:
|
|
81
81
|
|
|
82
|
-
| YAML | `triggerInput.<name>` | Template |
|
|
83
|
-
| ------------------------------------------ |
|
|
84
|
-
| `type: file` | `{
|
|
85
|
-
| `type: array`, `items: { type: file }` | `[{
|
|
82
|
+
| YAML | durable `triggerInput.<name>` | Template |
|
|
83
|
+
| ------------------------------------------ | ------------------------------ | --------------------------------------- |
|
|
84
|
+
| `type: file` | `{ "$file": "input/..." }` | `{{ input.<name> }}` |
|
|
85
|
+
| `type: array`, `items: { type: file }` | `[{ "$file": "input/..." }]` | `{{ input.<name>[0] }}` (or `forEach:`) |
|
|
86
|
+
|
|
87
|
+
API/SDK ingress can use `{ "$fileId": "file_..." }`, inline bytes via
|
|
88
|
+
`{ "$inline": { filename, mimeType, base64 } }`, or multipart file parts.
|
|
89
|
+
Eigenpal snapshots those into run-scoped artifacts before execution.
|
|
86
90
|
|
|
87
91
|
If you see `Invalid input ... expected object, received array` from a
|
|
88
92
|
step that takes a single file, the workflow input is `type: file` but
|
|
@@ -474,7 +478,7 @@ _Generated from `WorkflowDefinitionSchema` in `@eigenpal/types/src/workflow/work
|
|
|
474
478
|
| `triggerMethods` | array<object> | no | `[{"type":"manual"}]` | |
|
|
475
479
|
| `inputs` | array<object> | no | | |
|
|
476
480
|
| `steps` | array<unknown> | yes | | |
|
|
477
|
-
| `output` | record<string, string> | no | | |
|
|
481
|
+
| `output` | record<string, string> \| string | no | | |
|
|
478
482
|
| `settings` | object | no | | |
|
|
479
483
|
| `defaultModel` | string | no | | |
|
|
480
484
|
|