0eb447113e
Add -m, --model <provider/model> option to oh-my-opencode run command. Allows users to override the model while keeping the agent unchanged. Changes: - Add model?: string to RunOptions interface - Create model-resolver.ts to parse provider/model format - Add model-resolver.test.ts with 7 test cases (TDD) - Add --model CLI option with help text examples - Wire resolveRunModel in runner.ts and pass to promptAsync - Export resolveRunModel from barrel (index.ts) Example usage: bunx oh-my-opencode run --model anthropic/claude-sonnet-4 "Fix the bug" bunx oh-my-opencode run --agent Sisyphus --model openai/gpt-5.4 "Task"
84 lines
2.0 KiB
TypeScript
84 lines
2.0 KiB
TypeScript
/// <reference types="bun-types" />
|
|
|
|
import { describe, it, expect } from "bun:test"
|
|
import { resolveRunModel } from "./model-resolver"
|
|
|
|
describe("resolveRunModel", () => {
|
|
it("given no model string, when resolved, then returns undefined", () => {
|
|
// given
|
|
const modelString = undefined
|
|
|
|
// when
|
|
const result = resolveRunModel(modelString)
|
|
|
|
// then
|
|
expect(result).toBeUndefined()
|
|
})
|
|
|
|
it("given empty string, when resolved, then throws Error", () => {
|
|
// given
|
|
const modelString = ""
|
|
|
|
// when
|
|
const resolve = () => resolveRunModel(modelString)
|
|
|
|
// then
|
|
expect(resolve).toThrow()
|
|
})
|
|
|
|
it("given valid 'anthropic/claude-sonnet-4', when resolved, then returns correct object", () => {
|
|
// given
|
|
const modelString = "anthropic/claude-sonnet-4"
|
|
|
|
// when
|
|
const result = resolveRunModel(modelString)
|
|
|
|
// then
|
|
expect(result).toEqual({ providerID: "anthropic", modelID: "claude-sonnet-4" })
|
|
})
|
|
|
|
it("given nested slashes 'openai/gpt-5.3/preview', when resolved, then modelID is 'gpt-5.3/preview'", () => {
|
|
// given
|
|
const modelString = "openai/gpt-5.3/preview"
|
|
|
|
// when
|
|
const result = resolveRunModel(modelString)
|
|
|
|
// then
|
|
expect(result).toEqual({ providerID: "openai", modelID: "gpt-5.3/preview" })
|
|
})
|
|
|
|
it("given no slash 'claude-sonnet-4', when resolved, then throws Error", () => {
|
|
// given
|
|
const modelString = "claude-sonnet-4"
|
|
|
|
// when
|
|
const resolve = () => resolveRunModel(modelString)
|
|
|
|
// then
|
|
expect(resolve).toThrow()
|
|
})
|
|
|
|
it("given empty provider '/claude-sonnet-4', when resolved, then throws Error", () => {
|
|
// given
|
|
const modelString = "/claude-sonnet-4"
|
|
|
|
// when
|
|
const resolve = () => resolveRunModel(modelString)
|
|
|
|
// then
|
|
expect(resolve).toThrow()
|
|
})
|
|
|
|
it("given trailing slash 'anthropic/', when resolved, then throws Error", () => {
|
|
// given
|
|
const modelString = "anthropic/"
|
|
|
|
// when
|
|
const resolve = () => resolveRunModel(modelString)
|
|
|
|
// then
|
|
expect(resolve).toThrow()
|
|
})
|
|
})
|