82 lines
3.8 KiB
Go
82 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"sort"
|
|
"time"
|
|
|
|
"git.cin.su/m/Assistant/contracts/capability"
|
|
"git.cin.su/m/Assistant/contracts/identity"
|
|
)
|
|
|
|
type discoveryService struct {
|
|
resolver bindingResolver
|
|
providers map[string]providerRegistration
|
|
owner identity.PrincipalID
|
|
now func() time.Time
|
|
}
|
|
|
|
func (s discoveryService) handler(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method == http.MethodGet && r.URL.Path == "/v1/provider-discovery/status" {
|
|
s.statusHandler(w, r)
|
|
return
|
|
}
|
|
registration, ok := s.providers[r.PathValue("provider")]
|
|
if !ok || registration.Discovery == nil {
|
|
http.Error(w, "provider discovery not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
discovered, probe := registration.Discovery.Discover(r.Context())
|
|
snapshot := capability.CognitiveDiscoverySnapshot{ProviderInstanceID: registration.ProviderInstanceID, ProviderKind: registration.Kind, EndpointRef: registration.EndpointRef, CredentialRef: registration.CredentialRef, AuthMode: registration.AuthMode, BillingMode: registration.BillingMode, Enabled: true, OwnerPrincipalID: s.owner, CapabilityID: creatorAdvisoryCapabilityID, DataPolicy: registration.DataPolicy, LimitPolicyRef: "creator-advisory-local-v1", Health: probe.Health, FailureClass: capability.CognitiveFailureType(probe.Failure), ObservedAtUnixMillis: s.now().UnixMilli()}
|
|
for _, model := range discovered {
|
|
snapshot.Models = append(snapshot.Models, capability.DiscoveredModelSnapshot{ProviderModelID: model.ProviderModelID, Fingerprint: model.Fingerprint, MaxContextBytes: model.MaxContextBytes, Modalities: model.Modalities, Capabilities: model.Capabilities, Installed: capability.OperationalYes, Loaded: capability.OperationalNotObserved, Invokable: capability.OperationalNotObserved})
|
|
}
|
|
result, err := s.resolver.RegisterDiscovery(r.Context(), snapshot)
|
|
if err != nil {
|
|
http.Error(w, "provider discovery registration unavailable", http.StatusBadGateway)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_ = json.NewEncoder(w).Encode(result)
|
|
}
|
|
|
|
type discoveryStatus struct {
|
|
Provider string `json:"provider"`
|
|
ProviderKind capability.ProviderKind `json:"provider_kind"`
|
|
Health capability.HealthState `json:"health"`
|
|
FailureClass capability.CognitiveFailureType `json:"failure_class,omitempty"`
|
|
ObservedAtUnixMillis int64 `json:"observed_at_unix_millis"`
|
|
Models []discoveredModelStatus `json:"models"`
|
|
}
|
|
|
|
type discoveredModelStatus struct {
|
|
ProviderModelID capability.ProviderModelID `json:"provider_model_id"`
|
|
Fingerprint capability.ModelFingerprint `json:"fingerprint,omitempty"`
|
|
Capabilities []capability.ModelCapability `json:"capabilities,omitempty"`
|
|
}
|
|
|
|
func (s discoveryService) statusHandler(w http.ResponseWriter, r *http.Request) {
|
|
providers := make([]string, 0, len(s.providers))
|
|
for name := range s.providers {
|
|
providers = append(providers, name)
|
|
}
|
|
sort.Strings(providers)
|
|
result := make([]discoveryStatus, 0, len(providers))
|
|
for _, name := range providers {
|
|
registration := s.providers[name]
|
|
status := discoveryStatus{Provider: name, ProviderKind: registration.Kind, Health: capability.HealthUnknown, ObservedAtUnixMillis: s.now().UnixMilli(), Models: []discoveredModelStatus{}}
|
|
if registration.Discovery != nil {
|
|
models, probe := registration.Discovery.Discover(r.Context())
|
|
status.Health = probe.Health
|
|
status.FailureClass = capability.CognitiveFailureType(probe.Failure)
|
|
for _, model := range models {
|
|
status.Models = append(status.Models, discoveredModelStatus{ProviderModelID: model.ProviderModelID, Fingerprint: model.Fingerprint, Capabilities: model.Capabilities})
|
|
}
|
|
}
|
|
result = append(result, status)
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_ = json.NewEncoder(w).Encode(result)
|
|
}
|