@loadline/providers
v0.1.1
Published
Model access for loadline gates. Anthropic and OpenRouter, behind one interface.
Readme
@loadline/providers
Model access for loadline gates. Anthropic and OpenRouter behind one interface.
import { createSelector, resolveProvider } from '@loadline/providers';
const { provider } = resolveProvider(); // reads the environment
const selector = createSelector(provider, model);
const calls = await selector.select({ question, tools, instructions });Why two providers
A gate that only runs against one vendor's model tests that vendor, not your system. Running the same suite across providers is how the interesting findings surface — a rule that holds on one model and is ignored by two others is a different problem from a rule that holds everywhere.
It is also about cost. A gate that runs on every pull request has to be cheap enough that nobody argues for removing it, which usually means OpenRouter and a capable non-frontier model rather than the largest thing available.
Resolution
OPENROUTER_API_KEY is preferred when both are set; ANTHROPIC_API_KEY is used
otherwise. Pass { provider } to force one. When neither key is present,
resolveProvider returns { provider: undefined, problem } rather than
throwing — the caller decides how to report a missing key, and a gate should say
which variable to set rather than print a stack trace.
Defaults: claude-opus-5 on Anthropic, z-ai/glm-5.2 on OpenRouter. Any model
with tool-calling support works via --model.
Shape
interface ToolCall { name: string; input: Record<string, unknown>; }
interface ToolSelector {
label: string; // shown in reports and stored in baselines
select(request: SelectRequest): Promise<ToolCall[]>;
}OpenAI-shaped tool calls arrive as JSON strings and are parsed defensively: a
model that emits malformed arguments should produce a case that fails, not a
crash that takes the run down. toOpenAiTools and parseOpenAiToolCalls are
exported for anyone wiring up a third provider.
label includes the model id and is recorded in the baseline, so a comparison
across two different models is visible rather than silent.
