Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions docs/website/content/docs/cli/http-server/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,39 @@ curl http://localhost:11434/v1/chat/completions \

A `tools` request for a model loaded without `config.tools: true` returns `400 tools_not_enabled` rather than answering in prose.

**Forcing a tool call** with `tool_choice`:

```bash
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "my-llm",
"messages": [{"role": "user", "content": "What is the weather in London?"}],
"tools": [{ "type": "function", "function": { "name": "get_weather" } }],
"tool_choice": "required"
}'
```

`tool_choice` accepts `"auto"` (the default), `"none"`, `"required"`, or
`{ "type": "function", "function": { "name": "get_weather" } }` to force one
specific tool. On llama.cpp-backed models `required` and a named tool constrain
the sampler with the chat template's tool grammar, so the model calls a tool
instead of answering in prose.

Both forms need a matching entry in `tools`: a demanding `tool_choice` with no
`tools`, or a name that isn't declared, returns `400 invalid_tool_choice`. A bare
tool name in place of the object form is rejected the same way β€” use the object
form to target one tool.

`auto`, `none` and `required` are reserved: a tool carrying one of those names
cannot be targeted through `tool_choice` and the request returns
`400 invalid_tool_choice`. Rename the tool to target it.

A tool call the model emits that fails to parse or validate is dropped, so the
response comes back with `finish_reason: "stop"` and no `tool_calls`. The server
log records what happened (`toolerrors=1 (PARSE_ERROR)`) β€” the OpenAI response
shape has no field for it.

#### Message content

`messages[].content` accepts both the plain string form and the OpenAI **array-of-parts** form (`[{ "type": "text", "text": "…" }, …]`) that modern clients such as Cline and Open WebUI send. Parts of type `text` are concatenated into a single string; non-text parts (`image_url`, `input_audio`, `file`) are **silently dropped** β€” the chat surface is text-only and vision is out of scope. Both shapes below are valid:
Expand Down Expand Up @@ -671,6 +704,8 @@ When generation is truncated because it hit `max_output_tokens` / `max_tokens`,

The following Responses-API features are intentionally rejected with `400`: `conversation`, `background: true`, and built-in tools (`web_search`, `file_search`, `code_interpreter`). `function`-typed tools work when the model was loaded with `config.tools: true`; otherwise the request returns `400 tools_not_enabled`.

`tool_choice` is supported in the same shapes as chat completions, except that the object form is the Responses API's flattened `{ "type": "function", "name": "get_weather" }`.

#### `GET /v1/responses/:id`

Retrieve a previously stored response by id.
Expand Down
49 changes: 49 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,54 @@
# Changelog

## [0.14.0]

πŸ“¦ **NPM:** https://www.npmjs.com/package/@qvac/cli/v/0.14.0

QVAC CLI 0.14.0 follows `@qvac/sdk` 0.20.0. `qvac serve` adds `DELETE /qvac/v1/kv_cache`, MiniMax-H3 fields on `/v1/videos`, the 0.8.x TTS load options on `/v1/audio/speech`, and `tool_choice` on `/v1/chat/completions` and `/v1/responses`. `qvac configure` no longer offers the removed diffusion CPU flags, and `qvac verify bundle` looks for TTS host packages next to `@qvac/tts-ggml` instead of under its `prebuilds/` directory.

Install `@qvac/cli@0.14.0` with `@qvac/sdk@^0.20.0`. Publish this cut after SDK 0.20.0 is on npm.

## Breaking Changes

### Diffusion CPU flags in `qvac configure`

`clip_on_cpu`, `vae_on_cpu`, and `control_net_cpu` are gone from the diffusion schema. Configure prompts for `params_backend`, `backend`, `max_vram`, and `stream_layers` instead. Existing configs that still set the old keys fail validation.

**Before:**

```json
{
"clip_on_cpu": true,
"vae_on_cpu": true,
"control_net_cpu": true
}
```

**After:**

