DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Llm Pi Ai Live — DeepSeek Harness 插件(DSH Plugin)
← Plugins
L

dsh-llm-pi-ai-live

Llm Pi Ai Live

为 DSH llm-pi-ai 路由实时刷新模型列表:查询每个提供商端点,将已安装的 pi-ai 目录元数据合并到实时 ID 上,并通过官方设置接口追加新模型。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:WeatherWind/dsh-llm-pi-ai-live#ac92a8f5d91eed6feb9b59eeace2b5a46584abd3
README兼容性版本

兼容性与来源证明

Llm Pi Ai Live 以 dsh-llm-pi-ai-live 发布,当前版本为 0.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
github
Registry 更新时间
2026/9/29

版本

0.1.0stable
2026/9/29

相关插件

正在加载相关插件…

最新版
0.1.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
any
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/9/29
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录

相关插件

继续浏览 models-usage 分类下经过校验的插件。

Usage@linxin666/dsh-usage用于 dsh Web GUI 的使用统计插件:检测各提供商的余额和编程套餐配额,并实时记录令牌使用情况;侧边栏 Settings 行上方显示紧凑的价格概览卡片Client Ui Model Capabilities@linxin666/dsh-client-ui-model-capabilities为自定义 pi-ai 提供商声明每个模型的能力(图像输入和推理力度),可直接在 Models 设置卡片中编辑;写入官方 llm-pi-ai 设置命名空间,不更改 DSH 源代码。Codex Subscriptiondsh-codex-subscription通过 OAuth 在 DeepSeek Harness 中使用 ChatGPT 和 Codex 订阅,支持配额管理、安全重置、网页搜索、图像和快速模式Commandcode Provider@mars-sea/dsh-commandcode-provider适用于 Command Code 的非官方 DeepSeek Harness LLM 提供商插件,移植自 pi-commandcode-provider(MIT)。注册“commandcode”提供商路由,并在 Models 页面添加卡片和实时模型目录。

README

dsh-llm-pi-ai-live

English | 中文

A companion plugin that keeps DSH llm-pi-ai provider routes' model catalogs current with what their endpoints actually serve. It patches nothing: it works through the official settings, credentials, llm, and tools seams.

Why it exists

The shipped @deepseek-ai/dsh-llm-pi-ai adapter answers "which models can this provider serve?" from pi-ai's installed snapshot for every route the snapshot knows, and never contacts the endpoint:

// dsh-llm-pi-ai/lib/index.js  discoverModels()
const installed = catalogModels(request.provider)
if (installed.size > 0) return [...installed.values()].map(...)   // snapshot, no network

That is a deliberate trade — the snapshot carries contextWindow, maxTokens, and modality facts no listing endpoint discloses — but it means a model released after the pinned pi-ai version can never appear, and a hand-written models list stays frozen at whatever was typed.

The drift has been reported repeatedly:

  • #3816 — opencode-go serves 28 models live, the snapshot knew 16; glm-5.3, qwen3.8-max and others never showed up
  • #5306 — "model list is stale and incomplete — never refreshed from provider endpoints"
  • #5691 — "model catalogs are static: OpenRouter shows 333 of 431 models"
  • #4685 — "fetching models from OpenRouter doesn't work"

This plugin implements what those reports ask for together: always query the live endpoint, fall back to the catalog on failure, merge catalog metadata onto live ids, and actually persist the result into the route.

What it does

One refresh — scheduled, on startup, or via the refresh_model_catalog tool:

  1. Plan — read the live configurable-provider directory through llm.listConfigurableProviders() to learn each route's owning settings namespace and path. Nothing hard-codes llm-pi-ai: the settings namespace is the profile's loader entry id (include:llm-pi-ai in a stock profile), so a plugin that hard-codes the plugin name silently does nothing.
  2. Interrogate — GET {baseURL}/models with bearer auth for the OpenAI dialects, GET {root}/v1/models?limit=1000 with x-api-key and anthropic-version for Anthropic Messages. Both reply dialects normalize into one candidate shape.
  3. Merge — live ids decide membership; the installed pi-ai catalog supplies name, contextWindow, maxTokens, and input; an endpoint-reported capacity is the fallback.
  4. Persist — through settings.mutate(), re-reading the revision first and confirming the value landed afterwards.

Guarantees

  • Append-only. Existing entries pass through by reference, in order, with their fields untouched. New ids are appended. A model the endpoint stopped advertising is never removed.
  • Refuse rather than guess. If the stored models value is not a list this plugin can fully account for — a string, or an entry with no id — the whole route is skipped and reported, instead of being overwritten with a guess.
  • Failures never touch the configuration. A 5xx, a timeout, a non-JSON body, an unreadable protocol, or a rejected write all leave the route exactly as it was and appear in the report.
  • No synthesized risky fields. Only id, name, contextWindow, maxTokens, and input are ever written. reasoningEfforts and compat are deliberately never inferred from a listing: leaving them unset inherits the installed catalog entry's capability, which is always at least as correct as anything derivable from a bare list of ids.

