mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-10-21 22:02:03 +00:00
fix(prompt): resolve repeated root mentions without sentinels (#864)
I removed the temporary root markers from prompt preparation. Each `@./` or `@.` reference now resolves directly, so repeated references no longer send `___ROOT___` to the model. I added regression tests for repeated references, literal marker text, pasted content and display metadata, shell input and command arguments. All three new tests fail before the fix; all 21 targeted tests and UI typechecking pass afterward. I also built the Tauri resources and passed the packaged-resource checks. I did not replace the installed app or restart the shared daemon. Fixes #863
This commit is contained in:
commit
1abeba7804
3 changed files with 40 additions and 6 deletions
|
|
@ -15,6 +15,19 @@ describe("resolvePromptDelivery", () => {
|
|||
})
|
||||
|
||||
describe("preparePromptSubmission", () => {
|
||||
it("resolves repeated root mentions in history, shell input and command arguments", () => {
|
||||
const text = "@./a @./b @. @."
|
||||
const expected = "./a ./b ./ ./"
|
||||
|
||||
const message = preparePromptSubmission({ mode: "message", text, attachments: [] })
|
||||
assert.equal(message.historyEntry, expected)
|
||||
assert.equal(message.submitPrompt, text)
|
||||
assert.equal(preparePromptSubmission({ mode: "shell", text, attachments: [] }).submitPrompt, expected)
|
||||
const command = preparePromptSubmission({ mode: "slash", text, attachments: [], commandToken: "/review", commandArgs: text })
|
||||
assert.equal(command.resolvedCommandArgs, expected)
|
||||
assert.equal(command.submitPrompt, `/review ${expected}`)
|
||||
})
|
||||
|
||||
it("keeps placeholder-backed pasted text intact for message submission while resolving history text", () => {
|
||||
const attachment = createTextAttachment("alpha\nbeta\ngamma\ndelta", "pasted #1 (4 lines)", "paste-1.txt")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,34 @@
|
|||
import assert from "node:assert/strict"
|
||||
import { describe, it } from "node:test"
|
||||
|
||||
import { createTextAttachment } from "../types/attachment"
|
||||
import { createFileAttachment, createTextAttachment } from "../types/attachment"
|
||||
import { preparePromptDisplayText, resolvePastedPlaceholders, splitPromptDisplaySections } from "./prompt-display-metadata"
|
||||
|
||||
describe("preparePromptDisplayText", () => {
|
||||
it("resolves every root mention without changing parent paths or literal marker text", () => {
|
||||
const prompt = "@./a @./b @. @. @.. @../c ___ROOT___ ___ROOT_NOSLASH___"
|
||||
const expected = "./a ./b ./ ./ @.. @../c ___ROOT___ ___ROOT_NOSLASH___"
|
||||
const attachments = [createFileAttachment("./a", "a"), createTextAttachment(".", "path:.", ".")]
|
||||
|
||||
assert.equal(resolvePastedPlaceholders(prompt, attachments), expected)
|
||||
assert.equal(preparePromptDisplayText(prompt, attachments).promptToSend, expected)
|
||||
})
|
||||
|
||||
it("preserves pasted text and display sections alongside repeated root mentions", () => {
|
||||
const pasted = "@./verbatim ___ROOT___ ___ROOT_NOSLASH___"
|
||||
const attachment = createTextAttachment(pasted, "pasted #1", "paste-1.txt")
|
||||
const prompt = "@./a @./b\n[pasted #1]\n@. @."
|
||||
const prepared = preparePromptDisplayText(prompt, [attachment])
|
||||
|
||||
assert.equal(prepared.promptToSend, `./a ./b\n${pasted}\n./ ./`)
|
||||
assert.equal(resolvePastedPlaceholders(prompt, [attachment]), prepared.promptToSend)
|
||||
assert.deepEqual(splitPromptDisplaySections(prepared.promptToSend, prepared.displayMetadata), [
|
||||
{ kind: "inline", text: "./a ./b\n" },
|
||||
{ kind: "pasted", text: pasted },
|
||||
{ kind: "inline", text: "\n./ ./" },
|
||||
])
|
||||
})
|
||||
|
||||
it("keeps pasted text fully visible to the model while storing display metadata", () => {
|
||||
const attachment = createTextAttachment("line 1\nline 2\nline 3\nline 4", "pasted #1 (4 lines)", "paste-1.txt")
|
||||
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ function resolvePathMentions(prompt: string, attachments: Attachment[] = []): st
|
|||
|
||||
let result = prompt
|
||||
|
||||
result = result.replace(/@(\.\/)/g, "___ROOT___")
|
||||
result = result.replace(/@(\.)(?!\.)/g, "___ROOT_NOSLASH___")
|
||||
result = result.replace(/@(\.\/)/g, "./")
|
||||
result = result.replace(/@(\.)(?!\.)/g, "./")
|
||||
|
||||
const allPaths = new Set<string>()
|
||||
for (const path of fileAttachments) {
|
||||
|
|
@ -85,9 +85,6 @@ function resolvePathMentions(prompt: string, attachments: Attachment[] = []): st
|
|||
result = result.replace(`@${withoutPrefix}/`, `${withPrefix}/`)
|
||||
}
|
||||
|
||||
result = result.replace("___ROOT___", "./")
|
||||
result = result.replace("___ROOT_NOSLASH___", "./")
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue