Repository navigation
Releases: seonzzy/dsh-zen-adapter
Release list
v0.2.0
Note
如果你是从 v0.1.x 升上来的:那两个版本完全不可用(每个请求 403 / 每轮 PI_AI_ERROR),
没有需要迁移的配置,直接换到这一版即可。
Fixed
-
Every chat turn failed with
Cannot read properties of undefined (reading 'apiKey')(PI_AI_ERROR), while the availability probe kept
reporting models as reachable. The provider was built without an auth
plane, so pi-ai dereferencedprovider.auth.apiKeyon the first request and
threw before anything reached the network — which is exactly why the probe,
which speaks HTTP directly rather than through pi-ai, still looked healthy.The provider now carries a placeholder api-key method that satisfies pi-ai's
resolution path, and the adapter's credential seam returnsundefinedrather
than''so the request-level override is omitted entirely. The lane remains
anonymous: no credential is sent, andAuthorizationis suppressed explicitly
rather than filled with a placeholder value. -
The catalog re-downloaded 5.69 MB on every catalogue build. models.dev
answers with a single document covering every provider it knows, of which this
plugin reads one section. It is now cached on disk with its own TTL, and the
previously declared-but-unusedMETADATA_TTL_MS(24 hours) is what actually
governs it — the on-sale list keeps the shorter 5-minute TTL, because a new
model should appear in the picker promptly.Startup no longer waits for that download, an offline start still gets a full
list, and the refresh button still forces a real round trip instead of being
answered from cache.
Changed
- The upstream endpoint is
https://opencode.ai/inference/v1; the previously
used/zen/v1path is retired. The request shape that the lane accepts is
now centralised inlib/upstream.js.
Notes
- Verified against the live lane with the plugin's own code path
(ZenCatalogService.probeAll()): 8 of 12 advertised free models answer,
including multi-turn recall. The remaining failures are upstream-side and are
expected —cat-jam-freeandmuse-spark-1.3-contributor-freeare
region-blocked (403 RegionError),jev-1.13-freeis
400 ModelProtocolUnsupported. - Cache location is
~/.cache/dsh-zen-adapter/catalog.db, following the same
convention asdsh-free-search. Delete that directory to clear it; nothing
else is left behind.ZEN_CACHE_DIRrelocates it. - The free lane is undocumented upstream behaviour and may change without
notice. If every model starts returning403, the gate has moved — the
availability button is the early warning for that.
v0.1.1
Warning
此版本同样不可用。 403 已经修好,但对话每一轮都会失败
(PI_AI_ERROR:Cannot read properties of undefined (reading 'apiKey'))——
provider 缺了 auth plane,pi-ai 在发请求前就抛错了。
请直接安装 v0.2.0。
Fixed
-
Free lane rejected every request with
403 FreeTierError. The session id
sent upstream was well-shaped but derived wrongly: its 12 hex characters came
from a SHA-256 digest, while the lane decodes them as a bit-inverted wall
clock and refuses anything that is not a plausible timestamp. Every request
failed, including ones that previously worked, while the catalog stayed
readable — so the plugin looked healthy and simply could not talk.The clock part is now produced with upstream's own arithmetic
(BigInt(timestamp) * 0x1000n + counter, then~, taking 6 bytes), in a new
lib/session.jsshared by the adapter and the availability probe.Two consequences worth recording, because both mislead:
- A shape match proves nothing.
/^ses_[0-9a-f]{12}[0-9A-Za-z]{14}$/
accepts the broken ids, so no shape assertion could have caught this. ffeis not a token. Ids that end inffehappen to work when
counteris 1, because~1ends inffe;~2ends inffdand~300
ined3. Hard-coding the suffix still yields a digest, not a clock.
- A shape match proves nothing.
-
The availability probe generated its own session id — a second copy of the
same broken derivation. The probe button would have reported403for every
model while chat worked, which reads as "upstream is down" rather than "the
probe is malformed". Both call sites now share one implementation.
Notes
- Verified against the live lane with the plugin's own code path
(ZenCatalogService.probeAll()): 5 of 10 advertised free models answer.
The remaining failures are upstream-side and are expected —
ling-3.1-flash-freeandstep-5-preview-freethrottle (429),
jev-1.13-freeis SystemOne-only (400 ModelProtocolUnsupported),
muse-spark-1.3-contributor-freeis region-blocked (403 RegionError). - A wrong recipe for this outage circulated publicly (switch to
/inference/openai, dropAuthorization, add ashelltool). It does not
work: the gate is the session id, not the endpoint, the auth header, or the
tool names.
v0.1.0
Warning
此版本完全不可用。 每一个请求都会被上游拒绝(403 FreeTierError)——
会话 id 的时钟推导方式不对,上游只接受看起来像时间戳的值。
请直接安装 v0.2.0。
Initial release.
Added
- Native DSH provider
zen-free— OpenCode Zen's free models registered
throughllm.registerAdapter(), so they appear in the model picker as the
OpenCode Zen (free lane) group. No signup, no API key, no extra process. - Live model catalog — the free roster is discovered at runtime from
opencode.ai/zen/v1/modelsintersected withmodels.dev/api.json, rather
than hard-coded. Refreshed in the background every 30 minutes, and a refresh
is announced to the client so the picker updates without a restart. - Free determination from pricing — a model is offered only when
models.dev reportsinputandoutputcost of 0. Deprecated or paid models
are refused even when their id ends in-free, because upstream keeps
delisted ids on sale for a while. The-freesuffix is a fallback used only
when metadata is missing altogether. - Real context limits —
contextWindowandmaxTokenscome from
models.dev per model instead of a fixed constant, so a 1M-token model is not
understated and a 200K model is not overstated. - Plugin detail page — a panel under Settings → Plugins → dsh-zen-adapter
with 获取模型 (re-pull the catalog) and 检测可用性 (send a real request
per model to see which ones answer right now), plus a table of model id,
context size, output limit, availability status and the reason behind it. - Zero dependencies —
@deepseek-ai/*and@earendil-works/pi-aiare
declared as optionalpeerDependenciesand resolved through the host's
module tree, so exactly one pi-ai generation exists on the machine and the
plugin can be installed alongside other provider plugins.
Notes
- Upstream availability is per-IP quota'd, and some models carry regional
restrictions. A model being listed does not mean it will answer:429,
403 RegionErrorand5xxare upstream-side behaviour this plugin cannot
fix. Use 检测可用性 to see current status. PROVIDER_IDis deliberatelyzen-freerather thanzen, because
llm.registerAdapter()is all-or-nothing and a second claimant of an
existing provider id throwsDUPLICATE_ADAPTER.