From f1007771997bd0401516eda87a7e0ac92f269680 Mon Sep 17 00:00:00 2001 From: adamdottv <2363879+adamdottv@users.noreply.github.com> Date: Fri, 9 May 2025 13:37:13 -0500 Subject: wip: logging improvements --- internal/llm/agent/agent.go | 8 +++++--- internal/llm/agent/mcp-tools.go | 10 +++++----- internal/llm/agent/tools.go | 2 +- internal/llm/prompt/prompt.go | 4 ++-- internal/llm/prompt/prompt_test.go | 6 +++++- internal/llm/provider/anthropic.go | 12 ++++++------ internal/llm/provider/gemini.go | 8 ++++---- internal/llm/provider/openai.go | 8 ++++---- internal/llm/provider/provider.go | 20 ++++++++++---------- internal/llm/tools/edit.go | 12 ++++++------ internal/llm/tools/patch.go | 8 ++++---- internal/llm/tools/write.go | 6 +++--- 12 files changed, 55 insertions(+), 49 deletions(-) (limited to 'internal/llm') diff --git a/internal/llm/agent/agent.go b/internal/llm/agent/agent.go index 695826cdf..295ac4654 100644 --- a/internal/llm/agent/agent.go +++ b/internal/llm/agent/agent.go @@ -8,6 +8,8 @@ import ( "sync" "time" + "log/slog" + "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/llm/models" "github.com/opencode-ai/opencode/internal/llm/prompt" @@ -177,7 +179,7 @@ func (a *agent) Run(ctx context.Context, sessionID string, content string, attac a.activeRequests.Store(sessionID, cancel) go func() { - logging.Debug("Request started", "sessionID", sessionID) + slog.Debug("Request started", "sessionID", sessionID) defer logging.RecoverPanic("agent.Run", func() { events <- a.err(fmt.Errorf("panic while running the agent")) }) @@ -189,7 +191,7 @@ func (a *agent) Run(ctx context.Context, sessionID string, content string, attac if result.Err() != nil && !errors.Is(result.Err(), ErrRequestCancelled) && !errors.Is(result.Err(), context.Canceled) { status.Error(result.Err().Error()) } - logging.Debug("Request completed", "sessionID", sessionID) + slog.Debug("Request completed", "sessionID", sessionID) a.activeRequests.Delete(sessionID) cancel() events <- result @@ -276,7 +278,7 @@ func (a *agent) processGeneration(ctx context.Context, sessionID, content string } return a.err(fmt.Errorf("failed to process events: %w", err)) } - logging.Info("Result", "message", agentMessage.FinishReason(), "toolResults", toolResults) + slog.Info("Result", "message", agentMessage.FinishReason(), "toolResults", toolResults) if (agentMessage.FinishReason() == message.FinishReasonToolUse) && toolResults != nil { // We are not done, we need to respond with the tool response messages = append(messages, agentMessage, *toolResults) diff --git a/internal/llm/agent/mcp-tools.go b/internal/llm/agent/mcp-tools.go index 237560641..9966b99d9 100644 --- a/internal/llm/agent/mcp-tools.go +++ b/internal/llm/agent/mcp-tools.go @@ -7,9 +7,9 @@ import ( "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/llm/tools" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/permission" "github.com/opencode-ai/opencode/internal/version" + "log/slog" "github.com/mark3labs/mcp-go/client" "github.com/mark3labs/mcp-go/mcp" @@ -146,13 +146,13 @@ func getTools(ctx context.Context, name string, m config.MCPServer, permissions _, err := c.Initialize(ctx, initRequest) if err != nil { - logging.Error("error initializing mcp client", "error", err) + slog.Error("error initializing mcp client", "error", err) return stdioTools } toolsRequest := mcp.ListToolsRequest{} tools, err := c.ListTools(ctx, toolsRequest) if err != nil { - logging.Error("error listing tools", "error", err) + slog.Error("error listing tools", "error", err) return stdioTools } for _, t := range tools.Tools { @@ -175,7 +175,7 @@ func GetMcpTools(ctx context.Context, permissions permission.Service) []tools.Ba m.Args..., ) if err != nil { - logging.Error("error creating mcp client", "error", err) + slog.Error("error creating mcp client", "error", err) continue } @@ -186,7 +186,7 @@ func GetMcpTools(ctx context.Context, permissions permission.Service) []tools.Ba client.WithHeaders(m.Headers), ) if err != nil { - logging.Error("error creating mcp client", "error", err) + slog.Error("error creating mcp client", "error", err) continue } mcpTools = append(mcpTools, getTools(ctx, name, m, permissions, c)...) diff --git a/internal/llm/agent/tools.go b/internal/llm/agent/tools.go index 43e5978e4..b337efb59 100644 --- a/internal/llm/agent/tools.go +++ b/internal/llm/agent/tools.go @@ -33,7 +33,7 @@ func CoderAgentTools( tools.NewGlobTool(), tools.NewGrepTool(), tools.NewLsTool(), - tools.NewSourcegraphTool(), + // tools.NewSourcegraphTool(), tools.NewViewTool(lspClients), tools.NewPatchTool(lspClients, permissions, history), tools.NewWriteTool(lspClients, permissions, history), diff --git a/internal/llm/prompt/prompt.go b/internal/llm/prompt/prompt.go index 83ec7442f..769fd51ab 100644 --- a/internal/llm/prompt/prompt.go +++ b/internal/llm/prompt/prompt.go @@ -9,7 +9,7 @@ import ( "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/llm/models" - "github.com/opencode-ai/opencode/internal/logging" + "log/slog" ) func GetAgentPrompt(agentName config.AgentName, provider models.ModelProvider) string { @@ -28,7 +28,7 @@ func GetAgentPrompt(agentName config.AgentName, provider models.ModelProvider) s if agentName == config.AgentCoder || agentName == config.AgentTask { // Add context from project-specific instruction files if they exist contextContent := getContextFromPaths() - logging.Debug("Context content", "Context", contextContent) + slog.Debug("Context content", "Context", contextContent) if contextContent != "" { return fmt.Sprintf("%s\n\n# Project-Specific Context\n Make sure to follow the instructions in the context below\n%s", basePrompt, contextContent) } diff --git a/internal/llm/prompt/prompt_test.go b/internal/llm/prompt/prompt_test.go index 405ad5194..fe492b136 100644 --- a/internal/llm/prompt/prompt_test.go +++ b/internal/llm/prompt/prompt_test.go @@ -2,6 +2,7 @@ package prompt import ( "fmt" + "log/slog" "os" "path/filepath" "testing" @@ -14,8 +15,11 @@ import ( func TestGetContextFromPaths(t *testing.T) { t.Parallel() + lvl := new(slog.LevelVar) + lvl.Set(slog.LevelDebug) + tmpDir := t.TempDir() - _, err := config.Load(tmpDir, false) + _, err := config.Load(tmpDir, false, lvl) if err != nil { t.Fatalf("Failed to load config: %v", err) } diff --git a/internal/llm/provider/anthropic.go b/internal/llm/provider/anthropic.go index edd1c1d70..9c599df5b 100644 --- a/internal/llm/provider/anthropic.go +++ b/internal/llm/provider/anthropic.go @@ -15,9 +15,9 @@ import ( "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/llm/models" "github.com/opencode-ai/opencode/internal/llm/tools" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/message" "github.com/opencode-ai/opencode/internal/status" + "log/slog" ) type anthropicOptions struct { @@ -107,7 +107,7 @@ func (a *anthropicClient) convertMessages(messages []message.Message) (anthropic } if len(blocks) == 0 { - logging.Warn("There is a message without content, investigate, this should not happen") + slog.Warn("There is a message without content, investigate, this should not happen") continue } anthropicMessages = append(anthropicMessages, anthropic.NewAssistantMessage(blocks...)) @@ -210,7 +210,7 @@ func (a *anthropicClient) send(ctx context.Context, messages []message.Message, cfg := config.Get() if cfg.Debug { jsonData, _ := json.Marshal(preparedMessages) - logging.Debug("Prepared messages", "messages", string(jsonData)) + slog.Debug("Prepared messages", "messages", string(jsonData)) } attempts := 0 @@ -222,7 +222,7 @@ func (a *anthropicClient) send(ctx context.Context, messages []message.Message, ) // If there is an error we are going to see if we can retry the call if err != nil { - logging.Error("Error in Anthropic API call", "error", err) + slog.Error("Error in Anthropic API call", "error", err) retry, after, retryErr := a.shouldRetry(attempts, err) if retryErr != nil { return nil, retryErr @@ -259,7 +259,7 @@ func (a *anthropicClient) stream(ctx context.Context, messages []message.Message cfg := config.Get() if cfg.Debug { jsonData, _ := json.Marshal(preparedMessages) - logging.Debug("Prepared messages", "messages", string(jsonData)) + slog.Debug("Prepared messages", "messages", string(jsonData)) } attempts := 0 eventChan := make(chan ProviderEvent) @@ -277,7 +277,7 @@ func (a *anthropicClient) stream(ctx context.Context, messages []message.Message event := anthropicStream.Current() err := accumulatedMessage.Accumulate(event) if err != nil { - logging.Warn("Error accumulating message", "error", err) + slog.Warn("Error accumulating message", "error", err) continue } diff --git a/internal/llm/provider/gemini.go b/internal/llm/provider/gemini.go index 2986c715e..c37aee4b6 100644 --- a/internal/llm/provider/gemini.go +++ b/internal/llm/provider/gemini.go @@ -13,11 +13,11 @@ import ( "github.com/google/uuid" "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/llm/tools" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/message" "github.com/opencode-ai/opencode/internal/status" "google.golang.org/api/iterator" "google.golang.org/api/option" + "log/slog" ) type geminiOptions struct { @@ -42,7 +42,7 @@ func newGeminiClient(opts providerClientOptions) GeminiClient { client, err := genai.NewClient(context.Background(), option.WithAPIKey(opts.apiKey)) if err != nil { - logging.Error("Failed to create Gemini client", "error", err) + slog.Error("Failed to create Gemini client", "error", err) return nil } @@ -176,7 +176,7 @@ func (g *geminiClient) send(ctx context.Context, messages []message.Message, too cfg := config.Get() if cfg.Debug { jsonData, _ := json.Marshal(geminiMessages) - logging.Debug("Prepared messages", "messages", string(jsonData)) + slog.Debug("Prepared messages", "messages", string(jsonData)) } attempts := 0 @@ -263,7 +263,7 @@ func (g *geminiClient) stream(ctx context.Context, messages []message.Message, t cfg := config.Get() if cfg.Debug { jsonData, _ := json.Marshal(geminiMessages) - logging.Debug("Prepared messages", "messages", string(jsonData)) + slog.Debug("Prepared messages", "messages", string(jsonData)) } attempts := 0 diff --git a/internal/llm/provider/openai.go b/internal/llm/provider/openai.go index 3bf8a6d42..777d9d8cc 100644 --- a/internal/llm/provider/openai.go +++ b/internal/llm/provider/openai.go @@ -14,9 +14,9 @@ import ( "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/llm/models" "github.com/opencode-ai/opencode/internal/llm/tools" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/message" "github.com/opencode-ai/opencode/internal/status" + "log/slog" ) type openaiOptions struct { @@ -199,7 +199,7 @@ func (o *openaiClient) send(ctx context.Context, messages []message.Message, too cfg := config.Get() if cfg.Debug { jsonData, _ := json.Marshal(params) - logging.Debug("Prepared messages", "messages", string(jsonData)) + slog.Debug("Prepared messages", "messages", string(jsonData)) } attempts := 0 for { @@ -256,7 +256,7 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t cfg := config.Get() if cfg.Debug { jsonData, _ := json.Marshal(params) - logging.Debug("Prepared messages", "messages", string(jsonData)) + slog.Debug("Prepared messages", "messages", string(jsonData)) } attempts := 0 @@ -427,7 +427,7 @@ func WithReasoningEffort(effort string) OpenAIOption { case "low", "medium", "high": defaultReasoningEffort = effort default: - logging.Warn("Invalid reasoning effort, using default: medium") + slog.Warn("Invalid reasoning effort, using default: medium") } options.reasoningEffort = defaultReasoningEffort } diff --git a/internal/llm/provider/provider.go b/internal/llm/provider/provider.go index 6aaf9ff09..45c63acac 100644 --- a/internal/llm/provider/provider.go +++ b/internal/llm/provider/provider.go @@ -6,8 +6,8 @@ import ( "github.com/opencode-ai/opencode/internal/llm/models" "github.com/opencode-ai/opencode/internal/llm/tools" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/message" + "log/slog" ) type EventType string @@ -166,13 +166,13 @@ func (p *baseProvider[C]) SendMessages(ctx context.Context, messages []message.M messages = p.cleanMessages(messages) response, err := p.client.send(ctx, messages, tools) if err == nil && response != nil { - logging.Debug("API request token usage", + slog.Debug("API request token usage", "model", p.options.model.Name, "input_tokens", response.Usage.InputTokens, "output_tokens", response.Usage.OutputTokens, "cache_creation_tokens", response.Usage.CacheCreationTokens, "cache_read_tokens", response.Usage.CacheReadTokens, - "total_tokens", response.Usage.InputTokens + response.Usage.OutputTokens) + "total_tokens", response.Usage.InputTokens+response.Usage.OutputTokens) } return response, err } @@ -188,30 +188,30 @@ func (p *baseProvider[C]) MaxTokens() int64 { func (p *baseProvider[C]) StreamResponse(ctx context.Context, messages []message.Message, tools []tools.BaseTool) <-chan ProviderEvent { messages = p.cleanMessages(messages) eventChan := p.client.stream(ctx, messages, tools) - + // Create a new channel to intercept events wrappedChan := make(chan ProviderEvent) - + go func() { defer close(wrappedChan) - + for event := range eventChan { // Pass the event through wrappedChan <- event - + // Log token usage when we get the complete event if event.Type == EventComplete && event.Response != nil { - logging.Debug("API streaming request token usage", + slog.Debug("API streaming request token usage", "model", p.options.model.Name, "input_tokens", event.Response.Usage.InputTokens, "output_tokens", event.Response.Usage.OutputTokens, "cache_creation_tokens", event.Response.Usage.CacheCreationTokens, "cache_read_tokens", event.Response.Usage.CacheReadTokens, - "total_tokens", event.Response.Usage.InputTokens + event.Response.Usage.OutputTokens) + "total_tokens", event.Response.Usage.InputTokens+event.Response.Usage.OutputTokens) } } }() - + return wrappedChan } diff --git a/internal/llm/tools/edit.go b/internal/llm/tools/edit.go index a5f0687cb..44787f525 100644 --- a/internal/llm/tools/edit.go +++ b/internal/llm/tools/edit.go @@ -12,9 +12,9 @@ import ( "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/diff" "github.com/opencode-ai/opencode/internal/history" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/lsp" "github.com/opencode-ai/opencode/internal/permission" + "log/slog" ) type EditParams struct { @@ -234,7 +234,7 @@ func (e *editTool) createNewFile(ctx context.Context, filePath, content string) _, err = e.files.CreateVersion(ctx, sessionID, filePath, content) if err != nil { // Log error but don't fail the operation - logging.Debug("Error creating file history version", "error", err) + slog.Debug("Error creating file history version", "error", err) } recordFileWrite(filePath) @@ -347,13 +347,13 @@ func (e *editTool) deleteContent(ctx context.Context, filePath, oldString string // User Manually changed the content store an intermediate version _, err = e.files.CreateVersion(ctx, sessionID, filePath, oldContent) if err != nil { - logging.Debug("Error creating file history version", "error", err) + slog.Debug("Error creating file history version", "error", err) } } // Store the new version _, err = e.files.CreateVersion(ctx, sessionID, filePath, "") if err != nil { - logging.Debug("Error creating file history version", "error", err) + slog.Debug("Error creating file history version", "error", err) } recordFileWrite(filePath) @@ -467,13 +467,13 @@ func (e *editTool) replaceContent(ctx context.Context, filePath, oldString, newS // User Manually changed the content store an intermediate version _, err = e.files.CreateVersion(ctx, sessionID, filePath, oldContent) if err != nil { - logging.Debug("Error creating file history version", "error", err) + slog.Debug("Error creating file history version", "error", err) } } // Store the new version _, err = e.files.CreateVersion(ctx, sessionID, filePath, newContent) if err != nil { - logging.Debug("Error creating file history version", "error", err) + slog.Debug("Error creating file history version", "error", err) } recordFileWrite(filePath) diff --git a/internal/llm/tools/patch.go b/internal/llm/tools/patch.go index dcd3027b5..e0c0bf5bc 100644 --- a/internal/llm/tools/patch.go +++ b/internal/llm/tools/patch.go @@ -11,9 +11,9 @@ import ( "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/diff" "github.com/opencode-ai/opencode/internal/history" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/lsp" "github.com/opencode-ai/opencode/internal/permission" + "log/slog" ) type PatchParams struct { @@ -318,7 +318,7 @@ func (p *patchTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error // If not adding a file, create history entry for existing file _, err = p.files.Create(ctx, sessionID, absPath, oldContent) if err != nil { - logging.Debug("Error creating file history", "error", err) + slog.Debug("Error creating file history", "error", err) } } @@ -326,7 +326,7 @@ func (p *patchTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error // User manually changed content, store intermediate version _, err = p.files.CreateVersion(ctx, sessionID, absPath, oldContent) if err != nil { - logging.Debug("Error creating file history version", "error", err) + slog.Debug("Error creating file history version", "error", err) } } @@ -337,7 +337,7 @@ func (p *patchTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error _, err = p.files.CreateVersion(ctx, sessionID, absPath, newContent) } if err != nil { - logging.Debug("Error creating file history version", "error", err) + slog.Debug("Error creating file history version", "error", err) } // Record file operations diff --git a/internal/llm/tools/write.go b/internal/llm/tools/write.go index decc51e47..617d69c29 100644 --- a/internal/llm/tools/write.go +++ b/internal/llm/tools/write.go @@ -12,9 +12,9 @@ import ( "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/diff" "github.com/opencode-ai/opencode/internal/history" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/lsp" "github.com/opencode-ai/opencode/internal/permission" + "log/slog" ) type WriteParams struct { @@ -201,13 +201,13 @@ func (w *writeTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error // User Manually changed the content store an intermediate version _, err = w.files.CreateVersion(ctx, sessionID, filePath, oldContent) if err != nil { - logging.Debug("Error creating file history version", "error", err) + slog.Debug("Error creating file history version", "error", err) } } // Store the new version _, err = w.files.CreateVersion(ctx, sessionID, filePath, params.Content) if err != nil { - logging.Debug("Error creating file history version", "error", err) + slog.Debug("Error creating file history version", "error", err) } recordFileWrite(filePath) -- cgit v1.2.3