ref: d3de5ed8b865e4675dbe167e8b8b80fda9dfb6a9
dir: /oai.c/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <json.h>
#include <String.h>
#include "oai.h"
static void
usage(void)
{
fprint(2, "usage: %s [-dq] [-k apikey] [-m model] [-u baseurl] [-s sysprompt]\n", argv0);
exits("usage");
}
static int trusted = 0;
static int quiet = 0;
static int
allowed(OToolcall toolcall)
{
JSON *j;
char buf[3];
int n;
fprint(2, "Attempt to call command: %s\n", toolcall.name);
j = jsonparse(toolcall.arguments);
if (j) {
fprint(2, "%J\n", j);
jsonfree(j);
}
if (trusted)
return 1;
Again:
fprint(2, "Continue? (y/n) ");
n = read(0, buf, 3);
if (n < 0)
sysfatal("lost connection");
if (!n)
goto Again;
switch (buf[0]) {
case 'y':
return 1;
case 'n':
return 0;
}
goto Again;
}
static char*
abortcall(OToolcall tc)
{
return smprint("%s request aborted by user!", tc.name);
}
static char*
list_files(OToolcall tc, void*)
{
String *str;
int n, i, fd;
Dir *dirbuf;
char *s;
if (!allowed(tc))
return abortcall(tc);
fd = open(".", OREAD);
if (fd < 0)
return strdup("");
n = dirreadall(fd, &dirbuf);
close(fd);
if (n < 0)
return strdup("");
str = s_new();
for (i = 0; i < n; i++) {
str = s_append(str, dirbuf[i].name);
str = s_append(str, "\n");
}
s = strdup(s_to_c(str));
s_free(str);
return s;
}
static char*
read_file(OToolcall toolcall, void*)
{
JSON *j, *fj;
char *file;
Biobuf *io;
char *s;
if (!allowed(toolcall))
return abortcall(toolcall);
j = jsonparse(toolcall.arguments);
fj = jsonbyname(j, "file");
if (!fj) {
fprint(2, "no file in read_file request!\n");
return strdup("bad request in read_file!\n");
}
file = jsonstr(fj);
if (!(file && file[0])) {
fprint(2, "invalid file in read_file request!\n");
return strdup("bad request in read_file: no file!\n");
}
io = Bopen(file, OREAD);
if (!io) {
fprint(2, "open file: %r\n");
return smprint("open file in read_file: %r");
}
fprint(2, "read_file: %s\n", file);
s = Brdstr(io, 0, 0);
jsonfree(j);
Bterm(io);
return s;
}
static char *readfileargs = "{"
" \"type\": \"object\","
" \"properties\": {"
" \"file\": {"
" \"type\": \"string\""
" }"
" }"
"}";
OTool *tools = nil;
static void
inittools(void)
{
tools = maketool(tools, Function, "list_files", "list all files in the current directory, similar to `ls` on unix systems.", nil, list_files, nil);
maketool(tools, Function, "read_file", "read in a specific file, similar to the `cat` unix command.", readfileargs, read_file, nil);
}
char *plan9prompt = "You are a helpful AI assistant on a Plan 9 system. Your name is Glenda. Your tone is serious. Be friendly and concise.";
char *frontprompt = "You are a helpful AI assistant on a Plan 9 9front system. Your name is Glenda and Cirno is your best friend. You like to refer to manuals and you have a sense of humor. Be concise.";
void
main(int argc, char **argv)
{
Biobuf *bin;
char *s;
ORequest req;
OResult res;
char *sysprompt;
int bflag = 0;
char *url = nil;
char *key = nil;
req.model = nil;
if (!(access("/dist/9front", AEXIST) && access("/dist/plan9front", AEXIST))) {
/* 9front system */
sysprompt = frontprompt;
} else {
/* other plan 9 system */
sysprompt = plan9prompt;
}
ARGBEGIN{
case 'h':
usage();
case 'k':
key = EARGF(usage());
break;
case 'm':
req.model = EARGF(usage());
break;
case 'u':
url = EARGF(usage());
break;
case 's':
sysprompt = EARGF(usage());
break;
case '9':
sysprompt = plan9prompt;
break;
case 'q':
quiet++;
break;
case 'd':
oaidebug++;
break;
case 'b':
bflag++;
break;
}ARGEND;
if (bflag > 1)
trusted = 1;
if (!initoai(url, key))
usage();
bin = Bfdopen(0, OREAD);
assert(bin);
inittools();
req.prompts = nil;
req.tools = tools;
if (sysprompt)
addstrprompt(&req, "system", "%s", sysprompt);
if (!quiet) print("user: ");
while (s = Brdstr(bin, '\n', 1)) {
addstrprompt(&req, "user", s);
res = makerequest(&req);
if (!res.success) {
fprint(2, "exiting!\n");
exits("fail");
}
print("%s%s%s\n\n", res.role, (quiet ? "" : ": "), res.message);
addprompt(&req, res.asprompt);
if (!quiet) print("user: ");
}
exits(nil);
}