Skip to content

AbstractCore v2.18.0

Choose a tag to compare

@github-actions github-actions released this 28 Sep 05:33
· 399 commits to main since this release

Capability routes say when their engine is not installed, Apple silicon fits account for the GPU
memory limit macOS can raise, the saved OpenAI key reaches AbstractVoice (never for a request the
server has not authenticated), and neither abstractcore engines open nor the terminal console
(abstractcore-console 0.4.0) tries to open a browser on a machine without a display.

Added

  • engine_missing: {engine, name, reason, install[, engine_row]} on capability routes whose
    in-process engine is not installed in this Python environment: MLX (mlx-lm), MLX-Gen
    (abstractvision + mlx-gen), llama.cpp (GGUF models on the huggingface provider), Transformers
    (other huggingface models) and every local voice engine (Supertonic, faster-whisper, ...), whose
    answer is AbstractVoice's own abstractvoice.engine_runtime probe (an AbstractVoice older than
    0.13.0 is itself the missing engine of those routes, with its upgrade command, and the rest of
    the grid is unaffected). install targets this Python interpreter, like the Engines screen's
    rows (uv pip install --python <interpreter> ... in a pip-less uv environment, else
    <interpreter> -m pip install ...). It appears on
    config defaults rows, apply-recommended entries and the recommended download plan, and the
    CLI prints it. It is distinct from route_unavailable (this host cannot run the engine at all)
    and from weights that are not downloaded. See Centralized config.
  • Fit verdict needs_gpu_limit (Apple silicon): the model does not fit the current GPU memory
    limit but fits under one macOS can grant; fit.gpu_limit carries the exact
    sudo sysctl iogpu.wired_limit_mb=<MB> command, the value and the verdict after it. A raised
    iogpu.wired_limit_mb is the ceiling in the light host reading too. The 128 GiB tier's
    recommended text model reports this verdict with its command instead of too_large, and the
    --fits filter keeps such models. See Local models.
  • The OpenAI API key saved in AbstractCore's config reaches the voice plugin as AbstractVoice's host
    setting voice_openai_api_key: from the config file an instance was created for (the gateway's
    core config), else the global config. An explicit create_llm(..., voice_openai_api_key=...)
    wins; with no key saved nothing is set. In the server's audio routes the key is read on every
    request and handed over only to server-authenticated requests whose voice engine is openai or
    openai-compatible, on a capability host built for that request (never cached): a rotated key
    is used on the next call, a removed one is no longer sent. See Server.
  • Wan2.2 T2V-A14B and I2V-A14B 8-bit carry their measured run-time memory (resident): about
    72 GiB each at AbstractVision's default canvas (1280x720, 81 frames), so their fit reads
    too_large on 64 GiB Macs, needs_gpu_limit on 96 GiB Macs and fits from 128 GiB. The
    recommended video route is unchanged (Wan2.2 TI2V-5B from about 96 GiB).
  • The Supertonic voice artifact (supertonic-3) carries its download size (401,276,744 bytes).
  • CI job local-models: the whole suite with CPU torch, Transformers and llama.cpp installed; the
    release workflow requires it.

