shithub: oai

Download patch

ref: 09836b88b3d499cc89fa7d22e8ff4bf4b5913cac
parent: 2385eae8d4de265c433778aa11f3fef391aaf62b
author: sirjofri <sirjofri@sirjofri.de>
date: Sat Feb 28 09:58:10 EST 2026

adds summarize tool

future: the summaries should be saved somewhere, for future retrieval.

--- a/oai.c
+++ b/oai.c
@@ -12,6 +12,10 @@
 	exits("usage");
 }
 
+static ORequest req;
+static char *sysprompt = nil;
+static int reprompt = 0;
+
 static int quiet = 0;
 static int vibemode = 0;
 static int yolomode = 0;
@@ -81,11 +85,29 @@
 	return cs;
 }
 
+static void
+resetprompts(void)
+{
+	OPrompt *p, *q;
+	
+	for (p = req.prompts; p; p = q) {
+		q = p->next;
+		if (p->role) free(p->role);
+		if (p->content) free(p->content);
+		if (p->jcname) free(p->jcname);
+		if (p->jcontent) jsonfree(p->jcontent);
+		if (p->callid) free(p->callid);
+		free(p);
+	}
+	req.prompts = nil;
+}
+
 #include "tools/listfiles.cinc"
 #include "tools/readfile.cinc"
 #include "tools/man.cinc"
 #include "tools/writefile.cinc"
 #include "tools/cmd.cinc"
+#include "tools/summarize.cinc"
 
 OTool *tools = nil;
 
@@ -98,6 +120,7 @@
 	maketool(tools, Function, "read_man", mandesc, manargs, man, nil);
 	maketool(tools, Function, "write_file", writefiledesc, writefileargs, writefile, nil);
 	maketool(tools, Function, "run_command", cmddesc, cmdargs, cmd, nil);
+	maketool(tools, Function, "summarize", sumdesc, sumargs, summarize, nil);
 }
 
 static char*
@@ -231,9 +254,7 @@
 {
 	Biobuf *bin;
 	char *s;
-	ORequest req;
 	OResult res;
-	char *sysprompt;
 	
 	char *url = nil;
 	char *key = nil;
@@ -317,6 +338,11 @@
 		res = makerequest(&req);
 		printusage(&res);
 		if (!res.success) {
+			if (reprompt) {
+				fprint(2, "start with new prompts\n");
+				reprompt = 0;
+				goto Next;
+			}
 			fprint(2, "ERROR: %r\n");
 			switch (ask(bin, "Try again (y/n)?", "yn")) {
 			default:
@@ -334,6 +360,7 @@
 		print("%s\n\n", res.message);
 		addprompt(&req, res.asprompt);
 Next:
+		free(s);
 		if (!quiet) print("user: ");
 	}
 	exits(nil);
--- a/oai_common.prompt
+++ b/oai_common.prompt
@@ -1,8 +1,11 @@
 You are an autonomous agent on a Plan 9 system. Your name is Glenda. You have access to the following tools:
 - list_files(path): Read the contents of a folder.
 - read_file(path): Read the contents of a file.
+- write_file(path): Write the contents of a file. The file will be created if needed, and its contents will be overwritten.
 - search_man(keywords): List man pages that contain _all_ the keywords.
 - read_man(section, name): Read a specific man page.
+- run_command(cmd, args): Run a command in the rc shell.
+- summarize(summary): Save a summary of the previous conversation to compress the context.
 
 **Your Task:**
 Solve the given problem by using these tools. Do **not** simulate commands or their output!
@@ -22,6 +25,13 @@
    - After a tool fails: Use search_man to find the solution to the problem.
    - If you can't get the info you need, ask the user.
    - If you can't finish the task because of missing data/permissions, ask the user.
+
+4. Summarize:
+   - If the topic changes, or the conversation goes into a different direction, use the summarize tool.
+   - If the conversation grows to a length close to the context limit, summarize.
+   - You may be presented with a summary of the last conversation at the beginning. Use this as additional context.
+   - When summarizing, also summarize the old summary, but reduce its size even further. Only keep the important points.
+   - The summary is for you, not for the user.
 
 **Important:**
 - Do not use shortcuts. Use the tools also for trivial tasks.
--- a/oailib.c
+++ b/oailib.c
@@ -484,8 +484,11 @@
 			continue;
 		}
 		r = toolfn(tc, tool->aux);
-		if (!r)
-			continue;
+		if (!r) {
+			/* if tool returns nil, assume that the requests will be handled manually */
+			res.success = 0;
+			return res;
+		}
 		addtcprompt(pr, &tc);
 		addtcprompt(resprompt, &tc);
 		pres = makeprompt("tool");
--- /dev/null
+++ b/tools/summarize.tool
@@ -1,0 +1,43 @@
+static char*
+summarize(OToolcall tc, void*)
+{
+	JSON *j, *jc;
+	char *content;
+	
+	j = jsonparse(tc.arguments);
+	jc = jsonbyname(j, "content");
+	if (!jc)
+		goto Err;
+	
+	content = jsonstr(jc);
+	if (!content)
+		goto Err;
+	
+	resetprompts();
+	if (sysprompt)
+		addstrprompt(&req, "system", "%s", sysprompt);
+	
+	addstrprompt(&req, "user", "Summarize the previous conversation");
+	addstrprompt(&req, "assistant", "%s", content);
+	
+	fprint(2, "summary: %s\n", content);
+	reprompt = 1;
+	return nil;
+
+Err:
+	jsonfree(j);
+	return strdup("no content");
+}
+
+static char *sumdesc = "Save a summary of the whole conversation to compress the context.";
+static char *sumargs = ""
+%%json
+{
+	"type": "object",
+	"properties": {
+		"content": { "type": "string" }
+	},
+	"required": [ "content" ]
+}
+%/json
+;
\ No newline at end of file
--