live: heartbeat sync 2026-10-29T15:29:37-07:00 (Refs #11)
This commit is contained in:
1 parent
3eb1ada55b
commit
4d76c6038e
14 files changed
+335
-16
No files matched your search
@@ -0,0 +1,86 @@
|
||||
---
|
||||
name: omp-provider-row-sources
|
||||
description: "Add a provider/model row to ~/.omp/agent/models.yml by reading the harness's own catalog tables (provider name, api, window, cost, compat) instead of guessing or web-searching, then prove it with a scratch-HOME call."
|
||||
---
|
||||
|
||||
# Scope
|
||||
|
||||
Adding (or correcting) a provider/model row in `~/.omp/agent/models.yml` for a
|
||||
provider the harness may already know: an upstream vendor API (DeepSeek, OpenAI,
|
||||
Anthropic, Moonshot, …) or a new local endpoint. The rule this skill exists for:
|
||||
**almost every field you are about to research on the web already exists in the
|
||||
installed bundle** — research there first, and the web only confirms it.
|
||||
|
||||
Canonical install root (resolve the symlink first if the repo lives under a
|
||||
worktree): `/home/blank/.bun/install/global/node_modules/@oh-my-pi/`.
|
||||
|
||||
# The three tables that own the facts
|
||||
|
||||
| You want | Read | Why |
|
||||
|---|---|---|
|
||||
| The legal **provider name**, its URL marker, and which quirks the harness gates on it | `pi-catalog/src/hosts.ts` (minified in `dist/cli.js` as the `VIn` map; consumed by `pi-catalog/src/compat/resolve.ts`) | The provider key is a **lookup key, not a display name**. e.g. `deepseekDirect: { providers: ["deepseek"], urlMarkers: ["api.deepseek.com"] }`, `anthropic: { providers: ["anthropic"], urlMarkers: ["api.anthropic.com"] }`. A label matching neither loses the behaviour set silently (the `max_tokens` field name, the thinking `extraBody`, the thinking-disable mode). |
|
||||
| Model rows: ids, `contextWindow`, `maxTokens`, `cost` rates, per-model `compat` | `pi-catalog/src/provider-models/<api>.ts` — `openai-compat.ts`, `anthropic-messages.ts`, …; factory helpers `openAiCompletionsDescriptor(...)` / `anthropicMessagesDescriptor(...)` | Rows are fetched from the provider's models-dev key, so the bundle carries the same numbers the vendor publishes (and often rates the vendor page hides). The descriptor's `compat:` block is the authored truth for that provider's transport shape — copy it, never simplify it. |
|
||||
| The **schema** itself (which keys are legal on a provider vs a model, and which are required) | `pi-coding-agent/src/config/models-config-schema-bundle.ts` (and the identical `dist/` copy) | Provider level and model level have *different* field sets. Cheaper and more correct than reading the minified bundle. |
|
||||
|
||||
Also in `pi-coding-agent/src/config/`: `model-registry.ts` (how `models.yml`
|
||||
merges onto the built-in catalog — `#mergeCustomModels` → `mergeByModelKey`),
|
||||
`resolve-config-value.ts` (how `apiKey` values resolve).
|
||||
|
||||
# Two traps this table pays for
|
||||
|
||||
- **Provider-level `api` only accepts chat/judge transports.** Naming a runner API
|
||||
(`openai-speech`, `openai-images`, `openai-embeddings`) at provider level fails
|
||||
whole-file validation and disables *every* custom provider, not just yours
|
||||
(`omp models` prints "models.yml validation failed", lists only built-ins).
|
||||
Runner api belongs on the **model** entry; see the managed skill
|
||||
`omp-models-yml-runner-api-placement`.
|
||||
- **A `models.yml` entry is an overlay, not a replacement.** Adding one model to a
|
||||
provider the catalog already ships does not remove the provider's other rows —
|
||||
`omp models <provider>` will show yours (yours wins on shared fields, including
|
||||
`cost` and `contextWindow`) plus the catalog rows. Same-id rows patch with the
|
||||
`replace` transport policy; a row that omits `contextWindow` inherits the
|
||||
bundled row's window and its policy tiers.
|
||||
|
||||
# Secret handling (non-prose tracked file)
|
||||
|
||||
Never inline the credential. `apiKey` resolution order is: leading `!` → command
|
||||
(`stdout` trimmed, cached for the process lifetime) → exact env-var name → literal.
|
||||
So write `apiKey: "!cat ~/.config/secrets/<name>_api_key"` with mode 600.
|
||||
|
||||
- A bare `sk-…` trips the pre-commit **shape** gate (every file type).
|
||||
- An unquoted `!` is a YAML tag — quote it.
|
||||
- A quoted command value also dodges the *assignment* gate: the gate's value
|
||||
charset rejects `~` and spaces, so only a literal key matches.
|
||||
|
||||
# Procedure
|
||||
|
||||
1. Read the three tables above for the provider you are adding. Take the exact
|
||||
provider name, base URL, api, and compat from them; take `contextWindow` /
|
||||
`maxTokens` / `cost` from the model row and cite the source in a comment.
|
||||
2. Write the secret to `~/.config/secrets/<name>_api_key`, `chmod 600`.
|
||||
3. Edit `models.yml`; for a repo-tracked config, follow that repo's own
|
||||
branch/log/index rules (in `dank/command-center`: branch → issue → PR).
|
||||
4. Verify with a **scratch HOME**, because `models.yml` loads at process start
|
||||
and a live session keeps the old registry:
|
||||
```bash
|
||||
mkdir -p /tmp/ompx/.omp/agent /tmp/ompx/.config
|
||||
cp agent/models.yml agent/config.yml /tmp/ompx/.omp/agent/
|
||||
ln -sfn ~/.config/secrets /tmp/ompx/.config/secrets # ~ in a !cmd value = $HOME
|
||||
HOME=/tmp/ompx omp models --no-extensions | grep -c 'validation failed' # must be 0
|
||||
HOME=/tmp/ompx omp --model '<provider>/<id>:off' --tools bash --no-session \
|
||||
--no-skills --no-rules --no-extensions --no-pty --no-lsp --no-title \
|
||||
--cwd /tmp -p 'Reply with exactly the word OK and nothing else.'
|
||||
```
|
||||
Then the **negative control**, the step that separates a real auth success from
|
||||
a cached/built-in answer: `sed` the `baseUrl` to a dead port in the scratch copy
|
||||
and repeat — it must hang or error, not answer. Then `rm -rf /tmp/ompx` (it
|
||||
holds endpoint URLs).
|
||||
|
||||
# Voice notes
|
||||
|
||||
- Prefer the bundled schema file over grepping `dist/cli.js`; grep the bundle only
|
||||
when the source and the bundle disagree, or for a runtime default the schema does
|
||||
not state (e.g. `reasoningDisableMode` per provider family).
|
||||
- `cost` is optional in the schema. Omitting it makes the status line report `$0`
|
||||
forever; one rate per direction is all the schema models, so a peak/off-peak
|
||||
vendor table can only carry the peak value.
|
||||
Reference in new issue
Block a user