deepagents 1.13.4-rc.0 → 1.13.5

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.
@@ -1,4 +1,4 @@
1
- import { AIMessage, HumanMessage, SystemMessage, ToolMessage, anthropicPromptCachingMiddleware, bedrockPromptCachingMiddleware, context, countTokensApproximately, createAgent, createMiddleware, humanInTheLoopMiddleware, omitPayload, todoListMiddleware, tool } from "langchain";
1
+ import { AIMessage, HumanMessage, SystemMessage, ToolMessage, anthropicPromptCachingMiddleware, bedrockPromptCachingMiddleware, context, countTokensApproximately, createAgent, createMiddleware, humanInTheLoopMiddleware, todoListMiddleware, tool } from "langchain";
2
2
  import { Command, REMOVE_ALL_MESSAGES, ReducedValue, StateSchema, getConfig, getCurrentTaskInput, getStore, isCommand } from "@langchain/langgraph";
3
3
  import { z } from "zod/v4";
4
4
  import micromatch from "micromatch";
@@ -206,6 +206,21 @@ function formatContentWithLineNumbers(content, startLine = 1) {
206
206
  return formatContentWithLineNumbersAndBoundaries(content, startLine).text;
207
207
  }
208
208
  /**
209
+ * Join file content into the unmodified source body of a `read_file` result.
210
+ *
211
+ * Source lines are emitted unchanged, with no numbering. A status header
212
+ * carries the line-range metadata separately, so nothing here needs to
213
+ * encode line numbers or escape anything.
214
+ */
215
+ function formatSourceBlock(content) {
216
+ let lines;
217
+ if (typeof content === "string") {
218
+ lines = content.split("\n");
219
+ if (lines.length > 0 && lines[lines.length - 1] === "") lines = lines.slice(0, -1);
220
+ } else lines = content;
221
+ return lines.join("\n");
222
+ }
223
+ /**
209
224
  * Check if content is empty and return warning message.
210
225
  *
211
226
  * @param content - Content to check
@@ -1539,7 +1554,6 @@ var CompositeBackend = class {
1539
1554
  * - Pluggable backends (StateBackend, StoreBackend, FilesystemBackend, CompositeBackend)
1540
1555
  * - Tool result eviction for large outputs
1541
1556
  */
1542
- const INT_FORMATTER = new Intl.NumberFormat("en-US");
1543
1557
  /**
1544
1558
  * Normalizes tool input so that models sending `path` instead of `file_path`
1545
1559
  * still work. If the input has `path` but not `file_path`, copies `path` into
@@ -1609,29 +1623,100 @@ const READ_FILE_TRUNCATION_MSG = `
1609
1623
 
1610
1624
  [Output was truncated due to size limits. The file content is very large. Consider reformatting the file to make it easier to navigate. For example, if this is JSON, use execute(command='jq . {file_path}') to pretty-print it with line breaks. For other formats, you can use appropriate formatting tools to split long lines.]`;
1611
1625
  /**
1612
- * Render backend pagination metadata as guidance for the model.
1626
+ * Describe the window a read returned, as status header fields.
1613
1627
  *
1614
1628
  * Backends own source-level pagination because only they know how much of the
1615
- * file was read. The middleware owns presentation: it line-numbers the text
1616
- * and turns optional metadata into a human-readable footer. Keeping the fields
1617
- * optional preserves compatibility with custom backends that predate this
1618
- * contract; those reads simply receive no pagination footer.
1629
+ * file was read. The middleware owns presentation: it renders the source
1630
+ * unmodified and turns optional metadata into a terse header. Keeping the
1631
+ * fields optional preserves compatibility with custom backends that predate
1632
+ * this contract — `prepareReadWindow` derives a range for those instead.
1619
1633
  *
1620
- * `nextOffset` is the signal that the read is partial. A result at EOF omits it,
1621
- * so complete reads retain their previous output shape.
1634
+ * Returns the `lines A-B[ of T]` field, followed by `next offset N` when the
1635
+ * window stopped short of the end of the file.
1622
1636
  */
