chore: import upstream snapshot with attribution
govulncheck / govulncheck (push) Has been cancelled
Lint / golangci-lint (push) Has been cancelled
Run Tests / Unit Tests (push) Has been cancelled
Run Tests / Etcd Integration Tests (push) Has been cancelled
Harness (E2E) / Harnesses (mock LLM) (push) Has been cancelled
Harness (E2E) / Provider harnesses (live LLM conformance) (push) Has been cancelled
govulncheck / govulncheck (push) Has been cancelled
Lint / golangci-lint (push) Has been cancelled
Run Tests / Unit Tests (push) Has been cancelled
Run Tests / Etcd Integration Tests (push) Has been cancelled
Harness (E2E) / Harnesses (mock LLM) (push) Has been cancelled
Harness (E2E) / Provider harnesses (live LLM conformance) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
package ai
|
||||
|
||||
import "sort"
|
||||
|
||||
// CapabilityRow is one deterministic row in a provider capability matrix.
|
||||
type CapabilityRow struct {
|
||||
// Provider is the registered provider name.
|
||||
Provider string `json:"provider"`
|
||||
Capabilities
|
||||
}
|
||||
|
||||
// Capabilities describes the AI interfaces a provider has registered.
|
||||
// It is intentionally based on package registration rather than external
|
||||
// provider marketing claims, so it reflects what this build can actually use.
|
||||
type Capabilities struct {
|
||||
// Model reports whether ai.New can construct a chat/text model provider.
|
||||
Model bool `json:"model"`
|
||||
// Image reports whether ai.NewImage can construct an image model provider.
|
||||
Image bool `json:"image"`
|
||||
// Video reports whether ai.NewVideo can construct a video model provider.
|
||||
Video bool `json:"video"`
|
||||
// Stream reports whether the provider has registered end-to-end token streaming.
|
||||
// Providers that only satisfy the Model interface with ErrStreamingUnsupported
|
||||
// leave this false until their Stream implementation is usable.
|
||||
Stream bool `json:"stream"`
|
||||
// ToolStream reports whether the provider supports agent Stream requests that
|
||||
// include tool schemas. Providers may support plain token streaming while
|
||||
// leaving this false when their streaming API cannot accept tools.
|
||||
ToolStream bool `json:"tool_stream"`
|
||||
}
|
||||
|
||||
// ProviderCapabilities reports the capabilities registered for provider.
|
||||
func ProviderCapabilities(provider string) Capabilities {
|
||||
_, hasModel := providers[provider]
|
||||
_, hasImage := imageProviders[provider]
|
||||
_, hasVideo := videoProviders[provider]
|
||||
_, hasStream := streamProviders[provider]
|
||||
_, hasToolStream := toolStreamProviders[provider]
|
||||
|
||||
return Capabilities{
|
||||
Model: hasModel,
|
||||
Image: hasImage,
|
||||
Video: hasVideo,
|
||||
Stream: hasStream,
|
||||
ToolStream: hasToolStream,
|
||||
}
|
||||
}
|
||||
|
||||
// CapabilityMatrix returns a snapshot of all registered AI providers and the
|
||||
// interfaces they support. The returned map is a copy and can be modified by
|
||||
// callers without mutating the registry. Use CapabilityRows when rendering a
|
||||
// deterministic table or report.
|
||||
func CapabilityMatrix() map[string]Capabilities {
|
||||
names := map[string]struct{}{}
|
||||
for name := range providers {
|
||||
names[name] = struct{}{}
|
||||
}
|
||||
for name := range imageProviders {
|
||||
names[name] = struct{}{}
|
||||
}
|
||||
for name := range videoProviders {
|
||||
names[name] = struct{}{}
|
||||
}
|
||||
for name := range streamProviders {
|
||||
names[name] = struct{}{}
|
||||
}
|
||||
for name := range toolStreamProviders {
|
||||
names[name] = struct{}{}
|
||||
}
|
||||
|
||||
matrix := make(map[string]Capabilities, len(names))
|
||||
for name := range names {
|
||||
matrix[name] = ProviderCapabilities(name)
|
||||
}
|
||||
return matrix
|
||||
}
|
||||
|
||||
// CapabilityRows returns a deterministic capability support matrix for every
|
||||
// registered AI provider. It is the ordered form of CapabilityMatrix, intended
|
||||
// for CLIs, docs generators, and conformance reports that need stable output.
|
||||
func CapabilityRows() []CapabilityRow {
|
||||
names := RegisteredProviders("")
|
||||
rows := make([]CapabilityRow, 0, len(names))
|
||||
for _, name := range names {
|
||||
rows = append(rows, CapabilityRow{
|
||||
Provider: name,
|
||||
Capabilities: ProviderCapabilities(name),
|
||||
})
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// RegisterStream records that provider has a usable Stream implementation.
|
||||
// Providers should call this from init alongside Register once Stream returns
|
||||
// chunks instead of ErrStreamingUnsupported.
|
||||
func RegisterStream(provider string) {
|
||||
streamProviders[provider] = struct{}{}
|
||||
}
|
||||
|
||||
// RegisterToolStream records that provider can accept tool schemas in Stream
|
||||
// requests. This is intentionally separate from RegisterStream because some
|
||||
// providers can stream tokens but cannot expose tools while streaming.
|
||||
func RegisterToolStream(provider string) {
|
||||
toolStreamProviders[provider] = struct{}{}
|
||||
}
|
||||
|
||||
var streamProviders = make(map[string]struct{})
|
||||
var toolStreamProviders = make(map[string]struct{})
|
||||
|
||||
// RegisteredProviders returns the registered provider names in sorted order.
|
||||
// kind may be "model", "image", "video", "stream", "tool_stream", or empty for the union of all
|
||||
// provider registries.
|
||||
func RegisteredProviders(kind string) []string {
|
||||
names := map[string]struct{}{}
|
||||
add := func(registry any) {
|
||||
switch r := registry.(type) {
|
||||
case map[string]NewFunc:
|
||||
for name := range r {
|
||||
names[name] = struct{}{}
|
||||
}
|
||||
case map[string]NewImageFunc:
|
||||
for name := range r {
|
||||
names[name] = struct{}{}
|
||||
}
|
||||
case map[string]NewVideoFunc:
|
||||
for name := range r {
|
||||
names[name] = struct{}{}
|
||||
}
|
||||
case map[string]struct{}:
|
||||
for name := range r {
|
||||
names[name] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case "model":
|
||||
add(providers)
|
||||
case "stream":
|
||||
add(streamProviders)
|
||||
case "tool_stream":
|
||||
add(toolStreamProviders)
|
||||
case "image":
|
||||
add(imageProviders)
|
||||
case "video":
|
||||
add(videoProviders)
|
||||
default:
|
||||
add(providers)
|
||||
add(imageProviders)
|
||||
add(videoProviders)
|
||||
}
|
||||
|
||||
out := make([]string, 0, len(names))
|
||||
for name := range names {
|
||||
out = append(out, name)
|
||||
}
|
||||
sort.Strings(out)
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user