Skip to content

Commit 68cae4c

Browse files
authored
FROM feat/420-project-endpoints TO development (#460)
* Init * UI in place, just need to collect checkpoint_id, send payload * Small tweak * Have a default system prompt for app * Fixes message content * Can send the query but needs to be selected for checkpoint * Can view and select, need to add final functionality * Can select and render messages, chat exp not best thoguh * Fix build * Fixed formatting * UPdate system prompts * using default system prompt * init * The service works correctly * Project Service * Small updates * Updates to system prommpt * Tidy up * optimized prompt meh * Updates
1 parent 7b9c0d4 commit 68cae4c

33 files changed

Lines changed: 561 additions & 433 deletions

File tree

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
- bug/370-anthropic-streaming (2025-09-16)
2020

2121
### Changed
22+
- feat/420-project-endpoints (2025-10-28)
2223
- feat/464-update-input-support-multiple-keys (2025-11-11)
2324
- feat/490-can-read-deepagents-agent-files (2025-11-10)
2425
- feat/485-user-env (2025-11-08)

backend/main.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
import os
21
import json
32
from typing import Callable
43
from time import perf_counter
54
from fastapi import FastAPI, Request, Response
6-
from fastapi.responses import FileResponse
7-
from fastapi.staticfiles import StaticFiles
85
from fastapi.middleware.cors import CORSMiddleware
96
from slowapi import _rate_limit_exceeded_handler
107
from slowapi.errors import RateLimitExceeded
@@ -63,7 +60,7 @@ async def lifespan(app: FastAPI):
6360

6461

6562
app = FastAPI(
66-
title="Enso 🤖",
63+
title="Enso Labs - Orchestra 🪶",
6764
version=APP_VERSION,
6865
description=(
6966
"This is a simple API for building chatbots with LangGraph. "

backend/mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
site_name: Enso Cloud ☁️
1+
site_name: Enso Labs - Orchestra 🪶
22
site_dir: src/public/docs
33
docs_dir: ../docs
44
use_directory_urls: false

backend/pyproject.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,3 @@ pythonpath = ["."]
6161
filterwarnings = [
6262
"ignore::DeprecationWarning:passlib.*"
6363
]
64-
65-
[tool.uv]
66-
prerelease = "allow"

backend/src/contexts/service.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Optional
22
from langchain_core.runnables import RunnableConfig
33
from langgraph.pregel.main import BaseCheckpointSaver
4+
from src.services.project import ProjectService
45
from src.services.checkpoint import CheckpointService
56
from src.services.thread import ThreadService
67
from src.services.assistant import AssistantService
@@ -31,6 +32,7 @@ def __init__(
3132
self.memory_service = MemoryService(user_id=self.user_id, store=store)
3233
self.thread_service = ThreadService(user_id=self.user_id, store=store)
3334
self.prompt_service = PromptService(user_id=self.user_id, store=store)
35+
self.project_service = ProjectService(user_id=self.user_id, store=store)
3436
self.assistant_service = AssistantService(user_id=self.user_id, store=store)
3537
self.presidio_service = PresidioService()
3638

backend/src/flows/__init__.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,13 @@ def graph_builder(
5555
context_schema: Type[ContextSchema] | None = None,
5656
checkpointer: BaseCheckpointSaver | None = None,
5757
store: BaseStore | None = None,
58-
graph_id: Literal[
59-
"react", "deepagents", "deepagent", "create_react_agent", "create_deep_agent"
60-
] = "react",
58+
graph_id: Literal['deepagent', 'react'] = "deepagent",
6159
) -> CompiledStateGraph:
6260
if graph_id in ["react", "create_react_agent", "create_agent"] and not subagents:
6361
return create_agent(
6462
model=model,
6563
tools=tools,
66-
prompt=prompt,
64+
system_prompt=prompt,
6765
checkpointer=checkpointer,
6866
context_schema=context_schema,
6967
store=store,
@@ -189,7 +187,7 @@ def __init__(
189187
# context_schema: Type[Any] | None = None,
190188
checkpointer: BaseCheckpointSaver = None,
191189
store: BaseStore = None,
192-
graph_id: Literal["react", "deepagent"] = "react",
190+
graph_id: Literal["react", "deepagent"] = "deepagent",
193191
):
194192
self.tools = tools
195193
self.model = model

backend/src/repos/project_repo.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from typing import Any
2+
from langgraph.store.base import BaseStore, SearchItem
3+
from src.services.db import get_in_memory_store
4+
5+
class ProjectRepo:
6+
def __init__(self,
7+
user_id: str,
8+
store: BaseStore = get_in_memory_store()
9+
):
10+
self.user_id = user_id
11+
self.store: BaseStore = store
12+
13+
def _get_namespace(self):
14+
return (self.user_id, "projects")
15+
16+
async def set(self, key: str, value: Any, ttl: int | None = None) -> bool:
17+
await self.store.aput(
18+
namespace=self._get_namespace(), key=key, value=value, ttl=ttl
19+
)
20+
return True
21+
22+
async def get(self, key: str) -> Any:
23+
return await self.store.aget(self._get_namespace(), key)
24+
25+
async def delete(self, key: str) -> bool:
26+
await self.store.adelete(self._get_namespace(), key)
27+
return True
28+
29+
async def search(
30+
self,
31+
query: str = None,
32+
limit: int = 20,
33+
) -> list[SearchItem]:
34+
return await self.store.asearch(
35+
self._get_namespace(), query=query, limit=limit
36+
)
37+
38+
39+
project_repo = ProjectRepo()

backend/src/routes/v0/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from .assistant import router as assistant
1515
from .schedule import router as schedule
1616
from .prompt import router as prompt
17+
from .project import router as project
1718

1819

1920
def create_api_router(app: FastAPI, prefix: str = "/api"):
@@ -22,8 +23,9 @@ def create_api_router(app: FastAPI, prefix: str = "/api"):
2223
app.include_router(llm, prefix=prefix)
2324
app.include_router(thread, prefix=prefix)
2425
app.include_router(tool, prefix=prefix)
25-
app.include_router(prompt, prefix=prefix)
2626
app.include_router(assistant, prefix=prefix)
27+
app.include_router(prompt, prefix=prefix)
28+
app.include_router(project, prefix=prefix)
2729
app.include_router(schedule, prefix=prefix)
2830
if LANGCONNECT_SERVER_URL:
2931
from .rag import gateway as rag

backend/src/routes/v0/llm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ async def list_models():
224224
return JSONResponse(
225225
status_code=status.HTTP_200_OK,
226226
content={
227-
"default": ChatModels.XAI_GROK_4_FAST.value,
227+
"default": ChatModels.ANTHROPIC_CLAUDE_4_5_HAIKU.value,
228228
"free": get_free_models(),
229229
"models": get_all_models(),
230230
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import uuid
2+
from fastapi import APIRouter, Body, Depends
3+
4+
from langgraph.store.postgres import AsyncPostgresStore
5+
6+
from src.contexts.service import ServiceContext
7+
# from src.constants.examples import Examples
8+
from src.schemas.models import ProtectedUser
9+
from src.services.db import get_store
10+
from src.utils.auth import verify_credentials
11+
from src.services.project import (
12+
Project,
13+
ProjectSearch,
14+
)
15+
16+
17+
################################################################################
18+
### Create Assistant
19+
################################################################################
20+
router = APIRouter(tags=["Project"], prefix="/projects")
21+
22+
23+
@router.post("/search", name="Query Projects")
24+
async def search_projects(
25+
project_search: ProjectSearch = Body(...),
26+
user: ProtectedUser = Depends(verify_credentials),
27+
store: AsyncPostgresStore = Depends(get_store),
28+
):
29+
service_context = ServiceContext(user_id=user.id, store=store)
30+
# If id is provided, return the project
31+
if "id" in project_search.filter:
32+
project = await service_context.project_service.get(
33+
project_search.filter["id"]
34+
)
35+
return {"projects": [project.model_dump()]}
36+
# If id is not provided, return all projects
37+
projects: list[Project] = await service_context.project_service.search(project_search)
38+
return {"projects": [project.model_dump() for project in projects]}

0 commit comments

Comments
 (0)