mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-06-12 18:16:01 -04:00
agent: consolidate listModels logic into Agent.zig
This commit is contained in:
@@ -6,8 +6,8 @@ pub const CommandExecutor = @import("agent/CommandExecutor.zig");
|
||||
pub const Recorder = @import("agent/Recorder.zig");
|
||||
pub const Verifier = @import("agent/Verifier.zig");
|
||||
pub const SlashCommand = @import("agent/SlashCommand.zig");
|
||||
pub const listModels = @import("agent/list_models.zig").run;
|
||||
pub const autoDetectProvider = Agent.autoDetectProvider;
|
||||
pub const listModels = Agent.listModels;
|
||||
|
||||
test {
|
||||
_ = Agent;
|
||||
|
||||
@@ -959,6 +959,41 @@ fn resolveApiKey(provider: ?Config.AiProvider, needs_llm: bool) !?[:0]const u8 {
|
||||
return error.MissingApiKey;
|
||||
}
|
||||
|
||||
/// One-shot for `--list-models`: resolve the provider (explicit, then env
|
||||
/// auto-detect), reject `--no-llm`, fetch chat-capable model IDs from the
|
||||
/// provider, and print them to stdout (sorted, one per line). Shares
|
||||
/// provider-resolution logic with `init` so the two paths can't drift.
|
||||
pub fn listModels(allocator: std.mem.Allocator, opts: Config.Agent) !void {
|
||||
if (opts.no_llm) {
|
||||
log.fatal(.app, "list-models needs LLM", .{
|
||||
.hint = "--no-llm and --list-models conflict; drop --no-llm",
|
||||
});
|
||||
return error.ConflictingFlags;
|
||||
}
|
||||
const provider = opts.provider orelse (try autoDetectProvider()) orelse {
|
||||
log.fatal(.app, "list-models needs LLM", .{
|
||||
.hint = "set ANTHROPIC_API_KEY (or OPENAI_API_KEY / GOOGLE_API_KEY) or pass --provider",
|
||||
});
|
||||
return error.MissingProvider;
|
||||
};
|
||||
const api_key = zenai.provider.envApiKey(provider) orelse {
|
||||
log.fatal(.app, "missing API key", .{
|
||||
.provider = @tagName(provider),
|
||||
.env = envVarName(provider),
|
||||
});
|
||||
return error.MissingApiKey;
|
||||
};
|
||||
|
||||
var arena_state = std.heap.ArenaAllocator.init(allocator);
|
||||
defer arena_state.deinit();
|
||||
const ids = try zenai.provider.listChatModelIds(allocator, arena_state.allocator(), provider, api_key, opts.base_url);
|
||||
|
||||
var stdout_file = std.fs.File.stdout().writer(&.{});
|
||||
const w = &stdout_file.interface;
|
||||
for (ids) |id| try w.print("{s}\n", .{id});
|
||||
try w.flush();
|
||||
}
|
||||
|
||||
/// Pick a provider from env keys when `--provider` was not given.
|
||||
/// Notices go to stderr unconditionally so users always know which mode they're in.
|
||||
pub fn autoDetectProvider() !?Config.AiProvider {
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
const std = @import("std");
|
||||
const zenai = @import("zenai");
|
||||
const log = @import("../log.zig");
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ProviderKind = zenai.provider.ProviderKind;
|
||||
|
||||
/// List the chat-capable models for `provider` and print their IDs to stdout,
|
||||
/// one per line, sorted. The per-provider listing logic lives in
|
||||
/// `zenai.provider.listChatModelIds`.
|
||||
pub fn run(allocator: Allocator, provider: ProviderKind, base_url_override: ?[:0]const u8) !void {
|
||||
const api_key = zenai.provider.envApiKey(provider) orelse {
|
||||
log.fatal(.app, "missing API key", .{
|
||||
.provider = @tagName(provider),
|
||||
.env = switch (provider) {
|
||||
.anthropic => "ANTHROPIC_API_KEY",
|
||||
.openai => "OPENAI_API_KEY",
|
||||
.gemini => "GOOGLE_API_KEY or GEMINI_API_KEY",
|
||||
.ollama => "(none)",
|
||||
},
|
||||
});
|
||||
return error.MissingApiKey;
|
||||
};
|
||||
|
||||
var arena_state = std.heap.ArenaAllocator.init(allocator);
|
||||
defer arena_state.deinit();
|
||||
const ids = try zenai.provider.listChatModelIds(allocator, arena_state.allocator(), provider, api_key, base_url_override);
|
||||
|
||||
var stdout_file = std.fs.File.stdout().writer(&.{});
|
||||
const w = &stdout_file.interface;
|
||||
for (ids) |id| try w.print("{s}\n", .{id});
|
||||
try w.flush();
|
||||
}
|
||||
14
src/main.zig
14
src/main.zig
@@ -64,19 +64,7 @@ fn run(allocator: Allocator, main_arena: Allocator) !void {
|
||||
return std.process.cleanExit();
|
||||
},
|
||||
.agent => |opts| if (opts.list_models) {
|
||||
if (opts.no_llm) {
|
||||
log.fatal(.app, "list-models needs LLM", .{
|
||||
.hint = "--no-llm and --list-models conflict; drop --no-llm",
|
||||
});
|
||||
return args.printUsageAndExit(false);
|
||||
}
|
||||
const provider = opts.provider orelse (try lp.agent.autoDetectProvider()) orelse {
|
||||
log.fatal(.app, "list-models needs LLM", .{
|
||||
.hint = "set ANTHROPIC_API_KEY (or OPENAI_API_KEY / GOOGLE_API_KEY) or pass --provider",
|
||||
});
|
||||
return args.printUsageAndExit(false);
|
||||
};
|
||||
try lp.agent.listModels(allocator, provider, opts.base_url);
|
||||
try lp.agent.listModels(allocator, opts);
|
||||
return std.process.cleanExit();
|
||||
},
|
||||
else => {},
|
||||
|
||||
Reference in New Issue
Block a user