summaryrefslogtreecommitdiff
path: root/libpanto/src/config.zig
diff options
context:
space:
mode:
authorT <t@tjp.lol>2026-05-25 21:50:43 -0600
committerT <t@tjp.lol>2026-05-25 22:19:44 -0600
commitf026bb81ae68f516910d0eb4f23c9344dd36b62b (patch)
treee091d1a870cc75dc92e6cee785ee78ff4d6f088f /libpanto/src/config.zig
parentdf2edee86eec2a8deb0ad57b5d20552199c12b65 (diff)
phase 2 done
Diffstat (limited to 'libpanto/src/config.zig')
-rw-r--r--libpanto/src/config.zig66
1 files changed, 50 insertions, 16 deletions
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);
}