* 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>
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_initialstependpoint 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
- User types in chat input.
PangeaTextControllerfires_onChange. - After debounce (
ChoreoConstants.msBeforeIGCStart),requestWritingAssistance()is called. IgcController.getIGCTextData()calls/grammar_v2viaIgcRepo.- Response contains a list of
SpanData(matches) — grammar errors, out-of-target markers, normalization fixes. - Auto-apply matches (punct, diacritics, spell, cap) are accepted automatically via
acceptNormalizationMatches(). Grammar/word-choice matches becomeopenMatches.
2. Matches displayed → Span cards
- Open matches render as colored underlines in the text field (colors set by
ReplacementTypeEnum.underlineColor()). - Tapping a match opens a span card overlay (
span_card.dart) showing the error category (ReplacementTypeEnum.displayName()), choices, and the error message. - Auto-applied corrections show an
AutocorrectPopupwith undo capability.
3. User resolves matches
Each match goes through PangeaMatchState with status transitions:
open→accepted(user chose a replacement)open→ignored(user dismissed)open→automatic(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():
- Calls
/tokenizeto getPangeaTokendata for the final text (with exponential backoff on errors). - Builds
PangeaMessageContentModelcontaining:- The final message text
ChoreoRecordModel(full editing history)PangeaRepresentationfor 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 grammar → subjectVerbAgreement).
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 typingigc— System applying IGC matchit— ⚠️ Deprecated — System applying IT continuanceitDismissed— ⚠️ 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.