From b44acab888eee56da42196af0448cff334529d99 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Wed, 5 Aug 2026 19:22:42 +0800 Subject: [PATCH] docs(tools): correct three comment claims about what defineTool and the subscript path do "defineTool compiles an object root, so the annotation is a bare TypedDict class name that opens nothing" is a false universal: parameterSchemaSpecToJsonSchema compiles an OPEN object root, so an empty parameter table and one with unrepresentable field names both degrade to dict[str, Any], which opens one bracket. The conclusion the sentence carries is unaffected -- 1 or 2 against a 182 cap -- so say "a bare TypedDict class name or dict[str, Any], neither of which carries a chain", in the JSDoc and the test comment that copied it. pyScalar's docstring said the subscript tool-name comment quotes "through the same call". It quotes through its own JSON.stringify call site in renderToolsSdkPy and never reaches pyScalar, which only takes const/enum scalars. Same function, different call site. The mode-'both' test attributed assembly.tools to the public schemas(). That projection is wireSchemas, wired at ctx.systemPrompt.tools. --- packages/core/tools/src/py-types.ts | 8 +++++--- packages/core/tools/tests/code-mode.spec.ts | 5 +++-- packages/core/tools/tests/py-types.spec.ts | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/core/tools/src/py-types.ts b/packages/core/tools/src/py-types.ts index a91816fadd..807c9de79c 100644 --- a/packages/core/tools/src/py-types.ts +++ b/packages/core/tools/src/py-types.ts @@ -192,7 +192,8 @@ const MAX_CLASS_NAME_BASE = 120 * still open around it: 180 `list[` plus `Literal[` plus the paren, 182, the * worst case. Reachable only through a raw `register()` whose `parameters` * is array-rooted; `defineTool` compiles an object root, so the annotation - * is a bare TypedDict class name that opens nothing. + * is a bare TypedDict class name or `dict[str, Any]` — neither carries a + * chain. * * A CPython grammar limit, not a deployment choice, so it is fixed rather than * configurable. The sibling `ts-types` renderer needs no counterpart: nothing @@ -279,8 +280,9 @@ function childClassName(base: string, segment: string): string { * parses and decodes back to the value the schema declared. DEL and the C1 * controls do reach it raw — legal but invisible, byte-for-byte as in the TS * flavor; escaping them is a both-flavors change. The subscript tool-name - * comment quotes its name through the same call and inherits both halves, - * escapes and pass-throughs alike. + * comment quotes its name through its own call to the same `JSON.stringify`, + * never through this function, and inherits both halves — escapes and + * pass-throughs alike. */ function pyScalar(value: JsonSchemaScalar): string { if (value === true) return 'True' diff --git a/packages/core/tools/tests/code-mode.spec.ts b/packages/core/tools/tests/code-mode.spec.ts index 1fa6e5064d..ee3ef2a91a 100644 --- a/packages/core/tools/tests/code-mode.spec.ts +++ b/packages/core/tools/tests/code-mode.spec.ts @@ -353,8 +353,9 @@ describe('mode-aware wire contribution', () => { it("assembles under a python runtime in mode 'both' as well, SDK and schema together", async () => { // `both` reaches the same wireSchemas/requireCodeRuntime/SDK-section code // as `code`, so this pins the mode-by-language matrix rather than a - // separate path — including that `schemas()` under `both` projects the - // Python flavor instead of hitting the flavor-table guard. + // separate path — including that the `wireSchemas` projection behind + // `assembly.tools` picks the Python flavor under `both` instead of hitting + // the flavor-table guard. const { ctx, systemPrompt } = await setup({ mode: 'both', runtime: { language: 'python' } }) registerEcho(ctx) const assembly = await systemPrompt.assemble() diff --git a/packages/core/tools/tests/py-types.spec.ts b/packages/core/tools/tests/py-types.spec.ts index 5b61523405..5b0873aa25 100644 --- a/packages/core/tools/tests/py-types.spec.ts +++ b/packages/core/tools/tests/py-types.spec.ts @@ -577,7 +577,7 @@ describe('renderToolsSdkPy', () => { // open around this annotation, so 180 `list[` plus the innermost bracket // plus that paren is 182 of CPython's 200. Only a raw `register()` reaches // it — `defineTool` compiles an object root, whose annotation is a bare - // TypedDict name that opens nothing. + // TypedDict name or `dict[str, Any]`, neither of which carries a chain. const rooted = (depth: number): ToolSdkSchema => { let schema: Record = { type: 'string', const: 'x' } for (let i = 0; i < depth; i++) schema = { type: 'array', items: schema }