deepagents 1.13.2 → 1.13.3
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/{agent-CH8GB5HD.d.ts → agent-CVBXKZAu.d.ts} +59 -82
- package/dist/{agent-BwYXPTyT.d.cts → agent-D7nWARfg.d.cts} +58 -82
- package/dist/browser.cjs +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/{langsmith-BBV5JlNW.js → langsmith-BYWZnEVh.js} +241 -95
- package/dist/langsmith-BYWZnEVh.js.map +1 -0
- package/dist/{langsmith-DL32swQ3.cjs → langsmith-Ynj9VKxb.cjs} +240 -99
- package/dist/langsmith-Ynj9VKxb.cjs.map +1 -0
- package/dist/node.cjs +2 -2
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +2 -2
- package/dist/{src-CKk0apeE.js → src-Blh1ZEYd.js} +2 -2
- package/dist/{src-CKk0apeE.js.map → src-Blh1ZEYd.js.map} +1 -1
- package/dist/{src-DdGDIhZk.cjs → src-DRMLI0-x.cjs} +2 -2
- package/dist/{src-DdGDIhZk.cjs.map → src-DRMLI0-x.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/langsmith-BBV5JlNW.js.map +0 -1
- package/dist/langsmith-DL32swQ3.cjs.map +0 -1
|
@@ -3382,6 +3382,83 @@ function createSummarizationMiddleware(options) {
|
|
|
3382
3382
|
});
|
|
3383
3383
|
}
|
|
3384
3384
|
//#endregion
|
|
3385
|
+
//#region src/middleware/utils.ts
|
|
3386
|
+
/**
|
|
3387
|
+
* Utility functions for middleware.
|
|
3388
|
+
*
|
|
3389
|
+
* This module provides shared helpers used across middleware implementations.
|
|
3390
|
+
*/
|
|
3391
|
+
/**
|
|
3392
|
+
* Merge custom middleware into an assembled stack by `.name`.
|
|
3393
|
+
*
|
|
3394
|
+
* Matching custom middleware replaces the existing entry in place. New
|
|
3395
|
+
* middleware is appended after the base stack in caller-provided order.
|
|
3396
|
+
*/
|
|
3397
|
+
function mergeMiddleware$1(base, custom) {
|
|
3398
|
+
const merged = new Map(base.map((middleware) => [middleware.name, middleware]));
|
|
3399
|
+
for (const middleware of custom) merged.set(middleware.name, middleware);
|
|
3400
|
+
return [...merged.values()];
|
|
3401
|
+
}
|
|
3402
|
+
function middlewareNames(middleware) {
|
|
3403
|
+
return new Set(middleware.map((entry) => entry.name));
|
|
3404
|
+
}
|
|
3405
|
+
function matchingMiddleware(middleware, names) {
|
|
3406
|
+
return middleware.filter((entry) => names.has(entry.name));
|
|
3407
|
+
}
|
|
3408
|
+
/**
|
|
3409
|
+
* Merge custom middleware into default and tail middleware segments.
|
|
3410
|
+
*
|
|
3411
|
+
* Same-name custom entries replace matching defaults in either segment. Novel
|
|
3412
|
+
* custom entries are inserted between the default and tail segments unless
|
|
3413
|
+
* `appendNew` is false.
|
|
3414
|
+
*/
|
|
3415
|
+
function mergeMiddlewareStack(defaultMiddleware, customMiddleware, tailMiddleware = [], options = {}) {
|
|
3416
|
+
const defaultMiddlewareNames = middlewareNames(defaultMiddleware);
|
|
3417
|
+
const tailMiddlewareNames = middlewareNames(tailMiddleware);
|
|
3418
|
+
const knownMiddlewareNames = /* @__PURE__ */ new Set([...defaultMiddlewareNames, ...tailMiddlewareNames]);
|
|
3419
|
+
const novelMiddleware = options.appendNew === false ? [] : customMiddleware.filter((entry) => !knownMiddlewareNames.has(entry.name));
|
|
3420
|
+
return [
|
|
3421
|
+
...mergeMiddleware$1(defaultMiddleware, matchingMiddleware(customMiddleware, defaultMiddlewareNames)),
|
|
3422
|
+
...novelMiddleware,
|
|
3423
|
+
...mergeMiddleware$1(tailMiddleware, matchingMiddleware(customMiddleware, tailMiddlewareNames))
|
|
3424
|
+
];
|
|
3425
|
+
}
|
|
3426
|
+
/**
|
|
3427
|
+
* Append text to a system message.
|
|
3428
|
+
*
|
|
3429
|
+
* Creates a new SystemMessage with the text appended to the existing content.
|
|
3430
|
+
* If the original message has content, the new text is separated by two newlines.
|
|
3431
|
+
*
|
|
3432
|
+
* @param systemMessage - Existing system message or null/undefined.
|
|
3433
|
+
* @param text - Text to add to the system message.
|
|
3434
|
+
* @returns New SystemMessage with the text appended.
|
|
3435
|
+
*
|
|
3436
|
+
* @example
|
|
3437
|
+
* ```typescript
|
|
3438
|
+
* const original = new SystemMessage({ content: "You are a helpful assistant." });
|
|
3439
|
+
* const updated = appendToSystemMessage(original, "Always be concise.");
|
|
3440
|
+
* // Result: SystemMessage with content "You are a helpful assistant.\n\nAlways be concise."
|
|
3441
|
+
* ```
|
|
3442
|
+
*/
|
|
3443
|
+
function appendToSystemMessage(systemMessage, text) {
|
|
3444
|
+
if (!systemMessage) return new _langchain_core_messages.SystemMessage({ content: text });
|
|
3445
|
+
const existingContent = systemMessage.content;
|
|
3446
|
+
if (typeof existingContent === "string") {
|
|
3447
|
+
const newContent = existingContent ? `${existingContent}\n\n${text}` : text;
|
|
3448
|
+
return new _langchain_core_messages.SystemMessage({ content: newContent });
|
|
3449
|
+
}
|
|
3450
|
+
if (Array.isArray(existingContent)) {
|
|
3451
|
+
const newContent = [...existingContent];
|
|
3452
|
+
const textToAdd = newContent.length > 0 ? `\n\n${text}` : text;
|
|
3453
|
+
newContent.push({
|
|
3454
|
+
type: "text",
|
|
3455
|
+
text: textToAdd
|
|
3456
|
+
});
|
|
3457
|
+
return new _langchain_core_messages.SystemMessage({ content: newContent });
|
|
3458
|
+
}
|
|
3459
|
+
return new _langchain_core_messages.SystemMessage({ content: text });
|
|
3460
|
+
}
|
|
3461
|
+
//#endregion
|
|
3385
3462
|
//#region src/middleware/subagents.ts
|
|
3386
3463
|
/**
|
|
3387
3464
|
* Config key used by task-tool callers to request dynamic response format.
|
|
@@ -3395,6 +3472,8 @@ const SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY = "__deepagents_subagent_response_form
|
|
|
3395
3472
|
* Provides a minimal base prompt that can be extended by specific subagent configurations.
|
|
3396
3473
|
*/
|
|
3397
3474
|
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.";
|
|
3475
|
+
const FORKED_CONTEXT_KEY = "_deepagentsForkedContext";
|
|
3476
|
+
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
3477
|
/**
|
|
3399
3478
|
* State keys excluded when passing state to subagents and when returning
|
|
3400
3479
|
* updates from subagents. Summarization keys are excluded because their
|
|
@@ -3407,6 +3486,18 @@ const EXCLUDED_STATE_KEYS = [
|
|
|
3407
3486
|
"skillsMetadata",
|
|
3408
3487
|
"memoryContents",
|
|
3409
3488
|
"_summarizationEvent",
|
|
3489
|
+
"_summarizationSessionId",
|
|
3490
|
+
FORKED_CONTEXT_KEY
|
|
3491
|
+
];
|
|
3492
|
+
/**
|
|
3493
|
+
* State keys excluded when inheriting state into a declarative fork.
|
|
3494
|
+
* Narrower than `EXCLUDED_STATE_KEYS`: a fork's mirrored middleware needs
|
|
3495
|
+
* the parent's private channels (skills metadata, memory contents, etc.)
|
|
3496
|
+
* to rebuild an equivalent prompt.
|
|
3497
|
+
*/
|
|
3498
|
+
const FORK_EXCLUDED_STATE_KEYS = [
|
|
3499
|
+
"structuredResponse",
|
|
3500
|
+
"_summarizationEvent",
|
|
3410
3501
|
"_summarizationSessionId"
|
|
3411
3502
|
];
|
|
3412
3503
|
/**
|
|
@@ -3416,25 +3507,37 @@ const EXCLUDED_STATE_KEYS = [
|
|
|
3416
3507
|
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
3508
|
function getTaskToolDescription(subagentDescriptions) {
|
|
3418
3509
|
return langchain.context`
|
|
3419
|
-
Launch an ephemeral subagent to handle a complex, multi-step task
|
|
3510
|
+
Launch an ephemeral subagent to handle a complex, multi-step task.
|
|
3420
3511
|
|
|
3421
3512
|
Available agent types and the tools they have access to:
|
|
3422
3513
|
${subagentDescriptions.join("\n")}
|
|
3423
3514
|
|
|
3424
3515
|
Specify subagent_type to select the agent. Usage notes:
|
|
3425
3516
|
- 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.
|
|
3517
|
+
- 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
3518
|
- 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
|
|
3519
|
+
- 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
3520
|
- If an agent's description says to use it proactively, do so without waiting to be asked.
|
|
3430
3521
|
- When only general-purpose is available, use it for any complex, context-heavy task; it has the same capabilities as the main agent.
|
|
3431
3522
|
`;
|
|
3432
3523
|
}
|
|
3524
|
+
const FORKED_SUBAGENT_TOOL_NOTE = " (inherits your full conversation and system prompt — no need to restate context here)";
|
|
3525
|
+
const COMPILED_FORKED_SUBAGENT_TOOL_NOTE = " (inherits your conversation history — its system prompt is fixed in its own runnable)";
|
|
3526
|
+
/** Render one subagent's listing line for the task tool description. */
|
|
3527
|
+
function describeSubagentForTool(name, description, forked, compiled = false) {
|
|
3528
|
+
return `- ${name}: ${description}${forked ? compiled ? COMPILED_FORKED_SUBAGENT_TOOL_NOTE : FORKED_SUBAGENT_TOOL_NOTE : ""}`;
|
|
3529
|
+
}
|
|
3530
|
+
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";
|
|
3531
|
+
/**
|
|
3532
|
+
* Whether a declarative subagent spec has `mode: "fork"` set.
|
|
3533
|
+
*
|
|
3534
|
+
* A plain boolean, not a type predicate: `SubAgent` covers both `"fork"` and
|
|
3535
|
+
* `"isolated"`, so there's no distinct type left to narrow to.
|
|
3536
|
+
*/
|
|
3433
3537
|
function isForkedSubAgent(value) {
|
|
3434
3538
|
if (typeof value !== "object" || value == null) return false;
|
|
3435
3539
|
if (!("mode" in value)) return false;
|
|
3436
|
-
|
|
3437
|
-
return true;
|
|
3540
|
+
return value.mode === "fork";
|
|
3438
3541
|
}
|
|
3439
3542
|
/**
|
|
3440
3543
|
* Base specification for the general-purpose subagent.
|
|
@@ -3477,15 +3580,26 @@ const GENERAL_PURPOSE_SUBAGENT = {
|
|
|
3477
3580
|
name: "general-purpose",
|
|
3478
3581
|
description: DEFAULT_GENERAL_PURPOSE_DESCRIPTION,
|
|
3479
3582
|
systemPrompt: DEFAULT_SUBAGENT_PROMPT,
|
|
3480
|
-
mode: "
|
|
3583
|
+
mode: "isolated"
|
|
3481
3584
|
};
|
|
3585
|
+
function filterState(state, excludedKeys) {
|
|
3586
|
+
const filtered = {};
|
|
3587
|
+
for (const [key, value] of Object.entries(state)) if (!excludedKeys.includes(key)) filtered[key] = value;
|
|
3588
|
+
return filtered;
|
|
3589
|
+
}
|
|
3482
3590
|
/**
|
|
3483
3591
|
* Filter state to exclude certain keys when passing to subagents
|
|
3484
3592
|
*/
|
|
3485
3593
|
function filterStateForSubagent(state) {
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3594
|
+
return filterState(state, EXCLUDED_STATE_KEYS);
|
|
3595
|
+
}
|
|
3596
|
+
/**
|
|
3597
|
+
* Filter state to exclude only the keys a declarative fork must not resume
|
|
3598
|
+
* (structured response, summarization event/session) — see
|
|
3599
|
+
* `FORK_EXCLUDED_STATE_KEYS`.
|
|
3600
|
+
*/
|
|
3601
|
+
function filterStateForFork(state) {
|
|
3602
|
+
return filterState(state, FORK_EXCLUDED_STATE_KEYS);
|
|
3489
3603
|
}
|
|
3490
3604
|
/**
|
|
3491
3605
|
* Invalid tool message block types
|
|
@@ -3529,6 +3643,15 @@ function stripInFlightAIMessage(messages) {
|
|
|
3529
3643
|
const last = messages.at(-1);
|
|
3530
3644
|
return _langchain_core_messages.AIMessage.isInstance(last) && (last.tool_calls?.length ?? 0) > 0 ? messages.slice(0, -1) : messages;
|
|
3531
3645
|
}
|
|
3646
|
+
const ForkedContextStateSchema = zod_v4.z.object({ [FORKED_CONTEXT_KEY]: zod_v4.z.boolean().optional() });
|
|
3647
|
+
function createForkTaskToolMiddleware(taskTool) {
|
|
3648
|
+
return (0, langchain.createMiddleware)({
|
|
3649
|
+
name: "forkTaskToolMiddleware",
|
|
3650
|
+
stateSchema: ForkedContextStateSchema,
|
|
3651
|
+
tools: [taskTool],
|
|
3652
|
+
beforeAgent: () => ({ [FORKED_CONTEXT_KEY]: true })
|
|
3653
|
+
});
|
|
3654
|
+
}
|
|
3532
3655
|
/**
|
|
3533
3656
|
* Create a runnable agent from a declarative `SubAgent` spec.
|
|
3534
3657
|
*
|
|
@@ -3558,6 +3681,17 @@ function createSubAgent(spec, options) {
|
|
|
3558
3681
|
});
|
|
3559
3682
|
}
|
|
3560
3683
|
/**
|
|
3684
|
+
* Resolve a fork's system prompt: the parent's inherited prompt, with the
|
|
3685
|
+
* fork's own systemPrompt (if any) appended as an addendum rather than
|
|
3686
|
+
* replacing it.
|
|
3687
|
+
*/
|
|
3688
|
+
function resolveForkSystemPrompt(parentSystemPrompt, forkAddendum) {
|
|
3689
|
+
if (!forkAddendum) return parentSystemPrompt ?? "";
|
|
3690
|
+
const addendumText = typeof forkAddendum === "string" ? forkAddendum : forkAddendum.text;
|
|
3691
|
+
if (langchain.SystemMessage.isInstance(parentSystemPrompt)) return appendToSystemMessage(parentSystemPrompt, addendumText);
|
|
3692
|
+
return parentSystemPrompt ? `${parentSystemPrompt}\n\n${addendumText}` : addendumText;
|
|
3693
|
+
}
|
|
3694
|
+
/**
|
|
3561
3695
|
* Create subagent instances from specifications.
|
|
3562
3696
|
*
|
|
3563
3697
|
* Returns compiled agents, raw specs keyed by name (for on-demand
|
|
@@ -3565,13 +3699,18 @@ function createSubAgent(spec, options) {
|
|
|
3565
3699
|
* of names that should fork the parent's conversation.
|
|
3566
3700
|
*/
|
|
3567
3701
|
function getSubagents(options) {
|
|
3568
|
-
const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware: gpMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, parentSystemPrompt = null } = options;
|
|
3702
|
+
const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware: gpMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, parentSystemPrompt = null, mirroredTaskTool } = options;
|
|
3569
3703
|
const defaultSubagentMiddleware = defaultMiddleware || [];
|
|
3570
3704
|
const generalPurposeMiddlewareBase = gpMiddleware || defaultSubagentMiddleware;
|
|
3571
3705
|
const agents = {};
|
|
3572
3706
|
const specsByName = {};
|
|
3573
3707
|
const subagentDescriptions = [];
|
|
3574
3708
|
const forkModeNames = /* @__PURE__ */ new Set();
|
|
3709
|
+
const seenNames = new Set(generalPurposeAgent ? ["general-purpose"] : []);
|
|
3710
|
+
for (const agentParams of subagents) {
|
|
3711
|
+
if (seenNames.has(agentParams.name)) throw new Error(`Duplicate subagent name '${agentParams.name}'; each subagent must have a unique name.`);
|
|
3712
|
+
seenNames.add(agentParams.name);
|
|
3713
|
+
}
|
|
3575
3714
|
if (generalPurposeAgent) {
|
|
3576
3715
|
const generalPurposeMiddleware = [...generalPurposeMiddlewareBase];
|
|
3577
3716
|
if (defaultInterruptOn) generalPurposeMiddleware.push((0, langchain.humanInTheLoopMiddleware)({ interruptOn: defaultInterruptOn }));
|
|
@@ -3585,24 +3724,34 @@ function getSubagents(options) {
|
|
|
3585
3724
|
};
|
|
3586
3725
|
agents["general-purpose"] = createSubAgent(gpSpec);
|
|
3587
3726
|
specsByName["general-purpose"] = gpSpec;
|
|
3588
|
-
subagentDescriptions.push(
|
|
3727
|
+
subagentDescriptions.push(describeSubagentForTool("general-purpose", DEFAULT_GENERAL_PURPOSE_DESCRIPTION, false));
|
|
3589
3728
|
}
|
|
3590
3729
|
for (const agentParams of subagents) {
|
|
3591
3730
|
const rawMode = agentParams.mode;
|
|
3592
|
-
if (rawMode != null && rawMode !== "
|
|
3593
|
-
|
|
3731
|
+
if (rawMode != null && rawMode !== "isolated" && rawMode !== "fork" && rawMode !== "handoff") throw new Error(`SubAgent '${agentParams.name}' has invalid mode '${rawMode}' — must be "isolated" or "fork".`);
|
|
3732
|
+
const forked = isForkedSubAgent(agentParams);
|
|
3733
|
+
const compiled = "runnable" in agentParams;
|
|
3734
|
+
subagentDescriptions.push(describeSubagentForTool(agentParams.name, agentParams.description, forked, compiled));
|
|
3594
3735
|
if ("runnable" in agentParams) {
|
|
3595
3736
|
agents[agentParams.name] = agentParams.runnable;
|
|
3596
3737
|
specsByName[agentParams.name] = agentParams;
|
|
3597
|
-
if (
|
|
3598
|
-
|
|
3738
|
+
if (forked) forkModeNames.add(agentParams.name);
|
|
3739
|
+
continue;
|
|
3740
|
+
}
|
|
3741
|
+
const subagentMiddleware = [...defaultSubagentMiddleware, ...agentParams.middleware ?? []];
|
|
3742
|
+
if (forked) {
|
|
3743
|
+
const rawSkills = agentParams.skills;
|
|
3744
|
+
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.`);
|
|
3745
|
+
const resolvedSystemPrompt = resolveForkSystemPrompt(parentSystemPrompt, agentParams.systemPrompt);
|
|
3746
|
+
const fsIndex = subagentMiddleware.findIndex((m) => m.name === "FilesystemMiddleware");
|
|
3747
|
+
subagentMiddleware.splice(fsIndex + 1, 0, createForkTaskToolMiddleware(mirroredTaskTool));
|
|
3599
3748
|
const resolvedSpec = {
|
|
3600
3749
|
...agentParams,
|
|
3601
|
-
systemPrompt:
|
|
3750
|
+
systemPrompt: resolvedSystemPrompt,
|
|
3602
3751
|
mode: void 0,
|
|
3603
3752
|
model: agentParams.model ?? defaultModel,
|
|
3604
3753
|
tools: agentParams.tools ?? defaultTools,
|
|
3605
|
-
middleware:
|
|
3754
|
+
middleware: subagentMiddleware,
|
|
3606
3755
|
interruptOn: agentParams.interruptOn ?? defaultInterruptOn ?? void 0
|
|
3607
3756
|
};
|
|
3608
3757
|
agents[agentParams.name] = createSubAgent(resolvedSpec);
|
|
@@ -3611,10 +3760,10 @@ function getSubagents(options) {
|
|
|
3611
3760
|
} else {
|
|
3612
3761
|
const resolvedSpec = {
|
|
3613
3762
|
...agentParams,
|
|
3614
|
-
mode: "
|
|
3763
|
+
mode: "isolated",
|
|
3615
3764
|
model: agentParams.model ?? defaultModel,
|
|
3616
3765
|
tools: agentParams.tools ?? defaultTools,
|
|
3617
|
-
middleware:
|
|
3766
|
+
middleware: subagentMiddleware,
|
|
3618
3767
|
interruptOn: agentParams.interruptOn ?? defaultInterruptOn ?? void 0
|
|
3619
3768
|
};
|
|
3620
3769
|
agents[agentParams.name] = createSubAgent(resolvedSpec);
|
|
@@ -3633,16 +3782,12 @@ function getSubagents(options) {
|
|
|
3633
3782
|
*/
|
|
3634
3783
|
function createTaskTool(options) {
|
|
3635
3784
|
const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, taskDescription, parentSystemPrompt = null } = options;
|
|
3636
|
-
const
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
subagents,
|
|
3643
|
-
generalPurposeAgent,
|
|
3644
|
-
parentSystemPrompt
|
|
3645
|
-
});
|
|
3785
|
+
const subagentNames = [...generalPurposeAgent ? ["general-purpose"] : [], ...subagents.map((spec) => spec.name)];
|
|
3786
|
+
const subagentDescriptions = [...generalPurposeAgent ? [describeSubagentForTool("general-purpose", DEFAULT_GENERAL_PURPOSE_DESCRIPTION, false)] : [], ...subagents.map((spec) => describeSubagentForTool(spec.name, spec.description, isForkedSubAgent(spec), "runnable" in spec))];
|
|
3787
|
+
const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
|
|
3788
|
+
let subagentGraphs = {};
|
|
3789
|
+
let specsByName = {};
|
|
3790
|
+
let forkModeNames = /* @__PURE__ */ new Set();
|
|
3646
3791
|
function selectSubagent(subagentType, config) {
|
|
3647
3792
|
const spec = specsByName[subagentType];
|
|
3648
3793
|
const responseFormat = config.configurable?.[SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY];
|
|
@@ -3650,18 +3795,19 @@ function createTaskTool(options) {
|
|
|
3650
3795
|
if ("runnable" in spec || responseFormat == null) return subagentGraphs[subagentType];
|
|
3651
3796
|
return createSubAgent(spec, { responseFormat });
|
|
3652
3797
|
}
|
|
3653
|
-
|
|
3654
|
-
return (0, langchain.tool)(async (input, config) => {
|
|
3798
|
+
async function runTask(input, config) {
|
|
3655
3799
|
const { description, subagent_type } = input;
|
|
3800
|
+
const currentState = (0, _langchain_langgraph.getCurrentTaskInput)();
|
|
3801
|
+
if (currentState[FORKED_CONTEXT_KEY]) return FORK_RECURSION_REFUSAL;
|
|
3656
3802
|
if (!(subagent_type in subagentGraphs)) {
|
|
3657
3803
|
const allowedTypes = Object.keys(subagentGraphs).map((k) => `\`${k}\``).join(", ");
|
|
3658
3804
|
throw new Error(`Error: invoked agent of type ${subagent_type}, the only allowed types are ${allowedTypes}`);
|
|
3659
3805
|
}
|
|
3660
3806
|
const shouldFork = forkModeNames.has(subagent_type);
|
|
3661
3807
|
const subagent = selectSubagent(subagent_type, config);
|
|
3662
|
-
const
|
|
3663
|
-
const subagentState = filterStateForSubagent(currentState);
|
|
3664
|
-
if (shouldFork) subagentState.messages = [...getEffectiveMessages(stripInFlightAIMessage(currentState.messages ?? []), currentState), new _langchain_core_messages.HumanMessage({ content: description })];
|
|
3808
|
+
const spec = specsByName[subagent_type];
|
|
3809
|
+
const subagentState = shouldFork && !("runnable" in spec) ? filterStateForFork(currentState) : filterStateForSubagent(currentState);
|
|
3810
|
+
if (shouldFork) subagentState.messages = [...getEffectiveMessages(stripInFlightAIMessage(currentState.messages ?? []), currentState), new _langchain_core_messages.HumanMessage({ content: FORK_TASK_PREAMBLE + description })];
|
|
3665
3811
|
else subagentState.messages = [new _langchain_core_messages.HumanMessage({ content: description })];
|
|
3666
3812
|
subagentState._summarizationSessionId = `session_${crypto.randomUUID().substring(0, 8)}`;
|
|
3667
3813
|
const subagentConfig = {
|
|
@@ -3688,14 +3834,35 @@ function createTaskTool(options) {
|
|
|
3688
3834
|
return content;
|
|
3689
3835
|
}
|
|
3690
3836
|
return returnCommandWithStateUpdate(result, config.toolCall.id);
|
|
3691
|
-
}
|
|
3837
|
+
}
|
|
3838
|
+
const taskToolSchema = zod_v4.z.object({
|
|
3839
|
+
description: zod_v4.z.string().describe("The task to execute with the selected agent"),
|
|
3840
|
+
subagent_type: zod_v4.z.string().describe(`Name of the agent to use. Available: ${subagentNames.join(", ")}`)
|
|
3841
|
+
});
|
|
3842
|
+
const taskTool = (0, langchain.tool)(runTask, {
|
|
3692
3843
|
name: "task",
|
|
3693
3844
|
description: finalTaskDescription,
|
|
3694
|
-
schema:
|
|
3695
|
-
|
|
3696
|
-
|
|
3845
|
+
schema: taskToolSchema
|
|
3846
|
+
});
|
|
3847
|
+
const { agents, specsByName: resolvedSpecsByName, forkModeNames: resolvedForkModeNames } = getSubagents({
|
|
3848
|
+
defaultModel,
|
|
3849
|
+
defaultTools,
|
|
3850
|
+
defaultMiddleware,
|
|
3851
|
+
generalPurposeMiddleware,
|
|
3852
|
+
defaultInterruptOn,
|
|
3853
|
+
subagents,
|
|
3854
|
+
generalPurposeAgent,
|
|
3855
|
+
parentSystemPrompt,
|
|
3856
|
+
mirroredTaskTool: (0, langchain.tool)(runTask, {
|
|
3857
|
+
name: "task",
|
|
3858
|
+
description: finalTaskDescription,
|
|
3859
|
+
schema: taskToolSchema
|
|
3697
3860
|
})
|
|
3698
3861
|
});
|
|
3862
|
+
subagentGraphs = agents;
|
|
3863
|
+
specsByName = resolvedSpecsByName;
|
|
3864
|
+
forkModeNames = resolvedForkModeNames;
|
|
3865
|
+
return taskTool;
|
|
3699
3866
|
}
|
|
3700
3867
|
/**
|
|
3701
3868
|
* Create subagent middleware with task tool
|
|
@@ -4697,48 +4864,6 @@ function createSkillsMiddleware(options) {
|
|
|
4697
4864
|
});
|
|
4698
4865
|
}
|
|
4699
4866
|
//#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
4867
|
//#region src/middleware/completion_callback.ts
|
|
4743
4868
|
/**
|
|
4744
4869
|
* Callback middleware for async subagents.
|
|
@@ -6367,8 +6492,18 @@ function createDeepAgent(params = {}) {
|
|
|
6367
6492
|
providerHint: getModelProvider(model),
|
|
6368
6493
|
identifierHint: getModelIdentifier(model)
|
|
6369
6494
|
});
|
|
6370
|
-
const
|
|
6371
|
-
|
|
6495
|
+
const computeProfileFilesystemTools = (profile) => {
|
|
6496
|
+
const filesystemTools = FILESYSTEM_TOOL_NAMES.filter((toolName) => !profile.excludedTools.has(toolName));
|
|
6497
|
+
return filesystemTools.length === FILESYSTEM_TOOL_NAMES.length ? void 0 : filesystemTools.includes("read_file") ? filesystemTools : ["read_file", ...filesystemTools];
|
|
6498
|
+
};
|
|
6499
|
+
const profileFilesystemTools = computeProfileFilesystemTools(harnessProfile);
|
|
6500
|
+
const resolveSubagentProfile = (subagentModel) => {
|
|
6501
|
+
if (subagentModel == null || subagentModel === model) return harnessProfile;
|
|
6502
|
+
return typeof subagentModel === "string" ? resolveHarnessProfile({ spec: subagentModel }) : resolveHarnessProfile({
|
|
6503
|
+
providerHint: getModelProvider(subagentModel),
|
|
6504
|
+
identifierHint: getModelIdentifier(subagentModel)
|
|
6505
|
+
});
|
|
6506
|
+
};
|
|
6372
6507
|
const toolOverrides = harnessProfile.toolDescriptionOverrides;
|
|
6373
6508
|
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
6509
|
const anthropicModel = isAnthropicModel(model);
|
|
@@ -6404,44 +6539,50 @@ function createDeepAgent(params = {}) {
|
|
|
6404
6539
|
* Only the general-purpose subagent inherits the main agent's skills.
|
|
6405
6540
|
* If a custom subagent needs skills, it must specify its own `skills` array.
|
|
6406
6541
|
*/
|
|
6407
|
-
const createSubagentDefaultMiddleware = (input) => {
|
|
6542
|
+
const createSubagentDefaultMiddleware = (input, subagentProfile, forked) => {
|
|
6408
6543
|
const effectivePermissions = input.permissions ?? permissions;
|
|
6409
6544
|
return [
|
|
6410
6545
|
createFilesystemMiddleware({
|
|
6411
6546
|
backend,
|
|
6412
6547
|
permissions: effectivePermissions,
|
|
6413
|
-
tools:
|
|
6548
|
+
tools: computeProfileFilesystemTools(subagentProfile)
|
|
6414
6549
|
}),
|
|
6415
6550
|
createSummarizationMiddleware({ backend }),
|
|
6416
6551
|
createPatchToolCallsMiddleware(),
|
|
6417
|
-
|
|
6552
|
+
...!forked && input.skills != null && input.skills.length > 0 ? [createSkillsMiddleware({
|
|
6418
6553
|
backend,
|
|
6419
6554
|
sources: input.skills
|
|
6420
6555
|
})] : []
|
|
6421
6556
|
];
|
|
6422
6557
|
};
|
|
6423
|
-
const buildSubagentMiddleware = (input
|
|
6424
|
-
|
|
6425
|
-
|
|
6558
|
+
const buildSubagentMiddleware = (input) => {
|
|
6559
|
+
const subagentProfile = resolveSubagentProfile(input.model);
|
|
6560
|
+
const forked = isForkedSubAgent(input);
|
|
6561
|
+
const subagentDefaultMiddleware = createSubagentDefaultMiddleware(input, subagentProfile, forked);
|
|
6562
|
+
if (forked && skills != null && skills.length > 0) subagentDefaultMiddleware.unshift(createSkillsMiddleware({
|
|
6563
|
+
backend,
|
|
6564
|
+
sources: skills
|
|
6565
|
+
}));
|
|
6566
|
+
let subagentMiddleware = mergeMiddlewareStack(subagentDefaultMiddleware, forked && customMiddleware.length > 0 ? mergeMiddleware$1(customMiddleware, input.middleware ?? []) : input.middleware ?? [], [
|
|
6567
|
+
...resolveMiddleware(subagentProfile.extraMiddleware),
|
|
6426
6568
|
...cacheMiddleware,
|
|
6427
|
-
...
|
|
6569
|
+
...forked && memory != null && memory.length > 0 ? [createMemoryMiddleware({
|
|
6570
|
+
backend,
|
|
6571
|
+
sources: memory,
|
|
6572
|
+
addCacheControl: anthropicModel
|
|
6573
|
+
})] : []
|
|
6428
6574
|
]);
|
|
6429
|
-
if (
|
|
6575
|
+
if (subagentProfile.excludedMiddleware.size > 0) subagentMiddleware = subagentMiddleware.filter((middleware) => !subagentProfile.excludedMiddleware.has(middleware.name));
|
|
6576
|
+
if (subagentProfile.excludedTools.size > 0) subagentMiddleware.push(createToolExclusionMiddleware(subagentProfile.excludedTools));
|
|
6430
6577
|
return subagentMiddleware;
|
|
6431
6578
|
};
|
|
6432
6579
|
const normalizeSubagentSpec = (input) => ({
|
|
6433
6580
|
...input,
|
|
6434
|
-
|
|
6435
|
-
middleware: buildSubagentMiddleware(input, false)
|
|
6436
|
-
});
|
|
6437
|
-
const normalizeForkedSubagentSpec = (input) => ({
|
|
6438
|
-
...input,
|
|
6439
|
-
tools: input.tools ?? [],
|
|
6440
|
-
middleware: buildSubagentMiddleware(input, true)
|
|
6581
|
+
middleware: buildSubagentMiddleware(input)
|
|
6441
6582
|
});
|
|
6442
6583
|
const allSubagents = subagents;
|
|
6443
6584
|
const asyncSubAgents = allSubagents.filter((item) => isAsyncSubAgent(item));
|
|
6444
|
-
const inlineSubagents = allSubagents.filter((item) => !isAsyncSubAgent(item)).map((item) => "runnable" in item ? item :
|
|
6585
|
+
const inlineSubagents = allSubagents.filter((item) => !isAsyncSubAgent(item)).map((item) => "runnable" in item ? item : normalizeSubagentSpec(item));
|
|
6445
6586
|
const gpConfig = harnessProfile.generalPurposeSubagent;
|
|
6446
6587
|
if (!(gpConfig?.enabled === false) && !inlineSubagents.some((item) => item.name === GENERAL_PURPOSE_SUBAGENT["name"])) {
|
|
6447
6588
|
const gpSystemPrompt = gpConfig?.systemPrompt ?? applyProfilePrompt(harnessProfile, GENERAL_PURPOSE_SUBAGENT.systemPrompt);
|
|
@@ -8931,4 +9072,4 @@ Object.defineProperty(exports, "serializeProfile", {
|
|
|
8931
9072
|
}
|
|
8932
9073
|
});
|
|
8933
9074
|
|
|
8934
|
-
//# sourceMappingURL=langsmith-
|
|
9075
|
+
//# sourceMappingURL=langsmith-Ynj9VKxb.cjs.map
|