Skip to content

Commit 41c87b6

Browse files
committed
Update
1 parent f9a10b2 commit 41c87b6

29 files changed

+152
-706
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
.PHONY: start
22

33
start:
4-
cd backend && poetry run langgraph up -c ../langgraph.json -d ../compose.override.yml
4+
cd backend && poetry run langgraph up -c ../langgraph.json -d ../compose.override.yml --postgres-uri 'postgres://postgres:postgres@langgraph-postgres:5432/postgres?sslmode=disable' --verbose

backend/Makefile

-4
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,10 @@ TEST_FILE ?= tests/unit_tests/
1616
start:
1717
poetry run uvicorn app.server:app --reload --port 8100 --log-config log_config.json
1818

19-
migrate:
20-
migrate -database postgres://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@$(POSTGRES_HOST):$(POSTGRES_PORT)/$(POSTGRES_DB)?sslmode=disable -path ./migrations up
21-
2219
test:
2320
# We need to update handling of env variables for tests
2421
YDC_API_KEY=placeholder OPENAI_API_KEY=placeholder poetry run pytest $(TEST_FILE)
2522

26-
2723
test_watch:
2824
# We need to update handling of env variables for tests
2925
YDC_API_KEY=placeholder OPENAI_API_KEY=placeholder poetry run ptw . -- $(TEST_FILE)

backend/app/api/assistants.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from typing import Annotated, List
2-
from uuid import uuid4
32

