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
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)
}
}
+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 TestAgentToolsAreStrictAndStable(t *testing.T) {
tools := promptTools()
- names := make([]string, len(tools))
- for n, tool := range tools {
- names[n] = tool.Name
- }
-
- require.Equal(t, []string{"zoom", "date", "shell", "read", "write", "edit"}, names)
+ require.Equal(t, []string{"zoom", "date", "shell", "read", "write", "edit", "spawn", "tell", "whatsapp_find", "whatsapp_send", "schedule_set", "schedule_list", "schedule_remove"}, promptToolNames(tools))
+ require.Equal(t, []string{"zoom", "date", "shell", "read", "write", "edit"}, promptToolNames(promptSubagentTools()))
for _, tool := range tools {
schema := tool.Parameters.(map[string]any)
properties := schema["properties"].(map[string]any)
require.True(t, tool.Strict, tool.Name)
require.Equal(t, false, schema["additionalProperties"], tool.Name)
- require.Equal(t, slices.Sorted(maps.Keys(properties)), schema["required"], tool.Name)
+ require.ElementsMatch(t, slices.Collect(maps.Keys(properties)), schema["required"], tool.Name)
}
first, err := json.Marshal(tools)
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
+}