Skip to content

Staging#200

Merged
galshubeli merged 16 commits intomainfrom
staging
Sep 3, 2025
Merged

Staging#200
galshubeli merged 16 commits intomainfrom
staging

Conversation

@galshubeli
Copy link
Copy Markdown
Collaborator

@galshubeli galshubeli commented Sep 3, 2025

Summary by CodeRabbit

  • New Features

    • Message box is now a multi-line textarea with auto-resize. Enter sends; Shift+Enter adds a newline.
  • UI/UX

    • Submit starts disabled until text is entered and a database is selected; controls re-enable on selection.
    • Updated header title and capitalized “Select Database.”
    • Graph refresh button starts disabled.
    • Improved button theming and disabled states; icons use currentColor.
    • File upload control uses a cleaner flex layout.
    • Chat avatar label for bot/follow-ups shows “QW.”
  • Behavior Changes

    • Sending is blocked without a selected database; no alert is shown.

@galshubeli galshubeli requested a review from Copilot September 3, 2025 11:19
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Sep 3, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Caution

Review failed

The pull request is closed.


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cb84e57 and b1692da.

📒 Files selected for processing (1)
  • app/ts/app.ts (4 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch staging

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit 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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Sep 3, 2025

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements comprehensive UI improvements and bug fixes for QueryWeaver, transforming the input field from a basic text input to an auto-resizing textarea with enhanced user experience. The changes focus on improving input handling, visual feedback, and consistency across the interface.

Key changes include:

  • Implementation of auto-resizing textarea functionality to replace the basic text input
  • Enhanced UI state management with proper button enabling/disabling logic
  • Visual consistency improvements including color scheme updates and layout adjustments

Reviewed Changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
app/ts/modules/input.ts New module implementing textarea auto-resize functionality with height adjustment logic
app/ts/modules/chat.ts Updated message sending logic with textarea support and improved UI state handling
app/ts/app.ts Enhanced event listeners for textarea input with shift+enter support and dynamic submit button state
app/templates/components/chat_input.j2 Converted input element to textarea with auto-resize capabilities
app/public/css/*.css Style updates for button states, color consistency, and layout improvements
app/ts/modules/config.ts Updated DOM element type from HTMLInputElement to HTMLTextAreaElement
api/memory/graphiti_tool.py Backend improvements to memory tool initialization and entity node creation

Comment thread app/ts/modules/input.ts
Comment thread app/ts/modules/chat.ts
Comment thread app/templates/components/chat_input.j2
Comment thread api/memory/graphiti_tool.py
Comment thread app/ts/app.ts Outdated
@galshubeli galshubeli merged commit 7e67cd5 into main Sep 3, 2025
18 checks passed
Copy link
Copy Markdown
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/ts/modules/chat.ts (1)

263-264: Bug: addMessage arg order wrong (userInfo passed as isQuery).

Third arg is isQuery (boolean). You're passing the user object there, which coerces to true and drops avatar/name.

-    addMessage(`User choice: ${confirmation}`, "user", (window as any).currentUser || null);
+    addMessage(`User choice: ${confirmation}`, "user", false, (window as any).currentUser || null);
api/memory/graphiti_tool.py (1)

329-366: Fix Cypher injection risk; parameterize values and embed the original text, not the escaped one

Manual string interpolation and DIY escaping are brittle. Use parameters for user_query/sql/error and keep the dynamic relationship type as derived from a boolean.

-            # Escape quotes in the query and SQL for Cypher
-            escaped_query = query.replace("'", "\\'").replace('"', '\\"')
-            escaped_sql = sql_query.replace("'", "\\'").replace('"', '\\"')
-            escaped_error = error.replace("'", "\\'").replace('"', '\\"') if error else ""
-            embeddings = Config.EMBEDDING_MODEL.embed(escaped_query)[0]
+            # Embed the original user query (escaping not needed for embeddings)
+            embeddings = Config.EMBEDDING_MODEL.embed(query)[0]
@@
-            check_query = f"""
-            MATCH (db:Entity {{uuid: "{database_node_uuid}"}})
-            MATCH (db)-[r]->(q:Query)
-            WHERE q.user_query = "{escaped_query}" AND q.sql_query = "{escaped_sql}"
-            RETURN q.uuid as existing_query_uuid
-            LIMIT 1
-            """
+            check_query = """
+            MATCH (db:Entity {uuid: $db_uuid})
+            MATCH (db)-[r]->(q:Query)
+            WHERE q.user_query = $user_query AND q.sql_query = $sql_query
+            RETURN q.uuid as existing_query_uuid
+            LIMIT 1
+            """
@@
-            check_result = await graph_driver.execute_query(check_query)
+            check_result, _, _ = await graph_driver.execute_query(
+                check_query,
+                db_uuid=database_node_uuid,
+                user_query=query,
+                sql_query=sql_query,
+            )
@@
-            cypher_query = f"""
-            MATCH (db:Entity {{uuid: "{database_node_uuid}"}})
-            MERGE (q:Query {{
-                user_query: "{escaped_query}",
-                sql_query: "{escaped_sql}",
-                success: {str(success).lower()},
-                error: "{escaped_error}",
-                timestamp: timestamp(),
-                embeddings: vecf32($embedding)
-            }})
-            CREATE (db)-[:{relationship_type} {{timestamp: timestamp()}}]->(q)
-            RETURN q.uuid as query_uuid
-            """
+            cypher_query = f"""
+            MATCH (db:Entity {{uuid: $db_uuid}})
+            CREATE (q:Query {{
+                uuid: randomUUID(),
+                user_query: $user_query,
+                sql_query: $sql_query,
+                success: $success,
+                error: $error,
+                timestamp: timestamp(),
+                embeddings: vecf32($embedding)
+            }})
+            CREATE (db)-[:{relationship_type} {{timestamp: timestamp()}}]->(q)
+            RETURN q.uuid as query_uuid
+            """
@@
-                result = await graph_driver.execute_query(cypher_query, embedding=embeddings)
+                await graph_driver.execute_query(
+                    cypher_query,
+                    db_uuid=database_node_uuid,
+                    user_query=query,
+                    sql_query=sql_query,
+                    success=success,
+                    error=error or "",
+                    embedding=embeddings,
+                )
                 return True
♻️ Duplicate comments (6)
app/templates/components/chat_input.j2 (1)

4-4: Remove invalid type attribute on textarea.

Textarea doesn’t support type=. This was flagged previously.

-        <textarea type="text" id="message-input" placeholder="Describe the SQL query you want..." rows="1"></textarea>
+        <textarea id="message-input" placeholder="Describe the SQL query you want..." rows="1"></textarea>
app/ts/app.ts (1)

228-229: Add missing semicolon (style consistency).

Previously noted; keep consistency with the codebase.

-  setupTextareaAutoResize()
+  setupTextareaAutoResize();
app/ts/modules/chat.ts (1)

23-27: Correct param order for addMessage (resolves earlier review).

Passing isQuery=false, userInfo as 4th arg is correct and addresses the prior comment.

app/ts/modules/input.ts (1)

15-26: NaN/Infinity bug: parseInt(maxHeight) breaks when max-height is 'none' or non-px.

This yields NaN and sets height to 'NaNpx'.

-  const maxHeight = parseInt(getComputedStyle(textarea).maxHeight);
+  const computedMaxHeight = getComputedStyle(textarea).maxHeight;
+  let maxHeight: number;
+  if (computedMaxHeight === "none") {
+    maxHeight = Infinity;
+  } else if (computedMaxHeight.endsWith("px")) {
+    maxHeight = parseFloat(computedMaxHeight);
+  } else {
+    const parsed = parseFloat(computedMaxHeight);
+    maxHeight = Number.isFinite(parsed) ? parsed : Infinity;
+  }
api/memory/graphiti_tool.py (2)

171-178: Avoid magic string for group_id

The hardcoded '\_' is a magic string; define a module-level constant and reuse.

+# Default group id for memory entities
+GROUP_ID_DEFAULT = "_"
@@
-                    'group_id': '\\_',
+                    'group_id': GROUP_ID_DEFAULT,

206-215: Repeat of magic string for group_id

Apply the same constant here for consistency.

-                    'group_id': '\\_',
+                    'group_id': GROUP_ID_DEFAULT,
🧹 Nitpick comments (17)
app/templates/components/database_modal.j2 (2)

9-15: Copy change looks fine; consider i18n key or helper to avoid hardcoded strings.

If you’re standardizing “Select Database” across the app, consider centralizing this label (i18n/const) so future tweaks don’t drift between templates.


28-28: Grammar tweak: add article “a”.

“Select Database type first...” reads a bit off. Suggest “Select a database type first...”.

Apply this template diff:

-<input type="text" id="db-url-input" class="db-modal-input" placeholder="Select Database type first..." disabled />
+<input type="text" id="db-url-input" class="db-modal-input" placeholder="Select a database type first..." disabled />
app/templates/components/chat_header.j2 (1)

25-26: Mark decorative arrow as hidden from screen readers.

The “▼” is purely decorative for a file label; hide it from AT.

-            <span class="dropdown-arrow">▼</span>
+            <span class="dropdown-arrow" aria-hidden="true">▼</span>
app/ts/modules/graph_select.ts (1)

46-49: Enable controls independently to be more resilient.

If one element is missing, the other should still be enabled.

-        if (DOM.graphSelectRefresh && DOM.submitButton) {
-            DOM.graphSelectRefresh.disabled = false
-            DOM.submitButton.disabled = false
-        };
+        if (DOM.graphSelectRefresh) {
+            DOM.graphSelectRefresh.disabled = false;
+        }
+        if (DOM.submitButton) {
+            DOM.submitButton.disabled = false;
+        }
app/public/css/chat-components.css (1)

86-102: Avoid conflicting avatar labels: remove user selector from the 'QW' rule.

Including .user-message-container::after here sets content:'QW' before being overridden below; it's redundant and can cause confusion. Limit this rule to bot/followup/final only.

-.user-message-container::after,
 .bot-message-container::before,
 .followup-message-container::before,
 .final-result-message-container::before {
   height: 32px;
   width: 32px;
-  content: 'QW';
+  content: 'QW';
   color: var(--text-secondary);
   display: flex;
app/templates/components/chat_input.j2 (1)

5-5: Add aria-labels for better accessibility.

Title helps on hover but screen readers benefit from aria-label on buttons.

-        <button class="input-button" title="Submit" id="submit-button" disabled>
+        <button class="input-button" title="Submit" aria-label="Submit message" id="submit-button" disabled>
...
-        <button class="input-button" title="Pause" id="pause-button">
+        <button class="input-button" title="Pause" aria-label="Pause response" id="pause-button">

Also applies to: 15-15

app/ts/app.ts (1)

65-70: Guard against IME composition when sending on Enter.

Prevent accidental sends for CJK input; also no need to cast e.

-  DOM.messageInput?.addEventListener("keydown", (e: KeyboardEvent) => {
-    if ((e as KeyboardEvent).key === "Enter" && !e.shiftKey) {
+  DOM.messageInput?.addEventListener("keydown", (e: KeyboardEvent) => {
+    if (e.isComposing) return;
+    if (e.key === "Enter" && !e.shiftKey) {
       e.preventDefault();
       sendMessage();
     }
   });
app/ts/modules/chat.ts (1)

17-17: Silent UX on no graph selection — consider user feedback.

Returning after console.debug gives no UI hint. Suggest prompting the user.

-    if (!selectedValue || selectedValue === "Select Database") return console.debug("No selected graph");
+    if (!selectedValue || selectedValue === "Select Database") {
+        addMessage('Please select a database before sending a message.', "followup");
+        return;
+    }
app/ts/modules/input.ts (1)

34-45: Auto-resize wiring looks good.

Input and paste handlers with initial adjust are correct. Optional: also handle "cut".

   // Adjust height on input
   textarea.addEventListener("input", adjustTextareaHeight);
+  textarea.addEventListener("cut", () => setTimeout(adjustTextareaHeight, 0));
api/memory/graphiti_tool.py (8)

30-44: Helper to strip provider prefix looks good

Handles simple "provider/model" shapes correctly. Consider trimming whitespace to be extra-safe.

 def extract_embedding_model_name(full_model_name: str) -> str:
@@
-    if "/" in full_model_name:
+    full_model_name = full_model_name.strip()
+    if "/" in full_model_name:
         return full_model_name.split("/", 1)[1]  # Remove provider prefix
     else:
         return full_model_name

63-69: Honor the use_direct_entities flag (currently unused) and keep the legacy path

You always call the direct path, ignoring the flag. Wire both paths, or drop the flag.

 @classmethod
-async def create(cls, user_id: str, graph_id: str, use_direct_entities: bool = True) -> "MemoryTool":
+async def create(cls, user_id: str, graph_id: str, use_direct_entities: bool = True) -> "MemoryTool":
     """Async factory to construct and initialize the tool."""
     self = cls(user_id, graph_id)
-
-    await self._ensure_entity_nodes_direct(user_id, graph_id)
+    if use_direct_entities:
+        await self._ensure_entity_nodes_direct(user_id, graph_id)
+    else:
+        # Legacy Graphiti-based ensure (kept for compatibility)
+        await self._ensure_user_node(user_id)
+        await self._ensure_database_node(graph_id, user_id)
 
     vector_size = Config.EMBEDDING_MODEL.get_vector_size()
     driver = self.graphiti_client.driver
-    await driver.execute_query(f"CREATE VECTOR INDEX FOR (p:Query) ON (p.embeddings) OPTIONS {{dimension:{vector_size}, similarityFunction:'euclidean'}}")
+    # Create vector index idempotently
+    try:
+        await driver.execute_query(
+            f"CREATE VECTOR INDEX FOR (p:Query) ON (p.embeddings) "
+            f"OPTIONS {{dimension:{vector_size}, similarityFunction:'euclidean'}}"
+        )
+    except Exception as e:
+        # Best-effort: ignore 'already exists' errors; re-raise others
+        if "already exists" not in str(e).lower():
+            raise

Run make lint to confirm ARG003 (unused arg) is resolved and no new lint issues are introduced.


150-201: Direct node lookup/create: prefer non-blocking embeddings within async and consistent result handling

  • Config.EMBEDDING_MODEL.embed likely does network I/O; calling it sync inside asyncio can block. Consider an async embedder or run_in_executor.
  • execute_query return handling mixes tuple indexing and destructuring across the file; standardize to destructuring for clarity.
-            user_name_embedding = Config.EMBEDDING_MODEL.embed(user_node_name)[0]
+            # Offload sync embedding call to avoid blocking the event loop
+            loop = asyncio.get_running_loop()
+            user_name_embedding = await loop.run_in_executor(
+                None, lambda: Config.EMBEDDING_MODEL.embed(user_node_name)[0]
+            )
@@
-            user_check_result = await graph_driver.execute_query(check_user_query, name=user_node_name)
-            
-            if not user_check_result[0]:  # If no records found, create user node
+            user_records, _, _ = await graph_driver.execute_query(check_user_query, name=user_node_name)
+            if not user_records:  # If no records found, create user node
                 user_uuid = str(uuid.uuid4())

232-252: Narrow exceptions and use try/else for relationship creation

Catching bare Exception and returning inside try triggers TRY300; restructure and narrow where possible.

-            try:
+            try:
                 relationship_query = """
@@
-                await graph_driver.execute_query(
+                await graph_driver.execute_query(
                     relationship_query, 
                     user_name=user_node_name,
                     database_name=database_node_name
                 )
-                print(f"Created HAS_DATABASE relationship between {user_node_name} and {database_node_name}")
-                
-            except Exception as rel_error:
+            except Exception as rel_error:
                 print(f"Error creating HAS_DATABASE relationship: {rel_error}")
-                # Don't fail the entire function if relationship creation fails
-            
-            return True
+                # Don't fail the entire function if relationship creation fails
+            else:
+                print(f"Created HAS_DATABASE relationship between {user_node_name} and {database_node_name}")
+            return True

308-325: Clarify result structure and avoid brittle double indexing

database_result[0][0]['uuid'] assumes a specific tuple-of-list-of-dict shape. Destructure for readability and to guard against API changes.

-            database_result = await graph_driver.execute_query(find_database_query, name=database_node_name)
-            
-            # Check if database node exists
-            if not database_result[0]:  # If no records found
+            db_records, _, _ = await graph_driver.execute_query(find_database_query, name=database_node_name)
+            # Check if database node exists
+            if not db_records:  # If no records found
                 print(f"Database entity node {database_node_name} not found")
                 return False
-            
-            database_node_uuid = database_result[0][0]['uuid']
+            database_node_uuid = db_records[0]['uuid']

If the driver actually returns a different record shape, adjust the key access accordingly and add a small helper to normalize it.


783-787: Avoid hard-coding embedding_dim; derive from Config to prevent mismatches

Tie the embedder dimension to the configured model to avoid silent shape errors if the model changes.

-                config=OpenAIEmbedderConfig(
-                    embedding_model=config.embedding_deployment,
-                    embedding_dim=1536
-                ),
+                config=OpenAIEmbedderConfig(
+                    embedding_model=config.embedding_deployment,
+                    embedding_dim=Config.EMBEDDING_MODEL.get_vector_size(),
+                ),

796-808: Apply the same dynamic dimension in the OpenAI fallback

Keep both branches consistent.

-        # Extract just the model name without provider prefix for Graphiti
-        embedding_model_name = extract_embedding_model_name(Config.EMBEDDING_MODEL_NAME)
+        # Extract just the model name without provider prefix for Graphiti
+        embedding_model_name = extract_embedding_model_name(Config.EMBEDDING_MODEL_NAME)
@@
-                config=OpenAIEmbedderConfig(
-                    embedding_model=embedding_model_name,
-                    embedding_dim=1536
-                )
+                config=OpenAIEmbedderConfig(
+                    embedding_model=embedding_model_name,
+                    embedding_dim=Config.EMBEDDING_MODEL.get_vector_size(),
+                )
             ),

5-5: Do not disable all pylint checks for this file

Repository guideline says all Python should pass pylint. Replace the global disable with targeted disables (e.g., for specific false positives) and fix violations where feasible.

Run make lint and selectively annotate only necessary disables (e.g., invalid-name, too-many-branches) rather than disable=all.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f6e7088 and cb84e57.

⛔ Files ignored due to path filters (1)
  • app/public/icons/pause.svg is excluded by !**/*.svg
📒 Files selected for processing (14)
  • api/memory/graphiti_tool.py (9 hunks)
  • app/public/css/buttons.css (3 hunks)
  • app/public/css/chat-components.css (2 hunks)
  • app/public/css/menu.css (1 hunks)
  • app/templates/components/chat_header.j2 (2 hunks)
  • app/templates/components/chat_input.j2 (1 hunks)
  • app/templates/components/database_modal.j2 (2 hunks)
  • app/ts/app.ts (4 hunks)
  • app/ts/modules/chat.ts (2 hunks)
  • app/ts/modules/config.ts (1 hunks)
  • app/ts/modules/graph_select.ts (1 hunks)
  • app/ts/modules/graphs.ts (0 hunks)
  • app/ts/modules/input.ts (1 hunks)
  • app/ts/modules/messages.ts (2 hunks)
💤 Files with no reviewable changes (1)
  • app/ts/modules/graphs.ts
🧰 Additional context used
📓 Path-based instructions (2)
app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Frontend source changes in app/**/*.{ts,tsx} must be compiled before production runs

Files:

  • app/ts/modules/messages.ts
  • app/ts/modules/input.ts
  • app/ts/modules/graph_select.ts
  • app/ts/modules/config.ts
  • app/ts/app.ts
  • app/ts/modules/chat.ts
**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

All Python code should pass pylint (use make lint)

Files:

  • api/memory/graphiti_tool.py
🧬 Code graph analysis (6)
app/ts/modules/messages.ts (2)
app/ts/modules/config.ts (1)
  • DOM (39-65)
app/ts/modules/input.ts (1)
  • adjustTextareaHeight (7-27)
app/ts/modules/input.ts (1)
app/ts/modules/config.ts (1)
  • DOM (39-65)
app/ts/modules/graph_select.ts (1)
app/ts/modules/config.ts (1)
  • DOM (39-65)
app/ts/app.ts (4)
app/ts/modules/config.ts (1)
  • DOM (39-65)
app/ts/modules/chat.ts (1)
  • sendMessage (10-72)
app/ts/modules/graph_select.ts (1)
  • getSelectedGraph (7-12)
app/ts/modules/input.ts (1)
  • setupTextareaAutoResize (29-45)
api/memory/graphiti_tool.py (1)
api/config.py (2)
  • Config (49-135)
  • embed (20-33)
app/ts/modules/chat.ts (4)
app/ts/modules/config.ts (2)
  • DOM (39-65)
  • state (73-77)
app/ts/modules/graph_select.ts (1)
  • getSelectedGraph (7-12)
app/ts/modules/messages.ts (1)
  • addMessage (9-119)
app/ts/modules/input.ts (1)
  • adjustTextareaHeight (7-27)
🪛 ast-grep (0.38.6)
app/ts/modules/messages.ts

[warning] 183-183: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: DOM.chatMessages.innerHTML = ""
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html

(dom-content-modification)

🪛 Ruff (0.12.2)
api/memory/graphiti_tool.py

63-63: Unused class method argument: use_direct_entities

(ARG003)


248-248: Do not catch blind exception: Exception

(BLE001)


252-252: Consider moving this statement to an else block

(TRY300)


254-254: Do not catch blind exception: Exception

(BLE001)

🔇 Additional comments (16)
app/templates/components/chat_header.j2 (2)

4-4: Copy alignment LGTM.

Title and “Select Database” capitalization align with the modal.

Also applies to: 14-15


6-6: No other disable flows found; refresh button is enabled on graph selection and never re-disabled.

app/public/css/menu.css (1)

206-209: Flex rewrite for #custom-file-upload looks good.

This cleanly replaces the background arrow; matches other flex-based headers.

app/ts/modules/config.ts (1)

40-40: No lingering HTMLInputElement usage for messageInput
Search returned no HTMLInputElement references for 'message-input'; messageInput is correctly typed as HTMLTextAreaElement.

app/public/css/chat-components.css (1)

231-234: Pause icon theming LGTM.

Explicit color ties the SVG fill to theme variables and matches the currentColor usage.

app/public/css/buttons.css (2)

3-7: Readable label color on primary button: good change.

Ensures the icon/text inherit the intended theme color on primary background.


19-22: Consistent disabled states: good additions.

Opacity and not-allowed cursor bring parity across inputs and actions.

Also applies to: 55-58

app/templates/components/chat_input.j2 (1)

5-13: SVG theming via currentColor: looks good.

Matches CSS variables and ensures consistent theming.

Also applies to: 16-22

app/ts/modules/messages.ts (2)

7-7: Import is correct and scoped minimally.


180-183: Resetting textarea and height on init: good UX polish.

app/ts/app.ts (2)

72-82: Submit enable/disable logic tied to content and selection: 👍

Aligns with new disabled styles and reduces accidental submits.


103-105: Replacing alert with console.debug: sensible UX choice.

app/ts/modules/chat.ts (3)

32-32: Verify CSS expects flex for pause button.

Ensure the button’s CSS layout is compatible with display:flex; otherwise use the prior display value.


198-198: Verify CSS expects flex for submit button.

Confirm this matches styles; if not, revert to the layout’s expected display (e.g., block/inline-flex).


8-8: Run TypeScript build and typecheck. Ensure the updated addMessage signature is applied consistently across all calls; your build will catch any mismatches.

api/memory/graphiti_tool.py (1)

726-729: Using extracted model name for Azure embedder is consistent with Graphiti expectations

Good normalization step.

@coderabbitai coderabbitai bot mentioned this pull request Sep 10, 2025
@coderabbitai coderabbitai bot mentioned this pull request Oct 8, 2025
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.

3 participants