```json
{
"params_backend": "te=cpu,vae=cpu",
"backend": "controlnet=cpu"
}
```

CPU layer streaming:

```json
{
"params_backend": "diffusion=cpu",
"max_vram": -1,
"stream_layers": true
}
```

## Features

`qvac serve` mounts `DELETE /qvac/v1/kv_cache` on the default QVAC surface to reclaim automatic KV caches. `/v1/videos` accepts MiniMax-H3 generation params. `/v1/audio/speech` passes through the TTS load options from `@qvac/tts-ggml` 0.8.x. `/v1/chat/completions` and `/v1/responses` accept `tool_choice` (`auto` / `none` / `required` / named tool) and log unparseable tool calls as `toolError` events.

`qvac verify bundle` accepts `@qvac/tts-ggml` 0.9.x, where the native binary lives in a per-platform package (`@qvac/tts-ggml-darwin-arm64` and siblings) beside the meta package.

## [0.13.1]

πŸ“¦ **NPM:** https://www.npmjs.com/package/@qvac/cli/v/0.13.1
Expand Down
10 changes: 5 additions & 5 deletions packages/cli/NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -31,29 +31,29 @@ JavaScript Dependencies
@qvac/embed-llamacpp@0.37.0
https://github.com/tetherto/qvac
@qvac/error@0.1.1
@qvac/fabric@0.10.0
@qvac/fabric@0.16.0
https://github.com/tetherto/qvac
@qvac/infer-base@0.4.2
https://github.com/tetherto/qvac
@qvac/infer-base@0.6.2
https://github.com/tetherto/qvac
@qvac/inference@0.19.0
@qvac/inference@0.20.0
https://github.com/tetherto/qvac
@qvac/langdetect-text@0.1.2
https://github.com/tetherto/qvac
@qvac/llm-llamacpp@0.49.1
@qvac/llm-llamacpp@0.53.0
https://github.com/tetherto/qvac
@qvac/logging@0.1.1
https://github.com/tetherto/qvac
@qvac/ocr-ggml@0.21.0
https://github.com/tetherto/qvac
@qvac/rag@0.8.0
@qvac/rag@0.8.1
https://github.com/tetherto/qvac
@qvac/registry-client@0.6.1
https://github.com/tetherto/qvac
@qvac/registry-schema@0.3.0
https://github.com/tetherto/qvac
@qvac/sdk@0.19.0
@qvac/sdk@0.20.0
https://github.com/tetherto/qvac
@qvac/translation-nmtcpp@0.13.0
https://github.com/tetherto/qvac
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ For tests that touch `qvac serve --openai`, `@qvac/ai-sdk-provider`, or agent-to
[`test/AGENT_STACK_E2E.md`](./test/AGENT_STACK_E2E.md). It defines which layer owns SDK e2e,
CLI contract tests, CLI in-process HTTP e2e, CLI spawned-binary e2e, provider integration, and plugin integration.

