]> git.giacomolli.uk - onechat/blobdiff - prompt.go
Send stored images to WhatsApp chats
[onechat] / prompt.go
index 36fda3288de8778c156fc51f35e79122b1015725..0852becedd396f6e4fab0088a611eee66d4443a9 100644 (file)
--- a/prompt.go
+++ b/prompt.go
@@ -41,10 +41,10 @@ var promptEfforts = []string{"low", "medium", "high", "xhigh"}
 // one added paragraph on the user's instructions file. The reference names its
 // own agent, so promptText has the name of the agent and the kind reply in its
 // place. It describes only what OneChat can do, so it leaves out the spec text
-// on images, computers, and computer tasks. Its paragraph on persistent mode
-// tells the model that a final answer ends the turn. prompt adds the clause on
-// the instructions of the user only when there are instructions. It holds no
-// date and no state, so turns and compactions share its prompt cache.
+// on computers and computer tasks. Its paragraph on persistent mode tells the
+// model that a final answer ends the turn. prompt adds the clause on the
+// instructions of the user only when there are instructions. It holds no date
+// and no state, so turns and compactions share its prompt cache.
 const promptText = `You are {name}, an AI agent that works for one user in a single chat that never
 ends. Each call to you is a turn or a compaction: the view below is followed by
 the user's new message, or by a task starting "Compaction:".
@@ -76,6 +76,9 @@ Tools:
 - zoom("Name") gives an agent's whole chat
 - date(id) gives the date and time of message id
 
+An [image FILE] line names a stored image. New images include pixels for this
+turn only. Use zoom(id, 1) to see an older image again.
+
 # Turns
 
 Do the user's tasks yourself, with your tools.
@@ -151,14 +154,16 @@ Pass area messages from mixed chats to the right child with sender, date, and
 words. Never send a WhatsApp reply drafted by a child without the user's
 agreement.
 Propose routing a source that talks only about one area to its child.
-Set or remove a route only after the user agrees.`
+Set or remove a route only after the user agrees.
+Use image_show or whatsapp_send with an image only on the user's request.
+Pass an image to a child with an [image FILE] line in tell.`
 
 // promptSubagentText is the system prompt of a subagent, from the subagent
 // prompt of the reference design: its head, then the doc of the view, without
-// the parts on devices and images. A subagent gets the view of the agent, then
-// its whole log, so it goes on from its log after a tell or a restart.
-// promptSubagent adds the clause on the instructions of the user only when
-// there are instructions.
+// the parts on devices. A subagent gets the view of the agent, then its whole
+// log, so it goes on from its log after a tell or a restart. promptSubagent
+// adds the clause on the instructions of the user only when there are
+// instructions.
 const promptSubagentText = `You are a subagent of {name}, an AI agent that works for one user in a single
 chat that never ends. {name} gave you a task. Do it yourself, with your tools.
 
@@ -189,7 +194,8 @@ was made from; zoom(id, 1) gives message id in full. Zoom whenever a summary
 only mentions something you need, such as what your last reply said, a
 decision, a past attempt or where a file is, before you act, guess or ask.
 date(id) gives the date and time of message id. zoom("Name") gives an agent's
-whole chat.`
+whole chat. An [image FILE] line names a stored image. Use zoom(id, 1)
+to see its pixels.`
 
 // prompt returns the system prompt of the reference with one added paragraph on
 // the user's instructions file at instructionsPath. It uses the agent name and
@@ -270,6 +276,15 @@ func promptTools() []ModelTool {
                        "message": promptStringSchema("The message."),
                }),
                Strict: true,
+       }, ModelTool{
+               Type:        "function",
+               Name:        "image_show",
+               Description: "Show a stored image to the user, only when the user asks to see it. Give its stored filename, not a path.",
+               Parameters: promptObjectSchema(map[string]any{
+                       "image":   promptStringSchema("The stored image filename from an [image FILE] line."),
+                       "caption": promptStringSchema("The caption, or an empty string."),
+               }),
+               Strict: true,
        }, ModelTool{
                Type:        "function",
                Name:        "whatsapp_find",
@@ -281,11 +296,12 @@ func promptTools() []ModelTool {
        }, ModelTool{
                Type:        "function",
                Name:        "whatsapp_send",
-               Description: "Send a text message to a WhatsApp chat. Send only a message that the user asked you to send, to the chat that the user named. Give a new id for each message: a call with an id that was used gives the answer of the first call and sends nothing.",
+               Description: "Send text or a stored image with text as its caption to a WhatsApp chat. Send only a message that the user asked you to send, to the chat that the user named. Give a new id for each message: a call with an id that was used gives the answer of the first call and sends nothing.",
                Parameters: promptObjectSchema(map[string]any{
-                       "id":   promptStringSchema("A new id for this message, such as a short random word."),
-                       "chat": promptStringSchema("The ID of the chat, from whatsapp_find or from a [WhatsApp] message."),
-                       "text": promptStringSchema("The text of the message."),
+                       "id":    promptStringSchema("A new id for this message, such as a short random word."),
+                       "chat":  promptStringSchema("The ID of the chat, from whatsapp_find or from a [WhatsApp] message."),
+                       "text":  promptStringSchema("The text, or the caption when sending an image. Can be empty with an image."),
+                       "image": promptNullableStringSchema("The stored image filename from an [image FILE] line, or null for text only."),
                }),
                Strict: true,
        }, ModelTool{