Skip to content

langchain-quickjs: nested Pydantic schemas render as unknown in PTC signatures #6459

Description

@AdamBurchett

Submission checklist

  • This is a bug, not a usage question.
  • I added a clear and descriptive title.
  • I searched existing issues and didn't find this.
  • I can reproduce this with the latest released version.
  • I included a minimal reproducible example and steps to reproduce.

Area (Required)

  • deepagents (SDK)
  • dcode
  • talon
  • acp
  • evals
  • daytona
  • modal
  • quickjs
  • runloop
  • vercel
  • langsmith-sandbox
  • Other / not sure / general

Related Issues / PRs

PR #3210, feat(quickjs): propagate return types, introduced return-type rendering but did not resolve compound schema references.

Reproduction Steps / Example Code (Python)

from langchain_core.tools import StructuredTool
from langchain_quickjs._ptc import render_ptc_prompt
from pydantic import BaseModel


class Address(BaseModel):
    city: str
    postal_code: str


class User(BaseModel):
    name: str
    address: Address


class BatchInput(BaseModel):
    users: list[User]


def normalize_users(users: list[User]) -> list[User]:
    return users


tool = StructuredTool.from_function(
    name="normalize_users",
    description="Normalize users.",
    func=normalize_users,
    args_schema=BatchInput,
)

prompt = render_ptc_prompt([tool])
print(prompt)

assert "users: unknown[]" not in prompt
assert "Promise<unknown[]>" not in prompt
assert "address: { city: string; postal_code: string }" in prompt

Error Message and Stack Trace (if applicable)

Description

langchain-quickjs lets an agent call Python tools from JavaScript. It generates a TypeScript-style API reference so the agent knows each tool's expected inputs and outputs.

When a tool uses nested Pydantic models, the generated reference loses their structure. In the reproduction provided, a tool accepting list[User], where each User contains an Address, is currently shown as:

tools.normalizeUsers(input: {
  users: unknown[];
}): Promise<unknown[]>

It should be shown as:

tools.normalizeUsers(input: {
  users: {
    name: string;
    address: {
      city: string;
      postal_code: string;
    };
  }[];
}): Promise<{
  name: string;
  address: {
    city: string;
    postal_code: string;
  };
}[]>

The JavaScript runtime can already transport these nested values. The problem is only in the generated API reference. Pydantic stores nested definitions using JSON Schema $defs and $ref, but the current renderer does not resolve those references and therefore falls back to unknown.

A minimal fix is to run input and return schemas through LangChain Core's existing dereference_refs utility before rendering them. This requires no new dependency or public API change and supports nested and inherited Pydantic models.

If this approach is acceptable, please assign this issue to me. I have a focused implementation and regression tests ready to submit.

Environment / System Info

OS: Linux x86_64
Python: 3.13.5
deepagents: 0.7.16
langchain: 1.4.2
langchain-core: 1.6.3
langchain-quickjs: 0.3.7
quickjs-rs: 0.2.5
Relevant environment variables: None
Date verified: September 21, 2026

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    integration:quickjsIntegration with the QuickJS sandbox package.org:externalIssue or pull request created by someone outside the `langchain-ai` GitHub organization.priority:backlogNot currently planned/prioritized work, often affecting a limited feature or set of users.topic:code-interpreterQuickJS and code interpreter middleware.topic:modelsModel providers, model selection, and model configuration.type:bugAn unexpected problem or incorrect behavior.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions