diff --git a/agent/agent.go b/agent/agent.go index ad47efaf..b7472f40 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -1019,6 +1019,24 @@ func shortcutToolCalls(prompt string) []shortcutToolCall { "weather": {{Tool: "weather_forecast", Args: map[string]any{"lat": 51.5074, "lon": -0.1278}}}, "reminder": {{Tool: "reminder", Args: map[string]any{}}}, "apps": {{Tool: "apps_search", Args: map[string]any{}}}, + "mail": {{Tool: "mail_read", Args: map[string]any{}}}, + // Personal queries + "do i have mail": {{Tool: "mail_read", Args: map[string]any{}}}, + "do i have unread mail": {{Tool: "mail_read", Args: map[string]any{}}}, + "do i have email": {{Tool: "mail_read", Args: map[string]any{}}}, + "check my mail": {{Tool: "mail_read", Args: map[string]any{}}}, + "check my email": {{Tool: "mail_read", Args: map[string]any{}}}, + "any new mail": {{Tool: "mail_read", Args: map[string]any{}}}, + "any new email": {{Tool: "mail_read", Args: map[string]any{}}}, + "any mail": {{Tool: "mail_read", Args: map[string]any{}}}, + "unread mail": {{Tool: "mail_read", Args: map[string]any{}}}, + "my mail": {{Tool: "mail_read", Args: map[string]any{}}}, + "btc price": {{Tool: "markets", Args: map[string]any{"category": "crypto"}}}, + "bitcoin price": {{Tool: "markets", Args: map[string]any{"category": "crypto"}}}, + "eth price": {{Tool: "markets", Args: map[string]any{"category": "crypto"}}}, + "what's happening": {{Tool: "news", Args: map[string]any{}}}, + "what's happening?": {{Tool: "news", Args: map[string]any{}}}, + "today's news": {{Tool: "news", Args: map[string]any{}}}, // Starter pill phrases "give me a summary of today's top news": {{Tool: "news", Args: map[string]any{}}}, "what's in the news?": {{Tool: "news", Args: map[string]any{}}}, diff --git a/agent/run.go b/agent/run.go index bd61f4d5..726273f1 100644 --- a/agent/run.go +++ b/agent/run.go @@ -133,10 +133,19 @@ func RunHandler(w http.ResponseWriter, r *http.Request) { _ = acc // authenticated // Step 1: Plan + userCtx := "" + if UserContextFunc != nil { + userCtx = UserContextFunc(acc.ID) + } + planSystem := "You are an AI agent. Given a user question, output ONLY a JSON array of tool calls.\n\n" + + agentToolsDesc + + "\n\nOutput format: [{\"tool\":\"tool_name\",\"args\":{}}]\nUse at most 5 tool calls. Output [] if no tools needed." + + "\n\nIMPORTANT: For personal questions like 'do I have mail', 'what's the weather', 'news today', 'btc price' — ALWAYS use the appropriate tool. Never say you can't access something. You have tools for everything." + if userCtx != "" { + planSystem += "\n\nUser context:\n" + userCtx + } planResult, err := ai.Ask(&ai.Prompt{ - System: "You are an AI agent. Given a user question, output ONLY a JSON array of tool calls.\n\n" + - agentToolsDesc + - "\n\nOutput format: [{\"tool\":\"tool_name\",\"args\":{}}]\nUse at most 5 tool calls. Output [] if no tools needed.", + System: planSystem, Question: req.Prompt, Priority: ai.PriorityHigh, Provider: model.Provider, @@ -186,12 +195,9 @@ func RunHandler(w http.ResponseWriter, r *http.Request) { // Step 3: Synthesise with user context. today := time.Now().UTC().Format("Monday, 2 January 2006 (UTC)") - userCtx := "" - if UserContextFunc != nil { - userCtx = UserContextFunc(acc.ID) - } synthSystem := "You are Micro, a personal AI assistant. Today is " + today + ". " + - "Answer concisely using the tool results below. Use markdown." + "Answer concisely using the tool results and user context below. Use markdown. " + + "If the user context already contains the answer (e.g. unread mail count), use it directly." if userCtx != "" { synthSystem += "\n\nUser context:\n" + userCtx } diff --git a/home/home.go b/home/home.go index 34eb4ea1..a22e917c 100644 --- a/home/home.go +++ b/home/home.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "sort" "strings" "sync" @@ -20,7 +21,6 @@ import ( "mu/mail" "mu/news" "mu/social" - "mu/stream" "mu/markets" "mu/reminder" "mu/video" @@ -389,7 +389,11 @@ func Handler(w http.ResponseWriter, r *http.Request) { } inviteHTML = fmt.Sprintf(`%s`, link, label) } - dateLine.WriteString(fmt.Sprintf(`