Files
pygienium/AGENTS.md
Michael Freno 6213281b3c fix: give sub-agents the provider their pinned model needs
Sub-agent sessions are created with `noExtensions: true`, which also
removes every provider an extension registered through
`pi.registerProvider` from the sub-session's own ModelRuntime. Since
bff187d pinned sub-agents to the invoking session's model, every check
depends on a provider registration it deliberately does not load, so
scans died in about 20ms with "No API key found for neuralwatt" on a
perfectly healthy login — the key was in auth.json, the provider simply
did not exist in that session's runtime.

Thread the invoking session's registry down to the runner and
re-register just the pinned model's provider there, through an inline
extension factory: inline factories load regardless of `noExtensions`,
so the sub-agent authenticates exactly as the host does while every
other extension stays out of its scope. Registrations are narrowed once
at the extension entry point (`asProviderRegistry`) and relayed
untouched — a native provider keeps its own stream and auth wiring.

The generated omp port keeps its isolation: it disables extension
discovery and has no extension registrations to forward, so it carries
the same shapes with a stub for the helper.

Tests: new tests/provider-forwarding.test.ts pins the narrowing and the
relay (native wins over config-only, nothing forwarded for a built-in);
it fails on the previous tree, where the helper does not exist. Full
suite 162 pass with one pre-existing failure (MISC-46, worktree-only).
bun run typecheck clean; port-to-omp regenerates and typechecks.

MISC-45

Co-Authored-By: nw-flash-flex <noreply@neuralwatt.com>
2026-10-20 17:43:54 -04:00

37 lines
3.0 KiB
Markdown

# AGENTS.md
Pygienium is a `pi` extension: code-hygiene checks that scan a target with isolated sub-agent sessions (analysis), optionally apply fixes, then verify artifacts. Sub-agents are defined as markdown in `agents/*.md` (YAML frontmatter: `name`, `allowedTools`; body = system prompt).
## Commands
- `bun run typecheck` — `tsc --noEmit` on `src/`
- `bun test` — full suite (bun test)
## Layout
- `src/checks/` — check definitions; self-register on import (`registerCheck`)
- `src/agent-runner.ts` — spawns sub-agent sessions; runner injectable (`setAgentRunner`), tests use `fakeAgentRunner` (no real model calls)
- `src/commands.ts` — slash-command handlers, exported for direct test invocation with a stub `PygieniumCtx`
- `tests/` — bun tests; stub ctx with `{ cwd, mode: "print", hasUI: false, ui: undefined } as PygieniumCtx`
- `port-to-omp.mjs` — regenerates the self-contained omp port (see commit process)
## Conventions
- Checks: `gate` (skip reason), `buildScanTask`, optional `buildFixTask`, optional `verify`. Scan tasks embed `!write`/`!echo` lines as deterministic fallback for the fake runner.
- Sub-agent sessions must be pinned to the invoking session's model: thread `ctx.model` through `PygieniumCtx` → run options → `AgentTaskOptions.model` → `createAgentSession({ model })`.
- A pinned model needs its provider too: a provider an extension registered (`pi.registerProvider`) exists only in the invoking `ModelRegistry`, and the sub-session runs `noExtensions`, so thread `ctx.modelRegistry` (narrowed by `asProviderRegistry`) through the same chain to `AgentTaskOptions.modelRegistry` → `providerForwardingExtension`, which re-registers that one provider through an inline factory. Drop that link and every check dies with `No API key found for <provider>`.
- Keep files modular; no compatibility shims.
## Commit process (IMPORTANT)
Commits are gated by the pre-commit hook (enable: `git config core.hooksPath .githooks`). It regenerates the omp port into a temp dir and typechecks it — exactly what CI runs. A failing hook blocks the commit; never bypass with `--no-verify`.
`port-to-omp.mjs` rewrites source via exact-string matchers (`FILE_RULES`). Editing these files **requires** keeping the matching ops in sync or the port regeneration throws and the commit is blocked:
- `src/index.ts` — removes `mode: ctx.mode` from the `pygieniumCtx` literal
- `src/commands.ts` — removes `mode` from the `PygieniumCtx` Pick; swaps `ctx.mode` for `ctx.hasUI` in `print`
- `src/agent-runner.ts` — swaps the SDK import + loader for the omp SDK's `createAgentSession` options (`toolNames`, `systemPrompt`, `agentRegistry`, …); reduces `ProviderRegistry` to an SDK-free shape and stubs `providerForwardingExtension` (the port disables extension discovery, so it has nothing to forward)
- `src/agents.ts` — `find` → `glob`
After touching any of those, run `bun port-to-omp.mjs --out <tmp>` and `(cd <tmp> && bun run typecheck)` before committing; the hook does the same.