shithub: oai

Download patch

ref: 1559dbd7dbc128db9ad7c7f3a389cd38a978b6cc
parent: 0849b371cf6d2f129634195433fd43185e7de27d
author: sirjofri <sirjofri@sirjofri.de>
date: Tue Feb 24 13:55:54 EST 2026

refactors tool call into function pointers

--- a/oai.c
+++ b/oai.c
@@ -13,7 +13,7 @@
 }
 
 static char*
-list_files(OToolcall)
+list_files(OToolcall, void*)
 {
 	String *str;
 	int n, i, fd;
@@ -44,7 +44,7 @@
 static void
 inittools(void)
 {
-	tools = maketool(tools, Function, "list_files", "list all files in the current directory, similar to `ls` on unix systems.", nil);
+	tools = maketool(tools, Function, "list_files", "list all files in the current directory, similar to `ls` on unix systems.", nil, list_files, nil);
 }
 
 static char*
@@ -51,7 +51,7 @@
 toolcall(OToolcall tc)
 {
 	if (strcmp(tc.name, "list_files") == 0) {
-		return list_files(tc);
+		return list_files(tc, nil);
 	}
 	return strdup("");
 }
@@ -108,7 +108,7 @@
 		break;
 	}ARGEND;
 	
-	if (!initoai(url, key, toolcall))
+	if (!initoai(url, key))
 		usage();
 	
 	bin = Bfdopen(0, OREAD);
--- a/oai.h
+++ b/oai.h
@@ -4,7 +4,7 @@
 typedef struct OTool OTool;
 typedef struct OToolcall OToolcall;
 
-typedef char* (*OToolcallfn)(OToolcall);
+typedef char* (*OToolcallfn)(OToolcall,void*);
 
 typedef enum {
 	Function,
@@ -39,7 +39,9 @@
 	Tooltype type;
 	char *name;
 	char *description;
-	char *parameters;
+	JSON *parameters;
+	OToolcallfn func;
+	void *aux;
 	OTool *next;
 };
 
@@ -55,7 +57,7 @@
  * initoai returns 1 on success. If baseurl or apikey is nil, it'll try to fetch the data
  * from the environment variables $oaiurl and $oaikey. Key is optional.
  */
-int initoai(char *baseurl, char *apikey, char* (*f)(OToolcall));
+int initoai(char *baseurl, char *apikey);
 
 /*
  * makerequest to make the request.
@@ -83,4 +85,4 @@
 /*
  * append tool
  */
-OTool* maketool(OTool*, Tooltype, char *name, char *description, char *parameters);
+OTool* maketool(OTool*, Tooltype, char *name, char *description, char *parameters, char* (*f)(OToolcall, void*), void*);
--- a/oailib.c
+++ b/oailib.c
@@ -7,8 +7,6 @@
 static char *baseurl = nil;
 static char *apikey = nil;
 
-static OToolcallfn toolcall = nil;
-
 int oaidebug = 0;
 
 static JSON*
@@ -24,7 +22,7 @@
 }
 
 int
-initoai(char *url, char *key, OToolcallfn fn)
+initoai(char *url, char *key)
 {
 	if (!url)
 		url = getenv("oaiurl");
@@ -33,7 +31,6 @@
 		return 0;
 	}
 	baseurl = url;
-	toolcall = fn;
 	
 	if (!key)
 		key = getenv("oaikey");
@@ -109,8 +106,11 @@
 	el->val->t = JSONObject;
 	el->val->first = mkstrjson("name", t->name);
 	el->val->first->next = mkstrjson("description", t->description);
-	if (t->parameters)
-		el->val->first->next->next = mkstrjson("parameters", t->parameters);
+	if (!t->parameters)
+		return;
+	el = el->val->first->next->next = mallocz(sizeof(JSONEl), 1);
+	el->name = strdup("parameters");
+	el->val = copyjtree(t->parameters);
 }
 
 static void
@@ -297,6 +297,8 @@
 	j = jel->val = mallocz(sizeof(JSON), 1);
 	j->t = JSONObject;
 	jel = j->first = mkstrjson("name", tc->name);
+	if (!tc->arguments)
+		return;
 	jel = jel->next = mkstrjson("arguments", tc->arguments);
 	USED(jel);
 }
@@ -389,6 +391,16 @@
 	tc->arguments = strdup(jsonstr(args));
 }
 
+static OTool*
+findtool(ORequest *req, char *name)
+{
+	OTool *t;
+	for (t = req->tools; t; t = t->next)
+		if (strcmp(t->name, name) == 0)
+			return t;
+	return nil;
+}
+
 static OResult
 calltool(JSON *j, ORequest *req)
 {
@@ -395,6 +407,8 @@
 	JSON *first;
 	JSON *calls;
 	JSONEl *el;
+	OTool *tool;
+	OToolcallfn toolfn;
 	OToolcall tc;
 	OResult res;
 	OPrompt *pr, *pres;
@@ -401,9 +415,6 @@
 	OPrompt *resprompt;
 	char *r;
 	
-	if (!toolcall)
-		sysfatal("tool calls not supported by application!");
-	
 	first = getfirstchoice(j);
 	first = getmessage(first);
 	calls = jsonbyname(first, "tool_calls");
@@ -421,7 +432,17 @@
 	
 	for (el = calls->first; el; el = el->next) {
 		tcparse(el->val, &tc);
-		r = toolcall(tc);
+		tool = findtool(req, tc.name);
+		if (!tool) {
+			fprint(2, "missing tool: %s\n", tc.name);
+			continue;
+		}
+		toolfn = tool->func;
+		if (!toolfn) {
+			fprint(2, "tool %s has no func\n", tc.name);
+			continue;
+		}
+		r = toolfn(tc, tool->aux);
 		if (!r)
 			continue;
 		addtcprompt(pr, &tc);
@@ -496,8 +517,7 @@
 		break;
 	case Ftoolcall:
 		ret.success = 0;
-		if (toolcall)
-			ret = calltool(jres, req);
+		ret = calltool(jres, req);
 		return ret;
 	}
 	
@@ -672,7 +692,7 @@
 }
 
 OTool*
-maketool(OTool *tool, Tooltype type, char *name, char *description, char *parameters)
+maketool(OTool *tool, Tooltype type, char *name, char *description, char *parameters, char* (*f)(OToolcall,void*), void *aux)
 {
 	OTool *t, *n;
 	
@@ -683,7 +703,9 @@
 	t->name = strdup(name);
 	t->description = strdup(description);
 	if (parameters && parameters[0])
-		t->parameters = strdup(parameters);
+		t->parameters = jsonparse(parameters);
+	t->func = f;
+	t->aux = aux;
 	
 	if (!tool)
 		return t;
--- a/ocomplete.c
+++ b/ocomplete.c
@@ -92,7 +92,7 @@
 	
 	readfilename();
 	
-	if (!initoai(url, key, nil))
+	if (!initoai(url, key))
 		sysfatal("initoai: %r");
 	
 	/* get addr */
--