mirror of
https://github.com/mark3labs/kit.git
synced 2026-06-13 19:20:06 +00:00
3881d1c28f
Fantasy's hardcoded responsesModelIDs list gates whether a model uses the Responses API or Chat Completions code path. When a new model (e.g. gpt-5.5) is added via `kit update-models` but fantasy hasn't been updated yet, the type mismatch between *ResponsesProviderOptions and *ProviderOptions causes a crash. - Add isResponsesAPIModel()/isResponsesReasoningModel() helpers that supplement fantasy's checks with prefix-based heuristics for modern OpenAI model families (gpt-4.1+, gpt-5+, o-series, codex, chatgpt) - Add RegisterResponsesModels() using go:linkname to append missing model IDs from our database into fantasy's internal slices at init time and after ReloadGlobalRegistry() - Replace all direct openai.IsResponsesModel/IsResponsesReasoningModel calls in providers.go with the new helpers - Merge embedded + cached model databases instead of cache-only fallback - Bump fantasy v0.19.0 -> v0.20.0 to match existing import usage - Document the technique and model-family update process in AGENTS.md
59 lines
2.2 KiB
Go
59 lines
2.2 KiB
Go
package models
|
|
|
|
import (
|
|
_ "unsafe" // Required for go:linkname.
|
|
)
|
|
|
|
// responsesModelIDs and responsesReasoningModelIDs are the unexported slices
|
|
// in charm.land/fantasy/providers/openai that gate whether a model uses the
|
|
// Responses API code path vs Chat Completions. When a brand-new model is
|
|
// released (e.g. gpt-5.5) and models.dev is updated via `kit update-models`,
|
|
// Kit recognises the model but fantasy's hardcoded list does not. That causes
|
|
// a type-mismatch crash: Kit builds *ResponsesProviderOptions (correct for
|
|
// the Responses endpoint) but fantasy routes through Chat Completions and
|
|
// rejects the type.
|
|
//
|
|
// RegisterResponsesModels appends model IDs that are missing from fantasy's
|
|
// lists so the provider routes through the correct code path. It is called
|
|
// once during provider creation after loading the model database.
|
|
|
|
//go:linkname fantasyResponsesModelIDs charm.land/fantasy/providers/openai.responsesModelIDs
|
|
var fantasyResponsesModelIDs []string
|
|
|
|
//go:linkname fantasyResponsesReasoningModelIDs charm.land/fantasy/providers/openai.responsesReasoningModelIDs
|
|
var fantasyResponsesReasoningModelIDs []string
|
|
|
|
// RegisterResponsesModels ensures every OpenAI model known to our model
|
|
// database that should use the Responses API is present in fantasy's
|
|
// internal lists. This is a no-op for models already registered.
|
|
func RegisterResponsesModels() {
|
|
registry := GetGlobalRegistry()
|
|
providerInfo := registry.GetProviderInfo("openai")
|
|
if providerInfo == nil {
|
|
return
|
|
}
|
|
|
|
existing := make(map[string]bool, len(fantasyResponsesModelIDs))
|
|
for _, id := range fantasyResponsesModelIDs {
|
|
existing[id] = true
|
|
}
|
|
existingReasoning := make(map[string]bool, len(fantasyResponsesReasoningModelIDs))
|
|
for _, id := range fantasyResponsesReasoningModelIDs {
|
|
existingReasoning[id] = true
|
|
}
|
|
|
|
for modelID, modelInfo := range providerInfo.Models {
|
|
if !isResponsesAPIModel(modelID) {
|
|
continue
|
|
}
|
|
if !existing[modelID] {
|
|
fantasyResponsesModelIDs = append(fantasyResponsesModelIDs, modelID)
|
|
existing[modelID] = true
|
|
}
|
|
if modelInfo.Reasoning && !existingReasoning[modelID] {
|
|
fantasyResponsesReasoningModelIDs = append(fantasyResponsesReasoningModelIDs, modelID)
|
|
existingReasoning[modelID] = true
|
|
}
|
|
}
|
|
}
|