Tool calling & structured output

Multi-turn tool loops and schema-validated JSON output, OpenAI wire shape.
Malibu ships both features as OpenAI-compatible wire surfaces on /v1/chat/completions, so any framework built on the OpenAI SDK can use them without changes. The examples use client from Using Malibu with the OpenAI SDK.

Tool calling

Supported: multi-turn tool loops, streamed tool-call deltas, tool_call_id back-references, and role: "tool" messages. Anchor framework: Cline, pointed at the Malibu base URL with a Qwen-family model.
Which models emit tool_calls[]:
  • Qwen family (Qwen 2.5, Qwen 3, Qwen3-Coder, and later Qwen releases in the catalog). Full multi-turn support.
  • gpt-oss (gpt-oss-20b, gpt-oss-120b). First-turn tool calls only. Sending tool results back returns 400 unsupported_modelID_for_multi_turn.
  • Other models (Llama 3.1 / 3.2, Gemma 4, Nemotron, GLM). They accept tools but reply with plain assistant text.
tool_choice supports "auto". "required" and named-function choices are accepted but handled as "auto", and "none" returns 400. Full model list, multi-turn example, streaming reassembly, and caps: Agentic tooling → Tool calling.

Buyer-side validation obligation

Emitted tool_calls[] reflect model output, not provider-verified intent. Buyer-side agent frameworks MUST validate before execution. Malibu delivers the parsed OpenAI-compatible shape. It does not decide whether a requested tool name or argument payload is safe for your agent policy. Treat emitted tool calls with the same trust posture you would apply to a model running on local hardware. See Agentic tooling → Buyer-side validation.

Structured output

Send response_format with json_schema or json_object. The provider steers the model with your schema, then validates the output before it returns success. If the output doesn’t validate, you get a 502 (or a terminal SSE error when streaming) instead of invalid JSON. This is post-inference validation, not constrained decoding. It works streaming and non-streaming, on every catalog model.
Supported subset: a strict subset of JSON Schema. type is required on every node, every object needs additionalProperties: false, and every property must be listed in required. $ref, anyOf / oneOf, pattern, format, and length constraints are rejected with 400 before inference runs. response_format: {"type": "json_object"} is enforced too. Output that isn’t JSON with an object or array at the top level returns 502 malformed_json_response. Full reference: Agentic tooling → Structured output.