Skip to content

Commit 1f8a910

Browse files
committed
Merge branch 'main' of https://github.com/BrunoV21/CodeTide
2 parents 9b6a096 + 532c745 commit 1f8a910

25 files changed

+2147
-258
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,6 @@ examples/hf_demo_space/chainlit.md
186186

187187
examples/hf_demo_space/public/
188188
database.db-journal
189+
database.db-shm
189190
.chainlit/
191+
pgdata/

Dockerfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
FROM python:3.13-slim
2+
3+
# Set environment variables
4+
ENV PYTHONDONTWRITEBYTECODE=1
5+
ENV PYTHONUNBUFFERED=1
6+
7+
# Set work directory
8+
WORKDIR /app
9+
10+
# Install system dependencies (if any are needed, add here)
11+
# RUN apt-get update && apt-get install -y <dependencies> && rm -rf /var/lib/apt/lists/*
12+
13+
# Copy requirements and install dependencies
14+
COPY requirements.txt .
15+
RUN pip install --upgrade pip && pip install -r requirements.txt
16+
17+
# Copy the rest of the code
18+
COPY . .
19+
20+
# Install the package (so entry points are available)
21+
RUN pip install -e .
22+
23+
# Default command: launch the CLI
24+
ENTRYPOINT ["codetide-cli"]

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ uvx --from codetide codetide-cli --help
4444

4545
AgentTide consists of a demo, showing how CodeTide can integrate with LLMs and augment code generation and condebase related workflows. If you ask Tide to describe himself, he will say something like this: I'm the next-generation, precision-driven software engineering agent built on top of CodeTide. You can use it via the command-line interface (CLI) or a beautiful interactive UI.
4646

47+
> **Demo available:** Try AgentTide live on Hugging Face Spaces: [https://mclovinittt-agenttidedemo.hf.space/](https://mclovinittt-agenttidedemo.hf.space/)
48+
4749
---
4850

4951
<div align="center">
@@ -552,6 +554,8 @@ Here’s what’s next for CodeTide:
552554
553555
## 🤖 Agents Module: AgentTide
554556
557+
> **Demo available:** Try AgentTide live on Hugging Face Spaces: [https://mclovinittt-agenttidedemo.hf.space/](https://mclovinittt-agenttidedemo.hf.space/)
558+
555559
CodeTide now includes an `agents` module, featuring **AgentTide**—a precision-driven software engineering agent that connects directly to your codebase and executes your requests with full code context.
556560
557561
**AgentTide** leverages CodeTide’s symbolic code understanding to:

codetide/__init__.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def relative_filepaths(self)->List[str]:
100100

101101
@property
102102
def cached_ids(self)->List[str]:
103-
return self.codebase.unique_ids+self.relative_filepaths
103+
return self.codebase.non_import_unique_ids+self.relative_filepaths
104104

105105
@property
106106
def repo(self)->Optional[pygit2.Repository]:
@@ -571,6 +571,8 @@ def get(
571571
"""
572572
if isinstance(code_identifiers, str):
573573
code_identifiers = [code_identifiers]
574+
else:
575+
code_identifiers = self.get_unique_paths(code_identifiers)
574576

575577
logger.info(
576578
f"Context request - IDs: {code_identifiers}, "
@@ -602,3 +604,23 @@ def _as_file_paths(self, code_identifiers: Union[str, List[str]])->List[str]:
602604
as_file_paths.append(element)
603605

604606
return as_file_paths
607+
608+
@staticmethod
609+
def get_unique_paths(path_list):
610+
"""
611+
Process a list of path strings and return only unique entries.
612+
Normalizes path separators to handle both forward and back slashes.
613+
"""
614+
seen = set()
615+
unique_paths = []
616+
617+
for path in path_list:
618+
# Normalize the path to use OS-appropriate separators
619+
normalized = os.path.normpath(path)
620+
621+
# Only add if we haven't seen this normalized path before
622+
if normalized not in seen:
623+
seen.add(normalized)
624+
unique_paths.append(normalized)
625+
626+
return unique_paths

codetide/agents/data_layer.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
from sqlalchemy import String, Text, ForeignKey, Boolean, Integer
44
from sqlalchemy.ext.asyncio import create_async_engine
55
from sqlalchemy.types import TypeDecorator
6+
from sqlalchemy.exc import OperationalError
67
except ImportError as e:
78
raise ImportError(
89
"This module requires 'sqlalchemy' and 'ulid-py'. "
910
"Install them with: pip install codetide[agents-ui]"
10-
) from e
11+
) from e
1112

13+
import asyncio
1214
from datetime import datetime
13-
from sqlalchemy import Select
1415
from ulid import ulid
15-
import asyncio
1616
import json
1717

1818
# SQLite-compatible JSON and UUID types
@@ -169,11 +169,27 @@ class Feedback(Base):
169169
# chats = await db.list_chats()
170170
# for c in chats:
171171
# print(f"{c.id} — {c.name}")
172-
async def init_db(path: str):
173-
from sqlalchemy.ext.asyncio import async_sessionmaker, AsyncSession
174-
engine = create_async_engine(f"sqlite+aiosqlite:///{path}")
175-
async with engine.begin() as conn:
176-
await conn.run_sync(Base.metadata.create_all)
177-
178-
if __name__ == "__main__":
179-
asyncio.run(init_db("database.db"))
172+
173+
async def init_db(conn_str: str, max_retries: int = 5, retry_delay: int = 2):
174+
"""
175+
Initialize database with retry logic for connection issues.
176+
"""
177+
engine = create_async_engine(conn_str)
178+
179+
for attempt in range(max_retries):
180+
try:
181+
async with engine.begin() as conn:
182+
await conn.run_sync(Base.metadata.create_all)
183+
print("Database initialized successfully!")
184+
return
185+
except OperationalError as e:
186+
if attempt == max_retries - 1:
187+
print(f"Failed to initialize database after {max_retries} attempts: {e}")
188+
raise
189+
else:
190+
print(f"Database connection failed (attempt {attempt + 1}/{max_retries}): {e}")
191+
print(f"Retrying in {retry_delay} seconds...")
192+
await asyncio.sleep(retry_delay)
193+
except Exception as e:
194+
print(f"Unexpected error initializing database: {e}")
195+
raise

0 commit comments

Comments
 (0)