diff options
| author | Paul Buetow <paul@buetow.org> | 2025-08-16 15:58:40 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-08-16 15:58:40 +0300 |
| commit | 02cc0e3ac6c08f422f11b668c729102fcf0c7f38 (patch) | |
| tree | 3910b94e08239c3a7f0a47cdf7f092c7de58008d | |
| parent | 2caaae5863c2fd31803a6d944ced4b8b0a7b5e36 (diff) | |
logging: add -log-preview-limit flag with HEXAI_LOG_PREVIEW_LIMIT env; wire through llm.SetLogPreviewLimit; document in README
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | internal/llm/openai.go | 8 | ||||
| -rw-r--r-- | internal/llm/provider.go | 36 |
3 files changed, 30 insertions, 15 deletions
@@ -46,3 +46,4 @@ Notes: | `-context-mode` | `file-on-new-func` | `HEXAI_CONTEXT_MODE` | `minimal` `window` `file-on-new-func` `always-full` | | `-context-window-lines` | `120` | `HEXAI_CONTEXT_WINDOW_LINES` | Lines around cursor when using `window` mode. | | `-max-context-tokens` | `2000` | `HEXAI_MAX_CONTEXT_TOKENS` | Token budget for additional context. | +| `-log-preview-limit` | `0` (unlimited) | `HEXAI_LOG_PREVIEW_LIMIT` | Limit characters shown in LLM preview logs. | diff --git a/internal/llm/openai.go b/internal/llm/openai.go index 45cb1b8..7cfabc1 100644 --- a/internal/llm/openai.go +++ b/internal/llm/openai.go @@ -95,8 +95,8 @@ func (c *openAIClient) Chat(ctx context.Context, messages []Message, opts ...Req start := time.Now() c.logf("chat start model=%s temp=%.2f max_tokens=%d stop=%d messages=%d", o.Model, o.Temperature, o.MaxTokens, len(o.Stop), len(messages)) for i, m := range messages { - // Sending context (cyan) — log full content with real newlines - c.logf("msg[%d] role=%s size=%d preview=%s%s%s", i, m.Role, len(m.Content), ansiCyan, m.Content, ansiNormal) + // Sending context (cyan) + c.logf("msg[%d] role=%s size=%d preview=%s%s%s", i, m.Role, len(m.Content), ansiCyan, previewForLog(m.Content), ansiNormal) } req := oaChatRequest{Model: o.Model} req.Messages = make([]oaMessage, len(messages)) @@ -154,8 +154,8 @@ func (c *openAIClient) Chat(ctx context.Context, messages []Message, opts ...Req return "", errors.New("openai: no choices returned") } content := out.Choices[0].Message.Content - // Received context (green) — log full content with real newlines - c.logf("success choice=0 finish=%s size=%d preview=%s%s%s duration=%s", out.Choices[0].FinishReason, len(content), ansiGreen, content, ansiNormal, time.Since(start)) + // Received context (green) + c.logf("success choice=0 finish=%s size=%d preview=%s%s%s duration=%s", out.Choices[0].FinishReason, len(content), ansiGreen, previewForLog(content), ansiNormal, time.Since(start)) return content, nil } diff --git a/internal/llm/provider.go b/internal/llm/provider.go index fd9d4d3..a80b1c1 100644 --- a/internal/llm/provider.go +++ b/internal/llm/provider.go @@ -1,10 +1,10 @@ package llm import ( - "context" - "errors" - "log" - "os" + "context" + "errors" + "log" + "os" ) // Message represents a chat-style prompt message. @@ -16,8 +16,8 @@ type Message struct { // Client is a minimal LLM provider interface. // Future providers (Ollama, etc.) should implement this. type Client interface { - // Chat sends chat messages and returns the assistant text. - Chat(ctx context.Context, messages []Message, opts ...RequestOption) (string, error) + // Chat sends chat messages and returns the assistant text. + Chat(ctx context.Context, messages []Message, opts ...RequestOption) (string, error) } // Options for a request. Providers may ignore unsupported fields. @@ -41,9 +41,23 @@ func WithStop(stop ...string) RequestOption { // NewDefault returns the default provider using environment configuration. // Currently this is the OpenAI provider using OPENAI_API_KEY. func NewDefault(logger *log.Logger) (Client, error) { - apiKey := os.Getenv("OPENAI_API_KEY") - if apiKey == "" { - return nil, errors.New("OPENAI_API_KEY is not set") - } - return newOpenAIFromEnv(apiKey, logger), nil + apiKey := os.Getenv("OPENAI_API_KEY") + if apiKey == "" { + return nil, errors.New("OPENAI_API_KEY is not set") + } + return newOpenAIFromEnv(apiKey, logger), nil +} + +// Logging configuration for previews +var logPreviewLimit int // 0 means unlimited + +// SetLogPreviewLimit sets the maximum number of characters to log for +// request/response previews. Set to 0 for unlimited. +func SetLogPreviewLimit(n int) { logPreviewLimit = n } + +func previewForLog(s string) string { + if logPreviewLimit > 0 { + return trimPreview(s, logPreviewLimit) + } + return s } |
