🧫 test: Lock Subagent File Context Propagation (#15126)

This commit is contained in:
Danny Avila 2026-08-23 02:06:57 -04:00 committed by GitHub
parent c411eb4cc6
commit 2018c70040
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 108 additions and 0 deletions

View file

@ -3838,6 +3838,50 @@ describe('AgentClient - titleConvo', () => {
expect(mockAgent.additional_instructions).toContain('Direct primary context');
});
it('hydrates a pure lazy subagent with its own File Context when selected', async () => {
const childContext = makeTextFile('child-context', 'child.txt', 'Pure child private context');
const resolvedChild = {
id: 'pure-child-agent',
endpoint: EModelEndpoint.openAI,
provider: EModelEndpoint.openAI,
instructions: 'Pure child instructions',
model_parameters: { model: 'gpt-4' },
tools: [],
agentContextAttachments: [childContext],
};
const descriptor = {
id: resolvedChild.id,
resolve: jest.fn().mockResolvedValue(resolvedChild),
};
mockAgent.lazySubagentConfigs = [descriptor];
client.agentConfigs = new Map();
await client.buildMessages(
[
{
messageId: 'msg-1',
parentMessageId: null,
sender: 'User',
text: 'Answer from the child context.',
isCreatedByUser: true,
},
],
'msg-1',
{},
);
const resolved = await descriptor.resolve({ signal: new AbortController().signal });
expect(resolved).toBe(resolvedChild);
expect(resolvedChild.additional_instructions).toContain('Pure child private context');
expect(mockAgent.additional_instructions ?? '').not.toContain('Pure child private context');
expect(mockBuildAgentScopedContext).toHaveBeenLastCalledWith(
expect.objectContaining({
agentIds: ['pure-child-agent'],
attachmentsByAgentId: new Map([['pure-child-agent', [childContext]]]),
}),
);
});
});
describe('provider-native YouTube file preflight', () => {

View file

@ -1251,6 +1251,70 @@ describe('subagentConfigs', () => {
expect(childInputs.name).toBe('Researcher');
});
it.each([
['foreground', undefined],
[
'detached',
{
store: new InMemorySubagentTaskStore(),
scopeId: 'file-context-task-scope',
} satisfies SubagentTaskConfig,
],
])("preserves a lazy child's prepared File Context in %s execution", async (_mode, tasks) => {
const fileContext = 'Attached document(s):\n```md\n# "child.txt"\nChild-only facts\n\n```';
const resolve = jest.fn().mockResolvedValue(
makeAgent({
id: 'agent_child',
name: 'Researcher',
additional_instructions: fileContext,
}),
);
const agents = await callAndCapture({
subagentTasks: tasks,
agents: [
makeAgent({
subagents: { enabled: true, allowSelf: false, agent_ids: ['agent_child'] },
lazySubagentConfigs: [
{
id: 'agent_child',
name: 'Researcher',
description: 'Uses private File Context',
configId: 'agent_child:3:fingerprint',
resolve,
},
],
}),
],
});
const [config] = agents[0].subagentConfigs as Array<Record<string, unknown>>;
const childInputs = await (
config.resolveAgentInputs as (context: never) => Promise<Record<string, unknown>>
)({ signal: new AbortController().signal } as never);
expect(childInputs.additional_instructions).toBe(fileContext);
});
it('preserves prepared File Context for an eager legacy subagent', async () => {
const fileContext = 'Attached document(s):\n```md\n# "child.txt"\nLegacy child facts\n\n```';
const child = makeAgent({
id: 'agent_child',
name: 'Researcher',
additional_instructions: fileContext,
});
const agents = await callAndCapture({
agents: [
makeAgent({
subagents: { enabled: true, allowSelf: false, agent_ids: ['agent_child'] },
subagentAgentConfigs: [child],
}),
],
});
const [config] = agents[0].subagentConfigs as Array<Record<string, unknown>>;
const childInputs = config.agentInputs as Record<string, unknown>;
expect(childInputs.additional_instructions).toBe(fileContext);
});
it('uses a fresh expansion budget for each lazy descriptor resolution', async () => {
const nestedDescriptors = Array.from({ length: 99 }, (_, index) => ({
id: `agent_nested_${index}`,