Merge 934a3ffcba35e074672732d38d46af0b2e3c92af into 8a05c05596ca9ba0735dafd8e359885de4c2c969
This commit is contained in:
commit
2132566141
@ -28,7 +28,7 @@ import type { VerboseLevel } from "../thinking.js";
|
||||
import type { GetReplyOptions } from "../types.js";
|
||||
import {
|
||||
buildEmbeddedRunExecutionParams,
|
||||
resolveModelFallbackOptions,
|
||||
resolveCompactionModelFallbackOptions,
|
||||
} from "./agent-runner-utils.js";
|
||||
import {
|
||||
hasAlreadyFlushedForCurrentCompaction,
|
||||
@ -282,13 +282,14 @@ export async function runMemoryFlushIfNeeded(params: {
|
||||
return sandboxCfg.workspaceAccess === "rw";
|
||||
})();
|
||||
|
||||
const isCli = isCliProvider(params.followupRun.run.provider, params.cfg);
|
||||
const compactionFallbackOptions = resolveCompactionModelFallbackOptions(params.followupRun.run);
|
||||
const isCli = isCliProvider(compactionFallbackOptions.provider, params.cfg);
|
||||
const canAttemptFlush = memoryFlushWritable && !params.isHeartbeat && !isCli;
|
||||
let entry =
|
||||
params.sessionEntry ??
|
||||
(params.sessionKey ? params.sessionStore?.[params.sessionKey] : undefined);
|
||||
const contextWindowTokens = resolveMemoryFlushContextWindowTokens({
|
||||
modelId: params.followupRun.run.model ?? params.defaultModel,
|
||||
modelId: compactionFallbackOptions.model ?? params.defaultModel,
|
||||
agentCfgContextTokens: params.agentCfgContextTokens,
|
||||
});
|
||||
|
||||
@ -478,7 +479,7 @@ export async function runMemoryFlushIfNeeded(params: {
|
||||
.join("\n\n");
|
||||
try {
|
||||
await runWithModelFallback({
|
||||
...resolveModelFallbackOptions(params.followupRun.run),
|
||||
...compactionFallbackOptions,
|
||||
runId: flushRunId,
|
||||
run: async (provider, model, runOptions) => {
|
||||
const { embeddedContext, senderContext, runBaseParams } = buildEmbeddedRunExecutionParams({
|
||||
|
||||
@ -1,20 +1,11 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { FollowupRun } from "./queue.js";
|
||||
|
||||
const hoisted = vi.hoisted(() => {
|
||||
const resolveRunModelFallbacksOverrideMock = vi.fn();
|
||||
return { resolveRunModelFallbacksOverrideMock };
|
||||
});
|
||||
|
||||
vi.mock("../../agents/agent-scope.js", () => ({
|
||||
resolveRunModelFallbacksOverride: (...args: unknown[]) =>
|
||||
hoisted.resolveRunModelFallbacksOverrideMock(...args),
|
||||
}));
|
||||
|
||||
const {
|
||||
buildThreadingToolContext,
|
||||
buildEmbeddedRunBaseParams,
|
||||
buildEmbeddedRunContexts,
|
||||
resolveCompactionModelFallbackOptions,
|
||||
resolveModelFallbackOptions,
|
||||
resolveProviderScopedAuthProfile,
|
||||
} = await import("./agent-runner-utils.js");
|
||||
@ -45,20 +36,21 @@ function makeRun(overrides: Partial<FollowupRun["run"]> = {}): FollowupRun["run"
|
||||
|
||||
describe("agent-runner-utils", () => {
|
||||
beforeEach(() => {
|
||||
hoisted.resolveRunModelFallbacksOverrideMock.mockClear();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("resolves model fallback options from run context", () => {
|
||||
hoisted.resolveRunModelFallbacksOverrideMock.mockReturnValue(["fallback-model"]);
|
||||
const run = makeRun();
|
||||
const run = makeRun({
|
||||
sessionKey: "agent:agent-1:main",
|
||||
config: {
|
||||
agents: {
|
||||
list: [{ id: "agent-1", model: { fallbacks: ["fallback-model"] } }],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const resolved = resolveModelFallbackOptions(run);
|
||||
|
||||
expect(hoisted.resolveRunModelFallbacksOverrideMock).toHaveBeenCalledWith({
|
||||
cfg: run.config,
|
||||
agentId: run.agentId,
|
||||
sessionKey: run.sessionKey,
|
||||
});
|
||||
expect(resolved).toEqual({
|
||||
cfg: run.config,
|
||||
provider: run.provider,
|
||||
@ -69,19 +61,93 @@ describe("agent-runner-utils", () => {
|
||||
});
|
||||
|
||||
it("passes through missing agentId for helper-based fallback resolution", () => {
|
||||
hoisted.resolveRunModelFallbacksOverrideMock.mockReturnValue(["fallback-model"]);
|
||||
const run = makeRun({ agentId: undefined });
|
||||
const run = makeRun({
|
||||
agentId: undefined,
|
||||
sessionKey: "agent:agent-2:main",
|
||||
config: {
|
||||
agents: {
|
||||
list: [{ id: "agent-2", model: { fallbacks: ["fallback-model"] } }],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const resolved = resolveModelFallbackOptions(run);
|
||||
|
||||
expect(hoisted.resolveRunModelFallbacksOverrideMock).toHaveBeenCalledWith({
|
||||
cfg: run.config,
|
||||
agentId: undefined,
|
||||
sessionKey: run.sessionKey,
|
||||
});
|
||||
expect(resolved.fallbacksOverride).toEqual(["fallback-model"]);
|
||||
});
|
||||
|
||||
it("uses compaction model override for compaction-scoped fallback resolution", () => {
|
||||
const run = makeRun({
|
||||
sessionKey: "agent:agent-1:main",
|
||||
config: {
|
||||
agents: {
|
||||
list: [{ id: "agent-1", model: { fallbacks: ["fallback-model"] } }],
|
||||
defaults: {
|
||||
compaction: {
|
||||
model: "openrouter/anthropic/claude-sonnet-4-5",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const resolved = resolveCompactionModelFallbackOptions(run);
|
||||
|
||||
expect(resolved).toEqual({
|
||||
cfg: run.config,
|
||||
provider: "openrouter",
|
||||
model: "anthropic/claude-sonnet-4-5",
|
||||
agentDir: run.agentDir,
|
||||
fallbacksOverride: ["openrouter/fallback-model"],
|
||||
});
|
||||
});
|
||||
|
||||
it("rebases model-only fallbacks onto the compaction provider", () => {
|
||||
const run = makeRun({
|
||||
sessionKey: "agent:agent-1:main",
|
||||
config: {
|
||||
agents: {
|
||||
list: [{ id: "agent-1", model: { fallbacks: ["fallback-model", "anthropic/haiku"] } }],
|
||||
defaults: {
|
||||
compaction: {
|
||||
model: "openrouter/anthropic/claude-sonnet-4-5",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const resolved = resolveCompactionModelFallbackOptions(run);
|
||||
|
||||
expect(resolved.fallbacksOverride).toEqual(["openrouter/fallback-model", "anthropic/haiku"]);
|
||||
});
|
||||
|
||||
it("keeps the primary provider when compaction model override omits a provider", () => {
|
||||
const run = makeRun({
|
||||
sessionKey: "agent:agent-1:main",
|
||||
config: {
|
||||
agents: {
|
||||
list: [{ id: "agent-1", model: { fallbacks: ["fallback-model"] } }],
|
||||
defaults: {
|
||||
compaction: {
|
||||
model: "claude-sonnet-4-5",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const resolved = resolveCompactionModelFallbackOptions(run);
|
||||
|
||||
expect(resolved).toEqual({
|
||||
cfg: run.config,
|
||||
provider: run.provider,
|
||||
model: "claude-sonnet-4-5",
|
||||
agentDir: run.agentDir,
|
||||
fallbacksOverride: ["fallback-model"],
|
||||
});
|
||||
});
|
||||
|
||||
it("builds embedded run base params with auth profile and run metadata", () => {
|
||||
const run = makeRun({ enforceFinalTag: true });
|
||||
const authProfile = resolveProviderScopedAuthProfile({
|
||||
@ -191,7 +257,6 @@ describe("agent-runner-utils", () => {
|
||||
|
||||
expect(context).toMatchObject({
|
||||
currentChannelId: "telegram:-1003841603622",
|
||||
currentThreadTs: "928",
|
||||
currentMessageId: "2284",
|
||||
});
|
||||
});
|
||||
|
||||
@ -168,6 +168,40 @@ export function resolveModelFallbackOptions(run: FollowupRun["run"]) {
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveCompactionModelFallbackOptions(run: FollowupRun["run"]) {
|
||||
const resolved = resolveModelFallbackOptions(run);
|
||||
const override = run.config?.agents?.defaults?.compaction?.model?.trim();
|
||||
if (!override) {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
const slashIdx = override.indexOf("/");
|
||||
if (slashIdx > 0) {
|
||||
const provider = override.slice(0, slashIdx).trim();
|
||||
const model = override.slice(slashIdx + 1).trim();
|
||||
if (provider && model) {
|
||||
const fallbacksOverride = resolved.fallbacksOverride?.map((fallback) => {
|
||||
const trimmed = fallback.trim();
|
||||
if (!trimmed || trimmed.includes("/")) {
|
||||
return trimmed;
|
||||
}
|
||||
return `${provider}/${trimmed}`;
|
||||
});
|
||||
return {
|
||||
...resolved,
|
||||
provider,
|
||||
model,
|
||||
fallbacksOverride,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...resolved,
|
||||
model: override,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildEmbeddedRunBaseParams(params: {
|
||||
run: FollowupRun["run"];
|
||||
provider: string;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user