Summary
Audit across the Stackbilt ecosystem (2026-04-10) found 5 critical hotspots where eco repos make direct LLM provider SDK imports or raw HTTPS calls instead of routing through @stackbilt/llm-providers. This issue tracks the consolidation work and surfaces one capability gap in llm-providers that blocks a full migration.
Rule established 2026-04-10 (Kurt): "ANY bolted-in LM logic in any eco repo should be ultimately replaced with llm-providers imports."
Critical hotspots (production, deployed)
1. stackbilt-mcp-gateway — intent classifier
src/intent-classifier.ts:64 — direct fetch('https://api.cerebras.ai/v1/chat/completions', ...)
src/types.ts:95 — CEREBRAS_API_KEY env var reference
src/gateway.ts:465-467 — routes into the direct Cerebras path
Status: Being deprecated as part of the scaffold composition migration — the new engine-side composition (Stackbilt-dev/tarotscript docs/design-scaffold-composition.md, Phase E) uses deterministic tarotscript classify-cast and removes the mcp-gateway LLM fallback entirely. No migration needed; just deletion. Not a blocker for this issue, but close the loop when Phase E ships.
2. aegis-daemon — groq client
src/utils/groq.ts:1 — direct openai SDK import used as Groq client (baseURL override)
web/src/kernel/executors/groq.ts — multiple call sites wrapping an askGroq() helper that uses the direct SDK
- Inconsistency:
web/src/lib/llm.ts and web/src/kernel/executors/cerebras.ts already use @stackbilt/llm-providers correctly. Some paths are compliant, others aren't.
Action: Replace askGroq() with GroqProvider from @stackbilt/llm-providers. Audit all downstream consumers of the helper.
3. aegis-oss — mirror of aegis-daemon
web/src/kernel/executors/groq.ts — same pattern as aegis-daemon
Action: Same migration as aegis-daemon.
Peripheral hotspots (non-deployed / experimental)
Edgestack-Architech/worker/providers/groq.ts — direct Groq
Edgestack-Architech/worker/providers/anthropic.ts — direct Anthropic
voice_plaform_v2/packages/llm-client/src/groq.js — custom Groq client
Action: Deprioritize unless these ship to production. Tag with wontfix-unless-deployed if that's the call.
Capability gap in llm-providers
The highest-priority hotspot (mcp-gateway intent-classifier) uses a classification pattern — extract structured fields (pattern, routes, integrations) from a free-text intention. llm-providers currently exposes:
generateResponse() — text generation, tool calls, streaming
MODELS.* — model constants
getRecommendedModel() — use-case routing
- Circuit breakers, cost tracking, fallback logic
- Tool/function calling with validation
ImageProvider — image generation
Missing: a dedicated classify() method for structured extraction tasks. Callers either use generateResponse() with a carefully-crafted structured-output prompt (works but awkward) or fall back to direct SDK calls (current state).
Recommendation: Add a classify() method that wraps generateResponse() with:
- A structured-output schema (Zod)
- Automatic JSON mode / structured output provider selection
- Confidence scoring
- Deterministic seed support where the provider allows it
This unblocks the intent-classifier migration cleanly (even though Phase E of scaffold composition is deprecating that specific caller — a classify() primitive will be needed elsewhere).
Checklist
Already compliant (keep doing this)
aegis-daemon/web/src/lib/llm.ts:8-9 — imports GroqProvider, CloudflareProvider from @stackbilt/llm-providers ✅
aegis-daemon/web/src/kernel/executors/cerebras.ts:8-9 — imports CerebrasProvider ✅
@stackbilt/llm-providers itself — this is the integration point; direct SDK imports are intentional here ✅
Related
- Stackbilt-dev/tarotscript
docs/design-scaffold-composition.md — scaffold composition ADR, Phase E deprecates the mcp-gateway LLM classifier
- Stackbilt-dev/tarotscript#166 — agents/run silent fallback (adjacent trust-erosion bug)
- Sera auto-memory:
feedback_llm_providers_only.md — the rule being enforced
Severity
P2 — not blocking production, but every direct SDK import is provider lock-in creeping back in. The longer these sit, the harder the eventual consolidation.
Summary
Audit across the Stackbilt ecosystem (2026-04-10) found 5 critical hotspots where eco repos make direct LLM provider SDK imports or raw HTTPS calls instead of routing through
@stackbilt/llm-providers. This issue tracks the consolidation work and surfaces one capability gap in llm-providers that blocks a full migration.Rule established 2026-04-10 (Kurt): "ANY bolted-in LM logic in any eco repo should be ultimately replaced with llm-providers imports."
Critical hotspots (production, deployed)
1. stackbilt-mcp-gateway — intent classifier
src/intent-classifier.ts:64— directfetch('https://api.cerebras.ai/v1/chat/completions', ...)src/types.ts:95—CEREBRAS_API_KEYenv var referencesrc/gateway.ts:465-467— routes into the direct Cerebras pathStatus: Being deprecated as part of the scaffold composition migration — the new engine-side composition (Stackbilt-dev/tarotscript
docs/design-scaffold-composition.md, Phase E) uses deterministic tarotscript classify-cast and removes the mcp-gateway LLM fallback entirely. No migration needed; just deletion. Not a blocker for this issue, but close the loop when Phase E ships.2. aegis-daemon — groq client
src/utils/groq.ts:1— directopenaiSDK import used as Groq client (baseURL override)web/src/kernel/executors/groq.ts— multiple call sites wrapping anaskGroq()helper that uses the direct SDKweb/src/lib/llm.tsandweb/src/kernel/executors/cerebras.tsalready use@stackbilt/llm-providerscorrectly. Some paths are compliant, others aren't.Action: Replace
askGroq()withGroqProviderfrom@stackbilt/llm-providers. Audit all downstream consumers of the helper.3. aegis-oss — mirror of aegis-daemon
web/src/kernel/executors/groq.ts— same pattern as aegis-daemonAction: Same migration as aegis-daemon.
Peripheral hotspots (non-deployed / experimental)
Edgestack-Architech/worker/providers/groq.ts— direct GroqEdgestack-Architech/worker/providers/anthropic.ts— direct Anthropicvoice_plaform_v2/packages/llm-client/src/groq.js— custom Groq clientAction: Deprioritize unless these ship to production. Tag with
wontfix-unless-deployedif that's the call.Capability gap in llm-providers
The highest-priority hotspot (mcp-gateway intent-classifier) uses a classification pattern — extract structured fields (pattern, routes, integrations) from a free-text intention. llm-providers currently exposes:
generateResponse()— text generation, tool calls, streamingMODELS.*— model constantsgetRecommendedModel()— use-case routingImageProvider— image generationMissing: a dedicated
classify()method for structured extraction tasks. Callers either usegenerateResponse()with a carefully-crafted structured-output prompt (works but awkward) or fall back to direct SDK calls (current state).Recommendation: Add a
classify()method that wrapsgenerateResponse()with:This unblocks the intent-classifier migration cleanly (even though Phase E of scaffold composition is deprecating that specific caller — a
classify()primitive will be needed elsewhere).Checklist
classify()capability to@stackbilt/llm-providers— wrapsgenerateResponse()with structured-output schema + confidence scoringsrc/intent-classifier.tsis complete when Phase E of scaffold composition ships (tracked in Stackbilt-dev/tarotscriptdocs/design-scaffold-composition.md)src/utils/groq.ts+web/src/kernel/executors/groq.tswithGroqProviderfrom@stackbilt/llm-providers@anthropic-ai/sdk,openai,groq-sdk,cerebras-cloud-sdk,@mistralai/mistralai,@google/generative-ai— enforcement gatewontfix-unless-deployedor migrate case-by-caseAlready compliant (keep doing this)
aegis-daemon/web/src/lib/llm.ts:8-9— importsGroqProvider, CloudflareProviderfrom@stackbilt/llm-providers✅aegis-daemon/web/src/kernel/executors/cerebras.ts:8-9— importsCerebrasProvider✅@stackbilt/llm-providersitself — this is the integration point; direct SDK imports are intentional here ✅Related
docs/design-scaffold-composition.md— scaffold composition ADR, Phase E deprecates the mcp-gateway LLM classifierfeedback_llm_providers_only.md— the rule being enforcedSeverity
P2 — not blocking production, but every direct SDK import is provider lock-in creeping back in. The longer these sit, the harder the eventual consolidation.