diff --git a/dev/tasks/DEV-000083-domovoy-lifeboat-mode.json b/dev/tasks/DEV-000083-domovoy-lifeboat-mode.json index d4288f6..d3c9175 100644 --- a/dev/tasks/DEV-000083-domovoy-lifeboat-mode.json +++ b/dev/tasks/DEV-000083-domovoy-lifeboat-mode.json @@ -18,6 +18,8 @@ "cmd/core-runtime/main_test.go", "cmd/cognitive-worker/main.go", "cmd/cognitive-worker/main_test.go", + "modules/capability/domain/cognitive_registry.go", + "modules/capability/domain/cognitive_registry_test.go", "cmd/creator-web/static/assets/chat.js", "cmd/creator-web/static/chat.html", "cmd/creator-web/chat_test.go", diff --git a/modules/capability/domain/cognitive_registry.go b/modules/capability/domain/cognitive_registry.go index ff257d7..d8e6d66 100644 --- a/modules/capability/domain/cognitive_registry.go +++ b/modules/capability/domain/cognitive_registry.go @@ -20,7 +20,7 @@ func BuildDiscoveryRegistration(snapshot capability.CognitiveDiscoverySnapshot) return capability.CognitiveDiscoveryRegistration{}, ErrInvalidCognitiveRegistryRecord } providerRevision := stableRevision(string(snapshot.ProviderKind), string(snapshot.EndpointRef), string(snapshot.CredentialRef), fmt.Sprint(snapshot.Enabled)) - provider := capability.ProviderInstance{ID: snapshot.ProviderInstanceID, Revision: providerRevision, Kind: snapshot.ProviderKind, EndpointRef: snapshot.EndpointRef, CredentialRef: snapshot.CredentialRef, Enabled: snapshot.Enabled, Qualification: capability.QualificationDiscovered, Health: capability.HealthUnknown, ObservedAtUnixMillis: snapshot.ObservedAtUnixMillis} + provider := capability.ProviderInstance{ID: snapshot.ProviderInstanceID, Revision: providerRevision, Kind: snapshot.ProviderKind, EndpointRef: snapshot.EndpointRef, CredentialRef: snapshot.CredentialRef, Enabled: snapshot.Enabled, Qualification: capability.QualificationDiscovered, Health: snapshot.Health, ObservedAtUnixMillis: snapshot.ObservedAtUnixMillis} registration := capability.CognitiveDiscoveryRegistration{Provider: provider, ProviderHealth: capability.ProviderHealthObservation{ProviderInstanceID: provider.ID, Health: snapshot.Health, ObservedAtUnixMillis: snapshot.ObservedAtUnixMillis, FailureClass: snapshot.FailureClass}} for _, discovered := range snapshot.Models { if discovered.ProviderModelID == "" || discovered.MaxContextBytes < 0 || len(discovered.Modalities) == 0 || len(discovered.Capabilities) == 0 || !validOperational(discovered.Installed) || !validOperational(discovered.Loaded) || !validOperational(discovered.Invokable) { @@ -28,10 +28,10 @@ func BuildDiscoveryRegistration(snapshot capability.CognitiveDiscoverySnapshot) } modelID := capability.ModelDescriptorID(stableID("model", string(snapshot.ProviderInstanceID), string(discovered.ProviderModelID))) modelRevision := stableRevision(string(discovered.Fingerprint), fmt.Sprint(discovered.MaxContextBytes), fmt.Sprint(discovered.Modalities), fmt.Sprint(discovered.Capabilities)) - model := capability.ModelDescriptor{ID: modelID, Revision: modelRevision, ProviderInstanceID: provider.ID, ProviderModelID: discovered.ProviderModelID, Fingerprint: discovered.Fingerprint, MaxContextBytes: discovered.MaxContextBytes, Modalities: append([]capability.ModelModality(nil), discovered.Modalities...), Capabilities: append([]capability.ModelCapability(nil), discovered.Capabilities...), Qualification: capability.QualificationDiscovered, Health: capability.HealthUnknown, ObservedAtUnixMillis: snapshot.ObservedAtUnixMillis} + model := capability.ModelDescriptor{ID: modelID, Revision: modelRevision, ProviderInstanceID: provider.ID, ProviderModelID: discovered.ProviderModelID, Fingerprint: discovered.Fingerprint, MaxContextBytes: discovered.MaxContextBytes, Modalities: append([]capability.ModelModality(nil), discovered.Modalities...), Capabilities: append([]capability.ModelCapability(nil), discovered.Capabilities...), Qualification: capability.QualificationDiscovered, Health: snapshot.Health, ObservedAtUnixMillis: snapshot.ObservedAtUnixMillis} bindingID := capability.CapabilityBindingID(stableID("binding", string(snapshot.OwnerPrincipalID), string(snapshot.CapabilityID), string(provider.ID), string(model.ID))) bindingRevision := stableRevision(fmt.Sprint(provider.Revision), fmt.Sprint(model.Revision), string(snapshot.DataPolicy), string(snapshot.LimitPolicyRef)) - binding := capability.CognitiveBinding{ID: bindingID, Revision: bindingRevision, CapabilityID: snapshot.CapabilityID, OwnerPrincipalID: snapshot.OwnerPrincipalID, ProviderInstanceID: provider.ID, ProviderRevision: provider.Revision, ModelDescriptorID: model.ID, ModelRevision: model.Revision, DataPolicy: snapshot.DataPolicy, Qualification: capability.QualificationDiscovered, Activation: capability.ActivationInactive, Health: capability.HealthUnknown, LimitPolicyRef: snapshot.LimitPolicyRef} + binding := capability.CognitiveBinding{ID: bindingID, Revision: bindingRevision, CapabilityID: snapshot.CapabilityID, OwnerPrincipalID: snapshot.OwnerPrincipalID, ProviderInstanceID: provider.ID, ProviderRevision: provider.Revision, ModelDescriptorID: model.ID, ModelRevision: model.Revision, DataPolicy: snapshot.DataPolicy, Qualification: capability.QualificationDiscovered, Activation: capability.ActivationInactive, Health: snapshot.Health, LimitPolicyRef: snapshot.LimitPolicyRef} registration.Models = append(registration.Models, model) registration.Bindings = append(registration.Bindings, binding) registration.ModelAvailability = append(registration.ModelAvailability, capability.ModelOperationalObservation{ProviderInstanceID: provider.ID, ModelDescriptorID: model.ID, Installed: discovered.Installed, Loaded: discovered.Loaded, Invokable: discovered.Invokable, Health: snapshot.Health, ObservedAtUnixMillis: snapshot.ObservedAtUnixMillis}) diff --git a/modules/capability/domain/cognitive_registry_test.go b/modules/capability/domain/cognitive_registry_test.go new file mode 100644 index 0000000..89d3a90 --- /dev/null +++ b/modules/capability/domain/cognitive_registry_test.go @@ -0,0 +1,40 @@ +package domain + +import ( + "testing" + + "git.cin.su/m/Assistant/contracts/capability" +) + +func TestBuildDiscoveryRegistrationCarriesObservedHealthToCanaryPrecondition(t *testing.T) { + registration, err := BuildDiscoveryRegistration(capability.CognitiveDiscoverySnapshot{ + ProviderInstanceID: "local-lifeboat", + ProviderKind: "openai-compatible-chat-v1", + EndpointRef: "local-lifeboat-v1", + OwnerPrincipalID: "domovoy-creator-principal", + CapabilityID: "creator-advisory", + DataPolicy: capability.DataPolicyLocalOnly, + LimitPolicyRef: "creator-advisory-local-v1", + Health: capability.HealthAvailable, + ObservedAtUnixMillis: 1000, + Models: []capability.DiscoveredModelSnapshot{{ + ProviderModelID: "domovoy-lifeboat", + Fingerprint: "fingerprint", + MaxContextBytes: 32768, + Modalities: []capability.ModelModality{capability.ModalityText}, + Capabilities: []capability.ModelCapability{capability.CapabilityAdvisory}, + Installed: capability.OperationalYes, + Loaded: capability.OperationalNotObserved, + Invokable: capability.OperationalYes, + }}, + }) + if err != nil { + t.Fatal(err) + } + if registration.Provider.Health != capability.HealthAvailable || len(registration.Models) != 1 || len(registration.Bindings) != 1 { + t.Fatalf("unexpected registration: %+v", registration) + } + if registration.Models[0].Health != capability.HealthAvailable || registration.Bindings[0].Health != capability.HealthAvailable { + t.Fatalf("discovery health was not carried into canary candidates: model=%s binding=%s", registration.Models[0].Health, registration.Bindings[0].Health) + } +}