deepagents 1.13.2 → 1.13.4-rc.0

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/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { A as DEFAULT_GENERAL_PURPOSE_DESCRIPTION, B as StateBackend, C as MAX_SKILL_DESCRIPTION_LENGTH, D as createMemoryMiddleware, E as createSkillsMiddleware, F as createSubAgentMiddleware, G as resolveBackend, H as applyGrepMaxCount, I as computeSummarizationDefaults, K as adaptBackendProtocol, L as createSummarizationMiddleware, M as GENERAL_PURPOSE_SUBAGENT, N as SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY, O as filesValue, P as createSubAgent, R as createFilesystemMiddleware, S as createCompletionCallbackMiddleware, T as MAX_SKILL_NAME_LENGTH, U as isSandboxBackend, V as SandboxError, W as isSandboxProtocol, Z as normalizeReadPagination, _ as createHarnessProfile, a as ASYNC_TASK_SYSTEM_PROMPT, b as createAsyncSubAgentMiddleware, c as TASK_SYSTEM_PROMPT, d as registerHarnessProfile, f as generalPurposeSubagentConfigSchema, g as EMPTY_HARNESS_PROFILE, h as serializeProfile, i as StoreBackend, j as DEFAULT_SUBAGENT_PROMPT, k as createPatchToolCallsMiddleware, l as createDeepAgent, m as parseHarnessProfileConfig, n as BaseSandbox, o as BASE_AGENT_PROMPT, p as harnessProfileConfigSchema, q as adaptSandboxProtocol, r as ContextHubBackend, s as EXECUTION_SYSTEM_PROMPT, t as LangSmithSandbox, u as getHarnessProfile, v as REQUIRED_MIDDLEWARE_NAMES, w as MAX_SKILL_FILE_SIZE, x as isAsyncSubAgent, y as ConfigurationError, z as CompositeBackend } from "./langsmith-BBV5JlNW.js";
2
- import { a as createAgentMemoryMiddleware, i as parseSkillMetadata, n as FilesystemBackend, o as createSettings, r as listSkills, s as findProjectRoot, t as LocalShellBackend } from "./src-CKk0apeE.js";
1
+ import { A as DEFAULT_GENERAL_PURPOSE_DESCRIPTION, B as StateBackend, C as MAX_SKILL_DESCRIPTION_LENGTH, D as createMemoryMiddleware, E as createSkillsMiddleware, F as createSubAgentMiddleware, G as resolveBackend, H as applyGrepMaxCount, I as computeSummarizationDefaults, K as adaptBackendProtocol, L as createSummarizationMiddleware, M as GENERAL_PURPOSE_SUBAGENT, N as SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY, O as filesValue, P as createSubAgent, R as createFilesystemMiddleware, S as createCompletionCallbackMiddleware, T as MAX_SKILL_NAME_LENGTH, U as isSandboxBackend, V as SandboxError, W as isSandboxProtocol, Z as normalizeReadPagination, _ as createHarnessProfile, a as ASYNC_TASK_SYSTEM_PROMPT, b as createAsyncSubAgentMiddleware, c as TASK_SYSTEM_PROMPT, d as registerHarnessProfile, f as generalPurposeSubagentConfigSchema, g as EMPTY_HARNESS_PROFILE, h as serializeProfile, i as StoreBackend, j as DEFAULT_SUBAGENT_PROMPT, k as createPatchToolCallsMiddleware, l as createDeepAgent, m as parseHarnessProfileConfig, n as BaseSandbox, o as BASE_AGENT_PROMPT, p as harnessProfileConfigSchema, q as adaptSandboxProtocol, r as ContextHubBackend, s as EXECUTION_SYSTEM_PROMPT, t as LangSmithSandbox, u as getHarnessProfile, v as REQUIRED_MIDDLEWARE_NAMES, w as MAX_SKILL_FILE_SIZE, x as isAsyncSubAgent, y as ConfigurationError, z as CompositeBackend } from "./langsmith-CkXiO0e9.js";
2
+ import { a as createAgentMemoryMiddleware, i as parseSkillMetadata, n as FilesystemBackend, o as createSettings, r as listSkills, s as findProjectRoot, t as LocalShellBackend } from "./src-C2mTq52i.js";
3
3
  export { ASYNC_TASK_SYSTEM_PROMPT, BASE_AGENT_PROMPT, BaseSandbox, CompositeBackend, ConfigurationError, ContextHubBackend, DEFAULT_GENERAL_PURPOSE_DESCRIPTION, DEFAULT_SUBAGENT_PROMPT, EMPTY_HARNESS_PROFILE, EXECUTION_SYSTEM_PROMPT, FilesystemBackend, GENERAL_PURPOSE_SUBAGENT, LangSmithSandbox, LocalShellBackend, MAX_SKILL_DESCRIPTION_LENGTH, MAX_SKILL_FILE_SIZE, MAX_SKILL_NAME_LENGTH, REQUIRED_MIDDLEWARE_NAMES, SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY, SandboxError, StateBackend, StoreBackend, TASK_SYSTEM_PROMPT, adaptBackendProtocol, adaptSandboxProtocol, applyGrepMaxCount, computeSummarizationDefaults, createAgentMemoryMiddleware, createAsyncSubAgentMiddleware, createCompletionCallbackMiddleware, createDeepAgent, createFilesystemMiddleware, createHarnessProfile, createMemoryMiddleware, createPatchToolCallsMiddleware, createSettings, createSkillsMiddleware, createSubAgent, createSubAgentMiddleware, createSummarizationMiddleware, filesValue, findProjectRoot, generalPurposeSubagentConfigSchema, getHarnessProfile, harnessProfileConfigSchema, isAsyncSubAgent, isSandboxBackend, isSandboxProtocol, listSkills, normalizeReadPagination, parseHarnessProfileConfig, parseSkillMetadata, registerHarnessProfile, resolveBackend, serializeProfile };
