Compatibility matrix¶
This guide tells you which kneo-client release supports which kneo_serv platform version, what forward and backward compatibility mean in practice, and how to use the drop-to-transport escape hatch when you need access to an endpoint the current kneo-client release doesn't wrap yet.
What "compatibility" means in kneo-client¶
The Kneo Agent Platform's /v1 HTTP API is a stability boundary — a kneo-client release pinned to one kneo_serv minor works against any patch-level kneo_serv release on the same minor line, and against newer minors that don't break /v1.
The pinning is explicit and committed: schemas/openapi.json is a /v1-filtered copy of one specific kneo_serv release's published OpenAPI spec. Bumping the pin is a deliberate PR (via scripts/bump_schemas.py), reviewed in isolation, and never happens automatically. See ADR-004 for the rationale.
Current matrix¶
kneo-client |
Pinned to kneo_serv |
Tested against | Python | Status |
|---|---|---|---|---|
0.1.0 |
v0.4.0 (info.version 0.4.0) |
kneo_serv 0.4.x line |
>=3.12 |
First release |
The pinned kneo_serv version is recorded in schemas/SOURCE.md — that's the source of truth for which platform version generated the committed _generated/ tree.
How pinning works in practice¶
The pin is the input to the generated layer. When you bump it:
scripts/bump_schemas.pyfetches the newopenapi.jsonfrom the targetkneo_servref (or a local checkout).- The spec is filtered to
/v1paths only —kneo_servmounts every route at both/v1/…and/…; we drop the unprefixed mounts. - The filtered spec replaces
schemas/openapi.json,schemas/SOURCE.mdis updated, and_generated/is regenerated. - The hand-rolled adapter layer (
platform/,agent/) may need updates if endpoints were added, renamed, or had their shapes change. The contract testtests/contract/test_path_coverage.pycatches both sides of that drift.
A kneo-client minor release ships exactly one kneo_serv pin. Patches don't change pins. A pin bump can land in any minor / patch — versioning is independent.
Forward compatibility — newer kneo_serv than the pin¶
kneo-client ships an explicit list of every (method, path) it wraps. A newer kneo_serv that adds endpoints will still work for everything kneo-client already wraps — you just won't have wrappers for the new endpoints until the next kneo-client release.
If you need access to a new endpoint before that release, drop to the raw transport:
async with KneoClient.from_profile() as client:
# Call an endpoint that doesn't have a wrapper yet:
resp = await client._transport.request("GET", "/v1/some/new/endpoint")
payload = resp.json()
The _transport attribute is informally accessible (single-underscore prefix). It's not part of the documented stability surface, but the API has been stable since 0.1.0 and is unlikely to churn. The transport handles auth, retries, idempotency, request-ID injection, and error mapping just like the wrapped methods do — you just lose the typed response model.
Backward compatibility — older kneo_serv than the pin¶
kneo-client X.Y.Z is not guaranteed against kneo_serv releases older than its pin. Wrappers may rely on response fields that older kneo_serv versions don't emit, and the client's error mapping assumes the current platform error shape. A KeyError on from_dict() is the typical symptom — the wrapper expects a field that wasn't in the older platform's response.
If you have to talk to an older kneo_serv, pin to a matching kneo-client minor:
Need to talk to kneo_serv… |
Use kneo-client |
|---|---|
0.4.x |
0.1.x |
(More rows added as the project ships.)
Breaking changes¶
A breaking change in either direction triggers a major bump:
kneo-clientmajor — the public Python API (kneo_client.*namespace) changes incompatibly. Very rare.kneo_servmajor — i.e., introduction of/v2.kneo-clientmay need a major bump if/v1is sunset; otherwise it ships a new minor that supports both.
Within a major, deprecated surfaces keep aliases for at least one minor. See docs/dev/contributing.md for the deprecation policy.
Verifying compatibility yourself¶
The simplest smoke is the bundled examples:
# Install a specific kneo-client version
python -m pip install "kneo-client==X.Y.Z"
# Point it at your kneo_serv instance
export KNEO_URL=https://your-kneo-serv.example.com
export KNEO_API_KEY=...
# Run the smoke (touches health, runs, audit, agent specs, and human tasks)
python -m kneo_client.examples.01_basic_run YOUR_SPEC_ID
The five examples/ scripts collectively touch the platform health, runs, audit, agent spec, and human-task surfaces — enough to catch obvious incompatibilities in seconds.
For deeper validation, the integration test suite is env-gated; set KNEO_TEST_URL and KNEO_TEST_API_KEY and run python -m pytest tests/integration -v.
What the pin does not guarantee¶
The pin guarantees the wire format and the path set of /v1. It does not guarantee:
- Provider availability — whether your
kneo_servdeployment has GPT-4 configured, an MCP server reachable, a specific runtime registered. The pin says nothing about deployment state. - Spec compatibility — a spec that works on one
kneo_servmay fail on another if the spec relies on a specific provider, tool, or platform version. Validate specs against the target environment withclient.agent.specs.validate(...). - Policy outcomes —
policies.environment_*queries return whatever policy is configured on the target deployment.
These are platform-deployment concerns, not client-library concerns. The client gives you a clean wire to the platform; what the platform allows is a separate dimension.