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