@@ -2598,6 +2598,7 @@ function createFilesystemMiddleware(options = {}) {
2598
2598
  }
2599
2599
  return (0, langchain.createMiddleware)({
2600
2600
  name: "FilesystemMiddleware",
2601
+ tracePolicy: { processInputs: langchain.omitPayload },
2601
2602
  stateSchema: FilesystemStateSchema,
2602
2603
  tools: allTools,
2603
2604
  async beforeAgent(state) {
@@ -3337,6 +3338,7 @@ function createSummarizationMiddleware(options) {
3337
3338
  }
3338
3339
  return (0, langchain.createMiddleware)({
3339
3340
  name: "SummarizationMiddleware",
3341
+ tracePolicy: { processInputs: langchain.omitPayload },
3340
3342
  stateSchema: SummarizationStateSchema,
3341
3343
  async wrapModelCall(request, handler) {
3342
3344
  const effectiveMessages = getEffectiveMessages(request.messages ?? [], request.state);
@@ -3382,6 +3384,83 @@ function createSummarizationMiddleware(options) {
3382
3384
  });
3383
3385
  }
3384
3386
  //#endregion
3387
+ //#region src/middleware/utils.ts
3388
+ /**
3389
+ * Utility functions for middleware.
3390
+ *
3391
+ * This module provides shared helpers used across middleware implementations.
3392
+ */
3393
+ /**
3394
+ * Merge custom middleware into an assembled stack by `.name`.
3395
+ *
3396
+ * Matching custom middleware replaces the existing entry in place. New
3397
+ * middleware is appended after the base stack in caller-provided order.
3398
+ */
3399
+ function mergeMiddleware$1(base, custom) {
3400
+ const merged = new Map(base.map((middleware) => [middleware.name, middleware]));
3401
+ for (const middleware of custom) merged.set(middleware.name, middleware);
3402
+ return [...merged.values()];
3403
+ }
3404
+ function middlewareNames(middleware) {
3405
+ return new Set(middleware.map((entry) => entry.name));
3406
+ }
3407
+ function matchingMiddleware(middleware, names) {
3408
+ return middleware.filter((entry) => names.has(entry.name));
3409
+ }
3410
+ /**
3411
+ * Merge custom middleware into default and tail middleware segments.
3412
+ *
3413
+ * Same-name custom entries replace matching defaults in either segment. Novel
3414
+ * custom entries are inserted between the default and tail segments unless
3415
+ * `appendNew` is false.
3416
+ */
3417
+ function mergeMiddlewareStack(defaultMiddleware, customMiddleware, tailMiddleware = [], options = {}) {
3418
+ const defaultMiddlewareNames = middlewareNames(defaultMiddleware);
3419
+ const tailMiddlewareNames = middlewareNames(tailMiddleware);
3420
+ const knownMiddlewareNames = /* @__PURE__ */ new Set([...defaultMiddlewareNames, ...tailMiddlewareNames]);
3421
+ const novelMiddleware = options.appendNew === false ? [] : customMiddleware.filter((entry) => !knownMiddlewareNames.has(entry.name));
3422
+ return [
3423
+ ...mergeMiddleware$1(defaultMiddleware, matchingMiddleware(customMiddleware, defaultMiddlewareNames)),
3424
+ ...novelMiddleware,
3425
+ ...mergeMiddleware$1(tailMiddleware, matchingMiddleware(customMiddleware, tailMiddlewareNames))
3426
+ ];
3427
+ }
3428
+ /**
3429
+ * Append text to a system message.
3430
+ *
3431
+ * Creates a new SystemMessage with the text appended to the existing content.
3432
+ * If the original message has content, the new text is separated by two newlines.
3433
+ *
3434
+ * @param systemMessage - Existing system message or null/undefined.
3435
+ * @param text - Text to add to the system message.
3436
+ * @returns New SystemMessage with the text appended.
3437
+ *
3438
+ * @example
3439
+ * ```typescript
3440
+ * const original = new SystemMessage({ content: "You are a helpful assistant." });
3441
+ * const updated = appendToSystemMessage(original, "Always be concise.");
3442
+ * // Result: SystemMessage with content "You are a helpful assistant.\n\nAlways be concise."
3443
+ * ```
3444
+ */
3445
+ function appendToSystemMessage(systemMessage, text) {
3446
+ if (!systemMessage) return new _langchain_core_messages.SystemMessage({ content: text });
3447
+ const existingContent = systemMessage.content;
3448
+ if (typeof existingContent === "string") {
3449
+ const newContent = existingContent ? `${existingContent}\n\n${text}` : text;
3450
+ return new _langchain_core_messages.SystemMessage({ content: newContent });
3451
+ }
3452
+ if (Array.isArray(existingContent)) {
3453
+ const newContent = [...existingContent];
3454
+ const textToAdd = newContent.length > 0 ? `\n\n${text}` : text;
3455
+ newContent.push({
3456
+ type: "text",
3457
+ text: textToAdd
3458
+ });
3459
+ return new _langchain_core_messages.SystemMessage({ content: newContent });
3460
+ }
3461
+ return new _langchain_core_messages.SystemMessage({ content: text });
3462
+ }
3463
+ //#endregion
3385
3464
  //#region src/middleware/subagents.ts
3386
3465
  /**
3387
3466
  * Config key used by task-tool callers to request dynamic response format.
@@ -3395,6 +3474,8 @@ const SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY = "__deepagents_subagent_response_form
3395
3474
  * Provides a minimal base prompt that can be extended by specific subagent configurations.
3396
3475
  */
3397
3476
  const DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools.";
3477
+ const FORKED_CONTEXT_KEY = "_deepagentsForkedContext";
3478
+ const FORK_RECURSION_REFUSAL = "You are a subagent and cannot delegate to another subagent. Complete this task yourself instead of calling this tool again.";
3398
3479
  /**
3399
3480
  * State keys excluded when passing state to subagents and when returning
3400
3481
  * updates from subagents. Summarization keys are excluded because their
@@ -3407,6 +3488,18 @@ const EXCLUDED_STATE_KEYS = [
3407
3488
  "skillsMetadata",
3408
3489
  "memoryContents",
3409
3490
  "_summarizationEvent",
3491
+ "_summarizationSessionId",
3492
+ FORKED_CONTEXT_KEY
3493
+ ];
3494
+ /**
3495
+ * State keys excluded when inheriting state into a declarative fork.
3496
+ * Narrower than `EXCLUDED_STATE_KEYS`: a fork's mirrored middleware needs
3497
+ * the parent's private channels (skills metadata, memory contents, etc.)
3498
+ * to rebuild an equivalent prompt.
3499
+ */
3500
+ const FORK_EXCLUDED_STATE_KEYS = [
3501
+ "structuredResponse",
3502
+ "_summarizationEvent",
3410
3503
  "_summarizationSessionId"
3411
3504
  ];
3412
3505
  /**
@@ -3416,25 +3509,37 @@ const EXCLUDED_STATE_KEYS = [
3416
3509
  const DEFAULT_GENERAL_PURPOSE_DESCRIPTION = "General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.";
3417
3510
  function getTaskToolDescription(subagentDescriptions) {
3418
3511
  return langchain.context`
3419
- Launch an ephemeral subagent to handle a complex, multi-step task in an isolated context window.
3512
+ Launch an ephemeral subagent to handle a complex, multi-step task.
3420
3513
 
3421
3514
  Available agent types and the tools they have access to:
3422
3515
  ${subagentDescriptions.join("\n")}
3423
3516
 
3424
3517
  Specify subagent_type to select the agent. Usage notes:
3425
3518
  - Launch multiple agents concurrently when their tasks are independent, using a single message with multiple tool calls.
3426
- - Each invocation is stateless: the agent sees only the prompt you give it and returns a single final report. Put full detail in the prompt and state exactly what it should return.
3519
+ - Each invocation is stateless by default: the agent sees only the prompt you give it and returns a single final report. Put full detail in the prompt and state exactly what it should return — unless an agent type below says it inherits your conversation instead.
3427
3520
  - The agent's report is not shown to the user; relay a summary yourself.
3428
- - Tell the agent whether to create content, analyze, or only research, since it cannot see the user's intent.
3521
+ - Tell the agent whether to create content, analyze, or only research, since it can't necessarily see the user's intent unless it inherits your conversation, as noted per agent type below.
3429
3522
  - If an agent's description says to use it proactively, do so without waiting to be asked.
3430
3523
  - When only general-purpose is available, use it for any complex, context-heavy task; it has the same capabilities as the main agent.
3431
3524
  `;
3432
3525
  }
3526
+ const FORKED_SUBAGENT_TOOL_NOTE = " (inherits your full conversation and system prompt — no need to restate context here)";
3527
+ const COMPILED_FORKED_SUBAGENT_TOOL_NOTE = " (inherits your conversation history — its system prompt is fixed in its own runnable)";
3528
+ /** Render one subagent's listing line for the task tool description. */
3529
+ function describeSubagentForTool(name, description, forked, compiled = false) {
3530
+ return `- ${name}: ${description}${forked ? compiled ? COMPILED_FORKED_SUBAGENT_TOOL_NOTE : FORKED_SUBAGENT_TOOL_NOTE : ""}`;
3531
+ }
3532
+ const FORK_TASK_PREAMBLE = "[The messages above are a prior conversation you are continuing as the subagent that was just invoked. Any mention in them of delegating to a subagent already happened — you are that subagent, not the one being asked to delegate further. If you try to delegate to another subagent yourself, it will be refused — complete this task directly. Use the specific facts, figures, and identifiers already established in that conversation when completing the task below — do not answer generically when exact details are already available above. Your actual task is below.]\n\n";
3533
+ /**
3534
+ * Whether a declarative subagent spec has `mode: "fork"` set.
3535
+ *
3536
+ * A plain boolean, not a type predicate: `SubAgent` covers both `"fork"` and
3537
+ * `"isolated"`, so there's no distinct type left to narrow to.
3538
+ */
3433
3539
  function isForkedSubAgent(value) {
3434
3540
  if (typeof value !== "object" || value == null) return false;
3435
3541
  if (!("mode" in value)) return false;
3436
- if (value.mode !== "fork") return false;
3437
- return true;
3542
+ return value.mode === "fork";
3438
3543
  }
3439
3544
  /**
3440
3545
  * Base specification for the general-purpose subagent.
@@ -3477,15 +3582,26 @@ const GENERAL_PURPOSE_SUBAGENT = {
3477
3582
  name: "general-purpose",
3478
3583
  description: DEFAULT_GENERAL_PURPOSE_DESCRIPTION,
3479
3584
  systemPrompt: DEFAULT_SUBAGENT_PROMPT,
3480
- mode: "handoff"
3585
+ mode: "isolated"
3481
3586
  };
3587
+ function filterState(state, excludedKeys) {
3588
+ const filtered = {};
3589
+ for (const [key, value] of Object.entries(state)) if (!excludedKeys.includes(key)) filtered[key] = value;
3590
+ return filtered;
3591
+ }
3482
3592
  /**
3483
3593
  * Filter state to exclude certain keys when passing to subagents
3484
3594
  */
3485
3595
  function filterStateForSubagent(state) {
3486
- const filtered = {};
3487
- for (const [key, value] of Object.entries(state)) if (!EXCLUDED_STATE_KEYS.includes(key)) filtered[key] = value;
3488
- return filtered;
3596
+ return filterState(state, EXCLUDED_STATE_KEYS);
3597
+ }
3598
+ /**
3599
+ * Filter state to exclude only the keys a declarative fork must not resume
3600
+ * (structured response, summarization event/session) — see
3601
+ * `FORK_EXCLUDED_STATE_KEYS`.
3602
+ */
3603
+ function filterStateForFork(state) {
3604
+ return filterState(state, FORK_EXCLUDED_STATE_KEYS);
3489
3605
  }
3490
3606
  /**
3491
3607
  * Invalid tool message block types
@@ -3529,6 +3645,16 @@ function stripInFlightAIMessage(messages) {
3529
3645
  const last = messages.at(-1);
3530
3646
  return _langchain_core_messages.AIMessage.isInstance(last) && (last.tool_calls?.length ?? 0) > 0 ? messages.slice(0, -1) : messages;
3531
3647
  }
3648
+ const ForkedContextStateSchema = zod_v4.z.object({ [FORKED_CONTEXT_KEY]: zod_v4.z.boolean().optional() });
3649
+ function createForkTaskToolMiddleware(taskTool) {
3650
+ return (0, langchain.createMiddleware)({
3651
+ name: "forkTaskToolMiddleware",
3652
+ tracePolicy: { processInputs: langchain.omitPayload },
3653
+ stateSchema: ForkedContextStateSchema,
3654
+ tools: [taskTool],
3655
+ beforeAgent: () => ({ [FORKED_CONTEXT_KEY]: true })
3656
+ });
3657
+ }
3532
3658
  /**
3533
3659
  * Create a runnable agent from a declarative `SubAgent` spec.
3534
3660
  *
@@ -3558,6 +3684,17 @@ function createSubAgent(spec, options) {
3558
3684
  });
3559
3685
  }
3560
3686
  /**
3687
+ * Resolve a fork's system prompt: the parent's inherited prompt, with the
3688
+ * fork's own systemPrompt (if any) appended as an addendum rather than
3689
+ * replacing it.
3690
+ */
3691
+ function resolveForkSystemPrompt(parentSystemPrompt, forkAddendum) {
3692
+ if (!forkAddendum) return parentSystemPrompt ?? "";
3693
+ const addendumText = typeof forkAddendum === "string" ? forkAddendum : forkAddendum.text;
3694
+ if (langchain.SystemMessage.isInstance(parentSystemPrompt)) return appendToSystemMessage(parentSystemPrompt, addendumText);
3695
+ return parentSystemPrompt ? `${parentSystemPrompt}\n\n${addendumText}` : addendumText;
3696
+ }
3697
+ /**
3561
3698
  * Create subagent instances from specifications.
3562
3699
  *
3563
3700
  * Returns compiled agents, raw specs keyed by name (for on-demand
@@ -3565,13 +3702,18 @@ function createSubAgent(spec, options) {
3565
3702
  * of names that should fork the parent's conversation.
3566
3703
  */
3567
3704
  function getSubagents(options) {
3568
- const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware: gpMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, parentSystemPrompt = null } = options;
3705
+ const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware: gpMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, parentSystemPrompt = null, mirroredTaskTool } = options;
3569
3706
  const defaultSubagentMiddleware = defaultMiddleware || [];
3570
3707
  const generalPurposeMiddlewareBase = gpMiddleware || defaultSubagentMiddleware;
3571
3708
  const agents = {};
3572
3709
  const specsByName = {};
3573
3710
  const subagentDescriptions = [];
3574
3711
  const forkModeNames = /* @__PURE__ */ new Set();
3712
+ const seenNames = new Set(generalPurposeAgent ? ["general-purpose"] : []);
3713
+ for (const agentParams of subagents) {
3714
+ if (seenNames.has(agentParams.name)) throw new Error(`Duplicate subagent name '${agentParams.name}'; each subagent must have a unique name.`);
3715
+ seenNames.add(agentParams.name);
3716
+ }
3575
3717
  if (generalPurposeAgent) {
3576
3718
  const generalPurposeMiddleware = [...generalPurposeMiddlewareBase];
3577
3719
  if (defaultInterruptOn) generalPurposeMiddleware.push((0, langchain.humanInTheLoopMiddleware)({ interruptOn: defaultInterruptOn }));
@@ -3585,24 +3727,34 @@ function getSubagents(options) {
3585
3727
  };
3586
3728
  agents["general-purpose"] = createSubAgent(gpSpec);
3587
3729
  specsByName["general-purpose"] = gpSpec;
3588
- subagentDescriptions.push(`- general-purpose: ${DEFAULT_GENERAL_PURPOSE_DESCRIPTION}`);
3730
+ subagentDescriptions.push(describeSubagentForTool("general-purpose", DEFAULT_GENERAL_PURPOSE_DESCRIPTION, false));
3589
3731
  }
3590
3732
  for (const agentParams of subagents) {
3591
3733
  const rawMode = agentParams.mode;
3592
- if (rawMode != null && rawMode !== "handoff" && rawMode !== "fork") throw new Error(`SubAgent '${agentParams.name}' has invalid mode '${rawMode}' — must be "handoff" or "fork".`);
3593
- subagentDescriptions.push(`- ${agentParams.name}: ${agentParams.description}`);
3734
+ if (rawMode != null && rawMode !== "isolated" && rawMode !== "fork" && rawMode !== "handoff") throw new Error(`SubAgent '${agentParams.name}' has invalid mode '${rawMode}' — must be "isolated" or "fork".`);
3735
+ const forked = isForkedSubAgent(agentParams);
3736
+ const compiled = "runnable" in agentParams;
3737
+ subagentDescriptions.push(describeSubagentForTool(agentParams.name, agentParams.description, forked, compiled));
3594
3738
  if ("runnable" in agentParams) {
3595
3739
  agents[agentParams.name] = agentParams.runnable;
3596
3740
  specsByName[agentParams.name] = agentParams;
3597
- if (isForkedSubAgent(agentParams)) forkModeNames.add(agentParams.name);
3598
- } else if (isForkedSubAgent(agentParams)) {
3741
+ if (forked) forkModeNames.add(agentParams.name);
3742
+ continue;
3743
+ }
3744
+ const subagentMiddleware = [...defaultSubagentMiddleware, ...agentParams.middleware ?? []];
3745
+ if (forked) {
3746
+ const rawSkills = agentParams.skills;
3747
+ if (Array.isArray(rawSkills) && rawSkills.length > 0) throw new Error(`SubAgent '${agentParams.name}' cannot set skills under mode: "fork"; the parent's skills are inherited instead.`);
3748
+ const resolvedSystemPrompt = resolveForkSystemPrompt(parentSystemPrompt, agentParams.systemPrompt);
3749
+ const fsIndex = subagentMiddleware.findIndex((m) => m.name === "FilesystemMiddleware");
3750
+ subagentMiddleware.splice(fsIndex + 1, 0, createForkTaskToolMiddleware(mirroredTaskTool));
3599
3751
  const resolvedSpec = {
3600
3752
  ...agentParams,
3601
- systemPrompt: parentSystemPrompt ?? "",
3753
+ systemPrompt: resolvedSystemPrompt,
3602
3754
  mode: void 0,
3603
3755
  model: agentParams.model ?? defaultModel,
3604
3756
  tools: agentParams.tools ?? defaultTools,
3605
- middleware: [...defaultSubagentMiddleware, ...agentParams.middleware ?? []],
3757
+ middleware: subagentMiddleware,
3606
3758
  interruptOn: agentParams.interruptOn ?? defaultInterruptOn ?? void 0
3607
3759
  };
3608
3760
  agents[agentParams.name] = createSubAgent(resolvedSpec);
@@ -3611,10 +3763,10 @@ function getSubagents(options) {
3611
3763
  } else {
3612
3764
  const resolvedSpec = {
3613
3765
  ...agentParams,
3614
- mode: "handoff",
3766
+ mode: "isolated",
3615
3767
  model: agentParams.model ?? defaultModel,
3616
3768
  tools: agentParams.tools ?? defaultTools,
3617
- middleware: [...defaultSubagentMiddleware, ...agentParams.middleware ?? []],
3769
+ middleware: subagentMiddleware,
3618
3770
  interruptOn: agentParams.interruptOn ?? defaultInterruptOn ?? void 0
3619
3771
  };
3620
3772
  agents[agentParams.name] = createSubAgent(resolvedSpec);
@@ -3633,16 +3785,12 @@ function getSubagents(options) {
3633
3785
  */
3634
3786
  function createTaskTool(options) {
3635
3787
  const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, taskDescription, parentSystemPrompt = null } = options;
3636
- const { agents: subagentGraphs, specsByName, descriptions: subagentDescriptions, forkModeNames } = getSubagents({
3637
- defaultModel,
3638
- defaultTools,
3639
- defaultMiddleware,
3640
- generalPurposeMiddleware,
3641
- defaultInterruptOn,
3642
- subagents,
3643
- generalPurposeAgent,
3644
- parentSystemPrompt
3645
- });
3788
+ const subagentNames = [...generalPurposeAgent ? ["general-purpose"] : [], ...subagents.map((spec) => spec.name)];
3789
+ const subagentDescriptions = [...generalPurposeAgent ? [describeSubagentForTool("general-purpose", DEFAULT_GENERAL_PURPOSE_DESCRIPTION, false)] : [], ...subagents.map((spec) => describeSubagentForTool(spec.name, spec.description, isForkedSubAgent(spec), "runnable" in spec))];
3790
+ const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
3791
+ let subagentGraphs = {};
3792
+ let specsByName = {};
3793
+ let forkModeNames = /* @__PURE__ */ new Set();
3646
3794
  function selectSubagent(subagentType, config) {
3647
3795
  const spec = specsByName[subagentType];
3648
3796
  const responseFormat = config.configurable?.[SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY];
@@ -3650,18 +3798,19 @@ function createTaskTool(options) {
3650
3798
  if ("runnable" in spec || responseFormat == null) return subagentGraphs[subagentType];
3651
3799
  return createSubAgent(spec, { responseFormat });
3652
3800
  }
3653
- const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
3654
- return (0, langchain.tool)(async (input, config) => {
3801
+ async function runTask(input, config) {
3655
3802
  const { description, subagent_type } = input;
3803
+ const currentState = (0, _langchain_langgraph.getCurrentTaskInput)();
3804
+ if (currentState[FORKED_CONTEXT_KEY]) return FORK_RECURSION_REFUSAL;
3656
3805
  if (!(subagent_type in subagentGraphs)) {
3657
3806
  const allowedTypes = Object.keys(subagentGraphs).map((k) => `\`${k}\``).join(", ");
3658
3807
  throw new Error(`Error: invoked agent of type ${subagent_type}, the only allowed types are ${allowedTypes}`);
3659
3808
  }
3660
3809
  const shouldFork = forkModeNames.has(subagent_type);
3661
3810
  const subagent = selectSubagent(subagent_type, config);
3662
- const currentState = (0, _langchain_langgraph.getCurrentTaskInput)();
3663
- const subagentState = filterStateForSubagent(currentState);
3664
- if (shouldFork) subagentState.messages = [...getEffectiveMessages(stripInFlightAIMessage(currentState.messages ?? []), currentState), new _langchain_core_messages.HumanMessage({ content: description })];
3811
+ const spec = specsByName[subagent_type];
3812
+ const subagentState = shouldFork && !("runnable" in spec) ? filterStateForFork(currentState) : filterStateForSubagent(currentState);
3813
+ if (shouldFork) subagentState.messages = [...getEffectiveMessages(stripInFlightAIMessage(currentState.messages ?? []), currentState), new _langchain_core_messages.HumanMessage({ content: FORK_TASK_PREAMBLE + description })];
3665
3814
  else subagentState.messages = [new _langchain_core_messages.HumanMessage({ content: description })];
3666
3815
  subagentState._summarizationSessionId = `session_${crypto.randomUUID().substring(0, 8)}`;
3667
3816
  const subagentConfig = {
@@ -3688,14 +3837,35 @@ function createTaskTool(options) {
3688
3837
  return content;
3689
3838
  }
3690
3839
  return returnCommandWithStateUpdate(result, config.toolCall.id);
3691
- }, {
3840
+ }
3841
+ const taskToolSchema = zod_v4.z.object({
3842
+ description: zod_v4.z.string().describe("The task to execute with the selected agent"),
3843
+ subagent_type: zod_v4.z.string().describe(`Name of the agent to use. Available: ${subagentNames.join(", ")}`)
3844
+ });
3845
+ const taskTool = (0, langchain.tool)(runTask, {
3692
3846
  name: "task",
3693
3847
  description: finalTaskDescription,
3694
- schema: zod_v4.z.object({
3695
- description: zod_v4.z.string().describe("The task to execute with the selected agent"),
3696
- subagent_type: zod_v4.z.string().describe(`Name of the agent to use. Available: ${Object.keys(subagentGraphs).join(", ")}`)
3848
+ schema: taskToolSchema
3849
+ });
3850
+ const { agents, specsByName: resolvedSpecsByName, forkModeNames: resolvedForkModeNames } = getSubagents({
3851
+ defaultModel,
3852
+ defaultTools,
3853
+ defaultMiddleware,
3854
+ generalPurposeMiddleware,
3855
+ defaultInterruptOn,
3856
+ subagents,
3857
+ generalPurposeAgent,
3858
+ parentSystemPrompt,
3859
+ mirroredTaskTool: (0, langchain.tool)(runTask, {
3860
+ name: "task",
3861
+ description: finalTaskDescription,
3862
+ schema: taskToolSchema
3697
3863
  })
3698
3864
  });
3865
+ subagentGraphs = agents;
3866
+ specsByName = resolvedSpecsByName;
3867
+ forkModeNames = resolvedForkModeNames;
3868
+ return taskTool;
3699
3869
  }
3700
3870
  /**
3701
3871
  * Create subagent middleware with task tool
@@ -3715,6 +3885,7 @@ function createSubAgentMiddleware(options) {
3715
3885
  });
3716
3886
  return (0, langchain.createMiddleware)({
3717
3887
  name: "subAgentMiddleware",
3888
+ tracePolicy: { processInputs: langchain.omitPayload },
3718
3889
  tools: [taskTool],
3719
3890
  wrapModelCall: async (request, handler) => {
3720
3891
  if (systemPrompt !== null) return handler({
@@ -3819,6 +3990,7 @@ function patchDanglingToolCalls(messages) {
3819
3990
  function createPatchToolCallsMiddleware() {
3820
3991
  return (0, langchain.createMiddleware)({
3821
3992
  name: "patchToolCallsMiddleware",
3993
+ tracePolicy: { processInputs: langchain.omitPayload },
3822
3994
  beforeAgent: async (state) => {
3823
3995
  const messages = state.messages;
3824
3996
  if (!messages || messages.length === 0) return;
@@ -4180,6 +4352,7 @@ function createMemoryMiddleware(options) {
4180
4352
  const { backend, sources, addCacheControl = false } = options;
4181
4353
  return (0, langchain.createMiddleware)({
4182
4354
  name: "MemoryMiddleware",
4355
+ tracePolicy: { processInputs: langchain.omitPayload },
4183
4356
  stateSchema: MemoryStateSchema,
4184
4357
  async beforeAgent(state) {
4185
4358
  if ("memoryContents" in state && state.memoryContents != null) return;
@@ -4664,6 +4837,7 @@ function createSkillsMiddleware(options) {
4664
4837
  let loadedSkills = [];
4665
4838
  return (0, langchain.createMiddleware)({
4666
4839
  name: "SkillsMiddleware",
4840
+ tracePolicy: { processInputs: langchain.omitPayload },
4667
4841
  stateSchema: SkillsStateSchema,
4668
4842
  async beforeAgent(state) {
4669
4843
  const stateHasSkills = "skillsMetadata" in state && Array.isArray(state.skillsMetadata) && state.skillsMetadata.length > 0;
@@ -4697,48 +4871,6 @@ function createSkillsMiddleware(options) {
4697
4871
  });
4698
4872
  }
4699
4873
  //#endregion
4700
- //#region src/middleware/utils.ts
4701
- /**
4702
- * Utility functions for middleware.
4703
- *
4704
- * This module provides shared helpers used across middleware implementations.
4705
- */
4706
- /**
4707
- * Merge custom middleware into an assembled stack by `.name`.
4708
- *
4709
- * Matching custom middleware replaces the existing entry in place. New
4710
- * middleware is appended after the base stack in caller-provided order.
4711
- */
4712
- function mergeMiddleware$1(base, custom) {
4713
- const merged = new Map(base.map((middleware) => [middleware.name, middleware]));
4714
- for (const middleware of custom) merged.set(middleware.name, middleware);
4715
- return [...merged.values()];
4716
- }
4717
- function middlewareNames(middleware) {
4718
- return new Set(middleware.map((entry) => entry.name));
4719
- }
4720
- function matchingMiddleware(middleware, names) {
4721
- return middleware.filter((entry) => names.has(entry.name));
4722
- }
4723
- /**
4724
- * Merge custom middleware into default and tail middleware segments.
4725
- *
4726
- * Same-name custom entries replace matching defaults in either segment. Novel
4727
- * custom entries are inserted between the default and tail segments unless
4728
- * `appendNew` is false.
4729
- */
4730
- function mergeMiddlewareStack(defaultMiddleware, customMiddleware, tailMiddleware = [], options = {}) {
4731
- const defaultMiddlewareNames = middlewareNames(defaultMiddleware);
4732
- const tailMiddlewareNames = middlewareNames(tailMiddleware);
4733
- const knownMiddlewareNames = /* @__PURE__ */ new Set([...defaultMiddlewareNames, ...tailMiddlewareNames]);
4734
- const novelMiddleware = options.appendNew === false ? [] : customMiddleware.filter((entry) => !knownMiddlewareNames.has(entry.name));
4735
- return [
4736
- ...mergeMiddleware$1(defaultMiddleware, matchingMiddleware(customMiddleware, defaultMiddlewareNames)),
4737
- ...novelMiddleware,
4738
- ...mergeMiddleware$1(tailMiddleware, matchingMiddleware(customMiddleware, tailMiddlewareNames))
4739
- ];
4740
- }
4741
- //#endregion
4742
4874
  //#region src/middleware/completion_callback.ts
4743
4875
  /**
4744
4876
  * Callback middleware for async subagents.
@@ -4950,6 +5082,7 @@ function createCompletionCallbackMiddleware(options) {
4950
5082
  }
4951
5083
  return (0, langchain.createMiddleware)({
4952
5084
  name: "CompletionCallbackMiddleware",
5085
+ tracePolicy: { processInputs: langchain.omitPayload },
4953
5086
  stateSchema: CompletionCallbackStateSchema,
4954
5087
  /**
4955
5088
  * After-agent hook: fires when the subagent completes successfully.
@@ -5491,6 +5624,7 @@ function createAsyncSubAgentMiddleware(options) {
5491
5624
  const fullSystemPrompt = systemPrompt ? `${systemPrompt}\n\nAvailable async subagent types:\n${agentsDescription}` : null;
5492
5625
  return (0, langchain.createMiddleware)({
5493
5626
  name: "asyncSubAgentMiddleware",
5627
+ tracePolicy: { processInputs: langchain.omitPayload },
5494
5628
  stateSchema: AsyncTaskStateSchema,
5495
5629
  tools,
5496
5630
  wrapModelCall: async (request, handler) => {
@@ -5573,6 +5707,7 @@ var ConfigurationError = class ConfigurationError extends Error {
5573
5707
  function createCacheBreakpointMiddleware() {
5574
5708
  return (0, langchain.createMiddleware)({
5575
5709
  name: "CacheBreakpointMiddleware",
5710
+ tracePolicy: { processInputs: langchain.omitPayload },
5576
5711
  wrapModelCall(request, handler) {
5577
5712
  if (!isAnthropicModel(request.model)) return handler(request);
5578
5713
  const existingContent = request.systemMessage.content;
@@ -5607,6 +5742,7 @@ function hasToolName(tool) {
5607
5742
  function createToolExclusionMiddleware(excludedTools) {
5608
5743
  return (0, langchain.createMiddleware)({
5609
5744
  name: "_ToolExclusionMiddleware",
5745
+ tracePolicy: { processInputs: langchain.omitPayload },
5610
5746
  wrapModelCall(request, handler) {
5611
5747
  return handler({
5612
5748
  ...request,
@@ -6367,8 +6503,18 @@ function createDeepAgent(params = {}) {
6367
6503
  providerHint: getModelProvider(model),
6368
6504
  identifierHint: getModelIdentifier(model)
6369
6505
  });
6370
- const filesystemTools = FILESYSTEM_TOOL_NAMES.filter((toolName) => !harnessProfile.excludedTools.has(toolName));
6371
- const profileFilesystemTools = filesystemTools.length === FILESYSTEM_TOOL_NAMES.length ? void 0 : filesystemTools.includes("read_file") ? filesystemTools : ["read_file", ...filesystemTools];
6506
+ const computeProfileFilesystemTools = (profile) => {
6507
+ const filesystemTools = FILESYSTEM_TOOL_NAMES.filter((toolName) => !profile.excludedTools.has(toolName));
6508
+ return filesystemTools.length === FILESYSTEM_TOOL_NAMES.length ? void 0 : filesystemTools.includes("read_file") ? filesystemTools : ["read_file", ...filesystemTools];
6509
+ };
6510
+ const profileFilesystemTools = computeProfileFilesystemTools(harnessProfile);
6511
+ const resolveSubagentProfile = (subagentModel) => {
6512
+ if (subagentModel == null || subagentModel === model) return harnessProfile;
6513
+ return typeof subagentModel === "string" ? resolveHarnessProfile({ spec: subagentModel }) : resolveHarnessProfile({
6514
+ providerHint: getModelProvider(subagentModel),
6515
+ identifierHint: getModelIdentifier(subagentModel)
6516
+ });
6517
+ };
6372
6518
  const toolOverrides = harnessProfile.toolDescriptionOverrides;
6373
6519
  const effectiveTools = Object.keys(toolOverrides).length > 0 ? tools.map((t) => t.name in toolOverrides ? Object.assign(Object.create(Object.getPrototypeOf(t)), t, { description: toolOverrides[t.name] }) : t) : tools;
6374
6520
  const anthropicModel = isAnthropicModel(model);
@@ -6404,44 +6550,50 @@ function createDeepAgent(params = {}) {
6404
6550
  * Only the general-purpose subagent inherits the main agent's skills.
6405
6551
  * If a custom subagent needs skills, it must specify its own `skills` array.
6406
6552
  */
6407
- const createSubagentDefaultMiddleware = (input) => {
6553
+ const createSubagentDefaultMiddleware = (input, subagentProfile, forked) => {
6408
6554
  const effectivePermissions = input.permissions ?? permissions;
6409
6555
  return [
6410
6556
  createFilesystemMiddleware({
6411
6557
  backend,
6412
6558
  permissions: effectivePermissions,
6413
- tools: profileFilesystemTools
6559
+ tools: computeProfileFilesystemTools(subagentProfile)
6414
6560
  }),
6415
6561
  createSummarizationMiddleware({ backend }),
6416
6562
  createPatchToolCallsMiddleware(),
6417
- ...input.skills != null && input.skills.length > 0 ? [createSkillsMiddleware({
6563
+ ...!forked && input.skills != null && input.skills.length > 0 ? [createSkillsMiddleware({
6418
6564
  backend,
6419
6565
  sources: input.skills
6420
6566
  })] : []
6421
6567
  ];
6422
6568
  };
6423
- const buildSubagentMiddleware = (input, isForkable) => {
6424
- let subagentMiddleware = mergeMiddlewareStack(createSubagentDefaultMiddleware(input), input.middleware ?? [], [
6425
- ...resolveMiddleware(harnessProfile.extraMiddleware),
6569
+ const buildSubagentMiddleware = (input) => {
6570
+ const subagentProfile = resolveSubagentProfile(input.model);
6571
+ const forked = isForkedSubAgent(input);
6572
+ const subagentDefaultMiddleware = createSubagentDefaultMiddleware(input, subagentProfile, forked);
6573
+ if (forked && skills != null && skills.length > 0) subagentDefaultMiddleware.unshift(createSkillsMiddleware({
6574
+ backend,
6575
+ sources: skills
6576
+ }));
6577
+ let subagentMiddleware = mergeMiddlewareStack(subagentDefaultMiddleware, forked && customMiddleware.length > 0 ? mergeMiddleware$1(customMiddleware, input.middleware ?? []) : input.middleware ?? [], [
6578
+ ...resolveMiddleware(subagentProfile.extraMiddleware),
6426
6579
  ...cacheMiddleware,
6427
- ...isForkable ? memoryMiddleware : []
6580
+ ...forked && memory != null && memory.length > 0 ? [createMemoryMiddleware({
6581
+ backend,
6582
+ sources: memory,
6583
+ addCacheControl: anthropicModel
6584
+ })] : []
6428
6585
  ]);
6429
- if (harnessProfile.excludedMiddleware.size > 0) subagentMiddleware = subagentMiddleware.filter((middleware) => !harnessProfile.excludedMiddleware.has(middleware.name));
6586
+ if (subagentProfile.excludedMiddleware.size > 0) subagentMiddleware = subagentMiddleware.filter((middleware) => !subagentProfile.excludedMiddleware.has(middleware.name));
6587
+ if (subagentProfile.excludedTools.size > 0) subagentMiddleware.push(createToolExclusionMiddleware(subagentProfile.excludedTools));
6430
6588
  return subagentMiddleware;
6431
6589
  };
6432
6590
  const normalizeSubagentSpec = (input) => ({
6433
6591
  ...input,
6434
- tools: input.tools ?? [],
6435
- middleware: buildSubagentMiddleware(input, false)
6436
- });
6437
- const normalizeForkedSubagentSpec = (input) => ({
6438
- ...input,
6439
- tools: input.tools ?? [],
6440
- middleware: buildSubagentMiddleware(input, true)
6592
+ middleware: buildSubagentMiddleware(input)
6441
6593
  });
6442
6594
  const allSubagents = subagents;
6443
6595
  const asyncSubAgents = allSubagents.filter((item) => isAsyncSubAgent(item));
6444
- const inlineSubagents = allSubagents.filter((item) => !isAsyncSubAgent(item)).map((item) => "runnable" in item ? item : isForkedSubAgent(item) ? normalizeForkedSubagentSpec(item) : normalizeSubagentSpec(item));
6596
+ const inlineSubagents = allSubagents.filter((item) => !isAsyncSubAgent(item)).map((item) => "runnable" in item ? item : normalizeSubagentSpec(item));
6445
6597
  const gpConfig = harnessProfile.generalPurposeSubagent;
6446
6598
  if (!(gpConfig?.enabled === false) && !inlineSubagents.some((item) => item.name === GENERAL_PURPOSE_SUBAGENT["name"])) {
6447
6599
  const gpSystemPrompt = gpConfig?.systemPrompt ?? applyProfilePrompt(harnessProfile, GENERAL_PURPOSE_SUBAGENT.systemPrompt);
@@ -8931,4 +9083,4 @@ Object.defineProperty(exports, "serializeProfile", {
8931
9083
  }
8932
9084
  });
8933
9085
 
8934
- //# sourceMappingURL=langsmith-DL32swQ3.cjs.map
9086
+ //# sourceMappingURL=langsmith-BRsbzTlK.cjs.map