Install

# 1) build
cd dsh-plugins/dsh-llm-pi-ai-live
npm install && npm run verify && npm run build

# 2) add to the target profile (local path uses link:)
dsh plugin --profile <profile> add link:$PWD

# 3) restart DSH

Alternatively merge the insert block from cordis.patch.yml into <DSH_PROFILE_DIR>/cordis.patch.yml.

Start with dryRun: true for the first pass. A dry run computes and reports without writing, and the report goes to the log:

[live-catalog] mounted (first pass in 0ms, periodic refresh off, dry run)
[live-catalog] openrouter: dry run — would add 464 model(s): openai/gpt-6.1-sol-pro, ...
[live-catalog] scheduled: 1 updated, 464 added, 0 failed, 0 skipped in 932ms

That output is from a real boot against OpenRouter's live endpoint. Turn dryRun off once it looks right.

Configuration

Every field is optional; defaults are documented in cordis.patch.yml.

FieldDefaultMeaning
enabledtrueMaster switch; false loads the plugin but schedules nothing
startupDelayMs10000Delay after mount before the first pass (ms); 0 runs it immediately, and the startup pass always runs
intervalMs21600000Period between passes (ms, six hours); 0 disables the periodic pass
timeoutMs30000Per-request network timeout
settingsNamespaces[]Namespaces to serve; empty auto-detects the pi-ai namespace
include[]Routes to refresh; empty means every configured route
exclude[]Routes to leave alone, e.g. ['openrouter']
enrichFromCatalogtrueFill new entries from the installed pi-ai catalog
maxModels2000Cap on stored model entries per route
dryRunfalseCompute and report without writing
toolEnabledtrueRegister the refresh_model_catalog tool

Declaring reasoning effort for third-party models

The gap, measured. A route pi-ai's catalog does not describe has to declare everything itself, and reasoningEfforts is the one field with no sensible default. Against a real DSH boot:

Third-party modelresolveModelInfo().reasoning
declares no reasoningEffortsnull — no thinking level is offered at all
declares reasoningEfforts{efforts: [off, high, max]} ✓
declares reasoningEfforts: falsenull (correctly declared non-reasoning)

Writing the map by hand works, but every new model needs it written again. This automates that without guessing:

reasoning:
  enabled: true
  rules:
    - provider: 'acme-gateway'   # glob against the route key
      model: 'glm-*'             # glob against the model id
      efforts:
        off: null                # null is allowed only for `off`
        high: high
        max: ultra               # rename a level for this gateway
    - provider: 'local-vllm'
      model: '*'
      efforts: false             # declare them non-reasoning

Only a genuine gap is filled, on two rules:

  • An entry that already declares reasoningEfforts — including false, which is a deliberate statement that the model does not reason — is never touched.
  • A model the installed catalog knows is never touched either: leaving the field absent inherits the catalog entry's capability, so nothing is missing.

Nothing is inferred from a model's name. The levels and their wire spellings are the operator's statement about their own gateway, and a wrong guess changes the request shape. A rule with a mistyped level is refused and named by index in the log, rather than failing silently.

Tool

refresh_model_catalog — optional provider narrows the pass to one route. Lets the agent pick up a newly released model on demand, with no config edit or restart.

What it does not do

  • It does not replace the "fetch available models" action. ctx.llm.registerModelDiscovery(ns) throws DUPLICATE_DISCOVERY for a namespace that already has one, and llm-pi-ai owns its own, so no external plugin can replace the built-in short-circuit. This plugin takes the other road: it writes the live result into the route's models.
  • It does not touch a route with no interrogable endpoint. A provider with neither a configured baseURL nor a catalog endpoint (pure-OAuth Bedrock/Vertex) is reported as NO_ENDPOINT.
  • It does not probe protocols. When a catalog route speaks several (OpenRouter ships both an Anthropic and an OpenAI dialect), the listing request uses the plurality dialect; the route's own models keep their individual protocols.
  • It does not fill fields beyond models. See the guarantee above.
  • A large gateway produces a long models list. Measuring OpenRouter's 464 live models wrote about 88 KB into cordis.patch.yml. That is the inherent cost of pinning the live directory into configuration; maxModels (default 2000) is the guard rail, and exclude can drop a route entirely.

How it differs from the other plugins in this space

