Skip to content

Keep character identity consistent in expressions and AI writing - #3

Merged
rustyorb merged 2 commits into
masterfrom
codex/picture-deletion-face-reference
Oct 19, 2026
Merged

rustyorb merged 2 commits into
masterfrom
codex/picture-deletion-face-reference

Conversation

@rustyorb

@rustyorb rustyorb commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Character expressions could repaint an unrelated person, and field edits received a shortened whole-card digest with no control over which details influenced the result. This update makes the reference and writing context explicit.

  • Expressions use the selected portrait as both the starting image and IP-Adapter reference. Plus Face is the default for illustrated faces; FaceID Plus v2 is available for photographic faces. Adapter failures stop the set without an unconditioned fallback. The page shows the reference, a one-expression test, progress/errors and direct Delete picture / Delete expression / Delete character controls with confirmation and Undo.
  • Ask AI offers checked-by-default earlier-field context in card authoring order. Only selected earlier fields are sent, in full, alongside the current field and author instruction. Choices persist per field and character. Quick directions also retain the author's typed instruction.
  • Voice has a priority direction for accents and speech quirks. It overrides conflicting spoken-style instructions in dialogue and opening generation, including developing an existing character. Structured and raw dialogue editors expose the same AI controls. These settings stay outside exported V2/V3 card data.
  • README, Quickstart, in-app help and verification notes match the final controls.

Validation: 181 tests pass. Local SillyTavern at 127.0.0.1:8123 was checked at 1440x1000 and 390x844 with no browser exceptions or horizontal overflow. Real ComfyUI joy/anger jobs used Plus Face and retained the reference's hair, clothing and pose; mood changes were subtle. Background removal was disabled for those jobs. FaceID generation was not run because its matching LoRA was absent; a mocked model failure verified the stop/error path. Writing requests were captured with mocked model replies to verify context exclusions, voice priority, additive edits, three takes and alternate openings. Preferences survived reload. Deletion/cancellation/Undo were exercised, temporary fixtures were removed and original local project data/settings restored. No remote SillyTavern instance was used.

Summary by Sourcery

Keep character identity and writing context consistent by conditioning expressions on the selected portrait and making AI field context and voice direction explicit.

New Features:

  • Add portrait-conditioned expression generation with selectable IP-Adapter Plus Face or FaceID Plus v2 methods, test generation, progress/error feedback, and no unconditioned fallback.
  • Add configurable, persistent earlier-field context selection for Ask AI edits and preserve typed instructions in quick directions.
  • Add highest-priority voice direction controls for AI-generated dialogue, openings, and character development across structured and raw editors.
  • Add direct picture, expression, and character deletion controls with confirmation and Undo.

Bug Fixes:

  • Prevent expression generation from repainting an unrelated identity when reference adapters fail.
  • Ensure AI field edits receive only the selected earlier fields in full rather than an implicit shortened whole-card digest.
  • Ensure voice instructions override conflicting spoken-style guidance in generated dialogue and openings.

Enhancements:

  • Record expression reference and adapter metadata and flag older expression sets for regeneration.
  • Improve expression-generation setup guidance and status reporting.

Documentation:

  • Update the README, Quickstart, in-app help, and verification notes for expression identity, AI context controls, voice direction, and deletion workflows.

Tests:

  • Expand automated coverage to 181 tests for identity-conditioned expression workflows, adapter failures, explicit AI context selection, voice priority, persistence, and deletion-related behavior.

Copilot AI balanced review requested due to automatic review settings October 19, 2026 03:14
@sourcery-ai

sourcery-ai Bot commented Oct 19, 2026

Copy link
Copy Markdown

Sorry @rustyorb, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 12 hours and 32 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Oct 19, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR makes character identity and writing context explicit: expressions use the selected portrait through a required face adapter with no unconditioned fallback, while AI edits use persisted per-field context selections and priority voice direction; UI controls, deletion/Undo flows, documentation, and verification coverage were updated accordingly.

Sequence diagram for identity-preserving expression generation

sequenceDiagram
    participant Author
    participant PicturesUI
    participant paintSprites
    participant ComfyUI
    participant Project

    Author->>PicturesUI: Generate one expression
    PicturesUI->>paintSprites: paintSprites(reference, identity, labels)
    paintSprites->>ComfyUI: buildIdentityExpression(reference, adapter)
    ComfyUI-->>paintSprites: Generated expression or adapter error
    alt generation succeeds
        paintSprites->>Project: saveCharacterPicture(referenceMediaId, method)
        Project-->>PicturesUI: Saved expression
    else adapter or model failure
        paintSprites-->>PicturesUI: Error, stop without fallback
    end
Loading

Sequence diagram for priority voice direction in AI writing

sequenceDiagram
    participant Author
    participant VoiceEditor
    participant AIPipeline
    participant WritingTask
    participant CharacterCard

    Author->>VoiceEditor: Set voiceDirection
    VoiceEditor->>CharacterCard: Save voiceDirection outside card export
    Author->>AIPipeline: Generate dialogue or opening
    AIPipeline->>CharacterCard: Read voiceDirection and selected context
    AIPipeline->>WritingTask: Build task with voiceInstruction(voiceDirection)
    WritingTask-->>AIPipeline: Voice-prioritized generated text
    AIPipeline-->>Author: Apply or review generated result
Loading

Flow diagram for explicit AI writing context

