From 225c2e3c4f0698bcb3802650d57d2e6703ee6577 Mon Sep 17 00:00:00 2001 From: Severian Date: Tue, 4 Aug 2026 01:22:09 +0800 Subject: [PATCH] chore: 2.3 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01BvRuentLsG1UGpy9gmNWvR --- README.md | 1 + src/app/api/proxy/route.ts | 21 +++++++++++++++++++++ src/app/page.tsx | 36 ++++++++++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9a2aeb9..c50c988 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ You can also build and run Sucker as a Docker container with `docker compose bui ### Changelog +- 2.3: ECHO. Put ECHO: anywhere in a message and sucker repeats whatever comes after it in the reply — for triggering char-side script and lorebook keywords. - 2.2: Added support for directly inputting webp file names or character image links when creating PNG character cards - 2.1: updated deps, note about image fetching, list of mirrors - 2.0: from Tui: Multimessage support! Tracks changes to character descriptions and scenarios across multiple extractions. Shows version badges, message counts, and provides detailed change history viewer. diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 4e630ce..e3b1999 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -93,6 +93,15 @@ function parseConversationToken(content: string | undefined | null): string | nu return null; } +function parseEchoText(content: string | undefined | null): string | null { + if (!content) return null; + const match = content.match(/ECHO:\s*([\s\S]+)/i); + if (match && match[1].trim()) { + return match[1].trim(); + } + return null; +} + function removePersonaTags(content: string): string { let result = content; const openingMatch = result.match(/<[^<>]+?\s*'s\s+Persona>/i); @@ -487,6 +496,18 @@ export async function POST(request: NextRequest) { responseMessage = `New character "${extracted.data.name}" created (v1).${tokenNote}`; } + // Echo back anything the user sent after an "ECHO:" marker in their + // latest message, appended after the normal status message + const lastUserMessage = + [...body.messages] + .reverse() + .find((m: { role?: string }) => m?.role === "user") ?? + body.messages[body.messages.length - 1]; + const echoText = parseEchoText(lastUserMessage?.content); + if (echoText) { + responseMessage += `\n\n${echoText}`; + } + cleanupExpiredCards(); // Return SSE response if requested, otherwise JSON diff --git a/src/app/page.tsx b/src/app/page.tsx index afe72d6..447e6d6 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -371,9 +371,9 @@ export default function Home() { {/* Row 1: Title on left, Hamburger on right */}
-

Sucker v2.2

+

Sucker v2.3

- Consider joining Avalon! + ECHO: Consider joining Avalon!

@@ -409,9 +409,9 @@ export default function Home() { {/* Desktop Layout */}
-

Sucker v2.2

+

Sucker v2.3

- Consider joining Avalon! + ECHO: Consider joining Avalon!

@@ -820,6 +820,14 @@ export default function Home() { moment, but you can use the changes detected to modify the character card yourself post-export. +
  • + Some advanced scripts and lorebooks only add their entries + when the character says the keyword, not you. Put{" "} + ECHO:{" "} + in a message and everything after it gets repeated at the end + of the reply — instant character-side keywords, and sucker + tracks whatever gets added. +
  • Download the JSON files or go through a little more effort to get PNGs instead. @@ -928,6 +936,26 @@ export default function Home() {
    +
    +

    Aug 2026 - ECHO

    +
    +

    + Sucker can parrot now. Send a message with ECHO: in it, and + everything after that gets repeated back at the end of the + reply, exactly as you typed it. +

    +

    + The usual responses don't change at all — the echoed part + just tags along after them. The point: some of the fancier + scripts and lorebooks on the platform you suck from only add + their entries when the character says the keyword, not you. + ECHO plants your words on the character's side of the + chat, those entries fire, and sucker catches whatever they + sneak in. Case doesn't matter, echo: works too. +

    +
    +
    +

    Mar 2026 - Better error messaging for context size issues