refactor(athena): consolidate parseModelString to single source of truth

This commit is contained in:
ismeth
2026-02-20 14:21:23 +01:00
committed by YeonGyu-Kim
parent aa3b5274c5
commit ad481472eb
5 changed files with 38 additions and 37 deletions
-1
View File
@@ -1,5 +1,4 @@
export * from "./types"
export * from "./agent"
export * from "./council-member-agent"
export * from "./model-parser"
-73
View File
@@ -1,73 +0,0 @@
import { describe, expect, test } from "bun:test"
import { parseModelString } from "./model-parser"
describe("parseModelString", () => {
describe("valid model strings", () => {
//#given provider/model strings with one separator
//#when parsing model strings
//#then it returns providerID and modelID parts
test("parses anthropic model", () => {
expect(parseModelString("anthropic/claude-opus-4-6")).toEqual({
providerID: "anthropic",
modelID: "claude-opus-4-6",
})
})
test("parses openai model", () => {
expect(parseModelString("openai/gpt-5.3-codex")).toEqual({
providerID: "openai",
modelID: "gpt-5.3-codex",
})
})
test("parses google model", () => {
expect(parseModelString("google/gemini-3-flash")).toEqual({
providerID: "google",
modelID: "gemini-3-flash",
})
})
test("parses xai model", () => {
expect(parseModelString("xai/grok-code-fast-1")).toEqual({
providerID: "xai",
modelID: "grok-code-fast-1",
})
})
})
describe("edge cases", () => {
//#given a model string with extra slashes
//#when parsing with first slash as separator
//#then provider is before first slash and model keeps remaining path
test("keeps extra slashes in model segment", () => {
expect(parseModelString("provider/model/with/extra/slashes")).toEqual({
providerID: "provider",
modelID: "model/with/extra/slashes",
})
})
})
describe("invalid model strings", () => {
//#given malformed or empty model strings
//#when parsing model strings
//#then it returns null
test("returns null for empty string", () => {
expect(parseModelString("")).toBeNull()
})
test("returns null for model without slash", () => {
expect(parseModelString("no-slash-model")).toBeNull()
})
test("returns null for empty provider", () => {
expect(parseModelString("/missing-provider")).toBeNull()
})
test("returns null for empty model", () => {
expect(parseModelString("missing-model/")).toBeNull()
})
})
})
-23
View File
@@ -1,23 +0,0 @@
export interface ParsedModel {
providerID: string
modelID: string
}
export function parseModelString(model: string): ParsedModel | null {
if (!model) {
return null
}
const slashIndex = model.indexOf("/")
if (slashIndex <= 0) {
return null
}
const providerID = model.substring(0, slashIndex)
const modelID = model.substring(slashIndex + 1)
if (!modelID) {
return null
}
return { providerID, modelID }
}
@@ -1,7 +1,7 @@
import type { AgentConfig } from "@opencode-ai/sdk"
import type { CouncilConfig, CouncilMemberConfig } from "../athena/types"
import { createCouncilMemberAgent } from "../athena/council-member-agent"
import { parseModelString } from "../athena/model-parser"
import { parseModelString } from "../../tools/delegate-task/model-string-parser"
import { log } from "../../shared/logger"
/** Prefix used for all dynamically-registered council member agent keys. */