⚠️ Coming in alpha.26 — BREAKING API unification (canonical messages input) #62
baabakk
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
messagesinput)TL;DR — The next release of
@llm-portswill break the shape of four methods to align with every provider's native protocol. A one-cycle deprecation window is planned. Migration is ~30 minutes mechanical or ~4 hours idiomatic per consumer. If you're using@llm-portsin production, please weigh in on the open design questions below before implementation begins.What's changing
The current port has TWO input shapes for what is architecturally the same thing:
generateText/generateStructured/streamText/streamStructuredaccept{ instructions?: string, prompt: MessageContent }.runAgentaccepts{ messages: LLMMessage[] }.Every provider's actual API (OpenAI, Anthropic, Google, DeepInfra, Cerebras, Groq, SambaNova, everyone) speaks
messages: Message[]. The two-shape design was a defensible compression when most calls were single-turn, but it doesn't model the multi-turn use case any richer than "chat interview" workload needs. Alpha.26 unifies:All five port methods will accept
messages: LLMMessage[]as the canonical input.Why this is worth breaking
Three real production workloads have been blocked or forced onto a bad workaround:
promptstring (loses role fidelity, breaks provider-native caching), abuserunAgentwithtools: {}(semantically broken; loop terminates on first assistant turn), or reach past the port viaproviderExtras(kills the abstraction).The abstraction should model what the underlying protocol supports natively.
What alpha.26 will ship
Plus three helpers:
Migration path
During the alpha.26 window (~2 weeks):
Consumers with 20 call sites: ~30 minutes for the mechanical migration via
toMessages(), ~4 hours to idiomatic nativemessagesarrays.At alpha.27 (~2 weeks after alpha.26):
The deprecated
instructions/promptfields are removed. TypeScript compilation fails for consumers that haven't migrated. Deprecation warnings during the alpha.26 window make this visible in advance.Deprecation UX
console.warnby default.RegistryOptions.suppressDeprecationWarnings: true.Open design questions (please weigh in)
instructions+messagesconflict handling. During the alpha.26 window, if a consumer passes BOTH the legacyinstructionsstring AND amessagesarray containing a system-role message, what happens? Recommendation: throwMessagesConflictError. Ambiguity is a caller bug worth surfacing. Comment if you'd prefer silent precedence rules.sys()acceptingMessageContent(not juststring). Recommendation: keepsys()restricted tostringfor the common case. Callers with the rare multimodal-system-prompt case use the object-literal{role: "system", content: [...]}. Comment if you have a real use case for multimodal system prompts.Assistant-turn construction sugar. Recommendation: no
asst()helper — assistant turns typically come from captured LLM outputs and object literal is fine. Comment if you construct assistant turns from strings frequently.refsand multi-turn. Recommendation: refs are per-call, not per-turn. If consumer passes refs on turn N of an interview, only turn N's observability events carry them. Comment if you want per-turn refs propagation.Adapter behavior on multi-system-role or mid-conversation-system messages. Anthropic + Google split system out of the messages array; OpenAI keeps it inline. If a consumer supplies multiple system messages OR a mid-conversation system message, adapters need a policy. Recommendation: concatenate contiguous system messages at the start; throw on mid-conversation system for Anthropic + Google, pass through for OpenAI. Comment if you have a use case for mid-conversation system messages.
Automated codemod. Nice to have — a
jscodeshifttransform that rewrites{instructions, prompt}to{messages: toMessages(...)}mechanically. 20 sites is 30 minutes by hand. Comment if you'd use one.Timeline (planned)
Slippage tolerance: the alpha.26 timeline can slip freely without impacting alpha.25 or existing consumers. The migration window between alpha.26 and alpha.27 can extend to 3-4 weeks if consumer feedback indicates additional runway is needed.
What is NOT changing
runAgentalready takesmessages. Zero migration impact on runAgent consumers.MessageContenttype (per-turn content:string | ContentBlock[]) is unchanged. Multimodal content per turn still works exactly the same way.Alternatives considered and rejected
messagesalongsideprompt, exactly one must be set). Rejected: two-ways-to-do-one-thing is a maintenance surface that never converges.chatmethod (chat(opts: ChatOptions)). Rejected: grows the port from 5 methods to 7 for a semantic distinction that doesn't exist.prompttoinputwith union type (input: MessageContent | LLMMessage[]). Rejected: runtime discrimination churn without clarity gain.MessageContentto includeLLMMessage[]. Rejected: collapses "content of a turn" and "sequence of turns" into one type.How to give feedback
Once open questions are settled, the design freezes and implementation begins on a
feature/alpha-26-messages-canonicalbranch.Thanks for reading — feedback in the next two weeks is when it has the most leverage.
Beta Was this translation helpful? Give feedback.
All reactions