@sema-agent/core 1.435.0 → 1.436.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.
@@ -5,6 +5,7 @@ import { type ExecutionEnv } from "../internal/harness.js";
5
5
  import type { RunInternals } from "../core/runner/prepare-task.js";
6
6
  import type { TaskNotificationPayload } from "../core/task-notification.js";
7
7
  export type { SubagentStep, SubagentEditedFile } from "./subagent-steps.js";
8
+ export declare function notifyResultField(result: string | undefined): string | undefined;
8
9
  export declare function inheritedManifestScopeFor(snapshot: readonly unknown[] | undefined): RunInternals["inheritedManifestScope"];
9
10
  export declare const DEFAULT_SUBAGENT_TOOL_NAME = "Agent";
10
11
  export declare const LEGACY_SUBAGENT_TOOL_NAME = "Task";
@@ -12,6 +12,7 @@ import { SUBAGENT_PROMPT } from "../prompts/default.js";
12
12
  import { hasSessionFork } from "../core/session.js";
13
13
  import { isDurablePause } from "./suspend-guard.js";
14
14
  import { delimitUntrusted, inlineUntrusted } from "../core/untrusted-text.js";
15
+ import { boundedRedactedSummary } from "../core/untrusted-egress.js";
15
16
  import { uuidv7 } from "../internal/harness.js";
16
17
  import { addWorktree } from "../core/git-worktree-env.js";
17
18
  import { BG_AGENT_REAP_STOP_ERROR, DURABLE_AGENT_HANDLE_RE, DURABLE_AGENT_HEARTBEAT_MS, normalizeAgentName } from "../core/task-registry.js";
@@ -19,6 +20,23 @@ import { canAccessAgentRecord } from "../core/background-agent-store.js";
19
20
  import { extractErrorCode } from "../brain/errors.js";
20
21
  import { ObserverDigestTap, ObserverPairing, createObserverReportToolSpec, markObserverTaskId, unmarkObserverTaskId, isObserverTaskId, observerFramingPrompt, observerSlug, resolveObserverDeclaration, OBSERVER_SENDMESSAGE_SENDER_REFUSAL, OBSERVER_SENDMESSAGE_TARGET_REFUSAL, } from "./observer.js";
21
22
  import { SubagentStepRecorder, stepsFromMessages } from "./subagent-steps.js";
