mirror of
https://github.com/lukaszraczylo/mcp-captcharesolver.git
synced 2026-10-13 00:48:34 +00:00
feat(llm): fake supports per-call response sequences
Add VisionResponses to Fake. Vision returns the element matching the call index (clamped to last beyond length), falling back to VisionResp when empty. Enables self-consistency voting tests.
This commit is contained in:
+14
-1
@@ -8,6 +8,7 @@ type Fake struct {
|
|||||||
TranscribeResp string
|
TranscribeResp string
|
||||||
VisionErr error
|
VisionErr error
|
||||||
TranscribeErr error
|
TranscribeErr error
|
||||||
|
VisionResponses []string
|
||||||
VisionCalls []VisionCall
|
VisionCalls []VisionCall
|
||||||
TranscribeCalls []TranscribeCall
|
TranscribeCalls []TranscribeCall
|
||||||
}
|
}
|
||||||
@@ -26,9 +27,21 @@ type TranscribeCall struct {
|
|||||||
Audio []byte
|
Audio []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vision implements Client.
|
// Vision implements Client. When VisionResponses is non-empty it returns the
|
||||||
|
// element matching the call index (clamped to the last for calls beyond the
|
||||||
|
// slice length); otherwise it falls back to VisionResp.
|
||||||
func (f *Fake) Vision(_ context.Context, prompt string, images []Image, opts Options) (string, error) {
|
func (f *Fake) Vision(_ context.Context, prompt string, images []Image, opts Options) (string, error) {
|
||||||
|
i := len(f.VisionCalls)
|
||||||
f.VisionCalls = append(f.VisionCalls, VisionCall{Prompt: prompt, Images: images, Opts: opts})
|
f.VisionCalls = append(f.VisionCalls, VisionCall{Prompt: prompt, Images: images, Opts: opts})
|
||||||
|
if f.VisionErr != nil {
|
||||||
|
return "", f.VisionErr
|
||||||
|
}
|
||||||
|
if len(f.VisionResponses) > 0 {
|
||||||
|
if i >= len(f.VisionResponses) {
|
||||||
|
i = len(f.VisionResponses) - 1
|
||||||
|
}
|
||||||
|
return f.VisionResponses[i], nil
|
||||||
|
}
|
||||||
return f.VisionResp, f.VisionErr
|
return f.VisionResp, f.VisionErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,3 +19,28 @@ func TestFakeClient(t *testing.T) {
|
|||||||
t.Fatalf("transcribe got %q err %v", tr, err)
|
t.Fatalf("transcribe got %q err %v", tr, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFakeVisionResponsesCycle(t *testing.T) {
|
||||||
|
f := &Fake{VisionResponses: []string{"a", "b", "c"}}
|
||||||
|
want := []string{"a", "b", "c", "c", "c"} // clamps to last beyond slice length
|
||||||
|
for i, w := range want {
|
||||||
|
got, err := f.Vision(context.Background(), "p", nil, Options{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("call %d err %v", i, err)
|
||||||
|
}
|
||||||
|
if got != w {
|
||||||
|
t.Fatalf("call %d got %q want %q", i, got, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(f.VisionCalls) != len(want) {
|
||||||
|
t.Fatalf("recorded %d calls, want %d", len(f.VisionCalls), len(want))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFakeVisionFallsBackToVisionResp(t *testing.T) {
|
||||||
|
f := &Fake{VisionResp: "single"}
|
||||||
|
got, err := f.Vision(context.Background(), "p", nil, Options{})
|
||||||
|
if err != nil || got != "single" {
|
||||||
|
t.Fatalf("got %q err %v, want single", got, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user