Compare commits
1 Commits
main
...
feature/xh
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0a79c19f9 |
@ -57,7 +57,7 @@ describe("resolveAgentConfig", () => {
|
|||||||
defaults: {
|
defaults: {
|
||||||
model: {
|
model: {
|
||||||
primary: "anthropic/claude-sonnet-4",
|
primary: "anthropic/claude-sonnet-4",
|
||||||
fallbacks: ["openai/gpt-4.1"],
|
fallbacks: ["openai/gpt-5-nano"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
list: [
|
list: [
|
||||||
|
|||||||
@ -8,7 +8,7 @@ function makeCfg(overrides: Partial<ClawdbotConfig> = {}): ClawdbotConfig {
|
|||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
model: {
|
model: {
|
||||||
primary: "openai/gpt-4.1-mini",
|
primary: "openai/gpt-5-nano",
|
||||||
fallbacks: ["anthropic/claude-haiku-3-5"],
|
fallbacks: ["anthropic/claude-haiku-3-5"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -29,7 +29,7 @@ describe("runWithModelFallback", () => {
|
|||||||
runWithModelFallback({
|
runWithModelFallback({
|
||||||
cfg,
|
cfg,
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
model: "gpt-4.1-mini",
|
model: "gpt-5-nano",
|
||||||
run,
|
run,
|
||||||
}),
|
}),
|
||||||
).rejects.toThrow("bad request");
|
).rejects.toThrow("bad request");
|
||||||
@ -46,7 +46,7 @@ describe("runWithModelFallback", () => {
|
|||||||
const result = await runWithModelFallback({
|
const result = await runWithModelFallback({
|
||||||
cfg,
|
cfg,
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
model: "gpt-4.1-mini",
|
model: "gpt-5-nano",
|
||||||
run,
|
run,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ describe("runWithModelFallback", () => {
|
|||||||
const result = await runWithModelFallback({
|
const result = await runWithModelFallback({
|
||||||
cfg,
|
cfg,
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
model: "gpt-4.1-mini",
|
model: "gpt-5-nano",
|
||||||
run,
|
run,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ describe("runWithModelFallback", () => {
|
|||||||
const result = await runWithModelFallback({
|
const result = await runWithModelFallback({
|
||||||
cfg,
|
cfg,
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
model: "gpt-4.1-mini",
|
model: "gpt-5-nano",
|
||||||
run,
|
run,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ describe("runWithModelFallback", () => {
|
|||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
model: {
|
model: {
|
||||||
primary: "openai/gpt-4.1-mini",
|
primary: "openai/gpt-5-nano",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -173,13 +173,13 @@ describe("runWithModelFallback", () => {
|
|||||||
cfg,
|
cfg,
|
||||||
provider: "anthropic",
|
provider: "anthropic",
|
||||||
model: "claude-opus-4-5",
|
model: "claude-opus-4-5",
|
||||||
fallbacksOverride: ["openai/gpt-4.1"],
|
fallbacksOverride: ["openai/gpt-5-nano"],
|
||||||
run: async (provider, model) => {
|
run: async (provider, model) => {
|
||||||
calls.push({ provider, model });
|
calls.push({ provider, model });
|
||||||
if (provider === "anthropic") {
|
if (provider === "anthropic") {
|
||||||
throw Object.assign(new Error("nope"), { status: 401 });
|
throw Object.assign(new Error("nope"), { status: 401 });
|
||||||
}
|
}
|
||||||
if (provider === "openai" && model === "gpt-4.1") {
|
if (provider === "openai" && model === "gpt-5-nano") {
|
||||||
return "ok";
|
return "ok";
|
||||||
}
|
}
|
||||||
throw new Error(`unexpected candidate: ${provider}/${model}`);
|
throw new Error(`unexpected candidate: ${provider}/${model}`);
|
||||||
@ -189,7 +189,7 @@ describe("runWithModelFallback", () => {
|
|||||||
expect(res.result).toBe("ok");
|
expect(res.result).toBe("ok");
|
||||||
expect(calls).toEqual([
|
expect(calls).toEqual([
|
||||||
{ provider: "anthropic", model: "claude-opus-4-5" },
|
{ provider: "anthropic", model: "claude-opus-4-5" },
|
||||||
{ provider: "openai", model: "gpt-4.1" },
|
{ provider: "openai", model: "gpt-5-nano" },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ describe("runWithModelFallback", () => {
|
|||||||
const result = await runWithModelFallback({
|
const result = await runWithModelFallback({
|
||||||
cfg,
|
cfg,
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
model: "gpt-4.1-mini",
|
model: "gpt-5-nano",
|
||||||
run,
|
run,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ describe("runWithModelFallback", () => {
|
|||||||
const result = await runWithModelFallback({
|
const result = await runWithModelFallback({
|
||||||
cfg,
|
cfg,
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
model: "gpt-4.1-mini",
|
model: "gpt-5-nano",
|
||||||
run,
|
run,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ describe("runWithModelFallback", () => {
|
|||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
model: {
|
model: {
|
||||||
primary: "openai/gpt-4.1-mini",
|
primary: "openai/gpt-5-nano",
|
||||||
fallbacks: [],
|
fallbacks: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -292,6 +292,6 @@ describe("runWithModelFallback", () => {
|
|||||||
expect(result.result).toBe("ok");
|
expect(result.result).toBe("ok");
|
||||||
expect(run).toHaveBeenCalledTimes(2);
|
expect(run).toHaveBeenCalledTimes(2);
|
||||||
expect(result.provider).toBe("openai");
|
expect(result.provider).toBe("openai");
|
||||||
expect(result.model).toBe("gpt-4.1-mini");
|
expect(result.model).toBe("gpt-5-nano");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,8 +13,8 @@ import {
|
|||||||
const catalog = [
|
const catalog = [
|
||||||
{
|
{
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
id: "gpt-4",
|
id: "gpt-5-nano",
|
||||||
name: "GPT-4",
|
name: "GPT-5 Nano",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ describe("buildAllowedModelSet", () => {
|
|||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
models: {
|
models: {
|
||||||
"openai/gpt-4": { alias: "gpt4" },
|
"openai/gpt-5-nano": { alias: "gpt5nano" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -38,7 +38,9 @@ describe("buildAllowedModelSet", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(allowed.allowAny).toBe(false);
|
expect(allowed.allowAny).toBe(false);
|
||||||
expect(allowed.allowedKeys.has(modelKey("openai", "gpt-4"))).toBe(true);
|
expect(allowed.allowedKeys.has(modelKey("openai", "gpt-5-nano"))).toBe(
|
||||||
|
true,
|
||||||
|
);
|
||||||
expect(allowed.allowedKeys.has(modelKey("claude-cli", "opus-4.5"))).toBe(
|
expect(allowed.allowedKeys.has(modelKey("claude-cli", "opus-4.5"))).toBe(
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
@ -57,7 +59,9 @@ describe("buildAllowedModelSet", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(allowed.allowAny).toBe(true);
|
expect(allowed.allowAny).toBe(true);
|
||||||
expect(allowed.allowedKeys.has(modelKey("openai", "gpt-4"))).toBe(true);
|
expect(allowed.allowedKeys.has(modelKey("openai", "gpt-5-nano"))).toBe(
|
||||||
|
true,
|
||||||
|
);
|
||||||
expect(allowed.allowedKeys.has(modelKey("claude-cli", "opus-4.5"))).toBe(
|
expect(allowed.allowedKeys.has(modelKey("claude-cli", "opus-4.5"))).toBe(
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
@ -236,7 +240,7 @@ describe("resolveAllowedModelRef", () => {
|
|||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
models: {
|
models: {
|
||||||
"openai/gpt-4": { alias: "GPT4" },
|
"openai/gpt-5-nano": { alias: "GPT5NANO" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -244,12 +248,12 @@ describe("resolveAllowedModelRef", () => {
|
|||||||
const resolved = resolveAllowedModelRef({
|
const resolved = resolveAllowedModelRef({
|
||||||
cfg,
|
cfg,
|
||||||
catalog: [
|
catalog: [
|
||||||
{ provider: "openai", id: "gpt-4", name: "GPT-4" },
|
{ provider: "openai", id: "gpt-5-nano", name: "GPT-5 Nano" },
|
||||||
{ provider: "anthropic", id: "claude-sonnet-4-1", name: "Sonnet" },
|
{ provider: "anthropic", id: "claude-sonnet-4-1", name: "Sonnet" },
|
||||||
],
|
],
|
||||||
raw: "anthropic/claude-sonnet-4-1",
|
raw: "anthropic/claude-sonnet-4-1",
|
||||||
defaultProvider: "openai",
|
defaultProvider: "openai",
|
||||||
defaultModel: "gpt-4",
|
defaultModel: "gpt-5-nano",
|
||||||
});
|
});
|
||||||
expect(resolved).toEqual({
|
expect(resolved).toEqual({
|
||||||
error: "model not allowed: anthropic/claude-sonnet-4-1",
|
error: "model not allowed: anthropic/claude-sonnet-4-1",
|
||||||
|
|||||||
@ -207,11 +207,11 @@ describe("resolveExtraParams", () => {
|
|||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns undefined for openai/gpt-4 with no config", () => {
|
it("returns undefined for openai/gpt-5-nano with no config", () => {
|
||||||
const result = resolveExtraParams({
|
const result = resolveExtraParams({
|
||||||
cfg: undefined,
|
cfg: undefined,
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
modelId: "gpt-4",
|
modelId: "gpt-5-nano",
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
@ -223,7 +223,7 @@ describe("resolveExtraParams", () => {
|
|||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
models: {
|
models: {
|
||||||
"openai/gpt-4": {
|
"openai/gpt-5-nano": {
|
||||||
params: {
|
params: {
|
||||||
logprobs: true,
|
logprobs: true,
|
||||||
top_logprobs: 5,
|
top_logprobs: 5,
|
||||||
@ -234,7 +234,7 @@ describe("resolveExtraParams", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
modelId: "gpt-4",
|
modelId: "gpt-5-nano",
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
|
|||||||
@ -42,7 +42,7 @@ describe("block streaming", () => {
|
|||||||
piEmbeddedMock.runEmbeddedPiAgent.mockReset();
|
piEmbeddedMock.runEmbeddedPiAgent.mockReset();
|
||||||
vi.mocked(loadModelCatalog).mockResolvedValue([
|
vi.mocked(loadModelCatalog).mockResolvedValue([
|
||||||
{ id: "claude-opus-4-5", name: "Opus 4.5", provider: "anthropic" },
|
{ id: "claude-opus-4-5", name: "Opus 4.5", provider: "anthropic" },
|
||||||
{ id: "gpt-4.1-mini", name: "GPT-4.1 Mini", provider: "openai" },
|
{ id: "gpt-5-nano", name: "GPT-5 Nano", provider: "openai" },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,7 @@ describe("directive behavior", () => {
|
|||||||
vi.mocked(loadModelCatalog).mockResolvedValue([
|
vi.mocked(loadModelCatalog).mockResolvedValue([
|
||||||
{ id: "claude-opus-4-5", name: "Opus 4.5", provider: "anthropic" },
|
{ id: "claude-opus-4-5", name: "Opus 4.5", provider: "anthropic" },
|
||||||
{ id: "claude-sonnet-4-1", name: "Sonnet 4.1", provider: "anthropic" },
|
{ id: "claude-sonnet-4-1", name: "Sonnet 4.1", provider: "anthropic" },
|
||||||
{ id: "gpt-4.1-mini", name: "GPT-4.1 Mini", provider: "openai" },
|
{ id: "gpt-5-nano", name: "GPT-5 Nano", provider: "openai" },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ describe("directive behavior", () => {
|
|||||||
{
|
{
|
||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
model: "openai/gpt-4.1-mini",
|
model: "openai/gpt-5-nano",
|
||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1655,7 +1655,7 @@ describe("directive behavior", () => {
|
|||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
models: {
|
models: {
|
||||||
"anthropic/claude-opus-4-5": {},
|
"anthropic/claude-opus-4-5": {},
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1666,7 +1666,7 @@ describe("directive behavior", () => {
|
|||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
expect(text).toContain("anthropic/claude-opus-4-5");
|
expect(text).toContain("anthropic/claude-opus-4-5");
|
||||||
expect(text).toContain("Pick: /model <#> or /model <provider/model>");
|
expect(text).toContain("Pick: /model <#> or /model <provider/model>");
|
||||||
expect(text).toContain("gpt-4.1-mini — openai");
|
expect(text).toContain("gpt-5-nano — openai");
|
||||||
expect(text).not.toContain("claude-sonnet-4-1");
|
expect(text).not.toContain("claude-sonnet-4-1");
|
||||||
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@ -1687,7 +1687,7 @@ describe("directive behavior", () => {
|
|||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
models: {
|
models: {
|
||||||
"anthropic/claude-opus-4-5": {},
|
"anthropic/claude-opus-4-5": {},
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1697,7 +1697,7 @@ describe("directive behavior", () => {
|
|||||||
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
expect(text).toContain("anthropic/claude-opus-4-5");
|
expect(text).toContain("anthropic/claude-opus-4-5");
|
||||||
expect(text).toContain("openai/gpt-4.1-mini");
|
expect(text).toContain("openai/gpt-5-nano");
|
||||||
expect(text).not.toContain("claude-sonnet-4-1");
|
expect(text).not.toContain("claude-sonnet-4-1");
|
||||||
expect(text).toContain("auth:");
|
expect(text).toContain("auth:");
|
||||||
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
||||||
@ -1719,7 +1719,7 @@ describe("directive behavior", () => {
|
|||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
models: {
|
models: {
|
||||||
"anthropic/claude-opus-4-5": {},
|
"anthropic/claude-opus-4-5": {},
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1730,7 +1730,7 @@ describe("directive behavior", () => {
|
|||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
expect(text).toContain("Pick: /model <#> or /model <provider/model>");
|
expect(text).toContain("Pick: /model <#> or /model <provider/model>");
|
||||||
expect(text).toContain("claude-opus-4-5 — anthropic");
|
expect(text).toContain("claude-opus-4-5 — anthropic");
|
||||||
expect(text).toContain("gpt-4.1-mini — openai");
|
expect(text).toContain("gpt-5-nano — openai");
|
||||||
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1751,7 +1751,7 @@ describe("directive behavior", () => {
|
|||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
models: {
|
models: {
|
||||||
"anthropic/claude-opus-4-5": {},
|
"anthropic/claude-opus-4-5": {},
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1762,7 +1762,7 @@ describe("directive behavior", () => {
|
|||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
expect(text).toContain("Pick: /model <#> or /model <provider/model>");
|
expect(text).toContain("Pick: /model <#> or /model <provider/model>");
|
||||||
expect(text).toContain("claude-opus-4-5 — anthropic");
|
expect(text).toContain("claude-opus-4-5 — anthropic");
|
||||||
expect(text).toContain("gpt-4.1-mini — openai");
|
expect(text).toContain("gpt-5-nano — openai");
|
||||||
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1778,7 +1778,7 @@ describe("directive behavior", () => {
|
|||||||
id: "claude-opus-4-5",
|
id: "claude-opus-4-5",
|
||||||
name: "Claude Opus 4.5",
|
name: "Claude Opus 4.5",
|
||||||
},
|
},
|
||||||
{ provider: "openai", id: "gpt-4.1-mini", name: "GPT-4.1 mini" },
|
{ provider: "openai", id: "gpt-5-nano", name: "GPT-5 Nano" },
|
||||||
]);
|
]);
|
||||||
const storePath = path.join(home, "sessions.json");
|
const storePath = path.join(home, "sessions.json");
|
||||||
|
|
||||||
@ -1792,7 +1792,7 @@ describe("directive behavior", () => {
|
|||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
models: {
|
models: {
|
||||||
"anthropic/claude-opus-4-5": {},
|
"anthropic/claude-opus-4-5": {},
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
"minimax/MiniMax-M2.1": { alias: "minimax" },
|
"minimax/MiniMax-M2.1": { alias: "minimax" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1813,7 +1813,7 @@ describe("directive behavior", () => {
|
|||||||
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
expect(text).toContain("claude-opus-4-5 — anthropic");
|
expect(text).toContain("claude-opus-4-5 — anthropic");
|
||||||
expect(text).toContain("gpt-4.1-mini — openai");
|
expect(text).toContain("gpt-5-nano — openai");
|
||||||
expect(text).toContain("MiniMax-M2.1 — minimax");
|
expect(text).toContain("MiniMax-M2.1 — minimax");
|
||||||
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@ -1853,7 +1853,7 @@ describe("directive behavior", () => {
|
|||||||
const storePath = path.join(home, "sessions.json");
|
const storePath = path.join(home, "sessions.json");
|
||||||
|
|
||||||
await getReplyFromConfig(
|
await getReplyFromConfig(
|
||||||
{ Body: "/model openai/gpt-4.1-mini", From: "+1222", To: "+1222" },
|
{ Body: "/model openai/gpt-5-nano", From: "+1222", To: "+1222" },
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
agents: {
|
agents: {
|
||||||
@ -1862,7 +1862,7 @@ describe("directive behavior", () => {
|
|||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
models: {
|
models: {
|
||||||
"anthropic/claude-opus-4-5": {},
|
"anthropic/claude-opus-4-5": {},
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1871,7 +1871,7 @@ describe("directive behavior", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assertModelSelection(storePath, {
|
assertModelSelection(storePath, {
|
||||||
model: "gpt-4.1-mini",
|
model: "gpt-5-nano",
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
});
|
});
|
||||||
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
||||||
@ -1889,10 +1889,10 @@ describe("directive behavior", () => {
|
|||||||
{
|
{
|
||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
model: { primary: "openai/gpt-4.1-mini" },
|
model: { primary: "openai/gpt-5-nano" },
|
||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
models: {
|
models: {
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
"anthropic/claude-opus-4-5": { alias: "Opus" },
|
"anthropic/claude-opus-4-5": { alias: "Opus" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2209,10 +2209,10 @@ describe("directive behavior", () => {
|
|||||||
{
|
{
|
||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
model: { primary: "openai/gpt-4.1-mini" },
|
model: { primary: "openai/gpt-5-nano" },
|
||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
models: {
|
models: {
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
"anthropic/claude-opus-4-5": { alias: "Opus" },
|
"anthropic/claude-opus-4-5": { alias: "Opus" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2242,10 +2242,10 @@ describe("directive behavior", () => {
|
|||||||
{
|
{
|
||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
model: { primary: "openai/gpt-4.1-mini" },
|
model: { primary: "openai/gpt-5-nano" },
|
||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
models: {
|
models: {
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
"anthropic/claude-opus-4-5": { alias: "Opus" },
|
"anthropic/claude-opus-4-5": { alias: "Opus" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2278,7 +2278,7 @@ describe("directive behavior", () => {
|
|||||||
{
|
{
|
||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
model: { primary: "openai/gpt-4.1-mini" },
|
model: { primary: "openai/gpt-5-nano" },
|
||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2309,7 +2309,7 @@ describe("directive behavior", () => {
|
|||||||
{
|
{
|
||||||
agents: {
|
agents: {
|
||||||
defaults: {
|
defaults: {
|
||||||
model: { primary: "openai/gpt-4.1-mini" },
|
model: { primary: "openai/gpt-5-nano" },
|
||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -2336,7 +2336,7 @@ describe("directive behavior", () => {
|
|||||||
|
|
||||||
const res = await getReplyFromConfig(
|
const res = await getReplyFromConfig(
|
||||||
{
|
{
|
||||||
Body: "please sync /model openai/gpt-4.1-mini now",
|
Body: "please sync /model openai/gpt-5-nano now",
|
||||||
From: "+1004",
|
From: "+1004",
|
||||||
To: "+2000",
|
To: "+2000",
|
||||||
},
|
},
|
||||||
@ -2348,7 +2348,7 @@ describe("directive behavior", () => {
|
|||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
models: {
|
models: {
|
||||||
"anthropic/claude-opus-4-5": {},
|
"anthropic/claude-opus-4-5": {},
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -41,7 +41,7 @@ const modelCatalogMocks = vi.hoisted(() => ({
|
|||||||
name: "Claude Opus 4.5 (OpenRouter)",
|
name: "Claude Opus 4.5 (OpenRouter)",
|
||||||
contextWindow: 200000,
|
contextWindow: 200000,
|
||||||
},
|
},
|
||||||
{ provider: "openai", id: "gpt-4.1-mini", name: "GPT-4.1 mini" },
|
{ provider: "openai", id: "gpt-5-nano", name: "GPT-5 Nano" },
|
||||||
{ provider: "openai", id: "gpt-5.2", name: "GPT-5.2" },
|
{ provider: "openai", id: "gpt-5.2", name: "GPT-5.2" },
|
||||||
{ provider: "openai-codex", id: "gpt-5.2", name: "GPT-5.2 (Codex)" },
|
{ provider: "openai-codex", id: "gpt-5.2", name: "GPT-5.2 (Codex)" },
|
||||||
{ provider: "minimax", id: "MiniMax-M2.1", name: "MiniMax M2.1" },
|
{ provider: "minimax", id: "MiniMax-M2.1", name: "MiniMax M2.1" },
|
||||||
@ -320,7 +320,7 @@ describe("trigger handling", () => {
|
|||||||
|
|
||||||
const res = await getReplyFromConfig(
|
const res = await getReplyFromConfig(
|
||||||
{
|
{
|
||||||
Body: "/model openai/gpt-4.1-mini",
|
Body: "/model openai/gpt-5-nano",
|
||||||
From: "telegram:111",
|
From: "telegram:111",
|
||||||
To: "telegram:111",
|
To: "telegram:111",
|
||||||
ChatType: "direct",
|
ChatType: "direct",
|
||||||
@ -336,11 +336,11 @@ describe("trigger handling", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
expect(text).toContain("Model set to openai/gpt-4.1-mini");
|
expect(text).toContain("Model set to openai/gpt-5-nano");
|
||||||
|
|
||||||
const store = loadSessionStore(cfg.session.store);
|
const store = loadSessionStore(cfg.session.store);
|
||||||
expect(store[targetSessionKey]?.providerOverride).toBe("openai");
|
expect(store[targetSessionKey]?.providerOverride).toBe("openai");
|
||||||
expect(store[targetSessionKey]?.modelOverride).toBe("gpt-4.1-mini");
|
expect(store[targetSessionKey]?.modelOverride).toBe("gpt-5-nano");
|
||||||
expect(store[slashSessionKey]).toBeUndefined();
|
expect(store[slashSessionKey]).toBeUndefined();
|
||||||
|
|
||||||
vi.mocked(runEmbeddedPiAgent).mockResolvedValue({
|
vi.mocked(runEmbeddedPiAgent).mockResolvedValue({
|
||||||
@ -368,7 +368,7 @@ describe("trigger handling", () => {
|
|||||||
expect(vi.mocked(runEmbeddedPiAgent).mock.calls[0]?.[0]).toEqual(
|
expect(vi.mocked(runEmbeddedPiAgent).mock.calls[0]?.[0]).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
model: "gpt-4.1-mini",
|
model: "gpt-5-nano",
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -122,7 +122,7 @@ describe("buildStatusMessage", () => {
|
|||||||
sessionId: "override-1",
|
sessionId: "override-1",
|
||||||
updatedAt: 0,
|
updatedAt: 0,
|
||||||
providerOverride: "openai",
|
providerOverride: "openai",
|
||||||
modelOverride: "gpt-4.1-mini",
|
modelOverride: "gpt-5-nano",
|
||||||
modelProvider: "anthropic",
|
modelProvider: "anthropic",
|
||||||
model: "claude-haiku-4-5",
|
model: "claude-haiku-4-5",
|
||||||
contextTokens: 32_000,
|
contextTokens: 32_000,
|
||||||
@ -133,7 +133,7 @@ describe("buildStatusMessage", () => {
|
|||||||
modelAuth: "api-key",
|
modelAuth: "api-key",
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(normalizeTestText(text)).toContain("Model: openai/gpt-4.1-mini");
|
expect(normalizeTestText(text)).toContain("Model: openai/gpt-5-nano");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("keeps provider prefix from configured model", () => {
|
it("keeps provider prefix from configured model", () => {
|
||||||
|
|||||||
@ -25,9 +25,7 @@ describe("listThinkingLevels", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("excludes xhigh for non-codex models", () => {
|
it("excludes xhigh for non-codex models", () => {
|
||||||
expect(listThinkingLevels(undefined, "gpt-4.1-mini")).not.toContain(
|
expect(listThinkingLevels(undefined, "gpt-5-nano")).not.toContain("xhigh");
|
||||||
"xhigh",
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -152,10 +152,10 @@ describe("agentCommand", () => {
|
|||||||
await withTempHome(async (home) => {
|
await withTempHome(async (home) => {
|
||||||
const store = path.join(home, "sessions.json");
|
const store = path.join(home, "sessions.json");
|
||||||
mockConfig(home, store, {
|
mockConfig(home, store, {
|
||||||
model: { primary: "openai/gpt-4.1-mini" },
|
model: { primary: "openai/gpt-5-nano" },
|
||||||
models: {
|
models: {
|
||||||
"anthropic/claude-opus-4-5": {},
|
"anthropic/claude-opus-4-5": {},
|
||||||
"openai/gpt-4.1-mini": {},
|
"openai/gpt-5-nano": {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ describe("agentCommand", () => {
|
|||||||
|
|
||||||
const callArgs = vi.mocked(runEmbeddedPiAgent).mock.calls.at(-1)?.[0];
|
const callArgs = vi.mocked(runEmbeddedPiAgent).mock.calls.at(-1)?.[0];
|
||||||
expect(callArgs?.provider).toBe("openai");
|
expect(callArgs?.provider).toBe("openai");
|
||||||
expect(callArgs?.model).toBe("gpt-4.1-mini");
|
expect(callArgs?.model).toBe("gpt-5-nano");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ describe("agents helpers", () => {
|
|||||||
name: "Work",
|
name: "Work",
|
||||||
workspace: "/work-ws",
|
workspace: "/work-ws",
|
||||||
agentDir: "/state/agents/work/agent",
|
agentDir: "/state/agents/work/agent",
|
||||||
model: "openai/gpt-4.1",
|
model: "openai/gpt-5-nano",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@ -157,8 +157,8 @@ describe("models list/status", () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
id: "gpt-4.1-mini",
|
id: "gpt-5-nano",
|
||||||
name: "GPT-4.1 mini",
|
name: "GPT-5 Nano",
|
||||||
input: ["text"],
|
input: ["text"],
|
||||||
baseUrl: "https://api.openai.com/v1",
|
baseUrl: "https://api.openai.com/v1",
|
||||||
contextWindow: 128000,
|
contextWindow: 128000,
|
||||||
@ -199,8 +199,8 @@ describe("models list/status", () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
id: "gpt-4.1-mini",
|
id: "gpt-5-nano",
|
||||||
name: "GPT-4.1 mini",
|
name: "GPT-5 Nano",
|
||||||
input: ["text"],
|
input: ["text"],
|
||||||
baseUrl: "https://api.openai.com/v1",
|
baseUrl: "https://api.openai.com/v1",
|
||||||
contextWindow: 128000,
|
contextWindow: 128000,
|
||||||
@ -241,8 +241,8 @@ describe("models list/status", () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
provider: "openai",
|
provider: "openai",
|
||||||
id: "gpt-4.1-mini",
|
id: "gpt-5-nano",
|
||||||
name: "GPT-4.1 mini",
|
name: "GPT-5 Nano",
|
||||||
input: ["text"],
|
input: ["text"],
|
||||||
baseUrl: "https://api.openai.com/v1",
|
baseUrl: "https://api.openai.com/v1",
|
||||||
contextWindow: 128000,
|
contextWindow: 128000,
|
||||||
|
|||||||
@ -1603,10 +1603,10 @@ describe("legacy config detection", () => {
|
|||||||
const res = migrateLegacyConfig({
|
const res = migrateLegacyConfig({
|
||||||
agent: {
|
agent: {
|
||||||
model: "anthropic/claude-opus-4-5",
|
model: "anthropic/claude-opus-4-5",
|
||||||
modelFallbacks: ["openai/gpt-4.1-mini"],
|
modelFallbacks: ["openai/gpt-5-nano"],
|
||||||
imageModel: "openai/gpt-4.1-mini",
|
imageModel: "openai/gpt-5-nano",
|
||||||
imageModelFallbacks: ["anthropic/claude-opus-4-5"],
|
imageModelFallbacks: ["anthropic/claude-opus-4-5"],
|
||||||
allowedModels: ["anthropic/claude-opus-4-5", "openai/gpt-4.1-mini"],
|
allowedModels: ["anthropic/claude-opus-4-5", "openai/gpt-5-nano"],
|
||||||
modelAliases: { Opus: "anthropic/claude-opus-4-5" },
|
modelAliases: { Opus: "anthropic/claude-opus-4-5" },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -1615,10 +1615,10 @@ describe("legacy config detection", () => {
|
|||||||
"anthropic/claude-opus-4-5",
|
"anthropic/claude-opus-4-5",
|
||||||
);
|
);
|
||||||
expect(res.config?.agents?.defaults?.model?.fallbacks).toEqual([
|
expect(res.config?.agents?.defaults?.model?.fallbacks).toEqual([
|
||||||
"openai/gpt-4.1-mini",
|
"openai/gpt-5-nano",
|
||||||
]);
|
]);
|
||||||
expect(res.config?.agents?.defaults?.imageModel?.primary).toBe(
|
expect(res.config?.agents?.defaults?.imageModel?.primary).toBe(
|
||||||
"openai/gpt-4.1-mini",
|
"openai/gpt-5-nano",
|
||||||
);
|
);
|
||||||
expect(res.config?.agents?.defaults?.imageModel?.fallbacks).toEqual([
|
expect(res.config?.agents?.defaults?.imageModel?.fallbacks).toEqual([
|
||||||
"anthropic/claude-opus-4-5",
|
"anthropic/claude-opus-4-5",
|
||||||
@ -1627,7 +1627,7 @@ describe("legacy config detection", () => {
|
|||||||
res.config?.agents?.defaults?.models?.["anthropic/claude-opus-4-5"],
|
res.config?.agents?.defaults?.models?.["anthropic/claude-opus-4-5"],
|
||||||
).toMatchObject({ alias: "Opus" });
|
).toMatchObject({ alias: "Opus" });
|
||||||
expect(
|
expect(
|
||||||
res.config?.agents?.defaults?.models?.["openai/gpt-4.1-mini"],
|
res.config?.agents?.defaults?.models?.["openai/gpt-5-nano"],
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
expect(res.config?.agent).toBeUndefined();
|
expect(res.config?.agent).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -213,7 +213,7 @@ describe("runCronIsolatedAgentTurn", () => {
|
|||||||
job: makeJob({
|
job: makeJob({
|
||||||
kind: "agentTurn",
|
kind: "agentTurn",
|
||||||
message: "do it",
|
message: "do it",
|
||||||
model: "openai/gpt-4.1-mini",
|
model: "openai/gpt-5-nano",
|
||||||
}),
|
}),
|
||||||
message: "do it",
|
message: "do it",
|
||||||
sessionKey: "cron:job-1",
|
sessionKey: "cron:job-1",
|
||||||
@ -226,7 +226,7 @@ describe("runCronIsolatedAgentTurn", () => {
|
|||||||
model?: string;
|
model?: string;
|
||||||
};
|
};
|
||||||
expect(call?.provider).toBe("openai");
|
expect(call?.provider).toBe("openai");
|
||||||
expect(call?.model).toBe("gpt-4.1-mini");
|
expect(call?.model).toBe("gpt-5-nano");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ describe("hooks mapping", () => {
|
|||||||
match: { path: "gmail" },
|
match: { path: "gmail" },
|
||||||
action: "agent",
|
action: "agent",
|
||||||
messageTemplate: "Subject: {{messages[0].subject}}",
|
messageTemplate: "Subject: {{messages[0].subject}}",
|
||||||
model: "openai/gpt-4.1-mini",
|
model: "openai/gpt-5-nano",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -58,7 +58,7 @@ describe("hooks mapping", () => {
|
|||||||
});
|
});
|
||||||
expect(result?.ok).toBe(true);
|
expect(result?.ok).toBe(true);
|
||||||
if (result?.ok && result.action.kind === "agent") {
|
if (result?.ok && result.action.kind === "agent") {
|
||||||
expect(result.action.model).toBe("openai/gpt-4.1-mini");
|
expect(result.action.model).toBe("openai/gpt-5-nano");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -88,7 +88,7 @@ describe("gateway server hooks", () => {
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
message: "Do it",
|
message: "Do it",
|
||||||
name: "Email",
|
name: "Email",
|
||||||
model: "openai/gpt-4.1-mini",
|
model: "openai/gpt-5-nano",
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
expect(res.status).toBe(202);
|
expect(res.status).toBe(202);
|
||||||
@ -96,7 +96,7 @@ describe("gateway server hooks", () => {
|
|||||||
const call = cronIsolatedRun.mock.calls[0]?.[0] as {
|
const call = cronIsolatedRun.mock.calls[0]?.[0] as {
|
||||||
job?: { payload?: { model?: string } };
|
job?: { payload?: { model?: string } };
|
||||||
};
|
};
|
||||||
expect(call?.job?.payload?.model).toBe("openai/gpt-4.1-mini");
|
expect(call?.job?.payload?.model).toBe("openai/gpt-5-nano");
|
||||||
drainSystemEvents(resolveMainKey());
|
drainSystemEvents(resolveMainKey());
|
||||||
await server.close();
|
await server.close();
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user