Changed

  • Server audio routes without a provider/model (the AbstractVoice path: speech, speech stream,
    transcriptions, voice clone, and their /{provider}/v1/... forms) apply the same rule as
    model=openai/...: when the engine that would run is remote in AbstractVoice's own words
    (abstractvoice.engine_runtime: OpenAI or an OpenAI-compatible server, under every spelling it
    accepts, such as remote, compatible or proxy), or is an engine AbstractVoice does not know,
    and the server holds an OpenAI key (saved, or OPENAI_API_KEY, which AbstractVoice would fall
    back to), a request that is not server-authenticated gets 401 (also with
    ABSTRACTCORE_SERVER_ALLOW_UNAUTHENTICATED=1); an explicit X-AbstractCore-Provider-API-Key
    is then the only key used. Local engines are unaffected. The audio discovery routes
    (/v1/audio/voices, .../providers, .../models) follow the same rule: the saved key counts as
    server-held, ABSTRACTCORE_SERVER_ALLOW_UNAUTHENTICATED=1 no longer exempts them, and they pass
    the saved key to AbstractVoice only for authenticated requests.
  • The vision routes guarded by server-held OpenAI credentials (/v1/vision/providers/,
    /v1/vision/models and the other vision discovery routes, and image/video generation, edits and
    upscale through OpenAI or an OpenAI-compatible upstream) apply the same rule, through the one
    guard the audio discovery routes use (abstractcore.server.credentials): an unauthenticated
    request gets 401 when the server holds an OpenAI key (saved or OPENAI_API_KEY), also with
    ABSTRACTCORE_SERVER_ALLOW_UNAUTHENTICATED=1; an explicit X-AbstractCore-Provider-API-Key is
    spent instead.
  • /v1/audio/music and /{provider}/v1/audio/music: while the server holds a key AbstractMusic
    reads (ACEMUSIC_API_KEY, ELEVENLABS_API_KEY, in the environment or as the matching
    music_*_api_key route option), a request that is not server-authenticated gets 401 whatever
    backend it names, also with ABSTRACTCORE_SERVER_ALLOW_UNAUTHENTICATED=1; an explicit
    X-AbstractCore-Provider-API-Key is handed to the remote music backends in place of the
    server's keys. Local music on a server holding none of these keys works unauthenticated. This is
    an interim rule until AbstractMusic can say which of its backends are remote.
  • The capability discovery routes (/v1/capabilities, /v1/capabilities/{capability}/providers,
    /v1/capabilities/{capability}/models, /v1/audio/music/providers, /v1/audio/music/models,
    /v1/audio/music/provider-details) follow the same rules: they call into the plugins, which
    probe their remote providers with the keys they read, so a request that is not
    server-authenticated gets 401 while the server holds a key the capability could spend (OpenAI
    for voice, audio and vision; the music keys for music; both for /v1/capabilities and for any
    other capability). A caller's own key is handed to the plugins in place of the server's.
  • Music requests: an unknown backend selector (body provider or route prefix, e.g.
    /elevenlabs/v1/audio/music; AbstractMusic's ElevenLabs selector is elevenlabs-music) is
    refused with 400 instead of running another backend; a selected backend that is not installed
    is refused (501) instead of falling back to another one; a caller's own key reaches only the
    backend the request selected.
  • abstractcore engines open prints the link and launches nothing without a display (SSH session;
    Linux/BSD without DISPLAY or WAYLAND_DISPLAY), with the reason (not_opened in --json):
    the console crate's rule, now also abstractcore.utils.display in Python.
  • The voice extras (voice, audio, all, all-apple, all-gpu, all-non-mlx, full-dev)
    require abstractvoice>=0.13.0, the first release with the public engine runtime probe.
  • vLLM's engine row on a host without an NVIDIA GPU reads "vLLM needs Linux with an NVIDIA GPU
    (CUDA); use a remote vLLM server instead".
  • abstractcore-console 0.4.0: o never launches a browser without a display (SSH
    sessions; Linux/BSD without DISPLAY or WAYLAND_DISPLAY) and prints the link instead; routes
    whose engine is not installed read engine not installed with the install command; models that
    need a raised GPU limit show the command; remote-only engines read remote only.

Fixed

  • Five local-model tests (Transformers cached lane, GGUF control plane) match the provider's
    current signatures and cache contracts.
  • The Transformers snapshot-lane tests load their tokenizer at test time from the cached snapshot
    directory, and skip without network when it is not cached: loading it by repo id at collection
    made huggingface_hub 1.33 contact huggingface.co, and the test network guard failed the
    local-models job.
  • Clearing a configured API key (set_api_key(provider, "")) restores the environment variable
    value it had shadowed (or unsets it), so the removed key stops being used in this process.