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 */
--
⑨