Skip to content

Releases: americanjeff/modelspoke

v0.3.3

Choose a tag to compare

@americanjeff americanjeff released this 18 Oct 21:29

Rebuilt and re-verified against the dsh 0.2.1 host line. No behavior change.

The 0.2.1 contract change consumed

  • The host's ConfigFormSnapshot.mode ('host' | 'memory') field is gone in the
    0.2.1 line (dsh 23c29d067a, "persist authenticated browser preferences on the
    Host"): remote browsers now persist preferences to the Host, and a read-only
    form is expressed by writable: false alone. modelspoke's client hard-coded
    mode: "memory" in its locale fallback snapshot const, which failed the
    client typecheck against the 0.2.1 types (TS2353); the field is dropped.
    Nothing else in the plugin read .mode.

Verification

  • 797 unit tests green (vitest)
  • Full e2e — 92 assertions — green against a live dsh 0.2.1-rc.2 host; no
    selector rework needed
  • dsh-* devDependencies now ride the next channel (0.2.1-rc.2, the running
    host channel, same convention as dsh-image-settings); peer ranges untouched
  • Publish path: first modelspoke release cut via npm trusted publishing
    (tag push → GitHub Actions → OIDC npm publish, Sigstore provenance
    attached); the .github/workflows/publish.yml workflow is new in this tree

The attached asset is the official npm registry tarball for 0.3.3.

v0.3.2

Choose a tag to compare

@americanjeff americanjeff released this 30 Sep 01:08

What's new

Fixed: deleting every model row no longer flips a provider to serving its whole catalog

Removing all rows and hitting Apply used to store the route with no models: list, which reads back as "serve the full catalog": the card re-populated with every model from the provider. An empty list is now a real, stored state (models: "none" — configured, serves nothing) and stays empty across reopens. Hand-edited models: [] or absent models: still mean the full catalog, as before.

A new provider starts empty

Connecting a provider no longer immediately serves (and, after the first edit, routes) every model in its catalog. The new provider is configured but serves nothing until you add models; the catalog remains visible in the card to add from.

Fixed: tool calls silently broken on dsh 0.2.0-rc.2

dsh 0.2.0-rc.2 bundles pi-ai ≥0.87, which reads request tools only from its new transcript context shape. modelspoke's context envelope dropped the tool schemas from the wire, and the model answered with literal <toolcall> XML text instead of calling tools. modelspoke now folds its context through the host's normalizeContext when it is present (runtime feature detection, so hosts on older pi-ai are untouched). Verified end-to-end against a live dsh 0.2.0-rc.2 web (92-assertion E2E).

v0.3.1

Choose a tag to compare

@americanjeff americanjeff released this 28 Sep 05:56

What's new

Fixed: the session now gets the capabilities the provider card already showed

The session's model resolution skipped the backend-registry scan the settings card runs, so a model like glm-5.3-flash:cloud on an Ollama route listed its full reasoning-effort map, image input, and 1M context window on the card while the session resolved the same model on defaults: no reasoning-effort control in the session, read_image refusing with "does not declare image input", and a silent 256K context fallback. Card and session resolve through the same discovery tier now (equally for SGLang / vLLM / LM Studio / llama.cpp routes). A thinking model the built-in tables don't cover simply offers no effort control — the server's own default thinking applies.

Fixed: "Off" actually turns thinking off on Ollama models

Selecting Off dispatched no effort at all, so the server default applied (max thinking on glm-5.3-flash:cloud); Off now sends the model's own off spelling (reasoning_effort: "none").

The settings card is flat

No expand/collapse, no boxed panel: the providers section renders directly on the plugin page, open on arrival.

v0.3.0

Choose a tag to compare

@americanjeff americanjeff released this 24 Sep 04:49

modelspoke 0.3.0 — dsh 0.1.7 host support

Breaking: the host requirement is now dsh 0.1.7 (verified against
0.1.7-rc.1). dsh 0.1.5 and 0.1.6 hosts are no longer supported.

What changed for you

  • The settings home moved. dsh 0.1.7 removed the settings brand seam
    (installSettingsSection / the "Plugin configuration" tab). Modelspoke's
    configuration now lives in the active profile's cordis.patch.yml
    (the modelspoke entry), written through the dsh config editor. A
    settings.yaml left by an older dsh is imported once on first 0.1.7
    boot (then renamed settings.yaml.imported), so an existing configuration
    migrates automatically.
  • The card moved. The Modelspoke settings card now renders on the
    sidebar Plugins page (the modelspoke bundle detail), not inside the
    Settings dialog — 0.1.7's Settings dialog holds a read-only "Built-in
    plugins" inventory instead.
  • read_image rows render natively (the dsh 0.1.5 host fix) — no
    plugin-side view.

Per-model configuration, server discovery, the curation presets, and the
draft-scoped reset flow are unchanged in behavior — end-to-end verified
against a live 0.1.7-rc.1 dsh web profile (86-assertion e2e suite).

v0.2.0

Choose a tag to compare

@americanjeff americanjeff released this 11 Sep 22:29

v0.2.0

Breaking: the host requirement is now dsh 0.1.5

modelspoke loads on dsh 0.1.5 and newer only (verified against 0.1.5-rc.2); dsh 0.1.1 and 0.1.2 hosts are no longer supported. The loopback metadata bridge that rode the host's logical RPC channel is now a plain authenticated POST /api/modelspoke Fetch route — same reachability, no correlation machinery (the 0.1.5 host reads webServer on a fiber that never injects it for third-party plugins — dsh BUG-025).

The custom read_image view is retired

dsh 0.1.5 ships its own read_image row (read-family chrome, collapsed-by-default card, session-authorized image loader, PTC-nested coverage) that modelspoke's earlier view only shadowed. The renderReadImages setting is gone: if you ever set it, delete that line from your modelspoke: section.

Fixed: deleting a model row and re-adding the same model resurrected the deleted row's saved settings

The re-added row is a fresh row, but the card's committed-configuration lookup keyed the deleted row's settings (for example a stale input: [text] that out-shadowed the live discovery's image-input support) onto the re-add by name / wire id. A within-session removal now blocks that re-association: the re-added row seeds from discovery as if it were never configured, and an edited re-add commits a fresh entry instead of re-minting the deleted row's settings.

v0.1.4

Choose a tag to compare

@americanjeff americanjeff released this 07 Sep 02:08

The web UI (the browser half of the plugin) now works under dsh 0.1.2.

dsh 0.1.2 reorganized the client architecture: dsh-client-runtime was
dropped (its types scattered across dsh-api-session-controller,
dsh-client-ui-settings, dsh-client-ui-conversation, and
dsh-client-ui-renderer), the ctx.connection.api remote client was
replaced by a namespaced ctx.remote client, and the web shell's module
table changed. The 0.1.3 client bundle targeted the 0.1.1 shell's module
table and surfaces, so it did not load under a 0.1.2 web shell.

This release rebuilds the client half against the 0.1.2-rc.1 web shell:

  • the model card's catalog fetch now goes through
    ctx.remote.llm.discoverModels (namespaced remote client,
    RemoteResult envelope, LlmDiscoveredModel rows) instead of the removed
    connection.api.llm;
  • the bundle's externals now match the 0.1.2 platform module table — at
    runtime the bundle requires only react and react/jsx-runtime;
  • the dsh.client manifest now declares the five 0.1.2 provider rows.

Verified: the full e2e suite (85 assertions) green against a live
0.1.2-rc.1 dsh web instance + llama-swap + chromium, and 796 unit tests.

Compatibility: the node half loads under both dsh 0.1.1 and 0.1.2
(unchanged from 0.1.3). The client bundle targets the 0.1.2 web shell.

Update: re-run the install command for each profile you use
(dsh plugin --profile web add modelspoke, …), then restart dsh.

v0.1.3

Choose a tag to compare

@americanjeff americanjeff released this 05 Sep 20:11

v0.1.3 — dsh 0.1.2 host compatibility

modelspoke now loads and serves its routes when your dsh installation is updated
to 0.1.2 (previously it failed to load after the dsh update). 0.1.1 is
still supported
— one build works on both.

What changed for you

  • Works on a dsh 0.1.2 host. Two dsh 0.1.2 API changes had made modelspoke
    fail to load; a small version-tolerant shim (src/dsh/compat.ts) now handles
    both, resolving to the 0.1.1 symbols on a 0.1.1 host and the 0.1.2 ones on a
    0.1.2 host:
    • dsh-llm renamed its tool-call-id brand CallId → ToolCallId. This was
      a link-time break — the named import threw before any code ran.
    • dsh-settings dropped the installSettingsSection / settingsNamespace
      free functions in favor of a ctx.inject(["settings"], …) service seam, and
      moved deepEqualJson off the main entry.
  • Verified end-to-end on 0.1.2-rc.1 (a task routed through a modelspoke
    route served a real model response) and regression-checked on 0.1.1.

Also in this release

  • Completed the 0.1.2 changelog header (the shipped 0.1.2 work had been left
    under "Unreleased").

One known follow-up

  • The settings card (web UI) is the one surface not yet web-verified on a
    live 0.1.2 host — it is unchanged from the 0.1.1 release and has no
    dsh-client-* runtime dependency, so its risk is limited to core
    service-interface stability. The routes it configures work regardless.

v0.1.2

Choose a tag to compare

@americanjeff americanjeff released this 05 Sep 17:14

v0.1.2

Single-command install — no pnpm build-script approval. modelspoke no
longer pulls its own pi-ai copy into the profile; it uses the one its dsh
installation ships (tested span 0.82.1–0.84.x). A fresh profile install now
pulls nothing beyond modelspoke itself, so the pnpm 11 build-approval gate
can no longer trip it.

The settings UI moved to the Plugins settings page. The standalone
"modelspoke" settings section is replaced by an expandable Modelspoke
card in Settings → Plugins → Plugin configuration; expand the card, then
+ Add provider.

The first-run "Use your local models" import step is gone. Its trigger
was too narrow to be worth keeping. To migrate a hand-written llm-pi-ai
block: add the modelspoke route manually (same name/base URL; the block
shadows a same-named route until you delete it), then delete the block.

Install: see the README — npm install --global pnpm once (skip if you
already have pnpm), then one dsh plugin --profile <name> add modelspoke
per profile, then a dsh restart.

v0.1.1

Choose a tag to compare

@americanjeff americanjeff released this 04 Sep 13:21

v0.1.1 — 2026-09-04

  • ./lib core hardening — discoverModels no longer crashes in a browser bundle (accepts a caller-resolved apiKey; the apiKeyEnv read degrades to "no key" without process.env); non-object /v1/models elements degrade to a bare row instead of throwing; server error bodies are read with a cap; extractInput never reports image without text; matchPreset tolerates a malformed pattern in a caller-supplied catalog; the resolveModel tier-1 precondition is documented.
  • A model loaded into the router (e.g. llama-swap) after the last /v1/models fetch now shows up in dsh within a minute, without a process restart (discovery memo TTL).
  • A route models list whose elements are all malformed (e.g. an empty id) now degrades to the full catalog, instead of serving an explicit empty set.

Asset modelspoke-0.1.1.tgz is the official npm registry tarball.
sha256: 81385b0481da8b9f2df3ba929cece30da73a006d2677234f744d4fd6f266e6d4

v0.1.0

Choose a tag to compare

@americanjeff americanjeff released this 04 Sep 04:57

modelspoke 0.1.0

First public release.

modelspoke is a DeepSeek Harness (dsh) plugin: it discovers local OpenAI-compatible model servers and resolves per-model reasoning metadata — thinking levels, context window, modalities, compat — through a tiered chain (override → preset → discovered → default).

Install

dsh plugin add modelspoke

Then add routes in dsh settings (the plugin offers the onboarding flow on first use). Full setup: README.

What's in 0.1.0

  • Discovery — a llama-swap catalog tier plus five server-specific backends (SGLang, Ollama, LM Studio, vLLM, llama.cpp) under a frozen C1–C12 discovery contract, with the shared conformance corpus in contract/.
  • Resolution — per-route tiered metadata resolution (user overrides → built-in presets → live discovery → defaults), with fail-soft per field and no invented values.
  • Presets — four built-in chat-template presets (Qwen 3.8 / 3.6 / 3.5, gpt-oss-120b) pinned by a drift checker that verifies template pins against the upstream repos.
  • ./lib export — the framework-neutral core (discovery backends, canonical types, resolver) for other hosts; the . entry is the dsh plugin.
  • Settings UI — routes, per-model detail view, and the preset-draft authoring command (npm run preset-draft) in the dsh client.
  • Coverage — 846 unit tests, a 405-vector conformance corpus, and an 11-journey e2e suite (test/e2e).

Docs: design · provider details · dsh plugin guidance

The release asset is the official npm registry tarball (shasum-verified against the publish).