Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
367ce8e
feat: integrate @falkordb/canvas for schema visualization and remove …
Anchel123 Dec 30, 2025
9bf6497
Implement feature X to enhance user experience and optimize performance
Anchel123 Dec 30, 2025
ddfe7bc
chore: update @falkordb/canvas dependency to version 0.0.21
Anchel123 Jan 4, 2026
71bb1cd
Implement new feature for user authentication and improve error handling
Anchel123 Jan 4, 2026
6489f85
chore: update @falkordb/canvas dependency from 0.0.12 to 0.0.21 in pa…
Anchel123 Jan 5, 2026
1dbbc58
chore: update @falkordb/canvas dependency from 0.0.21 to 0.0.22 in pa…
Anchel123 Jan 7, 2026
67d82b9
chore: update @falkordb/canvas dependency from 0.0.21 to 0.0.22 in pa…
Anchel123 Jan 7, 2026
e1b8588
Merge remote-tracking branch 'origin/staging' into falkordb-canvas
Anchel123 Jan 7, 2026
755a2f4
refactor: update theme handling and improve styling in SchemaViewer c…
Anchel123 Jan 7, 2026
3f5e4d7
chore: update @falkordb/canvas dependency to version 0.0.23 in packag…
Anchel123 Jan 8, 2026
4c00d49
Bump urllib3 from 2.6.2 to 2.6.3 in the pip group across 1 directory
dependabot[bot] Jan 8, 2026
dddfbb5
Add weekly updates for GitHub Actions dependencies
gkorland Jan 8, 2026
31ba4ef
Merge branch 'staging' into dependabot/pip/pip-8177a8837a
gkorland Jan 8, 2026
bfef44f
Merge pull request #371 from FalkorDB/dependabot/pip/pip-8177a8837a
gkorland Jan 8, 2026
8af91e5
chore: update @falkordb/canvas dependency to version 0.0.24 in packag…
Anchel123 Jan 12, 2026
cddd3eb
chore: add preact dependency and update version to 10.28.2 in package…
Anchel123 Jan 18, 2026
444e271
Implement feature X to enhance user experience and fix bug Y in module Z
Anchel123 Jan 18, 2026
ce084c2
chore: update preact dependency to version 10.28.2 in package.json an…
Anchel123 Jan 18, 2026
870a0c2
Refactor code structure for improved readability and maintainability
Anchel123 Jan 18, 2026
784c386
Initial plan
Copilot Jan 24, 2026
989bac7
Add HSTS header to prevent man-in-the-middle attacks
Copilot Jan 24, 2026
93df5c9
Fix test endpoint path from /api/graphs to /graphs
Copilot Jan 24, 2026
c2b3551
Merge branch 'staging' into copilot/add-hsts-header
gkorland Jan 24, 2026
48eba40
Merge pull request #382 from FalkorDB/copilot/add-hsts-header
gkorland Jan 24, 2026
904f859
Bump jsonschema from 4.25.1 to 4.26.0
dependabot[bot] Jan 26, 2026
d7d4d2a
Refactor code structure for improved readability and maintainability
Anchel123 Feb 1, 2026
dc8e04b
Refactor code structure for improved readability and maintainability
Anchel123 Feb 1, 2026
f060d88
Refactor code structure for improved readability and maintainability
Anchel123 Feb 2, 2026
b6d2b67
Merge branch 'staging' into falkordb-canvas
Naseem77 Feb 3, 2026
927675c
Merge pull request #351 from FalkorDB/falkordb-canvas
Naseem77 Feb 3, 2026
364bbc1
Merge branch 'staging' into dependabot/pip/staging/jsonschema-4.26.0
gkorland Feb 3, 2026
befe74e
Merge pull request #377 from FalkorDB/dependabot/pip/staging/jsonsche…
gkorland Feb 3, 2026
351082b
add-ttl-memory
galshubeli Feb 12, 2026
40bf368
env-var
galshubeli Feb 12, 2026
0103263
redis-error
galshubeli Feb 12, 2026
3dd4d13
spell
galshubeli Feb 12, 2026
9859c08
update-docker
galshubeli Feb 12, 2026
d767956
update-docker
galshubeli Feb 12, 2026
90c6a5c
bust docker cache for nodejs install
galshubeli Feb 12, 2026
de08a9a
fix: remove pre-installed nodejs before installing NodeSource version
galshubeli Feb 12, 2026
b884bb9
Merge pull request #389 from FalkorDB/memory-ttl
galshubeli Feb 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ FALKORDB_URL=redis://localhost:6379/0 # REQUIRED - change to your FalkorDB URL
# Google Tag Manager ID (optional)
# GOOGLE_TAG_MANAGER_ID=GTM-XXXXXXX

