@ai-setting/roy-agent-cli 1.6.1 → 1.6.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.
@@ -7407,7 +7407,7 @@ var require_dist = __commonJS((exports) => {
7407
7407
  var require_package = __commonJS((exports, module) => {
7408
7408
  module.exports = {
7409
7409
  name: "@ai-setting/roy-agent-cli",
7410
- version: "1.6.1",
7410
+ version: "1.6.2",
7411
7411
  type: "module",
7412
7412
  description: "CLI for roy-agent - Non-interactive command execution",
7413
7413
  main: "./dist/index.js",
@@ -9762,6 +9762,68 @@ function joinResolvedSystemPrompts(prompts) {
9762
9762
  // src/commands/shared/ask-user-handler.ts
9763
9763
  import * as readline from "readline";
9764
9764
  import chalk3 from "chalk";
9765
+
9766
+ // src/commands/shared/ask-user-timeout.ts
9767
+ var ASK_USER_TIMEOUT_MS = 120000;
9768
+ var ASK_USER_TIMEOUT_SENTINEL_PREFIX = "__ASK_USER_TIMEOUT__:";
9769
+ function isAskUserTimeoutSentinel(value) {
9770
+ return typeof value === "string" && value.length > ASK_USER_TIMEOUT_SENTINEL_PREFIX.length && value.startsWith(ASK_USER_TIMEOUT_SENTINEL_PREFIX);
9771
+ }
9772
+ function createAskUserTimeoutSentinel(errorInfo, timeoutMs, extra) {
9773
+ const payload = {
9774
+ query: errorInfo?.query ?? extra?.question ?? "",
9775
+ sessionId: errorInfo?.sessionId,
9776
+ agentSessionId: errorInfo?.agentSessionId,
9777
+ nodeId: errorInfo?.nodeId,
9778
+ nodeType: errorInfo?.nodeType,
9779
+ timestamp: Date.now(),
9780
+ timeoutMs,
9781
+ source: extra?.source ?? "repl"
9782
+ };
9783
+ return ASK_USER_TIMEOUT_SENTINEL_PREFIX + JSON.stringify(payload);
9784
+ }
9785
+ function withAskUserTimeoutRace(opts) {
9786
+ const { rl, timeoutMs, onLine, onTimeout } = opts;
9787
+ let resolved = false;
9788
+ let timer = null;
9789
+ const handleLine = (input) => {
9790
+ if (resolved)
9791
+ return;
9792
+ resolved = true;
9793
+ rl.removeListener("line", handleLine);
9794
+ if (timer) {
9795
+ clearTimeout(timer);
9796
+ timer = null;
9797
+ }
9798
+ onLine(input);
9799
+ };
9800
+ rl.on("line", handleLine);
9801
+ timer = setTimeout(() => {
9802
+ if (resolved)
9803
+ return;
9804
+ resolved = true;
9805
+ rl.removeListener("line", handleLine);
9806
+ onTimeout();
9807
+ timer = null;
9808
+ }, timeoutMs);
9809
+ if (timer && typeof timer.unref === "function") {
9810
+ timer.unref();
9811
+ }
9812
+ return {
9813
+ cancel() {
9814
+ if (resolved)
9815
+ return;
9816
+ resolved = true;
9817
+ rl.removeListener("line", handleLine);
9818
+ if (timer) {
9819
+ clearTimeout(timer);
9820
+ timer = null;
9821
+ }
9822
+ }
9823
+ };
9824
+ }
9825
+
9826
+ // src/commands/shared/ask-user-handler.ts
9765
9827
  function parseOptionsFromQuery(query) {
9766
9828
  const optionsMatch = query.match(/\(选项:\s*(.+)\)/);
9767
9829
  if (optionsMatch) {
@@ -9816,7 +9878,6 @@ function parseUserInput(input, options) {
9816
9878
  }
9817
9879
  return { type: "text", value: trimmedInput };
9818
9880
  }
9819
-
9820
9881
  // src/commands/interactive-shutdown.ts
9821
9882
  import { TempFileManager as TempFileManager2 } from "@ai-setting/roy-agent-core/utils/temp-file-manager";
9822
9883
  async function shutdownInteractiveSteps(deps) {
@@ -9963,6 +10024,7 @@ class REPL {
9963
10024
  sessionComponent = null;
9964
10025
  lastAttachPath = undefined;
9965
10026
  lastUsage = null;
10027
+ askUserTimeoutMs = ASK_USER_TIMEOUT_MS;
9966
10028
  setLastUsage(usage) {
9967
10029
  this.lastUsage = usage;
9968
10030
  }
@@ -10350,22 +10412,27 @@ ${COLORS.error("❌ 执行失败: " + error)}
10350
10412
  async handleAskUserInteraction(errorInfo) {
10351
10413
  const { question, options } = parseOptionsFromQuery(errorInfo.query);
10352
10414
  console.log(formatAskUserOutput({ ...errorInfo, query: question, options }));
10353
- const userResponse = await this.promptUser(question, options);
10415
+ const userResponse = await this.promptUser(question, options, errorInfo);
10416
+ if (isAskUserTimeoutSentinel(userResponse)) {
10417
+ console.log(chalk5.dim(`
10418
+ 请直接输入新指令继续,或使用 /abort 中断当前工作流。`));
10419
+ return;
10420
+ }
10354
10421
  console.log(COLORS.userInput(`❯ ${userResponse.replace(/\n/g, `
10355
10422
  ` + COLORS.userInput("❯ "))}`));
10356
10423
  await this.executeInternal(userResponse, { showPrompt: false });
10357
10424
  }
10358
- promptUser(question, options) {
10425
+ promptUser(question, options, errorInfo, opts) {
10426
+ const timeoutMs = opts?.timeoutMs ?? this.askUserTimeoutMs ?? ASK_USER_TIMEOUT_MS;
10359
10427
  return new Promise((resolve) => {
10360
10428
  this.rl.setPrompt(COLORS.userInput("❯ "));
10361
10429
  this.rl.prompt(true);
10362
- const handleLine = (input) => {
10363
- this.rl.removeListener("line", handleLine);
10430
+ const finishWithUserInput = (input) => {
10364
10431
  const trimmedInput = input.trim();
10365
10432
  if (!trimmedInput) {
10366
10433
  console.log(chalk5.yellow(`⚠️ 输入不能为空,请重新输入
10367
10434
  `));
10368
- this.promptUser(question, options).then(resolve);
10435
+ this.promptUser(question, options, errorInfo, opts).then(resolve);
10369
10436
  return;
10370
10437
  }
10371
10438
  const parsed = parseUserInput(trimmedInput, options);
@@ -10380,7 +10447,21 @@ ${COLORS.error("❌ 执行失败: " + error)}
10380
10447
  resolve(parsed.value);
10381
10448
  }
10382
10449
  };
10383
- this.rl.on("line", handleLine);
10450
+ withAskUserTimeoutRace({
10451
+ rl: this.rl,
10452
+ timeoutMs,
10453
+ onLine: (input) => {
10454
+ finishWithUserInput(input);
10455
+ },
10456
+ onTimeout: () => {
10457
+ console.log(chalk5.yellow(`
10458
+ ⏱ ask_user 超时:${timeoutMs}ms 内未收到回应,已自动解除等待。`));
10459
+ resolve(createAskUserTimeoutSentinel(errorInfo, timeoutMs, {
10460
+ source: "repl",
10461
+ question
10462
+ }));
10463
+ }
10464
+ });
10384
10465
  });
10385
10466
  }
10386
10467
  handleSigint() {
@@ -18493,6 +18574,19 @@ function renderRunResult(result) {
18493
18574
  } else if (result.status === "stopped") {
18494
18575
  lines.push(chalk65.yellow(`
18495
18576
  ⚠️ Workflow stopped`));
18577
+ } else if (result.status === "paused") {
18578
+ lines.push(chalk65.yellow(`
18579
+ ⏸️ Workflow paused`));
18580
+ if (result.pendingNodeId) {
18581
+ lines.push(chalk65.gray(` Pending node: ${result.pendingNodeId}`));
18582
+ }
18583
+ if (result.query) {
18584
+ lines.push("");
18585
+ lines.push(chalk65.bold("\uD83D\uDCAC Agent asked: ") + chalk65.white(result.query));
18586
+ }
18587
+ if (result.agentSessionId) {
18588
+ lines.push(chalk65.gray(` Agent sub-session: ${result.agentSessionId}`));
18589
+ }
18496
18590
  } else {
18497
18591
  lines.push(chalk65.blue(`
18498
18592
  \uD83D\uDD04 Workflow ${result.status}`));
@@ -19971,6 +20065,20 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
19971
20065
  input = args.session ? args.input : undefined;
19972
20066
  }
19973
20067
  }
20068
+ let nodeConfig;
20069
+ if (args.nodeConfig) {
20070
+ try {
20071
+ const parsed = JSON.parse(args.nodeConfig);
20072
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
20073
+ output.error(`Invalid --node-config: expected a JSON object mapping nodeId → overrides, got: ${args.nodeConfig}`);
20074
+ process.exit(1);
20075
+ }
20076
+ nodeConfig = parsed;
20077
+ } catch (err) {
20078
+ output.error(`Invalid --node-config JSON: ${err instanceof Error ? err.message : String(err)}`);
20079
+ process.exit(1);
20080
+ }
20081
+ }
19974
20082
  if (args.session && !args.session.startsWith("workflow_")) {
19975
20083
  output.error(`Invalid session ID: must start with 'workflow_' (got: ${args.session})`);
19976
20084
  process.exit(1);
@@ -19978,7 +20086,8 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
19978
20086
  const runOptions = {
19979
20087
  debug: args.debug,
19980
20088
  parallelLimit: args.parallelLimit,
19981
- timeout: args.timeout
20089
+ timeout: args.timeout,
20090
+ ...nodeConfig ? { nodeConfig } : {}
19982
20091
  };
19983
20092
  const rawEnvParentId = process.env["ROY_PARENT_SESSION_ID"];
19984
20093
  if (typeof rawEnvParentId === "string" && rawEnvParentId.length > 0) {
@@ -20002,7 +20111,10 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
20002
20111
  status: result.status,
20003
20112
  output: result.output,
20004
20113
  error: result.error,
20005
- durationMs: result.durationMs
20114
+ durationMs: result.durationMs,
20115
+ ...result.pendingNodeId ? { pendingNodeId: result.pendingNodeId } : {},
20116
+ ...result.query ? { query: result.query } : {},
20117
+ ...result.agentSessionId ? { agentSessionId: result.agentSessionId } : {}
20006
20118
  }));
20007
20119
  } catch (err) {
20008
20120
  const msg = err instanceof Error ? err.message : String(err);
@@ -20044,24 +20156,29 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
20044
20156
  process.exit(0);
20045
20157
  }
20046
20158
  output.log(chalk71.blue(`\uD83D\uDE80 Running workflow: ${workflow.name}`));
20047
- const result = await service.runWorkflow(definition, input, runOptions);
20159
+ const fileBranchInput = typeof input === "string" ? undefined : input;
20160
+ const result = await service.runWorkflow(definition, fileBranchInput, runOptions);
20048
20161
  output.log(renderRunResult({
20049
20162
  runId: result.runId,
20050
20163
  status: result.status,
20051
20164
  output: result.output,
20052
20165
  error: result.error,
20053
- durationMs: result.durationMs
20166
+ durationMs: result.durationMs,
20167
+ ...result.pendingNodeId ? { pendingNodeId: result.pendingNodeId } : {},
20168
+ ...result.query ? { query: result.query } : {},
20169
+ ...result.agentSessionId ? { agentSessionId: result.agentSessionId } : {}
20054
20170
  }));
20055
20171
  if (result.status === "paused") {
20056
20172
  output.log(chalk71.gray(`
20057
- \uD83D\uDCA1 Use "roy-agent workflow run ${result.runId} --session ${result.runId} --input '<response>'" to resume`));
20173
+ \uD83D\uDCA1 Resume with: roy-agent workflow run ${result.runId} --session ${result.runId} --input "<your answer>"`));
20058
20174
  }
20059
20175
  } else {
20060
20176
  const tool = createRunWorkflowTool(service);
20061
20177
  const toolResult = await tool.execute({
20062
20178
  workflow_name: args.identifier,
20063
- input: input || undefined,
20064
- timeout: args.timeout
20179
+ input: typeof input === "string" ? undefined : input || undefined,
20180
+ timeout: args.timeout,
20181
+ ...nodeConfig ? { node_config: nodeConfig } : {}
20065
20182
  }, {});
20066
20183
  if (!toolResult.success) {
20067
20184
  const outAny = toolResult.output;
@@ -20080,11 +20197,14 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
20080
20197
  status: runData.status,
20081
20198
  output: runData.output,
20082
20199
  error: runData.error,
20083
- durationMs: runData.duration_ms
20200
+ durationMs: runData.duration_ms,
20201
+ ...runData.pending_node_id ? { pendingNodeId: runData.pending_node_id } : {},
20202
+ ...runData.query ? { query: runData.query } : {},
20203
+ ...runData.agent_session_id ? { agentSessionId: runData.agent_session_id } : {}
20084
20204
  }));
20085
20205
  if (runData.status === "paused") {
20086
20206
  output.log(chalk71.gray(`
20087
- \uD83D\uDCA1 Use "roy-agent workflow run ${runData.run_id} --session ${runData.run_id} --input '<response>'" to resume`));
20207
+ \uD83D\uDCA1 Resume with: roy-agent workflow run ${args.identifier} --session ${runData.run_id} --input "<your answer>"`));
20088
20208
  }
20089
20209
  }
20090
20210
  if (workflowSpan) {
@@ -20150,6 +20270,9 @@ var WorkflowRunCommand = {
20150
20270
  alias: "s",
20151
20271
  describe: "从已有 session 恢复运行(支持 workflow pause/interrupt 恢复;runId == sessionId,传 workflow run 的 runId 即可)",
20152
20272
  type: "string"
20273
+ }).option("node-config", {
20274
+ describe: `Per-node runtime config overrides (Task #1974). JSON string: { "<nodeId>": { "timeout": 5000 } }. Shallow-merged into each node's effective config; input wins over nodeDef.config.`,
20275
+ type: "string"
20153
20276
  }),
20154
20277
  handler: runWorkflow
20155
20278
  };
package/dist/index.js CHANGED
@@ -7406,7 +7406,7 @@ var require_dist = __commonJS((exports) => {
7406
7406
  var require_package = __commonJS((exports, module) => {
7407
7407
  module.exports = {
7408
7408
  name: "@ai-setting/roy-agent-cli",
7409
- version: "1.6.1",
7409
+ version: "1.6.2",
7410
7410
  type: "module",
7411
7411
  description: "CLI for roy-agent - Non-interactive command execution",
7412
7412
  main: "./dist/index.js",
@@ -9761,6 +9761,68 @@ function joinResolvedSystemPrompts(prompts) {
9761
9761
  // src/commands/shared/ask-user-handler.ts
9762
9762
  import * as readline from "readline";
9763
9763
  import chalk3 from "chalk";
9764
+
9765
+ // src/commands/shared/ask-user-timeout.ts
9766
+ var ASK_USER_TIMEOUT_MS = 120000;
9767
+ var ASK_USER_TIMEOUT_SENTINEL_PREFIX = "__ASK_USER_TIMEOUT__:";
9768
+ function isAskUserTimeoutSentinel(value) {
9769
+ return typeof value === "string" && value.length > ASK_USER_TIMEOUT_SENTINEL_PREFIX.length && value.startsWith(ASK_USER_TIMEOUT_SENTINEL_PREFIX);
9770
+ }
9771
+ function createAskUserTimeoutSentinel(errorInfo, timeoutMs, extra) {
9772
+ const payload = {
9773
+ query: errorInfo?.query ?? extra?.question ?? "",
9774
+ sessionId: errorInfo?.sessionId,
9775
+ agentSessionId: errorInfo?.agentSessionId,
9776
+ nodeId: errorInfo?.nodeId,
9777
+ nodeType: errorInfo?.nodeType,
9778
+ timestamp: Date.now(),
9779
+ timeoutMs,
9780
+ source: extra?.source ?? "repl"
9781
+ };
9782
+ return ASK_USER_TIMEOUT_SENTINEL_PREFIX + JSON.stringify(payload);
9783
+ }
9784
+ function withAskUserTimeoutRace(opts) {
9785
+ const { rl, timeoutMs, onLine, onTimeout } = opts;
9786
+ let resolved = false;
9787
+ let timer = null;
9788
+ const handleLine = (input) => {
9789
+ if (resolved)
9790
+ return;
9791
+ resolved = true;
9792
+ rl.removeListener("line", handleLine);
9793
+ if (timer) {
9794
+ clearTimeout(timer);
9795
+ timer = null;
9796
+ }
9797
+ onLine(input);
9798
+ };
9799
+ rl.on("line", handleLine);
9800
+ timer = setTimeout(() => {
9801
+ if (resolved)
9802
+ return;
9803
+ resolved = true;
9804
+ rl.removeListener("line", handleLine);
9805
+ onTimeout();
9806
+ timer = null;
9807
+ }, timeoutMs);
9808
+ if (timer && typeof timer.unref === "function") {
9809
+ timer.unref();
9810
+ }
9811
+ return {
9812
+ cancel() {
9813
+ if (resolved)
9814
+ return;
9815
+ resolved = true;
9816
+ rl.removeListener("line", handleLine);
9817
+ if (timer) {
9818
+ clearTimeout(timer);
9819
+ timer = null;
9820
+ }
9821
+ }
9822
+ };
9823
+ }
9824
+
9825
+ // src/commands/shared/ask-user-handler.ts
9764
9826
  function parseOptionsFromQuery(query) {
9765
9827
  const optionsMatch = query.match(/\(选项:\s*(.+)\)/);
9766
9828
  if (optionsMatch) {
@@ -9815,7 +9877,6 @@ function parseUserInput(input, options) {
9815
9877
  }
9816
9878
  return { type: "text", value: trimmedInput };
9817
9879
  }
9818
-
9819
9880
  // src/commands/interactive-shutdown.ts
9820
9881
  import { TempFileManager as TempFileManager2 } from "@ai-setting/roy-agent-core/utils/temp-file-manager";
9821
9882
  async function shutdownInteractiveSteps(deps) {
@@ -9962,6 +10023,7 @@ class REPL {
9962
10023
  sessionComponent = null;
9963
10024
  lastAttachPath = undefined;
9964
10025
  lastUsage = null;
10026
+ askUserTimeoutMs = ASK_USER_TIMEOUT_MS;
9965
10027
  setLastUsage(usage) {
9966
10028
  this.lastUsage = usage;
9967
10029
  }
@@ -10349,22 +10411,27 @@ ${COLORS.error("❌ 执行失败: " + error)}
10349
10411
  async handleAskUserInteraction(errorInfo) {
10350
10412
  const { question, options } = parseOptionsFromQuery(errorInfo.query);
10351
10413
  console.log(formatAskUserOutput({ ...errorInfo, query: question, options }));
10352
- const userResponse = await this.promptUser(question, options);
10414
+ const userResponse = await this.promptUser(question, options, errorInfo);
10415
+ if (isAskUserTimeoutSentinel(userResponse)) {
10416
+ console.log(chalk5.dim(`
10417
+ 请直接输入新指令继续,或使用 /abort 中断当前工作流。`));
10418
+ return;
10419
+ }
10353
10420
  console.log(COLORS.userInput(`❯ ${userResponse.replace(/\n/g, `
10354
10421
  ` + COLORS.userInput("❯ "))}`));
10355
10422
  await this.executeInternal(userResponse, { showPrompt: false });
10356
10423
  }
10357
- promptUser(question, options) {
10424
+ promptUser(question, options, errorInfo, opts) {
10425
+ const timeoutMs = opts?.timeoutMs ?? this.askUserTimeoutMs ?? ASK_USER_TIMEOUT_MS;
10358
10426
  return new Promise((resolve) => {
10359
10427
  this.rl.setPrompt(COLORS.userInput("❯ "));
10360
10428
  this.rl.prompt(true);
10361
- const handleLine = (input) => {
10362
- this.rl.removeListener("line", handleLine);
10429
+ const finishWithUserInput = (input) => {
10363
10430
  const trimmedInput = input.trim();
10364
10431
  if (!trimmedInput) {
10365
10432
  console.log(chalk5.yellow(`⚠️ 输入不能为空,请重新输入
10366
10433
  `));
10367
- this.promptUser(question, options).then(resolve);
10434
+ this.promptUser(question, options, errorInfo, opts).then(resolve);
10368
10435
  return;
10369
10436
  }
10370
10437
  const parsed = parseUserInput(trimmedInput, options);
@@ -10379,7 +10446,21 @@ ${COLORS.error("❌ 执行失败: " + error)}
10379
10446
  resolve(parsed.value);
10380
10447
  }
10381
10448
  };
10382
- this.rl.on("line", handleLine);
10449
+ withAskUserTimeoutRace({
10450
+ rl: this.rl,
10451
+ timeoutMs,
10452
+ onLine: (input) => {
10453
+ finishWithUserInput(input);
10454
+ },
10455
+ onTimeout: () => {
10456
+ console.log(chalk5.yellow(`
10457
+ ⏱ ask_user 超时:${timeoutMs}ms 内未收到回应,已自动解除等待。`));
10458
+ resolve(createAskUserTimeoutSentinel(errorInfo, timeoutMs, {
10459
+ source: "repl",
10460
+ question
10461
+ }));
10462
+ }
10463
+ });
10383
10464
  });
10384
10465
  }
10385
10466
  handleSigint() {
@@ -18492,6 +18573,19 @@ function renderRunResult(result) {
18492
18573
  } else if (result.status === "stopped") {
18493
18574
  lines.push(chalk65.yellow(`
18494
18575
  ⚠️ Workflow stopped`));
18576
+ } else if (result.status === "paused") {
18577
+ lines.push(chalk65.yellow(`
18578
+ ⏸️ Workflow paused`));
18579
+ if (result.pendingNodeId) {
18580
+ lines.push(chalk65.gray(` Pending node: ${result.pendingNodeId}`));
18581
+ }
18582
+ if (result.query) {
18583
+ lines.push("");
18584
+ lines.push(chalk65.bold("\uD83D\uDCAC Agent asked: ") + chalk65.white(result.query));
18585
+ }
18586
+ if (result.agentSessionId) {
18587
+ lines.push(chalk65.gray(` Agent sub-session: ${result.agentSessionId}`));
18588
+ }
18495
18589
  } else {
18496
18590
  lines.push(chalk65.blue(`
18497
18591
  \uD83D\uDD04 Workflow ${result.status}`));
@@ -19970,6 +20064,20 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
19970
20064
  input = args.session ? args.input : undefined;
19971
20065
  }
19972
20066
  }
20067
+ let nodeConfig;
20068
+ if (args.nodeConfig) {
20069
+ try {
20070
+ const parsed = JSON.parse(args.nodeConfig);
20071
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
20072
+ output.error(`Invalid --node-config: expected a JSON object mapping nodeId → overrides, got: ${args.nodeConfig}`);
20073
+ process.exit(1);
20074
+ }
20075
+ nodeConfig = parsed;
20076
+ } catch (err) {
20077
+ output.error(`Invalid --node-config JSON: ${err instanceof Error ? err.message : String(err)}`);
20078
+ process.exit(1);
20079
+ }
20080
+ }
19973
20081
  if (args.session && !args.session.startsWith("workflow_")) {
19974
20082
  output.error(`Invalid session ID: must start with 'workflow_' (got: ${args.session})`);
19975
20083
  process.exit(1);
@@ -19977,7 +20085,8 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
19977
20085
  const runOptions = {
19978
20086
  debug: args.debug,
19979
20087
  parallelLimit: args.parallelLimit,
19980
- timeout: args.timeout
20088
+ timeout: args.timeout,
20089
+ ...nodeConfig ? { nodeConfig } : {}
19981
20090
  };
19982
20091
  const rawEnvParentId = process.env["ROY_PARENT_SESSION_ID"];
19983
20092
  if (typeof rawEnvParentId === "string" && rawEnvParentId.length > 0) {
@@ -20001,7 +20110,10 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
20001
20110
  status: result.status,
20002
20111
  output: result.output,
20003
20112
  error: result.error,
20004
- durationMs: result.durationMs
20113
+ durationMs: result.durationMs,
20114
+ ...result.pendingNodeId ? { pendingNodeId: result.pendingNodeId } : {},
20115
+ ...result.query ? { query: result.query } : {},
20116
+ ...result.agentSessionId ? { agentSessionId: result.agentSessionId } : {}
20005
20117
  }));
20006
20118
  } catch (err) {
20007
20119
  const msg = err instanceof Error ? err.message : String(err);
@@ -20043,24 +20155,29 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
20043
20155
  process.exit(0);
20044
20156
  }
20045
20157
  output.log(chalk71.blue(`\uD83D\uDE80 Running workflow: ${workflow.name}`));
20046
- const result = await service.runWorkflow(definition, input, runOptions);
20158
+ const fileBranchInput = typeof input === "string" ? undefined : input;
20159
+ const result = await service.runWorkflow(definition, fileBranchInput, runOptions);
20047
20160
  output.log(renderRunResult({
20048
20161
  runId: result.runId,
20049
20162
  status: result.status,
20050
20163
  output: result.output,
20051
20164
  error: result.error,
20052
- durationMs: result.durationMs
20165
+ durationMs: result.durationMs,
20166
+ ...result.pendingNodeId ? { pendingNodeId: result.pendingNodeId } : {},
20167
+ ...result.query ? { query: result.query } : {},
20168
+ ...result.agentSessionId ? { agentSessionId: result.agentSessionId } : {}
20053
20169
  }));
20054
20170
  if (result.status === "paused") {
20055
20171
  output.log(chalk71.gray(`
20056
- \uD83D\uDCA1 Use "roy-agent workflow run ${result.runId} --session ${result.runId} --input '<response>'" to resume`));
20172
+ \uD83D\uDCA1 Resume with: roy-agent workflow run ${result.runId} --session ${result.runId} --input "<your answer>"`));
20057
20173
  }
20058
20174
  } else {
20059
20175
  const tool = createRunWorkflowTool(service);
20060
20176
  const toolResult = await tool.execute({
20061
20177
  workflow_name: args.identifier,
20062
- input: input || undefined,
20063
- timeout: args.timeout
20178
+ input: typeof input === "string" ? undefined : input || undefined,
20179
+ timeout: args.timeout,
20180
+ ...nodeConfig ? { node_config: nodeConfig } : {}
20064
20181
  }, {});
20065
20182
  if (!toolResult.success) {
20066
20183
  const outAny = toolResult.output;
@@ -20079,11 +20196,14 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
20079
20196
  status: runData.status,
20080
20197
  output: runData.output,
20081
20198
  error: runData.error,
20082
- durationMs: runData.duration_ms
20199
+ durationMs: runData.duration_ms,
20200
+ ...runData.pending_node_id ? { pendingNodeId: runData.pending_node_id } : {},
20201
+ ...runData.query ? { query: runData.query } : {},
20202
+ ...runData.agent_session_id ? { agentSessionId: runData.agent_session_id } : {}
20083
20203
  }));
20084
20204
  if (runData.status === "paused") {
20085
20205
  output.log(chalk71.gray(`
20086
- \uD83D\uDCA1 Use "roy-agent workflow run ${runData.run_id} --session ${runData.run_id} --input '<response>'" to resume`));
20206
+ \uD83D\uDCA1 Resume with: roy-agent workflow run ${args.identifier} --session ${runData.run_id} --input "<your answer>"`));
20087
20207
  }
20088
20208
  }
20089
20209
  if (workflowSpan) {
@@ -20149,6 +20269,9 @@ var WorkflowRunCommand = {
20149
20269
  alias: "s",
20150
20270
  describe: "从已有 session 恢复运行(支持 workflow pause/interrupt 恢复;runId == sessionId,传 workflow run 的 runId 即可)",
20151
20271
  type: "string"
20272
+ }).option("node-config", {
20273
+ describe: `Per-node runtime config overrides (Task #1974). JSON string: { "<nodeId>": { "timeout": 5000 } }. Shallow-merged into each node's effective config; input wins over nodeDef.config.`,
20274
+ type: "string"
20152
20275
  }),
20153
20276
  handler: runWorkflow
20154
20277
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-agent-cli",
3
- "version": "1.6.1",
3
+ "version": "1.6.2",
4
4
  "type": "module",
5
5
  "description": "CLI for roy-agent - Non-interactive command execution",
6
6
  "main": "./dist/index.js",