Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: update GraphQL mutation input type and clean up comments and add… #174

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

NarwhalChen
Copy link
Collaborator

@NarwhalChen NarwhalChen commented Mar 8, 2025

…ing interactivity chat to do some tasks

Summary by CodeRabbit

  • New Features

    • Enhanced chat functionality now supports saving messages with role information and retrieving current project details.
    • Introduced a new endpoint to fetch a project’s file structure.
    • Added a utility to convert XML responses into JSON for improved file handling.
    • New tools for managing tasks within a multi-agent system have been introduced, enhancing task execution capabilities.
    • Added nullable fields in chat-related data models for improved flexibility.
  • Refactor

    • Improved error handling and logging across chat operations for a more reliable experience.
    • Streamlined data handling in various components to enhance performance and maintainability.

Copy link
Contributor

coderabbitai bot commented Mar 8, 2025

Walkthrough

This pull request updates multiple backend and frontend components. In the backend, GraphQL models, resolvers, and service methods are modified to allow nullable fields, improve error handling, and add new functionalities such as project retrieval. On the frontend, corresponding GraphQL queries, mutations, and types are updated alongside new API routes and utility functions (including XML parsing and file reading adjustments). Additionally, enhancements in hook behavior and stream processing have been implemented.

Changes

File(s) Change Summary
backend/src/chat/chat.model.ts Updated GraphQL field definitions in ChatCompletionChoice and ChatCompletionChunk to allow null values.
backend/src/chat/chat.resolver.ts Renamed triggerChatStream to saveMessage, updated service call parameters, added error handling/logging, and introduced new query getCurProject.
backend/src/chat/chat.service.ts Added new method getProjectByChatId to fetch an associated project by chatId.
backend/src/chat/dto/chat.input.ts Added new field role (MessageRole) to ChatInput.
backend/src/common/.../openai-model-provider.ts Introduced variable oldStreamValue for preserving the last stream chunk during processing.
frontend/src/app/api/.../route.ts Added new GET endpoint to retrieve a file structure based on projectId with proper parameter validation and error handling.
frontend/src/graphql/{request.ts, schema.gql, type.tsx} Added new GraphQL queries (GET_CUR_PROJECT) and mutation (SAVE_MESSAGE), updated nullable fields, and modified the return structure of updateProjectPublicStatus.
frontend/src/hooks/useChatStream.ts Exported the UseChatStreamProps interface, integrated the SAVE_MESSAGE mutation, and enhanced logging in the handleChatResponse function.
frontend/src/utils/file-reader.ts Modified updateFile to trim newContent and added logging in place of JSON parsing.
frontend/src/utils/parser.ts Introduced parseXmlToJson, a new function to extract and parse JSON content from XML strings.
frontend/src/hooks/multi-agent/agentPrompt.ts Added enumeration TaskType and multiple functions for generating prompts related to agent tasks.
frontend/src/hooks/multi-agent/managerAgent.ts Implemented managerAgent function for managing multi-step AI-driven tasks with comprehensive error handling.
frontend/src/hooks/multi-agent/toolNodes.ts Defined tools for managing tasks, including ToolUsage interface and utility functions for tool management.
frontend/src/hooks/multi-agent/tools.ts Introduced various asynchronous functions for AI interactions and file management tasks.

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant CR as ChatResolver
    participant CS as ChatService

    C->>CR: saveMessage(input with role)
    CR->>CS: saveMessage(input)
    CS-->>CR: Boolean result
    CR-->>C: Response (Boolean)
Loading
sequenceDiagram
    participant C as Client
    participant API as API Route
    participant FR as FileReader

    C->>API: GET /api/filestructure?projectId=...
    API->>FR: fetchFileStructure(projectId)
    FR-->>API: File structure data
    API-->>C: File structure response / error
Loading

Possibly related PRs

  • feat(backend):fix some small issues #92: The changes in the main PR regarding nullable types in the ChatCompletionChoice and ChatCompletionChunk classes are related to the modifications in the ChatResolver class in the retrieved PR, specifically the updates to the MessageRole used when saving messages, as both involve adjustments to the handling of message data structures.
  • feat: getting project by chatId and show load status in code engine #119: The changes in the main PR, which involve making certain fields nullable in the ChatCompletionChoice and ChatCompletionChunk classes, are related to the modifications in the retrieved PR that also involve making the project field in the Chat class nullable, indicating a shared focus on enhancing the flexibility of data models.
  • feat(backend): add chat REST API with streaming support and DTO validation #189: The changes in the main PR, which involve modifying GraphQL field definitions for nullable types in the ChatCompletionChoice and ChatCompletionChunk classes, are related to the retrieved PR that introduces a new ChatController handling chat requests and saving messages, as both involve modifications to the chat-related data structures and message handling logic.

Suggested labels

enhancement

Poem

I'm a rabbit hopping through the code,
Tweaking fields to lighten each load.
New routes and queries in rhythmic flow,
With nulls allowed, the data will glow.
I nibble on logs and dance with delight—
CodeRabbit cheers this change, shining bright! 🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

frontend/src/hooks/multi-agent/agentPrompt.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the config "next/core-web-vitals" to extend from. Please check that the name of the config is correct.

The config "next/core-web-vitals" was referenced from the config file in "/frontend/.eslintrc.json".

If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.

Tip

⚡🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@NarwhalChen NarwhalChen marked this pull request as ready for review March 9, 2025 02:31
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🔭 Outside diff range comments (1)
backend/src/common/model-provider/openai-model-provider.ts (1)

12-12: 💡 Verification agent

🧩 Analysis chain

Resolve the dependency issue for 'codefox-common'

The pipeline is failing due to a missing dependency. Make sure 'codefox-common' is properly installed and configured.


🏁 Script executed:

#!/bin/bash
# Check if codefox-common is installed
if [ -f package.json ]; then
  echo "Checking package.json for codefox-common dependency"
  grep -A 5 "dependencies" package.json | grep "codefox-common"
fi

# Check if there's a local reference to the package
find . -name "codefox-common" -type d

Length of output: 253


Resolve Missing Dependency for codefox-common

The pipeline is failing because the module isn’t declared as a dependency in the backend’s package.json—even though a local directory (./codefox-common) exists. To fix this, please update the dependency configuration in your package.json (for example, by adding an entry like "codefox-common": "file:../codefox-common" if this module is meant to be used as a local package). This will ensure that the module is properly installed and available during the pipeline execution.

  • File: backend/src/common/model-provider/openai-model-provider.ts (line 12)
  • Issue: Missing dependency declaration in package.json despite the local folder presence.
  • Recommendation: Add or update the dependency configuration to reference the local package correctly.
🧰 Tools
🪛 GitHub Actions: Run tests and upload coverage

[error] 12-12: TS2307: Cannot find module 'codefox-common' or its corresponding type declarations.

🧹 Nitpick comments (16)
frontend/src/app/api/filestructure/route.ts (2)

24-31: Add type definition for projectId parameter

The fetchFileStructure function is missing type information for its parameter.