Several community plugins already work this area, and the differences are worth knowing before choosing. The sharpest one:

  • This plugin does not go through ctx.llm.discoverModels('llm-pi-ai', …). That service short-circuits to the installed snapshot for any route the pi-ai catalog knows — the exact root cause #3816 and #5306 describe. A "live sync" built on it receives the snapshot. This plugin makes its own HTTP request instead.
  • Protocol-generic, not tied to one gateway: both the OpenAI dialects and Anthropic Messages listings are read.
  • Endpoint recovery from the catalog's models, which is what makes the common "credential-only route" case work for providers like opencode-go whose provider record carries no baseUrl.
  • Append-only with a refusal path: an unreadable models value abandons that route rather than overwriting it.
  • Never synthesizes reasoningEfforts or compat. Some peers probe or infer thinking levels; leaving them unset inherits the catalog capability, and a wrong guess changes the request shape.

Related work: mpetruc/dsh-model-sync, ddddd-ren/dsh-relay-toolkit (broader — settings UI, connectivity probing, capability backfill), Retr67/dsh-opencode-models, fan56/dsh-model-sync, zpis666/dsh-opencode-go-sync, dsh-model-catalog-refresh, dsh-model-catalog-sync. This plugin's trade-off is narrow and verifiable: no UI panel, with the effort spent on merge semantics and verification depth.

Development

npm run typecheck   # source and tests, via two tsconfigs
npm test            # vitest (unit + real-catalog integration)
npm run build       # src → lib
npm run verify      # typecheck + test
npm run test:e2e    # boot a real DSH and verify end to end

Two layers of tests:

  • test/{listing,merge,routes,sync,index}.test.ts — pure logic and orchestration over fake seams.
  • test/integration.test.ts — exercises the #3816 scenario (an opencode-go route configured with nothing but a credential) against the real installed catalog, and skips itself when @earendil-works/pi-ai is not resolvable.

To run the real-catalog integration test, link the profile's packages in:

PROF=$DSH_PROFILE_DIR/node_modules
mkdir -p node_modules/@earendil-works
ln -sfn $PROF/@earendil-works/pi-ai node_modules/@earendil-works/pi-ai

End-to-end verification

npm run test:e2e:

  1. builds a throwaway DSH_HOME and scratch profile under this package's .e2e/;
  2. links the packages of the profile you point it at (default ~/.dsh/profiles/desktop) and links this package in by name — the loader imports a bare specifier, and an absolute directory path cannot be resolved by ESM, so name: must be the package name;
  3. serves a fake /models endpoint on 127.0.0.1 and writes a patch mounting a real llm-pi-ai route;
  4. boots the real dsh --profile scratch;
  5. asserts the profile patch gained the endpoint's new model while the hand-written entry survived.

Point it elsewhere with DSH_PROFILE_DIR=... npm run test:e2e. No server other than the local fake endpoint is started.

This step is not optional. It caught two defects no unit test could: a missing timer in inject that stopped the plugin activating in a real profile at all, and a startupDelayMs: 0 guard that silently skipped the startup pass. Both are fixed and pinned by regression tests.

Dependencies and resolution

Per the official publish.md and the app-boot README:

  • Before importing a plugin, DSH checks every @deepseek-ai/dsh and @deepseek-ai/dsh-* entry in peerDependencies against the runtime version and refuses a mismatch. This plugin declares >=0.1.7-rc.2 <0.2.0.
  • Those packages are distributed inside the DSH installation and have no matching version on the public registry, so every peer is marked optional: true: the version claim still feeds the admission check, while pnpm is never sent looking for a package it cannot fetch.
  • Peers outside @deepseek-ai/dsh* (cordis, the timer plugin, pi-ai) are not admission-checked and are optional too.
  • @deepseek-ai/schemastery stays a plain dependencies entry: it is a stateless schema utility, which the official guide puts under dependencies, and shipping our own copy guarantees the plugin loads in any profile.

How pi-ai is found. The plugin does not depend on pi-ai at build time and resolves it at runtime in two steps: the ordinary bare import first, then a filesystem search, which matters because dsh plugin add produces pnpm's non-hoisted layout. The usual fallback cannot help — pi-ai exports no ./package.json and declares its subpaths under the import condition alone — so the plugin carries a minimal exports wildcard resolver (pi-ai declares "./providers/*", not a literal key). When both steps fail it is not an error: new models simply carry only what the endpoint disclosed.

Environment

inject: ['settings', 'llm', 'timer'] are hard dependencies; timer comes from @deepseek-ai/cordis-plugin-timer, which dsh-base already includes. credentials and tools are read optionally through ctx.get: without them the plugin still refreshes, it simply cannot resolve an apiKeyEnv reference and has no manual tool.

License

MIT