Files
2026-08-17 21:49:12 +03:00

137 lines
4.3 KiB
Go

package main
import (
"context"
"encoding/json"
"errors"
"flag"
"fmt"
"os"
"time"
"git.cin.su/m/Assistant/adapters/models"
"git.cin.su/m/Assistant/contracts/capability"
"git.cin.su/m/Assistant/contracts/cognitive"
realityevaluation "git.cin.su/m/Assistant/tests/reality_evaluation"
)
type manifest struct {
ArtifactID string `json:"artifact_id"`
Providers []providerCandidate `json:"providers"`
}
type providerCandidate struct {
ProviderInstanceID string `json:"provider_instance_id"`
ProviderKind string `json:"provider_kind"`
Endpoint string `json:"endpoint"`
Candidates []modelCandidate `json:"candidates"`
}
type modelCandidate struct {
ProviderModelID string `json:"provider_model_id"`
ModelDescriptorID string `json:"model_descriptor_id"`
ModelRevision int64 `json:"model_revision"`
BindingID string `json:"binding_id"`
BindingRevision int64 `json:"binding_revision"`
}
func main() {
manifestPath := flag.String("manifest", "", "benchmark manifest JSON")
suitePath := flag.String("suite", "", "cognitive evaluation suite JSON")
outputPath := flag.String("output", "", "output artifact JSON")
observedAt := flag.String("observed-at", "2026-08-17T12:00:00Z", "RFC3339 timestamp for reproducible artifact generation")
timeout := flag.Duration("case-timeout", 30*time.Second, "deadline for each case")
flag.Parse()
if *manifestPath == "" || *suitePath == "" || *outputPath == "" || *timeout <= 0 {
fatal(errors.New("manifest, suite, output and positive case-timeout are required"))
}
at, err := time.Parse(time.RFC3339, *observedAt)
if err != nil {
fatal(err)
}
input, err := os.ReadFile(*manifestPath)
if err != nil {
fatal(err)
}
var plan manifest
if err := json.Unmarshal(input, &plan); err != nil {
fatal(err)
}
if len(plan.Providers) == 0 || len(plan.Providers[0].Candidates) == 0 {
fatal(errors.New("manifest has no candidates"))
}
suite, err := realityevaluation.LoadCognitiveSuite(*suitePath)
if err != nil {
fatal(err)
}
provider := plan.Providers[0]
candidate := provider.Candidates[0]
adapter, err := newProvider(provider)
if err != nil {
fatal(err)
}
responses := map[string]string{}
for index, item := range suite.Cases {
caseCtx, cancel := context.WithTimeout(context.Background(), *timeout)
response, err := adapter.Advise(caseCtx, cognitive.AdvisoryRequest{
Version: cognitive.CreatorAdvisoryV1,
RequestID: cognitive.RequestID(fmt.Sprintf("cognitive-eval-%d", index)),
ActorID: "benchmark-actor",
PrincipalID: "domovoy-creator-principal",
ScopeID: "benchmark-public-synthetic",
Message: item.Prompt,
Locale: "ru-RU",
MaxOutputBytes: 4096,
ProviderBindingID: capability.CapabilityBindingID(candidate.BindingID),
ProviderBindingRevision: candidate.BindingRevision,
ProviderInstanceID: capability.ProviderInstanceID(provider.ProviderInstanceID),
ModelDescriptorID: capability.ModelDescriptorID(candidate.ModelDescriptorID),
ProviderModelID: capability.ProviderModelID(candidate.ProviderModelID),
})
cancel()
if err != nil {
responses[item.ID] = "ADAPTER_ERROR: " + err.Error()
continue
}
responses[item.ID] = response.AdvisoryText
}
artifact, err := realityevaluation.EvaluateCognitiveSuite(
suite,
provider.ProviderInstanceID,
candidate.ProviderModelID,
candidate.ModelDescriptorID,
candidate.BindingID,
candidate.BindingRevision,
responses,
at,
)
if err != nil {
fatal(err)
}
payload, err := json.MarshalIndent(artifact, "", " ")
if err != nil {
fatal(err)
}
payload = append(payload, '\n')
if err := os.WriteFile(*outputPath, payload, 0o600); err != nil {
fatal(err)
}
fmt.Printf("artifact=%s total_cases=%d output=%s\n", artifact.ArtifactID, artifact.TotalCases, *outputPath)
}
func newProvider(candidate providerCandidate) (models.LocalProvider, error) {
switch candidate.ProviderKind {
case "openai-compatible-chat-v1":
return models.NewOpenAICompatibleLocalAdapter(candidate.Endpoint, nil)
case "ollama-v1":
return models.NewOllamaAdapter(candidate.Endpoint, nil)
default:
return nil, fmt.Errorf("unsupported provider kind %q", candidate.ProviderKind)
}
}
func fatal(err error) {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}