Repository navigation
Description
Context
PR #848 proposed putting CLI and server transport details into model specs. The review correctly identified that as the wrong ownership boundary, and the PR is closed. This issue proposes the integration outcome without reviving that schema direction.
Problem
External control planes such as my own project (llamacppStudio) need a reliable, machine-readable contact surface to install packages, start audio.cpp, discover loaded-model capabilities, construct valid requests, consume streaming events, and interpret results. Today an integration has to hardcode routes and field conventions, infer support from model-family names or option names, or analyze source code and documentation. Those approaches drift as the server and model set evolve.
A model spec alone must not become that contact surface: it cannot safely own HTTP paths, JSON/multipart mappings, CLI flags, server.json fields, stream envelopes, or response layouts. Those belong to the front-end that implements them.
Proposal
Provide a versioned, machine-readable integration contract generated by each front-end from its own implementation. In particular:
- The server owns and publishes its lifecycle/configuration schema, operation identifiers, routes, request encodings and fields, response forms, errors, and streaming events.
- The CLI owns and publishes its invocation/configuration surface independently.
- Existing v1 model specs remain model-facing: family metadata, packages, tasks, modes, capabilities, logical inputs/outputs when stabilized, options, and dependencies.
- The server composes its API contract with the selected model's v1 metadata for model discovery. A client can learn which logical tasks and options a model supports and which server-owned operations can serve them, without a model spec copying an HTTP route or wire mapping.
The exact transport and endpoint are deliberately open for discussion. It could be a small introspection endpoint, an OpenAPI-like document, a --describe --json command, or a shared internal descriptor that powers all of those. The important constraint is one authoritative server/CLI definition, rather than parallel metadata.
Why this matters to integrators
Studio is a useful concrete consumer. It manages model catalogs and packages, starts audio.cpp as a subprocess or service, and presents a unified UI across model families. To integrate safely it needs to answer, from supported data rather than heuristics:
- What server/CLI configuration is accepted to start a model?
- Which installed or loaded models expose which logical tasks, modes, capabilities, inputs, and options?
- Which server operation should be used for each supported task?
- How must a request be encoded, including audio artifacts and streaming?
- What response, error, and stream-event shapes should the client handle?
Without this contract, every integration hardcodes family-specific rules or duplicates source-code knowledge. That makes new models harder to adopt, causes silent incompatibilities after API changes, and makes third-party front ends less useful to audio.cpp users.
Suggested incremental path
- Document and test the v1 model-spec ownership boundary; do not add schema 2.
- Introduce a server-local canonical operation descriptor, with no behavior change.
- Expose a versioned server contract from that descriptor.
- Compose per-model discovery from the server contract and existing v1 model metadata.
- Add a separate CLI description surface if it cannot share the server descriptor.
- Evolve v1 package or logical-I/O metadata only through small, separately reviewed proposals.
Non-goals
- No HTTP, request-body, response, streaming, CLI, or server-config fields in model specs.
- No schema 2 proposal.
- No requirement that every model immediately provide richer logical metadata. Unknown remains preferable to inferred support.
I would appreciate guidance on the preferred shape and hosting location for this front-end-owned contract before implementation begins.
Activity
0xShug0 commentedon Oct 13, 2026
@lapy Thanks! This is generally useful, but please hold for now. A few more refactors are underway. Once they're done, I'll check how this fits into the codebase and ping you.
lapy commentedon Oct 13, 2026
Hi @0xShug0, of course! No rush :)
Thanks for considering it and for the great work you’re doing with Audio.cpp.
supomarlo commentedon Oct 23, 2026
This direction would help downstream clients like mine.
I maintain a desktop client for audio.cpp. It does not bundle the server; users point
it at their own copy, so versions vary, including third-party builds.
A smaller related need: exposing the server version over HTTP (e.g. in
GET /health)would be useful. Model support and interfaces differ between versions, and the client
needs to know which version it is talking to.
--versionis the only programmatic source today, and it is not reliable for me. Someservers were started outside the app, so I cannot reliably query the binary that
launched them. Some third-party builds do not produce a parseable version string. In
both cases, version detection becomes cumbersome and fragile.
chenhz01 commentedon Nov 2, 2026
The hold makes sense mid-refactor — one small thing for whenever this lands: supomarlo's /health version point composes naturally with the contract idea, since a published contract already needs a version field to be meaningful. To make the shape testable before any routes get frozen, here's a validator for the server-owned surface:
It checks the fields the thread agrees the server should own — semver, routes with request/response encodings, errors, stream events — plus an independently-owned CLI block. Run it against a draft contract.json during the refactors and whatever survives is the schema worth publishing. Happy to draft the schema spec and this linter as a PR whenever you're ready.