Skip to content

Expose the effective agent model to dynamic resolvers #2300

Description

@prha

What problem are you trying to solve?

Dynamic resolvers sometimes need to compose capabilities with the model their agent is about to use. For example, a dynamic subagent may inherit its parent agent's model, a tool resolver may omit tools unsupported by a smaller model, or an instruction resolver may choose a model-specific prompt dialect.

The shared resolver context currently exposes session, channel, and message data, but not model selection. Authors must hard-code a second model ID or duplicate their model policy, which can drift from session-, turn-, or step-scoped dynamic selection.

The value also needs precise timing semantics. A cached “active model” can describe the last synchronized selection rather than the model eve would actually use next, especially while a model resolver is replacing one scope.

Proposed solution

Expose the agent's effective model on every dynamic resolver context:

ctx.model; // { readonly id: string } | null

“Effective” means the model eve would use if the resolver made no change, using one framework-owned precedence rule:

step selection > turn selection > session selection > static model > null

The harness and resolver context should derive this value through the same code path rather than materializing and synchronizing a second active-model value.

Resolver ordering and scope should be explicit:

  • Model resolution completes before other resolver kinds for the same lifecycle event.
  • Non-model resolvers see the model selected for that event.
  • A model resolver sees the effective model with its own event scope excluded, so it can make a relative choice without feeding back on its previous result.
  • ctx.model is null only for a dynamic-only agent observed before its first applicable selection.
  • The descriptor remains read-only, minimal, and serializable; live model instances and provider options are not exposed.

A dynamic subagent can then snapshot its parent's effective model while retaining an explicit fallback:

export default defineDynamic({
  events: {
    "session.started": (_event, ctx) =>
      defineAgent({
        description: "Analyze financial and accounting data.",
        model: ctx.model ? ctx.model.id : "openai/gpt-5.5-mini",
      }),
  },
});

The snapshot follows the resolver's lifecycle event. A later parent model change does not silently retarget an already resolved child config.

Alternatives considered

  • Expose ctx.agent.model. This reads like configured agent reflection rather than the runtime-effective selection and introduces an agent.* namespace for one field.
  • Expose ctx.modelId as a string. This is smaller but prevents adding stable, serializable model metadata later.
  • Cache an active-model context key. This duplicates the precedence rule and creates synchronization obligations whenever selection changes, allowing resolver context to drift from the harness.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions