Function: renderToolsAsPromptText()
function renderToolsAsPromptText(
tools: readonly (Tool<SpooledArtifact> | ArtifactTool)[],
deps?: {
descriptionToChatCompletionsJsonSchema: (d: DescriptionLike) => JsonSchema;
},
): string;Defined in: src/batteries/llm/litert_lm/helpers.ts:168
Render tool definitions as a SYSTEM-PROMPT text block (the prompt-injection tool-delivery path), rather than the native preface.tools field.
Parameters
| Parameter | Type |
|---|---|
tools | readonly ( | Tool<SpooledArtifact> | ArtifactTool)[] |
deps | { descriptionToChatCompletionsJsonSchema: (d: DescriptionLike) => JsonSchema; } |
deps.descriptionToChatCompletionsJsonSchema | (d: DescriptionLike) => JsonSchema |
Returns
string
Remarks
Why this exists. LiteRT-LM applies the model's OWN bundled chat template; for the Gemma-4 .litertlm preview builds, the template's tools branch is broken — passing preface.tools throws Failed to apply template: undefined value inside the wasm runtime (a known Gemma-4 chat-template bug, also seen in llama.cpp / mlx-lm / LM Studio when tools[] hits the native template). The portable fix every other browser runtime uses (WebLLM/MLC, Open WebUI's "default" mode) is to describe the tools as TEXT in the system prompt and parse the model's emitted call out of the output — which the shared createAutoToolCallParser already does (its gemma family handles the decoder-stripped call:NAME{…} runtime form, plus hermes/pythonic as fallbacks).
The block lists each tool's name, description, and JSON-Schema parameters, then instructs Gemma's OWN trained call format call:NAME{key:value, …} — NOT the pythonic [func(arg=value)] form. This matters: the LiteRT-web runtime is Gemma-only, and a real Gemma E2B/E4B run emits the decoder-stripped call:NAME{…} shape natively (verified via the real-model matrix; the gemma family in createAutoToolCallParser is built for exactly this). Instructing the pythonic form instead FIGHTS the model's training — a small instruct model, caught between its trained format and a conflicting instruction, degenerates to an unparseable hybrid (e.g. say_i_dont_know\nreason: …) that no parser catches, so the "call" leaks into the answer as prose. Teaching the model the format it already knows makes its natural output parse on the first try. A concrete example is included because a 2B follows a shown example far more reliably than an abstract grammar.