flowchart TD
    A[Author opens Ask AI] --> B[Select earlier fields]
    B --> C[Persist choices per character and target field]
    C --> D[selectedContextFields]
    D --> E[fieldContextText]
    E --> F[Include full selected earlier fields]
    F --> G[Include current field and author instruction]
    G --> H[Exclude unchecked and later fields]
    H --> I[Generate rewrite, additive edit, or 3 takes]
Loading

File-Level Changes

Change Details Files
Expression generation now conditions every mood on the selected portrait and fails closed when identity adapters cannot run.
  • Added IP-Adapter Plus Face and FaceID Plus v2 workflow construction, including sampler wiring and reference metadata.
  • Removed unconditioned expression fallback; jobs report actionable errors, progress, cancellation, and save failures.
  • Added one-expression validation flow, adapter selection, regeneration warnings, and direct expression/picture/character deletion with confirmation and Undo.
src/core/comfy.js
src/st/comfy.js
src/ui/character-pictures.js
src/ui/deletion.js
src/ui/areas/media.js
src/ui/media.js
style.css
tests/comfy.test.js
AI field editing now sends explicit, configurable earlier-field context instead of a shortened whole-card digest.
  • Defined shared authoring order and full-value context formatting for V2/V3 cards, excluding unchecked and later fields.
  • Added per-character, per-field context checkboxes with checked-by-default persistence and latest-state reads at request time.
  • Applied the same context controls to rewrites, additions, three takes, quick directions, alternate openings, and structured/raw dialogue editing.
src/core/field-context.js
src/ui/field-context.js
src/ui/ai-assist.js
src/ui/areas/characters.js
src/ai/tasks.js
src/ai/pipeline.js
tests/field-context.test.js
Priority voice direction steers generated dialogue and openings while remaining outside exported card data.
  • Added a highest-priority voice instruction to dialogue, opening, whole-character development, and existing-character generation paths.
  • Preserved typed instructions when applying quick directions and exposed consistent controls in structured and raw editors.
  • Verified voice/context isolation, persistence, and export boundaries.
src/ai/tasks.js
src/ai/pipeline.js
src/ui/areas/characters.js
tests/field-context.test.js
Documentation and verification records were updated to describe the final expression, writing, deletion, and setup controls.
  • Updated README, Quickstart, in-app help, test-count badges, and image setup guidance.
  • Recorded unit, mocked-request, local browser, GPU expression, failure-path, deletion, Undo, responsive, and persistence validation.
README.md
docs/QUICKSTART.md
docs/STATUS.md
src/ui/guide.js

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@rustyorb
rustyorb merged commit 6f86b2e into master Oct 19, 2026
2 checks passed
@rustyorb
rustyorb deleted the codex/picture-deletion-face-reference branch October 19, 2026 03:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unresolved writing and layout issues, together with unvalidated real-backend FaceID generation, require fixes and human verification.

2 open issues
1 file not reviewed
  • src/ui/guide.js: Generated file
What changed in this PR

This PR strengthens character consistency in expression generation and AI-assisted writing.

Changes:

  • Conditions expressions on the selected portrait, with adapter selection and failure feedback.
  • Adds persistent field-context choices and priority voice guidance.
  • Adds direct deletion controls and updates documentation and tests.
File Description
tests/​field-context.test.js Tests context selection, persistence, and voice guidance.
tests/​comfy.test.js Tests adapter workflows and failure handling.
style.css Styles context, expression, and deletion controls.
src/​ui/​media.js Saves expression reference metadata.
src/​ui/​image-setup.js Updates adapter setup guidance.
src/​ui/​guide.js Updates in-app help.
src/​ui/​field-context.js Adds context controls and current-value retrieval.
src/​ui/​deletion.js Adds picture and character deletion buttons.
src/​ui/​character-pictures.js Adds portrait-conditioned expression controls.
src/​ui/​areas/​media.js Adds direct library deletion controls.
src/​ui/​areas/​characters.js Integrates context selection and voice direction.
src/​ui/​ai-assist.js Preserves typed instructions in quick directions.
src/​st/​comfy.js Runs identity-conditioned expression jobs.
src/​core/​field-context.js Defines field order and context filtering.
src/​core/​comfy.js Builds face-adapter expression workflows.
src/​ai/​tasks.js Incorporates selected context and voice guidance.
src/​ai/​pipeline.js Passes writing preferences into generation steps.
README.md Documents updated workflows.
docs/​STATUS.md Records validation results and limitations.
docs/​QUICKSTART.md Explains the new controls.

Review effort: Balanced

Comment thread src/ai/pipeline.js
// Filling gaps in an existing card: ask only for what is empty instead of rewriting everything and discarding it.
const gaps = s.fillOnly ? CORE_CARD_FIELDS.filter(k => (Array.isArray(card?.data[k]) ? !card.data[k].length : !String(card?.data[k] ?? '').trim())) : [];
return { concept: { ...s.concept, story: brief(s) }, card, style: styleFrom(dials), ...(gaps.length ? { only: gaps } : {}) };
return { concept: { ...s.concept, story: brief(s) }, card, voiceDirection: char(p, s)?.voiceDirection, style: styleFrom(dials), ...(gaps.length ? { only: gaps } : {}) };
${!gallery.length && html`<p class="cs-muted">Your generated and uploaded pictures will appear here.</p>`}
<div class="cs-gallery">${[...gallery].reverse().map(m => html`<figure key=${m.id} class="cs-gallery-item">
<a href=${m.url} target="_blank" rel="noopener"><img src=${m.url} alt=${m.name} title=${m.prompt ?? m.name} loading="lazy" /></a>
<figcaption>${m.purpose ?? ''}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants