package integration_test import ( "context" "encoding/json" "fmt" "gitea.maximumdirect.net/eric/notarius/internal/framework/contracts" "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared" ) type extractionResponse struct { SpellCasts []spellCastResponse `json:"spell_casts"` } type spellCastResponse struct { Caster string `json:"caster"` Spell string `json:"spell"` Effect string `json:"effect"` NarrativeDescription string `json:"narrative_description"` SourceRefs []shared.SourceRefResponse `json:"source_refs"` } type fakeSpellsLLMClient struct { response extractionResponse requests []contracts.StructuredCompletionRequest } func (client *fakeSpellsLLMClient) CompleteStructured(_ context.Context, req contracts.StructuredCompletionRequest, out any) (contracts.StructuredCompletionResponse, error) { client.requests = append(client.requests, cloneStructuredCompletionRequest(req)) content, err := json.Marshal(client.response) if err != nil { return contracts.StructuredCompletionResponse{}, err } if err := json.Unmarshal(content, out); err != nil { return contracts.StructuredCompletionResponse{}, fmt.Errorf("populate structured target: %w", err) } return contracts.StructuredCompletionResponse{Content: content}, nil } func responseSourceRefs(sourceID string, startUnitID int, endUnitID int) []shared.SourceRefResponse { return []shared.SourceRefResponse{ { SourceID: sourceID, StartUnitID: shared.UnitRefFromInt(startUnitID), EndUnitID: shared.UnitRefFromInt(endUnitID), }, } } func cloneStructuredCompletionRequest(req contracts.StructuredCompletionRequest) contracts.StructuredCompletionRequest { req.Inputs = req.Inputs.Clone() if len(req.Vars) == 0 { req.Vars = nil return req } vars := make(map[string]any, len(req.Vars)) for key, value := range req.Vars { vars[key] = value } req.Vars = vars return req }