fix: avoid directive hits inside URLs and add tests
This commit is contained in:
29
src/auto-reply/reply.directive.test.ts
Normal file
29
src/auto-reply/reply.directive.test.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { extractVerboseDirective, extractThinkDirective } from "./reply.js";
|
||||||
|
|
||||||
|
describe("directive parsing", () => {
|
||||||
|
it("ignores verbose directive inside URL", () => {
|
||||||
|
const body = "https://x.com/verioussmith/status/1997066835133669687";
|
||||||
|
const res = extractVerboseDirective(body);
|
||||||
|
expect(res.hasDirective).toBe(false);
|
||||||
|
expect(res.cleaned).toBe(body);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("ignores think directive inside URL", () => {
|
||||||
|
const body = "see https://example.com/path/thinkstuff";
|
||||||
|
const res = extractThinkDirective(body);
|
||||||
|
expect(res.hasDirective).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("matches verbose with leading space", () => {
|
||||||
|
const res = extractVerboseDirective(" please /verbose on now");
|
||||||
|
expect(res.hasDirective).toBe(true);
|
||||||
|
expect(res.verboseLevel).toBe("on");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("matches think at start of line", () => {
|
||||||
|
const res = extractThinkDirective("/think:high run slow");
|
||||||
|
expect(res.hasDirective).toBe(true);
|
||||||
|
expect(res.thinkLevel).toBe("high");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -36,15 +36,18 @@ export type { GetReplyOptions, ReplyPayload } from "./types.js";
|
|||||||
const ABORT_TRIGGERS = new Set(["stop", "esc", "abort", "wait", "exit"]);
|
const ABORT_TRIGGERS = new Set(["stop", "esc", "abort", "wait", "exit"]);
|
||||||
const ABORT_MEMORY = new Map<string, boolean>();
|
const ABORT_MEMORY = new Map<string, boolean>();
|
||||||
|
|
||||||
function extractThinkDirective(body?: string): {
|
export function extractThinkDirective(body?: string): {
|
||||||
cleaned: string;
|
cleaned: string;
|
||||||
thinkLevel?: ThinkLevel;
|
thinkLevel?: ThinkLevel;
|
||||||
rawLevel?: string;
|
rawLevel?: string;
|
||||||
hasDirective: boolean;
|
hasDirective: boolean;
|
||||||
} {
|
} {
|
||||||
if (!body) return { cleaned: "", hasDirective: false };
|
if (!body) return { cleaned: "", hasDirective: false };
|
||||||
// Match the longest keyword first to avoid partial captures (e.g. "/think:high")
|
// Match the longest keyword first to avoid partial captures (e.g. "/think:high").
|
||||||
const match = body.match(/\/(?:thinking|think|t)\s*:?\s*([a-zA-Z-]+)\b/i);
|
// Require start of string or whitespace before "/" to avoid catching URLs.
|
||||||
|
const match = body.match(
|
||||||
|
/(?:^|\s)\/(?:thinking|think|t)\s*:?\s*([a-zA-Z-]+)\b/i,
|
||||||
|
);
|
||||||
const thinkLevel = normalizeThinkLevel(match?.[1]);
|
const thinkLevel = normalizeThinkLevel(match?.[1]);
|
||||||
const cleaned = match
|
const cleaned = match
|
||||||
? body.replace(match[0], "").replace(/\s+/g, " ").trim()
|
? body.replace(match[0], "").replace(/\s+/g, " ").trim()
|
||||||
@@ -57,14 +60,15 @@ function extractThinkDirective(body?: string): {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractVerboseDirective(body?: string): {
|
export function extractVerboseDirective(body?: string): {
|
||||||
cleaned: string;
|
cleaned: string;
|
||||||
verboseLevel?: VerboseLevel;
|
verboseLevel?: VerboseLevel;
|
||||||
rawLevel?: string;
|
rawLevel?: string;
|
||||||
hasDirective: boolean;
|
hasDirective: boolean;
|
||||||
} {
|
} {
|
||||||
if (!body) return { cleaned: "", hasDirective: false };
|
if (!body) return { cleaned: "", hasDirective: false };
|
||||||
const match = body.match(/\/(?:verbose|v)\s*:?\s*([a-zA-Z-]+)\b/i);
|
// Require start or whitespace before "/verbose" to avoid matching URLs like /verioussmith.
|
||||||
|
const match = body.match(/(?:^|\s)\/(?:verbose|v)\s*:?\s*([a-zA-Z-]+)\b/i);
|
||||||
const verboseLevel = normalizeVerboseLevel(match?.[1]);
|
const verboseLevel = normalizeVerboseLevel(match?.[1]);
|
||||||
const cleaned = match
|
const cleaned = match
|
||||||
? body.replace(match[0], "").replace(/\s+/g, " ").trim()
|
? body.replace(match[0], "").replace(/\s+/g, " ").trim()
|
||||||
|
|||||||
Reference in New Issue
Block a user