[GH-ISSUE #51] Is here a way to cause the DeepAgent and/or subagents to return the output with favour of zod schema? #14

Closed
opened 2026-02-16 06:16:48 -05:00 by yindo · 2 comments
Owner

Originally created by @kotekpsotek on GitHub (Nov 8, 2025).
Original GitHub issue: https://github.com/langchain-ai/deepagentsjs/issues/51

Does exist builtin mechanism to handle a zod schema as a final output of a createDeepAgent function for convininience?

If not: Can it be implemented in the initial form for deepagent supervisor/planner and the subagents?

Since this method doesn't work:

const agent = createDeepAgent({
        model: supervisorModel.withStructuredOutput(deepAgentsActionAnswerSchema as any),
        tools: [], 
        middleware: [],
        subagents: [
            researcher
        ],
        systemPrompt: systemPromptBasicFiles["supervisor"]
    })

while in ai provider llm handler definition for withStructuredOutput method is:

// ... Class internal scope
withStructuredOutput(outputSchema, config) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const schema = outputSchema;
        const name = config?.name;
        const method = config?.method;
        const includeRaw = config?.includeRaw;
        if (method === "jsonMode") {
            throw new Error(`ChatGoogleGenerativeAI only supports "jsonSchema" or "functionCalling" as a method.`);
        }
        let llm;
        let outputParser;
        if (method === "functionCalling") {
            let functionName = name ?? "extract";
            let tools;
            if (isInteropZodSchema(schema)) {
                const jsonSchema = schemaToGenerativeAIParameters(schema);
                tools = [
                    {
                        functionDeclarations: [
                            {
                                name: functionName,
                                description: jsonSchema.description ?? "A function available to call.",
                                parameters: jsonSchema,
                            },
                        ],
                    },
                ];
                outputParser = new GoogleGenerativeAIToolsOutputParser({
                    returnSingle: true,
                    keyName: functionName,
                    zodSchema: schema,
                });
            }
            else {
                let geminiFunctionDefinition;
                if (typeof schema.name === "string" &&
                    typeof schema.parameters === "object" &&
                    schema.parameters != null) {
                    geminiFunctionDefinition = schema;
                    geminiFunctionDefinition.parameters = removeAdditionalProperties(schema.parameters);
                    functionName = schema.name;
                }
                else {
                    geminiFunctionDefinition = {
                        name: functionName,
                        description: schema.description ?? "",
                        parameters: removeAdditionalProperties(schema),
                    };
                }
                tools = [
                    {
                        functionDeclarations: [geminiFunctionDefinition],
                    },
                ];
                outputParser = new GoogleGenerativeAIToolsOutputParser({
                    returnSingle: true,
                    keyName: functionName,
                });
            }
            llm = this.bindTools(tools).withConfig({
                allowedFunctionNames: [functionName],
            });
        }
        else {
            const jsonSchema = schemaToGenerativeAIParameters(schema);
            llm = this.withConfig({
                responseSchema: jsonSchema,
            });
            outputParser = new JsonOutputParser();
        }
        if (!includeRaw) {
            return llm.pipe(outputParser).withConfig({
                runName: "ChatGoogleGenerativeAIStructuredOutput",
            });
        }
        const parserAssign = RunnablePassthrough.assign({
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            parsed: (input, config) => outputParser.invoke(input.raw, config),
        });
        const parserNone = RunnablePassthrough.assign({
            parsed: () => null,
        });
        const parsedWithFallback = parserAssign.withFallbacks({
            fallbacks: [parserNone],
        });
        return RunnableSequence.from([
            {
                raw: llm,
            },
            parsedWithFallback,
        ]).withConfig({
            runName: "StructuredOutputRunnable",
        });
    }

neither there isn't any property in createDeepAgent config object to provide the output schema in same fashion as is for tool LangChain function.

Additionally:

  • Zod Schema doesn't offer to string parser so there isn't option to simply parse it to string with keeping the specification, although you can use zod-to-json-schema library to make from your schema json output and specify it to the prompt;
