@livx.cc/agentx 0.99.83 → 0.99.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -16407,7 +16407,7 @@ function parseArgs(argv) {
16407
16407
  if (a.seed && !a.boddb) throw new Error("--seed only applies with --boddb (it seeds the database from cwd on first run)");
16408
16408
  if (a.worktree && (a.vfs || a.boddb)) throw new Error("--worktree is a real-disk concept \u2014 incompatible with --vfs/--boddb");
16409
16409
  if (a.duplex && (a.task || a.print)) throw new Error("--duplex is interactive-only (a conversational mode) \u2014 drop the task/-p");
16410
- if (a.inputFormat && (!a.duplex || a.outputFormat !== "stream-json")) throw new Error("--input-format stream-json is headless duplex \u2014 use it with --duplex (or --voice) and --output-format stream-json");
16410
+ if (a.inputFormat && (!a.duplex && !a.print || a.outputFormat !== "stream-json")) throw new Error("--input-format stream-json needs --output-format stream-json and --duplex (or --voice) or -p");
16411
16411
  if (a.duplex && a.plan) throw new Error("--plan is not supported in --duplex (workers are non-interactive; a plan could never be approved)");
16412
16412
  if (a.voiceSystemPrompt && !a.duplex) throw new Error("--voice-system-prompt only applies with --duplex");
16413
16413
  if (a.voiceModel && !a.duplex) throw new Error("--voice-model only applies with --duplex");
@@ -16472,6 +16472,8 @@ Flags:
16472
16472
  --timeout <sec> wall-clock kill-switch (default 120)
16473
16473
  --input-format stream-json with --duplex|--voice + --output-format stream-json: headless duplex for a host app
16474
16474
  (NDJSON turns/barge-ins on stdin, reflex text + worker speech + task events on stdout)
16475
+ with -p: the first {"type":"user","text"} line is the prompt; later ones STEER the running turn
16476
+ (unconsumed steers come back as the result's \`unsteered\`)
16475
16477
  --output-format <f> headless output: text (default) | json (one result object) | stream-json (NDJSON events: {type:text|thinking}\u2026 then {type:result})
16476
16478
  -v, --version print version and exit
16477
16479
  -h, --help
@@ -20016,6 +20018,33 @@ async function duplexServe(args, ai, cfg, cwd) {
20016
20018
  persist();
20017
20019
  await closeMcp(mounted);
20018
20020
  }
20021
+ function readStdinSteers() {
20022
+ const early = [];
20023
+ let sink, got;
20024
+ const first = new Promise((res) => {
20025
+ got = res;
20026
+ });
20027
+ const rl = createInterface({ input: process.stdin });
20028
+ rl.on("line", (line) => {
20029
+ let m;
20030
+ try {
20031
+ m = JSON.parse(line);
20032
+ } catch {
20033
+ return;
20034
+ }
20035
+ if (m?.type !== "user" || typeof m.text !== "string" || !m.text.trim()) return;
20036
+ if (got) {
20037
+ got(m.text);
20038
+ got = void 0;
20039
+ } else if (sink) sink(m.text);
20040
+ else early.push(m.text);
20041
+ });
20042
+ rl.on("close", () => got?.(""));
20043
+ return { first, steer: (to) => {
20044
+ sink = to;
20045
+ early.splice(0).forEach(to);
20046
+ } };
20047
+ }
20019
20048
  function readAllStdin() {
20020
20049
  return new Promise((res) => {
20021
20050
  let data = "";
@@ -20049,7 +20078,9 @@ async function main() {
20049
20078
  process.exit(installUpdate() ? 0 : 1);
20050
20079
  }
20051
20080
  if (args.debug) process.env.DEBUG ||= "*";
20052
- if (args.print && !args.task && !process.stdin.isTTY) args.task = (await readAllStdin()).trim();
20081
+ const steers = args.print && args.inputFormat && !args.task ? readStdinSteers() : void 0;
20082
+ if (steers) args.task = (await steers.first).trim();
20083
+ else if (args.print && !args.task && !process.stdin.isTTY) args.task = (await readAllStdin()).trim();
20053
20084
  if (args.print && !args.task) {
20054
20085
  console.error(red(" -p: empty prompt (no task argument and nothing on stdin)"));
20055
20086
  process.exit(2);
@@ -20139,6 +20170,7 @@ async function main() {
20139
20170
  const store = new SessionStore(cwd);
20140
20171
  const session = startSession(args, store, agent, cwd);
20141
20172
  process.once("SIGINT", () => activeTurn?.abort());
20173
+ steers?.steer((text) => agent.inject(text));
20142
20174
  const { ok, res } = await runTurn(agent, store, session, args.task, void 0, cwd, autoRouteSend(args, agent, () => session, (m) => providerOptionsFor(m, cwd, cfg.mcpServers, mounted.map((x) => x.name))));
20143
20175
  if (cfg.reflectOnFailure && !ok && res?.finishReason !== "needs_input" && res && agent.options.memoryDir) {
20144
20176
  const _fsBase = agent.options.fs.getCwd() === "/" ? "" : agent.options.fs.getCwd();
@@ -20148,7 +20180,8 @@ async function main() {
20148
20180
  }
20149
20181
  await closeMcp(mounted);
20150
20182
  if (args.outputFormat === "json" || args.outputFormat === "stream-json") {
20151
- const obj = res ? jsonResult(res, session) : { ok: false, finishReason: "error", sessionId: session.meta.id };
20183
+ const left = steers ? agent.drainPendingSteers() : [];
20184
+ const obj = { ...res ? jsonResult(res, session) : { ok: false, finishReason: "error", sessionId: session.meta.id }, ...left.length ? { unsteered: left } : {} };
20152
20185
  process.stdout.write(JSON.stringify(args.outputFormat === "stream-json" ? { type: "result", ...obj } : obj) + "\n");
20153
20186
  }
20154
20187
  worktreeCleanup?.();