Roles: refresh the live selection when re-pointing a reused Session
Deploying dee76b1 proved a raw durable append insufficient: the 07:54 dispatch recorded the wandering selection, yet the request assembled half a second later still carried the deepseek header, because prompt assembly reads the Session Controller's in-memory selection and the internal Agent controller caches one per Agent. Call its own selectForNextRequest primitive — append plus cache refresh, still without saving the deployment default — and fall back to the public selectModel if the surface moves. Fixture gains the Controller; two cases pin fast-path and fallback.
This commit is contained in:
+11
-3
@@ -2,6 +2,7 @@
|
||||
import type { Context } from '@deepseek-ai/cordis'
|
||||
import type { Agent, ModelSelection } from '@deepseek-ai/dsh-agent'
|
||||
import { ReasoningEffortId } from '@deepseek-ai/dsh-llm'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-session/types'
|
||||
import type { RoleModel } from '../policy.ts'
|
||||
|
||||
/** Resolve a configured route through the live provider; catalog membership is not a restriction. */
|
||||
@@ -27,9 +28,16 @@ export async function alignRoleModel(ctx: Context, agent: Agent, model: RoleMode
|
||||
const selected = await resolveRoleModel(ctx, model)
|
||||
if (current && current.provider === selected.provider && current.model === selected.model
|
||||
&& (selected.reasoningEffort === undefined || current.reasoningEffort === selected.reasoningEffort)) return
|
||||
// Appending the durable event is what a Session-local selection is; the model-selection projection feeds it to the next
|
||||
// request, and unlike selectModel it leaves the deployment-wide default alone. A mid-session switch is ordinary DSH usage.
|
||||
agent.session.append('model/selection', selected)
|
||||
// A durable event alone cannot re-point a live Agent: prompt assembly reads the Session Controller's in-memory selection,
|
||||
// which a raw append leaves stale. `selectForNextRequest` is that Controller's own primitive — append plus cache refresh —
|
||||
// and unlike the public selectModel it leaves the deployment-wide default alone. The fallback keeps correctness, at the cost
|
||||
// of saving the default, if the internal surface ever moves; a mid-session switch itself is ordinary DSH usage.
|
||||
const installSelection = (ctx.sessionController as unknown as {
|
||||
agents?: { selectForNextRequest?(agent: Agent, selection: ModelSelection): void }
|
||||
}).agents?.selectForNextRequest?.bind((ctx.sessionController as unknown as { agents: object }).agents)
|
||||
if (installSelection) installSelection(agent, selected)
|
||||
else await ctx.sessionController.selectModel({ sessionId: agent.id as SessionId, provider: selected.provider, model: selected.model,
|
||||
...(selected.reasoningEffort ? { reasoningEffort: selected.reasoningEffort } : {}) })
|
||||
await ctx.sessionPersistence.flush()
|
||||
ctx.logger.info('dsh-superagent re-pointed Session %s from %s/%s to %s/%s', agent.id,
|
||||
current?.provider ?? 'unset', current?.model ?? 'unset', selected.provider, selected.model)
|
||||
|
||||
Reference in New Issue
Block a user