fix(server): an option a session drops when opening is not brought back by a configured default

The opening snapshot merged defaults over the options after the session's openOptionsPatch had removed a key. Defaults now merge into what the session was given and the patch applies after.
This commit is contained in:
Mohamed Boudra
2026-11-04 04:25:10 +01:00
parent 21bda8897f
commit 4d019da632
2 changed files with 26 additions and 2 deletions
@@ -13120,6 +13120,15 @@ describe("agent options", () => {
expect(published.every((options) => options?.service_tier === "slow")).toBe(true);
});
test("an option the session dropped when opening does not come back from a configured default", async () => {
const { manager, agentId } = await createOptionsAgent(undefined, { service_tier: null });
const agent = manager.getAgent(agentId);
expect(agent?.effectiveOptions).toEqual({});
await manager.markAgentUnread(agentId);
expect(toAgentPayload(manager.getAgent(agentId)!).options).toEqual({});
});
test("an option without a control is settable through the patch and readable in the snapshot", async () => {
const { manager, client, storage, agentId } = await createOptionsAgent();
@@ -3930,6 +3930,12 @@ export class AgentManager {
resolvedAgentId,
session,
config,
// Defaults merge into what the session was given; what it reports it ended up with comes
// after, so an option it dropped does not come back from a default.
effectiveOptions: applyProviderOptionsPatch({
options: this.effectiveOptionsFor(openedConfig.provider, openedConfig.providerOptions),
patch: session.openOptionsPatch ?? {},
}),
now,
durableTimelineHasRows,
background: options?.background === true,
@@ -4075,6 +4081,7 @@ export class AgentManager {
resolvedAgentId: string;
session: AgentSession;
config: AgentSessionConfig;
effectiveOptions: ProviderOptions;
now: Date;
durableTimelineHasRows: boolean;
background: boolean;
@@ -4095,7 +4102,15 @@ export class AgentManager {
}
| undefined;
}): ActiveManagedAgent {
const { resolvedAgentId, session, config, now, durableTimelineHasRows, options } = params;
const {
resolvedAgentId,
session,
config,
effectiveOptions,
now,
durableTimelineHasRows,
options,
} = params;
return {
id: resolvedAgentId,
provider: config.provider,
@@ -4107,7 +4122,7 @@ export class AgentManager {
capabilities: session.capabilities,
config,
// What the session opened with. Provider defaults edited later reach it when it next opens.
effectiveOptions: this.effectiveOptionsFor(config.provider, config.providerOptions),
effectiveOptions,
runtimeInfo: undefined,
lifecycle: "initializing",
createdAt: options?.createdAt ?? now,