shithub: oai

ref: 584040ed6f329d180f03c374474fb9dc321e88e3
dir: /oai.c/

View raw version
#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 char*
list_files(OToolcall, void*)
{
	String *str;
	int n, i, fd;
	Dir *dirbuf;
	char *s;
	
	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*)
{
	fprint(2, "toolcall: %s\n", toolcall.name);
	fprint(2, " args: %s\n", toolcall.arguments);
	return strdup("not implemented yet");
}

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;
	int quiet = 0;
	ORequest req;
	OResult res;
	char *sysprompt;
	
	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;
	}ARGEND;
	
	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);
}