The CLI depends on the published `@qvac/sdk` (`^0.17.0`), which provides the
The CLI depends on the published `@qvac/sdk` (`^0.20.0`), which provides the
`./commands` subpath that `bundle`/`verify` re-export and the server runtime
the `serve` commands use. A normal `npm install` pulls it from the registry β€”
no local SDK build is required.
Expand Down Expand Up @@ -504,7 +504,7 @@ npm run dev:unlink
```

This runs `git checkout HEAD -- package.json` and re-installs, so the
committed `@qvac/sdk` dependency (`^0.17.0`) is restored regardless of what you
committed `@qvac/sdk` dependency (`^0.20.0`) is restored regardless of what you
swapped in locally. `package-lock.json` is gitignored and is regenerated by the
trailing `npm install`.

Expand Down
19 changes: 19 additions & 0 deletions packages/cli/changelog/0.14.0/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog v0.14.0

Release Date: 2026-09-17

## ✨ Features

- Integrate diffusion layer streaming in the SDK. (see PR [#4389](https://github.com/tetherto/qvac/pull/4389)) - See [breaking changes](./breaking.md)

## πŸ”Œ API

- Expose KV-cache reclaim over serve. (see PR [#4249](https://github.com/tetherto/qvac/pull/4249)) - See [API changes](./api.md)
- Integrate MiniMax-H3 video generation across inference and SDK. (see PR [#4351](https://github.com/tetherto/qvac/pull/4351)) - See [API changes](./api.md)
- Close the SDK gaps against @qvac/tts-ggml 0.8.x. (see PR [#4414](https://github.com/tetherto/qvac/pull/4414)) - See [API changes](./api.md)
- Update @qvac/tts-ggml to 0.9.1. (see PR [#4428](https://github.com/tetherto/qvac/pull/4428)) - See [API changes](./api.md)
- Accept tool_choice on the serve OpenAI routes. (see PR [#4524](https://github.com/tetherto/qvac/pull/4524)) - See [API changes](./api.md)

## βš™οΈ Infrastructure

- Typecheck CLI push CI against the in-repo SDK on non-release branches. (see PR [#4470](https://github.com/tetherto/qvac/pull/4470))
48 changes: 48 additions & 0 deletions packages/cli/changelog/0.14.0/CHANGELOG_LLM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# QVAC CLI v0.14.0 Release Notes

πŸ“¦ **NPM:** https://www.npmjs.com/package/@qvac/cli/v/0.14.0

QVAC CLI 0.14.0 follows `@qvac/sdk` 0.20.0. `qvac serve` adds `DELETE /qvac/v1/kv_cache`, MiniMax-H3 fields on `/v1/videos`, the 0.8.x TTS load options on `/v1/audio/speech`, and `tool_choice` on `/v1/chat/completions` and `/v1/responses`. `qvac configure` no longer offers the removed diffusion CPU flags, and `qvac verify bundle` looks for TTS host packages next to `@qvac/tts-ggml` instead of under its `prebuilds/` directory.

Install `@qvac/cli@0.14.0` with `@qvac/sdk@^0.20.0`. Publish this cut after SDK 0.20.0 is on npm.

## Breaking Changes

### Diffusion CPU flags in `qvac configure`

`clip_on_cpu`, `vae_on_cpu`, and `control_net_cpu` are gone from the diffusion schema. Configure prompts for `params_backend`, `backend`, `max_vram`, and `stream_layers` instead. Existing configs that still set the old keys fail validation.

**Before:**

```json
{
"clip_on_cpu": true,
"vae_on_cpu": true,
"control_net_cpu": true
}
```

**After:**

```json
{
"params_backend": "te=cpu,vae=cpu",
"backend": "controlnet=cpu"
}
```

CPU layer streaming:

```json
{
"params_backend": "diffusion=cpu",
"max_vram": -1,
"stream_layers": true
}
```

## Features

`qvac serve` mounts `DELETE /qvac/v1/kv_cache` on the default QVAC surface to reclaim automatic KV caches. `/v1/videos` accepts MiniMax-H3 generation params. `/v1/audio/speech` passes through the TTS load options from `@qvac/tts-ggml` 0.8.x. `/v1/chat/completions` and `/v1/responses` accept `tool_choice` (`auto` / `none` / `required` / named tool) and log unparseable tool calls as `toolError` events.

`qvac verify bundle` accepts `@qvac/tts-ggml` 0.9.x, where the native binary lives in a per-platform package (`@qvac/tts-ggml-darwin-arm64` and siblings) beside the meta package.
73 changes: 73 additions & 0 deletions packages/cli/changelog/0.14.0/api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# πŸ”Œ API Changes v0.14.0

## Expose KV-cache reclaim over serve

PR: [#4249](https://github.com/tetherto/qvac/pull/4249)

```bash
curl -X DELETE http://localhost:11434/qvac/v1/kv_cache
```

```json
{ "object": "kv_cache.reclaim", "deleted": true }
```

---

## Integrate MiniMax-H3 video generation across inference and SDK

PR: [#4351](https://github.com/tetherto/qvac/pull/4351)

`POST /v1/videos` accepts MiniMax-H3 fields on the OpenAI-shaped video job (H3 text-encoder / video VAE / audio VAE sources via `serve.models`). Poll `GET /v1/videos/{id}` then fetch bytes from `GET /v1/videos/{id}/content`.

---

## Close the SDK gaps against @qvac/tts-ggml 0.8.x

PR: [#4414](https://github.com/tetherto/qvac/pull/4414)

`POST /v1/audio/speech` passes through the TTS load options that 0.8.x exposed (CosyVoice3, Chatterbox, Supertonic, Parler).

---

## Update @qvac/tts-ggml to 0.9.1

PR: [#4428](https://github.com/tetherto/qvac/pull/4428)

```bash
# tts-ggml 0.9.0 installs the host's binaries next to the meta package
node_modules/@qvac/tts-ggml/ # JavaScript only: addon: true, no prebuilds/
node_modules/@qvac/tts-ggml-darwin-arm64/ # os/cpu filtered optionalDependency
addon/package.json # { "name": "@qvac/tts-ggml", "addon": true }
addon/prebuilds/darwin-arm64/qvac__tts-ggml.bare

