Skip to content

refactor(llm): colocate per-type factories on their namespaces#26799

Merged
kitlangton merged 1 commit into
devfrom
chore/llm-colocate-factories
May 11, 2026
Merged

refactor(llm): colocate per-type factories on their namespaces#26799
kitlangton merged 1 commit into
devfrom
chore/llm-colocate-factories

Conversation

@kitlangton
Copy link
Copy Markdown
Contributor

Why

packages/llm already follows a clean pattern everywhere else: per-type factories live on the type's own namespace (Message.user, Message.assistant, Message.tool, Message.make, Message.text, SystemPart.make, ToolDefinition.make, ToolCallPart.make, ToolResultPart.make, ToolChoice.make, ToolChoice.named, GenerationOptions.make, HttpOptions.make, ModelRef.update, LLMRequest.update).

src/llm.ts was also re-exporting those same factories at the top level as LLM.user, LLM.assistant, LLM.toolMessage, LLM.toolCall, LLM.toolResult, LLM.toolDefinition, LLM.toolChoice, LLM.toolChoiceName, LLM.generation, LLM.system, LLM.message, LLM.text. Two construction paths to the same value is one too many — this isn't matching the AI SDK (which has no factories at all), it's matching ourselves.

The top-level LLM namespace stays focused on the request-shaped call API: LLM.request, LLM.generate, LLM.stream, LLM.model, LLM.limits, LLM.stepCountIs, LLM.requestInput, LLM.updateRequest, LLM.generateObject.

What changed

  • Deleted 12 alias re-exports from packages/llm/src/llm.ts: text, system, message, user, assistant, toolDefinition, toolCall, toolResult, toolMessage, toolChoiceName, toolChoice, generation.
  • Rewrote LLM.request's internal use of those aliases to call the canonical forms directly (Message.make, Message.user, ToolDefinition.make, ToolChoice.make, GenerationOptions.make).
  • Rewrote every call site in packages/llm/test/** to the colocated form (one provider test file plus the shared recorded-scenarios.ts and the unit tests).
  • Updated the tool-loop example in packages/llm/AGENTS.md to match.
  • Added a "Conventions" section to packages/llm/AGENTS.md documenting the rule.

No call sites existed outside packages/llm/.

Migration

Old New
LLM.user(x) Message.user(x)
LLM.assistant(x) Message.assistant(x)
LLM.toolMessage(x) Message.tool(x)
LLM.message(x) Message.make(x)
LLM.text(x) Message.text(x)
LLM.system(x) SystemPart.make(x)
LLM.toolDefinition(x) ToolDefinition.make(x)
LLM.toolCall(x) ToolCallPart.make(x)
LLM.toolResult(x) ToolResultPart.make(x)
LLM.toolChoice(x) ToolChoice.make(x)
LLM.toolChoiceName(x) ToolChoice.named(x)
LLM.generation(x) GenerationOptions.make(x)

All types are re-exported from @opencode-ai/llm's barrel via export * from "./schema".

Test plan

  • bun run --cwd packages/llm typecheck — clean
  • bun run --cwd packages/llm test — 174 pass / 31 skip / 0 fail
  • bun run --cwd packages/opencode typecheck — clean
  • bun run --cwd packages/opencode test — only pre-existing unrelated failures (Worktree > list > uses parent folder name... and session.created event...); neither test references LLM.*

Drop the LLM.user / LLM.assistant / LLM.toolMessage / LLM.toolCall /
LLM.toolResult / LLM.toolDefinition / LLM.toolChoice / LLM.toolChoiceName /
LLM.generation / LLM.system / LLM.message / LLM.text aliases from the
top-level LLM namespace and route every caller through the
Schema-class-colocated forms (Message.user, ToolDefinition.make, ToolChoice.make, ...).

The colocated form is already the codebase convention; two ways to
construct the same thing is one too many. The top-level LLM namespace
stays focused on the request-shaped call API (LLM.request, LLM.generate,
LLM.stream, LLM.model, LLM.updateRequest, LLM.generateObject).

Adds a Conventions section to packages/llm/AGENTS.md capturing the rule.
@kitlangton kitlangton force-pushed the chore/llm-colocate-factories branch from 00ae041 to 874332f Compare May 11, 2026 14:00
@kitlangton kitlangton marked this pull request as ready for review May 11, 2026 17:05
@kitlangton kitlangton merged commit 023e1c7 into dev May 11, 2026
10 checks passed
@kitlangton kitlangton deleted the chore/llm-colocate-factories branch May 11, 2026 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant