Context providers give Glove agents a fresh view of application state before every model iteration, without rewriting their system instructions or saving snapshots as conversation history.
A trip’s destination can change. A background lookup can finish. A form can acquire an answer. A goal can become complete between two model calls in the same request.
The distinction is useful: instructions describe how the agent should behave; working context describes what is true right now. Runtime context in glove-core gives that changing state a place in the loop.
The core API is small. addContextProvider registers a callback that returns text, synchronously or asynchronously. It can return null or undefined when it has nothing to contribute, and registration returns a function that removes the provider.
For example, a travel concierge can read its current trip before each model call. Here, agent is an existing Glove instance and loadCurrentTrip is an application-owned loader that returns only the trip details the model should see:
const removeContext = agent.addContextProvider(async (signal) => {
const trip = await loadCurrentTrip(signal);
return trip ? `Current trip state:\n${JSON.stringify(trip)}` : null;
});Glove calls the provider when preparing model input. If a tool updates the trip, the next model iteration reads its current state.
Several providers can be registered independently. One might expose the trip, another the status of an asynchronous lookup, and another the current selection in an application. Forms, goals, and pinned context use this same mechanism; the core API has no dependency on their schemas. Applications can also use it for job status, workspace state, or a changing set of available resources.
The provider’s output is a synthetic context message supplied by the framework. In the current implementation, Glove appends it as user-role content with framework_context: "runtime" metadata. It follows stored conversation history and complete tool-result bundles.
That placement gives the model a fresh view of external state without saving another copy of that state as a conversation message. On the next iteration, Glove reconstructs the model input and resolves the providers again.
The source of truth stays in the application’s adapter or store.
Previously, the memory integrations rendered changing state into sections of the system prompt. The implementation used attachPromptSection to maintain those sections and called setSystemPrompt as they changed.
A completed checklist item or a newly filled form field therefore changed text near the beginning of the model request. For prefix-based caching, the reusable prefix stops at the changed content. Even when the conversation history remained identical, the changing system section could prevent reuse of the prefix extending through that history.
The fix removed those mutable system-prompt sections and moved their content to transient messages at the end of model input.
Conceptually, the request changed from:
Instructions + changing memory state
Conversation historyto:
Instructions
Conversation history
Current memory snapshotCaching was not disabled. The change preserves the stable system and history prefix while allowing the trailing state to change.
Actual cache hits still depend on provider formatting, configuration, minimum sizes, and breakpoint placement. The fix preserves the opportunity for prefix reuse; applications should check provider-reported cache usage to measure the result.
The new timing also improves freshness. The old form integration refreshed its prompt section before a request. A field filled during tool execution could therefore leave that section outdated until the next request. Context providers run before each model iteration, including the iteration after a tool result.
A framework snapshot uses a supported provider role, but it is not a new human utterance.
The follow-up correction adds provenance and excludes framework context from the calculation of the last real user turn. Otherwise, with tool-result summarization enabled, a fresh snapshot could cause full results from the current turn to be replaced by their summaries prematurely.
The same correction preserves structured images and video when certain adapters merge adjacent user messages. Appending a text snapshot must not flatten an existing media message into a string.
The framework marker identifies where the message came from. It does not grant stored user content the authority of system instructions.
Providers should remain focused on reading and rendering state. They receive an abort signal, and the core loop stops before calling the model if a provider fails. Expensive preparation or inference belongs in an explicit workflow operation, not inside a repeatedly evaluated snapshot callback.
Subscribers can observe resolved snapshots through the runtime_context event. External runtimes can obtain them through getRuntimeContext(). The realtime voice bridge uses that method at startup and after tools; hosts call await realtime.refreshContext() after external changes. Earlier voice snapshots may remain in the provider’s session history, with later snapshots identifying themselves as replacements.
Context providers arrived with the glove-core 4 compatibility change. Custom runnable wrappers must forward addContextProvider and getRuntimeContext; custom builders need provider registration support. Goals and forms can opt out of their default status injection when an application supplies its own renderer.
Keep authoritative state in a store, expose a concise view through a provider, and keep behavioral instructions in the system prompt. After a tool changes the trip, completes a job, or updates a resource, the next model call can work from the new state.