-async function fetchFileStructure(projectId) {
+async function fetchFileStructure(projectId: string) {

7-7: Consider renaming searchParam for clarity

The parameter is named 'path' in the URL but used as 'projectId' in the code. Consider aligning these names for better clarity.

-  const projectId = searchParams.get('path');
+  const projectId = searchParams.get('projectId');
backend/src/chat/chat.resolver.ts (4)

35-38: Consider validating 'input.chatId' before returning the asyncIterator.

If 'input.chatId' may be empty or undefined, add a guard clause or fallback to avoid potential runtime errors.


42-54: Validate arguments or handle invalid roles.

Consider validating 'input.role' against allowed roles. Currently, any string could be passed, potentially causing issues in your service layer. You could throw a specific error or handle unrecognized roles gracefully.


55-99: Ensure final chunk logic covers all edge cases.

The code accumulates content across the stream, then calls iterator.return() in finally. If the stream ends prematurely or iterator.return() is undefined, consider robust error handling or fallback logic to avoid potential runtime issues. Also be mindful of memory usage for very large streams.


132-144: Return null if project is not found instead of throwing.

Currently, you throw an error if no project is found or if fetching fails. Depending on the business logic, returning null (since the return type is nullable) might provide a more graceful UX. Alternatively, you could differentiate between “no project found” vs. “failed to fetch” errors to enhance clarity.

frontend/src/hooks/useChatStream.ts (8)

1-9: Consolidate imports usage.

Some of these imports might not be used in the final code snippet (e.g., 'debug' from 'console' or 'set' from 'react-hook-form'). Remove unused imports to keep your code clean.


13-14: Unused imports.

'debug' from 'console' and 'set' from 'react-hook-form' do not appear to be used. Consider removing them to avoid confusion.


56-56: Check whether 'isInsideJsonResponse' is used.

Currently, 'isInsideJsonResponse' is set to false but doesn't appear to be updated or consumed elsewhere. Consider removing or implementing it if required.


67-78: Multiple new states for file editing steps.

These states help manage various editing tasks. However, consider grouping them into a single object if they are often updated together, reducing the risk of stale states.


92-112: Reset states on chatId change.

Consider scoping the reset logic if only certain fields need to be cleared. A single complex effect can become a maintenance burden.


155-289: Large onData subscription callback.

  1. Consider extracting the typewriter logic into a separate utility for clarity and testability.
  2. If large messages arrive, character-by-character rendering could degrade performance; evaluate chunking or throttling.
  3. Validate 'chunk.choices?.[0]?.delta?.content' carefully to avoid runtime errors on missing fields.

376-377: Verbose logging.

Remove or demote these logs to avoid cluttering the console in production. If needed strictly for debugging, consider conditional logging.


425-495: taskAgent function handles multiple flows.

This function is sizable. Consider splitting 'debug', 'refactor', and 'optimize' flows into separate helper functions to enhance readability.

frontend/src/graphql/type.tsx (2)

59-61: Fields made nullable in ChatCompletionChoiceType

The delta and index fields in ChatCompletionChoiceType have been made optional. This change improves flexibility but may require additional null checks in consuming code.

Make sure any code that consumes these fields handles the possibility of null values to prevent runtime errors.


67-70: Multiple fields made nullable in ChatCompletionChunkType

The created, model, and object fields have been changed from required to optional. This improves API flexibility but might require updates to client-side code.

Ensure that consumers of this type are updated to handle potential null values for these fields.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf82dbf and 8df0262.

📒 Files selected for processing (13)
  • backend/src/chat/chat.model.ts (2 hunks)
  • backend/src/chat/chat.resolver.ts (4 hunks)
  • backend/src/chat/chat.service.ts (2 hunks)
  • backend/src/chat/dto/chat.input.ts (2 hunks)
  • backend/src/common/model-provider/openai-model-provider.ts (3 hunks)
  • frontend/src/app/api/filestructure/route.ts (1 hunks)
  • frontend/src/graphql/request.ts (2 hunks)
  • frontend/src/graphql/schema.gql (4 hunks)
  • frontend/src/graphql/type.tsx (11 hunks)
  • frontend/src/hooks/agentPrompt.ts (1 hunks)
  • frontend/src/hooks/useChatStream.ts (7 hunks)
  • frontend/src/utils/file-reader.ts (1 hunks)
  • frontend/src/utils/parser.ts (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Run tests and upload coverage
backend/src/common/model-provider/openai-model-provider.ts

[error] 12-12: TS2307: Cannot find module 'codefox-common' or its corresponding type declarations.

🔇 Additional comments (48)
backend/src/chat/dto/chat.input.ts (2)

3-3: Proper import of MessageRole enum.

The import statement correctly brings in the MessageRole enum from the message model file, which will be used for the new field in the ChatInput class.


30-31:

❓ Verification inconclusive

Good addition of the role field to ChatInput.

Adding the role field typed as MessageRole to the ChatInput class makes the API more versatile by allowing the specification of message roles instead of hardcoding them. This is a good enhancement.

However, be aware that this change might require updates in the model-provider.ts file mentioned in the TODO comment at line 20.


🏁 Script executed:

#!/bin/bash
# Check if the updated ChatInput is used in model-provider.ts and if any adjustments are needed there
echo "Checking for usage of ChatInput in model-provider.ts"
rg "ChatInput" --type ts "src/common/model-provider" -A 5 -B 5

Length of output: 241


Action Required: Verify Model-Provider Update

Great job on adding the role field typed as MessageRole to the ChatInput class—this enhancement clearly increases the API's flexibility. However, the original note mentioned that updates might be needed in the model-provider.ts file (per the TODO on line 20). Our initial check did not find a file at the expected location (src/common/model-provider), suggesting that either the file has been moved or the reference in the TODO is outdated.

  • Next Steps:
    • Please confirm whether the intended model-provider.ts file exists elsewhere in the repository.
    • If it does exist in a different location, ensure that any necessary adjustments concerning the new role field in ChatInput are applied accordingly.
    • If the file is no longer used or the TODO comment is obsolete, consider updating or removing the comment to prevent future confusion.
backend/src/chat/chat.service.ts (2)

14-14: Appropriate import for the Project model.

The import of the Project model is correctly added to support the new method for retrieving projects by chat ID.


95-102: Well-implemented project retrieval method.

The getProjectByChatId method is cleanly implemented with proper error handling. It:

  1. Queries for chats that aren't deleted
  2. Correctly includes the project relation
  3. Gracefully handles the null case instead of throwing exceptions

The method provides a useful way to get project information associated with a chat, likely to support new functionality in the application.

backend/src/common/model-provider/openai-model-provider.ts (2)

121-121: Good addition for handling stream state

Adding oldStreamValue to store the last received chunk is a good approach for maintaining state, especially for handling stream completion properly.


170-181: Good implementation for handling stream completion

The return implementation correctly handles stream completion by including the last stored chunk value and setting the appropriate status and finish reason.

frontend/src/app/api/filestructure/route.ts (1)

5-22: Well-structured API endpoint with proper error handling

The GET endpoint is well-structured with appropriate error handling for missing parameters and potential exceptions during execution.

frontend/src/graphql/request.ts (2)

175-183: Well-defined GraphQL query for project retrieval

The new query for retrieving project information based on a chatId is well-structured and includes the essential project properties.


184-188: Well-defined mutation for saving messages

The new mutation for saving messages is concise and properly typed with the required input parameter.

backend/src/chat/chat.model.ts (4)

78-79: Good enhancement for type flexibility

Making the index field nullable improves flexibility when handling streaming responses that might have incomplete data.


81-82: Good enhancement for type flexibility

Making the delta field nullable improves flexibility in the data model, especially for handling streaming responses where certain fields might be absent.


93-100: Good enhancement for type flexibility

Making these fields nullable enhances the data model's flexibility when dealing with partial data or external API responses where certain fields might not always be present.


104-110:

❓ Verification inconclusive

Verify compatibility with nullable fields

The choices array is required, while its elements have nullable fields. Ensure that your application properly handles cases where these fields might be null, especially in TypeScript code that expects these values to be defined.


🏁 Script executed:

#!/bin/bash
# Search for places where ChatCompletionChunk is used to ensure null handling
echo "Searching for usage of ChatCompletionChunk..."
rg "ChatCompletionChunk" -A 3 -B 3 --glob "*.ts"

Length of output: 10319


Attention: Verify Null Handling in ChatCompletion Choices

The GraphQL schema requires the choices array, but individual elements within it may have nullable properties. Please ensure that every consumer of this data (e.g., in ChatService, ChatResolver, etc.) explicitly handles these potential null values—especially in cases where TypeScript code assumes the properties are defined. This check is crucial to avoid unintended runtime errors when processing chat completions.

backend/src/chat/chat.resolver.ts (3)

2-2: Importing StreamStatus is beneficial.


5-5: Import for Message is logically consistent.


15-15: Import for Project appears consistent with usage.

frontend/src/hooks/useChatStream.ts (14)

18-26: Modular approach for prompt generation.

This is a good approach for separating prompt logic from the main hook, making code more maintainable.


28-32: Proper enumeration of stream statuses.

Well-defined enum capturing the streaming states. Great clarity for readability.


34-39: SubscriptionState interface is straightforward.

No concerns here.


41-47: Clear prop interface definition.

Looks good for typed prop usage, ensuring clarity in the hook’s arguments.


61-62: Tracking currentChatId and cumulatedContent.

Using separate states for chat ID and aggregated content is a helpful approach for clarity and debugging.


80-80: Storing project data in state is sensible.

No immediate concerns.


82-90: Querying for CurProject on the client side.

The approach of skipping the query until 'currentChatId' is non-empty is good to avoid redundant requests.


114-118: Handling projectError with an effect.

Logs the error if fetching fails, good for debugging. Optionally consider user-facing error messages if needed.


303-349: startChatStream workflow.

Persisting the user message with 'saveMessage' is an excellent improvement. The approach of passing an 'assistant' prompt aligns well with the agent-based tasks.


500-552: Fetching file contents in parallel efficiently.

Good use of Promise.all to retrieve multiple files concurrently. Consider more robust error handling for each fetch in case one fails.


587-641: Code review agent logic.

Parses 'modified_files' from JSON, merges into ‘newFileContents’, and triggers a review prompt. This is a practical approach for an integrated code review workflow.


643-661: Committing changes agent function.

Generating a commit message with the new approach is consistent with your commit prompt. The standardized flow ensures clarity.


15-17:

❓ Verification inconclusive

Check environment constraints for 'path' usage.

Some browsers or bundlers may not fully support 'path' from Node. Validate that your environment or bundler is properly configured to handle 'path' usage in the frontend.


🏁 Script executed:

#!/bin/bash
rg -A 5 "path from 'path'"

Length of output: 15418


Action Required: Verify Node Polyfill Configuration for Frontend Bundling

The import of Node’s built-in "path" module in frontend/src/hooks/useChatStream.ts (and elsewhere in the frontend) could lead to runtime issues in browser environments if your bundler isn’t set up to polyfill Node core modules. Please double-check your bundler (e.g., Vite, Webpack) configuration to ensure that Node’s "path" is either properly polyfilled (for example, using path-browserify or an equivalent plugin) or replaced with a browser-compatible alternative if its functionality is needed in the browser.

  • Verify Bundler Configurations:
    • If using Vite, confirm that you have a plugin or configuration setting for Node polyfills.
    • If using Webpack, ensure the resolve.fallback for "path" is defined.

556-585:

❓ Verification inconclusive

Applying changes to local files.

Confirm that the backend /api/file endpoint is secure and properly authenticates users. Otherwise, malicious requests could overwrite files. Let’s search usage of /api/file in the codebase:


🏁 Script executed:

#!/bin/bash
rg "/api/file"

Length of output: 670


Security Verification of /api/file Endpoint

The frontend code that calls the /api/file endpoint appears to work as expected when applying file changes. However, please double-check the backend implementation in frontend/src/app/api/file/route.ts to ensure that it enforces proper authentication (e.g., validating sessions or tokens) before authorizing file modifications. This verification is crucial to avoid potential unauthorized or malicious changes.

  • Files to review:
    • frontend/src/app/api/file/route.ts
frontend/src/hooks/agentPrompt.ts (8)

1-60: Centralized system prompt definition.

Encapsulating system-level instructions in one function is a good practice, making the prompts consistent across multiple tasks.


61-97: Leader prompt sets the stage for analyzing user requirements.

Appropriately references systemPrompt and ensures structured JSON output, which aligns with your AI-based tasks.


98-134: Refactor prompt.

Clearly directs the AI to return structured JSON describing refactoring changes. The instructions about code modularization are suitably detailed.


135-171: Optimize prompt for performance improvements.

Covers typical re-render or API inefficiency scenarios. Well-structured for highlighting performance bottlenecks.


172-215: Prompt for file editing.

Captures a robust approach to guiding the AI through analyzing bug descriptions and file contents. Good clarity in how the updated code must be returned.


216-255: Prompt for code reviews.

Straightforward instructions for the AI to provide a structured review result, including 'review_result' and 'comments'.


256-290: Prompt for generating commit messages.

Ensures commits are documented clearly and concisely, aligned with conventional commit standards.


291-325: Prompt for bug diagnosis.

Focuses on identifying potentially affected files and returning them in a structured JSON output.

frontend/src/graphql/type.tsx (5)

165-165: New saveMessage mutation added

A new mutation for saving messages has been introduced, along with its corresponding argument type.

This is a good addition that provides a dedicated method for saving chat messages.

Also applies to: 221-223


298-298: New getCurProject query added

A new query has been added to retrieve the current project based on a chatId.

This is a useful addition that enables retrieving project context within chat interactions.

Also applies to: 326-328


787-792: Resolver implementation for saveMessage mutation

The resolver implementation for the new saveMessage mutation has been properly defined.

The implementation correctly specifies the return type and required input parameters.


925-930: Resolver implementation for getCurProject query

The resolver implementation for the new getCurProject query has been properly defined.

The implementation correctly specifies the return type and required chatId parameter.


84-84:

✅ Verification successful

Required role field added to ChatInputType

The addition of a required role field to ChatInputType is a breaking change that might affect existing code using this type.

Verify that all places using ChatInputType are updated to include the role parameter:


🏁 Script executed:

#!/bin/bash
# Search for places using ChatInputType without providing role
rg "ChatInputType|triggerChatStream|chatStream" -A 5 -B 5 --type ts --type tsx

Length of output: 108


Attention: Verify updates in ChatInputType usage

The update at frontend/src/graphql/type.tsx (line 84) adds a required role field to ChatInputType, which is a breaking change. Please manually verify that all usages of ChatInputType (including calls in contexts like triggerChatStream or chatStream) have been updated to include the role parameter. The above script now correctly searches both .ts and .tsx files—use its output to confirm there are no cases missing the new field.


---

🏁 Script executed:

```shell

#!/bin/bash
# Re-run the search command using corrected globs for TypeScript files.
rg "ChatInputType" --glob "*.ts" --glob "*.tsx" -A 5 -B 5

Length of output: 16625


All instances of ChatInputType now include the required role parameter.
We verified that every usage—such as in frontend/src/hooks/useChatStream.ts and within GraphQL request definitions—appropriately passes a role value. No branch of the codebase was found to be missing this update.

frontend/src/graphql/schema.gql (5)

19-21: Fields made nullable in ChatCompletionChoiceType

The delta and index fields have been made nullable in the schema. This provides more flexibility in handling API responses.

This matches the corresponding changes in the TypeScript definitions.


26-29: Multiple fields made nullable in ChatCompletionChunkType

The created, model, and object fields have been made nullable. This allows for more flexible API responses.

This is consistent with the changes in the TypeScript types file.


42-42: Required role field added to ChatInputType

A new required field role: String! has been added to the ChatInputType input type.

Since this is a breaking change, ensure all clients sending chat inputs have been updated to include the role field. The role should be one of the values defined in the Role enum (Assistant, System, or User).


121-121: New saveMessage mutation added

A new mutation has been added to save chat messages, taking a ChatInputType and returning a Boolean.

This provides a clear API endpoint for saving chat messages.


179-179: New getCurProject query added

A new query has been added to retrieve the current project associated with a chat.

This enhances the API by providing a way to get project context from a chat ID.

Comment on lines 89 to 91
const content = newContent.trim();
console.log(content);
console.log('log content');
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove debugging logs and clarify content handling changes.

The changes to the updateFile method have removed JSON parsing in favor of simple string trimming. Additionally, debugging console logs have been added that don't provide meaningful context.

Consider:

  1. Removing console.log statements that don't provide useful debugging information
  2. Clarifying whether removing JSON parsing was intentional - if content should still be validated as JSON, add appropriate validation
-      const content = newContent.trim();
-      console.log(content);
-      console.log('log content');
+      const content = newContent.trim();
+      // Validate content if needed (e.g., check JSON validity if required)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const content = newContent.trim();
console.log(content);
console.log('log content');
const content = newContent.trim();
// Validate content if needed (e.g., check JSON validity if required)

Comment on lines 1 to 20
export const parseXmlToJson = (xmlString: string) => {
console.log(xmlString);
const match = xmlString.match(/<jsonResponse>([\s\S]*?)<\/jsonResponse>/);
console.log(match);
console.log(match[1]);
if (!match || !match[1]) {
throw new Error('Invalid XML: No <jsonResponse> element found');
}

const jsonText = match[1].trim();
console.log(jsonText);

try {
return JSON.parse(jsonText);
} catch (error) {
throw new Error(
'Invalid JSON: Failed to parse content inside <jsonResponse>' + error
);
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Clean up debug logging and improve XML parsing approach.

The parseXmlToJson function needs several improvements for production code:

  1. Remove the numerous console.log statements (lines 2, 4, 5, 11)
  2. The error handling in line 6 has an issue - it will attempt to access match[1] after checking if match exists, but before validating that match[1] exists
  3. Consider using a proper XML parser library instead of regex for more robust parsing
  4. Include the original input in error messages to aid debugging
export const parseXmlToJson = (xmlString: string) => {
-  console.log(xmlString);
  const match = xmlString.match(/<jsonResponse>([\s\S]*?)<\/jsonResponse>/);
-  console.log(match);
-  console.log(match[1]);
-  if (!match || !match[1]) {
+  if (!match) {
    throw new Error('Invalid XML: No <jsonResponse> element found');
  }
+  
+  if (!match[1]) {
+    throw new Error('Empty content in <jsonResponse> tags');
+  }

  const jsonText = match[1].trim();
-  console.log(jsonText);

  try {
    return JSON.parse(jsonText);
  } catch (error) {
    throw new Error(
-      'Invalid JSON: Failed to parse content inside <jsonResponse>' + error
+      `Invalid JSON: Failed to parse content inside <jsonResponse>: ${error.message}`
    );
  }
};

For a more robust solution, consider using an XML parser library like fast-xml-parser or xml2js.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const parseXmlToJson = (xmlString: string) => {
console.log(xmlString);
const match = xmlString.match(/<jsonResponse>([\s\S]*?)<\/jsonResponse>/);
console.log(match);
console.log(match[1]);
if (!match || !match[1]) {
throw new Error('Invalid XML: No <jsonResponse> element found');
}
const jsonText = match[1].trim();
console.log(jsonText);
try {
return JSON.parse(jsonText);
} catch (error) {
throw new Error(
'Invalid JSON: Failed to parse content inside <jsonResponse>' + error
);
}
};
export const parseXmlToJson = (xmlString: string) => {
const match = xmlString.match(/<jsonResponse>([\s\S]*?)<\/jsonResponse>/);
if (!match) {
throw new Error('Invalid XML: No <jsonResponse> element found');
}
if (!match[1]) {
throw new Error('Empty content in <jsonResponse> tags');
}
const jsonText = match[1].trim();
try {
return JSON.parse(jsonText);
} catch (error) {
throw new Error(
`Invalid JSON: Failed to parse content inside <jsonResponse>: ${error.message}`
);
}
};

Comment on lines +148 to +150
console.log('isDone:', chunk.done);
console.log('chunk:', chunk);
if (!chunk.done) oldStreamValue = chunkValue;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove debugging console logs before merging

These console logs appear to be debugging statements that should be removed before merging to production. They could potentially log sensitive information and will clutter the console.

-          console.log('isDone:', chunk.done);
-          console.log('chunk:', chunk);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log('isDone:', chunk.done);
console.log('chunk:', chunk);
if (!chunk.done) oldStreamValue = chunkValue;
if (!chunk.done) oldStreamValue = chunkValue;

Comment on lines +165 to +167
console.log(stream);
console.log(streamIterator);
console.log('return() called');
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove debugging console logs before merging

These console logs should be removed before merging to production.

-        console.log(stream);
-        console.log(streamIterator);
-        console.log('return() called');
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log(stream);
console.log(streamIterator);
console.log('return() called');

Comment on lines +236 to +240
path
projectPackages {
id
content
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify frontend usage after mutation response change

The response structure of UPDATE_PROJECT_PUBLIC_STATUS has changed from returning isPublic to returning path and adding projectPackages. Make sure all frontend code that uses this mutation is updated accordingly.


🏁 Script executed:

#!/bin/bash
# Search for references to updateProjectPublicStatus that might need updating
echo "Searching for updateProjectPublicStatus usage..."
rg -A 5 -B 5 "updateProjectPublicStatus" --glob "*.{ts,tsx,js,jsx}"

Length of output: 9517


Action: Update mutation handling in frontend to align with updated response structure

It looks like the GraphQL mutation definition in frontend/src/graphql/request.ts now returns path and projectPackages (with fields such as id and content) instead of the old isPublic field. However, the client code—specifically in frontend/src/components/chat/code-engine/project-context.tsx—still relies on data.updateProjectPublicStatus.isPublic for displaying toast messages and updating local state.

Please adjust the following:

  • Toast Success Message: Modify the onCompleted handler so that it no longer uses isPublic (e.g., update the message logic if the new fields can determine visibility).
  • State Updates: Update the state management logic in project-context.tsx that currently expects an isPublic property (e.g., update the mapping of projects and setting of the current project) so that it conforms to the new API response.

Review all usages of updateProjectPublicStatus to ensure that the new response structure is fully supported.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
frontend/src/graphql/type.tsx (1)

90-90: Required role field added to ChatInputType.

The addition of a required role field to the ChatInputType will help differentiate between different message types in the chat.

Consider using the existing Role enum type for better type safety rather than a string:

-  role: Scalars['String']['input'];
+  role: Role;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8df0262 and 8912aa8.

📒 Files selected for processing (3)
  • frontend/src/graphql/request.ts (2 hunks)
  • frontend/src/graphql/schema.gql (4 hunks)
  • frontend/src/graphql/type.tsx (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/graphql/schema.gql
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Install and Build Frontend
  • GitHub Check: Install and Build Backend
🔇 Additional comments (9)
frontend/src/graphql/request.ts (3)

176-184: New GET_CUR_PROJECT query looks good.

This query to retrieve a project by chatId provides a useful endpoint for getting project context in chat functionality.


185-189: Added SAVE_MESSAGE mutation supports persisting chat messages.

This new mutation will allow saving messages, enhancing the chat feature's functionality.


237-241: UPDATE_PROJECT_PUBLIC_STATUS mutation now returns different fields.

The mutation response has been updated to return path and projectPackages instead of the previous isPublic field.

This change requires updating all places in the code that use this mutation response. Please check for any UI components that might be expecting the isPublic field in the response.

#!/bin/bash
# Search for places that use UPDATE_PROJECT_PUBLIC_STATUS mutation response
echo "Searching for places using updateProjectPublicStatus mutation response..."
rg -A 5 "updateProjectPublicStatus" --glob "*.{ts,tsx}"
frontend/src/graphql/type.tsx (6)

65-67: ChatCompletionChoiceType fields are now optional.

Making the delta, finishReason, and index fields optional improves compatibility with API responses that might not include these fields.


73-76: ChatCompletionChunkType fields are now optional.

Similar to the previous change, making the created, model, and object fields optional helps handle more flexible API responses.


228-230: New MutationSaveMessageArgs type added.

This properly defines the arguments for the new saveMessage mutation.


338-340: New QueryGetCurProjectArgs type added.

This supports the new getCurProject query for retrieving a project by chatId.


816-821: New saveMessage resolver defined.

The resolver is properly typed to match the GraphQL schema definition.


960-965: New getCurProject resolver defined.

The resolver follows the correct typing pattern for the GraphQL schema.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (18)
frontend/src/hooks/multi-agents/managerAgent.ts (1)

85-85: Address linter complaint about the while (true) loop.
This may cause a pipeline failure due to “unexpected constant condition.” Consider a more descriptive condition or disable the rule locally if the loop is intentional.

Example fix:

-while (true) {
+let continueLoop = true;
+while (continueLoop) {
   ...
   if (responseJson.status === 'END') {
     continueLoop = false;
   }
}
🧰 Tools
🪛 GitHub Check: autofix

[failure] 85-85:
Unexpected constant condition

🪛 GitHub Actions: autofix.ci

[error] 85-85: Unexpected constant condition.

frontend/src/hooks/useChatStream.ts (9)

13-14: Unused imports
The imports set from 'react-hook-form' and debug from 'console' don't appear to be used. Cleaning them out can reduce clutter and potential confusion.

- import { set } from 'react-hook-form';
- import { debug } from 'console';

15-17: Potential error handling for XML parsing
parseXmlToJson is imported, but there's no visible fallback or error handling if the XML is malformed. Consider wrapping usage in a try/catch to avoid runtime exceptions.

+  try {
+    const parsedContent = parseXmlToJson(cumulatedContent);
+    // ...
+  } catch (e) {
+    console.error("Failed to parse XML response", e);
+  }

34-47: Well-defined interfaces for subscription logic
Both SubscriptionState and UseChatStreamProps interfaces improve type safety. Consider making fields optional or using more explicit union types if you expect certain properties to be absent.


56-56: Large state usage in a single hook
Multiple local states (isInsideJsonResponse, taskDescription, fileStructure, etc.) increase the complexity of useChatStream. For better maintainability, consider grouping related states into a reducer or a context if they are semantically related.

Also applies to: 61-62, 67-80


82-118: Project fetching and error handling
The useQuery for GET_CUR_PROJECT and subsequent useEffect to refetch data is a practical approach. However, you only log the error to console if projectError occurs. Consider user-facing error states or fallback UI to improve clarity and UX.


147-156: Subscription onData logic
Your onData callback checks for chatStream nullability and updates the UI state. The current approach works, but be aware of unsubscribing or cleaning up if a user navigates away mid-stream to avoid potential memory leaks.

Also applies to: 159-159, 162-162


167-167: Accumulating content and text streaming
Appending to cumulatedContent and then parsing it into JSON is creative. Ensure that extremely large messages don't degrade performance or cause out-of-memory issues. The typewriter effect is nice for UX but can be CPU bound if the text is long; consider a speed-limiting option or user-cancel button.

Also applies to: 170-170, 173-174, 177-183, 186-245


248-290: Modular tasks in switch statement
Calling different agents (taskAgent, editFileAgent, etc.) is a flexible design. However, a fallback default case (even if just logging an unrecognized task) might help detect unexpected taskStep values.


375-392: handleSubmit logic
The ability to create a new chat or continue an existing one is straightforward. Consider adding a loading or disabled state for the form to prevent accidental double submits.

frontend/src/hooks/multi-agents/agentPrompt.ts (3)

61-97: Task classification logic
leaderPrompt clarifies how to detect a debugging, optimizing, or unrelated request. This is helpful context. Ensure that more complex tasks (like both debugging and refactoring) are gracefully handled, or at least recognized, in future expansions.


98-215: Refactor, optimize, and edit file prompts
These prompts provide clear instructions for specialized tasks (refactoring, optimizing, or editing files). They embed instructions for the AI to produce carefully structured JSON. This approach is fine, though combining large strings can impose maintainability concerns if they grow further.


256-289: Commit changes prompt
The commit message prompt includes separate commit_message and thinking_process. This clarifies what to write in the commit log. Keep an eye out for potential expansions, such as referencing issue IDs or merging references.

frontend/src/hooks/multi-agents/tools.ts (5)

17-85: taskAgent implementation
The logic to fetch a file structure once and store it is sensible. However, ensure that repeated calls (e.g., switching tasks within the same chat) correctly update or reuse the file structure. A fallback or default case for unknown tasks (like "unrelated") might avoid silent no-ops.


87-147: editFileAgent retrieval of file contents
Fetching file contents per path is a practical approach. Consider concurrency limits or error handling if a file fetch fails. Right now, it logs console errors; adding sticky notifications or UI feedback might improve the user experience.


149-186: applyChangesAgent writes updated files
Posting to /api/file with new content is straightforward. For large files, watch out for potential timeouts or large payload sizes. Also, the agent automatically calls commitChangesAgent after applying changes. Confirm that’s always desired, or allow the user to confirm first.


188-242: codeReviewAgent JSON parsing
There's a try/catch block to handle potential parsing issues with modified_files. This is good practice, though you may want to add user-facing error feedback (via toast.error) to explain that the code review input was invalid.


271-296: createChat and startChatStream placeholders
These are simple placeholders that log to console and simulate chat creation/stream start. Ensure they integrate with real GraphQL mutations in production. Failure states should be handled with user feedback.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8912aa8 and 1bdfedf.

📒 Files selected for processing (7)
  • frontend/src/hooks/multi-agents/agentPrompt.ts (1 hunks)
  • frontend/src/hooks/multi-agents/agentType.ts (1 hunks)
  • frontend/src/hooks/multi-agents/managerAgent.ts (1 hunks)
  • frontend/src/hooks/multi-agents/managerContext.ts (1 hunks)
  • frontend/src/hooks/multi-agents/toolNodes.ts (1 hunks)
  • frontend/src/hooks/multi-agents/tools.ts (1 hunks)
  • frontend/src/hooks/useChatStream.ts (7 hunks)
🧰 Additional context used
🪛 GitHub Check: autofix
frontend/src/hooks/multi-agents/managerAgent.ts

[failure] 85-85:
Unexpected constant condition

🪛 GitHub Actions: autofix.ci
frontend/src/hooks/multi-agents/managerAgent.ts

[error] 85-85: Unexpected constant condition.

🔇 Additional comments (14)
frontend/src/hooks/multi-agents/agentType.ts (2)

1-5: Interfaces look good overall.
Introduces a clear contract for manager agent inputs. No issues noted.


7-10: Straightforward response interface.
This is well-structured and easy to maintain. No changes required.

frontend/src/hooks/multi-agents/toolNodes.ts (1)

20-57: All tool implementations are well-organized.
The overall structure is good, and each tool has a clear toolName, behavior, and description.

frontend/src/hooks/multi-agents/managerContext.ts (1)

5-36: Context interface is comprehensive.
Properties and setters are well-defined. Integration with GraphQL types is consistent.

frontend/src/hooks/useChatStream.ts (5)

1-9: Appropriate import additions, no immediate issues observed
These lines add necessary imports from React and Apollo libraries. The usage appears correct and follows standard practices for integrating React hooks with Apollo.


28-32: Clear enumeration for stream states
Introducing StreamStatus as an enum helps maintain clarity around possible streaming states. This is a good pattern for consistent status checks.


137-137: Mutation usage
Using saveMessage and createChat is straightforward. Make sure to handle any concurrency or race conditions when rapidly creating or switching chats. For example, a user might click “new chat” multiple times in quick succession.

Also applies to: 141-141


303-315: Initiating chat with user and assistant prompts
Creating combined user and assistant input, then triggering the chat is well structured. Be sure to validate message content for length or forbidden characters if the user input might be malicious.

Also applies to: 324-325, 329-337, 340-349


663-672: Returning final hook API
Exposing loadingSubmit, handleSubmit, handleInputChange, and others is standard. This nicely finalizes the custom hook’s interface for consuming components.

frontend/src/hooks/multi-agents/agentPrompt.ts (3)

1-59: Structured system prompt
The systemPrompt function strictly enforces a JSON-in-XML response format. This is an effective way to standardize outputs. However, be sure that the AI always correctly wraps the JSON, as any user-provided code or chain-of-thought might disrupt the strict format.


216-255: Code review prompt
The prompt structure for code review is descriptive and consistent with the rest of the system. If future code review expansions are needed (e.g., security scanning or style checks), this format can be extended easily.


291-324: Bug-finding prompt
findbugPrompt effectively guides the AI to identify likely affected files. The usage is consistent with the other tasks. Just confirm that your code doesn't trip up if it encounters an unusual bug scenario that doesn't fit typical patterns.

frontend/src/hooks/multi-agents/tools.ts (2)

1-16: Import statements and commentary
Imports for ChatInputType, toast, and the various prompt generators are organized. The high-level code comment clarifies the module's purpose, providing quick insight into how tasks are handled.


244-269: commitChangesAgent
Composing the commit message from the user-provided changes is a nice final step. Consider ensuring these messages meet a typical commit style guideline if your project follows one (e.g., Conventional Commits).

Comment on lines 12 to 16
export interface Tool {
toolName: string;
behavior: string;
description: string;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Flag mismatch with implementation of Tool interface.
Here, behavior is declared as a string, but in toolNodes.ts, it’s a function (input: ChatInputType) => Promise<void>. This can lead to runtime errors or TypeScript type mismatches.

To fix, align them under a single definition, for example:

 export interface Tool {
   toolName: string;
-  behavior: string;
+  behavior: (input: ChatInputType) => Promise<void>;
   description: string;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export interface Tool {
toolName: string;
behavior: string;
description: string;
}
export interface Tool {
toolName: string;
behavior: (input: ChatInputType) => Promise<void>;
description: string;
}

Comment on lines 14 to 18
export interface Tool {
toolName: string;
behavior: (input: ChatInputType) => Promise<void>;
description: string;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Mismatched parameter signature for behavior.
The Tool interface in agentType.ts differs, defining behavior as a string. Ensure both definitions match to avoid type conflicts.

Comment on lines 11 to 22
async function executeTool(
toolName: string,
input: ManagerAgentInput,
context: ManagerContext
): Promise<string> {
const tool = managerTools.find((t) => t.toolName === toolName);
if (!tool) {
throw new Error(`Tool ${toolName} not found`);
}
// 调用工具的 behavior 方法,并返回真实的 JSON 字符串结果
return await tool.behavior(input, context);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Check for type compatibility with behavior.
executeTool passes context to tool.behavior, yet the Tool interface in toolNodes.ts only accepts a single parameter. Clarify the function signatures to avoid runtime or TypeScript errors.

Comment on lines 425 to 661
console.log('Updating file:', filePath);
console.log('New Content:', newContent);
const fpath = path.join(curProject.projectPath, filePath);
await fetch('/api/file', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ filePath: fpath, newContent }),
});
}
);

await Promise.all(updatePromises);
setTaskStep('apply_changes');
toast.success('Changes applied successfully');
commitChangesAgent({
chatId: input.chatId,
message: JSON.stringify(newFileContents),
model: input.model,
role: 'assistant',
});
},
[newFileContents]
);

const codeReviewAgent = useCallback(async (input: ChatInputType) => {
console.log('codeReviewAgent called with input:', input);

let parsedMessage: { [key: string]: string } = {};

try {
if (typeof input.message === 'string') {
const parsedObject = JSON.parse(input.message);

if (
parsedObject.modified_files &&
typeof parsedObject.modified_files === 'object'
) {
parsedMessage = parsedObject.modified_files;
} else {
console.error('modified_files is missing or not an object');
}
}
} catch (error) {
console.error('Failed to parse input.message:', error);
}

console.log('Parsed modified_files:', parsedMessage);

console.log('Parsed Message:', parsedMessage);

setNewFileContents((prev) => ({ ...prev, ...parsedMessage }));

const formattedMessage = Object.entries(parsedMessage)
.map(
([filePath, content]) =>
`### File: ${filePath}\n\`\`\`\n${content}\n\`\`\``
)
.join('\n\n');

const prompt = codeReviewPrompt(formattedMessage);

const promptInput: ChatInputType = {
chatId: input.chatId,
message: prompt,
model: input.model,
role: 'assistant',
};

console.log('Prompt Input:', promptInput);
setTaskStep('code_review');
setStreamStatus(StreamStatus.STREAMING);
setSubscription({
enabled: true,
variables: { input: promptInput },
});

await new Promise((resolve) => setTimeout(resolve, 100));
await triggerChat({ variables: { input: promptInput } });
}, []);

