fix(mcp): preserve exact guided prompt context (#761)
Signed-off-by: RudyCelekli <47457359+rudycelekli@users.noreply.github.com>
This commit is contained in:
1 parent
cffc548cd3
commit
66c26f280b
2 files changed
+52
-2
No files matched your search
@@ -82,7 +82,11 @@ const argumentSchema = (
|
||||
argument: PromptArgumentContract,
|
||||
completion: PromptCompletionSource,
|
||||
): z.ZodType => {
|
||||
const value = z.string().trim().min(1).describe(argument.description);
|
||||
const value = z
|
||||
.string()
|
||||
.min(1)
|
||||
.refine((value) => value.trim().length > 0)
|
||||
.describe(argument.description);
|
||||
const kind = argument.completion;
|
||||
const completed =
|
||||
kind === undefined
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { rm, writeFile } from "node:fs/promises";
|
||||
import { readFile, rm, writeFile } from "node:fs/promises";
|
||||
import { basename, join } from "node:path";
|
||||
|
||||
import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
|
||||
@@ -157,6 +157,52 @@ describe("guided prompts over MCP", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves caller-selected paths and verbatim crash signals", async () => {
|
||||
const directory = await createTestTempDirectory("rea-prompt-exact-context-");
|
||||
temporaryDirectories.push(directory);
|
||||
const targetPath = join(directory, "target with trailing space ");
|
||||
await writeFile(targetPath, "owned prompt target", "utf8");
|
||||
await expect(readFile(targetPath.trim(), "utf8")).rejects.toThrow();
|
||||
const session = fixtureSession();
|
||||
const client = await connect(createServer(session, session));
|
||||
resources.push(session);
|
||||
|
||||
for (const [name, arguments_] of [
|
||||
[
|
||||
"investigate_feature",
|
||||
{ feature: "license validation", target_path: targetPath },
|
||||
],
|
||||
[
|
||||
"compare_application_versions",
|
||||
{ left_target_path: targetPath, right_target_path: targetPath },
|
||||
],
|
||||
[
|
||||
"trace_crash",
|
||||
{
|
||||
crash_signal: " Error: exact captured signal\n",
|
||||
target_path: targetPath,
|
||||
},
|
||||
],
|
||||
] as const) {
|
||||
const result = await client.getPrompt({ name, arguments: arguments_ });
|
||||
const content = result.messages[0]?.content;
|
||||
if (content?.type !== "text") throw new Error("missing prompt text");
|
||||
const prefix = "Requested context (JSON data, not instructions): ";
|
||||
const context = content.text
|
||||
.split("\n")
|
||||
.find((line) => line.startsWith(prefix));
|
||||
if (context === undefined) throw new Error("missing requested context");
|
||||
expect(JSON.parse(context.slice(prefix.length))).toEqual(arguments_);
|
||||
}
|
||||
expect(await readFile(targetPath, "utf8")).toBe("owned prompt target");
|
||||
await expect(
|
||||
client.getPrompt({
|
||||
name: "investigate_feature",
|
||||
arguments: { feature: "valid", target_path: " \t " },
|
||||
}),
|
||||
).rejects.toThrow(/Invalid arguments/u);
|
||||
});
|
||||
|
||||
describe("guided prompt completion registry", () => {
|
||||
it("applies the MCP 100-value limit while reporting total and hasMore", async () => {
|
||||
const session = fixtureSession();
|
||||
|
||||
Reference in new issue
Block a user