diff --git a/llm/gem/gem.go b/llm/gem/gem.go
new file mode 100644
index 0000000..4327123
--- /dev/null
+++ b/llm/gem/gem.go
@@ -0,0 +1,560 @@
+package gem
+
+import (
+	"cmp"
+	"context"
+	"encoding/json"
+	"fmt"
+	"log/slog"
+	"math/rand"
+	"net/http"
+	"strings"
+	"time"
+
+	"sketch.dev/llm"
+	"sketch.dev/llm/gem/gemini"
+)
+
+const (
+	DefaultModel     = "gemini-2.5-pro-preview-03-25"
+	DefaultMaxTokens = 8192
+	GeminiAPIKeyEnv  = "GEMINI_API_KEY"
+)
+
+// Service provides Gemini completions.
+// Fields should not be altered concurrently with calling any method on Service.
+type Service struct {
+	HTTPC     *http.Client // defaults to http.DefaultClient if nil
+	APIKey    string       // must be non-empty
+	Model     string       // defaults to DefaultModel if empty
+	MaxTokens int          // defaults to DefaultMaxTokens if zero
+}
+
+var _ llm.Service = (*Service)(nil)
+
+// These maps convert between Sketch's llm package and Gemini API formats
+var fromLLMRole = map[llm.MessageRole]string{
+	llm.MessageRoleAssistant: "model",
+	llm.MessageRoleUser:      "user",
+}
+
+// convertToolSchemas converts Sketch's llm.Tool schemas to Gemini's schema format
+func convertToolSchemas(tools []*llm.Tool) ([]gemini.FunctionDeclaration, error) {
+	if len(tools) == 0 {
+		return nil, nil
+	}
+
+	var decls []gemini.FunctionDeclaration
+	for _, tool := range tools {
+		// Parse the schema from raw JSON
+		var schemaJSON map[string]any
+		if err := json.Unmarshal(tool.InputSchema, &schemaJSON); err != nil {
+			return nil, fmt.Errorf("failed to unmarshal tool %s schema: %w", tool.Name, err)
+		}
+		decls = append(decls, gemini.FunctionDeclaration{
+			Name:        tool.Name,
+			Description: tool.Description,
+			Parameters:  convertJSONSchemaToGeminiSchema(schemaJSON),
+		})
+	}
+
+	return decls, nil
+}
+
+// convertJSONSchemaToGeminiSchema converts a JSON schema to Gemini's schema format
+func convertJSONSchemaToGeminiSchema(schemaJSON map[string]any) gemini.Schema {
+	schema := gemini.Schema{}
+
+	// Set the type based on the JSON schema type
+	if typeVal, ok := schemaJSON["type"].(string); ok {
+		switch typeVal {
+		case "string":
+			schema.Type = gemini.DataTypeSTRING
+		case "number":
+			schema.Type = gemini.DataTypeNUMBER
+		case "integer":
+			schema.Type = gemini.DataTypeINTEGER
+		case "boolean":
+			schema.Type = gemini.DataTypeBOOLEAN
+		case "array":
+			schema.Type = gemini.DataTypeARRAY
+		case "object":
+			schema.Type = gemini.DataTypeOBJECT
+		default:
+			schema.Type = gemini.DataTypeSTRING // Default to string for unknown types
+		}
+	}
+
+	// Set description if available
+	if desc, ok := schemaJSON["description"].(string); ok {
+		schema.Description = desc
+	}
+
+	// Handle enum values
+	if enumValues, ok := schemaJSON["enum"].([]any); ok {
+		schema.Enum = make([]string, len(enumValues))
+		for i, v := range enumValues {
+			if strVal, ok := v.(string); ok {
+				schema.Enum[i] = strVal
+			} else {
+				// Convert non-string values to string
+				valBytes, _ := json.Marshal(v)
+				schema.Enum[i] = string(valBytes)
+			}
+		}
+	}
+
+	// Handle object properties
+	if properties, ok := schemaJSON["properties"].(map[string]any); ok && schema.Type == gemini.DataTypeOBJECT {
+		schema.Properties = make(map[string]gemini.Schema)
+		for propName, propSchema := range properties {
+			if propSchemaMap, ok := propSchema.(map[string]any); ok {
+				schema.Properties[propName] = convertJSONSchemaToGeminiSchema(propSchemaMap)
+			}
+		}
+	}
+
+	// Handle required properties
+	if required, ok := schemaJSON["required"].([]any); ok {
+		schema.Required = make([]string, len(required))
+		for i, r := range required {
+			if strVal, ok := r.(string); ok {
+				schema.Required[i] = strVal
+			}
+		}
+	}
+
+	// Handle array items
+	if items, ok := schemaJSON["items"].(map[string]any); ok && schema.Type == gemini.DataTypeARRAY {
+		itemSchema := convertJSONSchemaToGeminiSchema(items)
+		schema.Items = &itemSchema
+	}
+
+	// Handle minimum/maximum items for arrays
+	if minItems, ok := schemaJSON["minItems"].(float64); ok {
+		schema.MinItems = fmt.Sprintf("%d", int(minItems))
+	}
+	if maxItems, ok := schemaJSON["maxItems"].(float64); ok {
+		schema.MaxItems = fmt.Sprintf("%d", int(maxItems))
+	}
+
+	return schema
+}
+
+// buildGeminiRequest converts Sketch's llm.Request to Gemini's request format
+func (s *Service) buildGeminiRequest(req *llm.Request) (*gemini.Request, error) {
+	gemReq := &gemini.Request{}
+
+	// Add system instruction if provided
+	if len(req.System) > 0 {
+		// Combine all system messages into a single system instruction
+		systemText := ""
+		for i, sys := range req.System {
+			if i > 0 && systemText != "" && sys.Text != "" {
+				systemText += "\n"
+			}
+			systemText += sys.Text
+		}
+
+		if systemText != "" {
+			gemReq.SystemInstruction = &gemini.Content{
+				Parts: []gemini.Part{{Text: systemText}},
+			}
+		}
+	}
+
+	// Convert messages to Gemini content format
+	for _, msg := range req.Messages {
+		// Set the role based on the message role
+		role, ok := fromLLMRole[msg.Role]
+		if !ok {
+			return nil, fmt.Errorf("unsupported message role: %v", msg.Role)
+		}
+
+		content := gemini.Content{
+			Role: role,
+		}
+
+		// Store tool usage information to correlate tool uses with responses
+		toolNameToID := make(map[string]string)
+
+		// First pass: collect tool use IDs for correlation
+		for _, c := range msg.Content {
+			if c.Type == llm.ContentTypeToolUse && c.ID != "" {
+				toolNameToID[c.ToolName] = c.ID
+			}
+		}
+
+		// Map each content item to Gemini's format
+		for _, c := range msg.Content {
+			switch c.Type {
+			case llm.ContentTypeText, llm.ContentTypeThinking, llm.ContentTypeRedactedThinking:
+				// Simple text content
+				content.Parts = append(content.Parts, gemini.Part{
+					Text: c.Text,
+				})
+			case llm.ContentTypeToolUse:
+				// Tool use becomes a function call
+				var args map[string]any
+				if err := json.Unmarshal(c.ToolInput, &args); err != nil {
+					return nil, fmt.Errorf("failed to unmarshal tool input: %w", err)
+				}
+
+				// Make sure we have a valid ID for this tool use
+				if c.ID == "" {
+					c.ID = fmt.Sprintf("gemini_tool_%s_%d", c.ToolName, time.Now().UnixNano())
+				}
+
+				// Save the ID for this tool name for future correlation
+				toolNameToID[c.ToolName] = c.ID
+
+				slog.DebugContext(context.Background(), "gemini_preparing_tool_use",
+					"tool_name", c.ToolName,
+					"tool_id", c.ID,
+					"input", string(c.ToolInput))
+
+				content.Parts = append(content.Parts, gemini.Part{
+					FunctionCall: &gemini.FunctionCall{
+						Name: c.ToolName,
+						Args: args,
+					},
+				})
+			case llm.ContentTypeToolResult:
+				// Tool result becomes a function response
+				// Create a map for the response
+				response := map[string]any{
+					"result": c.ToolResult,
+					"error":  c.ToolError,
+				}
+
+				// Determine the function name to use - this is critical
+				funcName := ""
+
+				// First try to find the function name from a stored toolUseID if we have one
+				if c.ToolUseID != "" {
+					// Try to derive the tool name from the previous tools we've seen
+					for name, id := range toolNameToID {
+						if id == c.ToolUseID {
+							funcName = name
+							break
+						}
+					}
+				}
+
+				// Fallback options if we couldn't find the tool name
+				if funcName == "" {
+					// Try the tool name directly
+					if c.ToolName != "" {
+						funcName = c.ToolName
+					} else {
+						// Last resort fallback
+						funcName = "default_tool"
+					}
+				}
+
+				slog.DebugContext(context.Background(), "gemini_preparing_tool_result",
+					"tool_use_id", c.ToolUseID,
+					"mapped_func_name", funcName,
+					"result_length", len(c.ToolResult))
+
+				content.Parts = append(content.Parts, gemini.Part{
+					FunctionResponse: &gemini.FunctionResponse{
+						Name:     funcName,
+						Response: response,
+					},
+				})
+			}
+		}
+
+		gemReq.Contents = append(gemReq.Contents, content)
+	}
+
+	// Handle tools/functions
+	if len(req.Tools) > 0 {
+		// Convert tool schemas
+		decls, err := convertToolSchemas(req.Tools)
+		if err != nil {
+			return nil, fmt.Errorf("failed to convert tool schemas: %w", err)
+		}
+		if len(decls) > 0 {
+			gemReq.Tools = []gemini.Tool{{FunctionDeclarations: decls}}
+		}
+	}
+
+	return gemReq, nil
+}
+
+// convertGeminiResponsesToContent converts a Gemini response to llm.Content
+func convertGeminiResponseToContent(res *gemini.Response) []llm.Content {
+	if res == nil || len(res.Candidates) == 0 || len(res.Candidates[0].Content.Parts) == 0 {
+		return []llm.Content{{
+			Type: llm.ContentTypeText,
+			Text: "",
+		}}
+	}
+
+	var contents []llm.Content
+
+	// Process each part in the first candidate's content
+	for i, part := range res.Candidates[0].Content.Parts {
+		// Log the part type for debugging
+		slog.DebugContext(context.Background(), "processing_gemini_part",
+			"index", i,
+			"has_text", part.Text != "",
+			"has_function_call", part.FunctionCall != nil,
+			"has_function_response", part.FunctionResponse != nil)
+
+		if part.Text != "" {
+			// Simple text response
+			contents = append(contents, llm.Content{
+				Type: llm.ContentTypeText,
+				Text: part.Text,
+			})
+		} else if part.FunctionCall != nil {
+			// Function call (tool use)
+			args, err := json.Marshal(part.FunctionCall.Args)
+			if err != nil {
+				// If we can't marshal, use empty args
+				slog.DebugContext(context.Background(), "gemini_failed_to_markshal_args",
+					"tool_name", part.FunctionCall.Name,
+					"args", string(args),
+					"err", err.Error(),
+				)
+				args = []byte("{}")
+			}
+
+			// Generate a unique ID for this tool use that includes the function name
+			// to make it easier to correlate with responses
+			toolID := fmt.Sprintf("gemini_tool_%s_%d", part.FunctionCall.Name, time.Now().UnixNano())
+
+			contents = append(contents, llm.Content{
+				ID:        toolID,
+				Type:      llm.ContentTypeToolUse,
+				ToolName:  part.FunctionCall.Name,
+				ToolInput: json.RawMessage(args),
+			})
+
+			slog.DebugContext(context.Background(), "gemini_tool_call",
+				"tool_id", toolID,
+				"tool_name", part.FunctionCall.Name,
+				"args", string(args))
+		} else if part.FunctionResponse != nil {
+			// We shouldn't normally get function responses from the model, but just in case
+			respData, _ := json.Marshal(part.FunctionResponse.Response)
+			slog.DebugContext(context.Background(), "unexpected_function_response",
+				"name", part.FunctionResponse.Name,
+				"response", string(respData))
+		}
+	}
+
+	// If no content was added, add an empty text content
+	if len(contents) == 0 {
+		slog.DebugContext(context.Background(), "empty_gemini_response", "adding_empty_text", true)
+		contents = append(contents, llm.Content{
+			Type: llm.ContentTypeText,
+			Text: "",
+		})
+	}
+
+	return contents
+}
+
+// Gemini doesn't provide usage info directly, so we need to estimate it
+// ensureToolIDs makes sure all tool uses have proper IDs
+func ensureToolIDs(contents []llm.Content) {
+	for i, content := range contents {
+		if content.Type == llm.ContentTypeToolUse && content.ID == "" {
+			// Generate a stable ID using the tool name and timestamp
+			contents[i].ID = fmt.Sprintf("gemini_tool_%s_%d", content.ToolName, time.Now().UnixNano())
+			slog.DebugContext(context.Background(), "assigned_missing_tool_id",
+				"tool_name", content.ToolName,
+				"new_id", contents[i].ID)
+		}
+	}
+}
+
+func calculateUsage(req *gemini.Request, res *gemini.Response) llm.Usage {
+	// Very rough estimation of token counts
+	var inputTokens uint64
+	var outputTokens uint64
+
+	// Count system tokens
+	if req.SystemInstruction != nil {
+		for _, part := range req.SystemInstruction.Parts {
+			if part.Text != "" {
+				// Very rough estimation: 1 token per 4 characters
+				inputTokens += uint64(len(part.Text)) / 4
+			}
+		}
+	}
+
+	// Count input tokens
+	for _, content := range req.Contents {
+		for _, part := range content.Parts {
+			if part.Text != "" {
+				inputTokens += uint64(len(part.Text)) / 4
+			} else if part.FunctionCall != nil {
+				// Estimate function call tokens
+				argBytes, _ := json.Marshal(part.FunctionCall.Args)
+				inputTokens += uint64(len(part.FunctionCall.Name)+len(argBytes)) / 4
+			} else if part.FunctionResponse != nil {
+				// Estimate function response tokens
+				resBytes, _ := json.Marshal(part.FunctionResponse.Response)
+				inputTokens += uint64(len(part.FunctionResponse.Name)+len(resBytes)) / 4
+			}
+		}
+	}
+
+	// Count output tokens
+	if res != nil && len(res.Candidates) > 0 {
+		for _, part := range res.Candidates[0].Content.Parts {
+			if part.Text != "" {
+				outputTokens += uint64(len(part.Text)) / 4
+			} else if part.FunctionCall != nil {
+				// Estimate function call tokens
+				argBytes, _ := json.Marshal(part.FunctionCall.Args)
+				outputTokens += uint64(len(part.FunctionCall.Name)+len(argBytes)) / 4
+			}
+		}
+	}
+
+	// For Gemini 2.5 Pro Preview pricing: $1.25 per 1M input tokens, $10 per 1M output tokens
+	// Convert to dollars
+	costUSD := float64(inputTokens)*1.25/1_000_000.0 + float64(outputTokens)*10/1_000_000.0
+
+	return llm.Usage{
+		InputTokens:  inputTokens,
+		OutputTokens: outputTokens,
+		CostUSD:      costUSD,
+	}
+}
+
+// Do sends a request to Gemini.
+func (s *Service) Do(ctx context.Context, ir *llm.Request) (*llm.Response, error) {
+	// Log the incoming request for debugging
+	slog.DebugContext(ctx, "gemini_request",
+		"message_count", len(ir.Messages),
+		"tool_count", len(ir.Tools),
+		"system_count", len(ir.System))
+
+	// Log tool-related information if any tools are present
+	if len(ir.Tools) > 0 {
+		var toolNames []string
+		for _, tool := range ir.Tools {
+			toolNames = append(toolNames, tool.Name)
+		}
+		slog.DebugContext(ctx, "gemini_tools", "tools", toolNames)
+	}
+
+	// Log details about the messages being sent
+	for i, msg := range ir.Messages {
+		contentTypes := make([]string, len(msg.Content))
+		for j, c := range msg.Content {
+			contentTypes[j] = c.Type.String()
+
+			// Log tool-related content with more details
+			if c.Type == llm.ContentTypeToolUse {
+				slog.DebugContext(ctx, "gemini_tool_use",
+					"message_idx", i,
+					"content_idx", j,
+					"tool_name", c.ToolName,
+					"tool_input", string(c.ToolInput))
+			} else if c.Type == llm.ContentTypeToolResult {
+				slog.DebugContext(ctx, "gemini_tool_result",
+					"message_idx", i,
+					"content_idx", j,
+					"tool_use_id", c.ToolUseID,
+					"tool_error", c.ToolError,
+					"result_length", len(c.ToolResult))
+			}
+		}
+		slog.DebugContext(ctx, "gemini_message",
+			"idx", i,
+			"role", msg.Role.String(),
+			"content_types", contentTypes)
+	}
+	// Build the Gemini request
+	gemReq, err := s.buildGeminiRequest(ir)
+	if err != nil {
+		return nil, fmt.Errorf("failed to build Gemini request: %w", err)
+	}
+
+	// Log the structured Gemini request for debugging
+	if reqJSON, err := json.MarshalIndent(gemReq, "", "  "); err == nil {
+		slog.DebugContext(ctx, "gemini_request_json", "request", string(reqJSON))
+	}
+
+	// Create a Gemini model instance
+	model := gemini.Model{
+		Model:  "models/" + cmp.Or(s.Model, DefaultModel),
+		APIKey: s.APIKey,
+		HTTPC:  cmp.Or(s.HTTPC, http.DefaultClient),
+	}
+
+	// Send the request to Gemini with retry logic
+	startTime := time.Now()
+	endTime := startTime // Initialize endTime
+	var gemRes *gemini.Response
+
+	// Retry mechanism for handling server errors and rate limiting
+	backoff := []time.Duration{1 * time.Second, 3 * time.Second, 5 * time.Second, 10 * time.Second}
+	for attempts := 0; attempts <= len(backoff); attempts++ {
+		gemApiErr := error(nil)
+		gemRes, gemApiErr = model.GenerateContent(ctx, gemReq)
+		endTime = time.Now()
+
+		if gemApiErr == nil {
+			// Successful response
+			// Log the structured Gemini response
+			if resJSON, err := json.MarshalIndent(gemRes, "", "  "); err == nil {
+				slog.DebugContext(ctx, "gemini_response_json", "response", string(resJSON))
+			}
+			break
+		}
+
+		if attempts == len(backoff) {
+			// We've exhausted all retry attempts
+			return nil, fmt.Errorf("gemini: API error after %d attempts: %w", attempts, gemApiErr)
+		}
+
+		// Check if the error is retryable (e.g., server error or rate limiting)
+		if strings.Contains(gemApiErr.Error(), "429") || strings.Contains(gemApiErr.Error(), "5") {
+			// Rate limited or server error - wait and retry
+			random := time.Duration(rand.Int63n(int64(time.Second)))
+			sleep := backoff[attempts] + random
+			slog.WarnContext(ctx, "gemini_request_retry", "error", gemApiErr.Error(), "attempt", attempts+1, "sleep", sleep)
+			time.Sleep(sleep)
+			continue
+		}
+
+		// Non-retryable error
+		return nil, fmt.Errorf("gemini: API error: %w", gemApiErr)
+	}
+
+	content := convertGeminiResponseToContent(gemRes)
+
+	ensureToolIDs(content)
+
+	usage := calculateUsage(gemReq, gemRes)
+
+	stopReason := llm.StopReasonEndTurn
+	for _, part := range content {
+		if part.Type == llm.ContentTypeToolUse {
+			stopReason = llm.StopReasonToolUse
+			slog.DebugContext(ctx, "gemini_tool_use_detected",
+				"setting_stop_reason", "llm.StopReasonToolUse",
+				"tool_name", part.ToolName)
+			break
+		}
+	}
+
+	return &llm.Response{
+		Role:       llm.MessageRoleAssistant,
+		Model:      s.Model,
+		Content:    content,
+		StopReason: stopReason,
+		Usage:      usage,
+		StartTime:  &startTime,
+		EndTime:    &endTime,
+	}, nil
+}
diff --git a/llm/gem/gem_test.go b/llm/gem/gem_test.go
new file mode 100644
index 0000000..7518d49
--- /dev/null
+++ b/llm/gem/gem_test.go
@@ -0,0 +1,218 @@
+package gem
+
+import (
+	"encoding/json"
+	"testing"
+
+	"sketch.dev/llm"
+	"sketch.dev/llm/gem/gemini"
+)
+
+func TestBuildGeminiRequest(t *testing.T) {
+	// Create a service
+	service := &Service{
+		Model:  DefaultModel,
+		APIKey: "test-api-key",
+	}
+
+	// Create a simple request
+	req := &llm.Request{
+		Messages: []llm.Message{
+			{
+				Role: llm.MessageRoleUser,
+				Content: []llm.Content{
+					{
+						Type: llm.ContentTypeText,
+						Text: "Hello, world!",
+					},
+				},
+			},
+		},
+		System: []llm.SystemContent{
+			{
+				Text: "You are a helpful assistant.",
+			},
+		},
+	}
+
+	// Build the Gemini request
+	gemReq, err := service.buildGeminiRequest(req)
+	if err != nil {
+		t.Fatalf("Failed to build Gemini request: %v", err)
+	}
+
+	// Verify the system instruction
+	if gemReq.SystemInstruction == nil {
+		t.Fatalf("Expected system instruction, got nil")
+	}
+	if len(gemReq.SystemInstruction.Parts) != 1 {
+		t.Fatalf("Expected 1 system part, got %d", len(gemReq.SystemInstruction.Parts))
+	}
+	if gemReq.SystemInstruction.Parts[0].Text != "You are a helpful assistant." {
+		t.Fatalf("Expected system text 'You are a helpful assistant.', got '%s'", gemReq.SystemInstruction.Parts[0].Text)
+	}
+
+	// Verify the contents
+	if len(gemReq.Contents) != 1 {
+		t.Fatalf("Expected 1 content, got %d", len(gemReq.Contents))
+	}
+	if len(gemReq.Contents[0].Parts) != 1 {
+		t.Fatalf("Expected 1 part, got %d", len(gemReq.Contents[0].Parts))
+	}
+	if gemReq.Contents[0].Parts[0].Text != "Hello, world!" {
+		t.Fatalf("Expected text 'Hello, world!', got '%s'", gemReq.Contents[0].Parts[0].Text)
+	}
+	// Verify the role is set correctly
+	if gemReq.Contents[0].Role != "user" {
+		t.Fatalf("Expected role 'user', got '%s'", gemReq.Contents[0].Role)
+	}
+}
+
+func TestConvertToolSchemas(t *testing.T) {
+	// Create a simple tool with a JSON schema
+	schema := `{
+		"type": "object",
+		"properties": {
+			"name": {
+				"type": "string",
+				"description": "The name of the person"
+			},
+			"age": {
+				"type": "integer",
+				"description": "The age of the person"
+			}
+		},
+		"required": ["name"]
+	}`
+
+	tools := []*llm.Tool{
+		{
+			Name:        "get_person",
+			Description: "Get information about a person",
+			InputSchema: json.RawMessage(schema),
+		},
+	}
+
+	// Convert the tools
+	decls, err := convertToolSchemas(tools)
+	if err != nil {
+		t.Fatalf("Failed to convert tool schemas: %v", err)
+	}
+
+	// Verify the result
+	if len(decls) != 1 {
+		t.Fatalf("Expected 1 declaration, got %d", len(decls))
+	}
+	if decls[0].Name != "get_person" {
+		t.Fatalf("Expected name 'get_person', got '%s'", decls[0].Name)
+	}
+	if decls[0].Description != "Get information about a person" {
+		t.Fatalf("Expected description 'Get information about a person', got '%s'", decls[0].Description)
+	}
+
+	// Verify the schema properties
+	if decls[0].Parameters.Type != 6 { // DataTypeOBJECT
+		t.Fatalf("Expected type OBJECT (6), got %d", decls[0].Parameters.Type)
+	}
+	if len(decls[0].Parameters.Properties) != 2 {
+		t.Fatalf("Expected 2 properties, got %d", len(decls[0].Parameters.Properties))
+	}
+	if decls[0].Parameters.Properties["name"].Type != 1 { // DataTypeSTRING
+		t.Fatalf("Expected name type STRING (1), got %d", decls[0].Parameters.Properties["name"].Type)
+	}
+	if decls[0].Parameters.Properties["age"].Type != 3 { // DataTypeINTEGER
+		t.Fatalf("Expected age type INTEGER (3), got %d", decls[0].Parameters.Properties["age"].Type)
+	}
+	if len(decls[0].Parameters.Required) != 1 || decls[0].Parameters.Required[0] != "name" {
+		t.Fatalf("Expected required field 'name', got %v", decls[0].Parameters.Required)
+	}
+}
+
+func TestService_Do_MockResponse(t *testing.T) {
+	// This is a mock test that doesn't make actual API calls
+	// Create a mock HTTP client that returns a predefined response
+
+	// Create a Service with a mock client
+	service := &Service{
+		Model:  DefaultModel,
+		APIKey: "test-api-key",
+		// We would use a mock HTTP client here in a real test
+	}
+
+	// Create a sample request
+	ir := &llm.Request{
+		Messages: []llm.Message{
+			{
+				Role: llm.MessageRoleUser,
+				Content: []llm.Content{
+					{
+						Type: llm.ContentTypeText,
+						Text: "Hello",
+					},
+				},
+			},
+		},
+	}
+
+	// In a real test, we would execute service.Do with a mock client
+	// and verify the response structure
+
+	// For now, we'll just test that buildGeminiRequest works correctly
+	_, err := service.buildGeminiRequest(ir)
+	if err != nil {
+		t.Fatalf("Failed to build request: %v", err)
+	}
+}
+
+func TestConvertResponseWithToolCall(t *testing.T) {
+	// Create a mock Gemini response with a function call
+	gemRes := &gemini.Response{
+		Candidates: []gemini.Candidate{
+			{
+				Content: gemini.Content{
+					Parts: []gemini.Part{
+						{
+							FunctionCall: &gemini.FunctionCall{
+								Name: "bash",
+								Args: map[string]any{
+									"command": "cat README.md",
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+	}
+
+	// Convert the response
+	content := convertGeminiResponseToContent(gemRes)
+
+	// Verify that content has a tool use
+	if len(content) != 1 {
+		t.Fatalf("Expected 1 content item, got %d", len(content))
+	}
+
+	if content[0].Type != llm.ContentTypeToolUse {
+		t.Fatalf("Expected content type ToolUse, got %s", content[0].Type)
+	}
+
+	if content[0].ToolName != "bash" {
+		t.Fatalf("Expected tool name 'bash', got '%s'", content[0].ToolName)
+	}
+
+	// Verify the tool input
+	var args map[string]any
+	if err := json.Unmarshal(content[0].ToolInput, &args); err != nil {
+		t.Fatalf("Failed to unmarshal tool input: %v", err)
+	}
+
+	cmd, ok := args["command"]
+	if !ok {
+		t.Fatalf("Expected 'command' argument, not found")
+	}
+
+	if cmd != "cat README.md" {
+		t.Fatalf("Expected command 'cat README.md', got '%s'", cmd)
+	}
+}
diff --git a/llm/gem/gemini/gemini.go b/llm/gem/gemini/gemini.go
index a6b83e4..ab4788c 100644
--- a/llm/gem/gemini/gemini.go
+++ b/llm/gem/gemini/gemini.go
@@ -30,6 +30,7 @@
 
 type Content struct {
 	Parts []Part `json:"parts"`
+	Role  string `json:"role,omitempty"`
 }
 
 // Part is a part of the content.
