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

    deferred-needs-inputBlocked on a decision that belongs to the founderenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions