Sessions

session.set({ model })

How a local SDK session explicitly binds its default model instance

session.set({ model })

session.set({ model }) lets a local SDK Session override the Agent model with its own AgentModel. It accepts either an AI SDK LanguageModel or a City CityModel directly.

await session.set({
  model: openai.responses("gpt-5"),
});

When a runtime switch takes effect

A successful session.set() means the configured value was written and queued for the Session. It does not replace an in-flight provider request.

  • the current stream and active tool execution keep using the previous model
  • the new model becomes effective at the next Session step checkpoint; if the current Session turn ends first, it takes effect when the next Session turn starts
  • config changes and steer prompts are committed in queue order
  • the Session timeline emits a completed action message when the switch becomes effective

The config API reports whether the change succeeded. The action message reports the Session turn and step where it became effective for model execution. Timeline persistence is observational: if writing that action fails, the effective configuration is not rolled back and the SDK records a warning.

Controlling the Action and Mutation

The optional second argument to set() controls only the observable result after the configuration commits. It does not change configuration persistence or checkpoint behavior:

await session.set(
  { model },
  { persist_action: false, publish_mutation: false },
);
  • persist_action defaults to true. When false, no configuration Action Message is created.
  • publish_mutation defaults to the value of persist_action. Set it to false to keep the historical Action without publishing its Mutation through subscribe().
  • publish_mutation=true is invalid when persist_action=false, because every Message Mutation must correspond to a canonical Message.
  • Setting the same model identity again does not create another configuration Action. After restart, passing the same model only rebinds the runtime instance.

Session initialization and restoration can disable both outputs. User-driven model changes normally keep the defaults.

When you need it

This is useful when:

  • you are using @downcity/agent in pure SDK embedding mode
  • you manage a local Session directly

Agent default model

When several Sessions share one model, provide the instance directly to the Agent:

const agent = new Agent({
  id: "repo-helper",
  workspace: new Workspace({ path: "/path/to/project" }),
  model,
});

A Session without an explicit model falls back to the Agent model; once set, its own model takes priority. Model instances are not persisted.

Why it works this way

The local SDK behaves more like an embedded execution shell:

  • the agent handles path, tools, plugins, and session storage
  • the caller decides which live model instance should be used

That makes the local SDK more flexible, but it also makes the caller responsible for model readiness.

What happens if you skip it

If neither the Agent nor the local Session has a model instance, execution fails explicitly.

What about remote sessions

Remote Sessions do not expose a model-setting API. Remote clients only send prompts; the server creates the local Agent with its runtime model instance.

What about Downcity Agent projects

If you are working inside a normal Downcity Agent project, the model should usually come from:

  • Agent config execution.modelId
  • the connected Federation AIService

In that case, session.set({ model }) should not be treated as the default path.