Originally created by @kotekpsotek on GitHub (Nov 8, 2025). Original GitHub issue: https://github.com/langchain-ai/deepagentsjs/issues/51 ## Does exist builtin mechanism to handle a zod schema as a final output of a `createDeepAgent` function for convininience? ### If not: Can it be implemented in the initial form for deepagent supervisor/planner and the subagents? Since this method doesn't work: ```typescript const agent = createDeepAgent({ model: supervisorModel.withStructuredOutput(deepAgentsActionAnswerSchema as any), tools: [], middleware: [], subagents: [ researcher ], systemPrompt: systemPromptBasicFiles["supervisor"] }) ``` while in `ai provider llm handler` definition for withStructuredOutput method is: ```typescript // ... Class internal scope withStructuredOutput(outputSchema, config) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const schema = outputSchema; const name = config?.name; const method = config?.method; const includeRaw = config?.includeRaw; if (method === "jsonMode") { throw new Error(`ChatGoogleGenerativeAI only supports "jsonSchema" or "functionCalling" as a method.`); } let llm; let outputParser; if (method === "functionCalling") { let functionName = name ?? "extract"; let tools; if (isInteropZodSchema(schema)) { const jsonSchema = schemaToGenerativeAIParameters(schema); tools = [ { functionDeclarations: [ { name: functionName, description: jsonSchema.description ?? "A function available to call.", parameters: jsonSchema, }, ], }, ]; outputParser = new GoogleGenerativeAIToolsOutputParser({ returnSingle: true, keyName: functionName, zodSchema: schema, }); } else { let geminiFunctionDefinition; if (typeof schema.name === "string" && typeof schema.parameters === "object" && schema.parameters != null) { geminiFunctionDefinition = schema; geminiFunctionDefinition.parameters = removeAdditionalProperties(schema.parameters); functionName = schema.name; } else { geminiFunctionDefinition = { name: functionName, description: schema.description ?? "", parameters: removeAdditionalProperties(schema), }; } tools = [ { functionDeclarations: [geminiFunctionDefinition], }, ]; outputParser = new GoogleGenerativeAIToolsOutputParser({ returnSingle: true, keyName: functionName, }); } llm = this.bindTools(tools).withConfig({ allowedFunctionNames: [functionName], }); } else { const jsonSchema = schemaToGenerativeAIParameters(schema); llm = this.withConfig({ responseSchema: jsonSchema, }); outputParser = new JsonOutputParser(); } if (!includeRaw) { return llm.pipe(outputParser).withConfig({ runName: "ChatGoogleGenerativeAIStructuredOutput", }); } const parserAssign = RunnablePassthrough.assign({ // eslint-disable-next-line @typescript-eslint/no-explicit-any parsed: (input, config) => outputParser.invoke(input.raw, config), }); const parserNone = RunnablePassthrough.assign({ parsed: () => null, }); const parsedWithFallback = parserAssign.withFallbacks({ fallbacks: [parserNone], }); return RunnableSequence.from([ { raw: llm, }, parsedWithFallback, ]).withConfig({ runName: "StructuredOutputRunnable", }); } ``` neither there isn't any property in createDeepAgent config object to provide the output schema in same fashion as is for `tool` LangChain function. ### Additionally: - Zod Schema doesn't offer to string parser so there isn't option to simply parse it to string with keeping the specification, although you can use `zod-to-json-schema` library to make from your schema json output and specify it to the prompt;
yindo closed this issue 2026-02-16 06:16:48 -05:00
Author
Owner

@christian-bromann commented on GitHub (Jan 3, 2026):

@kotekpsotek thanks for raising this issue. Have you tried to use responseFormat, e.g.:

const agent = createDeepAgent({
    model: "openai:gpt-5.2",
    tools: [], 
    middleware: [],
    subagents: [
        researcher
    ],
    systemPrompt: systemPromptBasicFiles["supervisor"],
    responseFormat: z.object({ ... }) // <-- define return object here
})

// then access it via
const result = await agent.invoke(...)
console.log(result.structuredOutput)
@christian-bromann commented on GitHub (Jan 3, 2026): @kotekpsotek thanks for raising this issue. Have you tried to use `responseFormat`, e.g.: ```ts const agent = createDeepAgent({ model: "openai:gpt-5.2", tools: [], middleware: [], subagents: [ researcher ], systemPrompt: systemPromptBasicFiles["supervisor"], responseFormat: z.object({ ... }) // <-- define return object here }) // then access it via const result = await agent.invoke(...) console.log(result.structuredOutput) ```
Author
Owner

@christian-bromann commented on GitHub (Feb 2, 2026):

I will go ahead and close this issue, let. me know if you have any further questions!

@christian-bromann commented on GitHub (Feb 2, 2026): I will go ahead and close this issue, let. me know if you have any further questions!
yindo changed title from Is here a way to cause the DeepAgent and/or subagents to return the output with favour of zod schema? to [GH-ISSUE #51] Is here a way to cause the DeepAgent and/or subagents to return the output with favour of zod schema? 2026-06-05 17:20:58 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/deepagentsjs#14