shithub: oai

Download patch

ref: 0849b371cf6d2f129634195433fd43185e7de27d
parent: 1f68d6a68ba2b4512d963ea2815280cabe707f53
author: sirjofri <sirjofri@sirjofri.de>
date: Sun Feb 22 19:17:34 EST 2026

fixes requests after tool calls

--- a/oai.c
+++ b/oai.c
@@ -2,6 +2,7 @@
 #include <libc.h>
 #include <bio.h>
 #include <json.h>
+#include <String.h>
 #include "oai.h"
 
 static void
@@ -11,22 +12,48 @@
 	exits("usage");
 }
 
-OTool *tools;
+static char*
+list_files(OToolcall)
+{
+	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;
+}
 
+OTool *tools = nil;
+
 static void
 inittools(void)
 {
-	tools = maketool(nil, Function, "list_files", "list all files in the current directory", nil);
+	tools = maketool(tools, Function, "list_files", "list all files in the current directory, similar to `ls` on unix systems.", nil);
 }
 
 static char*
 toolcall(OToolcall tc)
 {
-	fprint(2, "toolcall!\n");
-	fprint(2, "  name: %s\n", tc.name);
-	fprint(2, "  args: %s\n", tc.arguments);
-	fprint(2, "  id:   %s\n", tc.id);
-	return strdup("a b c");
+	if (strcmp(tc.name, "list_files") == 0) {
+		return list_files(tc);
+	}
+	return strdup("");
 }
 
 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.";
@@ -98,13 +125,13 @@
 	if (!quiet) print("user: ");
 	while (s = Brdstr(bin, '\n', 1)) {
 		addstrprompt(&req, "user", s);
-		res = makerequest(req);
+		res = makerequest(&req);
 		if (!res.success) {
 			fprint(2, "exiting!\n");
 			exits("fail");
 		}
 		print("%s%s%s\n\n", res.role, (quiet ? "" : ": "), res.message);
-		addstrprompt(&req, res.role, "%s", res.message);
+		addprompt(&req, res.asprompt);
 		if (!quiet) print("user: ");
 	}
 	exits(nil);
--- a/oai.h
+++ b/oai.h
@@ -32,6 +32,7 @@
 	int success;
 	char *role;
 	char *message;
+	OPrompt *asprompt;
 };
 
 struct OTool {
@@ -59,7 +60,7 @@
 /*
  * makerequest to make the request.
  */
-OResult makerequest(ORequest);
+OResult makerequest(ORequest*);
 
 /*
  * create a new prompt object.
--- a/oailib.c
+++ b/oailib.c
@@ -11,6 +11,18 @@
 
 int oaidebug = 0;
 
+static JSON*
+copyjtree(JSON *in)
+{
+	JSON *out;
+	char *s;
+	
+	s = smprint("%J", in);
+	out = jsonparse(s);
+	free(s);
+	return out;
+}
+
 int
 initoai(char *url, char *key, OToolcallfn fn)
 {
@@ -68,7 +80,7 @@
 	}
 	el = el->next = mallocz(sizeof(JSONEl), 1);
 	el->name = p->jcname ? strdup(p->jcname) : strdup("content");
-	el->val = p->jcontent;
+	el->val = copyjtree(p->jcontent);
 	return top;
 }
 
@@ -386,6 +398,7 @@
 	OToolcall tc;
 	OResult res;
 	OPrompt *pr, *pres;
+	OPrompt *resprompt;
 	char *r;
 	
 	if (!toolcall)
@@ -403,6 +416,9 @@
 	pr->jcname = strdup("tool_calls");
 	addprompt(req, pr);
 	
+	resprompt = makeprompt("assistant");
+	resprompt->jcname = strdup("tool_calls");
+	
 	for (el = calls->first; el; el = el->next) {
 		tcparse(el->val, &tc);
 		r = toolcall(tc);
@@ -409,6 +425,7 @@
 		if (!r)
 			continue;
 		addtcprompt(pr, &tc);
+		addtcprompt(resprompt, &tc);
 		pres = makeprompt("tool");
 		pres->content = r;
 		pres->callid = strdup(tc.id);
@@ -415,12 +432,12 @@
 		addprompt(req, pres);
 	}
 	
-	res = makerequest(*req);
+	res = makerequest(req);
 	return res;
 }
 
 OResult
-makerequest(ORequest req)
+makerequest(ORequest *req)
 {
 	char buf[128];
 	int ctlfd, pbodyfd;
@@ -431,7 +448,7 @@
 	JSON *jreq;
 	JSON *jres;
 	
-	jreq = req2json(&req);
+	jreq = req2json(req);
 	
 	ctlfd = open("/mnt/web/clone", ORDWR);
 	if (ctlfd < 0)
@@ -480,7 +497,7 @@
 	case Ftoolcall:
 		ret.success = 0;
 		if (toolcall)
-			ret = calltool(jres, &req);
+			ret = calltool(jres, req);
 		return ret;
 	}
 	
@@ -490,6 +507,7 @@
 	jsonfree(jreq);
 	jsonfree(jres);
 	
+	ret.asprompt = nil;
 	return ret;
 }
 
@@ -524,6 +542,10 @@
 addprompt(ORequest *r, OPrompt *p)
 {
 	OPrompt *pr;
+	
+	if (!p)
+		return 1;
+	
 	p->next = nil;
 	if (!r->prompts) {
 		r->prompts = p;
--- a/ocomplete.c
+++ b/ocomplete.c
@@ -168,7 +168,7 @@
 	free(p1body);
 	free(selection);
 	
-	res = makerequest(req);
+	res = makerequest(&req);
 	if (!res.message)
 		sysfatal("invalid result");
 	
--