# Passes on this branch; on main it reports missing-prebuild for every host
qvac verify bundle --addons-source ./node_modules --host darwin-arm64
```

```text
@qvac/tts-ggml@0.9.0 is missing a prebuild for linux-x64
(expected …/@qvac/tts-ggml/prebuilds/linux-x64/*.bare).
No per-platform package @qvac/tts-ggml-linux-x64 is installed alongside it either.
```

---

## Accept tool_choice on the serve OpenAI routes

PR: [#4524](https://github.com/tetherto/qvac/pull/4524)

`POST /v1/chat/completions` and `POST /v1/responses` accept `tool_choice`: `"auto"` | `"none"` | `"required"` | a named-tool object. Chat uses `{ type: "function", function: { name } }`; Responses flattens to `{ type: "function", name }`. A demanding choice with no matching tool returns `400 invalid_tool_choice`. Parse failures are dropped from the OpenAI response and logged as `toolError` events.

```bash
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "my-llm",
"messages": [{"role": "user", "content": "What is the weather in London?"}],
"tools": [{ "type": "function", "function": { "name": "get_weather" } }],
"tool_choice": "required"
}'
```

---
36 changes: 36 additions & 0 deletions packages/cli/changelog/0.14.0/breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# πŸ’₯ Breaking Changes v0.14.0

## Integrate diffusion layer streaming in the SDK

PR: [#4389](https://github.com/tetherto/qvac/pull/4389)

**BEFORE:**

```typescript
const modelConfig = {
clip_on_cpu: true,
vae_on_cpu: true,
control_net_cpu: true
}
```

**AFTER:**

```typescript
const modelConfig = {
params_backend: 'te=cpu,vae=cpu',
backend: 'controlnet=cpu'
}
```

To run the text encoder or VAE graph on CPU, add `te=cpu` or `vae=cpu` to `backend`.

CPU layer streaming requires CPU diffusion parameter residency and graph cutting enabled by `max_vram`:

```typescript
const modelConfig = {
params_backend: 'diffusion=cpu',
max_vram: -1,
stream_layers: true
}
```
4 changes: 2 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qvac/cli",
"version": "0.13.1",
"version": "0.14.0",
"description": "Command-line interface for the QVAC ecosystem",
"author": "Tether",
"license": "Apache-2.0",
Expand Down Expand Up @@ -59,7 +59,7 @@
"@fastify/swagger": "^9.0.0",
"@fastify/swagger-ui": "^6.1.1",
"@inquirer/prompts": "8.5.2",
"@qvac/sdk": "^0.19.0",
"@qvac/sdk": "^0.20.0",
"close-with-grace": "^2.1.0",
"commander": "^14.0.3",
"fastify": "^5.0.0",
Expand Down
Loading
Loading