mirror of
https://github.com/anomalyco/opencode.git
synced 2026-04-24 06:45:22 +00:00
fix(cli): robust suggestions for unknown provider and model-only input; ignore bun build artifacts
This commit is contained in:
1
packages/opencode/.gitignore
vendored
1
packages/opencode/.gitignore
vendored
@@ -2,3 +2,4 @@ research
|
||||
dist
|
||||
gen
|
||||
app.log
|
||||
*.bun-build
|
||||
|
||||
@@ -526,6 +526,19 @@ export namespace Provider {
|
||||
if (!provider) {
|
||||
let suggestions: string[] = []
|
||||
const normalize = (str: string) => str.toLowerCase().replace(/[^a-z0-9]/g, "")
|
||||
const levenshtein = (a: string, b: string) => {
|
||||
const m = a.length, n = b.length
|
||||
const dp = Array.from({ length: m + 1 }, () => new Array<number>(n + 1).fill(0))
|
||||
for (let i = 0; i <= m; i++) dp[i][0] = i
|
||||
for (let j = 0; j <= n; j++) dp[0][j] = j
|
||||
for (let i = 1; i <= m; i++) {
|
||||
for (let j = 1; j <= n; j++) {
|
||||
const cost = a[i - 1] === b[j - 1] ? 0 : 1
|
||||
dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost)
|
||||
}
|
||||
}
|
||||
return dp[m][n]
|
||||
}
|
||||
if (!modelID || modelID.trim() === "") {
|
||||
// Treat single-token input as an unqualified model; search across all providers' models.
|
||||
const q = normalize(providerID)
|
||||
@@ -538,11 +551,31 @@ export namespace Provider {
|
||||
const byNorm = fuzzysort.go(q, entries as any, { limit: 5, key: "norm" }).map((r: any) => r.obj.combo)
|
||||
const combos = entries.map((e) => e.combo)
|
||||
const byRaw = fuzzysort.go(providerID, combos, { limit: 5 }).map((r) => r.target)
|
||||
suggestions = Array.from(new Set([...byNorm, ...byRaw])).slice(0, 3)
|
||||
let merged = Array.from(new Set([...byNorm, ...byRaw]))
|
||||
if (merged.length === 0) {
|
||||
// fallback to edit distance on normalized mid
|
||||
const scored = entries
|
||||
.map((e) => ({ combo: e.combo, d: levenshtein(q, e.norm) }))
|
||||
.sort((a, b) => a.d - b.d)
|
||||
.slice(0, 3)
|
||||
.map((x) => x.combo)
|
||||
merged = scored
|
||||
}
|
||||
suggestions = merged.slice(0, 3)
|
||||
} else {
|
||||
const providerSuggestions = fuzzysort
|
||||
.go(providerID, Object.keys(s.providers), { limit: 3 })
|
||||
.map((r) => r.target + "/" + modelID)
|
||||
const pcands = Object.keys(s.providers)
|
||||
const corpus = pcands.map((raw) => ({ raw, norm: normalize(raw) }))
|
||||
const q = normalize(providerID)
|
||||
const hits = fuzzysort.go(q, corpus as any, { limit: 5, key: "norm" })
|
||||
let ranked = hits.map((r: any) => r.obj.raw)
|
||||
if (ranked.length === 0) {
|
||||
ranked = pcands
|
||||
.map((p) => ({ p, d: levenshtein(q, normalize(p)) }))
|
||||
.sort((a, b) => a.d - b.d)
|
||||
.slice(0, 3)
|
||||
.map((x) => x.p)
|
||||
}
|
||||
const providerSuggestions = ranked.map((r) => r + "/" + modelID)
|
||||
suggestions = providerSuggestions
|
||||
}
|
||||
throw new ModelNotFoundError({ providerID, modelID, suggestions })
|
||||
|
||||
Reference in New Issue
Block a user