package llm import ( "context" "strings" ) // RewriteMaxRunes caps how much selected text a single rewrite will accept. A // rewrite is a focused "fix this sentence/paragraph" action, not a whole-doc // pass — bounding it keeps latency sane and the model on-task. The handler // rejects longer selections before calling the model. const RewriteMaxRunes = 2000 // RunRewrite rewrites a selected passage in the requested style (e.g. "natural", // "academic"). It is a one-shot Complete — the result is shown as a preview the // writer accepts or discards, so we want the whole rewrite before rendering. func RunRewrite(ctx context.Context, client LLMClient, text, style string) (string, error) { out, err := client.Complete(ctx, CompletionRequest{ Messages: RewriteMessages(text, style), MaxTokens: 1024, Temperature: 0.7, TopP: 0.9, RepetitionPenalty: 1.1, }) if err != nil { return "", err } return cleanRewrite(out), nil } // cleanRewrite trims the model's output down to just the rewritten passage. The // prompt asks for no quotes or preamble, but small instruct models occasionally // wrap the answer in matching quotes — strip a single surrounding pair so the // text drops cleanly into the editor. func cleanRewrite(s string) string { s = strings.TrimSpace(s) if len(s) >= 2 { first, last := s[0], s[len(s)-1] if (first == '"' && last == '"') || (first == '\'' && last == '\'') || (strings.HasPrefix(s, "“") && strings.HasSuffix(s, "”")) { s = strings.TrimSpace(strings.Trim(s, "\"'“”")) } } return s }