const commitChangesAgent = useCallback(async (input: ChatInputType) => {
console.log('commitChangesAgent called with input:', input);
const prompt = commitChangesPrompt(input.message);
const promptInput: ChatInputType = {
chatId: input.chatId,
message: prompt,
model: input.model,
role: 'assistant',
};
console.log('Prompt Input:', promptInput);
setTaskStep('commit');
setStreamStatus(StreamStatus.STREAMING);
setSubscription({
enabled: true,
variables: { input: promptInput },
});
await new Promise((resolve) => setTimeout(resolve, 100));
await triggerChat({ variables: { input: promptInput } });
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Potential duplication with existing tools
The embedded definitions for taskAgent, editFileAgent, applyChangesAgent, codeReviewAgent, and commitChangesAgent appear identical or very similar to the logic in multi-agents/tools.ts. Maintaining them in two places can lead to inconsistencies. Refactor to avoid duplication and keep a single source of truth.

@NarwhalChen NarwhalChen force-pushed the feat-frontend-interactive-chat branch from a1375b7 to f9daff6 Compare March 17, 2025 03:47
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
backend/src/chat/chat.service.ts (1)

102-109: Consider adding logging for improved debugging.

The implementation of getProjectByChatId looks good and follows the pattern of other methods in the service. However, consider adding logging (using the Logger) to track when projects or chats are not found, which would help with debugging.

  async getProjectByChatId(chatId: string): Promise<Project> {
    const chat = await this.chatRepository.findOne({
      where: { id: chatId, isDeleted: false },
      relations: ['project'],
    });
+
+    if (!chat) {
+      Logger.log(`Chat with id ${chatId} not found when retrieving project`);
+    } else if (!chat.project) {
+      Logger.log(`No project associated with chat id ${chatId}`);
+    }

    return chat ? chat.project : null;
  }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1bdfedf and f9daff6.

📒 Files selected for processing (3)
  • backend/src/chat/chat.service.ts (2 hunks)
  • frontend/src/hooks/useChatStream.ts (3 hunks)
  • frontend/src/utils/file-reader.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/utils/file-reader.ts
  • frontend/src/hooks/useChatStream.ts
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Install and Build Frontend
  • GitHub Check: Run tests and collect coverage
🔇 Additional comments (2)
backend/src/chat/chat.service.ts (2)

14-14: LGTM: Clean import addition.

The import of the Project model is correctly added to support the new method functionality.


102-109:

❓ Verification inconclusive

Verify consistent error handling with other service methods.

The method returns null for not-found cases instead of throwing a NotFoundException like getChatDetails. This appears to be a deliberate choice to handle the not-found case gracefully, similar to methods like getChatHistory. Verify that this is the intended behavior for this use case.


🏁 Script executed:

#!/bin/bash
# Check how error handling is implemented in the GraphQL resolver that calls this method

# Look for the resolver that uses the getProjectByChatId method
rg -A 10 "getCurProject|getProjectByChatId" --type ts --glob="**/*.resolver.ts"

Length of output: 936


Confirm the Intended Error Handling Behavior for getProjectByChatId

After verifying the resolver that calls this method (see backend/src/chat/chat.resolver.ts), it appears that the code is designed to return null for a not-found chat instead of throwing a NotFoundException, similar to the approach taken in getChatHistory. The resolver wraps the call in a try-catch block but does not perform an explicit check for a null response, which suggests this behavior is deliberate.

  • Review the usage: The resolver calls getProjectByChatId and logs the result directly before returning it.
  • Confirm intent: Ensure that, for this use case, returning null is the expected and documented behavior. If returning null is intended, consider adding a comment in the service method to clarify this design decision for future maintainers.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (5)
frontend/src/api/ChatStreamAPI.ts (1)

31-68: Incomplete streaming implementation with TODOs.

There's a large commented-out section for handling streaming responses. This could lead to confusion about what's implemented vs. what's planned.

Consider either:

  1. Implementing the streaming functionality now
  2. Moving the commented code to a separate file as a reference
  3. Converting it to a proper TODO with less code to reduce visual noise
frontend/src/hooks/useChatStream.ts (2)

35-36: Remove console.log statements before production.

Debug logging statements should be removed before code goes to production.

- console.log('curProject:', curProject);

130-131: Remove debug console.log statements.

These debug statements should be removed before production.

- console.log('currentChatId: ' + currentChatId);
- console.log('Creating new chat...');
frontend/src/hooks/multi-agent/tools.ts (1)

223-326: Line-by-line animation is user-friendly but can be slow for large files.
The progressive content update is a creative approach. If project files scale up, you could consider an option to skip or speed up the animation for better performance.

frontend/src/hooks/multi-agent/agentPrompt.ts (1)

6-34: Improve type safety for editorRef.
The editorRef property is declared as React.MutableRefObject<any> which weakens type checking. Consider using a more specific type or introducing a generic type parameter to avoid over-reliance on any. This leads to more reliable IntelliSense and compile-time checks.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9daff6 and 90df595.

📒 Files selected for processing (12)
  • backend/src/chat/chat.controller.ts (2 hunks)
  • frontend/src/api/ChatStreamAPI.ts (1 hunks)
  • frontend/src/components/chat/code-engine/code-engine.tsx (2 hunks)
  • frontend/src/components/chat/code-engine/project-context.tsx (5 hunks)
  • frontend/src/graphql/schema.gql (5 hunks)
  • frontend/src/graphql/type.tsx (12 hunks)
  • frontend/src/hooks/multi-agent/agentPrompt.ts (1 hunks)
  • frontend/src/hooks/multi-agent/managerAgent.ts (1 hunks)
  • frontend/src/hooks/multi-agent/toolNodes.ts (1 hunks)
  • frontend/src/hooks/multi-agent/tools.ts (1 hunks)
  • frontend/src/hooks/useChatStream.ts (5 hunks)
  • frontend/src/utils/parser.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • frontend/src/utils/parser.ts
  • frontend/src/graphql/schema.gql
  • frontend/src/graphql/type.tsx
🧰 Additional context used
🧬 Code Definitions (3)
frontend/src/api/ChatStreamAPI.ts (1)
frontend/src/graphql/type.tsx (1) (1)
  • ChatInputType (86:91)
frontend/src/hooks/useChatStream.ts (4)
frontend/src/components/chat/code-engine/project-context.tsx (1) (1)
  • ProjectContext (55:57)
frontend/src/graphql/request.ts (1) (1)
  • SAVE_MESSAGE (185:189)
frontend/src/graphql/type.tsx (1) (1)
  • ChatInputType (86:91)
frontend/src/hooks/multi-agent/managerAgent.ts (1) (1)
  • managerAgent (41:223)
frontend/src/hooks/multi-agent/managerAgent.ts (5)
frontend/src/graphql/type.tsx (2) (2)
  • ChatInputType (86:91)
  • Message (145:155)
frontend/src/hooks/multi-agent/agentPrompt.ts (2) (2)
  • AgentContext (6:34)
  • confirmationPrompt (396:465)
frontend/src/api/ChatStreamAPI.ts (1) (1)
  • startChatStream (3:71)
frontend/src/utils/parser.ts (1) (1)
  • parseXmlToJson (4:23)
frontend/src/hooks/multi-agent/toolNodes.ts (1) (1)
  • findToolNode (110:112)
🔇 Additional comments (41)
backend/src/chat/chat.controller.ts (3)

35-35: Addition of explicit role parameter for streamChat.

The role: MessageRole.User parameter has been added to the streamChat method call. This change aligns with the removal of direct message saving in the controller, suggesting that role information is now passed to the proxy service to handle message persistence elsewhere in the system.


56-56: Addition of explicit role parameter for chatSync.

Similar to the streaming endpoint, the role: MessageRole.User parameter has been added to the chatSync method call. This maintains consistency between the streaming and non-streaming implementations, ensuring both methods properly identify the message originator.


18-66: Improved separation of concerns in chat handling.

The removal of direct message saving from the controller (as indicated in the summary) is a positive architectural change. By delegating message persistence to the service layer and only passing the necessary role information, the controller now has a cleaner, more focused responsibility of handling HTTP requests and responses.

frontend/src/components/chat/code-engine/code-engine.tsx (2)

23-24: You've correctly integrated the editor reference from the project context.

Nice work on accessing editorRef from the ProjectContext instead of managing it locally. This centralization improves component interaction and state management.


199-200: Simplified API request body by removing unnecessary JSON.stringify()

The change from JSON.stringify(value) to just value indicates the API now expects the raw content directly. This simplifies the code and reduces unnecessary serialization.

frontend/src/components/chat/code-engine/project-context.tsx (5)

52-53: Good addition of the editor reference to the ProjectContextType interface.

This addition makes the type definition complete and properly documents the new capability of the context.


107-108: Correctly initialized the editor reference.

Properly initializing editorRef with useRef<any>(null) ensures it's ready to be used throughout the component lifecycle.


330-331: Enhanced state update to ensure immutability.

The change from setProjects(data.getUserProjects) to setProjects([...data.getUserProjects]) creates a new array reference, which is a React best practice for reliable re-rendering.


916-917: Properly included editorRef in the context value.

The editor reference is now correctly exposed through the context.


932-933: Correctly updated the useMemo dependencies.

Good job adding editorRef to the useMemo dependencies array to ensure the context value is recalculated when the reference changes.

frontend/src/api/ChatStreamAPI.ts (3)

3-11: Well-structured function signature with proper parameter validation.

The function is well-defined with appropriate parameters and includes error handling for authentication.


26-30: Good error handling for network responses.

The function properly checks for response success and throws informative errors.


69-71: Simple non-streaming response handling.

The non-streaming response is correctly handled to extract and return just the content.

frontend/src/hooks/useChatStream.ts (6)

1-11: Updated imports to support new functionality.

The imports reflect the architectural changes, particularly the integration with the managerAgent and project context.


13-19: Improved interface visibility by exporting UseChatStreamProps.

Making the interface exported allows it to be reused across the application, improving code modularity.


31-39: Added project context integration with state management.

The component now properly integrates with the project context and maintains local state for the project path.


63-64: Added message persistence through saveMessage mutation.

Good addition of the saveMessage mutation for persisting messages.


82-93: Improved message handling with proper typing and persistence.

The message handling now creates a properly typed input object and saves it before processing, which is a good approach for ensuring data consistency.


93-102: Refactored to use the manager agent pattern.

The refactoring to use managerAgent instead of direct API calls centralizes the chat response handling logic, which is a good architectural decision.

frontend/src/hooks/multi-agent/toolNodes.ts (6)

12-18: Good use of a dedicated interface for tool usage details.
The ToolUsage interface neatly documents purpose, input, output, and usage conditions. This approach improves clarity and makes the tools more self-explanatory.


20-26: Interface extension is clear and consistent.
Adding usage to the Tool interface aligns it with the new usage data, ensuring each tool provides structured instructions.


28-108: Comprehensive definitions for each tool.
The managerTools array organizes tool data effectively, with each tool specifying a clear usage path. The standardized structure helps maintain a cohesive workflow.


110-112: Minimalistic and helpful utility function.
findToolNode is straightforward and effective for tool retrieval. Error handling is deferred to callers if the tool isn't found, which is acceptable.


114-121: Usage map retrieval is efficiently implemented.
Generating the usage map with a simple loop is concise and maintainable.


123-130: Description map retrieval is efficiently handled.
Similar to the usage map, this is well-structured and keeps code maintainable.

frontend/src/hooks/multi-agent/managerAgent.ts (7)

17-19: Path normalization logic looks correct.
Replacing backslashes with forward slashes helps ensure consistency across platforms.


24-32: Robust file validation.
Throwing an error when a path includes .. is a good security practice to prevent directory traversal.


41-75: Context initialization is straightforward.
Having a default task_type set to DEBUG and letting the AI update it later is a clear approach. No issues found.


76-92: Fetching file structure with proper error handling.
The try/catch block ensures robust handling of any network or data parsing issues.


93-174: Main loop logic is well-structured.
You correctly limit iterations and time, parse the AI’s response, and handle completion or tool execution. The step-based approach is logical.


176-202: File update mechanism is well handled.
The code updates each modified file via POST requests, then refreshes the project state. Error handling in the loop is properly encapsulated.


204-223: Final data saving is cleanly implemented.
Accumulated thoughts are merged into a single message. This approach helps record AI reasoning without cluttering logs.

frontend/src/hooks/multi-agent/tools.ts (7)

3-86: Smooth approach for saving thinking process with a typewriter effect.
The function captures AI explanations and then visually outputs them. Be mindful of performance on very large text, but for typical usage, this is a neat UX feature.


102-121: Prompt selection by task type is straightforward.
The switch statement is clear and easily extensible if new task types arise.


122-178: Task analysis flow is logical.
The taskTool properly selects the AI prompt, validates the response, and updates the required files. Error handling is comprehensive.


180-221: File reading logic is well-defined.
It fetches file content for each required file, handles errors cleanly, and logs outcomes.


328-352: Applying changes is simple and effective.
The updated content is verified, then synced back to fileContents.


354-404: Clear code review process.
Collecting each modified file and prompting the AI with a consolidated review context ensures thorough checks.


406-445: Commit message generation is well integrated.
It draws from the final changes, ensures format correctness, and stores the message in the context.

frontend/src/hooks/multi-agent/agentPrompt.ts (2)

351-390: Proper function invocation is correctly used here.
This section demonstrates the correct call to systemPrompt() rather than relying on implicit string conversion. Nicely done.


396-465: confirmationPrompt usage looks well-structured.
Here you consistently call systemPrompt() as intended, and the step-by-step logic is clear and methodical. No concerns at this time.

Comment on lines +12 to +24
const response = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
chatId,
message,
model,
stream,
}),
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Missing role parameter in API request.

