P5b and P5c plans: long-document retrieval (BM25 first, background embedding) and /v1/extract + sift extract; given tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 11:01:18 -07:00
co-authored by Claude Opus 5.5
parent 1311cf38d4
commit 49d96e197b
14 changed files with 1464 additions and 0 deletions
@@ -0,0 +1,46 @@
package main
// P5c task 02: `sift extract <file>` uploads a PDF to /v1/extract.
import (
"net/url"
"strings"
"testing"
)
func TestParseExtractOpts(t *testing.T) {
o, err := parseExtractOpts([]string{"thesis.pdf", "--pages", "41-60", "--grep", "attention head"})
if err != nil || o.File != "thesis.pdf" || o.Pages != "41-60" || o.Grep != "attention head" {
t.Errorf("%+v %v", o, err)
}
o, err = parseExtractOpts([]string{"--question", "what is the method?", "--json", "paper.pdf"})
if err != nil || o.File != "paper.pdf" || o.Question != "what is the method?" || !o.JSON {
t.Errorf("flags first: %+v %v", o, err)
}
if _, err := parseExtractOpts(nil); err == nil {
t.Error("no file: want an error")
}
if _, err := parseExtractOpts([]string{"a.pdf", "b.pdf"}); err == nil {
t.Error("two files: want an error")
}
if !strings.Contains(extractUsage, "sift extract <file.pdf>") {
t.Errorf("usage %q", extractUsage)
}
}
func TestExtractURL(t *testing.T) {
u, err := url.Parse(extractURL("https://sift.example:8443", extractOpts{File: "x.pdf", Pages: "2-3", Grep: "a b&c"}))
if err != nil {
t.Fatal(err)
}
if u.Path != "/v1/extract" || u.Query().Get("pages") != "2-3" || u.Query().Get("grep") != "a b&c" {
t.Errorf("url %s", u)
}
if u.Query().Has("question") || u.Query().Has("mode") {
t.Errorf("unset options must not be sent: %s", u)
}
u, _ = url.Parse(extractURL("https://sift.example:8443", extractOpts{File: "x.pdf", Question: "why?"}))
if u.Query().Get("question") != "why?" || u.Query().Get("mode") != "digest" {
t.Errorf("question url %s (mode must be digest with a question)", u)
}
}