# -----------------------------
# Memory TTL (optional)
# -----------------------------
# Set a TTL (in seconds) on per-user memory graphs so they auto-expire.
# When unset, memory graphs persist indefinitely.
# Example: 604800 = 1 week
# MEMORY_TTL_SECONDS=604800

# -----------------------------
# Optional MCP (Model Context Protocol) settings
# -----------------------------
Expand Down
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

version: 2
updates:
- package-ecosystem: "github-actions"
Comment thread
galshubeli marked this conversation as resolved.
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "pip"
directory: "/"
target-branch: "staging"
Expand Down
1 change: 1 addition & 0 deletions .github/wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,4 @@ Sanitization
JOINs
subqueries
subquery
TTL
15 changes: 12 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
netcat-openbsd \
git \
build-essential \
curl \
ca-certificates \
gnupg \
&& rm -rf /var/lib/apt/lists/* \
&& ln -sf /usr/local/bin/python3.12 /usr/bin/python3 \
&& ln -sf /usr/local/bin/python3.12 /usr/bin/python
Expand All @@ -36,9 +39,15 @@ RUN PIP_BREAK_SYSTEM_PACKAGES=1 pipenv sync --system

# Install Node.js (Node 22) so we can build the frontend inside the image.
# Use NodeSource setup script to get a recent Node version on Debian-based images.
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get update && apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/*
# Remove any pre-installed nodejs first to avoid conflicts.
RUN apt-get update \
&& apt-get remove -y nodejs || true \
&& rm -rf /var/lib/apt/lists/* \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get update \
&& apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/* \
&& node --version && npm --version
Comment on lines +43 to +50
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Operator precedence bug: || true swallows apt-get update failures too.

In shell, && and || are left-associative with equal precedence, so apt-get update && apt-get remove -y nodejs || true is parsed as (apt-get update && apt-get remove -y nodejs) || true. If apt-get update fails, the error is silently ignored.

Also, apt-get install -y nodejs on line 48 is missing --no-install-recommends, which inflates the image with unnecessary packages.

Proposed fix
-RUN apt-get update \
-    && apt-get remove -y nodejs || true \
-    && rm -rf /var/lib/apt/lists/* \
-    && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
-    && apt-get update \
-    && apt-get install -y nodejs \
-    && rm -rf /var/lib/apt/lists/* \
+RUN apt-get update \
+    && (apt-get remove -y nodejs || true) \
+    && rm -rf /var/lib/apt/lists/* \
+    && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
+    && apt-get update \
+    && apt-get install -y --no-install-recommends nodejs \
+    && rm -rf /var/lib/apt/lists/* \
     && node --version && npm --version
📝 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
RUN apt-get update \
&& apt-get remove -y nodejs || true \
&& rm -rf /var/lib/apt/lists/* \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get update \
&& apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/* \
&& node --version && npm --version
RUN apt-get update \
&& (apt-get remove -y nodejs || true) \
&& rm -rf /var/lib/apt/lists/* \
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get update \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/* \
&& node --version && npm --version
🧰 Tools
🪛 Trivy (0.69.1)

[error] 43-50: 'apt-get' missing '--no-install-recommends'

'--no-install-recommends' flag is missed: 'apt-get update && apt-get remove -y nodejs || true && rm -rf /var/lib/apt/lists/* && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && apt-get update && apt-get install -y nodejs && rm -rf /var/lib/apt/lists/* && node --version && npm --version'

Rule: DS-0029

Learn more

(IaC/Dockerfile)

🤖 Prompt for AI Agents
In `@Dockerfile` around lines 43 - 50, The RUN chain currently uses "apt-get
update && apt-get remove -y nodejs || true" which allows failures of apt-get
update to be swallowed; change that to ensure only the remove is optional by
grouping the remove with || true (e.g., "apt-get update && (apt-get remove -y
nodejs || true)") or separate into two RUN steps so apt-get update failure fails
the build; also add --no-install-recommends to the "apt-get install -y nodejs"
invocation to avoid pulling unnecessary packages and keep the rest of the
sequence (curl setup_22.x, second apt-get update, rm -rf /var/lib/apt/lists/*,
and the final node --version && npm --version) intact.


# Copy only frontend package files so Docker can cache npm installs when
# package.json / package-lock.json don't change.
Expand Down
2 changes: 1 addition & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ psycopg2-binary = "~=2.9.11"
pymysql = "~=1.1.0"
authlib = "~=1.6.4"
itsdangerous = "~=2.2.0"
jsonschema = "~=4.25.0"
jsonschema = "~=4.26.0"
tqdm = "~=4.67.1"
python-multipart = "~=0.0.10"
jinja2 = "~=3.1.4"
Expand Down
17 changes: 9 additions & 8 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ docker run -p 5000:5000 -it \

> For a full list of configuration options, consult `.env.example`.

## Memory TTL (optional)

QueryWeaver stores per-user conversation memory in FalkorDB. By default these graphs persist indefinitely. Set `MEMORY_TTL_SECONDS` to apply a Redis TTL (in seconds) so idle memory graphs are automatically cleaned up.

```bash
# Expire memory graphs after 1 week of inactivity
MEMORY_TTL_SECONDS=604800
```

The TTL is refreshed on every user interaction, so active users keep their memory.

## MCP server: host or connect (optional)

QueryWeaver includes optional support for the Model Context Protocol (MCP). You can either have QueryWeaver expose an MCP-compatible HTTP surface (so other services can call QueryWeaver as an MCP server), or configure QueryWeaver to call an external MCP server for model/context services.
Expand Down
8 changes: 8 additions & 0 deletions api/app_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ async def dispatch(self, request: Request, call_next):
return JSONResponse(status_code=403, content={"detail": "Forbidden"})

response = await call_next(request)

# Add HSTS header to prevent man-in-the-middle attacks
# max-age=31536000: 1 year in seconds
# includeSubDomains: apply to all subdomains
# preload: eligible for browser HSTS preload lists
hsts_value = "max-age=31536000; includeSubDomains; preload"
response.headers["Strict-Transport-Security"] = hsts_value

return response


Expand Down
24 changes: 22 additions & 2 deletions api/memory/graphiti_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from typing import List, Dict, Any, Optional, Tuple
from datetime import datetime

from redis import RedisError

# Import Azure OpenAI components
from openai import AsyncAzureOpenAI

Expand Down Expand Up @@ -47,10 +49,18 @@ def extract_embedding_model_name(full_model_name: str) -> str:
class MemoryTool:
"""Memory management tool for handling user memories and interactions."""

# Optional TTL (in seconds) for the memory graph key. Set via MEMORY_TTL_SECONDS
# env var to enable automatic expiry (e.g. 604800 for 1 week). Unset = no expiry.
MEMORY_TTL_SECONDS: Optional[int] = (
int(os.environ["MEMORY_TTL_SECONDS"])
if os.environ.get("MEMORY_TTL_SECONDS")
else None
)

def __init__(self, user_id: str, graph_id: str):
# Create FalkorDB driver with user-specific database
user_memory_db = f"{user_id}-memory"
falkor_driver = FalkorDriver(falkor_db=db, database=user_memory_db)
self.memory_db_name = f"{user_id}-memory"
falkor_driver = FalkorDriver(falkor_db=db, database=self.memory_db_name)


# Create Graphiti client with Azure OpenAI configuration
Expand All @@ -60,6 +70,13 @@ def __init__(self, user_id: str, graph_id: str):
self.graph_id = graph_id


async def _refresh_ttl(self) -> None:
"""Set a TTL on the memory graph key using Redis EXPIRE."""
try:
await db.execute_command("EXPIRE", self.memory_db_name, self.MEMORY_TTL_SECONDS)
except RedisError as e:
logging.warning("Failed to refresh TTL for %s: %s", self.memory_db_name, e)
Comment on lines +73 to +78
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find all calls to _refresh_ttl
rg -n --type=py '_refresh_ttl' .

Repository: FalkorDB/QueryWeaver

Length of output: 209


🏁 Script executed:

# Find all calls to create() on MemoryTool
rg -n --type=py 'create\(' . | grep -i memory

Repository: FalkorDB/QueryWeaver

Length of output: 406


🏁 Script executed:

# Check the graphiti_tool.py file to see the full implementation
cat -n api/memory/graphiti_tool.py | head -150

Repository: FalkorDB/QueryWeaver

Length of output: 6889


🏁 Script executed:

# Find the README and check what it says about TTL
find . -name "README*" -type f | head -5

Repository: FalkorDB/QueryWeaver

Length of output: 114


🏁 Script executed:

# Look for how MemoryTool is used - search for imports and instantiation
rg -n --type=py 'from.*graphiti_tool|import.*MemoryTool' .

Repository: FalkorDB/QueryWeaver

Length of output: 202


🏁 Script executed:

# Check text2sql.py around the create() calls to understand the pattern
sed -n '235,250p' api/core/text2sql.py

Repository: FalkorDB/QueryWeaver

Length of output: 697


🏁 Script executed:

# Check text2sql.py around line 725
sed -n '720,735p' api/core/text2sql.py

Repository: FalkorDB/QueryWeaver

Length of output: 761


🏁 Script executed:

# List all public methods in MemoryTool
rg -n --type=py '^\s+async def|^\s+def' api/memory/graphiti_tool.py

Repository: FalkorDB/QueryWeaver

Length of output: 1395


🏁 Script executed:

# Check README for the TTL statement
rg -n --type=md 'TTL|refresh' README.md | head -20

Repository: FalkorDB/QueryWeaver

Length of output: 427


🏁 Script executed:

# Get more context from the full MemoryTool implementation
sed -n '140,300p' api/memory/graphiti_tool.py

Repository: FalkorDB/QueryWeaver

Length of output: 7796


TTL is only refreshed during create(), not on every user interaction.

The README (line 69) states "The TTL is refreshed on every user interaction, so active users keep their memory." However, _refresh_ttl is only called inside create(). The per-interaction methods (search_memories, add_new_memory, save_query_memory, etc.) operate on an existing MemoryTool instance and do not refresh the TTL. This means active users with ongoing interactions can still lose their memory graphs if create() isn't invoked on every request.

Call _refresh_ttl in the per-interaction methods (at least the most common entry points like search_memories and add_new_memory), or update the README to reflect the actual behavior.

🤖 Prompt for AI Agents
In `@api/memory/graphiti_tool.py` around lines 73 - 78, The README claim that TTL
is refreshed on every user interaction is incorrect because _refresh_ttl is only
called in create(); update per-interaction methods (at least search_memories,
add_new_memory, save_query_memory and any other public handlers) to call await
self._refresh_ttl() after successful DB operations so the Redis EXPIRE for
self.memory_db_name using self.MEMORY_TTL_SECONDS is renewed, or alternatively
update the README if you prefer not to change runtime behavior.


@classmethod
async def create(cls, user_id: str, graph_id: str, use_direct_entities: bool = True) -> "MemoryTool":
"""Async factory to construct and initialize the tool."""
Expand All @@ -72,6 +89,9 @@ async def create(cls, user_id: str, graph_id: str, use_direct_entities: bool = T
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'}}")

if cls.MEMORY_TTL_SECONDS is not None:
await self._refresh_ttl()

return self

async def _ensure_entity_nodes_direct(self, user_id: str, database_name: str) -> bool:
Expand Down
Loading
Loading