Skip to content

Inference section — user-configured model connections #421

Description

@JArmandoAnaya

This feature spans the kernel, the wire, the server, the CLI, MCP and the UI. It sits between
the ModelProvider port that declares how a model is asked for a prediction (#418) and the work
that surfaces model provenance and confidence in the review loop (#417).

It carries deferred-needs-input because the two open questions at the bottom block UI placement
and persistence design. They do not block the kernel work.

Summary

VisionSet never bundles or auto-downloads inference models. Auto-labeling operates
against model connections the user creates: a new top-level configuration surface
where connections to local or remote models are created, set up, tested, and managed.
The auto-labeling feature itself is always present (not an optional extra); only the
local runtime ships as visionset[local-inference].

Ratified direction (Armando, 2026-08-07), recorded in full on the port issue (#418):

  • ModelProvider adapters are instantiated from user-created connections, never from a
    bundled default.
  • VisionSet never downloads weights at install time; download is an explicit user
    action during local-connection setup, with the size shown beforehand.
  • Nothing may preclude cloud execution later — a hosted adapter is just another
    connection type against the same port.

The user journey (design target)

Empty state. Centered card: "Connect a model to enable auto-labeling", primary CTA
Add connection. Meta line stating the policy as a value proposition: "VisionSet
never downloads models on its own — you choose what runs and where."

List. Compact rows (density principle): connection name · type chip (Local /
HTTP) · model identity (grounding-dino-base @ <revision>) · status (Ready /
Not set up / Unreachable), semantic token + text, never color alone. Per-row
overflow: edit, test, delete.

Create — two steps. Step 1: pick type. Step 2 by type:

  • Local: HF model id + revision (suggested default; download size shown before
    confirming), device, precision. If local-inference is not installed, the form stays
    usable and shows the exact command (pip install "visionset[local-inference]") —
    never a bare disabled control (design principle 9). Creating the connection downloads
    nothing; the row lands at Not set up with a Download weights action.
  • HTTP: endpoint URL, optional credential, and a Test button that makes a real
    call and reports what answered. The endpoint contract is defined by this project —
    the same contract a future hosted adapter implements, and anyone may implement it.
    Third-party inference protocols are not adopted as the contract.

Download weights runs as a background job on the existing infrastructure (SQLite
queue in visionset.db, workers in the FastAPI lifespan, /background-jobs routes,
observable progress).

Delete states its blast radius accurately: annotation provenance stores model
identity denormalized (id + revision copied at write time, no FK to the
connection), so deleting a connection never breaks provenance. Dialog copy: "Annotations
keep their model provenance; only this configuration is removed."

Scope by layer

Kernel (visionset.kernel) — one home, one spelling:

Persistence:

  • New workspace-scoped table (like background_job: no project_id), narrow port
    methods only.

Wire + server:

  • ConnectionOut with allowed_actions derived from the same transition tables the
    service enforces (standing contract): download_weights only for local + not-set-up;
    test only for HTTP; delete always, with the blast-radius message.
  • Routes under /inference/connections. Weight download responds 202 pointing at its
    background job. Regenerate and commit openapi.json.

CLI + MCP (SDK-first parity):

  • visionset inference list|create|test|download with --json.
  • Equivalent MCP tools — an agent must be able to make a workspace auto-label-ready
    without a browser.

UI:

  • Screens in ui-core, navigation as callbacks, render allowed_actions only, existing
    semantic status tokens — zero new colors.
  • Annotation-workspace suture: when auto-labeling is offered in the editor with no
    connections configured, principle 10 forbids forcing navigation out of the editor or
    losing work — same pattern as in-editor quick class creation, or minimally a
    state-preserving link. Design explicitly, do not improvise at implementation time.

Open questions — Armando's, do not decide (deferred-needs-input)

  1. Navigation placement. A top-level Inference section re-opens the closed-rail rule set
    by the routes-and-composition work (app: routes and composition — deliberately thin; all domain logic lives in ui-core (the enterprise rule) #58), which fixed the rail at "Home, Projects, avatar —
    nothing else". Two options are prepared rather than picked: (a) a new rail entry
    Inference; (b) another placement that leaves the app: routes and composition — deliberately thin; all domain logic lives in ui-core (the enterprise rule) #58 rule intact. Whichever is chosen is
    recorded as a superseding decision on that rule in the same turn it is confirmed.
  2. Credential storage. HTTP-connection credentials would land in plain SQLite inside
    the workspace. Local-first makes this defensible, but it ships only as an explicit
    decision, never a silent default. Options to prepare: plain storage documented as
    such; OS keyring integration; env-var indirection.

Non-goals

  • No model marketplace/registry — out of scope for this distribution.
  • No training or fine-tuning surfaces.
  • No bundled default connection of any kind.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions