02.11: Dialogue History
此内容尚不支持你的语言。
The dialogue history contributor formats recent conversation turns, records capability-neutral media descriptors, and injects context notes and date spacers at designated dialogue depths.
Flow and ownership
Section titled “Flow and ownership”The contributor appendDialogueHistoryContext in src/utils/text/context/dialogueHistory.ts appends directly to contextItems:
simplifiedMessageHistory │ ├─ calculate media window & duplicate image indices ├─ assemble active context notes (persona, channel, global, verbatim, reunion) │ └─ loop messages: ├─ emit date spacer if day boundary crossed ├─ emit active note if index matches note target depth ├─ map role (user vs model) and sender metadata ├─ attach capability-neutral mediaDescriptors (within window & image limits) ├─ format text: author label ("resolve") + content ("preserve" macros) └─ push item (tagged DIALOGUE_HISTORY)Turn mapping and formatting
Section titled “Turn mapping and formatting”- Role mapping: Messages from the active persona map to
model. During user impersonation, messages from the impersonated user ID map tomodel. All other messages map touser. - Blocked users: Messages from users with an active persona-scoped block (
block_type = 'block') are replaced in history by a single[System: ...]notice, and reply quote annotations targeting them are suppressed. - Reply quotes: Referenced message text includes recognized notices and embed previews, even when the message is outside the history window. Diagnostic embeds and unshared dice rolls stay excluded.
- Text formatting: Lines format as
${authorName}: ${content}. Author names resolve macros (identityMacroMode: "resolve"), whereas message bodies preserve{bot}and{user}literals (identityMacroMode: "preserve"). This prevents template drafts typed by users from collapsing into persona names. - File hints: each
documentAttachmentsentry adds a[System: ...]part built fromDOCUMENT_HINT_TEMPLATE. The native builder expands the template once with the turn’s tool macro resolver, so the instruction to callread_fileappears only when the turn exposes it; otherwise the hint says the contents are unavailable. The filename and media ID are filled in after expansion, so a filename is never parsed as a macro. - Deterministic humanization: When the Force Lowercase or Punctuation Splits toggle is on, model-role historical turns pass through
applyStableHumanizer. It applies only the deterministic casing and semicolon normalization those toggles imply, never the randomized comma noise, preserving prefix stability for provider prompt caching.
NovelAI reads the item’s completionText projection. History simplification preserves original
message prose in completionContent before adding reply references, reactions, and media hints.
Generated notices supply semantic prose or an empty string; completionSpeaker: false keeps
narration free of a speaker label. Merging carries this projection alongside ordinary content.
Other providers continue to use the annotated parts. NovelAI’s fitter polishes and counts the
projection separately; see NovelAI limitations.
Media descriptor emission
Section titled “Media descriptor emission”Instead of adapting media to a specific model’s vision capabilities during context build, this stage records capability-neutral MediaDescriptor objects:
- Media window: Capped by
Math.min(memoryGuard.getMediaWindow(), configuredMessageFetchLimit). - Rendered image limits: Messages with counted images (attachments other than emojis or stickers) are limited to the most recent
MEDIA_IMAGE_MESSAGE_LIMIT(default 3 messages). Images exceeding this limit emit a[System: N image(s) omitted due to rendered-image limit]note. - Deduplication: When an identical image appears multiple times within the window, earlier occurrences are omitted so only the latest occurrence renders.
- Per-attempt resolution: Concrete adaptation runs later in
resolveMediaForModelduring each generation attempt. That stage determines whether a descriptor becomes provider image/video parts, a blind-model notice, or a notice that names{image_analysis_tool}only when that attempt’s model and the turn’s Deliberate Tool Mode allowlist expose it.
Context note and spacer injection
Section titled “Context note and spacer injection”The registry applies note ordering at depths measured from the end of simplified history (totalMessages - depth), after each message’s date spacer. These saved depths count items, independently of speaker-turn counting for the tail slot:
- Persona and channel notes: Persona notes and channel notes are additive; both inject when configured. The global server context note is a fallback used only when neither persona nor channel configures a note.
- Verbatim tool-calling nudge: When
shouldInjectVerbatimToolCallingNudge(tomoriState)is true, injectsVERBATIM_TOOL_CALLING_NUDGEat depth 3 to guide custom endpoint models on verbatim tool syntax. - Reunion note: Injects a precomputed reunion note at
TIME_AWARENESS_NOTE_DEPTH(3) when a returning triggerer has an eligible absence gap. A turn answering another persona (a self-reply chain or a later scene turn) skips it and records no presence, because the person who started the chain did not address that persona. - Date spacers: Injects an absolute-date
[System: ...]separator before any message whose server-calendar day differs from the preceding timestamped turn. The pointer toreveal_message_metadatasits inside{{if tool:reveal_message_metadata}}.
Verified proxy history uses the persisted message index to recover the stable member identity and attested host. Superseded originals are excluded. Reply references outside the history window use the same attribution lookup. Host blocks filter these messages, while names and memories belong to the member. See message-proxy integration.
Constraints and rationale
Section titled “Constraints and rationale”- Capability-neutral history: Decoupling media descriptors from provider vision capabilities allows the same assembled context to be evaluated across fallback models without rebuilding history.
- Prompt cache preservation: Bypassing randomized punctuation noise keeps history deterministic. A context note deeper than the tail slot moves relative to history each chat turn and reduces cache reuse. Relative date-spacer wording such as “yesterday” changes at server-day boundaries. Anchored selection and budget truncation are owned upstream by Build Context.
- Hints follow the tool list: a hint that tells the model to call a tool wraps that instruction in
{{if tool:...}}, because history is simplified before the Deliberate Tool Mode allowlist exists. A hint written into message text at simplification time would name tools the turn never exposes. - Macro preservation: Preserving identity macros in user message bodies prevents corruption when users ask personas to draft or edit prompts containing
{user}or{bot}. - Preset reassembly: Dialogue items are tagged
DIALOGUE_HISTORYandCONTEXT_NOTE_INJECTION, which SillyTavern preset reassembly maps to thechatHistorymarker.
Source pointers
Section titled “Source pointers”src/utils/text/context/dialogueHistory.ts:appendDialogueHistoryContext.src/utils/text/context/history.ts: media descriptor filtering, timestamp formatting, and image limits.src/utils/text/context/mediaResolver.ts:resolveMediaForModelfor per-attempt media adaptation.src/utils/tools/verbatimToolCalling.ts:VERBATIM_TOOL_CALLING_NUDGE.src/utils/text/context/timeAwareness.ts:buildDateSpacerandTIME_AWARENESS_NOTE_DEPTH.