diff options
| author | t <t@tjp.lol> | 2026-07-07 11:29:23 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-07-07 12:15:28 -0600 |
| commit | 621d7fee0ace729f8d44126032d2c6e13f72ee7f (patch) | |
| tree | a2938b0a9e5c0930e8644721abbe94875df9ff08 /libpanto-go/panto_test.go | |
| parent | 0fa6d4209ff9b4a95e7d1955887aa4c73ee3423c (diff) | |
Remove the in-repo libpanto sources and binding projects from pantograph.
Consume libpantograph through the Zig package URL at
code.tjp.lol/libpantograph.git, including the Lua module artifact used by
CLI extensions.
Diffstat (limited to 'libpanto-go/panto_test.go')
| -rw-r--r-- | libpanto-go/panto_test.go | 213 |
1 files changed, 0 insertions, 213 deletions
diff --git a/libpanto-go/panto_test.go b/libpanto-go/panto_test.go deleted file mode 100644 index 1270ead..0000000 --- a/libpanto-go/panto_test.go +++ /dev/null @@ -1,213 +0,0 @@ -package panto - -import "testing" - -// memStore is a minimal custom SessionStore that mints its sessions via -// NewSession (gap #1) rather than dispatching back into the vtable. -type memStore struct { - self *GoSessionStore - created bool -} - -func (m *memStore) Create() (*Session, error) { - m.created = true - return NewSession(m.self, SessionInfo{ID: "sess-1"}) -} -func (m *memStore) List() ([]SessionInfo, error) { return nil, nil } -func (m *memStore) Resolve(id string) (*Session, bool, error) { - if id != "sess-1" { - return nil, false, nil - } - s, err := NewSession(m.self, SessionInfo{ID: id}) - return s, err == nil, err -} -func (m *memStore) Latest() (*Session, bool, error) { return m.Resolve("sess-1") } -func (m *memStore) Load(id string) (*Conversation, bool, error) { return nil, false, nil } -func (m *memStore) AppendMessages(string, []PersistentMessage) error { - return nil -} - -// Gap #1: a Go store can mint and return a *Session from its own Create() -// without recursing back into the vtable. -func TestCustomStoreMintsSession(t *testing.T) { - Init() - defer Deinit() - - impl := &memStore{} - gss, err := NewGoSessionStore(impl) - if err != nil { - t.Fatalf("NewGoSessionStore: %v", err) - } - defer gss.Close() - impl.self = gss - - sess, err := gss.Create() - if err != nil { - t.Fatalf("Create: %v", err) - } - if sess == nil || sess.ptr == nil { - t.Fatal("Create returned nil session") - } - if !impl.created { - t.Fatal("custom Create() was not invoked") - } - - got, ok, err := gss.Resolve("sess-1") - if err != nil || !ok || got == nil { - t.Fatalf("Resolve: got=%v ok=%v err=%v", got, ok, err) - } -} - -// Gap #3: rebuild a conversation containing tool_use / tool_result / thinking -// via the value-block API, then read the blocks back losslessly. -func TestMessageBuilderRoundTrip(t *testing.T) { - Init() - defer Deinit() - - conv, err := NewConversation() - if err != nil { - t.Fatalf("NewConversation: %v", err) - } - defer conv.Close() - - if err := conv.AddMessage(UserMessage( - ToolResultBlock("call-1", "result text", false), - )); err != nil { - t.Fatalf("AddMessage(user): %v", err) - } - - if err := conv.AddMessage(AssistantMessage(&Usage{Input: 10, Output: 5}, - TextBlock("let me search"), - ThinkingBlock("hmm", "sig", AnthropicMessages, "https://api", "claude"), - ToolUseBlock("call-1", "search", `{"q":1}`), - )); err != nil { - t.Fatalf("AddMessage(assistant): %v", err) - } - - if got := conv.MessageCount(); got != 2 { - t.Fatalf("MessageCount = %d, want 2", got) - } - - user := conv.Message(0).Snapshot() - if user.Role != RoleUser || len(user.Content) != 1 { - t.Fatalf("user message: role=%v blocks=%d", user.Role, len(user.Content)) - } - if tr := user.Content[0]; tr.Tag != BlockToolResult || tr.ToolID != "call-1" || tr.Text != "result text" || tr.IsError { - t.Fatalf("tool_result block: %+v", tr) - } - - asst := conv.Message(1).Snapshot() - if asst.Role != RoleAssistant || len(asst.Content) != 3 { - t.Fatalf("assistant message: role=%v blocks=%d", asst.Role, len(asst.Content)) - } - if b := asst.Content[0]; b.Tag != BlockText || b.Text != "let me search" { - t.Fatalf("text block: %+v", b) - } - if b := asst.Content[1]; b.Tag != BlockThinking || b.Text != "hmm" { - t.Fatalf("thinking block: %+v", b) - } - if b := asst.Content[2]; b.Tag != BlockToolUse || b.ToolID != "call-1" || b.ToolName != "search" || b.Text != `{"q":1}` { - t.Fatalf("tool_use block: %+v", b) - } - if asst.Usage == nil || asst.Usage.Input != 10 || asst.Usage.Output != 5 { - t.Fatalf("assistant usage: %+v", asst.Usage) - } -} - -// TestMessageBuilderSetIdentity rebuilds a message with a per-message wire -// identity (and no per-block thinking origin), the resumption path that lets -// callers avoid copying the identity onto every thinking block. -func TestMessageBuilderSetIdentity(t *testing.T) { - Init() - defer Deinit() - - conv, err := NewConversation() - if err != nil { - t.Fatalf("NewConversation: %v", err) - } - defer conv.Close() - - // Thinking block with a signature but NO per-block origin; provenance is - // carried at the message level instead, via WithIdentity. - msg := AssistantMessage(&Usage{Input: 10, Output: 5}, - ThinkingBlock("reasoned", "sig", OpenAIChat, "", ""), - TextBlock("answer"), - ).WithIdentity(MessageIdentity{ - APIStyle: AnthropicMessages, - BaseURL: "https://api.anthropic.com", - Model: "claude", - Reasoning: ReasoningDefault, - }) - if err := conv.AddMessage(msg); err != nil { - t.Fatalf("AddMessage: %v", err) - } - - asst := conv.Message(0).Snapshot() - if asst.Role != RoleAssistant || len(asst.Content) != 2 { - t.Fatalf("assistant message: role=%v blocks=%d", asst.Role, len(asst.Content)) - } - if b := asst.Content[0]; b.Tag != BlockThinking || b.Text != "reasoned" { - t.Fatalf("thinking block: %+v", b) - } -} - -func testConfig() Config { - return Config{ - Provider: ProviderConfig{ - OpenAIChat: &OpenAIChatConfig{ - APIKey: "test-key", - BaseURL: "http://localhost", - Model: "test-model", - MaxTokens: 16, - }, - }, - } -} - -func TestOpenAIResponsesProviderConfigPassesThrough(t *testing.T) { - provider := ProviderConfig{ - OpenAIResponses: &OpenAIResponsesConfig{ - APIKey: "test-key", - BaseURL: "http://localhost", - Model: "test-model", - Reasoning: ReasoningMedium, - MaxTokens: 128, - }, - } - c, strings, err := provider.c() - if err != nil { - t.Fatalf("ProviderConfig.c: %v", err) - } - defer strings.free() - - if APIStyle(c.tag) != OpenAIResponses { - t.Fatalf("tag = %v, want %v", APIStyle(c.tag), OpenAIResponses) - } - - Init() - defer Deinit() - - a, err := NewAgent(Config{Provider: provider}) - if err != nil { - t.Fatalf("NewAgent: %v", err) - } - defer a.Close() -} - -func TestNewAgentSetSystemPromptDoesNotCrash(t *testing.T) { - Init() - defer Deinit() - - a, err := NewAgent(testConfig()) - if err != nil { - t.Fatalf("NewAgent: %v", err) - } - defer a.Close() - - if err := a.SetSystemPrompt("be brief"); err != nil { - t.Fatalf("SetSystemPrompt: %v", err) - } - if err := a.AddSystemMessage("also be accurate"); err != nil { - t.Fatalf("AddSystemMessage: %v", err) - } -} |
