fix: improve executor model discovery

This commit is contained in:
liujing
2026-07-20 17:25:33 +08:00
parent 64b3ef6c60
commit a5daca7c4d
5 changed files with 150 additions and 68 deletions
+50 -3
View File
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { extractModelIds, discoverExecutorModels } from "./workflow-model-discovery.js";
import { extractModelIds, extractReasonixModels, discoverExecutorModels } from "./workflow-model-discovery.js";
import { saveGlobalExecutorModels, loadGlobalWorkflowConfig } from "./workflow-config.js";
describe("workflow-model-discovery helpers", () => {
@@ -24,6 +24,31 @@ describe("workflow-model-discovery helpers", () => {
],
})).toEqual(["model-a", "model-b"]);
});
it("extracts concrete Reasonix provider/model ids", () => {
expect(extractReasonixModels({
providers: [
{
name: "custom-opencode-ai",
models: ["deepseek-v4-flash", "deepseek-v4-pro"],
},
{ name: "anthropic", models: [] },
],
})).toEqual([
"custom-opencode-ai/deepseek-v4-flash",
"custom-opencode-ai/deepseek-v4-pro",
"anthropic",
]);
});
it("supports object model entries and legacy top-level models", () => {
expect(extractReasonixModels({
providers: [{ name: "gateway", models: [{ id: "model-a" }, { name: "model-b" }] }],
})).toEqual(["gateway/model-a", "gateway/model-b"]);
expect(extractReasonixModels({
models: [{ provider: "gateway", id: "model-c" }, "provider-only"],
})).toEqual(["gateway/model-c", "provider-only"]);
});
});
describe("saveGlobalExecutorModels", () => {
@@ -115,6 +140,25 @@ describe("discoverExecutorModels isolation", () => {
savedVars[key] = process.env[key];
delete process.env[key];
}
const binDir = path.join(tmpHome, "bin");
fs.mkdirSync(binDir, { recursive: true });
const agyBin = path.join(binDir, "agy");
const reasonixBin = path.join(binDir, "reasonix");
fs.writeFileSync(agyBin, "#!/bin/sh\nprintf '%s\\n' 'Test Agy Model'\n", { mode: 0o755 });
fs.writeFileSync(reasonixBin, `#!/bin/sh
printf '%s\\n' '{"providers":[{"name":"test-provider","models":["test-model"]}]}'
`, { mode: 0o755 });
const configDir = path.join(tmpHome, ".agent-workflow");
fs.mkdirSync(configDir, { recursive: true });
fs.writeFileSync(path.join(configDir, "config.json"), JSON.stringify({
version: "1",
executors: {
agy: { binary: agyBin },
reasonix: { binary: reasonixBin },
},
}));
});
afterEach(() => {
@@ -148,8 +192,11 @@ describe("discoverExecutorModels isolation", () => {
expect(result.claude.error).toBeTruthy();
expect(JSON.stringify(result)).not.toContain("secret-key-value");
expect(JSON.stringify(result)).not.toContain("user:pass");
expect(result.agy.status === "ok" || result.agy.status === "error").toBe(true);
expect(result.reasonix.status === "ok" || result.reasonix.status === "error").toBe(true);
expect(result.agy).toMatchObject({ status: "ok", models: ["Test Agy Model"] });
expect(result.reasonix).toMatchObject({
status: "ok",
models: ["test-provider/test-model"],
});
});
it("resolves Claude settings from ~/.claude/settings.json when process env is unset", async () => {