fluffychat/.github/instructions/choreographer.instructions.md
wcjord dec473d579
Writing assistance (#5598)
* feat: wa working full stack

* feat: writing assistance made anew

* docs: migrate copilot docs to .github/instructions/ format

- Create choreographer.instructions.md (applyTo: lib/pangea/choreographer/**)
- Create events-and-tokens.instructions.md (applyTo: lib/pangea/events/**,lib/pangea/extensions/**)
- Create modules.instructions.md (applyTo: lib/pangea/**) — full module map
- Track copilot-instructions.md (remove .gitignore rule)
- Add documentation reference table to copilot-instructions.md

Content sourced from docs/copilot/ on writing-assistance branch.

* docs: remove old docs/copilot/ (migrated to .github/instructions/)

* docs: update choreographer + modules docs for writing-assistance audit

- Mark IT (Interactive Translation) as deprecated throughout
- Document new ReplacementTypeEnum taxonomy (grammar, surface, word-choice categories)
- Add AssistanceStateEnum, AutocorrectPopup, feedback rerun flow
- Mark SpanDataRepo/span_details as dead code
- Mark SpanChoiceTypeEnum.bestCorrection/bestAnswer as deprecated
- Add new files to modules listing (autocorrect_popup, start_igc_button, etc.)
- Update API endpoints table with active/deprecated/dead status

* formatting, replace deprecated withOpacity calls

* fix linter issues from deprecated types

* use better error color

* move cloing of overlays into choreographer

* reduce duplicate code on igc_controller, update UI on feedback

* couple of adjustments

* display prompt in span card by type

* fix error in tests

* translations

* simplify span card feedback

---------

Co-authored-by: ggurdin <ggurdin@gmail.com>
2026-02-09 15:55:18 -05:00

8.6 KiB

applyTo
lib/pangea/choreographer/**

Choreographer — Writing Assistance Flow

The choreographer is the client-side orchestrator for real-time writing assistance. It coordinates user text input, API calls to /grammar_v2, match display, and the creation of choreo records saved with sent messages.

⚠️ IT (Interactive Translation) is deprecated. The it/ directory, ITController, and /it_initialstep endpoint are still wired into the choreographer but are being phased out. IT will become just another match type returned by IGC. Do not add new IT functionality.

Architecture

Choreographer (ChangeNotifier)
├── PangeaTextController           ← Extended TextEditingController (tracks edit types)
├── IgcController                   ← Grammar check matches (primary flow)
├── ITController                    ← ⚠️ DEPRECATED — Translation step-by-step flow
├── ChoreographerErrorController    ← Error state + backoff
└── ChoreographerStateExtension     ← AssistanceStateEnum derivation

Key files

File Purpose
choreographer.dart Main orchestrator (ChangeNotifier)
choreographer_state_extension.dart Derives AssistanceStateEnum from current state
assistance_state_enum.dart UI states: noSub, noMessage, notFetched, fetching, fetched, complete, error
choreo_mode_enum.dart igc (active) or it (⚠️ deprecated)
choreo_record_model.dart Record of edits saved with message
igc/igc_controller.dart IGC state management (437 lines)
igc/replacement_type_enum.dart Granular match type taxonomy (grammar, surface, word-choice, etc.)
igc/autocorrect_popup.dart Undo popup for auto-applied corrections
text_editing/pangea_text_controller.dart Text controller with edit type tracking
it/it_controller.dart ⚠️ DEPRECATED — IT state

Flow

1. User types → debounce → IGC request

  1. User types in chat input. PangeaTextController fires _onChange.
  2. After debounce (ChoreoConstants.msBeforeIGCStart), requestWritingAssistance() is called.
  3. IgcController.getIGCTextData() calls /grammar_v2 via IgcRepo.
  4. Response contains a list of SpanData (matches) — grammar errors, out-of-target markers, normalization fixes.
  5. Auto-apply matches (punct, diacritics, spell, cap) are accepted automatically via acceptNormalizationMatches(). Grammar/word-choice matches become openMatches.

2. Matches displayed → Span cards

  1. Open matches render as colored underlines in the text field (colors set by ReplacementTypeEnum.underlineColor()).
  2. Tapping a match opens a span card overlay (span_card.dart) showing the error category (ReplacementTypeEnum.displayName()), choices, and the error message.
  3. Auto-applied corrections show an AutocorrectPopup with undo capability.

3. User resolves matches

Each match goes through PangeaMatchState with status transitions:

  • openaccepted (user chose a replacement)
  • openignored (user dismissed)
  • openautomatic (auto-apply correction)
  • Any → undo (user reverted)

When a match is accepted/ignored, the IgcController fires matchUpdateStream. The Choreographer listens and:

  • Updates the text via textController.setSystemText()
  • Records the step in ChoreoRecordModel

4. Feedback rerun

If the user is unsatisfied with results, rerunWithFeedback(feedbackText) re-calls IGC with user feedback and the previous request/response context (_lastRequest, _lastResponse).

5. Sending

On send, Choreographer.getMessageContent():

  1. Calls /tokenize to get PangeaToken data for the final text (with exponential backoff on errors).
  2. Builds PangeaMessageContentModel containing:
    • The final message text
    • ChoreoRecordModel (full editing history)
    • PangeaRepresentation for original written text (if IT was used)
    • PangeaMessageTokens (token/lemma/morph data)

AssistanceStateEnum

Derived in choreographer_state_extension.dart. Drives the send-button color and UI hints:

State Meaning
noSub User has no active subscription
noMessage Text field is empty
notFetched Text entered but IGC hasn't run yet
fetching IGC request in flight
fetched Matches present — user needs to resolve them
complete All matches resolved, ready to send
error IGC error (backoff active)

ReplacementTypeEnum — Match Type Taxonomy

Defined in igc/replacement_type_enum.dart. Categories returned by /grammar_v2:

Category Types Behavior
Client-only definition, practice, itStart Not from server; itStart triggers deprecated IT flow
Grammar (~21 types) verbConjugation, verbTense, verbMood, subjectVerbAgreement, genderAgreement, numberAgreement, caseError, article, preposition, pronoun, wordOrder, negation, questionFormation, relativeClause, connector, possessive, comparative, passiveVoice, conditional, infinitiveGerund, modal Orange underline, user must accept/ignore
Surface corrections punct, diacritics, spell, cap Auto-applied (no user interaction), undo via AutocorrectPopup
Word choice falseCognate, l1Interference, collocation, semanticConfusion Blue underline, user must accept/ignore
Higher-level transcription, style, fluency, didYouMean, translation, other Teal (style/fluency) or error color

Key extension helpers: isAutoApply, isGrammarType, isWordChoiceType, underlineColor(), displayName(), fromString() (handles legacy snake_case and old type names like grammarsubjectVerbAgreement).

Key Models

Model File Purpose
SpanData igc/span_data_model.dart A match span (offset, length, choices, message, rule, ReplacementTypeEnum)
PangeaMatch igc/pangea_match_model.dart SpanData + status
PangeaMatchState igc/pangea_match_state_model.dart Mutable wrapper tracking original vs updated match state
ChoreoRecordModel choreo_record_model.dart Full editing history: steps, open matches, original text
ChoreoRecordStepModel choreo_edit_model.dart Single edit step (text before/after, accepted match)
IGCRequestModel igc/igc_request_model.dart Request to /grammar_v2
IGCResponseModel igc/igc_response_model.dart Response from /grammar_v2
MatchRuleIdModel igc/match_rule_id_model.dart Rule ID constants (⚠️ tokenNeedsTranslation, tokenSpanNeedsTranslation, l1SpanAndGrammar — not currently sent by server)
AutocorrectPopup igc/autocorrect_popup.dart Undo widget for auto-applied corrections

API Endpoints

Endpoint Repo File Status
/choreo/grammar_v2 igc/igc_repo.dart Active — primary IGC endpoint
/choreo/tokenize events/repo/tokens_repo.dart Active — tokenizes final text on send
/choreo/span_details igc/span_data_repo.dart Dead code — SpanDataRepo class is defined but never imported anywhere
/choreo/it_initialstep it/it_repo.dart ⚠️ Deprecated — IT flow
/choreo/contextual_definition contextual_definition_repo.dart ⚠️ Deprecated — only used by IT's word_data_card.dart

Edit Types (EditTypeEnum)

  • keyboard — User typing
  • igc — System applying IGC match
  • it⚠️ Deprecated — System applying IT continuance
  • itDismissed⚠️ Deprecated — IT dismissed, restoring source text

Deprecated: SpanChoiceTypeEnum

In igc/span_choice_type_enum.dart:

  • bestCorrection@Deprecated('Use suggestion instead')
  • bestAnswer@Deprecated('Use suggestion instead')
  • suggestion — Active replacement

Error Handling

  • IGC and token errors trigger exponential backoff (_igcErrorBackoff *= 2, _tokenErrorBackoff *= 2)
  • Backoff resets on next successful request
  • Errors surfaced via ChoreographerErrorController
  • Error state exposed in AssistanceStateEnum.error

⚠️ Deprecated: Interactive Translation (IT)

Do not extend. IT is being deprecated. Translation will become a match type within IGC.

The it/ directory still contains ITController, ITRepo, ITStepModel, CompletedITStepModel, GoldRouteTrackerModel, it_bar.dart, it_feedback_card.dart, and word_data_card.dart. The choreographer still wires up IT via _onOpenIT() / _onCloseIT() / _onAcceptContinuance(), triggered when an itStart match is found. The it_bar.dart widget is still imported by chat_input_bar.dart.

This entire flow will be removed once testing confirms IT is no longer needed as a separate mode.