Skip to content

feat(server,stage-ui): sync message to server#990

Merged
luoling8192 merged 1 commit intomainfrom
dev/sync-chat
Jan 24, 2026
Merged

feat(server,stage-ui): sync message to server#990
luoling8192 merged 1 commit intomainfrom
dev/sync-chat

Conversation

@luoling8192
Copy link
Member

No description provided.

…pdates

- Added chat service to handle chat synchronization and member management.
- Introduced chat routes for syncing chat data with the server.
- Updated database schema to include new fields for chat members and messages.
- Enhanced chat session management in the UI to support new chat features.
@github-actions
Copy link
Contributor

⏳ Approval required for deploying to Cloudflare Workers (Preview) for stage-web.

Name Link
🔭 Waiting for approval For maintainers, approve here

Hey, @nekomeowww, @sumimakito, @luoling8192, @LemonNekoGH, kindly take some time to review and approve this deployment when you are available. Thank you! 🙏

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @luoling8192, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new feature to synchronize chat messages and chat session metadata between the client and the server. It involves significant database schema changes to support richer chat functionalities, the creation of a dedicated API endpoint for handling synchronization requests, and the implementation of robust client-side logic to manage and transmit chat data, ensuring data consistency and enabling more dynamic chat interactions.

Highlights

  • Database Schema Update: The database schema has been updated with a new Drizzle migration. The chat_members table now supports member_type and character_id (making user_id nullable), the chats table includes a title column, and the messages table now has a role column to classify message types.
  • Chat Synchronization API: A new /api/chats/sync endpoint has been introduced on the server. This endpoint is responsible for receiving and processing chat session data, including chat metadata, members, and messages, from the client for synchronization.
  • Client-Side Synchronization Logic: The stage-ui application now incorporates comprehensive client-side logic to manage and synchronize chat sessions. This includes preparing chat data, generating unique message IDs, and scheduling synchronization tasks to the server using a local-first approach, ensuring data consistency.
  • Enhanced Chat Member Management: The chat_members table and associated logic now support different types of chat participants (users, characters, bots) and link to character IDs, enabling more flexible and diverse chat interactions.
  • Message Role Support: Messages now include a role field (e.g., 'system', 'user', 'assistant'), allowing for better classification and handling of messages within chat conversations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces chat synchronization functionality, allowing chat sessions and messages to be synced between the client and the server. The changes include schema updates for chat-related tables, a new API endpoint for syncing, and corresponding service logic on the server. On the client side, the chat-session store has been updated to prepare and send chat data to the server using a local-first approach. The implementation generally looks solid, with good use of valibot for schema validation and drizzle-orm for database interactions. The client-side queuing for persistence and synchronization is also well-designed. One comment has been updated to reference a relevant rule regarding programmatic identifiers for event sources.

ALTER TABLE "chat_members" ADD COLUMN "member_type" text NOT NULL;--> statement-breakpoint
ALTER TABLE "chat_members" ADD COLUMN "character_id" text;--> statement-breakpoint
ALTER TABLE "chats" ADD COLUMN "title" text;--> statement-breakpoint
ALTER TABLE "messages" ADD COLUMN "role" text NOT NULL;--> statement-breakpoint
Copy link
Contributor

Choose a reason for hiding this comment

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

high

Adding a NOT NULL column role to the messages table without a default value can cause issues if there are existing rows in the messages table. If this migration is applied to an existing database with data, it will fail unless a default value is provided or a two-step migration is performed (add column nullable, update existing rows, then alter column to not null). If this is for a fresh database, it's fine.

@@ -0,0 +1,6 @@
ALTER TABLE "chat_members" ALTER COLUMN "user_id" DROP NOT NULL;--> statement-breakpoint
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The change to user_id from NOT NULL to nullable is a significant schema alteration. While this is likely intended to allow character_id to be present instead, it's important to ensure that the application logic correctly handles cases where user_id might be null, especially if member_type dictates whether user_id or character_id should be present. This could impact data integrity if not properly managed at the application level.

Comment on lines +39 to +42
function resolveSenderId(role: MessageRole, userId: string, characterId?: string) {
if (role === 'user')
return userId
return characterId ?? role
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The resolveSenderId function defaults to characterId ?? role when the role is not 'user'. If characterId is null, the senderId will be set to the role string itself (e.g., 'system', 'assistant', 'tool', 'error'). While this might be intended, it means these role strings will be stored in the senderId column, which is typically expected to hold actual user or character IDs. Consider if these role strings should be explicitly handled or if a dedicated system_id or similar mechanism is more appropriate to avoid potential confusion or conflicts with actual user/character IDs in the future.

References
  1. For extensibility, identify the source of an event using a programmatic identifier (e.g., a source field in metadata) rather than relying on string patterns within the message content.

Comment on lines +159 to +160
mediaIds: [],
stickerIds: [],
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The mediaIds and stickerIds arrays are hardcoded to empty arrays when inserting new messages. If the intention is to support media and stickers in messages, the SyncChatMessagePayload interface and the client-side buildSyncMessages function should be updated to include these fields, and the server-side logic should process them accordingly. If they are not currently supported, consider adding a comment to clarify this limitation or plan for future implementation.

content,
} satisfies SystemMessage
createdAt: Date.now(),
} satisfies ChatHistoryItem
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The createdAt: Date.now() is added to the initial system message. This is a good change for consistency with other messages and for generating unique message IDs. However, Date.now() provides milliseconds since epoch. Ensure that the server-side timestamp column in Drizzle is configured to handle this precision, or convert it to seconds if the database expects that.

@luoling8192 luoling8192 merged commit 7c9a23f into main Jan 24, 2026
9 checks passed
@luoling8192 luoling8192 deleted the dev/sync-chat branch January 24, 2026 09:57
Joker-of-Gotham pushed a commit to Joker-of-Gotham/airi that referenced this pull request Jan 29, 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