oasis_test_v2 2.2.42 → 2.2.44

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.
Files changed (2) hide show
  1. package/dist/index.js +259 -113
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1509,8 +1509,8 @@ function trimRoundSummariesForReturn(summaries, recentRounds = DELEGATION_RETURN
1509
1509
  const cut = Math.max(0, summaries.length - keep);
1510
1510
  return summaries.map((summary, index2) => {
1511
1511
  if (index2 >= cut) return { round: summary.round, text: summary.text, truncated: false };
1512
- const firstLine2 = summary.text.split("\n").map((line) => line.trim()).find((line) => line.length > 0) ?? "";
1513
- return { round: summary.round, text: firstLine2, truncated: true };
1512
+ const firstLine3 = summary.text.split("\n").map((line) => line.trim()).find((line) => line.length > 0) ?? "";
1513
+ return { round: summary.round, text: firstLine3, truncated: true };
1514
1514
  });
1515
1515
  }
1516
1516
  function collectDelegationArtifacts(roundSummaries) {
@@ -3918,7 +3918,7 @@ var init_claude_code = __esm({
3918
3918
  const liveEventCbs = [];
3919
3919
  let eventSeq = 0;
3920
3920
  let lastResult;
3921
- const stderrTail = [];
3921
+ const stderrTail2 = [];
3922
3922
  const STDERR_MAX_LINES = 40;
3923
3923
  const STDERR_MAX_BYTES = 4e3;
3924
3924
  const usageAcc = newClaudeUsageAcc();
@@ -3991,11 +3991,11 @@ var init_claude_code = __esm({
3991
3991
  out.write(line + "\n");
3992
3992
  } catch {
3993
3993
  }
3994
- stderrTail.push(line);
3995
- while (stderrTail.length > STDERR_MAX_LINES) stderrTail.shift();
3996
- let total = stderrTail.reduce((n, l) => n + l.length + 1, 0);
3997
- while (total > STDERR_MAX_BYTES && stderrTail.length > 1) {
3998
- total -= stderrTail.shift().length + 1;
3994
+ stderrTail2.push(line);
3995
+ while (stderrTail2.length > STDERR_MAX_LINES) stderrTail2.shift();
3996
+ let total = stderrTail2.reduce((n, l) => n + l.length + 1, 0);
3997
+ while (total > STDERR_MAX_BYTES && stderrTail2.length > 1) {
3998
+ total -= stderrTail2.shift().length + 1;
3999
3999
  }
4000
4000
  });
4001
4001
  const callbacks = [];
@@ -4025,7 +4025,7 @@ var init_claude_code = __esm({
4025
4025
  if (exited) return;
4026
4026
  let reason = killReason ?? classifyExit(lastResult);
4027
4027
  const resultErrors = Array.isArray(lastResult?.errors) ? lastResult.errors.map(String) : [];
4028
- const resumeErrText = [stderrTail.join("\n"), String(lastResult?.result ?? ""), ...resultErrors].join("\n");
4028
+ const resumeErrText = [stderrTail2.join("\n"), String(lastResult?.result ?? ""), ...resultErrors].join("\n");
4029
4029
  if (!killReason && job.resumeRuntimeSession && reason !== "clean" && isSessionNotFoundError(resumeErrText)) {
4030
4030
  reason = "session-not-found";
4031
4031
  }
@@ -4059,7 +4059,7 @@ var init_claude_code = __esm({
4059
4059
  const composed = [subtype && `[${subtype}]`, body2].filter(Boolean).join(" ").trim();
4060
4060
  if (composed) errorParts.push(composed);
4061
4061
  }
4062
- if (stderrTail.length) errorParts.push(stderrTail.join("\n").trim());
4062
+ if (stderrTail2.length) errorParts.push(stderrTail2.join("\n").trim());
4063
4063
  const errorMessage = isError ? errorParts.filter(Boolean).join("\n---\n").slice(-4e3).trim() || void 0 : void 0;
4064
4064
  exited = {
4065
4065
  code: killReason ? null : code2,
@@ -5476,7 +5476,7 @@ async function runProtocolSession(job, cfg) {
5476
5476
  let eventSeq = 0;
5477
5477
  let runtimeSessionId;
5478
5478
  const pendingTurnMessages = [];
5479
- const stderrTail = [];
5479
+ const stderrTail2 = [];
5480
5480
  const finish = (info) => {
5481
5481
  if (exited) return;
5482
5482
  closing = true;
@@ -5563,8 +5563,8 @@ async function runProtocolSession(job, cfg) {
5563
5563
  child.stderr.on("data", (chunk) => {
5564
5564
  const text6 = chunk.toString("utf8");
5565
5565
  transcript.write(text6);
5566
- stderrTail.push(text6.trim());
5567
- while (stderrTail.length > 40) stderrTail.shift();
5566
+ stderrTail2.push(text6.trim());
5567
+ while (stderrTail2.length > 40) stderrTail2.shift();
5568
5568
  });
5569
5569
  const timer = setTimeout(() => {
5570
5570
  killReason ??= "timeout";
@@ -5584,7 +5584,7 @@ async function runProtocolSession(job, cfg) {
5584
5584
  const info = {
5585
5585
  code: killReason ? null : code2,
5586
5586
  reason,
5587
- ...reason === "error" && stderrTail.length ? { errorMessage: stderrTail.join("\n").slice(-4e3) } : {}
5587
+ ...reason === "error" && stderrTail2.length ? { errorMessage: stderrTail2.join("\n").slice(-4e3) } : {}
5588
5588
  };
5589
5589
  finish(!killReason && cfg.processExitInfo ? cfg.processExitInfo(info, state) : info);
5590
5590
  }
@@ -6287,8 +6287,8 @@ ${task}` : task;
6287
6287
  }
6288
6288
  if (method === "turn/completed") {
6289
6289
  const turn = record2(params?.turn);
6290
- const failure = typeof turn?.id === "string" ? state.errorsByTurn.get(turn.id) : void 0;
6291
- if (params?.threadId !== state.threadId || turn?.id !== state.turnId || turn?.status !== "completed" || turn.error || failure && !failure.willRetry) return [];
6290
+ const failure2 = typeof turn?.id === "string" ? state.errorsByTurn.get(turn.id) : void 0;
6291
+ if (params?.threadId !== state.threadId || turn?.id !== state.turnId || turn?.status !== "completed" || turn.error || failure2 && !failure2.willRetry) return [];
6292
6292
  return [{ ...base, itemId: "turn-end", itemType: "control", operation: "completed", payload: { code: "output_block_completed" } }];
6293
6293
  }
6294
6294
  return [];
@@ -6340,8 +6340,8 @@ ${task}` : task;
6340
6340
  if (params?.threadId !== state.threadId || !state.turnId || turn?.id !== state.turnId) return void 0;
6341
6341
  state.active = false;
6342
6342
  if (turn.status === "interrupted") return { code: null, reason: "cancelled" };
6343
- const failure = state.errorsByTurn.get(state.turnId);
6344
- const error2 = turn.error ?? (turn.status === "failed" || !failure?.willRetry ? failure?.error : void 0);
6343
+ const failure2 = state.errorsByTurn.get(state.turnId);
6344
+ const error2 = turn.error ?? (turn.status === "failed" || !failure2?.willRetry ? failure2?.error : void 0);
6345
6345
  if (turn.status === "completed" && !error2) return { code: 0, reason: "clean" };
6346
6346
  return { code: 1, reason: "error", errorMessage: codexTurnErrorMessage(error2) };
6347
6347
  },
@@ -6540,15 +6540,15 @@ ${task}` : task;
6540
6540
  for (const cb of telemetryCbs) cb(full);
6541
6541
  }
6542
6542
  };
6543
- const stderrTail = [];
6543
+ const stderrTail2 = [];
6544
6544
  const STDERR_MAX_LINES = 40;
6545
6545
  const STDERR_MAX_BYTES = 4e3;
6546
6546
  const pushStderrTail = (line) => {
6547
- stderrTail.push(line);
6548
- while (stderrTail.length > STDERR_MAX_LINES) stderrTail.shift();
6549
- let total = stderrTail.reduce((n, l) => n + l.length + 1, 0);
6550
- while (total > STDERR_MAX_BYTES && stderrTail.length > 1) {
6551
- total -= stderrTail.shift().length + 1;
6547
+ stderrTail2.push(line);
6548
+ while (stderrTail2.length > STDERR_MAX_LINES) stderrTail2.shift();
6549
+ let total = stderrTail2.reduce((n, l) => n + l.length + 1, 0);
6550
+ while (total > STDERR_MAX_BYTES && stderrTail2.length > 1) {
6551
+ total -= stderrTail2.shift().length + 1;
6552
6552
  }
6553
6553
  };
6554
6554
  const stdoutErrorLines = [];
@@ -6633,8 +6633,8 @@ ${task}` : task;
6633
6633
  const runtimeSessionId = telemetry.sessionId ?? resumeSessionId;
6634
6634
  const sawStreamError = streamErrorMessages.length > 0;
6635
6635
  const isError = !killReason && (code2 !== 0 || sawStreamError);
6636
- const errorMessage = isError ? [...streamErrorMessages, ...stdoutErrorLines, ...stderrTail].join("\n").trim().slice(-4e3) || void 0 : void 0;
6637
- const sessionNotFound = !killReason && isResume && isSessionNotFoundError([...streamErrorMessages, ...stdoutErrorLines, ...stderrTail].join("\n"));
6636
+ const errorMessage = isError ? [...streamErrorMessages, ...stdoutErrorLines, ...stderrTail2].join("\n").trim().slice(-4e3) || void 0 : void 0;
6637
+ const sessionNotFound = !killReason && isResume && isSessionNotFoundError([...streamErrorMessages, ...stdoutErrorLines, ...stderrTail2].join("\n"));
6638
6638
  const reason = killReason ? killReason : sessionNotFound ? "session-not-found" : sawStreamError ? "error" : code2 === 0 ? "clean" : "error";
6639
6639
  finish({
6640
6640
  code: killReason ? null : code2,
@@ -7187,10 +7187,10 @@ function parseArgsJSON(argsText) {
7187
7187
  return { text: t };
7188
7188
  }
7189
7189
  }
7190
- function composeAcpErrorMessage(rpcError, stderrTail) {
7190
+ function composeAcpErrorMessage(rpcError, stderrTail2) {
7191
7191
  const parts = [];
7192
7192
  if (rpcError && rpcError.trim()) parts.push(rpcError.trim());
7193
- if (stderrTail.length) parts.push(stderrTail.join("\n").trim());
7193
+ if (stderrTail2.length) parts.push(stderrTail2.join("\n").trim());
7194
7194
  const combined = parts.filter(Boolean).join("\n---\n").slice(-4e3).trim();
7195
7195
  return combined || void 0;
7196
7196
  }
@@ -7344,20 +7344,26 @@ ${note}` : note };
7344
7344
  killReason ??= "timeout";
7345
7345
  child.kill("SIGKILL");
7346
7346
  }, job.limits.wallClockMs);
7347
- const stderrTail = [];
7347
+ const stderrTail2 = [];
7348
7348
  const STDERR_MAX_LINES = 40;
7349
7349
  const STDERR_MAX_BYTES = 4e3;
7350
+ let turnMessage = "";
7351
+ let turnStderr = [];
7350
7352
  const stderrRl = readline3.createInterface({ input: child.stderr });
7351
7353
  stderrRl.on("line", (line) => {
7352
7354
  try {
7353
7355
  transcriptOut.write(line + "\n");
7354
7356
  } catch {
7355
7357
  }
7356
- stderrTail.push(line);
7357
- while (stderrTail.length > STDERR_MAX_LINES) stderrTail.shift();
7358
- let total = stderrTail.reduce((n, l) => n + l.length + 1, 0);
7359
- while (total > STDERR_MAX_BYTES && stderrTail.length > 1) {
7360
- total -= stderrTail.shift().length + 1;
7358
+ if (cfg.classifyPromptFailure) {
7359
+ turnStderr.push(line);
7360
+ if (turnStderr.length > PROMPT_TURN_STDERR_MAX_LINES) turnStderr.shift();
7361
+ }
7362
+ stderrTail2.push(line);
7363
+ while (stderrTail2.length > STDERR_MAX_LINES) stderrTail2.shift();
7364
+ let total = stderrTail2.reduce((n, l) => n + l.length + 1, 0);
7365
+ while (total > STDERR_MAX_BYTES && stderrTail2.length > 1) {
7366
+ total -= stderrTail2.shift().length + 1;
7361
7367
  }
7362
7368
  });
7363
7369
  let lastRpcError;
@@ -7399,6 +7405,7 @@ ${note}` : note };
7399
7405
  },
7400
7406
  (text6) => {
7401
7407
  confirmAppendBatch();
7408
+ if (cfg.classifyPromptFailure && turnMessage.length < PROMPT_TURN_MESSAGE_MAX) turnMessage += text6;
7402
7409
  for (const cb of outputCbs) cb(text6);
7403
7410
  },
7404
7411
  (e) => {
@@ -7428,7 +7435,7 @@ ${note}` : note };
7428
7435
  });
7429
7436
  child.on("error", (err) => {
7430
7437
  clearTimeout(timer);
7431
- finish({ code: null, reason: "error", transcriptRef, errorMessage: composeAcpErrorMessage(err instanceof Error ? err.message : String(err), stderrTail) });
7438
+ finish({ code: null, reason: "error", transcriptRef, errorMessage: composeAcpErrorMessage(err instanceof Error ? err.message : String(err), stderrTail2) });
7432
7439
  });
7433
7440
  child.on("exit", (code2) => {
7434
7441
  clearTimeout(timer);
@@ -7438,7 +7445,7 @@ ${note}` : note };
7438
7445
  code: killReason ? null : code2,
7439
7446
  reason: killReason ?? (code2 === 0 ? "clean" : "error"),
7440
7447
  transcriptRef,
7441
- ...isError ? { errorMessage: composeAcpErrorMessage(lastRpcError, stderrTail) } : {}
7448
+ ...isError ? { errorMessage: composeAcpErrorMessage(lastRpcError, stderrTail2) } : {}
7442
7449
  });
7443
7450
  });
7444
7451
  });
@@ -7514,6 +7521,8 @@ ${task}` : task;
7514
7521
  }
7515
7522
  streamingCurrentTurn = true;
7516
7523
  const sendPrompt = async (text6) => {
7524
+ turnMessage = "";
7525
+ turnStderr = [];
7517
7526
  const p2 = client.request("session/prompt", { sessionId, prompt: [{ type: "text", text: text6 }] });
7518
7527
  inflightStopReason = p2.then((r) => extractStopReason(r), () => "");
7519
7528
  try {
@@ -7544,15 +7553,22 @@ ${task}` : task;
7544
7553
  inflightAppendBatch = [];
7545
7554
  }
7546
7555
  closingForExit = true;
7556
+ let failure2;
7557
+ if (cfg.classifyPromptFailure) {
7558
+ await new Promise((r) => setTimeout(r, PROMPT_FAILURE_STDERR_SETTLE_MS));
7559
+ failure2 = cfg.classifyPromptFailure({ message: turnMessage, stderrLines: [...turnStderr], result: promptResult });
7560
+ }
7547
7561
  const usage = buildReportedUsage(client.usage, actualModel, cfg.inputTokensIncludeCacheRead === true);
7548
- if (!exited) finish({ code: 0, reason: "clean", transcriptRef, usage, model: actualModel });
7562
+ if (!exited) {
7563
+ finish(failure2 ? { code: null, reason: failure2.reason, errorMessage: failure2.errorMessage, transcriptRef, usage, model: actualModel } : { code: 0, reason: "clean", transcriptRef, usage, model: actualModel });
7564
+ }
7549
7565
  child.kill("SIGTERM");
7550
7566
  } catch (err) {
7551
7567
  lastRpcError = err instanceof Error ? err.message : String(err);
7552
7568
  if (!exited) {
7553
7569
  const reason = killReason ?? "error";
7554
7570
  const usage = buildReportedUsage(client.usage, actualModel, cfg.inputTokensIncludeCacheRead === true);
7555
- finish({ code: null, reason, transcriptRef, usage, model: actualModel, ...killReason ? {} : { errorMessage: composeAcpErrorMessage(lastRpcError, stderrTail) } });
7571
+ finish({ code: null, reason, transcriptRef, usage, model: actualModel, ...killReason ? {} : { errorMessage: composeAcpErrorMessage(lastRpcError, stderrTail2) } });
7556
7572
  }
7557
7573
  } finally {
7558
7574
  await readerDone;
@@ -7637,7 +7653,7 @@ ${task}` : task;
7637
7653
  return run;
7638
7654
  }
7639
7655
  }
7640
- var import_node_child_process8, import_node_crypto10, fs9, path11, readline3, ACPClient, LEGACY_APPROVE_OPTION_ID;
7656
+ var import_node_child_process8, import_node_crypto10, fs9, path11, readline3, PROMPT_TURN_MESSAGE_MAX, PROMPT_TURN_STDERR_MAX_LINES, PROMPT_FAILURE_STDERR_SETTLE_MS, ACPClient, LEGACY_APPROVE_OPTION_ID;
7641
7657
  var init_acp = __esm({
7642
7658
  "../adapters/src/_core/acp.ts"() {
7643
7659
  "use strict";
@@ -7656,6 +7672,9 @@ var init_acp = __esm({
7656
7672
  init_transcript();
7657
7673
  init_filter_extra_args();
7658
7674
  init_root_bypass();
7675
+ PROMPT_TURN_MESSAGE_MAX = 4e3;
7676
+ PROMPT_TURN_STDERR_MAX_LINES = 200;
7677
+ PROMPT_FAILURE_STDERR_SETTLE_MS = 50;
7659
7678
  ACPClient = class {
7660
7679
  constructor(write, onOutput, onTelemetry, onStop, acceptNotification = () => true, finalUsageIsAuthoritative = false, vendorUsage) {
7661
7680
  this.write = write;
@@ -7935,12 +7954,79 @@ var init_acp = __esm({
7935
7954
  }
7936
7955
  });
7937
7956
 
7957
+ // ../adapters/src/hermes/prompt-failure.ts
7958
+ function classifyHermesPromptFailure(turn) {
7959
+ const errors = mainAgentErrorRecords(turn.stderrLines);
7960
+ if (promptResultHasUsage(turn.result)) {
7961
+ const gaveUp = errors.filter((r) => API_GAVE_UP_RE.test(r));
7962
+ return gaveUp.length > 0 ? failure(clip(gaveUp.slice(-MAX_ERROR_RECORDS).join("\n"))) : void 0;
7963
+ }
7964
+ const failedSentence = FAILED_SENTENCE_RE.test(turn.message) ? firstLine(turn.message) : void 0;
7965
+ const silent = turn.message.trim() === "";
7966
+ if (errors.length === 0 && !failedSentence && !silent) return void 0;
7967
+ return failure(errors.length > 0 ? clip(errors.slice(-MAX_ERROR_RECORDS).join("\n")) : failedSentence ?? `hermes \u672C\u8F6E\u6CA1\u6709\u6B63\u5E38\u6536\u5C3E\uFF08\u54CD\u5E94\u4E0D\u5E26\u7528\u91CF\uFF09\uFF0C\u6CA1\u6709\u8F93\u51FA\uFF0Cstderr \u4E5F\u6CA1\u6709 ERROR \u65E5\u5FD7\u3002${stderrTail(turn.stderrLines)}`);
7968
+ }
7969
+ function failure(errorMessage) {
7970
+ return { reason: QUOTA_RE.test(errorMessage) ? "rate-limit" : "error", errorMessage };
7971
+ }
7972
+ function promptResultHasUsage(result) {
7973
+ if (typeof result !== "object" || result === null) return false;
7974
+ return USAGE_KEYS.some((k2) => result[k2] != null);
7975
+ }
7976
+ function mainAgentErrorRecords(lines) {
7977
+ const records = [];
7978
+ let current = null;
7979
+ const flush = () => {
7980
+ if (current) records.push(current.join("\n").trimEnd());
7981
+ current = null;
7982
+ };
7983
+ for (const line of lines) {
7984
+ const m2 = LOG_RECORD_RE.exec(line);
7985
+ if (m2) {
7986
+ flush();
7987
+ const [, level, text6] = m2;
7988
+ if ((level === "ERROR" || level === "CRITICAL") && !SUBAGENT_PREFIX_RE.test(text6)) current = [text6];
7989
+ } else if (current) {
7990
+ current.push(line);
7991
+ }
7992
+ }
7993
+ flush();
7994
+ return records.filter((r) => r.trim() !== "");
7995
+ }
7996
+ function firstLine(text6) {
7997
+ return text6.trim().split("\n")[0].trim();
7998
+ }
7999
+ function clip(text6) {
8000
+ return text6.length > MAX_ERROR_CHARS ? `\u2026${text6.slice(-MAX_ERROR_CHARS)}` : text6;
8001
+ }
8002
+ function stderrTail(lines) {
8003
+ const tail = lines.filter((l) => l.trim() !== "").slice(-10).join("\n");
8004
+ return tail ? `
8005
+ stderr \u672B\u5C3E\uFF1A
8006
+ ${clip(tail)}` : "";
8007
+ }
8008
+ var QUOTA_RE, API_GAVE_UP_RE, FAILED_SENTENCE_RE, LOG_RECORD_RE, SUBAGENT_PREFIX_RE, MAX_ERROR_RECORDS, MAX_ERROR_CHARS, USAGE_KEYS;
8009
+ var init_prompt_failure = __esm({
8010
+ "../adapters/src/hermes/prompt-failure.ts"() {
8011
+ "use strict";
8012
+ QUOTA_RE = /\b429\b|rate.?limit|usage limit|quota|too many requests/i;
8013
+ API_GAVE_UP_RE = /^(?:Non-retryable client error: |API call failed after \d+ retries\. )/;
8014
+ FAILED_SENTENCE_RE = /^\s*API call failed after \d+ retries: /;
8015
+ LOG_RECORD_RE = /^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:[,.]\d+)?\s+\[([A-Z]+)\]\s+[\w.-]+:\s?(.*)$/;
8016
+ SUBAGENT_PREFIX_RE = /^\[subagent-\d+\]\s/;
8017
+ MAX_ERROR_RECORDS = 5;
8018
+ MAX_ERROR_CHARS = 4e3;
8019
+ USAGE_KEYS = ["usage", "token_usage", "tokenUsage", "tokens", "usageMetadata", "usage_metadata"];
8020
+ }
8021
+ });
8022
+
7938
8023
  // ../adapters/src/hermes/index.ts
7939
8024
  var HermesAdapter;
7940
8025
  var init_hermes = __esm({
7941
8026
  "../adapters/src/hermes/index.ts"() {
7942
8027
  "use strict";
7943
8028
  init_acp();
8029
+ init_prompt_failure();
7944
8030
  HermesAdapter = class {
7945
8031
  constructor(opts = {}) {
7946
8032
  this.opts = opts;
@@ -7972,6 +8058,8 @@ var init_hermes = __esm({
7972
8058
  // skills.external_dirs 配成该 env → hermes 每 session 发现各自技能。见
7973
8059
  // packages/adapters/docs/modules/07-skills-delivery.md 与 connect-script.ts。
7974
8060
  injectSkillsDirEnv: "OASIS_HERMES_SKILLS_DIR",
8061
+ // hermes 的 ACP 层不转发失败:API 没成功照样回 end_turn,原因只在 stderr 的 ERROR 日志里——见 prompt-failure.ts。
8062
+ classifyPromptFailure: classifyHermesPromptFailure,
7975
8063
  ...this.opts.syncSkills ? { syncSkills: this.opts.syncSkills } : {}
7976
8064
  });
7977
8065
  }
@@ -7985,6 +8073,7 @@ var init_oasis_agent = __esm({
7985
8073
  "../adapters/src/oasis-agent/index.ts"() {
7986
8074
  "use strict";
7987
8075
  init_acp();
8076
+ init_prompt_failure();
7988
8077
  OasisAgentAdapter = class {
7989
8078
  constructor(opts = {}) {
7990
8079
  this.opts = opts;
@@ -8015,6 +8104,8 @@ var init_oasis_agent = __esm({
8015
8104
  // 名字分开才能在同机共存时一眼看出哪份 config 是给谁的。node enroll 会把该字面量写进
8016
8105
  // `~/.oasis-agent/home/config.yaml` 的 skills.external_dirs(见 connect-script.ts)。
8017
8106
  injectSkillsDirEnv: "OASIS_AGENT_SKILLS_DIR",
8107
+ // 分叉没动 acp_adapter/,失败回合的线上形态与 hermes 相同(未在分叉上实测)。
8108
+ classifyPromptFailure: classifyHermesPromptFailure,
8018
8109
  ...this.opts.syncSkills ? { syncSkills: this.opts.syncSkills } : {}
8019
8110
  });
8020
8111
  }
@@ -8603,17 +8694,17 @@ async function runStreamJson(job, cfg) {
8603
8694
  );
8604
8695
  let killReason = null;
8605
8696
  let seq = 0;
8606
- const stderrTail = [];
8697
+ const stderrTail2 = [];
8607
8698
  const stderrRl = readline4.createInterface({ input: child.stderr });
8608
8699
  stderrRl.on("line", (line) => {
8609
8700
  try {
8610
8701
  transcriptOut.write(line + "\n");
8611
8702
  } catch {
8612
8703
  }
8613
- stderrTail.push(line);
8614
- while (stderrTail.length > 40) stderrTail.shift();
8615
- let total = stderrTail.reduce((n, l) => n + l.length + 1, 0);
8616
- while (total > 4e3 && stderrTail.length > 1) total -= stderrTail.shift().length + 1;
8704
+ stderrTail2.push(line);
8705
+ while (stderrTail2.length > 40) stderrTail2.shift();
8706
+ let total = stderrTail2.reduce((n, l) => n + l.length + 1, 0);
8707
+ while (total > 4e3 && stderrTail2.length > 1) total -= stderrTail2.shift().length + 1;
8617
8708
  });
8618
8709
  const rl = readline4.createInterface({ input: child.stdout });
8619
8710
  rl.on("line", (line) => {
@@ -8639,7 +8730,7 @@ async function runStreamJson(job, cfg) {
8639
8730
  child.on("exit", (code2) => {
8640
8731
  clearTimeout(timer);
8641
8732
  const isError = !killReason && typeof code2 === "number" && code2 !== 0;
8642
- const errorMessage = isError ? stderrTail.join("\n").trim().slice(-4e3) || void 0 : void 0;
8733
+ const errorMessage = isError ? stderrTail2.join("\n").trim().slice(-4e3) || void 0 : void 0;
8643
8734
  finish({
8644
8735
  code: killReason ? null : code2,
8645
8736
  reason: killReason ?? (code2 === 0 ? "clean" : "error"),
@@ -8715,17 +8806,17 @@ async function runOneShotText(job, cfg) {
8715
8806
  const text6 = chunk.toString("utf8");
8716
8807
  for (const cb of outputCbs) cb(text6);
8717
8808
  });
8718
- const stderrTail = [];
8809
+ const stderrTail2 = [];
8719
8810
  const stderrRl = readline4.createInterface({ input: child.stderr });
8720
8811
  stderrRl.on("line", (line) => {
8721
8812
  try {
8722
8813
  transcriptOut.write(line + "\n");
8723
8814
  } catch {
8724
8815
  }
8725
- stderrTail.push(line);
8726
- while (stderrTail.length > 40) stderrTail.shift();
8727
- let total = stderrTail.reduce((n, l) => n + l.length + 1, 0);
8728
- while (total > 4e3 && stderrTail.length > 1) total -= stderrTail.shift().length + 1;
8816
+ stderrTail2.push(line);
8817
+ while (stderrTail2.length > 40) stderrTail2.shift();
8818
+ let total = stderrTail2.reduce((n, l) => n + l.length + 1, 0);
8819
+ while (total > 4e3 && stderrTail2.length > 1) total -= stderrTail2.shift().length + 1;
8729
8820
  });
8730
8821
  const killChild = () => {
8731
8822
  if (containerized) killContainerBestEffort(containerized.containerName, containerized.mode);
@@ -8742,7 +8833,7 @@ async function runOneShotText(job, cfg) {
8742
8833
  child.on("exit", (code2) => {
8743
8834
  clearTimeout(timer);
8744
8835
  const isError = !killReason && typeof code2 === "number" && code2 !== 0;
8745
- const errorMessage = isError ? stderrTail.join("\n").trim().slice(-4e3) || void 0 : void 0;
8836
+ const errorMessage = isError ? stderrTail2.join("\n").trim().slice(-4e3) || void 0 : void 0;
8746
8837
  finish({
8747
8838
  code: killReason ? null : code2,
8748
8839
  reason: killReason ?? (code2 === 0 ? "clean" : "error"),
@@ -138626,7 +138717,7 @@ function classifyExitReason(info) {
138626
138717
  if (info.reason) return info.reason;
138627
138718
  const msg = info.errorMessage;
138628
138719
  if (!msg) return info.reason;
138629
- if (QUOTA_RE.test(msg)) return "rate-limit";
138720
+ if (QUOTA_RE2.test(msg)) return "rate-limit";
138630
138721
  if (UNREACHABLE_RE.test(msg)) return "server-unreachable";
138631
138722
  if (AUTH_RE.test(msg)) return "auth-error";
138632
138723
  return info.reason;
@@ -138643,11 +138734,11 @@ function extractResetHint(errorMessage) {
138643
138734
  const m2 = /((?:resets?|try again at)\s+[^·。\n]{1,48})/i.exec(errorMessage);
138644
138735
  return m2?.[1]?.trim().replace(/[.,;]$/, "");
138645
138736
  }
138646
- var QUOTA_RE, UNREACHABLE_RE, AUTH_RE;
138737
+ var QUOTA_RE2, UNREACHABLE_RE, AUTH_RE;
138647
138738
  var init_exit_classify = __esm({
138648
138739
  "../core/src/exit-classify.ts"() {
138649
138740
  "use strict";
138650
- QUOTA_RE = /hit your (?:weekly|session|usage|daily|monthly) limit|usage limit|rate.?limit|quota exceeded|too many requests|\b429\b/i;
138741
+ QUOTA_RE2 = /hit your (?:weekly|session|usage|daily|monthly) limit|usage limit|rate.?limit|quota exceeded|too many requests|\b429\b/i;
138651
138742
  UNREACHABLE_RE = /不在线|socket 非 OPEN|帧未送达|失联超宽限期|未见任何回执|unreachable|ECONNREFUSED|ETIMEDOUT/i;
138652
138743
  AUTH_RE = /\b401\b|\b403\b|unauthor|invalid[_ -]?api[_ -]?key|authentication failed|credential/i;
138653
138744
  }
@@ -187784,22 +187875,22 @@ var init_network_maintenance = __esm({
187784
187875
  });
187785
187876
  if (!saved.committed) throw new KnowledgeMaintenanceProcessingError(`\u77E5\u8BC6\u7F51\u7EDC\u4EFB\u52A1 ${taskKey} \u7ED3\u679C\u68C0\u67E5\u70B9\u63D0\u4EA4\u51B2\u7A81`, true);
187786
187877
  },
187787
- onTaskFailed: async (taskKey, failure) => {
187878
+ onTaskFailed: async (taskKey, failure2) => {
187788
187879
  const current = (await store.list(scope2, "maintenance_task")).find((task) => task.maintenanceRunId === run.id && task.taskKey === taskKey);
187789
187880
  if (!current || current.status === "succeeded") return;
187790
- const retryable = failure.kind === "runtime" && isRetryableKnowledgeMaintenanceError(failure.cause ?? new Error(failure.message));
187881
+ const retryable = failure2.kind === "runtime" && isRetryableKnowledgeMaintenanceError(failure2.cause ?? new Error(failure2.message));
187791
187882
  const now = this.iso();
187792
- const output = failure.rawOutput ? this.snapshot(ctx, "maintenance_task_output", stableJson2(failure.rawOutput), projectId2, run.spaceId, `snapshot:maintenance-task-output:${run.id}:${taskKey}:${current.retryCount}`) : void 0;
187883
+ const output = failure2.rawOutput ? this.snapshot(ctx, "maintenance_task_output", stableJson2(failure2.rawOutput), projectId2, run.spaceId, `snapshot:maintenance-task-output:${run.id}:${taskKey}:${current.retryCount}`) : void 0;
187793
187884
  const failed = {
187794
187885
  ...current,
187795
- ...failure.sessionId ? { sessionId: failure.sessionId } : {},
187886
+ ...failure2.sessionId ? { sessionId: failure2.sessionId } : {},
187796
187887
  status: retryable ? "failed_transient" : "failed_deterministic",
187797
187888
  ...output ? { outputSnapshotRef: output.ref, outputHash: output.contentHash } : {},
187798
187889
  validationStatus: "failed",
187799
- ...failure.validationError ? { validationError: failure.validationError } : {},
187800
- error: failure.message.slice(0, 2e3),
187890
+ ...failure2.validationError ? { validationError: failure2.validationError } : {},
187891
+ error: failure2.message.slice(0, 2e3),
187801
187892
  completedAt: now,
187802
- ...failure.kind === "deterministic" ? { validatedAt: now } : {},
187893
+ ...failure2.kind === "deterministic" ? { validatedAt: now } : {},
187803
187894
  updatedAt: now
187804
187895
  };
187805
187896
  const saved = await store.transact(scope2, {
@@ -187980,9 +188071,9 @@ var init_network_maintenance = __esm({
187980
188071
  if (!result.committed) throw new Error("\u7EF4\u62A4\u5206\u6790\u7ED3\u679C\u63D0\u4EA4\u51B2\u7A81");
187981
188072
  return ready;
187982
188073
  } catch (error2) {
187983
- const failure = maintenanceFailure(error2);
188074
+ const failure2 = maintenanceFailure(error2);
187984
188075
  const latestTasks = (await store.list(scope2, "maintenance_task")).filter((task) => task.maintenanceRunId === run.id);
187985
- const validationIssue = failure.retryable ? void 0 : validationIssueForFailure(error2, latestTasks);
188076
+ const validationIssue = failure2.retryable ? void 0 : validationIssueForFailure(error2, latestTasks);
187986
188077
  const repairTaskKeys = new Set(validationIssue?.taskKeys ?? []);
187987
188078
  const now = this.iso();
187988
188079
  const invalidatedTasks = latestTasks.flatMap((task) => {
@@ -188000,8 +188091,8 @@ var init_network_maintenance = __esm({
188000
188091
  const failed = {
188001
188092
  ...processing,
188002
188093
  status: "failed",
188003
- errorCode: failure.retryable ? "ANALYSIS_TRANSIENT_FAILED" : "ANALYSIS_OR_VALIDATION_FAILED",
188004
- error: failure.message.slice(0, 2e3),
188094
+ errorCode: failure2.retryable ? "ANALYSIS_TRANSIENT_FAILED" : "ANALYSIS_OR_VALIDATION_FAILED",
188095
+ error: failure2.message.slice(0, 2e3),
188005
188096
  ...validationIssue ? { validationIssues: [validationIssue] } : { validationIssues: void 0 },
188006
188097
  retryCount: processing.retryCount + 1,
188007
188098
  updatedAt: now
@@ -188018,7 +188109,7 @@ var init_network_maintenance = __esm({
188018
188109
  const latest = await store.get(scope2, "maintenance_run", run.id);
188019
188110
  if (latest && ["awaiting_review", "approved", "publishing", "active"].includes(latest.status)) return latest;
188020
188111
  }
188021
- throw failure;
188112
+ throw failure2;
188022
188113
  }
188023
188114
  }
188024
188115
  async validateAndMaterializeAnalysis(ctx, store, scope2, run, input, analysis, options = {}) {
@@ -188817,10 +188908,10 @@ var init_network_maintenance = __esm({
188817
188908
  run = activationRun;
188818
188909
  return await this.activateGeneration(ctx, store, scope2, run, generation, space, connection);
188819
188910
  } catch (error2) {
188820
- const failure = maintenanceFailure(error2);
188821
- const message = failure.message.slice(0, 2e3);
188911
+ const failure2 = maintenanceFailure(error2);
188912
+ const message = failure2.message.slice(0, 2e3);
188822
188913
  const activation = Boolean(run.stagedAt || run.activationStartedAt);
188823
- const errorCode = activation ? failure.retryable ? "GENERATION_ACTIVATION_TRANSIENT_FAILED" : "GENERATION_ACTIVATION_FAILED" : failure.retryable ? "GENERATION_TRANSIENT_FAILED" : "GENERATION_STAGE_FAILED";
188914
+ const errorCode = activation ? failure2.retryable ? "GENERATION_ACTIVATION_TRANSIENT_FAILED" : "GENERATION_ACTIVATION_FAILED" : failure2.retryable ? "GENERATION_TRANSIENT_FAILED" : "GENERATION_STAGE_FAILED";
188824
188915
  const failedRun = { ...run, status: "failed", errorCode, error: message, retryCount: run.retryCount + 1, updatedAt: this.iso() };
188825
188916
  const failedGeneration = { ...generation, status: "failed", failureCode: errorCode, error: message, updatedAt: this.iso() };
188826
188917
  const saved = await store.transact(scope2, {
@@ -188835,7 +188926,7 @@ var init_network_maintenance = __esm({
188835
188926
  const latest = await store.get(scope2, "maintenance_run", run.id);
188836
188927
  if (latest?.status === "active") return latest;
188837
188928
  }
188838
- throw failure;
188929
+ throw failure2;
188839
188930
  }
188840
188931
  }
188841
188932
  async activateGeneration(ctx, store, scope2, run, generation, space, connection) {
@@ -197862,7 +197953,7 @@ var init_knowledge2 = __esm({
197862
197953
  });
197863
197954
 
197864
197955
  // ../server/src/domains/delegations/parent-conversation.ts
197865
- function firstLine(content3) {
197956
+ function firstLine2(content3) {
197866
197957
  const line = content3.split("\n").map((s2) => s2.trim()).find((s2) => s2.length > 0);
197867
197958
  if (!line) return null;
197868
197959
  return line.length > FIRST_LINE_MAX ? `${line.slice(0, FIRST_LINE_MAX)}\u2026` : line;
@@ -197895,7 +197986,7 @@ function buildParentConversationSnapshot(messages, opts) {
197895
197986
  lines.push(`## \u66F4\u65E9\u7684 ${olderCount} \u8F6E\uFF08\u6BCF\u6761\u53EA\u7559\u9996\u884C\uFF09`, "");
197896
197987
  for (let i = 0; i < fullFrom; i++) {
197897
197988
  for (const m2 of turns[i]) {
197898
- const head = firstLine(m2.content);
197989
+ const head = firstLine2(m2.content);
197899
197990
  if (head) lines.push(`- **${ROLE_LABEL[m2.role]}**\uFF1A${head}`);
197900
197991
  }
197901
197992
  }
@@ -198241,8 +198332,8 @@ function roundRecorded(summaries, dispatchSeq) {
198241
198332
  return summaries.some((s2) => s2.dispatchSeq === void 0 ? s2.round === dispatchSeq + 1 : s2.dispatchSeq === dispatchSeq);
198242
198333
  }
198243
198334
  function taskHeadline(task) {
198244
- const firstLine2 = task.split("\n").map((s2) => s2.trim()).find((s2) => s2.length > 0) ?? "";
198245
- const sentence = firstLine2.split(/[。!?.!?]/)[0]?.trim() || firstLine2;
198335
+ const firstLine3 = task.split("\n").map((s2) => s2.trim()).find((s2) => s2.length > 0) ?? "";
198336
+ const sentence = firstLine3.split(/[。!?.!?]/)[0]?.trim() || firstLine3;
198246
198337
  return sentence.length > TITLE_TASK_CHARS ? sentence.slice(0, TITLE_TASK_CHARS) : sentence;
198247
198338
  }
198248
198339
  function actorSlug(actorId) {
@@ -206652,6 +206743,7 @@ async function startOasisServer(opts) {
206652
206743
  const label = ctx.effectLabel || ctx.command || "";
206653
206744
  return approved ? `\u547D\u4EE4\u5DF2\u7531 ${by} \u6279\u51C6\u5E76\u4EE5\u5176\u540D\u4E49\u6267\u884C${label ? `\uFF1A${label}` : ""}\u3002` : `\u547D\u4EE4\u5DF2\u88AB ${by} \u9A73\u56DE${reason ? `\uFF1A${reason}` : ""}\u3002`;
206654
206745
  };
206746
+ const GRAPH_EDIT_IN_FLIGHT_SUFFIX = "\uFF08\u8FD9\u6761\u662F\u5728\u4F60\u672C\u8F6E\u8FDB\u884C\u4E2D\u63D2\u5165\u7684\u901A\u77E5\uFF1A\u56DE\u5E94\u5B8C\u540E\u63A5\u7740\u505A\u4F60\u624B\u4E0A\u8FD8\u6CA1\u505A\u5B8C\u7684\u4E8B\uFF0C\u522B\u5C31\u6B64\u6536\u5C3E\u3002\uFF09";
206655
206747
  const authorizationResumePrompt = (resolution, ctx) => {
206656
206748
  const approved = resolution.status === "approved";
206657
206749
  const by = ctx.authorizedBy ?? "\u7BA1\u7406\u8005";
@@ -206705,12 +206797,43 @@ async function startOasisServer(opts) {
206705
206797
  await store.markMessageDeliveredToAgent?.(statusMessageId).catch(() => void 0);
206706
206798
  };
206707
206799
  const prompt2 = authorizationResumePrompt(resolution, ctx);
206800
+ const inFlightPrompt = ctx.kind === "graph-edit" ? `${prompt2}${GRAPH_EDIT_IN_FLIGHT_SUFFIX}` : prompt2;
206708
206801
  if (liveChat.isRunning(origin)) {
206709
- const appended = await liveChat.append(origin, prompt2, { system: true }).catch(() => ({ accepted: false }));
206802
+ const appended = await liveChat.append(origin, inFlightPrompt, { system: true }).catch(() => ({ accepted: false }));
206710
206803
  if (appended.accepted) await markDelivered();
206711
206804
  return;
206712
206805
  }
206713
206806
  const sessionCompanyId = session.companyId ?? companyId;
206807
+ let held;
206808
+ let itemStore;
206809
+ try {
206810
+ const turns = (opts.resolveChatTurns ? await opts.resolveChatTurns(sessionCompanyId) : opts.chatTurns) ?? null;
206811
+ itemStore = opts.resolveChatItems ? await opts.resolveChatItems(sessionCompanyId).catch(() => void 0) : opts.chatItems;
206812
+ const opened = await openChatTurn({
206813
+ turns,
206814
+ chatSessionId: origin,
206815
+ source: "internal",
206816
+ log: (m2) => console.warn(m2)
206817
+ });
206818
+ if (!opened.ok) {
206819
+ const appended = await liveChat.append(origin, inFlightPrompt, { system: true }).catch(() => ({ accepted: false }));
206820
+ if (appended.accepted) {
206821
+ await markDelivered();
206822
+ return;
206823
+ }
206824
+ console.warn(
206825
+ `[chat-system-message] \u6388\u6743\u5361\u7EC8\u5C40\u7EED\u8DD1\u672A\u5F00\u8F6E\uFF1A\u4F1A\u8BDD\u69FD\u88AB\u5360\u4E14\u672C\u5B9E\u4F8B\u63D2\u4E0D\u8FDB\uFF0C\u72B6\u6001\u6761\u7559\u4F5C\u5F85\u8865\u6295\uFF08draft=${draftId} session=${origin} company=${sessionCompanyId ?? "(\u9ED8\u8BA4)"} \u5360\u69FD\u8F6E=${opened.activeTurn.id} \u6765\u6E90=${opened.activeTurn.source}\uFF09`
206826
+ );
206827
+ return;
206828
+ }
206829
+ held = opened.turn;
206830
+ } catch (err) {
206831
+ console.error(
206832
+ `[chat-system-message] \u6388\u6743\u5361\u7EC8\u5C40\u7EED\u8DD1\u5360\u4F1A\u8BDD\u69FD\u5931\u8D25\uFF0C\u72B6\u6001\u6761\u7559\u4F5C\u5F85\u8865\u6295\uFF08draft=${draftId} session=${origin} company=${sessionCompanyId ?? "(\u9ED8\u8BA4)"}\uFF09:`,
206833
+ err
206834
+ );
206835
+ return;
206836
+ }
206714
206837
  let dispatched;
206715
206838
  try {
206716
206839
  dispatched = await dispatch({
@@ -206721,6 +206844,11 @@ async function startOasisServer(opts) {
206721
206844
  ...sessionCompanyId ? { companyId: sessionCompanyId } : {}
206722
206845
  });
206723
206846
  } catch (err) {
206847
+ await held?.settle({
206848
+ status: "failed",
206849
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
206850
+ lastError: err instanceof Error ? err.message : String(err)
206851
+ });
206724
206852
  console.error(
206725
206853
  `[chat-system-message] \u6388\u6743\u5361\u7EC8\u5C40\u7EED\u8DD1\u6D3E\u53D1\u5931\u8D25\uFF0C\u72B6\u6001\u6761\u7559\u4F5C\u5F85\u8865\u6295\uFF08draft=${draftId} session=${origin} company=${sessionCompanyId ?? "(\u672A\u5E26\uFF0C\u6309\u9ED8\u8BA4\u516C\u53F8)"}\uFF09:`,
206726
206854
  err
@@ -206744,9 +206872,25 @@ async function startOasisServer(opts) {
206744
206872
  chatStore: store,
206745
206873
  chatSessionId: origin,
206746
206874
  session: bgSession,
206747
- ...resumeOutputsPart ? { outputsPart: resumeOutputsPart } : {}
206875
+ ...resumeOutputsPart ? { outputsPart: resumeOutputsPart } : {},
206876
+ liveChat,
206877
+ liveHandle: {
206878
+ runtimeSessionId: dispatched.id,
206879
+ ...dispatched.runId ? { runId: dispatched.runId } : {},
206880
+ kill: () => {
206881
+ void dispatched.kill?.();
206882
+ },
206883
+ ...dispatched.appendInput ? { appendInput: (input) => dispatched.appendInput(input) } : {},
206884
+ get canAppendInput() {
206885
+ return typeof dispatched.appendInput === "function" && dispatched.canAppendInput !== false;
206886
+ }
206887
+ },
206888
+ ...itemStore ? { itemStore } : {},
206889
+ ...held ? { turnId: held.id } : {}
206748
206890
  });
206891
+ await held?.start({ assistantRunId: dispatched.runId ?? null, dispatchId: dispatched.runId ?? null });
206749
206892
  await markDelivered();
206893
+ void Promise.resolve(dispatched.done).then(() => held?.settle({ status: "succeeded", completedAt: (/* @__PURE__ */ new Date()).toISOString() })).catch((err) => held?.settle({ status: "failed", completedAt: (/* @__PURE__ */ new Date()).toISOString(), lastError: String(err) }));
206750
206894
  };
206751
206895
  const broadcastSeen = /* @__PURE__ */ new Set();
206752
206896
  let _broadcastFlushOwner = null;
@@ -207019,7 +207163,7 @@ async function startOasisServer(opts) {
207019
207163
  }
207020
207164
  },
207021
207165
  ...itemStore ? { itemStore } : {},
207022
- // 广播/委派回流带上 held turn id(B3);授权卡入口在别处,那条路本轮不接账本。
207166
+ // 广播/委派回流带上 held turn id(B3);授权卡续跑(settleAuthorizationStatusLine 第③档)同一口径。
207023
207167
  ...turnId ? { turnId } : {}
207024
207168
  });
207025
207169
  },
@@ -224182,7 +224326,7 @@ var init_list_usage = __esm({
224182
224326
  });
224183
224327
 
224184
224328
  // ../server/src/domains/actors/activity.ts
224185
- function clip(text6) {
224329
+ function clip2(text6) {
224186
224330
  const s2 = typeof text6 === "string" ? text6.trim() : "";
224187
224331
  return s2.length > CLIP ? `${s2.slice(0, CLIP)}\u2026` : s2;
224188
224332
  }
@@ -224205,9 +224349,9 @@ function eventSummary(ev) {
224205
224349
  return { summary: `\u6539\u56FE${parts.length ? `\uFF1A${parts.join("\u3001")}` : ""}`, detail: p2.addNodes?.[0]?.title };
224206
224350
  }
224207
224351
  case "plan.update_spec":
224208
- return { summary: `\u6539\u4EFB\u52A1\u89C4\u683C${p2.title ? `\uFF1A${clip(p2.title)}` : ""}` };
224352
+ return { summary: `\u6539\u4EFB\u52A1\u89C4\u683C${p2.title ? `\uFF1A${clip2(p2.title)}` : ""}` };
224209
224353
  case "plan.add_node":
224210
- return { summary: `\u65B0\u5EFA\u8282\u70B9${p2.title ? `\uFF1A${clip(p2.title)}` : ""}` };
224354
+ return { summary: `\u65B0\u5EFA\u8282\u70B9${p2.title ? `\uFF1A${clip2(p2.title)}` : ""}` };
224211
224355
  case "plan.delete_node":
224212
224356
  return { summary: "\u5220\u9664\u8282\u70B9" };
224213
224357
  case "plan.add_edge":
@@ -224225,7 +224369,7 @@ function eventSummary(ev) {
224225
224369
  case "work.create":
224226
224370
  return { summary: "\u6D3E\u6D3B" };
224227
224371
  case "work.kill":
224228
- return { summary: `\u505C\u6D3E${p2.reason ? `\uFF1A${clip(p2.reason)}` : ""}` };
224372
+ return { summary: `\u505C\u6D3E${p2.reason ? `\uFF1A${clip2(p2.reason)}` : ""}` };
224229
224373
  case "work.response":
224230
224374
  return { summary: p2.outcome === "failed" ? "\u4EA4\u7A3F\uFF08\u5931\u8D25\uFF09" : "\u4EA4\u7A3F" };
224231
224375
  case "work.timeout":
@@ -224237,41 +224381,41 @@ function eventSummary(ev) {
224237
224381
  case "review.create":
224238
224382
  return { summary: "\u5F00\u8BC4\u5BA1" };
224239
224383
  case "review.response":
224240
- return { summary: p2.verdict === "approve" ? "\u8BC4\u5BA1\u901A\u8FC7" : `\u8BC4\u5BA1\u6253\u56DE${p2.note ? `\uFF1A${clip(p2.note)}` : ""}` };
224384
+ return { summary: p2.verdict === "approve" ? "\u8BC4\u5BA1\u901A\u8FC7" : `\u8BC4\u5BA1\u6253\u56DE${p2.note ? `\uFF1A${clip2(p2.note)}` : ""}` };
224241
224385
  case "review.kill":
224242
- return { summary: `\u505C\u8BC4\u5BA1${p2.reason ? `\uFF1A${clip(p2.reason)}` : ""}` };
224386
+ return { summary: `\u505C\u8BC4\u5BA1${p2.reason ? `\uFF1A${clip2(p2.reason)}` : ""}` };
224243
224387
  case "review.timeout":
224244
224388
  return { summary: "\u8BC4\u5BA1\u8D85\u65F6" };
224245
224389
  case "issue.create": {
224246
224390
  switch (p2.issueKind) {
224247
224391
  case "gap":
224248
- return { summary: `\u62A5\u544A gap\uFF1A${clip(p2.body) || "\uFF08\u65E0\u63CF\u8FF0\uFF09"}`, detail: ev.issueId ? `issueId=${ev.issueId}` : void 0 };
224392
+ return { summary: `\u62A5\u544A gap\uFF1A${clip2(p2.body) || "\uFF08\u65E0\u63CF\u8FF0\uFF09"}`, detail: ev.issueId ? `issueId=${ev.issueId}` : void 0 };
224249
224393
  case "escalation":
224250
- return { summary: `\u4E0A\u62A5\u9700\u4EBA\u4ECB\u5165\uFF1A${clip(p2.body) || "\uFF08\u65E0\u539F\u56E0\uFF09"}` };
224394
+ return { summary: `\u4E0A\u62A5\u9700\u4EBA\u4ECB\u5165\uFF1A${clip2(p2.body) || "\uFF08\u65E0\u539F\u56E0\uFF09"}` };
224251
224395
  case "change_request":
224252
- return { summary: `\u53D8\u66F4\u8BF7\u6C42\uFF1A${clip(p2.body) || "\uFF08\u65E0\u63CF\u8FF0\uFF09"}` };
224396
+ return { summary: `\u53D8\u66F4\u8BF7\u6C42\uFF1A${clip2(p2.body) || "\uFF08\u65E0\u63CF\u8FF0\uFF09"}` };
224253
224397
  default:
224254
- return { summary: `\u6279\u6CE8\uFF1A${clip(p2.body) || "\uFF08\u7A7A\uFF09"}` };
224398
+ return { summary: `\u6279\u6CE8\uFF1A${clip2(p2.body) || "\uFF08\u7A7A\uFF09"}` };
224255
224399
  }
224256
224400
  }
224257
224401
  case "issue.reply":
224258
- return { summary: `\u56DE\u590D\u6279\u6CE8\uFF1A${clip(p2.body) || "\uFF08\u7A7A\uFF09"}` };
224402
+ return { summary: `\u56DE\u590D\u6279\u6CE8\uFF1A${clip2(p2.body) || "\uFF08\u7A7A\uFF09"}` };
224259
224403
  case "issue.resolve":
224260
- return { summary: `${p2.state === "resolved" ? "\u89E3\u9664" : "\u5173\u95ED"}${p2.note ? `\uFF1A${clip(p2.note)}` : ""}` };
224404
+ return { summary: `${p2.state === "resolved" ? "\u89E3\u9664" : "\u5173\u95ED"}${p2.note ? `\uFF1A${clip2(p2.note)}` : ""}` };
224261
224405
  case "issue.resolution_proposed":
224262
- return { summary: `\u63D0\u51FA\u5904\u7F6E\u65B9\u6848\uFF1A${clip(p2.proposal) || "\uFF08\u65E0\uFF09"}` };
224406
+ return { summary: `\u63D0\u51FA\u5904\u7F6E\u65B9\u6848\uFF1A${clip2(p2.proposal) || "\uFF08\u65E0\uFF09"}` };
224263
224407
  case "issue.resolution_rejected":
224264
224408
  return { summary: "\u9A73\u56DE\u5904\u7F6E\u65B9\u6848" };
224265
224409
  case "workorder.created":
224266
- return { summary: `\u5EFA\u5DE5\u5355${p2.title ? `\uFF1A${clip(p2.title)}` : ""}` };
224410
+ return { summary: `\u5EFA\u5DE5\u5355${p2.title ? `\uFF1A${clip2(p2.title)}` : ""}` };
224267
224411
  case "workorder.meta_changed":
224268
224412
  return { summary: "\u4FEE\u6539\u5DE5\u5355\u4FE1\u606F" };
224269
224413
  case "workorder.root_set":
224270
224414
  return { summary: "\u8BBE\u5B9A\u6839\u8282\u70B9" };
224271
224415
  case "workorder.sealed":
224272
- return { summary: `\u5C01\u5B58${p2.reason ? `\uFF1A${clip(p2.reason)}` : ""}${p2.note ? `\uFF1A${clip(p2.note)}` : ""}` };
224416
+ return { summary: `\u5C01\u5B58${p2.reason ? `\uFF1A${clip2(p2.reason)}` : ""}${p2.note ? `\uFF1A${clip2(p2.note)}` : ""}` };
224273
224417
  case "workorder.paused":
224274
- return { summary: `\u6682\u505C\u6D3E\u53D1${p2.reason ? `\uFF1A${clip(p2.reason)}` : ""}` };
224418
+ return { summary: `\u6682\u505C\u6D3E\u53D1${p2.reason ? `\uFF1A${clip2(p2.reason)}` : ""}` };
224275
224419
  case "workorder.resumed":
224276
224420
  return { summary: "\u6062\u590D\u6D3E\u53D1" };
224277
224421
  case "work.started":
@@ -224299,27 +224443,27 @@ function summarize3(kind, payload2) {
224299
224443
  switch (kind) {
224300
224444
  case "report_gap":
224301
224445
  return {
224302
- summary: `\u62A5\u544A gap\uFF1A${clip(p2.description) || "\uFF08\u65E0\u63CF\u8FF0\uFF09"}`,
224446
+ summary: `\u62A5\u544A gap\uFF1A${clip2(p2.description) || "\uFF08\u65E0\u63CF\u8FF0\uFF09"}`,
224303
224447
  ...p2.gapId ? { detail: `gapId=${p2.gapId}${p2.part ? `\uFF0Cpart=${p2.part}` : ""}` } : {}
224304
224448
  };
224305
224449
  case "resolve_gap":
224306
- return { summary: `\u89E3\u9664 gap\uFF1A${clip(p2.note) || "\uFF08\u65E0\u8BF4\u660E\uFF09"}`, ...p2.gapId ? { detail: `gapId=${p2.gapId}` } : {} };
224450
+ return { summary: `\u89E3\u9664 gap\uFF1A${clip2(p2.note) || "\uFF08\u65E0\u8BF4\u660E\uFF09"}`, ...p2.gapId ? { detail: `gapId=${p2.gapId}` } : {} };
224307
224451
  case "escalate":
224308
- return { summary: `\u4E0A\u62A5\u9700\u4EBA\u4ECB\u5165\uFF1A${clip(p2.reason) || "\uFF08\u65E0\u539F\u56E0\uFF09"}` };
224452
+ return { summary: `\u4E0A\u62A5\u9700\u4EBA\u4ECB\u5165\uFF1A${clip2(p2.reason) || "\uFF08\u65E0\u539F\u56E0\uFF09"}` };
224309
224453
  case "resolve_escalation":
224310
- return { summary: `\u5173\u95ED\u4E0A\u62A5${p2.note ? `\uFF1A${clip(p2.note)}` : ""}` };
224454
+ return { summary: `\u5173\u95ED\u4E0A\u62A5${p2.note ? `\uFF1A${clip2(p2.note)}` : ""}` };
224311
224455
  case "submit_review":
224312
- return { summary: `${p2.verdict === "approve" ? "\u8BC4\u5BA1\u901A\u8FC7" : "\u8BC4\u5BA1\u6253\u56DE"}${p2.note ? `\uFF1A${clip(p2.note)}` : ""}` };
224456
+ return { summary: `${p2.verdict === "approve" ? "\u8BC4\u5BA1\u901A\u8FC7" : "\u8BC4\u5BA1\u6253\u56DE"}${p2.note ? `\uFF1A${clip2(p2.note)}` : ""}` };
224313
224457
  case "propose_revision":
224314
- return { summary: `\u63D0\u4EA4\u7248\u672C\uFF1A${clip(p2.reason) || "\uFF08\u65E0\u8BF4\u660E\uFF09"}` };
224458
+ return { summary: `\u63D0\u4EA4\u7248\u672C\uFF1A${clip2(p2.reason) || "\uFF08\u65E0\u8BF4\u660E\uFF09"}` };
224315
224459
  case "merge":
224316
224460
  return { summary: "\u5408\u5E76\u7248\u672C\u4E3A\u5F53\u524D" };
224317
224461
  case "conclude":
224318
- return { summary: `\u6536\u5C3E\uFF08\u91CC\u7A0B\u7891\uFF09${p2.note ? `\uFF1A${clip(p2.note)}` : ""}` };
224462
+ return { summary: `\u6536\u5C3E\uFF08\u91CC\u7A0B\u7891\uFF09${p2.note ? `\uFF1A${clip2(p2.note)}` : ""}` };
224319
224463
  case "seal":
224320
- return { summary: `\u5C01\u5B58${p2.reason ? `\uFF1A${clip(p2.reason)}` : ""}${p2.note ? `\uFF1A${clip(p2.note)}` : ""}` };
224464
+ return { summary: `\u5C01\u5B58${p2.reason ? `\uFF1A${clip2(p2.reason)}` : ""}${p2.note ? `\uFF1A${clip2(p2.note)}` : ""}` };
224321
224465
  case "annotate":
224322
- return { summary: `${p2.blocks ? "\u6253\u56DE\u6279\u6CE8\uFF08\u963B\u585E\uFF09" : "\u6279\u6CE8"}\uFF1A${clip(p2.body) || "\uFF08\u7A7A\uFF09"}` };
224466
+ return { summary: `${p2.blocks ? "\u6253\u56DE\u6279\u6CE8\uFF08\u963B\u585E\uFF09" : "\u6279\u6CE8"}\uFF1A${clip2(p2.body) || "\uFF08\u7A7A\uFF09"}` };
224323
224467
  case "resolve_annotation":
224324
224468
  return { summary: "\u89E3\u9664\u6279\u6CE8" };
224325
224469
  case "spawn_artifact":
@@ -224329,9 +224473,9 @@ function summarize3(kind, payload2) {
224329
224473
  case "assign_owner":
224330
224474
  return { summary: "\u53D8\u66F4\u8282\u70B9 owner" };
224331
224475
  case "propose_intervention":
224332
- return { summary: `\u8D77\u8349\u6539\u56FE\u63D0\u6848${p2.reason ? `\uFF1A${clip(p2.reason)}` : ""}` };
224476
+ return { summary: `\u8D77\u8349\u6539\u56FE\u63D0\u6848${p2.reason ? `\uFF1A${clip2(p2.reason)}` : ""}` };
224333
224477
  case "reject_intervention":
224334
- return { summary: `\u9A73\u56DE\u6539\u56FE\u63D0\u6848${p2.reason ? `\uFF1A${clip(p2.reason)}` : ""}` };
224478
+ return { summary: `\u9A73\u56DE\u6539\u56FE\u63D0\u6848${p2.reason ? `\uFF1A${clip2(p2.reason)}` : ""}` };
224335
224479
  default:
224336
224480
  return { summary: kind };
224337
224481
  }
@@ -229375,8 +229519,8 @@ async function buildChatPreview(chatStore, sessionId, who) {
229375
229519
  const lastUser = [...msgs].reverse().find((m2) => m2.role === "user" && m2.content.trim().length > 0);
229376
229520
  const lastAsst = [...msgs].reverse().find((m2) => m2.role === "assistant" && m2.content.trim().length > 0);
229377
229521
  const lines = [];
229378
- if (lastUser) lines.push({ label: "\u4F60", text: clip2(lastUser.content) });
229379
- if (lastAsst) lines.push({ label: who, text: clip2(lastAsst.content) });
229522
+ if (lastUser) lines.push({ label: "\u4F60", text: clip3(lastUser.content) });
229523
+ if (lastAsst) lines.push({ label: who, text: clip3(lastAsst.content) });
229380
229524
  return lines.length ? { lines } : void 0;
229381
229525
  }
229382
229526
  async function buildChatInbox(chatStore, markers, me, resolveActor, excludeChildSessions) {
@@ -229410,14 +229554,14 @@ async function buildChatInbox(chatStore, markers, me, resolveActor, excludeChild
229410
229554
  }
229411
229555
  return out;
229412
229556
  }
229413
- var PREVIEW_MAX_CHARS, PREVIEW_FETCH_CAP, clip2;
229557
+ var PREVIEW_MAX_CHARS, PREVIEW_FETCH_CAP, clip3;
229414
229558
  var init_inbox_chat = __esm({
229415
229559
  "../server/src/domains/collab/inbox-chat.ts"() {
229416
229560
  "use strict";
229417
229561
  init_src();
229418
229562
  PREVIEW_MAX_CHARS = 200;
229419
229563
  PREVIEW_FETCH_CAP = 25;
229420
- clip2 = (s2) => {
229564
+ clip3 = (s2) => {
229421
229565
  const t = (s2 ?? "").trim();
229422
229566
  return t.length > PREVIEW_MAX_CHARS ? `${t.slice(0, PREVIEW_MAX_CHARS)}\u2026` : t;
229423
229567
  };
@@ -264156,7 +264300,9 @@ function buildChatExitError(info) {
264156
264300
  if (!detail && info.transcriptRef) detail = transcriptTail(info.transcriptRef);
264157
264301
  }
264158
264302
  const firstDetailLine = detail.split("\n").map((line) => line.trim()).find(Boolean) ?? "";
264159
- const summary = (info.reason ? SUMMARY_BY_REASON[info.reason] : void 0) ?? (firstDetailLine ? `\u5BF9\u8BDD\u5931\u8D25\uFF1A${firstDetailLine.slice(0, 200)}` : `\u5BF9\u8BDD\u5931\u8D25\uFF08${genericLine}\uFF09`);
264303
+ const firstErrorLine = info.errorMessage?.split("\n").map((line) => line.trim()).find(Boolean) ?? "";
264304
+ const fixed = info.reason ? SUMMARY_BY_REASON[info.reason] : void 0;
264305
+ const summary = fixed ? firstErrorLine && info.reason !== "cancelled" && info.reason !== "timeout" ? `${fixed}\uFF1A${firstErrorLine.slice(0, 200)}` : fixed : firstDetailLine ? `\u5BF9\u8BDD\u5931\u8D25\uFF1A${firstDetailLine.slice(0, 200)}` : `\u5BF9\u8BDD\u5931\u8D25\uFF08${genericLine}\uFF09`;
264160
264306
  const chatExit = {
264161
264307
  ...info.reason ? { reason: info.reason } : {},
264162
264308
  summary,
@@ -274710,9 +274856,9 @@ var GROUP_ORDER = [
274710
274856
  "\u5B58\u91CF\u7BA1\u7406"
274711
274857
  ];
274712
274858
  function indexSummary(description) {
274713
- const firstLine2 = description.split("\n")[0] ?? "";
274714
- const dot = firstLine2.indexOf("\u3002");
274715
- const head = dot >= 0 ? firstLine2.slice(0, dot + 1) : firstLine2;
274859
+ const firstLine3 = description.split("\n")[0] ?? "";
274860
+ const dot = firstLine3.indexOf("\u3002");
274861
+ const head = dot >= 0 ? firstLine3.slice(0, dot + 1) : firstLine3;
274716
274862
  return head.replace(/\*\*/g, "").trim();
274717
274863
  }
274718
274864
  function buildCommandIndex() {
@@ -278589,7 +278735,7 @@ function shimScript() {
278589
278735
  }
278590
278736
 
278591
278737
  // src/index.ts
278592
- var PKG_VERSION = true ? "2.2.42" : "dev";
278738
+ var PKG_VERSION = true ? "2.2.44" : "dev";
278593
278739
  var LOCAL_BIN = localBin();
278594
278740
  var NPM_PREFIX = npmPrefix();
278595
278741
  var INSTANCE = DEFAULT_INSTANCE;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oasis_test_v2",
3
- "version": "2.2.42",
3
+ "version": "2.2.44",
4
4
  "description": "Oasis node daemon + CLI — background daemon, auto-start, full server CLI",
5
5
  "bin": {
6
6
  "oasis": "./dist/index.js"
@@ -26,6 +26,6 @@
26
26
  "node": ">=20"
27
27
  },
28
28
  "oasisRelease": {
29
- "sourceHead": "0f4fa607e6e47a8a8df2194a3a42b194fef3ef0b"
29
+ "sourceHead": "91d9408678684a3e8cb17fdae1fdc0b7772cdcb4"
30
30
  }
31
31
  }