From f026bb81ae68f516910d0eb4f23c9344dd36b62b Mon Sep 17 00:00:00 2001 From: T Date: Mon, 25 May 2026 21:50:43 -0600 Subject: phase 2 done --- libpanto/src/config.zig | 66 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 16 deletions(-) (limited to 'libpanto/src/config.zig') diff --git a/libpanto/src/config.zig b/libpanto/src/config.zig index 74bdcc7..e395230 100644 --- a/libpanto/src/config.zig +++ b/libpanto/src/config.zig @@ -1,5 +1,14 @@ +//! Per-provider configuration. +//! +//! `Config` is a tagged union keyed by `APIStyle`. Each variant carries the +//! settings specific to one wire dialect. New providers add a new tag and a +//! new payload struct here; nothing else in libpanto needs a central enum +//! refresh. + +/// The wire dialect a provider speaks. pub const APIStyle = enum { openai_chat, + anthropic_messages, }; /// Reasoning intensity hint sent to providers that support it. @@ -17,37 +26,62 @@ pub const ReasoningEffort = enum { high, }; -pub const Config = struct { - api_style: APIStyle, +pub const OpenAIChatConfig = struct { api_key: []const u8, base_url: []const u8, model: []const u8, reasoning: ReasoningEffort = .default, }; +pub const AnthropicMessagesConfig = struct { + api_key: []const u8, + base_url: []const u8, + model: []const u8, + /// Value sent in the `anthropic-version` header. + api_version: []const u8 = "2023-06-01", + /// Required by Anthropic's Messages API. + max_tokens: u32 = 4096, +}; + +pub const Config = union(APIStyle) { + openai_chat: OpenAIChatConfig, + anthropic_messages: AnthropicMessagesConfig, + + pub fn style(self: Config) APIStyle { + return @as(APIStyle, self); + } +}; + const t = @import("std").testing; -test "Config - construct with all fields" { - const cfg = Config{ - .api_style = .openai_chat, +test "Config - openai_chat variant" { + const cfg: Config = .{ .openai_chat = .{ .api_key = "sk-test", .base_url = "https://api.openai.com/v1", .model = "gpt-4o", .reasoning = .high, - }; - try t.expectEqual(APIStyle.openai_chat, cfg.api_style); - try t.expectEqualStrings("sk-test", cfg.api_key); - try t.expectEqualStrings("https://api.openai.com/v1", cfg.base_url); - try t.expectEqualStrings("gpt-4o", cfg.model); - try t.expectEqual(ReasoningEffort.high, cfg.reasoning); + } }; + try t.expectEqual(APIStyle.openai_chat, cfg.style()); + try t.expectEqualStrings("sk-test", cfg.openai_chat.api_key); + try t.expectEqual(ReasoningEffort.high, cfg.openai_chat.reasoning); +} + +test "Config - anthropic_messages variant" { + const cfg: Config = .{ .anthropic_messages = .{ + .api_key = "sk-ant-test", + .base_url = "https://api.anthropic.com", + .model = "claude-sonnet-4-20250514", + } }; + try t.expectEqual(APIStyle.anthropic_messages, cfg.style()); + try t.expectEqualStrings("2023-06-01", cfg.anthropic_messages.api_version); + try t.expectEqual(@as(u32, 4096), cfg.anthropic_messages.max_tokens); } -test "Config - reasoning defaults to .default" { - const cfg = Config{ - .api_style = .openai_chat, +test "Config - openai_chat reasoning defaults to .default" { + const cfg: Config = .{ .openai_chat = .{ .api_key = "k", .base_url = "u", .model = "m", - }; - try t.expectEqual(ReasoningEffort.default, cfg.reasoning); + } }; + try t.expectEqual(ReasoningEffort.default, cfg.openai_chat.reasoning); } -- cgit v1.3