npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-pi-agent-providers

v0.1.2

Published

The pi agent's provider catalog (~/.pi/agent/models.json) as DeepSeek Harness LLM routes — installable and removable with `dsh plugin`, no dsh source patch

Readme

dsh-pi-agent-providers

dsh-TUI · 一个为 dsh-TUI 生态打造的插件

Imports the providers in pi's ~/.pi/agent/models.json as DeepSeek Harness llm routes, so models you already configured for the pi agent appear in the harness model pickers. Keys are read from the pi file on each request and are never copied into ~/.dsh.

~/.pi/agent/models.json   ->   pi-kividas, pi-code-for, pi-20xpin, ...

Install

dsh plugin --profile <name> add dsh-pi-agent-providers

Restart the profile. To remove:

dsh plugin --profile <name> remove dsh-pi-agent-providers

dsh picks up the package's cordis.patch.yml through its dsh.bundle.patch field, so removing the dependency removes the layer. Nothing in dsh or dsh-TUI needs to change.

pnpm reports this package's @deepseek-ai/* peer dependencies as missing during install. That is harmless: dsh installs the framework tree once under $DSH_HOME/profiles/node_modules, so the plugin resolves the same @deepseek-ai/dsh-llm-pi-ai the adapter loaded.

Configuration

Set in the patch row's config: block.

| Option | Default | Meaning | | --- | --- | --- | | configPath | $PI_CODING_AGENT_DIR/models.json, else ~/.pi/agent/models.json | File to import. The default follows pi's own resolution. | | routePrefix | pi- | Prepended to every route id. | | providers | all | pi provider keys to import. A key the file does not have is reported in the log. | | refreshIntervalMs | 5000 | How often the route set is reconciled with the file. |

A route id is the provider key lowercased, with anything outside [a-z0-9-] replaced by -, and routePrefix in front. The prefix is what makes 20xpin usable: on its own it does not start with a letter, so it is not a valid id.

Behaviour

  • The pi file is the only source of truth. Each route's key is read from it per request.
  • One adapter per route, so a route id another adapter already owns is logged and skipped while the rest still mount.
  • Edits reach the next request. Providers added or removed join the picker within refreshIntervalMs. No restart, no settings write.
  • A provider or model that cannot be served is reported by name and skipped. An unreadable file keeps the last good catalog instead of emptying the picker.

Mapping

| pi agent | harness / pi-ai | Notes | | --- | --- | --- | | baseUrl (provider or model) | Model.baseUrl | Model level wins, as in pi. | | api (provider or model) | Model.api | openai-completions, openai-responses, anthropic-messages. A route whose models disagree gets an api map, so pi-ai dispatches per model. | | models[].{id,name} | Model.{id,name} | name defaults to id, as in pi. | | models[].{contextWindow,maxTokens} | Model.{contextWindow,maxTokens} | Defaults are pi's (128000 / 16384), not the harness's. | | models[].reasoning | Model.reasoning | Defaults to false, as in pi. | | models[].thinkingLevelMap | Model.thinkingLevelMap | Levels pi-ai does not know are dropped and named. Absent stays absent, so pi-ai's asymmetry (base levels supported, xhigh / max not) is preserved. | | models[].input | Model.input | Defaults to ["text"], as in pi. | | models[].{cost,samplingParams} | Model.{cost,samplingParams} | Passed through when present. | | provider.compat + models[].compat | Model.compat | Merged as pi merges them, including key-by-key merging of openRouterRouting, vercelGatewayRouting, chatTemplateKwargs and chatTemplateArgs. | | apiKey | per-request credential | Read at request time; never persisted into ~/.dsh. | | authHeader: true | Authorization: Bearer <key> | Added on top of the protocol's own auth, as in pi. |

Provider-level oauth, modelOverrides and extensions are not imported: the first needs a credential flow rather than a key, and the other two extend a catalog this plugin does not read. Such a provider is skipped and named in the log.

If a gateway rejects off

A thinkingLevelMap value is the string sent on the wire, not a label for what you mean. pi calls the "no reasoning" level off; the OpenAI Responses API calls it none. So "off": "off" sends off, and a gateway accepting only none, minimal, low, medium, high, xhigh and max answers Invalid value: 'off' (param: reasoning.effort).

It breaks only when a request names no reasoning effort, since pi-ai then sends thinkingLevelMap.off ?? "none". Use "off": "none", or "off": null to send no reasoning field. Leave the rest of the map in place: xhigh and max are not in pi's default level set, so deleting the map loses those two levels.

Catalogs from a switcher often contain "off": "off", because the level names are copied from the provider record unchanged. The pi agent reads the same file and fails the same way.

Why there is no dsh-plugin.json

That manifest describes a TUI-plane plugin, registering contracts from dsh-TUI's ecosystem spec (tui.dsh/v1alpha1, commands.dsh/v1alpha1, and so on). This package registers into the harness's llm registry and declares no ecosystem contract, so it is a host-plane bundle only: package.json (dsh.bundle.patch) plus cordis.patch.yml.

Publishing

npm publish from this repository. prepublishOnly runs verify, so lib/ is rebuilt from src/ before the tarball is written; build output is not tracked in git.

Development

pnpm install
pnpm run verify                                   # tsc build, smoke, boot; offline
node scripts/live.mjs pi-20xpin gpt-6-astra low    # opt-in, one real request

scripts/smoke.mjs needs no cordis, harness or network: parsing and its diagnostics, route id mapping, the authHeader bearer header, the api shape pi-ai dispatches through, route construction against the installed pi-ai, and pi-ai's own getAuth.

scripts/boot.mjs mounts the plugin into a real cordis composition carrying only the llm service and reads the registry back: per-route registration and conflict isolation, the context window and thinking levels a picker sees, providers appearing and disappearing as the file changes, and a malformed file keeping its routes. Fixtures in a temp directory keep it off your own ~/.pi.

scripts/live.mjs sends one real request, so it costs money and needs network. It is not part of verify. It caught routes being handed pi-ai's protocol factory instead of the implementation pi-ai dispatches through, a mistake every offline check passes and the first request fails.

License

MIT