@amaster.ai/runtime-cli 1.1.14-beta.0 → 1.1.14-beta.2
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 +16 -1
- package/dist/cli.cjs +293 -5
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +293 -5
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +293 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +293 -5
- package/dist/index.js.map +1 -1
- package/dist/skill/SKILL.md +11 -3
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2269,6 +2269,8 @@ async function getUserRoles(client, options) {
|
|
|
2269
2269
|
exitWithCommandError3(spinner, "Failed to fetch user roles", error);
|
|
2270
2270
|
}
|
|
2271
2271
|
}
|
|
2272
|
+
var WORKFLOW_LIST_PATH = "/api/proxy/builtin/platform/workflow/openapi/apps";
|
|
2273
|
+
var WORKFLOW_GET_PATH = (workflowId) => `/api/proxy/builtin/platform/workflow/openapi/apps/${encodeURIComponent(workflowId)}/dsl`;
|
|
2272
2274
|
function resolveInputSource4(input) {
|
|
2273
2275
|
if (!input.startsWith("@")) {
|
|
2274
2276
|
return input;
|
|
@@ -2294,6 +2296,151 @@ function parseJsonInput3(input, label) {
|
|
|
2294
2296
|
function isPlainObject4(value) {
|
|
2295
2297
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2296
2298
|
}
|
|
2299
|
+
function parseWorkflowTracing(value) {
|
|
2300
|
+
if (!value) {
|
|
2301
|
+
return null;
|
|
2302
|
+
}
|
|
2303
|
+
if (isPlainObject4(value)) {
|
|
2304
|
+
return value;
|
|
2305
|
+
}
|
|
2306
|
+
if (typeof value !== "string") {
|
|
2307
|
+
return null;
|
|
2308
|
+
}
|
|
2309
|
+
try {
|
|
2310
|
+
const parsed = JSON.parse(value);
|
|
2311
|
+
return isPlainObject4(parsed) ? parsed : null;
|
|
2312
|
+
} catch {
|
|
2313
|
+
return null;
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
function getRunnableName(summary) {
|
|
2317
|
+
const tracing = parseWorkflowTracing(summary.tracing);
|
|
2318
|
+
const baseName = tracing?.base_name;
|
|
2319
|
+
if (typeof baseName === "string" && baseName.trim()) {
|
|
2320
|
+
return baseName.trim();
|
|
2321
|
+
}
|
|
2322
|
+
return null;
|
|
2323
|
+
}
|
|
2324
|
+
function normalizeWorkflowSummary(summary) {
|
|
2325
|
+
return {
|
|
2326
|
+
...summary,
|
|
2327
|
+
id: typeof summary.id === "string" ? summary.id : "",
|
|
2328
|
+
name: typeof summary.name === "string" ? summary.name : "",
|
|
2329
|
+
runnable_name: getRunnableName(summary),
|
|
2330
|
+
description: typeof summary.description === "string" ? summary.description : null,
|
|
2331
|
+
mode: typeof summary.mode === "string" ? summary.mode : null
|
|
2332
|
+
};
|
|
2333
|
+
}
|
|
2334
|
+
function extractWorkflowInputVariables(dsl) {
|
|
2335
|
+
if (!isPlainObject4(dsl)) {
|
|
2336
|
+
return [];
|
|
2337
|
+
}
|
|
2338
|
+
const candidateNodeSets = [];
|
|
2339
|
+
if (Array.isArray(dsl.nodes)) {
|
|
2340
|
+
candidateNodeSets.push(dsl.nodes);
|
|
2341
|
+
}
|
|
2342
|
+
if (isPlainObject4(dsl.graph) && Array.isArray(dsl.graph.nodes)) {
|
|
2343
|
+
candidateNodeSets.push(dsl.graph.nodes);
|
|
2344
|
+
}
|
|
2345
|
+
const variables = [];
|
|
2346
|
+
for (const nodeSet of candidateNodeSets) {
|
|
2347
|
+
for (const node of nodeSet) {
|
|
2348
|
+
if (!isPlainObject4(node) || !isPlainObject4(node.data)) {
|
|
2349
|
+
continue;
|
|
2350
|
+
}
|
|
2351
|
+
const nodeData = node.data;
|
|
2352
|
+
if (nodeData.type !== "start" || !Array.isArray(nodeData.variables)) {
|
|
2353
|
+
continue;
|
|
2354
|
+
}
|
|
2355
|
+
for (const variable of nodeData.variables) {
|
|
2356
|
+
if (!isPlainObject4(variable) || typeof variable.variable !== "string") {
|
|
2357
|
+
continue;
|
|
2358
|
+
}
|
|
2359
|
+
variables.push({
|
|
2360
|
+
...variable,
|
|
2361
|
+
variable: variable.variable,
|
|
2362
|
+
label: typeof variable.label === "string" ? variable.label : void 0,
|
|
2363
|
+
required: typeof variable.required === "boolean" ? variable.required : void 0,
|
|
2364
|
+
type: typeof variable.type === "string" ? variable.type : void 0
|
|
2365
|
+
});
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
return variables;
|
|
2370
|
+
}
|
|
2371
|
+
function normalizeWorkflowDefinition(definition) {
|
|
2372
|
+
return {
|
|
2373
|
+
...definition,
|
|
2374
|
+
workflow_id: typeof definition.workflow_id === "string" ? definition.workflow_id : "",
|
|
2375
|
+
app_id: typeof definition.app_id === "string" ? definition.app_id : "",
|
|
2376
|
+
version: typeof definition.version === "string" ? definition.version : void 0,
|
|
2377
|
+
name: typeof definition.name === "string" ? definition.name : "",
|
|
2378
|
+
dsl: isPlainObject4(definition.dsl) ? definition.dsl : void 0,
|
|
2379
|
+
context: typeof definition.context === "string" ? definition.context : void 0,
|
|
2380
|
+
input_variables: extractWorkflowInputVariables(definition.dsl)
|
|
2381
|
+
};
|
|
2382
|
+
}
|
|
2383
|
+
function invalidResponse(status, message) {
|
|
2384
|
+
return {
|
|
2385
|
+
data: null,
|
|
2386
|
+
error: {
|
|
2387
|
+
status,
|
|
2388
|
+
message
|
|
2389
|
+
},
|
|
2390
|
+
status
|
|
2391
|
+
};
|
|
2392
|
+
}
|
|
2393
|
+
function createWorkflowService(client) {
|
|
2394
|
+
return {
|
|
2395
|
+
async list(params = {}) {
|
|
2396
|
+
const response = await client.http.request({
|
|
2397
|
+
url: WORKFLOW_LIST_PATH,
|
|
2398
|
+
method: "GET",
|
|
2399
|
+
params: {
|
|
2400
|
+
page: params.page ?? 1,
|
|
2401
|
+
limit: params.limit ?? 20,
|
|
2402
|
+
mode: params.mode ?? "workflow"
|
|
2403
|
+
}
|
|
2404
|
+
});
|
|
2405
|
+
if (!response.data || !Array.isArray(response.data.data)) {
|
|
2406
|
+
return invalidResponse(
|
|
2407
|
+
response.status,
|
|
2408
|
+
response.error?.message || "Invalid workflow list response structure"
|
|
2409
|
+
);
|
|
2410
|
+
}
|
|
2411
|
+
return {
|
|
2412
|
+
...response,
|
|
2413
|
+
data: {
|
|
2414
|
+
...response.data,
|
|
2415
|
+
page: typeof response.data.page === "number" ? response.data.page : params.page ?? 1,
|
|
2416
|
+
limit: typeof response.data.limit === "number" ? response.data.limit : params.limit ?? 20,
|
|
2417
|
+
total: typeof response.data.total === "number" ? response.data.total : response.data.data.length,
|
|
2418
|
+
has_more: typeof response.data.has_more === "boolean" ? response.data.has_more : false,
|
|
2419
|
+
data: response.data.data.map(normalizeWorkflowSummary)
|
|
2420
|
+
}
|
|
2421
|
+
};
|
|
2422
|
+
},
|
|
2423
|
+
async get(workflowId) {
|
|
2424
|
+
if (!workflowId) {
|
|
2425
|
+
return invalidResponse(400, "workflowId is required");
|
|
2426
|
+
}
|
|
2427
|
+
const response = await client.http.request({
|
|
2428
|
+
url: WORKFLOW_GET_PATH(workflowId),
|
|
2429
|
+
method: "GET"
|
|
2430
|
+
});
|
|
2431
|
+
if (!response.data || !isPlainObject4(response.data)) {
|
|
2432
|
+
return invalidResponse(
|
|
2433
|
+
response.status,
|
|
2434
|
+
response.error?.message || "Invalid workflow definition response structure"
|
|
2435
|
+
);
|
|
2436
|
+
}
|
|
2437
|
+
return {
|
|
2438
|
+
...response,
|
|
2439
|
+
data: normalizeWorkflowDefinition(response.data)
|
|
2440
|
+
};
|
|
2441
|
+
}
|
|
2442
|
+
};
|
|
2443
|
+
}
|
|
2297
2444
|
function loadOptionalJsonObjectInput3(input, label) {
|
|
2298
2445
|
if (!input) {
|
|
2299
2446
|
return {};
|
|
@@ -2368,6 +2515,128 @@ async function runWorkflow(client, options) {
|
|
|
2368
2515
|
exitWithCommandError4(spinner, "Failed to run workflow", error);
|
|
2369
2516
|
}
|
|
2370
2517
|
}
|
|
2518
|
+
async function listWorkflows(client, options = {}) {
|
|
2519
|
+
const spinner = createSpinner("Fetching workflows...", options.format);
|
|
2520
|
+
try {
|
|
2521
|
+
const workflowService = createWorkflowService(client);
|
|
2522
|
+
const result = await workflowService.list({
|
|
2523
|
+
page: options.page,
|
|
2524
|
+
limit: options.limit,
|
|
2525
|
+
mode: options.mode
|
|
2526
|
+
});
|
|
2527
|
+
if (result.error) {
|
|
2528
|
+
spinner.fail("Failed to fetch workflows");
|
|
2529
|
+
console.error(chalk4__default.default.red(result.error.message));
|
|
2530
|
+
process.exit(1);
|
|
2531
|
+
}
|
|
2532
|
+
const payload = result.data;
|
|
2533
|
+
const workflows = payload?.data || [];
|
|
2534
|
+
spinner.succeed(`Found ${workflows.length} workflow${workflows.length === 1 ? "" : "s"}`);
|
|
2535
|
+
renderOutput(payload, {
|
|
2536
|
+
format: options.format,
|
|
2537
|
+
tableRows: workflows.map((workflow) => ({
|
|
2538
|
+
id: workflow.id,
|
|
2539
|
+
runnableName: workflow.runnable_name,
|
|
2540
|
+
platformName: workflow.name,
|
|
2541
|
+
mode: workflow.mode,
|
|
2542
|
+
description: workflow.description
|
|
2543
|
+
})),
|
|
2544
|
+
csvRows: workflows.map((workflow) => ({
|
|
2545
|
+
id: workflow.id,
|
|
2546
|
+
runnableName: workflow.runnable_name,
|
|
2547
|
+
platformName: workflow.name,
|
|
2548
|
+
mode: workflow.mode,
|
|
2549
|
+
description: workflow.description
|
|
2550
|
+
})),
|
|
2551
|
+
ndjsonItems: workflows,
|
|
2552
|
+
pretty: () => {
|
|
2553
|
+
console.log(chalk4__default.default.blue("\nWorkflows\n"));
|
|
2554
|
+
if (workflows.length === 0) {
|
|
2555
|
+
console.log(chalk4__default.default.gray("No workflows found."));
|
|
2556
|
+
return;
|
|
2557
|
+
}
|
|
2558
|
+
for (const workflow of workflows) {
|
|
2559
|
+
console.log(`${chalk4__default.default.green("\u2022")} ${chalk4__default.default.bold(workflow.runnable_name || workflow.name)}`);
|
|
2560
|
+
console.log(` ${chalk4__default.default.gray("ID:")} ${workflow.id}`);
|
|
2561
|
+
console.log(` ${chalk4__default.default.gray("Platform Name:")} ${workflow.name}`);
|
|
2562
|
+
console.log(` ${chalk4__default.default.gray("Mode:")} ${workflow.mode || "workflow"}`);
|
|
2563
|
+
if (workflow.description) {
|
|
2564
|
+
console.log(` ${chalk4__default.default.gray("Description:")} ${workflow.description}`);
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
});
|
|
2569
|
+
} catch (error) {
|
|
2570
|
+
exitWithCommandError4(spinner, "Failed to fetch workflows", error);
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
async function getWorkflow(client, options) {
|
|
2574
|
+
const spinner = createSpinner(`Fetching workflow: ${options.id}...`, options.format);
|
|
2575
|
+
try {
|
|
2576
|
+
const workflowService = createWorkflowService(client);
|
|
2577
|
+
const result = await workflowService.get(options.id);
|
|
2578
|
+
if (result.error) {
|
|
2579
|
+
spinner.fail("Failed to fetch workflow");
|
|
2580
|
+
console.error(chalk4__default.default.red(result.error.message));
|
|
2581
|
+
process.exit(1);
|
|
2582
|
+
}
|
|
2583
|
+
const workflow = result.data;
|
|
2584
|
+
const inputVariables = workflow?.input_variables || [];
|
|
2585
|
+
spinner.succeed("Workflow loaded");
|
|
2586
|
+
renderOutput(workflow, {
|
|
2587
|
+
format: options.format,
|
|
2588
|
+
tableRows: workflow ? [
|
|
2589
|
+
{
|
|
2590
|
+
appId: workflow.app_id,
|
|
2591
|
+
workflowId: workflow.workflow_id,
|
|
2592
|
+
runnableName: workflow.name,
|
|
2593
|
+
version: workflow.version || null,
|
|
2594
|
+
inputVariables: inputVariables.map((item) => item.variable).join(", ")
|
|
2595
|
+
}
|
|
2596
|
+
] : [],
|
|
2597
|
+
csvRows: workflow ? [
|
|
2598
|
+
{
|
|
2599
|
+
appId: workflow.app_id,
|
|
2600
|
+
workflowId: workflow.workflow_id,
|
|
2601
|
+
runnableName: workflow.name,
|
|
2602
|
+
version: workflow.version || null,
|
|
2603
|
+
inputVariables: inputVariables.map((item) => item.variable).join(", ")
|
|
2604
|
+
}
|
|
2605
|
+
] : [],
|
|
2606
|
+
ndjsonItems: workflow ? [workflow] : [],
|
|
2607
|
+
pretty: () => {
|
|
2608
|
+
if (!workflow) {
|
|
2609
|
+
console.log(chalk4__default.default.gray("No workflow found."));
|
|
2610
|
+
return;
|
|
2611
|
+
}
|
|
2612
|
+
console.log(chalk4__default.default.blue(`
|
|
2613
|
+
Workflow: ${workflow.name}
|
|
2614
|
+
`));
|
|
2615
|
+
console.log(`${chalk4__default.default.gray("App ID:")} ${workflow.app_id}`);
|
|
2616
|
+
console.log(`${chalk4__default.default.gray("Workflow ID:")} ${workflow.workflow_id}`);
|
|
2617
|
+
if (workflow.version) {
|
|
2618
|
+
console.log(`${chalk4__default.default.gray("Version:")} ${workflow.version}`);
|
|
2619
|
+
}
|
|
2620
|
+
console.log(`
|
|
2621
|
+
${chalk4__default.default.gray("Input Variables:")}`);
|
|
2622
|
+
if (inputVariables.length === 0) {
|
|
2623
|
+
console.log(chalk4__default.default.gray(" none"));
|
|
2624
|
+
} else {
|
|
2625
|
+
for (const variable of inputVariables) {
|
|
2626
|
+
const label = variable.label ? ` ${chalk4__default.default.gray(`(${variable.label})`)}` : "";
|
|
2627
|
+
const type = variable.type ? ` ${chalk4__default.default.gray(`[${variable.type}]`)}` : "";
|
|
2628
|
+
const required = variable.required ? chalk4__default.default.yellow(" required") : chalk4__default.default.gray(" optional");
|
|
2629
|
+
console.log(` - ${chalk4__default.default.bold(variable.variable)}${label}${type}${required}`);
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
console.log(`
|
|
2633
|
+
${chalk4__default.default.gray("Run With:")} amaster workflow run ${workflow.name} --app <app-code> --input '{...}'`);
|
|
2634
|
+
}
|
|
2635
|
+
});
|
|
2636
|
+
} catch (error) {
|
|
2637
|
+
exitWithCommandError4(spinner, "Failed to fetch workflow", error);
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2371
2640
|
function exitWithCommandError5(spinner, failureMessage, error) {
|
|
2372
2641
|
spinner.fail(failureMessage);
|
|
2373
2642
|
const details = error instanceof Error ? error.message : String(error);
|
|
@@ -2776,11 +3045,12 @@ function createAmasterClient(appCode) {
|
|
|
2776
3045
|
}
|
|
2777
3046
|
const client$1 = client.createClient({
|
|
2778
3047
|
baseURL: appConfig.baseURL,
|
|
2779
|
-
|
|
2780
|
-
|
|
3048
|
+
headers: {
|
|
3049
|
+
"x-app-code": appCode,
|
|
3050
|
+
...token ? {
|
|
2781
3051
|
Authorization: `Bearer ${token}`
|
|
2782
|
-
}
|
|
2783
|
-
}
|
|
3052
|
+
} : {}
|
|
3053
|
+
},
|
|
2784
3054
|
onUnauthorized: () => {
|
|
2785
3055
|
if (token) {
|
|
2786
3056
|
console.error(chalk4__default.default.red("\n\u274C Session expired. Please login again."));
|
|
@@ -3333,7 +3603,25 @@ bpmCmd.command("start-form-deployed <key>").description("Get deployed start form
|
|
|
3333
3603
|
format: options.format
|
|
3334
3604
|
});
|
|
3335
3605
|
});
|
|
3336
|
-
var workflowCmd = program.command("workflow").description("
|
|
3606
|
+
var workflowCmd = program.command("workflow").description("Inspect and run workflows");
|
|
3607
|
+
workflowCmd.command("list").description("List runnable workflows").option("--app <app-code>", "App code (uses default if not specified)").option("--page <n>", "Page number").option("--limit <n>", "Page size").addOption(
|
|
3608
|
+
new commander.Option("--mode <mode>", "Workflow app mode").choices(["workflow", "chat", "completion", "agent-chat"])
|
|
3609
|
+
).addOption(createFormatOption()).action(async (options) => {
|
|
3610
|
+
const appCode = resolveAppCode(options.app);
|
|
3611
|
+
await listWorkflows(createAmasterClient(appCode), {
|
|
3612
|
+
page: options.page ? parseInt(options.page, 10) : void 0,
|
|
3613
|
+
limit: options.limit ? parseInt(options.limit, 10) : void 0,
|
|
3614
|
+
mode: options.mode,
|
|
3615
|
+
format: options.format
|
|
3616
|
+
});
|
|
3617
|
+
});
|
|
3618
|
+
workflowCmd.command("get <id>").alias("inspect").description("Get workflow details and input variables by workflow app ID").option("--app <app-code>", "App code (uses default if not specified)").addOption(createFormatOption()).action(async (id, options) => {
|
|
3619
|
+
const appCode = resolveAppCode(options.app);
|
|
3620
|
+
await getWorkflow(createAmasterClient(appCode), {
|
|
3621
|
+
id,
|
|
3622
|
+
format: options.format
|
|
3623
|
+
});
|
|
3624
|
+
});
|
|
3337
3625
|
workflowCmd.command("run <name>").alias("execute").description("Run a workflow").option("--app <app-code>", "App code (uses default if not specified)").option("-i, --input <json>", "Workflow inputs object as JSON or @file").option("-r, --request <json>", "Full WorkflowRunRequest as JSON or @file").addOption(
|
|
3338
3626
|
new commander.Option("--response-mode <mode>", "Workflow response mode").choices(["blocking", "streaming"])
|
|
3339
3627
|
).option("--user <user>", "Workflow user identifier").option("--files <json>", "Workflow files array as JSON or @file").option("--trace-id <traceId>", "Workflow trace ID").addOption(createFormatOption()).action(async (name, options) => {
|