Skip to content

feat(records): add inline aliases and message marks - #495

Closed
KokerZhou wants to merge 5 commits into
ChatLab:mainfrom
KokerZhou:feat/chat-record-quick-actions
Closed

KokerZhou wants to merge 5 commits into
ChatLab:mainfrom
KokerZhou:feat/chat-record-quick-actions

Conversation

@KokerZhou

Copy link
Copy Markdown
Contributor

Chat records currently provide the original message content but offer few ways to organize or annotate individual messages. Member aliases also have to be edited from the separate member management view.

This PR adds an inline alias editor beside the sender name and keeps alias changes synchronized with member management. It also adds a copy action for the original content of a single message.

Messages can now be marked with any combination of categories, a color, and a free-form comment. Marks are displayed separately from the original message bubble and can be filtered by category, color, or comment text. Long comments remain readable without taking over the record view, and the controls work with narrow or resized record panels.

The mark data is stored separately from the message body. This keeps imported messages intact while establishing a clear place for information associated with a message but not originally part of it.

This separation may later support richer message preprocessing—for example, audio transcription and translation, image captions or classifications, and document ETL—without converting the original media into replacement text. That extension is intentionally not implemented here. It still needs a design for preserving media, namespaced and versioned preprocessing metadata, provenance, generated-result lifecycle, and how search or AI features consume those results.

The current PR stays focused on human organization: aliases, copying, categories, colors, and comments. It does not change imported message content or add media/AI processing. Schema migration, filtering, localization, keyboard and screen-reader state, virtual-list synchronization, and Desktop/CLI Web shared service paths are included in the implementation.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-13T00:39:36.438676Z 3a79f8d New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@KokerZhou
KokerZhou marked this pull request as draft October 11, 2026 10:58
@KokerZhou
KokerZhou force-pushed the feat/chat-record-quick-actions branch from 66b9b01 to 8920c57 Compare October 11, 2026 11:01

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66b9b0178e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id`
LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
LEFT JOIN message_mark mm ON mm.message_id = msg.id`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Add message_mark to the remaining full-message fixture

Because FULL_MSG_SELECT is also used by searchMessagesByKeywords, the default packages/tools/src/providers/core-data-provider.test.ts fixture—which creates only member and message—now throws no such table: message_mark on its first provider.searchMessages() call. The two core query fixtures were updated but this default-suite fixture was not, so add the table there (and to any other full-message fixtures) or make the shared select tolerate schemas without marks.

Useful? React with 👍 / 👎.

Comment on lines +107 to +110
mark:
row.markUpdatedAt == null
? null
: {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Strip human marks from AI tool context messages

In the CLI/MCP/HTTP-tool path, CoreDataProvider.getSearchMessageContext and getMessageContext return these MappedMessage objects directly as RawMessage, and the tool handlers JSON-serialize them. Once a user has added a mark, this new field sends its categories and free-form comment to the configured model (and sends mark:null for every unmarked context row) even though RawMessage exposes no such field; sanitize those provider returns or keep mark mapping viewer-specific.

Useful? React with 👍 / 👎.

Comment on lines +150 to +151
function applyMessageMark(messageId: number, mark: ChatRecordMessage['mark']) {
messages.value = messages.value.map((message) => (message.id === messageId ? { ...message, mark } : message))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reapply active mark filters after editing a mark

When query.markCategories, markColor, or markComments is active, changing or removing the matched mark emits update-mark, but this handler merely updates the row in place. A message that no longer satisfies the active filter therefore remains visible, with stale loaded count and pagination, until the user reapplies the filter; rerun the filtered search or remove and refill the row after save.

Useful? React with 👍 / 👎.

Comment on lines +393 to +394
version: 11,
description: 'Add user-defined message marks',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Add Desktop locale strings for migration 11

When Desktop opens a v10 database, getPendingMigrationInfos(10) synthesizes database.migrationV11Desc and database.migrationV11Message, but all four apps/desktop/main/i18n/locales/*.ts catalogs stop at V10, so the migration modal renders the literal internal key instead of an explanation; the existing migration-version assertion also still stops at 10. Add the V11 strings and extend that migration test.

AGENTS.md reference: AGENTS.md:L65-L65

Useful? React with 👍 / 👎.

@KokerZhou
KokerZhou force-pushed the feat/chat-record-quick-actions branch from 8920c57 to c3dbf1e Compare October 11, 2026 11:13
@KokerZhou
KokerZhou marked this pull request as ready for review October 11, 2026 11:18
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Failed to sample tokens
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

1 similar comment
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Failed to sample tokens
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c3dbf1e6bd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

try {
const query = toRaw(props.query)
const { filter, senderId, keywords } = buildFilterParams(query)
const { filter, senderId, keywords, markFilter } = buildFilterParams(query)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Pass mark filters through target-centered loads

When a mark filter is active and the user clicks a session in the timeline, ChatRecordWorkspace.handleSessionSelect preserves that filter while adding scrollToMessageId. This makes the target-ID branch run, but the computed markFilter is not passed to either getMessagesBefore or getMessagesAfter, so a mark-only query suddenly displays unmarked surrounding messages while the filter controls still show the filter as active; pass the mark criteria through these centered pagination calls or explicitly clear them when selecting a timeline session.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 3a79f8d. Target-centered initial loads and subsequent before/after pagination now receive the active mark filter, with regression coverage for filtered pages around a target.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3a79f8dcea

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +81 to +84
categories TEXT NOT NULL DEFAULT '[]',
color TEXT NOT NULL DEFAULT '',
comment TEXT NOT NULL DEFAULT '',
updated_at INTEGER NOT NULL,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Block AI raw SQL from viewer-only marks

In Agent/MCP runs where the default raw-SQL tools are available, this new table is returned by getDatabaseSchema(), while SHARED_TOOLS exposes both get_schema and unrestricted read-only execute_sql (packages/tools/src/registry.ts:52-75), so a model can execute SELECT categories, comment FROM message_mark and send these notes to the configured provider. Fresh evidence beyond the earlier context-return issue is the added test at packages/tools/src/providers/core-data-provider.test.ts:134-143, which explicitly calls marks viewer-only, while only the RawMessage mapping was sanitized. Hide and reject this table in both the CoreDataProvider and WorkerDataProvider schema/raw-SQL paths, or store marks outside the AI-visible database.

Useful? React with 👍 / 👎.

@KokerZhou KokerZhou closed this by deleting the head repository Oct 15, 2026
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.

1 participant