]> git.giacomolli.uk - onechat/blobdiff - prompt_test.go
Send messages to subagents with tell
[onechat] / prompt_test.go
index 4c88ad8a80d2683573ccc877523488691f6de5ac..6adb0ba92ad42ea55b174b94390c94472169a45f 100644 (file)
@@ -16,6 +16,7 @@ func TestPromptNamesTheAgent(t *testing.T) {
        require.Contains(t, text, "- reply: Ada's replies")
        require.Contains(t, text, "Goal: let Ada work later")
        require.Contains(t, text, `- work: an agent's report, starting "[Name]"`)
        require.Contains(t, text, "- reply: Ada's replies")
        require.Contains(t, text, "Goal: let Ada work later")
        require.Contains(t, text, `- work: an agent's report, starting "[Name]"`)
+       require.Contains(t, text, "- zoom(id, 1) gives message id whole\n- zoom(\"Name\") gives an agent's whole chat\n")
        require.NotContains(t, text, promptName)
 
        // The old agent name is built from parts, so the source does not spell
        require.NotContains(t, text, promptName)
 
        // The old agent name is built from parts, so the source does not spell
@@ -25,11 +26,39 @@ func TestPromptNamesTheAgent(t *testing.T) {
 
 func TestPromptLeavesOutAbsentFeatures(t *testing.T) {
        text := prompt("Ada", "")
 
 func TestPromptLeavesOutAbsentFeatures(t *testing.T) {
        text := prompt("Ada", "")
-       for _, absent := range []string{"image", "ubagent", "computer", "device", `zoom("Name")`, "instructions at the end"} {
+       for _, absent := range []string{"image", "computer", "device", "instructions at the end"} {
                require.NotContains(t, text, absent)
        }
 }
 
                require.NotContains(t, text, absent)
        }
 }
 
+func TestPromptHasTheLinesOnSubagents(t *testing.T) {
+       text := prompt("Ada", "")
+       require.Contains(t, text, "Do the user's tasks yourself, with your tools.\nUse subagents only when the user asks for them.\n")
+       require.Contains(t, text, `Messages the user sends while you work reach you between tool calls.
+Subagents run in the background; each one's report reaches you as a message
+starting "[Name]", between your tool calls or as a new turn. Never wait for one
+(no sleep, no polling): go on, or end your turn and tell the user what is
+running.
+`)
+}
+
+func TestSubagentPromptNamesTheAgentAndEndsWithTheInstructions(t *testing.T) {
+       text := promptSubagent("Ada", "\nI am Lena.\n")
+       require.True(t, strings.HasPrefix(text, "You are a subagent of Ada, an AI agent"))
+       require.Contains(t, text, "Ada gave you a task. Do it yourself, with your tools,\nfollowing the user's instructions at the end of this prompt: they say who the\nuser is, how their files are organized and how they want work done.\n")
+       require.Contains(t, text, "zoom(\"Name\") gives an agent's\nwhole chat.")
+       require.True(t, strings.HasSuffix(text, "\n\n# The user's instructions\n\nI am Lena."))
+       require.NotContains(t, text, promptName)
+
+       for _, absent := range []string{"image", "computer", "device", "Compaction"} {
+               require.NotContains(t, text, absent)
+       }
+
+       text = promptSubagent("Ada", " \n")
+       require.Contains(t, text, "Ada gave you a task. Do it yourself, with your tools.\n")
+       require.NotContains(t, text, "instructions")
+}
+
 func TestPromptEndsWithTheInstructions(t *testing.T) {
        text := prompt("Ada", "\nI am Lena. Keep replies short.\n\n")
        require.Contains(t, text, `Do the user's tasks yourself, with your tools, following the user's instructions
 func TestPromptEndsWithTheInstructions(t *testing.T) {
        text := prompt("Ada", "\nI am Lena. Keep replies short.\n\n")
        require.Contains(t, text, `Do the user's tasks yourself, with your tools, following the user's instructions
@@ -47,8 +76,9 @@ func TestPromptWithoutInstructionsHasNoClause(t *testing.T) {
 }
 
 func TestAgentToolsAreStrictAndStable(t *testing.T) {
 }
 
 func TestAgentToolsAreStrictAndStable(t *testing.T) {
-       tools := agentTools()
-       require.Equal(t, []string{"zoom", "date"}, []string{tools[0].Name, tools[1].Name})
+       tools := promptTools()
+       require.Equal(t, []string{"zoom", "date", "shell", "read", "write", "edit", "spawn", "tell"}, promptToolNames(tools))
+       require.Equal(t, []string{"zoom", "date", "shell", "read", "write", "edit"}, promptToolNames(promptSubagentTools()))
 
        for _, tool := range tools {
                schema := tool.Parameters.(map[string]any)
 
        for _, tool := range tools {
                schema := tool.Parameters.(map[string]any)
@@ -62,8 +92,18 @@ func TestAgentToolsAreStrictAndStable(t *testing.T) {
        require.NoError(t, err)
 
        for range 10 {
        require.NoError(t, err)
 
        for range 10 {
-               again, err := json.Marshal(agentTools())
+               again, err := json.Marshal(promptTools())
                require.NoError(t, err)
                require.Equal(t, first, again)
        }
 }
                require.NoError(t, err)
                require.Equal(t, first, again)
        }
 }
+
+// promptToolNames returns the names of tools.
+func promptToolNames(tools []ModelTool) []string {
+       names := make([]string, len(tools))
+       for n, tool := range tools {
+               names[n] = tool.Name
+       }
+
+       return names
+}