9p: use agent.Complete directly, remove mgr/complete.go

Code completion no longer routes through the manager. Callers
invoke agent.Complete() — the one-shot ephemeral agent.
This commit is contained in:
Levi Neely 2026-07-29 22:19:22 +02:00
parent 82a7f585f2
commit 3a8b1ba4a5
3 changed files with 3 additions and 105 deletions

View File

@ -575,7 +575,7 @@ func (a *DBusAdapter) Route(task, backendName string) (string, *dbus.Error) {
} }
func (a *DBusAdapter) Complete(cwd, filePath, prefix, suffix, extraContext string) (string, *dbus.Error) { func (a *DBusAdapter) Complete(cwd, filePath, prefix, suffix, extraContext string) (string, *dbus.Error) {
result, err := a.mgr.Complete(cwd, filePath, prefix, suffix, extraContext) result, err := agent.Complete(cwd, filePath, prefix, suffix, extraContext)
if err != nil { if err != nil {
return "", dbus.MakeFailedError(err) return "", dbus.MakeFailedError(err)
} }

View File

@ -1,103 +0,0 @@
package mgr
import (
"context"
"fmt"
"hash/crc32"
"ollie/backend"
"ollie/paths"
"os"
"strings"
)
// --- Code Completion ---
// Complete performs a stateless one-shot code completion via backend.Generate.
func (s *Manager) Complete(cwd, filePath, prefix, suffix, extraContext string) (string, error) {
if cwd == "" {
cwd, _ = os.Getwd()
}
cwd = paths.ExpandHome(os.ExpandEnv(cwd))
model := os.Getenv("OLLIE_COMPLETE_MODEL")
backendName := os.Getenv("OLLIE_COMPLETE_BACKEND")
if model == "" || backendName == "" {
return "", fmt.Errorf("OLLIE_COMPLETE_MODEL and OLLIE_COMPLETE_BACKEND must be set")
}
const prefixMax = 12000
const suffixMax = 1000
if len(prefix) > prefixMax {
prefix = prefix[len(prefix)-prefixMax:]
}
if len(suffix) > suffixMax {
suffix = suffix[:suffixMax]
}
fileHint := ""
if filePath != "" {
fileHint = " in " + filePath
}
contextBlock := ""
if extraContext != "" {
contextBlock = "\n" + extraContext
}
prompt := fmt.Sprintf(`Implement the code at the cursor%s. The prefix ends at the point where new code is needed. Write the implementation — do not echo stubs, TODOs, or placeholder returns from the prefix. Output ONLY raw code. No reasoning, no shell commands, no explanations, no markdown fences, no backticks, no preamble. Your entire response must be valid code that can be inserted directly into the file.
%s
<prefix>
%s
</prefix>
<suffix>
%s
</suffix>`, fileHint, contextBlock, prefix, suffix)
result, err := backend.Generate(context.Background(), backend.GenerateRequest{
Prompt: prompt,
Backend: backendName,
Model: model,
})
if err != nil {
return "", err
}
result = stripCompletionNoise(result)
result = stripPrefixEcho(prefix, result)
return result, nil
}
func stripCompletionNoise(s string) string {
var lines []string
for _, line := range strings.Split(s, "\n") {
trimmed := strings.TrimSpace(line)
if strings.HasPrefix(trimmed, "```") {
continue
}
if trimmed == "<prefix>" || trimmed == "</prefix>" ||
trimmed == "<suffix>" || trimmed == "</suffix>" {
continue
}
if strings.HasPrefix(trimmed, ":: ") {
continue
}
lines = append(lines, line)
}
return strings.Join(lines, "\n")
}
func stripPrefixEcho(prefix, result string) string {
tailMax := 200
if len(prefix) < tailMax {
tailMax = len(prefix)
}
for i := tailMax; i > 0; i-- {
tail := prefix[len(prefix)-i:]
if strings.HasPrefix(result, tail) {
return result[len(tail):]
}
}
return result
}
func crc32Str(s string) uint32 {
return crc32.ChecksumIEEE([]byte(s))
}

View File

@ -22,6 +22,7 @@ import (
"ollie/paths" "ollie/paths"
"olliesrv/fs" "olliesrv/fs"
"olliesrv/mgr" "olliesrv/mgr"
"ollie/agent"
"9fans.net/go/plan9" "9fans.net/go/plan9"
) )
@ -900,7 +901,7 @@ func (s *Server) write(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
// If not JSON, treat entire write as prefix (simple mode) // If not JSON, treat entire write as prefix (simple mode)
req.Prefix = strings.TrimSpace(string(fc.Data)) req.Prefix = strings.TrimSpace(string(fc.Data))
} }
result, err := s.sessionMgr.Complete(req.CWD, req.FilePath, req.Prefix, req.Suffix, req.ExtraContext) result, err := agent.Complete(req.CWD, req.FilePath, req.Prefix, req.Suffix, req.ExtraContext)
if err != nil { if err != nil {
return errFcall(fc, err.Error()) return errFcall(fc, err.Error())
} }