+// promptChildrenText gives the root the tools and consent rules for children.
+const promptChildrenText = `
+
+Use agent_create for permanent children, whose areas are in the state.
+Use tell for children and subagents, and zoom("Name") for their memory.
+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.
+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. 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.
+
+Your first message holds the view below, then your chat with {name} so far, its
+lines as "i|kind: text": what you are (note), your task (user), and later all
+you did and were told. The view shows you what {name} knows: what the user
+wants, decided and taught. Use it as context only, and do what your task says,
+not what the user's last message says, since {name} may have given you just
+part of the work. Your final reply is your report to {name}. {name} may send you
+more messages, even while you work: answer the last.
+
+The view: the whole chat between {name} and the user, oldest first, inside
+<chat> tags, as one-line summaries. Each line is
+
+ id+n|text the n messages from id on, summarized (newlines shown as spaces)
+
+A summary tags each item with its kind: user (the user's words), reply
+({name}'s replies), tool ({name}'s tool calls), echo (their results), note
+(memories from before this chat), or work (the report of a subagent, starting
+"[Name]"). A short message is its own line, word for word. Recent lines cover
+one message each; the older the messages, the more a line covers. A message not
+summarized yet shows as "(not summarized yet: zoom it)". No message appears in
+full, not even the last ones. A text too long for one message is split over
+several in a row.
+
+Navigating: zoom(id, n) opens line id+n into the two lines of n/2 messages it
+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. 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
+// ends with the user's instructions. Without instructions it has neither them
+// nor the clause that points to them, but keeps the file paragraph. Turns and
+// compactions send the same prompt and tools, so compactions read the prompt
+// cache of the turns.
+func prompt(name, instructionsPath, instructions string) string {
+ text := strings.NewReplacer(promptName, name, promptInstructionsPath, instructionsPath).Replace(promptText)
+ text = strings.Replace(text, "\n\n# Compactions", promptChildrenText+"\n\n# Compactions", 1)
+
+ return promptWithInstructions(text, promptTaskSentence, promptInstructionsClause, instructions)
+}
+
+// promptChild returns the prompt of a child with its area and reporting rules.
+// Its instructions file belongs to the child, not to the parent.
+func promptChild(name, parent, responsibility, instructionsPath, instructions string) string {
+ text := prompt(name, instructionsPath, "")
+ text = strings.Replace(text, "You are "+name+", an AI agent that works for one user in a single chat that never\nends.", "You are "+name+", a child agent of "+parent+".", 1)
+ text = strings.Replace(text, promptTaskSentence, `Do the tasks of your area yourself, with your tools.
+You are responsible for: `+responsibility+`
+Work only in this area. Report to `+parent+` only what needs the parent or the
+user: a decision, a deadline, a problem, a question you cannot settle, or a
+message outside your area. Your final reply is your report to the parent.
+End your turn with an empty reply when nothing needs the parent or the user.
+Send nothing to WhatsApp. Draft replies in your report instead, so the parent
+can ask the user before sending.`, 1)
+ text = strings.Replace(text, promptChildrenText, "", 1)
+
+ return promptWithInstructions(text, "Do the tasks of your area yourself, with your tools.", promptInstructionsClause, instructions)
+}
+
+// promptSubagent returns the system prompt of a subagent of the agent name,
+// with the instructions of the user at its end, as prompt does.
+func promptSubagent(name, instructions string) string {
+ text := strings.ReplaceAll(promptSubagentText, promptName, name)