The function doesn't include the role field from ChatInputType in the request body, although it's part of the type definition.

  body: JSON.stringify({
    chatId,
    message,
    model,
+   role: input.role,
    stream,
  }),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const response = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
chatId,
message,
model,
stream,
}),
});
const response = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
chatId,
message,
model,
role: input.role,
stream,
}),
});

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (8)
frontend/src/hooks/multi-agent/agentPrompt.ts (8)

7-35: Consider using more specific types instead of 'any'.

The AgentContext interface uses any for both saveMessage and editorRef, which reduces type safety. Consider using more specific types to improve code maintainability and prevent potential type-related bugs.

- editorRef: React.MutableRefObject<any>; // Monaco editor reference for direct updates
+ editorRef: React.MutableRefObject<monaco.editor.IStandaloneCodeEditor>; // Monaco editor reference for direct updates
- saveMessage: any;
+ saveMessage: (message: Message) => void; // Or whatever the actual type should be

134-171: Add explicit return type to refactorPrompt function.

For consistency with other functions and improved type safety, add an explicit return type.

- export const refactorPrompt = (message: string, file_structure: string[]) => {
+ export const refactorPrompt = (message: string, file_structure: string[]): string => {

172-209: Add explicit return type to optimizePrompt function.

For consistency with other functions and improved type safety, add an explicit return type.

- export const optimizePrompt = (message: string, file_structure: string[]) => {
+ export const optimizePrompt = (message: string, file_structure: string[]): string => {

210-276: Add explicit return type to editFilePrompt function.

For consistency with other functions and improved type safety, add an explicit return type.

- export const editFilePrompt = (
-   description: string,
-   file_content: { [key: string]: string }
- ) => {
+ export const editFilePrompt = (
+   description: string,
+   file_content: { [key: string]: string }
+ ): string => {

277-316: Add explicit return type to codeReviewPrompt function.

For consistency with other functions and improved type safety, add an explicit return type.

- export const codeReviewPrompt = (message: string) => {
+ export const codeReviewPrompt = (message: string): string => {

317-351: Add explicit return type to commitChangesPrompt function.

For consistency with other functions and improved type safety, add an explicit return type.

- export const commitChangesPrompt = (message: string) => {
+ export const commitChangesPrompt = (message: string): string => {

397-398: Move import statements to the top of the file.

Import statements are typically placed at the top of the file. This improves readability and follows standard conventions.

+ import { Message } from '@/const/MessageType';
+ import { getToolUsageMap } from './toolNodes';
+
export enum TaskType {
  DEBUG = 'debug',
  REFACTOR = 'refactor',
  OPTIMIZE = 'optimize',
  UNRELATED = 'unrelated',
}
// Rest of the code...

- import { Message } from '@/const/MessageType';
- import { getToolUsageMap } from './toolNodes';

471-500: Add explicit return type to findbugPrompt function.

For consistency with other functions and improved type safety, add an explicit return type.

- export const findbugPrompt = (message: string, file_structure: string[]) => {
+ export const findbugPrompt = (message: string, file_structure: string[]): string => {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 90df595 and e4f66ec.

📒 Files selected for processing (1)
  • frontend/src/hooks/multi-agent/agentPrompt.ts (1 hunks)
🔇 Additional comments (3)
frontend/src/hooks/multi-agent/agentPrompt.ts (3)

1-6: LGTM! TaskType enum now includes UNRELATED.

The TaskType enum correctly includes all the necessary values, including UNRELATED which was previously missing according to past review comments.


36-95: LGTM! System prompt function correctly implemented.

The systemPrompt function implementation looks correct and follows a good practice of returning a string with all necessary instructions.


97-133: LGTM! leaderPrompt correctly uses systemPrompt as a function.

The leaderPrompt implementation correctly calls systemPrompt() with parentheses, addressing the issue mentioned in past review comments.

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