diff --git a/packages/api/src/agents/__tests__/run-summarization.test.ts b/packages/api/src/agents/__tests__/run-summarization.test.ts index 5f8fc78eda..83ee5f6959 100644 --- a/packages/api/src/agents/__tests__/run-summarization.test.ts +++ b/packages/api/src/agents/__tests__/run-summarization.test.ts @@ -81,7 +81,7 @@ jest.mock('~/agents/checkpointer', () => ({ getAgentCheckpointer: jest.fn().mockResolvedValue({}), })); -import { Run } from '@librechat/agents'; +import { Run, buildChildInputs } from '@librechat/agents'; /** Minimal RunAgent factory */ function makeAgent( @@ -1020,6 +1020,36 @@ describe('subagentConfigs', () => { expect(configs[0].self).toBeUndefined(); }); + it('preserves explicit nested subagents across the SDK child graph boundary', async () => { + const grandchild = makeAgent({ id: 'agent_grandchild', name: 'Grandchild' }); + const child = makeAgent({ + id: 'agent_child', + name: 'Child', + subagents: { enabled: true, allowSelf: false, agent_ids: ['agent_grandchild'] }, + subagentAgentConfigs: [grandchild], + }); + const agents = await callAndCapture({ + agents: [ + makeAgent({ + subagents: { enabled: true, allowSelf: false, agent_ids: ['agent_child'] }, + subagentAgentConfigs: [child], + }), + ], + }); + + expect(agents[0].maxSubagentDepth).toBe(MAX_SUBAGENT_DEPTH); + const childConfig = (agents[0].subagentConfigs as Parameters[0][])[0]; + expect(childConfig.allowNested).toBe(true); + + const childInputs = buildChildInputs(childConfig, 'agent_child', MAX_SUBAGENT_DEPTH); + expect(childInputs.maxSubagentDepth).toBe(MAX_SUBAGENT_DEPTH - 1); + expect(childInputs.subagentConfigs).toHaveLength(1); + expect(childInputs.subagentConfigs?.[0]).toMatchObject({ + type: 'agent_grandchild', + allowNested: true, + }); + }); + it('combines self-spawn and explicit subagents when both enabled', async () => { const child = makeAgent({ id: 'agent_child', name: 'Helper' }); const agents = await callAndCapture({ diff --git a/packages/api/src/agents/run.ts b/packages/api/src/agents/run.ts index f063fecdf0..e69142d36c 100644 --- a/packages/api/src/agents/run.ts +++ b/packages/api/src/agents/run.ts @@ -991,6 +991,8 @@ function buildSubagentConfigs( child.description ?? `Delegate a subtask to the ${child.name ?? child.id} agent in an isolated context.`, agentInputs: childInputs, + /** Preserve the child's resolved subagent configs when the SDK builds its isolated graph. */ + allowNested: true, /** Honor each child agent's own resolved recursion limit. */ maxTurns: resolveSubagentMaxTurns(agentsEConfig, child), }); @@ -1350,6 +1352,8 @@ export async function createRun({ ); if (subagentConfigs.length > 0) { agentInput.subagentConfigs = subagentConfigs; + /** Seed the SDK countdown that bounds nested delegation across isolated child graphs. */ + agentInput.maxSubagentDepth = MAX_SUBAGENT_DEPTH; } agentInputs.push(agentInput); }