fix(tools): attach Python SDK docstrings to their own methods
A description was emitted above the `async def`, where Python treats the first string as the `Tools` class docstring and every later one as a dead expression — leaving each method undocumented in the model's only source of tool semantics. Emit it as the first statement of the method body instead. Also names the known languages in the run_code flavor guard (the reachable rejection, symmetric with the SDK_RENDERERS guard) and corrects three doc claims: the code-runtime group README no longer calls the generated SDK TypeScript, the base Code Mode note states its serial dispatch in past tense, and the tools README points at the rationale the language-dispatch note actually carries.
This commit is contained in:
@@ -138,7 +138,8 @@ function resolveFlavor(peekRuntime: () => CodeRuntime | undefined): RunCodeFlavo
|
||||
// resolve an inherited Object.prototype member as a flavor.
|
||||
const flavor = RUN_CODE_FLAVORS[runtime.language]
|
||||
if (!Object.hasOwn(RUN_CODE_FLAVORS, runtime.language) || flavor === undefined) {
|
||||
throw new Error(`dsh-tools: no run_code schema flavor registered for runtime language ${JSON.stringify(runtime.language)}`)
|
||||
const known = Object.keys(RUN_CODE_FLAVORS).map(name => JSON.stringify(name)).join(', ')
|
||||
throw new Error(`dsh-tools: no run_code schema flavor registered for runtime language ${JSON.stringify(runtime.language)} (known: ${known})`)
|
||||
}
|
||||
return flavor
|
||||
}
|
||||
|
||||
@@ -482,8 +482,18 @@ export function renderToolsSdkPy(schemas: ToolSdkSchema[]): string {
|
||||
const argType = renderType(schema.parameters, `${camelCase(schema.name)}Args`, state)
|
||||
const outputType = renderType(schema.output, `${camelCase(schema.name)}Output`, state)
|
||||
if (IDENTIFIER.test(schema.name) && !RESERVED.has(schema.name) && !schema.name.startsWith('_')) {
|
||||
members.push(...docLines(schema.description, 1))
|
||||
members.push(`${pad(1)}async def ${schema.name}(self, args: ${argType}) -> ${outputType}: ...`)
|
||||
// A docstring only documents its method when it is the FIRST statement
|
||||
// of that method's body. Emitted before the `async def` it would instead
|
||||
// become the `Tools` class docstring (for the first tool) or a dead
|
||||
// expression (for every later one), leaving every method undocumented —
|
||||
// and this SDK is the model's only description of what a tool does. A
|
||||
// docstring is a complete body, so the `...` stub is only for the
|
||||
// description-less case.
|
||||
const doc = docLines(schema.description, 2)
|
||||
members.push(doc.length > 0
|
||||
? `${pad(1)}async def ${schema.name}(self, args: ${argType}) -> ${outputType}:`
|
||||
: `${pad(1)}async def ${schema.name}(self, args: ${argType}) -> ${outputType}: ...`)
|
||||
members.push(...doc)
|
||||
statements += 1
|
||||
} else {
|
||||
// Not a legal attribute name — the model reaches it via ``tools[name]``.
|
||||
|
||||
Reference in New Issue
Block a user