diff --git a/kate/ollie_ghost.cpp b/kate/ollie_ghost.cpp index 1e49165..128c62f 100644 --- a/kate/ollie_ghost.cpp +++ b/kate/ollie_ghost.cpp @@ -313,33 +313,45 @@ void OllieGhostProvider::requestCompletion() m_triggerCursor = cursor; m_requesting = true; - // Build context with optional backend/model override - QString context; - if (m_plugin) { - QString backend = m_plugin->completionBackend(); - QString model = m_plugin->completionModel(); - if (!backend.isEmpty()) - context += QStringLiteral("backend=") + backend + QStringLiteral("\n"); - if (!model.isEmpty()) - context += QStringLiteral("model=") + model + QStringLiteral("\n"); - } + // Trim prefix/suffix to limits matching agent/complete.go + const int prefixMax = 12000; + const int suffixMax = 1000; + if (prefix.size() > prefixMax) + prefix = prefix.right(prefixMax); + if (suffix.size() > suffixMax) + suffix = suffix.left(suffixMax); - // Build JSON request for ollie-9p rdwr complete + // Build the completion prompt + QString fileHint; + if (!filePath.isEmpty()) + fileHint = " in " + filePath; + QString contextBlock; + if (!cwd.isEmpty()) + contextBlock = "\nWorking directory: " + cwd; + + QString prompt = QString( + "Implement the code at the cursor%2. 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.%1" + "\n%3\n\n\n%4\n" + ).arg(contextBlock).arg(fileHint).arg(prefix).arg(suffix); + + // Build JSON request for ollie-9p rdwr generate QJsonObject request; - request["file"] = filePath; - request["prefix"] = prefix; - request["suffix"] = suffix; - if (!context.isEmpty()) { - request["context"] = context; - } + request["prompt"] = prompt; + + QString backendName = m_plugin ? m_plugin->completionBackend() : QString(); + QString modelName = m_plugin ? m_plugin->completionModel() : QString(); + if (!backendName.isEmpty()) + request["backend"] = backendName; + if (!modelName.isEmpty()) + request["model"] = modelName; QJsonDocument docJson(request); QString jsonStr = QString::fromUtf8(docJson.toJson(QJsonDocument::Compact)); - // Run ollie-9p rdwr complete + // Run ollie-9p rdwr generate QProcess *process = new QProcess(this); process->setProgram("ollie-9p"); - process->setArguments({"rdwr", "complete"}); + process->setArguments({"rdwr", "generate"}); connect(process, QOverload::of(&QProcess::finished), this, [this, process](int exitCode, QProcess::ExitStatus exitStatus) { @@ -367,7 +379,15 @@ void OllieGhostProvider::onCompletionReply(const QString &result) if (m_view->cursorPosition() != m_triggerCursor) return; - QStringList lines = result.split(QStringLiteral("\n")); + // Strip completion noise (safety net — prompt asks for raw code only) + QString stripped = stripCompletionNoise(result); + // Strip prefix echo (model may repeat trailing prefix chars) + stripped = stripPrefixEcho(stripped); + + if (stripped.isEmpty()) + return; + + QStringList lines = stripped.split(QStringLiteral("\n")); // Append to history and advance index m_history.append(lines); @@ -488,4 +508,37 @@ QString OllieGhostProvider::gatherSuffix() const KTextEditor::Cursor endCursor(doc->lines() - 1, doc->lineLength(doc->lines() - 1)); KTextEditor::Range suffixRange(cursor, endCursor); return doc->text(suffixRange); +} + +// === Completion post-processing helpers (mirrors agent/complete.go) === + +static QString stripCompletionNoise(const QString &s) +{ + QStringList lines = s.split('\n'); + QStringList filtered; + for (const QString &line : lines) { + QString trimmed = line.trimmed(); + if (trimmed.startsWith("```")) + continue; + if (trimmed == "" || trimmed == "" || + trimmed == "" || trimmed == "") + continue; + if (trimmed.startsWith(":: ")) + continue; + filtered.append(line); + } + return filtered.join('\n'); +} + +static QString stripPrefixEcho(const QString &prefix, const QString &result) +{ + int tailMax = 200; + if (prefix.size() < tailMax) + tailMax = prefix.size(); + for (int i = tailMax; i > 0; --i) { + QString tail = prefix.right(i); + if (result.startsWith(tail)) + return result.mid(i); + } + return result; } \ No newline at end of file