code.oscarkilo.com/klex-git/api/funcs_test.go

..
api.go
datasets.go
embed.go
f.go
fake.go
fake_test.go
funcs.go
funcs_test.go
klex.go
messages.go
messages_test.go
pipelines.go
stream.go
worker.go
package api

// These tests pin the wire format of LLMFunc. CanSeeImages is the
// pre-existing capability flag (do not rename — production func
// definitions at oscarkilo.com/klex/funcs already use it).
// CanSeePDFs is the new capability flag for PDF attachments. The
// two are independent because some providers support images but
// not PDFs (Fireworks, Ollama, xAI-via-v1-of-our-adapter).

import "encoding/json"
import "strings"
import "testing"

func TestLLMFuncMarshalImagesPDFs(t *testing.T) {
  f := LLMFunc{
    Provider: "anthropic",
    Model: "claude-sonnet-4-6",
    CanSeeImages: true,
    CanSeePDFs: true,
    CanStream: true,
  }
  buf, err := json.Marshal(f)
  if err != nil {
    t.Fatalf("marshal: %v", err)
  }
  s := string(buf)
  if !strings.Contains(s, `"can_see_images":true`) {
    t.Errorf("missing can_see_images in %s", s)
  }
  if !strings.Contains(s, `"can_see_pdfs":true`) {
    t.Errorf("missing can_see_pdfs in %s", s)
  }
}

func TestLLMFuncUnmarshalLegacyData(t *testing.T) {
  // Existing production func versions are stored without a
  // can_see_pdfs key. They must unmarshal to CanSeePDFs=false
  // without error.
  in := []byte(
    `{"provider":"anthropic","model":"x","can_see_images":true}`)
  var f LLMFunc
  if err := json.Unmarshal(in, &f); err != nil {
    t.Fatalf("unmarshal: %v", err)
  }
  if !f.CanSeeImages {
    t.Errorf("CanSeeImages = false, want true")
  }
  if f.CanSeePDFs {
    t.Errorf("CanSeePDFs = true, want false (key absent)")
  }
}

func TestLLMFuncUnmarshalPDFsOnly(t *testing.T) {
  // A model that accepts PDFs but not images (rare but possible
  // if a future provider goes that way).
  in := []byte(
    `{"provider":"x","model":"y","can_see_pdfs":true}`)
  var f LLMFunc
  if err := json.Unmarshal(in, &f); err != nil {
    t.Fatalf("unmarshal: %v", err)
  }
  if f.CanSeeImages {
    t.Errorf("CanSeeImages = true, want false")
  }
  if !f.CanSeePDFs {
    t.Errorf("CanSeePDFs = false, want true")
  }
}

func TestLLMFuncUnmarshalBoth(t *testing.T) {
  in := []byte(
    `{"provider":"openai","model":"gpt-4o",` +
      `"can_see_images":true,"can_see_pdfs":true}`)
  var f LLMFunc
  if err := json.Unmarshal(in, &f); err != nil {
    t.Fatalf("unmarshal: %v", err)
  }
  if !f.CanSeeImages || !f.CanSeePDFs {
    t.Errorf("expected both flags true; got %+v", f)
  }
}

func TestLLMFuncUnmarshalNeither(t *testing.T) {
  in := []byte(`{"provider":"x","model":"y"}`)
  var f LLMFunc
  if err := json.Unmarshal(in, &f); err != nil {
    t.Fatalf("unmarshal: %v", err)
  }
  if f.CanSeeImages || f.CanSeePDFs {
    t.Errorf("expected both flags false; got %+v", f)
  }
}

func TestLLMFuncRoundTrip(t *testing.T) {
  orig := LLMFunc{
    Provider: "openai",
    Model: "gpt-4o",
    CanSeeImages: true,
    CanSeePDFs: true,
    CanUseTools: true,
    CanStream: true,
  }
  buf, err := json.Marshal(orig)
  if err != nil {
    t.Fatalf("marshal: %v", err)
  }
  var got LLMFunc
  if err := json.Unmarshal(buf, &got); err != nil {
    t.Fatalf("unmarshal: %v", err)
  }
  if got != orig {
    t.Errorf("round-trip diff\nwant: %+v\n got: %+v", orig, got)
  }
}