187 lines
4.1 KiB
Lua
187 lines
4.1 KiB
Lua
local createAi = require('/apis/libai');
|
|
local createVersion = require('/apis/libversion');
|
|
|
|
local rawArgs = table.pack(...);
|
|
local args = { n = 0 };
|
|
local verbose = false;
|
|
|
|
for i = 1, rawArgs.n do
|
|
if rawArgs[i] == '--verbose' or rawArgs[i] == '-v' then
|
|
verbose = true;
|
|
else
|
|
args.n = args.n + 1;
|
|
args[args.n] = rawArgs[i];
|
|
end
|
|
end
|
|
|
|
local function printUsage()
|
|
print('ai usage:');
|
|
print();
|
|
print(' ai <prompt>');
|
|
print(' ai ping');
|
|
print(' ai new <prompt>');
|
|
print(' ai --new <prompt>');
|
|
print(' ai lua-exec <prompt>');
|
|
print(' ai --lua-exec <prompt>');
|
|
print(' ai sessions');
|
|
print(' ai --sessions');
|
|
print(' ai --verbose <command>');
|
|
print(' ai --version');
|
|
print(' ai --help');
|
|
print();
|
|
print('settings required:');
|
|
print(' opencc.server_url');
|
|
print();
|
|
print('settings optional:');
|
|
print(' opencc.username (default: opencode)');
|
|
print(' opencc.password (Basic Auth password)');
|
|
print(' opencc.session_id (auto-managed)');
|
|
print(' opencc.provider_id (e.g. anthropic)');
|
|
print(' opencc.model_id (e.g. claude-opus-4-7)');
|
|
print(' opencc.timeout_seconds (per HTTP call, max 60)');
|
|
print(' opencc.poll_timeout_seconds (default: 300)');
|
|
print(' opencc.poll_interval_seconds (default: 2)');
|
|
end
|
|
|
|
local function printAiLog(message)
|
|
print('[ai] ' .. tostring(message));
|
|
end
|
|
|
|
local function askOptions()
|
|
if verbose then
|
|
return { log = printAiLog };
|
|
end
|
|
return nil;
|
|
end
|
|
|
|
local function joinArgs(start)
|
|
local parts = {};
|
|
for i = start, args.n do
|
|
parts[#parts + 1] = args[i];
|
|
end
|
|
return table.concat(parts, ' ');
|
|
end
|
|
|
|
local function printSessions(ai)
|
|
local ok, result = ai.listSessions(askOptions());
|
|
if not ok then
|
|
print(result);
|
|
return;
|
|
end
|
|
if #result == 0 then
|
|
print('no sessions');
|
|
else
|
|
for _, s in ipairs(result) do
|
|
print((s.id or '?') .. ' ' .. (s.title or '(untitled)'));
|
|
end
|
|
end
|
|
end
|
|
|
|
local function askAndPrint(ai, prompt)
|
|
local ok, result = ai.ask(prompt, askOptions());
|
|
if not ok then
|
|
print(result);
|
|
return;
|
|
end
|
|
print(result.reply);
|
|
end
|
|
|
|
local function printLuaExecLog(message)
|
|
local text = tostring(message or '');
|
|
if text == '' then
|
|
print('[lua-exec]');
|
|
return;
|
|
end
|
|
|
|
local start = 1;
|
|
while start <= #text do
|
|
local newline = string.find(text, '\n', start, true);
|
|
if not newline then
|
|
print('[lua-exec] ' .. string.sub(text, start));
|
|
return;
|
|
end
|
|
print('[lua-exec] ' .. string.sub(text, start, newline - 1));
|
|
start = newline + 1;
|
|
end
|
|
end
|
|
|
|
local function luaExec(ai, prompt)
|
|
local ok, result = ai.luaExec(prompt, {
|
|
executor = ai.createLuaExecutor({ live = true }),
|
|
log = printLuaExecLog,
|
|
});
|
|
if not ok then
|
|
printLuaExecLog('failed after ' .. tostring(result.attempts or 0) .. ' attempt(s)');
|
|
if result.errorKind then
|
|
printLuaExecLog('error kind: ' .. tostring(result.errorKind));
|
|
end
|
|
printLuaExecLog(tostring(result.error));
|
|
return;
|
|
end
|
|
|
|
printLuaExecLog('final reply:');
|
|
print(result.reply);
|
|
end
|
|
|
|
local command = args[1];
|
|
|
|
if command == '--version' or command == '-version' or command == 'version' then
|
|
print('v' .. createVersion().forSelf());
|
|
return;
|
|
end
|
|
|
|
if command == '--help' or command == '-help' or command == 'help' then
|
|
printUsage();
|
|
return;
|
|
end
|
|
|
|
if args.n == 0 then
|
|
printUsage();
|
|
return;
|
|
end
|
|
|
|
local ai = createAi();
|
|
|
|
if (command == 'sessions' or command == '--sessions') and args.n == 1 then
|
|
printSessions(ai);
|
|
return;
|
|
end
|
|
|
|
if command == 'ping' and args.n == 1 then
|
|
local ok, result = ai.ping(askOptions());
|
|
if not ok then
|
|
print(result);
|
|
return;
|
|
end
|
|
print(result.reply);
|
|
return;
|
|
end
|
|
|
|
if command == 'new' or command == '--new' then
|
|
local prompt = joinArgs(2);
|
|
if prompt == '' then
|
|
printUsage();
|
|
return;
|
|
end
|
|
ai.clearSession();
|
|
askAndPrint(ai, prompt);
|
|
return;
|
|
end
|
|
|
|
if command == 'lua-exec' or command == '--lua-exec' then
|
|
local prompt = joinArgs(2);
|
|
if prompt == '' then
|
|
printUsage();
|
|
return;
|
|
end
|
|
luaExec(ai, prompt);
|
|
return;
|
|
end
|
|
|
|
if string.sub(command, 1, 1) == '-' then
|
|
printUsage();
|
|
return;
|
|
end
|
|
|
|
askAndPrint(ai, joinArgs(1));
|