Severian 7569fb8e82 Diagnose setup by what is certain, and deliver errors the way the client asked
Review of the branch found the persona diagnosis was mostly truncation
wearing a name tag. The <.> marker sits at the start of the system
message and the persona marker after the card, so a card Janitor cut
short arrives with the prompt present and the persona gone — and was
told its persona was wrong, with truncation as an afterthought. The
original message was only ever about context size, which is the best
evidence there is about what actually happens.

diagnoseSetup() now says only what the markers make certain. A missing
<.> is a missing prompt, since truncation cannot remove the first three
characters. A persona marker that is present but not "." is a wrong
description, quoted back so there is nothing to guess. A persona marker
that is gone, or cut off mid-tag, leads with truncation and mentions the
persona second.

The error path decided "streaming?" from the Accept header while the
success path used body.stream, so a client that sent stream:true without
that header got JSON back for every error and never displayed it. The
flag is hoisted above the try; the header is only a fallback for when
the body could not be read.

Token search is restricted to after the greeting, in order. A card built
from a sucker-proxied chat could carry an expired token in its text, and
a lookup on it would fail forever. Conversation order also means the
token a chat was started with always wins over one pasted later. The
system fallback now takes a role-less first message only; a request with
roles but no system turn is reported as such rather than misdiagnosed as
a missing prompt. The echo feature reads the parser's lastUser instead of
its own case-sensitive lookup. "Nothing was saved" is dropped from the
unknown-error message, since it is not guaranteed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NX2SsmUqQftWTZAY4BDuFa
2026-09-11 06:46:52 +08:00
2025-12-09 10:40:18 +08:00
2026-01-30 18:22:16 +08:00
2026-01-30 18:22:16 +08:00
2025-01-19 21:47:26 +08:00
2025-12-11 08:42:20 +08:00
2025-12-11 08:42:20 +08:00
2026-01-30 18:22:16 +08:00
2026-09-11 05:15:01 +08:00
2025-01-19 21:47:35 +08:00
2025-12-09 10:40:18 +08:00

Sucker

Environment Variables

Add these to your .env.local file (optional):

# Disable Discord community banner (defaults to showing banner)
NEXT_PUBLIC_DISABLE_DISCORD_BANNER=true

Usage

Pull this repostory and build with npm run build. You can start the server with node ./.next/standalone/server.js

You can also build and run Sucker as a Docker container with docker compose build and docker compose up.

Changelog

  • 2.5: Real error messages instead of one blanket "dingus" reply; unexplained failures now ask you to DM @lyseverian. Unread dot on the Changelog button. Fixed extraction for users whose Janitor sends a request without the blank turn before the first message — sucker read the parts by position rather than by role, so for them it read the wrong ones and errored. Now resolved by role, with tests for both shapes.
  • 2.4: CSS editor for Janitor profiles. New banner links to the live-preview editor at tools.from-avalon.com/janitor-profile-maker.
  • 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.
  • also 2.0: V2 charcard format and alternate greetings.
  • 1.9: Not again. They changed stuff again. What is this?
  • 1.8: Handling for new prompt structure, new instructions
  • 1.7: Handling for nested XML character tags
  • 1.6: First message formatting, copy button for first message and other fields
  • 1.5: {{user}} substitution for user persona name
  • 1.4: Mooth just keeps finding bugs, damn.
  • 1.3: Mooth found a bug, fixed it.
  • 1.2: Fix for Janitor having changed their prompt system
  • 1.1: Fix for R1 handling change, blank user persona bug
  • 1.0: Yup.
S
Description
Char card extractor for you-know-what
Readme 2.5 MiB
Languages
TypeScript 96.4%
JavaScript 2.3%
CSS 1.3%