43
from fastapi import APIRouter, HTTPException, Path
54
from pydantic import BaseModel, Field
@@ -52,23 +51,22 @@ async def create_assistant(
5251
payload: AssistantPayload,
5352
) -> Assistant:
5453
"""Create an assistant."""
55-
return await storage.put_assistant(
54+
return await storage.create_assistant(
5655
user["user_id"],
57-
str(uuid4()),
5856
name=payload.name,
5957
config=payload.config,
6058
public=payload.public,
6159
)
6260

6361

64-
@router.put("/{aid}")
62+
@router.patch("/{aid}")
6563
async def upsert_assistant(
6664
user: AuthedUser,
6765
aid: AssistantID,
6866
payload: AssistantPayload,
6967
) -> Assistant:
7068
"""Create or update an assistant."""
71-
return await storage.put_assistant(
69+
return await storage.patch_assistant(
7270
user["user_id"],
7371
aid,
7472
name=payload.name,

backend/app/api/runs.py

+15-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import json
21
import pathlib
32
from typing import Any, Dict, Optional, Sequence, Union
43
from uuid import UUID
@@ -13,7 +12,7 @@
1312
from sse_starlette import EventSourceResponse
1413

1514
from app.auth.handlers import AuthedUser
16-
from app.lifespan import get_langserve
15+
from app.lifespan import get_api_client
1716
from app.storage import get_assistant, get_thread
1817

1918
router = APIRouter()
@@ -33,7 +32,7 @@ async def create_run(payload: CreateRunPayload, user: AuthedUser):
3332
thread = await get_thread(user["user_id"], payload.thread_id)
3433
if not thread:
3534
raise HTTPException(status_code=404, detail="Thread not found")
36-
return await get_langserve().runs.create(
35+
return await get_api_client().runs.create(
3736
payload.thread_id,
3837
thread["assistant_id"],
3938
input=payload.input,
@@ -53,21 +52,27 @@ async def stream_run(
5352
assistant = await get_assistant(user["user_id"], thread["assistant_id"])
5453
if not assistant:
5554
raise HTTPException(status_code=404, detail="Assistant not found")
55+
interrupt_before = (
56+
["action"]
57+
if assistant["config"]["configurable"].get(
58+
"type==agent/interrupt_before_action"
59+
)
60+
else None
61+
)
5662

5763
return EventSourceResponse(
5864
(
59-
{"event": e.event, "data": json.dumps(e.data)}
60-
async for e in get_langserve().runs.stream(
65+
{
66+
"event": "data" if e.event.startswith("messages") else e.event,
67+
"data": orjson.dumps(e.data).decode(),
68+
}
69+
async for e in get_api_client().runs.stream(
6170
payload.thread_id,
6271
thread["assistant_id"],
6372
input=payload.input,
6473
config=payload.config,
6574
stream_mode="messages",
66-
interrupt_before=["action"]
67-
if assistant["config"]["configurable"].get(
68-
"type==agent/interrupt_before_action"
69-
)
70-
else None,
75+
interrupt_before=interrupt_before,
7176
)
7277
)
7378
)

backend/app/api/threads.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from typing import Annotated, Any, Dict, List, Optional, Sequence, Union
2-
from uuid import uuid4
32

43
from fastapi import APIRouter, HTTPException, Path
54
from langchain.schema.messages import AnyMessage
@@ -136,22 +135,21 @@ async def create_thread(
136135
thread_put_request: ThreadPutRequest,
137136
) -> Thread:
138137
"""Create a thread."""
139-
return await storage.put_thread(
138+
return await storage.create_thread(
140139
user["user_id"],
141-
str(uuid4()),
142140
assistant_id=thread_put_request.assistant_id,
143141
name=thread_put_request.name,
144142
)
145143

146144

147-
@router.put("/{tid}")
145+
@router.patch("/{tid}")
148146
async def upsert_thread(
149147
user: AuthedUser,
150148
tid: ThreadID,
151149
thread_put_request: ThreadPutRequest,
152150
) -> Thread:
153151
"""Update a thread."""
154-
return await storage.put_thread(
152+
return await storage.patch_thread(
155153
user["user_id"],
156154
tid,
157155
assistant_id=thread_put_request.assistant_id,

backend/app/auth/handlers.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from fastapi import Depends, HTTPException, Request
88
from fastapi.security.http import HTTPBearer
99

10-
import app.storage as storage
1110
from app.auth.settings import AuthType, settings
1211
from app.schema import User
1312

@@ -23,8 +22,7 @@ class NOOPAuth(AuthHandler):
2322

2423
async def __call__(self, request: Request) -> User:
2524
sub = request.cookies.get("opengpts_user_id") or self._default_sub
26-
user, _ = await storage.get_or_create_user(sub)
27-
return user
25+
return User(user_id=sub, sub=sub)
2826

2927

3028
class JWTAuthBase(AuthHandler):
@@ -37,8 +35,7 @@ async def __call__(self, request: Request) -> User:
3735
except jwt.PyJWTError as e:
3836
raise HTTPException(status_code=401, detail=str(e))
3937

40-
user, _ = await storage.get_or_create_user(payload["sub"])
41-
return user
38+
return User(user_id=payload["sub"], sub=payload["sub"])
4239

4340
@abstractmethod
4441
def decode_token(self, token: str, decode_key: str) -> dict:

backend/app/lifespan.py

+3-34
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,17 @@
11
import os
22
from contextlib import asynccontextmanager
33

4-
import asyncpg
5-
import orjson
64
import structlog
75
from fastapi import FastAPI
8-
from langgraph_sdk.client import LangServeClient, get_client
6+
from langgraph_sdk.client import LangGraphClient, get_client
97

10-
_pg_pool = None
118
_langserve = None
129

1310

14-
def get_pg_pool() -> asyncpg.pool.Pool:
15-
return _pg_pool
16-
17-
18-
def get_langserve() -> LangServeClient:
11+
def get_api_client() -> LangGraphClient:
1912
return _langserve
2013

2114

22-
async def _init_connection(conn) -> None:
23-
await conn.set_type_codec(
24-
"json",
25-
encoder=lambda v: orjson.dumps(v).decode(),
26-
decoder=orjson.loads,
27-
schema="pg_catalog",
28-
)
29-
await conn.set_type_codec(
30-
"jsonb",
31-
encoder=lambda v: orjson.dumps(v).decode(),
32-
decoder=orjson.loads,
33-
schema="pg_catalog",
34-
)
35-
await conn.set_type_codec(
36-
"uuid", encoder=lambda v: str(v), decoder=lambda v: v, schema="pg_catalog"
37-
)
38-
39-
4015
@asynccontextmanager
4116
async def lifespan(app: FastAPI):
4217
structlog.configure(
@@ -52,15 +27,9 @@ async def lifespan(app: FastAPI):
5227
cache_logger_on_first_use=True,
5328
)
5429

55-
global _pg_pool, _langserve
30+
global _langserve
5631

57-
_pg_pool = await asyncpg.create_pool(
58-
os.environ["POSTGRES_URI"],
59-
init=_init_connection,
60-
)
6132
_langserve = get_client(url=os.environ["LANGGRAPH_URL"])
6233
yield
63-
await _pg_pool.close()
6434
await _langserve.http.client.aclose()
65-
_pg_pool = None
6635
_langserve = None

backend/app/schema.py

-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ class User(TypedDict):
99
"""The ID of the user."""
1010
sub: str
1111
"""The sub of the user (from a JWT token)."""
12-
created_at: datetime
13-
"""The time the user was created."""
1412

1513

1614
class Assistant(TypedDict):

0 commit comments

Comments
 (0)