diff --git a/crates/gyandoot-agent/src/agent_loop.rs b/crates/gyandoot-agent/src/agent_loop.rs index 94b6e0e..64c65fd 100644 --- a/crates/gyandoot-agent/src/agent_loop.rs +++ b/crates/gyandoot-agent/src/agent_loop.rs @@ -196,7 +196,7 @@ impl AgentLoop { let mut system_prompt = self.config.system_prompt.clone(); if !agent_name.is_empty() { system_prompt = format!( - "{}\n\n## Your Identity\n- Name: {}\n- Role: {}\n- You are speaking to: {} ({})\n\n## Memory\nYou have a verbatim dialogue log with your user. Use everything from past conversations as context when answering.", + "{}\n\n## Your Identity\n- Name: {}\n- Role: {}\n- You are speaking to: {} ({})\n\n## Your Capabilities\nYou have access to tools that let you:\n- Read, write, and edit files\n- Execute shell commands (bash) — use this for curl, git, package managers\n- Search files and directories\n- Use `bash` to run curl for web requests when needed\n\nWhen a user asks you to do something that requires external data, use your tools. Do NOT say you can't do something if you have a tool that can do it.\n\n## Memory\nYou have a verbatim dialogue log with your user. Use everything from past conversations as context when answering.", system_prompt, agent_name, if agent_role.is_empty() { "AI Assistant" } else { &agent_role }, diff --git a/crates/gyandoot-providers/src/ollama.rs b/crates/gyandoot-providers/src/ollama.rs index d9d2a9b..dc9597a 100644 --- a/crates/gyandoot-providers/src/ollama.rs +++ b/crates/gyandoot-providers/src/ollama.rs @@ -154,7 +154,7 @@ impl Provider for OllamaProvider { }) .collect(); - let body = serde_json::json!({ + let mut body = serde_json::json!({ "model": self.model, "messages": messages, "stream": false, @@ -163,6 +163,11 @@ impl Provider for OllamaProvider { } }); + // Add tools if present (for function calling) + if !context.tools.is_empty() { + body["tools"] = serde_json::to_value(&context.tools).unwrap_or_default(); + } + let url = format!("{}/api/chat", self.normalized_base_url()); let mut request = self .client @@ -192,9 +197,21 @@ impl Provider for OllamaProvider { .to_string(); let finish_reason = data["done_reason"].as_str().unwrap_or("stop").to_string(); + // Parse tool calls from response (qwen3.5 returns OpenAI-compatible format) + let tool_calls = data["message"]["tool_calls"].as_array().map(|calls| { + calls.iter().map(|tc| { + let func = &tc["function"]; + gyandoot_core::ToolCall { + id: tc["id"].as_str().unwrap_or_default().to_string(), + name: func["name"].as_str().unwrap_or_default().to_string(), + arguments: func["arguments"].clone(), + } + }).collect() + }); + Ok(ProviderResponse { content, - tool_calls: None, + tool_calls, finish_reason, }) }