Profile selection and prompt versions
An active profile supplies reusable configuration and renders prompt variables at generation time. Profile versions, fragment versions and the selected conversation settings describe different parts of the resulting prompt.
Profile and fragment version resolution
Unpinned conversations read later profile changes on a later turn. A nonzero profile version pin keeps the selected profile content, but fragments currently resolve from the latest fragment set even when the profile is pinned. Keep the resolved generation context when investigating a past turn; a saved profile does not capture every input or guarantee the same model response.
Version history
There is no rollback endpoint. To revert, get the old version and update with its
contents; that appends a new version rather than rewriting history.
Fragment-set versions
Fragments are versioned as a set, not individually: any fragment write bumps one
project-wide setVersion, reported by prompt-fragments/list. Record that number
alongside the profile version and resolved inputs. These identify source content;
they do not by themselves establish the final prompt. Prompt processing and any
context added during the turn can change what the model receives.
A profile version tells you what its own prompt looked like; the fragment-set version tells you what the blocks it included looked like. Keep both versions and the values supplied for that turn with its diagnostic trace when one is available. Profile pins currently do not pin the fragment set; reading an older set does not select it for future generation. These records do not guarantee identical model output.
setVersion is 0 when no fragment has ever been written in the project.
Profile selection and tool inheritance
Read the resulting conversation configuration and inspect a later reply. An empty setActiveProfileId leaves the selection unchanged: the current API cannot return a selected conversation to unprofiled operation. A conversation that needs to remain unprofiled must not select an active profile.
Recheck attached services as well. A profile’s mcpServers replaces the conversation list, including when the profile list is empty. Use overrideMcpServers for a supported per-turn selection; see agent tools.
Prompt-variable persistence
A profile's system prompt can carry {{.variable}} placeholders declared in its
variableSpecs. Prompt variables are where the values come from — set on the
conversation, re-rendered into the prompt on every subsequent turn, so the last value you set is reused. Update it when the underlying fact changes.
This is a merge, not a replace: variables you do not send keep their current values.
Pass updateMask to restrict the write to named variables.
Prompt rendering per send
Variables are rendered into the active profile's system-prompt template at generation time, per send — late-binding. An update takes effect on the next send-message call; it never changes an in-flight turn.
When the active profile cannot be used
A conversation's profile has to exist and be enabled, both when you name it and on every turn after. The call fails before anything else happens:
| Error code | HTTP | Meaning |
|---|---|---|
ACTIVE_PROFILE_NOT_FOUND | 404 | No profile with that id exists in the project. |
ACTIVE_PROFILE_DISABLED | 400 | The profile exists but is switched off. |
You get these from activeProfileId on CreateThread, from setActiveProfileId on
SendMessage / SendMessageSync, and from any SendMessage on a conversation whose
bound profile has since been deleted or disabled. A rejected SendMessage changes
nothing: no message is appended, no event is published, and the conversation stays on the
profile it had.
A conversation stuck on an unusable profile is not lost. Re-enable the profile, or move
the conversation with setActiveProfileId to one that works, and the next send goes
through. The one exception is a message queued behind a running turn (see
interruptPolicy): the profile is not checked when a queued message is accepted, and when
its turn comes it runs on the conversation's defaultGenerationConfig instead of failing,
with generationContext.profileId empty and promptSource not
PROMPT_SOURCE_PROFILE_TEMPLATE.