109 lines
3.7 KiB
Go
109 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.cin.su/m/Assistant/contracts/identity"
|
|
"git.cin.su/m/Assistant/contracts/interaction"
|
|
)
|
|
|
|
const tokenPath = "/run/secrets/acceptance_harness_service_token"
|
|
|
|
type client struct {
|
|
base string
|
|
token string
|
|
http *http.Client
|
|
}
|
|
|
|
func main() {
|
|
base := strings.TrimRight(os.Getenv("CORE_RUNTIME_URL"), "/")
|
|
if base == "" {
|
|
base = "http://core-runtime-candidate:8080"
|
|
}
|
|
token, err := os.ReadFile(tokenPath)
|
|
if err != nil {
|
|
fail("acceptance credential unavailable")
|
|
}
|
|
c := client{base: base, token: strings.TrimSpace(string(token)), http: &http.Client{Timeout: 90 * time.Second}}
|
|
if strings.TrimSpace(c.token) == "" {
|
|
fail("acceptance credential unavailable")
|
|
}
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
|
defer cancel()
|
|
var issued struct {
|
|
Token string
|
|
Session identity.CreatorSession
|
|
}
|
|
if err := c.post(ctx, "/v1/acceptance/sessions", nil, &issued); err != nil {
|
|
fail("acceptance authentication failed: " + err.Error())
|
|
}
|
|
if issued.Token == "" || issued.Session.PrincipalKind != identity.PrincipalKindService {
|
|
fail("acceptance principal was not authenticated as service")
|
|
}
|
|
c.token = issued.Token
|
|
var first interaction.ChatMessageResponse
|
|
if err := c.post(ctx, "/v1/creator/chat/messages", interaction.ChatMessageRequest{Message: "synthetic acceptance statement", CorrelationID: "acceptance-harness", SyntheticAcceptance: true, SyntheticScopeID: "synthetic-acceptance-scope"}, &first); err != nil {
|
|
fail("synthetic interaction failed: " + err.Error())
|
|
}
|
|
var corrected interaction.ChatMessageResponse
|
|
if err := c.post(ctx, "/v1/creator/chat/messages", interaction.ChatMessageRequest{ConversationID: first.ConversationID, Message: "synthetic acceptance correction", CorrelationID: "acceptance-harness-correction", CorrectsUtteranceID: first.UtteranceID, SyntheticAcceptance: true, SyntheticScopeID: "synthetic-acceptance-scope"}, &corrected); err != nil {
|
|
fail("synthetic correction failed: " + err.Error())
|
|
}
|
|
var summary struct {
|
|
LearningSignals int `json:"learning_signals"`
|
|
ImprovementNeeds int `json:"improvement_needs"`
|
|
LearningLedger int `json:"learning_ledger"`
|
|
}
|
|
if err := c.get(ctx, "/v1/acceptance/self/summary", &summary); err != nil {
|
|
fail("acceptance SELF summary unavailable: " + err.Error())
|
|
}
|
|
fmt.Printf("acceptance_pass learning_signals=%d improvement_needs=%d learning_ledger=%d\n", summary.LearningSignals, summary.ImprovementNeeds, summary.LearningLedger)
|
|
}
|
|
|
|
func (c client) post(ctx context.Context, path string, body any, out any) error {
|
|
return c.request(ctx, http.MethodPost, path, body, out)
|
|
}
|
|
func (c client) get(ctx context.Context, path string, out any) error {
|
|
return c.request(ctx, http.MethodGet, path, nil, out)
|
|
}
|
|
func (c client) request(ctx context.Context, method, path string, body any, out any) error {
|
|
var reader io.Reader
|
|
if body != nil {
|
|
data, err := json.Marshal(body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
reader = bytes.NewReader(data)
|
|
}
|
|
req, err := http.NewRequestWithContext(ctx, method, c.base+path, reader)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Set("Authorization", "Bearer "+c.token)
|
|
if body != nil {
|
|
req.Header.Set("Content-Type", "application/json")
|
|
}
|
|
resp, err := c.http.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
|
return fmt.Errorf("acceptance request denied with status %d", resp.StatusCode)
|
|
}
|
|
if out != nil && json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(out) != nil {
|
|
return errors.New("invalid acceptance response")
|
|
}
|
|
return nil
|
|
}
|
|
func fail(message string) { fmt.Fprintln(os.Stderr, message); os.Exit(1) }
|