From 7295dc337468eee47046ecf8477d50bb4931ed7a Mon Sep 17 00:00:00 2001 From: Cheikh Seck Date: Sat, 4 Apr 2026 07:30:09 +0000 Subject: [PATCH 1/3] change default temp. to be more deterministic --- internal/wizard/wizard.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/wizard/wizard.go b/internal/wizard/wizard.go index ba72316..1338614 100644 --- a/internal/wizard/wizard.go +++ b/internal/wizard/wizard.go @@ -192,7 +192,7 @@ func RunWizard(destination string) error { provider.Description, _ = prompt(reader, "Description", getDefault("description", "This model is red")) - tempStr, _ := prompt(reader, "Temperature (0.0-1.0). The higher the value, the more random the output.", getDefault("temperature", "0.5")) + tempStr, _ := prompt(reader, "Temperature (0.0-1.0). The higher the value, the more random the output.", getDefault("temperature", "0.2")) if tempStr != "" { if val, err := strconv.ParseFloat(tempStr, 64); err == nil { provider.Temperature = &val From ed6856d26c2b62c7b0e9b92fa1cb691267e5dbf9 Mon Sep 17 00:00:00 2001 From: Cheikh Seck Date: Sat, 4 Apr 2026 08:24:09 +0000 Subject: [PATCH 2/3] move isntructions as system message --- cmd/godex/main.go | 14 ++++++++++++ internal/providers/ollama.go | 37 ++++++++++++++++++++++++++++---- internal/providers/openrouter.go | 25 +++++++++++++++------ internal/providers/prompt.go | 33 ++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 internal/providers/prompt.go diff --git a/cmd/godex/main.go b/cmd/godex/main.go index 1d085d5..fbf9dd2 100644 --- a/cmd/godex/main.go +++ b/cmd/godex/main.go @@ -1693,6 +1693,16 @@ func getServerNames(servers []MCPServer) []string { return names } +func isOllamaPromptTooLong(err error) bool { + if err == nil { + return false + } + msg := err.Error() + return strings.Contains(msg, "ollama responded with 400") && + strings.Contains(msg, "prompt too long") && + strings.Contains(msg, "max context length") +} + func runSinglePrompt(ctx context.Context, provider *config.Provider, prompt string, autoConfirm bool, servers []MCPServer) error { tree, _ := godexcontext.BuildTree(".") wd, _ := os.Getwd() @@ -1829,6 +1839,10 @@ func runToolLoop(ctx context.Context, provider *config.Provider, servers []MCPSe default: } if err != nil { + if isOllamaPromptTooLong(err) { + fmt.Println("\n[Ollama] Prompt exceeded the model context limit.") + fmt.Println("Switch to a larger model to continue, or run `/commit`, then `/clear-context`, then `/commit-pull` to resume with a clean context window.") + } return "", err } diff --git a/internal/providers/ollama.go b/internal/providers/ollama.go index 650ec2a..db4b2ff 100644 --- a/internal/providers/ollama.go +++ b/internal/providers/ollama.go @@ -30,6 +30,7 @@ type ollamaProvider struct { cfg *config.Provider temperature *float64 client *http.Client + systemPrompt string messages []map[string]string mu sync.Mutex sendMu sync.Mutex @@ -217,10 +218,22 @@ func (o *ollamaProvider) Send(ctx context.Context, prompt string) (string, error defer o.sendMu.Unlock() o.mu.Lock() - o.messages = append(o.messages, map[string]string{ - "role": "user", - "content": prompt, - }) + systemPrompt, userInput := splitSystemUserPrompt(prompt) + if systemPrompt != "" { + o.systemPrompt = systemPrompt + } + if o.systemPrompt != "" { + o.ensureSystemMessage(o.systemPrompt) + } + if userInput == "" { + userInput = strings.TrimSpace(prompt) + } + if userInput != "" { + o.messages = append(o.messages, map[string]string{ + "role": "user", + "content": userInput, + }) + } ctx, cancel := context.WithCancel(ctx) o.cancelGen++ @@ -297,6 +310,22 @@ func (o *ollamaProvider) Send(ctx context.Context, prompt string) (string, error return response, nil } +func (o *ollamaProvider) ensureSystemMessage(system string) { + if strings.TrimSpace(system) == "" { + return + } + if len(o.messages) > 0 { + if role := o.messages[0]["role"]; role == "system" { + if o.messages[0]["content"] == system { + return + } + o.messages[0]["content"] = system + return + } + } + o.messages = append([]map[string]string{{"role": "system", "content": system}}, o.messages...) +} + type sendResult struct { response string totalPromptTokens int diff --git a/internal/providers/openrouter.go b/internal/providers/openrouter.go index 7906c76..cbf9a41 100644 --- a/internal/providers/openrouter.go +++ b/internal/providers/openrouter.go @@ -68,6 +68,7 @@ type openRouterProvider struct { apiKey string temperature *float64 client *http.Client + systemPrompt string messages []map[string]interface{} pendingToolCalls map[string]string // tool_call_id -> function_name for tracking tools []map[string]interface{} @@ -155,15 +156,22 @@ func newOpenRouterProvider(cfg *config.Provider) (Provider, error) { } func (p *openRouterProvider) Send(ctx context.Context, prompt string) (string, error) { - // Extract the actual user input from the prompt (everything after "User request:" or "User asked:") - userInput := extractUserInput(prompt) + systemPrompt, userInput := splitSystemUserPrompt(prompt) + if userInput == "" { + userInput = strings.TrimSpace(prompt) + } p.mu.Lock() + if systemPrompt != "" { + p.systemPrompt = systemPrompt + } // Track only the user input in history - p.messages = append(p.messages, map[string]interface{}{ - "role": "user", - "content": userInput, - }) + if userInput != "" { + p.messages = append(p.messages, map[string]interface{}{ + "role": "user", + "content": userInput, + }) + } // Sliding window: keep only the last N messages (negative = unlimited) maxHistory := getMaxHistoryMessages() if maxHistory > 0 && len(p.messages) > maxHistory { @@ -173,7 +181,10 @@ func (p *openRouterProvider) Send(ctx context.Context, prompt string) (string, e copy(messages, p.messages) p.mu.Unlock() - systemMsg := buildSystemWorkingDirMessage(prompt) + systemMsg := p.systemPrompt + if systemMsg == "" { + systemMsg = buildSystemWorkingDirMessage(prompt) + } if systemMsg != "" { messages = prependSystemMessage(messages, systemMsg) } diff --git a/internal/providers/prompt.go b/internal/providers/prompt.go new file mode 100644 index 0000000..706247e --- /dev/null +++ b/internal/providers/prompt.go @@ -0,0 +1,33 @@ +package providers + +import "strings" + +const ( + userRequestMarker = "User request:" + userAskedMarker = "User asked:" +) + +func splitSystemUserPrompt(prompt string) (string, string) { + prompt = strings.TrimSpace(prompt) + if prompt == "" { + return "", "" + } + + idx := -1 + marker := "" + if i := strings.Index(prompt, userRequestMarker); i != -1 { + idx = i + marker = userRequestMarker + } + if i := strings.Index(prompt, userAskedMarker); i != -1 && (idx == -1 || i < idx) { + idx = i + marker = userAskedMarker + } + if idx == -1 { + return "", prompt + } + + system := strings.TrimSpace(prompt[:idx]) + user := strings.TrimSpace(prompt[idx+len(marker):]) + return system, user +} From f514c6ab6e5229fd3b17bdf4bbb04690f75d7509 Mon Sep 17 00:00:00 2001 From: Cheikh Seck Date: Sat, 4 Apr 2026 08:33:36 +0000 Subject: [PATCH 3/3] prevent llm from stating it previously provided the answer --- cmd/godex/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/godex/main.go b/cmd/godex/main.go index fbf9dd2..380d6e9 100644 --- a/cmd/godex/main.go +++ b/cmd/godex/main.go @@ -872,7 +872,7 @@ promptLoop: if hasFinal { output = finalResp } else { - cprompt := fmt.Sprintf("The assistant gave the following response:\n%s\n\nSince there are no tool calls to execute, please provide a final answer based on this response.", resp) + cprompt := fmt.Sprintf("The assistant gave the following response:\n%s\n\nSince there are no tool calls to execute, please provide a final answer based on this response. Don't mention you already provided a previous answer", resp) fullPrompt = buildContinuePrompt(llmProvider, servers, fullPrompt, cprompt, round+1, maxToolRounds) continue } @@ -1883,7 +1883,7 @@ func runToolLoop(ctx context.Context, provider *config.Provider, servers []MCPSe } fmt.Printf("\n[No valid tool calls detected, asking for final answer...]\n") } - continuePrompt := fmt.Sprintf("You provided the following response:\n%s\n\nHowever, I couldn't find any valid tool calls in it. Please provide your FINAL_ANSWER now based on the information you have. Do NOT call any tools, just provide the final answer.", resp) + continuePrompt := fmt.Sprintf("You provided the following response:\n%s\n\nHowever, I couldn't find any valid tool calls in it. Please provide your FINAL_ANSWER now based on the information you have. Do NOT call any tools, just provide the final answer.Don't mention you already provided a previous answer", resp) fullPrompt = buildContinuePrompt(llmProvider, servers, input, continuePrompt, round+1, maxToolRounds)