docs(tools): align Code Mode docs with multi-language dispatch; py-types notes

Address ds-review-bot v5/v6 review round 3:
- Config.mode JSDoc and the regenerated config-catalog no longer claim Code
  Mode requires a TypeScript runtime; both now say a language with a
  registered SDK renderer.
- The active 2026-06-15-code-mode base note (both languages) follows shipped
  reality: the SDK renders the loaded runtime's language, dsh-tools accepts
  any language with a renderer and run_code flavor, and it cross-links the
  language-dispatch note.
- The language-dispatch note distinguishes the two Object.hasOwn guards'
  reachability and documents the peekRuntime no-runtime degrade vs the
  rejected silent fallback.
- SDK_RENDERERS comment: adding a language is two table entries, not one.
- py-types: document the deliberate PEP 586 deviation for float Literals;
  add oneOf-object-branch tests (named union classes and context-free
  degrade), keeping py-types.ts at 100% per-file coverage.
This commit is contained in:
Chinesezjc
2026-08-02 13:55:28 +08:00
parent 938ee4e2eb
commit 59affddfc5
10 changed files with 64 additions and 19 deletions

View File

@@ -31,7 +31,9 @@ import { renderToolsSdkPy } from './py-types.ts'
* `ctx.codeRuntime.language` in this table when assembling the `tools:sdk`
* section under a non-native mode; a runtime whose language is not a key
* fails the assembly loudly (same idiom as `toolOrder` violations). Adding a
* new backend language is a table entry plus its renderer, nothing else.
* new backend language is two table entries — a renderer here and a
* {@link RUN_CODE_FLAVORS} entry for its `run_code` schema strings — plus the
* renderer itself.
*/
const SDK_RENDERERS: Record<string, (schemas: ToolSdkSchema[]) => string> = {
typescript: renderToolsSdk,
@@ -604,8 +606,9 @@ export interface Config {
/**
* Model presentation. `native` (default) sends every visible schema; `code`
* sends only `run_code` plus a generated SDK prompt; `both` sends both forms.
* Code modes require a TypeScript runtime and fail prompt assembly when it is
* absent or mismatched. Under `code`, native names in `toolOrder` are invalid.
* Code modes require a `ctx.codeRuntime` whose `language` has a registered
* SDK renderer (TypeScript or Python) and fail prompt assembly when it is
* absent or has no renderer. Under `code`, native names in `toolOrder` are invalid.
*/
mode?: ToolPresentationMode
/**

View File

@@ -154,7 +154,14 @@ function pyScalar(value: JsonSchemaScalar): string {
return String(value)
}
/** Render a validated scalar `const`/`enum` as `Literal[...]`, falling back to the broad type. */
/**
* Render a validated scalar `const`/`enum` as `Literal[...]`, falling back to
* the broad type. Deliberately deviates from PEP 586, which restricts `Literal`
* parameters to int/bool/str/bytes/enum/None: a number `const`/`enum` emits a
* float literal (`Literal[1.5]`) a strict checker would reject. Harmless here —
* the stub is advisory prompt text, only required to parse — and keeping the
* exact value communicates the constraint to the model.
*/
function renderConstrainedScalar(node: Record<string, unknown>, broad: string, state: RenderState): string {
if (Object.hasOwn(node, 'const')) {
state.typing.add('Literal')