docs(tools): scope the Python SDK validity standard to the grammar
The list-nesting cap guards against a tokenizer SyntaxError, which makes the text not Python. A long `A | B | …` union is valid at any length and only defeats CPython's compile-time C recursion (measured: 1,000 branches compile, 5,000 raise RecursionError); nothing compiles this block, and capping would retire the deep-chain tests pinning the walk's linear time. Records that boundary at the `oneOf` arm and in the Agent Note (both languages). Also documents that the context-free degrade marker reads the call's className rather than the frame's — frames propagate a derived name, so a per-frame read would declare classes the caller cannot receive — and pins that path with oneOf-of-objects and array-of-oneOf assertions.
This commit is contained in:
@@ -249,6 +249,12 @@ describe('renderToolsSdkPy', () => {
|
||||
],
|
||||
})
|
||||
expect(type).toBe('dict[str, Any] | str')
|
||||
// Both branches objects, and the same shape reached through an array: the
|
||||
// marker is the CALL's className, so a propagated frame name (`Tool1`) does
|
||||
// not revive class declaration on a walk that has nowhere to declare into.
|
||||
const object = { type: 'object', additionalProperties: false, properties: { ok: { type: 'boolean' } }, required: ['ok'] }
|
||||
expect(jsonSchemaToPy({ oneOf: [object, object] })).toBe('dict[str, Any] | dict[str, Any]')
|
||||
expect(jsonSchemaToPy({ type: 'array', items: { oneOf: [object, { type: 'string' }] } })).toBe('list[dict[str, Any] | str]')
|
||||
})
|
||||
|
||||
it('suffixes a counter when two tools CamelCase to the same class base', () => {
|
||||
@@ -539,6 +545,9 @@ describe('renderToolsSdkPy', () => {
|
||||
// depth the quadratic path (~100,000^2 char copies) blows past vitest's 5s
|
||||
// default, so this fails loud on a regression; the `+`/ConsString path is
|
||||
// milliseconds. (Guard the depth explicitly so the assertions stay exact.)
|
||||
// The resulting chain is intentionally uncapped, unlike list nesting: it is
|
||||
// grammatically valid Python at any length, and only CPython's `compile()`
|
||||
// recursion would reject it — see the `oneOf` arm in py-types.ts.
|
||||
const depth = 100000
|
||||
let deep: Record<string, unknown> = { type: 'string' }
|
||||
for (let i = 0; i < depth; i++) deep = { oneOf: [deep, { type: 'null' }] }
|
||||
|
||||
Reference in New Issue
Block a user