23
+ const BG_AGENT_RESULT_MAX = 4_000;
24
+ const BG_AGENT_RESULT_FULL_MAX = 200_000;
25
+ function resultSettleFields(result) {
26
+ if (!result)
27
+ return {};
28
+ const full = boundedRedactedSummary(result, BG_AGENT_RESULT_FULL_MAX);
29
+ const display = full.length > BG_AGENT_RESULT_MAX ? boundedRedactedSummary(result, BG_AGENT_RESULT_MAX) : full;
30
+ return display === full ? { result: display } : { result: display, resultFull: full };
31
+ }
32
+ const BG_AGENT_NOTIFY_RESULT_MAX = 2_000;
33
+ export function notifyResultField(result) {
34
+ if (!result)
35
+ return undefined;
36
+ return result.length > BG_AGENT_NOTIFY_RESULT_MAX
37
+ ? `${result.slice(0, BG_AGENT_NOTIFY_RESULT_MAX)}\n[result truncated: ${result.length} chars total — call TaskOutput for the full text]`
38
+ : result;
39
+ }
22
40
  export function inheritedManifestScopeFor(snapshot) {
23
41
  if (!snapshot || snapshot.length === 0)
24
42
  return undefined;
@@ -610,7 +628,7 @@ function makeSubagentResume(deps) {
610
628
  try {
611
629
  const winner = deps.registry.settleRevivedAgent(deps.taskId, reviveCycle, {
612
630
  status,
613
- ...(child.result ? { result: child.result.slice(0, 2_000) } : {}),
631
+ ...resultSettleFields(child.result),
614
632
  ...(status !== "completed" ? { error: (child.errorMessage ?? `resumed run ${status}`).slice(0, 500) } : {}),
615
633
  });
616
634
  if (winner !== undefined)
@@ -644,7 +662,7 @@ function makeSubagentResume(deps) {
644
662
  ...(stoppedByRevive !== undefined ? { stoppedBy: stoppedByRevive } : {}),
645
663
  seq: entry.cycleSeq,
646
664
  summary: `Agent "${reviveName}" (resumed) ${status === "killed" ? "stopped" : child.status === "completed" ? "finished" : String(child.status)}${ccElapsedTag(Date.now() - reviveStartedAt)}`,
647
- ...(child.result ? { result: child.result.slice(0, 2_000) } : {}),
665
+ ...(child.result ? { result: notifyResultField(child.result) } : {}),
648
666
  ...(status === "killed" && child.result ? { partial: true } : {}),
649
667
  ...resumeResidual(),
650
668
  resumable: status !== "killed",
@@ -1771,7 +1789,7 @@ function makeSubagentTool(opts, depth, excluded, extraToolsBudget) {
1771
1789
  const reapedBg = !okBg && abort.signal.aborted;
1772
1790
  const settledBg = bg.registry.settleBackgroundAgent(taskId, {
1773
1791
  status: okBg ? "completed" : reapedBg ? "killed" : "failed",
1774
- ...(child.result ? { result: child.result.slice(0, 4_000) } : {}),
1792
+ ...resultSettleFields(child.result),
1775
1793
  ...(!okBg ? { error: reapedBg ? BG_AGENT_REAP_STOP_ERROR : child.errorMessage ?? String(child.status) } : {}),
1776
1794
  }) ?? (abort.signal.aborted ? "killed" : okBg ? "completed" : "failed");
1777
1795
  const stoppedByBg = settledBg === "killed" ? bg.registry.getStopAttribution(taskId) ?? "system" : undefined;
@@ -1809,7 +1827,7 @@ function makeSubagentTool(opts, depth, excluded, extraToolsBudget) {
1809
1827
  ...(stoppedByBg !== undefined ? { stoppedBy: stoppedByBg } : {}),
1810
1828
  summary: `${ccCompletionText(shortDesc, settledBg, String(child.status), Date.now() - forkBgStartedAt)}`,
1811
1829
  ...(child.sessionId ? { sessionId: child.sessionId } : {}),
1812
- ...(child.result ? { result: child.result.slice(0, 2_000) } : {}),
1830
+ ...(child.result ? { result: notifyResultField(child.result) } : {}),
1813
1831
  ...(settledBg === "killed" && child.result ? { partial: true } : {}),
1814
1832
  ...residualFork,
1815
1833
  resumable: resumableFork,
@@ -2347,7 +2365,7 @@ task_id: ${taskId}
2347
2365
  const settled = bg.registry.settleBackgroundAgent(taskId, {
2348
2366
  status: ok ? "completed" : reaped ? "killed" : "failed",
2349
2367
  seq: seqAtSettle ?? 1,
2350
- ...(child.result ? { result: child.result.slice(0, 4_000) } : {}),
2368
+ ...resultSettleFields(child.result),
2351
2369
  ...(!ok ? { error: reaped ? BG_AGENT_REAP_STOP_ERROR : child.errorMessage ?? String(child.status) } : {}),
2352
2370
  }) ??
2353
2371
  (abort.signal.aborted ? "killed" : ok ? "completed" : "failed");
@@ -2386,7 +2404,7 @@ task_id: ${taskId}
2386
2404
  ...(stoppedBy !== undefined ? { stoppedBy } : {}),
2387
2405
  summary: `${ccCompletionText(shortDesc, settled, String(child.status), Date.now() - bgStartedAt)}${observerNote}`,
2388
2406
  ...(child.sessionId ? { sessionId: child.sessionId } : {}),
2389
- ...(child.result ? { result: child.result.slice(0, 2_000) } : {}),
2407
+ ...(child.result ? { result: notifyResultField(child.result) } : {}),
2390
2408
  ...(settled === "killed" && child.result ? { partial: true } : {}),
2391
2409
  ...residual,
2392
2410
  resumable: resumableBg,
@@ -34,6 +34,7 @@ export interface BackgroundAgentRecord {
34
34
  parkClaimId?: string;
35
35
  summary?: string;
36
36
  finalOutput?: string;
37
+ finalOutputFull?: string;
37
38
  error?: string;
38
39
  resultIsPartial?: boolean;
39
40
  recentSteps?: SubagentStep[];
@@ -97,6 +97,7 @@ interface BackgroundAgentTaskHandle extends SemaTaskHandle {
97
97
  name?: string;
98
98
  sessionScoped?: true;
99
99
  result?: string;
100
+ resultFull?: string;
100
101
  error?: string;
101
102
  resultIsPartial?: boolean;
102
103
  stopSource?: StopSource;
@@ -291,6 +292,7 @@ export declare class TaskRegistry {
291
292
  settleBackgroundAgent(id: string, outcome: {
292
293
  status: "completed" | "failed" | "killed";
293
294
  result?: string;
295
+ resultFull?: string;
294
296
  error?: string;
295
297
  stoppedBy?: StopSource;
296
298
  seq?: number;
@@ -353,6 +355,7 @@ export declare class TaskRegistry {
353
355
  settleRevivedAgent(id: string, cycle: number, outcome: {
354
356
  status: "completed" | "failed" | "killed";
355
357
  result?: string;
358
+ resultFull?: string;
356
359
  error?: string;
357
360
  }): "completed" | "failed" | "killed" | undefined;
358
361
  unmarkRetainedContinuation(id: string): void;
@@ -1074,6 +1074,8 @@ export class TaskRegistry {
1074
1074
  handle.result = outcome.result;
1075
1075
  handle.resultIsPartial = true;
1076
1076
  backfilled = true;
1077
+ if (outcome.resultFull !== undefined)
1078
+ handle.resultFull = outcome.resultFull;
1077
1079
  }
1078
1080
  if (handle.error === undefined && outcome.error !== undefined && outcome.error !== BG_AGENT_REAP_STOP_ERROR) {
1079
1081
  handle.error = outcome.error;
@@ -1083,6 +1085,7 @@ export class TaskRegistry {
1083
1085
  handle.updatedAt = Date.now();
1084
1086
  this.durableAgentWrite(handle, {
1085
1087
  ...(handle.result !== undefined ? { finalOutput: handle.result } : {}),
1088
+ ...(handle.resultFull !== undefined ? { finalOutputFull: handle.resultFull } : {}),
1086
1089
  ...(handle.resultIsPartial ? { resultIsPartial: true } : {}),
1087
1090
  ...(handle.error !== undefined ? { error: handle.error } : {}),
1088
1091
  });
@@ -1103,6 +1106,8 @@ export class TaskRegistry {
1103
1106
  }
1104
1107
  if (outcome.result !== undefined)
1105
1108
  handle.result = outcome.result;
1109
+ if (outcome.resultFull !== undefined)
1110
+ handle.resultFull = outcome.resultFull;
1106
1111
  if (outcome.status === "killed" && outcome.result !== undefined && outcome.result !== "") {
1107
1112
  handle.resultIsPartial = true;
1108
1113
  }
@@ -1119,6 +1124,7 @@ export class TaskRegistry {
1119
1124
  settledAt: Date.now(),
1120
1125
  ...(handle.stoppedBy !== undefined ? { stoppedBy: handle.stoppedBy } : {}),
1121
1126
  ...(handle.result !== undefined ? { finalOutput: handle.result } : {}),
1127
+ ...(handle.resultFull !== undefined ? { finalOutputFull: handle.resultFull } : {}),
1122
1128
  ...(handle.resultIsPartial ? { resultIsPartial: true } : {}),
1123
1129
  ...(handle.error !== undefined ? { error: handle.error } : {}),
1124
1130
  }, ["parkedCheckpointToken", "parkClaimId", "parkedAt"]);
@@ -1841,7 +1847,7 @@ The agent is durably suspended, waiting for an approval decision. It resumes whe
1841
1847
  const body = `status: ${row.status}
1842
1848
  ${row.error ? `error: ${row.error}
1843
1849
  ` : ""}${row.finalOutput ? `--- result${row.resultIsPartial ? " (partial — produced before the task was stopped)" : ""} ---
1844
- ${clipTaskOutput(row.finalOutput)}` : "(no result text)"}`;
1850
+ ${clipTaskOutput(row.finalOutputFull ?? row.finalOutput)}` : "(no result text)"}`;
1845
1851
  return {
1846
1852
  content: delimitUntrusted(`TaskOutput ${row.handle}`, body),
1847
1853
  details: {
@@ -2019,13 +2025,14 @@ ${clipTaskOutput(row.finalOutput)}` : "(no result text)"}`;
2019
2025
  if (abort !== undefined)
2020
2026
  handle.abort = abort;
2021
2027
  handle.result = undefined;
2028
+ handle.resultFull = undefined;
2022
2029
  handle.error = undefined;
2023
2030
  handle.resultIsPartial = undefined;
2024
2031
  handle.stopSource = undefined;
2025
2032
  handle.reviveCycle = (handle.reviveCycle ?? 0) + 1;
2026
2033
  handle.cycleSeq = (handle.cycleSeq ?? 1) + 1;
2027
2034
  handle.updatedAt = Date.now();
2028
- this.durableAgentWrite(handle, { status: "running" }, ["settledAt", "stoppedBy", "finalOutput", "error", "resultIsPartial", "summary", "recentSteps", "editedFiles", "usage"]);
2035
+ this.durableAgentWrite(handle, { status: "running" }, ["settledAt", "stoppedBy", "finalOutput", "finalOutputFull", "error", "resultIsPartial", "summary", "recentSteps", "editedFiles", "usage"]);
2029
2036
  return { ok: true, cycle: handle.reviveCycle };
2030
2037
  }
2031
2038
  settleRevivedAgent(id, cycle, outcome) {
@@ -2579,7 +2586,7 @@ The agent is still working — you will be notified when it completes.`
2579
2586
  : `status: ${handle.status}
2580
2587
  ${handle.error ? `error: ${handle.error}
2581
2588
  ` : ""}${handle.result ? `--- result${handle.resultIsPartial ? " (partial — produced before the task was stopped)" : ""} ---
2582
- ${clipTaskOutput(handle.result, handle.outputFile)}` : "(no result text)"}`;
2589
+ ${clipTaskOutput(handle.resultFull ?? handle.result, handle.outputFile)}` : "(no result text)"}`;
2583
2590
  return {
2584
2591
  content: delimitUntrusted(`TaskOutput ${handle.id}`, body),
2585
2592
  details: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/core",
3
- "version": "1.435.0",
3
+ "version": "1.436.2",
4
4
  "description": "Stateless, task-oriented AI agent core",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",