1623
- function remainingLinesNotice(readResult) {
1637
+ function describeReadWindow(readResult) {
1624
1638
  const { startLine, endLine, nextOffset, totalLines } = readResult;
1625
- if (startLine === void 0 || endLine === void 0 || nextOffset === void 0 || !Number.isSafeInteger(startLine) || !Number.isSafeInteger(endLine) || !Number.isSafeInteger(nextOffset) || startLine < 1 || endLine < startLine || nextOffset !== endLine || totalLines !== void 0 && (!Number.isSafeInteger(totalLines) || totalLines < endLine)) return "";
1626
- const readCount = endLine - startLine + 1;
1627
- const readUnit = readCount === 1 ? "line" : "lines";
1628
- if (totalLines === void 0) return `\n\n[Read ${readCount} ${readUnit} (lines ${startLine}-${endLine}). More lines remain from offset ${nextOffset}.]`;
1629
- if (endLine >= totalLines) return "";
1630
- const remaining = totalLines - endLine;
1631
- return `\n\n[Read ${readCount} ${readUnit} (lines ${startLine}-${endLine} of ${totalLines} total). ${remaining} ${remaining === 1 ? "line" : "lines"} remaining from offset ${nextOffset}.]`;
1639
+ if (startLine === void 0 || endLine === void 0 || !Number.isSafeInteger(startLine) || !Number.isSafeInteger(endLine) || startLine < 1 || endLine < startLine || totalLines !== void 0 && (!Number.isSafeInteger(totalLines) || totalLines < endLine)) return [];
1640
+ let span = `lines ${startLine}-${endLine}`;
1641
+ if (totalLines !== void 0) span += ` of ${totalLines}`;
1642
+ const fields = [span];
1643
+ if (nextOffset !== void 0 && (totalLines === void 0 || endLine < totalLines)) fields.push(`next offset ${nextOffset}`);
1644
+ return fields;
1645
+ }
1646
+ /** Render the status header that sits above a text `read_file` result. */
1647
+ function readHeader(fields) {
1648
+ return `@@ ${fields.join(" | ")} @@`;
1649
+ }
1650
+ /** Notice disclosing that a negative `offset` was reinterpreted as the start of the file, or `undefined` for a non-negative offset. */
1651
+ function clampedOffsetNotice(offset) {
1652
+ if (offset >= 0) return;
1653
+ return `[Requested offset ${offset} is before the start of the file; read from line 1 instead.]`;
1632
1654
  }
1633
1655
  /**
1634
- * Fit a line-numbered read into the middleware's output budget without
1656
+ * Compose a read result from its notices, status header, and source body.
1657
+ *
1658
+ * Notices sit above the header, so every line below it is unmodified file
1659
+ * content and consumers (including `stripLineNumbers` in the quickjs
1660
+ * provider) can tell the two apart by position.
1661
+ */
1662
+ function assembleRead(body, options) {
1663
+ const { fields, notices = [] } = options;
1664
+ return [
1665
+ ...notices,
1666
+ readHeader(fields),
1667
+ body
1668
+ ].join("\n");
1669
+ }
1670
+ /** Derives a header range from `offset` when the backend left `startLine`/`endLine` unset. */
1671
+ function prepareReadWindow(readResult, content, offset) {
1672
+ const body = formatSourceBlock(content);
1673
+ if (readResult.startLine !== void 0 && readResult.endLine !== void 0) return {
1674
+ readResult,
1675
+ body
1676
+ };
1677
+ const startLine = offset + 1;
1678
+ const endLine = startLine + body.split("\n").length - 1;
1679
+ return {
1680
+ readResult: {
1681
+ ...readResult,
1682
+ startLine,
1683
+ endLine
1684
+ },
1685
+ body
1686
+ };
1687
+ }
1688
+ /**
1689
+ * Assemble a read cut inside a single source line too long to fit.
1690
+ *
1691
+ * No offset reaches the remainder of such a line, so the header reports how
1692
+ * much of it is shown in place of a resume point.
1693
+ */
1694
+ function midlineTruncatedRead(body, readResult, threshold, notices) {
1695
+ const newlineIdx = body.indexOf("\n");
1696
+ const oversized = newlineIdx === -1 ? body.length : newlineIdx;
1697
+ const clipped = {
1698
+ totalLines: readResult.totalLines,
1699
+ startLine: readResult.startLine,
1700
+ endLine: readResult.startLine,
1701
+ nextOffset: void 0
1702
+ };
1703
+ const fieldsFor = (shown) => [
1704
+ ...describeReadWindow(clipped),
1705
+ "truncated mid-line",
1706
+ `${shown} of ${oversized} chars`
1707
+ ];
1708
+ const reserved = assembleRead("", {
1709
+ fields: fieldsFor(oversized),
1710
+ notices
1711
+ }).length;
1712
+ const shown = Math.max(0, Math.min(oversized, threshold - reserved));
1713
+ return assembleRead(body.slice(0, shown), {
1714
+ fields: fieldsFor(shown),
1715
+ notices
1716
+ });
1717
+ }
1718
+ /**
1719
+ * Fit a paginated read into the middleware's output budget without
1635
1720
  * publishing a resume offset that skips content the model did not see.
1636
1721
  *
1637
1722
  * There are two independent forms of limiting:
@@ -1642,38 +1727,50 @@ function remainingLinesNotice(readResult) {
1642
1727
  * If the backend returned lines 1-100 but the middleware only displayed lines
1643
1728
  * 1-30, forwarding the backend's original `nextOffset: 100` would silently skip
1644
1729
  * lines 31-100 on the next read. This function therefore truncates only after a
1645
- * complete source line and rebuilds the remaining-lines notice using the last
1646
- * line actually displayed.
1647
- *
1648
- * Long source lines may occupy several formatted rows (`12`, `12.1`, ...). The
1649
- * formatter records a structured boundary only after the final chunk, so this
1650
- * function does not need to inspect or understand the gutter representation.
1651
- * If no complete source line can fit beside the truncation message, the function
1652
- * falls back to character truncation and omits pagination guidance rather than
1653
- * advertising an unsafe offset.
1654
- */
1655
- function truncatePaginatedRead(formatted, filePath, readResult, tokenLimit) {
1656
- const content = formatted.text;
1657
- const notice = remainingLinesNotice(readResult);
1658
- if (!tokenLimit || content.length + notice.length < 4 * tokenLimit) return content + notice;
1659
- const truncationMsg = READ_FILE_TRUNCATION_MSG.replace("{file_path}", filePath);
1730
+ * complete source line and rebuilds the header from the last line actually
1731
+ * displayed. If no complete source line fits alongside the truncation
1732
+ * message, it falls back to `midlineTruncatedRead`, which reports exactly how
1733
+ * much of the oversized line is shown rather than guessing at a resume point.
1734
+ */
1735
+ function truncatePaginatedRead(body, readResult, options) {
1736
+ const { filePath, tokenLimit, notices = [] } = options;
1737
+ const result = assembleRead(body, {
1738
+ fields: describeReadWindow(readResult),
1739
+ notices
1740
+ });
1741
+ if (!tokenLimit || result.length < 4 * tokenLimit) return result;
1742
+ const truncationMsg = READ_FILE_TRUNCATION_MSG.replace("{file_path}", filePath).trim();
1660
1743
  const threshold = 4 * tokenLimit;
1661
1744
  if (readResult.startLine !== void 0 && readResult.endLine !== void 0) {
1662
- const finalSourceLine = readResult.endLine;
1663
- const boundaries = formatted.sourceLineBoundaries.filter((boundary) => boundary.sourceLine <= finalSourceLine);
1745
+ const rows = body.split("\n");
1746
+ let position = 0;
1747
+ const boundaries = [];
1748
+ for (let index = 0; index < rows.length; index += 1) {
1749
+ const sourceLine = readResult.startLine + index;
1750
+ if (sourceLine > readResult.endLine) break;
1751
+ position += rows[index].length;
1752
+ boundaries.push({
1753
+ endOffset: position,
1754
+ endLine: sourceLine
1755
+ });
1756
+ position += 1;
1757
+ }
1664
1758
  for (let index = boundaries.length - 1; index >= 0; index -= 1) {
1665
- const boundary = boundaries[index];
1666
- const adjustedNotice = remainingLinesNotice({
1759
+ const { endOffset, endLine } = boundaries[index];
1760
+ const adjustedResult = {
1667
1761
  totalLines: readResult.totalLines,
1668
1762
  startLine: readResult.startLine,
1669
- endLine: boundary.sourceLine,
1670
- nextOffset: boundary.sourceLine
1763
+ endLine,
1764
+ nextOffset: endLine
1765
+ };
1766
+ const candidate = assembleRead(body.slice(0, endOffset), {
1767
+ fields: [...describeReadWindow(adjustedResult), "truncated due to size"],
1768
+ notices: [...notices, truncationMsg]
1671
1769
  });
1672
- if (boundary.endOffset + truncationMsg.length + adjustedNotice.length <= threshold) return content.slice(0, boundary.endOffset) + truncationMsg + adjustedNotice;
1770
+ if (candidate.length <= threshold) return candidate;
1673
1771
  }
1674
1772
  }
1675
- const maxContentLength = Math.max(0, threshold - truncationMsg.length);
1676
- return content.substring(0, maxContentLength) + truncationMsg;
1773
+ return midlineTruncatedRead(body, readResult, threshold, [...notices, truncationMsg]);
1677
1774
  }
1678
1775
  /**
1679
1776
  * Note appended to grep results that were cut short by the match-count cap.
@@ -2069,8 +2166,7 @@ const READ_FILE_TOOL_DESCRIPTION = context`
2069
2166
 
2070
2167
  Usage:
2071
2168
  - By default, it reads up to ${100} lines starting from the beginning of the file. Use \`offset\`/\`limit\` to page through large files instead of reading them whole.
2072
- - Results are returned with line numbers starting at \`offset\` + 1 (1 by default), then two spaces, then the source line. Never include these line-number prefixes when editing.
2073
- - Lines over ${INT_FORMATTER.format(MAX_LINE_LENGTH)} characters are split with continuation markers (e.g. 5.1, 5.2); \`limit\` counts source lines, so continuation rows do not consume the budget.
2169
+ - A status header, \`@@ field | field | ... @@\`, sits above the file content, and every line after it is unmodified file content. When content is truncated, there may be an explanation before the header. Never include the header when editing.
2074
2170
  - Speculatively batch multiple \`read_file\` calls in one response when several files may be useful.
2075
2171
  - An empty file returns a system-reminder warning in place of contents.
2076
2172
  - Large tool results may be offloaded to a file; the tool message gives the path. Read that path here, paging with \`offset\`/\`limit\`.
@@ -2090,7 +2186,7 @@ const EDIT_FILE_TOOL_DESCRIPTION = context`
2090
2186
 
2091
2187
  Usage:
2092
2188
  - You must read the file before editing; this tool errors otherwise.
2093
- - Preserve the exact indentation from the read output, and never include line-number prefixes in old_string or new_string.
2189
+ - Preserve the exact source indentation from the read output, and never include the read status header in old_string or new_string.
2094
2190
  - Prefer editing an existing file over creating a new one.
2095
2191
  - Only use emojis if the user explicitly requests it.
2096
2192
  `;
@@ -2225,6 +2321,10 @@ function createReadFileTool(backend, options) {
2225
2321
  }];
2226
2322
  }
2227
2323
  let content = typeof readResult.content === "string" ? readResult.content : "";
2324
+ if (content === "System reminder: File exists but has empty contents") return [{
2325
+ type: "text",
2326
+ text: content
2327
+ }];
2228
2328
  const lines = content.split("\n");
2229
2329
  let paginationResult = readResult;
2230
2330
  if (lines.length > limit) {
@@ -2238,9 +2338,15 @@ function createReadFileTool(backend, options) {
2238
2338
  };
2239
2339
  }
2240
2340
  }
2341
+ const { readResult: preparedResult, body } = prepareReadWindow(paginationResult, content, offset);
2342
+ const clampNotice = clampedOffsetNotice(requestedOffset);
2241
2343
  return [{
2242
2344
  type: "text",
2243
- text: truncatePaginatedRead(formatContentWithLineNumbersAndBoundaries(content, paginationResult.startLine ?? offset + 1), file_path, paginationResult, toolTokenLimitBeforeEvict)
2345
+ text: truncatePaginatedRead(body, preparedResult, {
2346
+ filePath: file_path,
2347
+ tokenLimit: toolTokenLimitBeforeEvict,
2348
+ notices: clampNotice ? [clampNotice] : []
2349
+ })
2244
2350
  }];
2245
2351
  }, {
2246
2352
  name: "read_file",
@@ -2574,7 +2680,6 @@ function createFilesystemMiddleware(options = {}) {
2574
2680
  }
2575
2681
  return createMiddleware({
2576
2682
  name: "FilesystemMiddleware",
2577
- tracePolicy: { processInputs: omitPayload },
2578
2683
  stateSchema: FilesystemStateSchema,
2579
2684
  tools: allTools,
2580
2685
  async beforeAgent(state) {
@@ -3314,7 +3419,6 @@ function createSummarizationMiddleware(options) {
3314
3419
  }
3315
3420
  return createMiddleware({
3316
3421
  name: "SummarizationMiddleware",
3317
- tracePolicy: { processInputs: omitPayload },
3318
3422
  stateSchema: SummarizationStateSchema,
3319
3423
  async wrapModelCall(request, handler) {
3320
3424
  const effectiveMessages = getEffectiveMessages(request.messages ?? [], request.state);
@@ -3453,6 +3557,24 @@ const DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the use
3453
3557
  const FORKED_CONTEXT_KEY = "_deepagentsForkedContext";
3454
3558
  const FORK_RECURSION_REFUSAL = "You are a subagent and cannot delegate to another subagent. Complete this task yourself instead of calling this tool again.";
3455
3559
  /**
3560
+ * Per-graph call accounting owned by the upstream limit middlewares. Upstream
3561
+ * declares these as plain values, so LangGraph gives them single-writer
3562
+ * `LastValue` channels: forwarding them crashed parallel delegation and let a
3563
+ * subagent's reset overwrite the parent's budget. Each agent counts its own
3564
+ * calls, so they never cross the boundary.
3565
+ *
3566
+ * Matching by name is targeted, not structural — other middleware declaring
3567
+ * plain state still collide, notably in a fork. A later change should derive
3568
+ * these keys from each subagent's middleware `stateSchema` and forward only
3569
+ * mergeable (`ReducedValue`) channels.
3570
+ */
3571
+ const CALL_COUNT_STATE_KEYS = [
3572
+ "threadModelCallCount",
3573
+ "runModelCallCount",
3574
+ "threadToolCallCount",
3575
+ "runToolCallCount"
3576
+ ];
3577
+ /**
3456
3578
  * State keys excluded when passing state to subagents and when returning
3457
3579
  * updates from subagents. Summarization keys are excluded because their
3458
3580
  * cutoffIndex is only valid against the message list it was computed from.
@@ -3463,6 +3585,7 @@ const EXCLUDED_STATE_KEYS = [
3463
3585
  "structuredResponse",
3464
3586
  "skillsMetadata",
3465
3587
  "memoryContents",
3588
+ ...CALL_COUNT_STATE_KEYS,
3466
3589
  "_summarizationEvent",
3467
3590
  "_summarizationSessionId",
3468
3591
  FORKED_CONTEXT_KEY
@@ -3472,9 +3595,13 @@ const EXCLUDED_STATE_KEYS = [
3472
3595
  * Narrower than `EXCLUDED_STATE_KEYS`: a fork's mirrored middleware needs
3473
3596
  * the parent's private channels (skills metadata, memory contents, etc.)
3474
3597
  * to rebuild an equivalent prompt.
3598
+ *
3599
+ * Call counts stay excluded: a fork inherits the parent's middleware, so
3600
+ * sharing them collides on the parent's channel.
3475
3601
  */
3476
3602
  const FORK_EXCLUDED_STATE_KEYS = [
3477
3603
  "structuredResponse",
3604
+ ...CALL_COUNT_STATE_KEYS,
3478
3605
  "_summarizationEvent",
3479
3606
  "_summarizationSessionId"
3480
3607
  ];
@@ -3625,7 +3752,6 @@ const ForkedContextStateSchema = z.object({ [FORKED_CONTEXT_KEY]: z.boolean().op
3625
3752
  function createForkTaskToolMiddleware(taskTool) {
3626
3753
  return createMiddleware({
3627
3754
  name: "forkTaskToolMiddleware",
3628
- tracePolicy: { processInputs: omitPayload },
3629
3755
  stateSchema: ForkedContextStateSchema,
3630
3756
  tools: [taskTool],
3631
3757
  beforeAgent: () => ({ [FORKED_CONTEXT_KEY]: true })
@@ -3861,7 +3987,6 @@ function createSubAgentMiddleware(options) {
3861
3987
  });
3862
3988
  return createMiddleware({
3863
3989
  name: "subAgentMiddleware",
3864
- tracePolicy: { processInputs: omitPayload },
3865
3990
  tools: [taskTool],
3866
3991
  wrapModelCall: async (request, handler) => {
3867
3992
  if (systemPrompt !== null) return handler({
@@ -3966,7 +4091,6 @@ function patchDanglingToolCalls(messages) {
3966
4091
  function createPatchToolCallsMiddleware() {
3967
4092
  return createMiddleware({
3968
4093
  name: "patchToolCallsMiddleware",
3969
- tracePolicy: { processInputs: omitPayload },
3970
4094
  beforeAgent: async (state) => {
3971
4095
  const messages = state.messages;
3972
4096
  if (!messages || messages.length === 0) return;
@@ -4328,7 +4452,6 @@ function createMemoryMiddleware(options) {
4328
4452
  const { backend, sources, addCacheControl = false } = options;
4329
4453
  return createMiddleware({
4330
4454
  name: "MemoryMiddleware",
4331
- tracePolicy: { processInputs: omitPayload },
4332
4455
  stateSchema: MemoryStateSchema,
4333
4456
  async beforeAgent(state) {
4334
4457
  if ("memoryContents" in state && state.memoryContents != null) return;
@@ -4810,18 +4933,11 @@ function validateModulePath(raw) {
4810
4933
  */
4811
4934
  function createSkillsMiddleware(options) {
4812
4935
  const { backend, sources } = options;
4813
- let loadedSkills = [];
4814
4936
  return createMiddleware({
4815
4937
  name: "SkillsMiddleware",
4816
- tracePolicy: { processInputs: omitPayload },
4817
4938
  stateSchema: SkillsStateSchema,
4818
4939
  async beforeAgent(state) {
4819
- const stateHasSkills = "skillsMetadata" in state && Array.isArray(state.skillsMetadata) && state.skillsMetadata.length > 0;
4820
- if (loadedSkills.length > 0) return stateHasSkills ? void 0 : { skillsMetadata: loadedSkills };
4821
- if (stateHasSkills) {
4822
- loadedSkills = state.skillsMetadata;
4823
- return;
4824
- }
4940
+ if ("skillsMetadata" in state && Array.isArray(state.skillsMetadata) && state.skillsMetadata.length > 0) return;
4825
4941
  const resolvedBackend = await resolveBackend(backend, { state });
4826
4942
  const allSkills = /* @__PURE__ */ new Map();
4827
4943
  for (const sourcePath of sources) try {
@@ -4830,11 +4946,10 @@ function createSkillsMiddleware(options) {
4830
4946
  } catch (error) {
4831
4947
  console.debug(`[BackendSkillsMiddleware] Failed to load skills from ${sourcePath}:`, error);
4832
4948
  }
4833
- loadedSkills = Array.from(allSkills.values());
4834
- return { skillsMetadata: loadedSkills };
4949
+ return { skillsMetadata: Array.from(allSkills.values()) };
4835
4950
  },
4836
4951
  wrapModelCall(request, handler) {
4837
- const skillsMetadata = loadedSkills.length > 0 ? loadedSkills : request.state?.skillsMetadata || [];
4952
+ const skillsMetadata = request.state?.skillsMetadata || [];
4838
4953
  const skillsLocations = formatSkillsLocations(sources);
4839
4954
  const skillsList = formatSkillsList(skillsMetadata, sources);
4840
4955
  const skillsSection = SKILLS_SYSTEM_PROMPT.replace("{skills_locations}", skillsLocations).replace("{skills_list}", skillsList);
@@ -5058,7 +5173,6 @@ function createCompletionCallbackMiddleware(options) {
5058
5173
  }
5059
5174
  return createMiddleware({
5060
5175
  name: "CompletionCallbackMiddleware",
5061
- tracePolicy: { processInputs: omitPayload },
5062
5176
  stateSchema: CompletionCallbackStateSchema,
5063
5177
  /**
5064
5178
  * After-agent hook: fires when the subagent completes successfully.
@@ -5600,7 +5714,6 @@ function createAsyncSubAgentMiddleware(options) {
5600
5714
  const fullSystemPrompt = systemPrompt ? `${systemPrompt}\n\nAvailable async subagent types:\n${agentsDescription}` : null;
5601
5715
  return createMiddleware({
5602
5716
  name: "asyncSubAgentMiddleware",
5603
- tracePolicy: { processInputs: omitPayload },
5604
5717
  stateSchema: AsyncTaskStateSchema,
5605
5718
  tools,
5606
5719
  wrapModelCall: async (request, handler) => {
@@ -5683,7 +5796,6 @@ var ConfigurationError = class ConfigurationError extends Error {
5683
5796
  function createCacheBreakpointMiddleware() {
5684
5797
  return createMiddleware({
5685
5798
  name: "CacheBreakpointMiddleware",
5686
- tracePolicy: { processInputs: omitPayload },
5687
5799
  wrapModelCall(request, handler) {
5688
5800
  if (!isAnthropicModel(request.model)) return handler(request);
5689
5801
  const existingContent = request.systemMessage.content;
@@ -5718,7 +5830,6 @@ function hasToolName(tool) {
5718
5830
  function createToolExclusionMiddleware(excludedTools) {
5719
5831
  return createMiddleware({
5720
5832
  name: "_ToolExclusionMiddleware",
5721
- tracePolicy: { processInputs: omitPayload },
5722
5833
  wrapModelCall(request, handler) {
5723
5834
  return handler({
5724
5835
  ...request,
@@ -8742,4 +8853,4 @@ var LangSmithSandbox = class LangSmithSandbox extends BaseSandbox {
8742
8853
  //#endregion
8743
8854
  export { DEFAULT_GENERAL_PURPOSE_DESCRIPTION as A, StateBackend as B, MAX_SKILL_DESCRIPTION_LENGTH as C, createMemoryMiddleware as D, createSkillsMiddleware as E, createSubAgentMiddleware as F, resolveBackend as G, applyGrepMaxCount as H, computeSummarizationDefaults as I, checkEmptyContent as J, adaptBackendProtocol as K, createSummarizationMiddleware as L, GENERAL_PURPOSE_SUBAGENT as M, SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY as N, filesValue as O, createSubAgent as P, performStringReplacement as Q, createFilesystemMiddleware as R, createCompletionCallbackMiddleware as S, MAX_SKILL_NAME_LENGTH as T, isSandboxBackend as U, SandboxError as V, isSandboxProtocol as W, isTextMimeType as X, getMimeType as Y, normalizeReadPagination as Z, createHarnessProfile as _, ASYNC_TASK_SYSTEM_PROMPT as a, createAsyncSubAgentMiddleware as b, TASK_SYSTEM_PROMPT as c, registerHarnessProfile as d, generalPurposeSubagentConfigSchema as f, EMPTY_HARNESS_PROFILE as g, serializeProfile as h, StoreBackend as i, DEFAULT_SUBAGENT_PROMPT as j, createPatchToolCallsMiddleware as k, createDeepAgent as l, parseHarnessProfileConfig as m, BaseSandbox as n, BASE_AGENT_PROMPT as o, harnessProfileConfigSchema as p, adaptSandboxProtocol as q, ContextHubBackend as r, EXECUTION_SYSTEM_PROMPT as s, LangSmithSandbox as t, getHarnessProfile as u, REQUIRED_MIDDLEWARE_NAMES as v, MAX_SKILL_FILE_SIZE as w, isAsyncSubAgent as x, ConfigurationError as y, CompositeBackend as z };
8744
8855
 
8745
- //# sourceMappingURL=langsmith-CkXiO0e9.js.map
8856
+ //# sourceMappingURL=langsmith-CY7MawjU.js.map