AgentOS 0.9.76 Exposes Sampling Controls Where Product Developers Actually Call the Model

AgentOS 0.9.76 Exposes Sampling Controls Where Product Developers Actually Call the Model

Agent framework APIs have a habit of hiding the controls that product teams actually need. The provider adapter supports the knob. The docs mention the knob. Somewhere in the stack, the knob exists. Then the public method your application calls quietly drops it, and suddenly “make this less repetitive” becomes a prompt-engineering superstition instead of a reviewable runtime setting.

That is why AgentOS 0.9.76 is more interesting than its size suggests. The release forwards topP, frequencyPenalty, and presencePenalty through generateText into provider calls. According to the release and commit notes, AgentOS already had OpenAI and OpenRouter adapters capable of mapping those fields, but callers using the top-level API could not reliably set them. In other words: the runtime had the control plane, but product code could not reach it.

That is a small patch with a large lesson. Sampling controls are not academic parameters for benchmark tweakers. They are part of how a real application says: this mode should be conservative, this one can explore, this one should avoid repetition, and this one should not start improvising while executing tools.

The missing API path is the bug

The core change lands in commit 530bdf3, which adds topP, frequencyPenalty, and presencePenalty to GenerateTextOptions and forwards them in both generation paths: the tool-loop path and the shim path. The commit changed src/api/generateText.ts with 20 additions. The release itself is compact — three commits and four changed files compared with v0.9.75 — but this is exactly the kind of plumbing that determines whether framework abstractions are useful or decorative.

The pre-fix behavior was awkward in the way framework bugs often are. generateText forwarded temperature, but not the other sampling fields. OpenAI and OpenRouter could map topP, frequency_penalty, and presence_penalty; the application simply had no public route to send them through. Developers were left with an abstraction that looked provider-neutral while silently narrowing the usable provider surface.

That matters because the public API is where product policy lives. If your customer-support assistant needs stable, low-surprise answers, that policy should be visible in code. If your ideation assistant can use a wider nucleus sample, that should be a named profile. If your companion agent keeps repeating the same memory phrase every third message, penalties should be available without rewriting the system prompt into a passive-aggressive style guide.

Putting those choices into parameters makes them reviewable. Putting them into prompts makes them folklore.

Provider neutrality always leaks

AgentOS also documents the less convenient part: not every provider honors the same controls. OpenAI and OpenRouter support the penalty parameters in the -2..2 range. Anthropic has no equivalent, so the Claude path drops them as a no-op. That is not inherently a problem. It becomes a problem when a framework pretends the abstraction is smoother than it is.

Multi-provider agent frameworks need to tell operators which knobs survived the trip. If presencePenalty was accepted by OpenAI and ignored by Claude, the trace should say so. If a generation profile claims to enforce low repetition across providers, but only one backend supports the mechanism, the framework should make that mismatch obvious. Otherwise teams end up debugging behavior drift with bad theories: maybe the prompt changed, maybe the memory retrieval changed, maybe the model is “moodier” today. No. Maybe the parameter was dropped.

This is the practical abstraction leak every agent platform has to own. A portable API is valuable, but portability cannot mean pretending incompatible providers are identical. The right model is closer to compiler warnings than marketing copy: here is the policy you requested, here is the provider that ran, here are the fields accepted, here are the fields ignored, and here is the resolved configuration that produced the output.

That kind of trace is not just nice for debugging. It is governance. If an agent is operating inside a product with safety, tone, cost, or compliance requirements, silent no-ops are not harmless. They are undocumented policy failures.

Sampling is part of the agent control plane

The broader AgentOS pitch makes this patch more relevant. The project describes itself as a local agent control plane with persistent cognitive memory, runtime tool forging, multi-agent orchestration, guardrails, voice support, 11 LLM providers, 100-plus extensions, and 88 skills auto-loaded at startup. Its README claims 85.6% on LongMemEval-S at $0.0090/correct using gpt-4o, plus 70.2% on LongMemEval-M. Those are the kinds of claims that attract developers building agents that persist, remember, call tools, and route across providers.

In that environment, generation variance compounds. A single chat response drifting a little is annoying. A memory-backed, tool-forging, multi-provider agent drifting across turns can change what tools it invents, how aggressively it calls them, how much it repeats retrieved memory, and how confidently it explains uncertain results. Sampling controls will not solve all of that, but they are one of the few deterministic levers developers have.

AgentOS’s tool-forging design is especially worth reading through this lens. The README says an agent can write a TypeScript function with a Zod schema, send it to a separate LLM judge for approval, run it in a hardened node:vm sandbox with a five-second wall clock and no eval, require, or process, and then add it to the session tool catalog. That is ambitious. It also means the runtime needs crisp boundaries between creativity, approval, execution, and observation. Sampling profiles belong in that same boundary system.

There is also a second control surface nearby. Another commit in the release, fda71f8, edits comments around model effort support, noting that output_config.effort controls reasoning depth and token spend for models including Fable/Mythos 5, Opus 4.5 through 4.8, and Sonnet 4.6, and that this is independent of extended-thinking blocks and tool_choice. That distinction matters. Sampling controls shape output distribution. Effort controls shape reasoning budget. Tool choice controls action routing. Product teams should treat those as separate axes, not one blob called “make the agent better.”

What builders should do now

If you use AgentOS, do not scatter these new parameters across random calls. Create named generation profiles: deterministic extraction, conservative support answer, exploratory brainstorming, companion chat, tool-execution narration. Put temperature, topP, penalties, max tokens, and effort settings in one place. Then log the resolved provider, model, accepted parameters, ignored parameters, and profile name on every run.

That sounds like platform ceremony until the first bug report says the agent became repetitive, expensive, or weirdly creative after a provider switch. With named profiles and resolved traces, the investigation has facts. Without them, someone will add “be concise and do not repeat yourself” to a prompt that is already 2,000 tokens too long. We have all seen this movie. It does not get better in the sequel.

The second move is to test cross-provider behavior directly. Run the same prompt/profile combination through OpenAI, OpenRouter, and Anthropic-backed models. Verify which fields are honored. If your product depends on penalties for UX quality, do not assume a Claude route behaves the same way. Either choose a provider that supports the policy, create a provider-specific fallback, or make the limitation visible in the product behavior you promise.

AgentOS 0.9.76 is not a flashy release. It is better than that: it removes an abstraction gap between what providers can do and what applications can govern. In agent frameworks, that is where a lot of the real work lives. The demo layer gets the attention. The public API boundary decides whether teams can operate the thing.

Sources: AgentOS 0.9.76 release, sampling-controls commit, effort-comment commit, AgentOS README, AgentOS cognitive memory docs, AgentOS guardrails docs.