summaryrefslogtreecommitdiff
path: root/libpanto-go
diff options
context:
space:
mode:
authort <t@tjp.lol>2026-07-06 16:39:32 -0600
committert <t@tjp.lol>2026-07-07 10:44:20 -0600
commit0fa6d4209ff9b4a95e7d1955887aa4c73ee3423c (patch)
treebb07dc02986bd67f6564f85949ad2cd784363514 /libpanto-go
parent715fc34d833e043e9919fcce503ce3ec7cae5aea (diff)
expose openai_responses API style to C and Go bindings
Diffstat (limited to 'libpanto-go')
-rw-r--r--libpanto-go/panto.go40
-rw-r--r--libpanto-go/panto_test.go30
2 files changed, 67 insertions, 3 deletions
diff --git a/libpanto-go/panto.go b/libpanto-go/panto.go
index 35bc5fa..30caaca 100644
--- a/libpanto-go/panto.go
+++ b/libpanto-go/panto.go
@@ -57,8 +57,10 @@ type (
// drift from the ABI: if a variant is inserted in panto.h, the values shift
// with it instead of desyncing. Keep one Go constant per C value.
const (
- OpenAIChat APIStyle = APIStyle(C.PANTO_OPENAI_CHAT)
- AnthropicMessages APIStyle = APIStyle(C.PANTO_ANTHROPIC_MESSAGES)
+ OpenAIChat APIStyle = APIStyle(C.PANTO_OPENAI_CHAT)
+ AnthropicMessages APIStyle = APIStyle(C.PANTO_ANTHROPIC_MESSAGES)
+ OpenAIResponses APIStyle = APIStyle(C.PANTO_OPENAI_RESPONSES)
+ OpenAICodexResponses APIStyle = APIStyle(C.PANTO_OPENAI_CODEX_RESPONSES)
)
const (
@@ -126,12 +128,18 @@ type Config struct {
type ProviderConfig struct {
OpenAIChat *OpenAIChatConfig
AnthropicMessages *AnthropicMessagesConfig
+ OpenAIResponses *OpenAIResponsesConfig
}
type OpenAIChatConfig struct {
APIKey, BaseURL, Model string
Reasoning ReasoningEffort
MaxTokens uint32
}
+type OpenAIResponsesConfig struct {
+ APIKey, BaseURL, Model string
+ Reasoning ReasoningEffort
+ MaxTokens uint32
+}
type AnthropicMessagesConfig struct {
APIKey, BaseURL, Model, APIVersion string
MaxTokens uint32
@@ -1106,7 +1114,17 @@ func (cfg Config) c() (C.PantoConfig, cStrings, error) {
func (p ProviderConfig) c() (C.PantoProviderConfig, cStrings, error) {
var out C.PantoProviderConfig
var cs cStrings
- if p.OpenAIChat != nil == (p.AnthropicMessages != nil) {
+ n := 0
+ if p.OpenAIChat != nil {
+ n++
+ }
+ if p.AnthropicMessages != nil {
+ n++
+ }
+ if p.OpenAIResponses != nil {
+ n++
+ }
+ if n != 1 {
return out, nil, errors.New("exactly one provider config must be set")
}
if p.OpenAIChat != nil {
@@ -1114,6 +1132,11 @@ func (p ProviderConfig) c() (C.PantoProviderConfig, cStrings, error) {
setOpenAI(&out, p.OpenAIChat, &cs)
return out, cs, nil
}
+ if p.OpenAIResponses != nil {
+ out.tag = C.PANTO_OPENAI_RESPONSES
+ setOpenAIResponses(&out, p.OpenAIResponses, &cs)
+ return out, cs, nil
+ }
out.tag = C.PANTO_ANTHROPIC_MESSAGES
setAnthropic(&out, p.AnthropicMessages, &cs)
return out, cs, nil
@@ -1130,6 +1153,17 @@ func setOpenAI(out *C.PantoProviderConfig, cfg *OpenAIChatConfig, cs *cStrings)
c.max_tokens = C.uint32_t(cfg.MaxTokens)
}
+func setOpenAIResponses(out *C.PantoProviderConfig, cfg *OpenAIResponsesConfig, cs *cStrings) {
+ apiKey, baseURL, model := C.CString(cfg.APIKey), C.CString(cfg.BaseURL), C.CString(cfg.Model)
+ *cs = append(*cs, apiKey, baseURL, model)
+ c := (*C.PantoOpenAIResponsesConfig)(unsafe.Pointer(&out.data[0]))
+ c.api_key = apiKey
+ c.base_url = baseURL
+ c.model = model
+ c.reasoning = C.PantoReasoningEffort(cfg.Reasoning)
+ c.max_tokens = C.uint32_t(cfg.MaxTokens)
+}
+
func setAnthropic(out *C.PantoProviderConfig, cfg *AnthropicMessagesConfig, cs *cStrings) {
apiKey, baseURL, model, ver := C.CString(cfg.APIKey), C.CString(cfg.BaseURL), C.CString(cfg.Model), C.CString(cfg.APIVersion)
*cs = append(*cs, apiKey, baseURL, model, ver)
diff --git a/libpanto-go/panto_test.go b/libpanto-go/panto_test.go
index af8cafc..1270ead 100644
--- a/libpanto-go/panto_test.go
+++ b/libpanto-go/panto_test.go
@@ -164,6 +164,36 @@ func testConfig() Config {
}
}
+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()