-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat(sessions): Add session title management functionality #3703
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
6517592
c737bba
6c96278
2a81c3a
f7853c6
075085c
6cfc057
dc98833
71a0e5d
1022f73
04f77ae
d7a722f
befd3c9
f64608c
649daaf
f8d77d6
bfe19b5
d224489
f70a2d8
880edcc
07f6061
81e5cf1
eafc126
2e9ab59
c76c9c2
3efab01
c7b8bd3
fc9d4ff
447b24b
0ae2796
b60e9e4
f4ea24e
c044877
6e10f74
853e9a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,12 +58,14 @@ async def create_session( | |
| user_id: str, | ||
| state: Optional[dict[str, Any]] = None, | ||
| session_id: Optional[str] = None, | ||
| title: Optional[str] = None, | ||
| ) -> Session: | ||
| return self._create_session_impl( | ||
| app_name=app_name, | ||
| user_id=user_id, | ||
| state=state, | ||
| session_id=session_id, | ||
| title=title, | ||
| ) | ||
|
|
||
| def create_session_sync( | ||
|
|
@@ -73,13 +75,15 @@ def create_session_sync( | |
| user_id: str, | ||
| state: Optional[dict[str, Any]] = None, | ||
| session_id: Optional[str] = None, | ||
| title: Optional[str] = None, | ||
| ) -> Session: | ||
| logger.warning('Deprecated. Please migrate to the async method.') | ||
| return self._create_session_impl( | ||
| app_name=app_name, | ||
| user_id=user_id, | ||
| state=state, | ||
| session_id=session_id, | ||
| title=title, | ||
| ) | ||
|
|
||
| def _create_session_impl( | ||
|
|
@@ -89,6 +93,7 @@ def _create_session_impl( | |
| user_id: str, | ||
| state: Optional[dict[str, Any]] = None, | ||
| session_id: Optional[str] = None, | ||
| title: Optional[str] = None, | ||
| ) -> Session: | ||
| if session_id and self._get_session_impl( | ||
| app_name=app_name, user_id=user_id, session_id=session_id | ||
|
|
@@ -116,6 +121,7 @@ def _create_session_impl( | |
| id=session_id, | ||
| state=session_state or {}, | ||
| last_update_time=time.time(), | ||
| title=title, | ||
| ) | ||
|
|
||
| if app_name not in self.sessions: | ||
|
|
@@ -286,6 +292,26 @@ def _delete_session_impl( | |
|
|
||
| self.sessions[app_name][user_id].pop(session_id) | ||
|
|
||
| @override | ||
| async def update_session_title( | ||
| self, | ||
| *, | ||
| app_name: str, | ||
| user_id: str, | ||
| session_id: str, | ||
| title: Optional[str], | ||
| ) -> None: | ||
| if ( | ||
| app_name not in self.sessions | ||
| or user_id not in self.sessions[app_name] | ||
| or session_id not in self.sessions[app_name][user_id] | ||
| ): | ||
| raise ValueError( | ||
| f'Session not found: app_name={app_name}, user_id={user_id},' | ||
| f' session_id={session_id}' | ||
| ) | ||
| self.sessions[app_name][user_id][session_id].title = title | ||
|
||
|
|
||
| @override | ||
| async def append_event(self, session: Session, event: Event) -> Event: | ||
| if event.partial: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,6 +64,7 @@ | |
| user_id TEXT NOT NULL, | ||
| id TEXT NOT NULL, | ||
| state TEXT NOT NULL, | ||
| title TEXT, | ||
| create_time REAL NOT NULL, | ||
| update_time REAL NOT NULL, | ||
| PRIMARY KEY (app_name, user_id, id) | ||
|
|
@@ -121,6 +122,7 @@ async def create_session( | |
| user_id: str, | ||
| state: Optional[dict[str, Any]] = None, | ||
| session_id: Optional[str] = None, | ||
| title: Optional[str] = None, | ||
| ) -> Session: | ||
| if session_id: | ||
| session_id = session_id.strip() | ||
|
|
@@ -160,14 +162,15 @@ async def create_session( | |
| # Store the session | ||
| await db.execute( | ||
| """ | ||
| INSERT INTO sessions (app_name, user_id, id, state, create_time, update_time) | ||
| VALUES (?, ?, ?, ?, ?, ?) | ||
| INSERT INTO sessions (app_name, user_id, id, state, title, create_time, update_time) | ||
| VALUES (?, ?, ?, ?, ?, ?, ?) | ||
| """, | ||
| ( | ||
| app_name, | ||
| user_id, | ||
| session_id, | ||
| json.dumps(session_state), | ||
| title, | ||
| now, | ||
| now, | ||
| ), | ||
|
|
@@ -185,6 +188,7 @@ async def create_session( | |
| state=merged_state, | ||
| events=[], | ||
| last_update_time=now, | ||
| title=title, | ||
| ) | ||
|
|
||
| @override | ||
|
|
@@ -198,14 +202,15 @@ async def get_session( | |
| ) -> Optional[Session]: | ||
| async with self._get_db_connection() as db: | ||
| async with db.execute( | ||
| "SELECT state, update_time FROM sessions WHERE app_name=? AND" | ||
| "SELECT state, title, update_time FROM sessions WHERE app_name=? AND" | ||
| " user_id=? AND id=?", | ||
| (app_name, user_id, session_id), | ||
| ) as cursor: | ||
| session_row = await cursor.fetchone() | ||
| if session_row is None: | ||
| return None | ||
| session_state = json.loads(session_row["state"]) | ||
| title = session_row["title"] | ||
| last_update_time = session_row["update_time"] | ||
|
|
||
| # Build events query | ||
|
|
@@ -248,6 +253,7 @@ async def get_session( | |
| state=merged_state, | ||
| events=events, | ||
| last_update_time=last_update_time, | ||
| title=title, | ||
| ) | ||
|
|
||
| @override | ||
|
|
@@ -259,13 +265,13 @@ async def list_sessions( | |
| # Fetch sessions | ||
| if user_id: | ||
| session_rows = await db.execute_fetchall( | ||
| "SELECT id, user_id, state, update_time FROM sessions WHERE" | ||
| "SELECT id, user_id, state, title, update_time FROM sessions WHERE" | ||
| " app_name=? AND user_id=?", | ||
| (app_name, user_id), | ||
| ) | ||
| else: | ||
| session_rows = await db.execute_fetchall( | ||
| "SELECT id, user_id, state, update_time FROM sessions WHERE" | ||
| "SELECT id, user_id, state, title, update_time FROM sessions WHERE" | ||
| " app_name=?", | ||
| (app_name,), | ||
| ) | ||
|
|
@@ -291,6 +297,7 @@ async def list_sessions( | |
| for row in session_rows: | ||
| session_user_id = row["user_id"] | ||
| session_state = json.loads(row["state"]) | ||
| title = row["title"] | ||
| user_state = user_states_map.get(session_user_id, {}) | ||
| merged_state = _merge_state(app_state, user_state, session_state) | ||
| sessions_list.append( | ||
|
|
@@ -301,10 +308,36 @@ async def list_sessions( | |
| state=merged_state, | ||
| events=[], | ||
| last_update_time=row["update_time"], | ||
| title=title, | ||
| ) | ||
| ) | ||
| return ListSessionsResponse(sessions=sessions_list) | ||
|
|
||
| @override | ||
| async def update_session_title( | ||
| self, | ||
| *, | ||
| app_name: str, | ||
| user_id: str, | ||
| session_id: str, | ||
| title: Optional[str], | ||
| ) -> None: | ||
| async with self._get_db_connection() as db: | ||
| async with db.execute( | ||
| "SELECT 1 FROM sessions WHERE app_name=? AND user_id=? AND id=?", | ||
| (app_name, user_id, session_id), | ||
| ) as cursor: | ||
| if not await cursor.fetchone(): | ||
| raise ValueError( | ||
| f"Session not found: app_name={app_name}, user_id={user_id}," | ||
| f" session_id={session_id}" | ||
| ) | ||
| await db.execute( | ||
| "UPDATE sessions SET title=? WHERE app_name=? AND user_id=? AND id=?", | ||
| (title, app_name, user_id, session_id), | ||
| ) | ||
| await db.commit() | ||
|
Comment on lines
357
to
375
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This implementation uses two separate database queries ( async def update_session_title(
self,
*,
app_name: str,
user_id: str,
session_id: str,
title: Optional[str],
) -> None:
async with self._get_db_connection() as db:
cursor = await db.execute(
"UPDATE sessions SET title=? WHERE app_name=? AND user_id=? AND id=?",
(title, app_name, user_id, session_id),
)
if cursor.rowcount == 0:
raise ValueError(
f"Session not found: app_name={app_name}, user_id={user_id},"
f" session_id={session_id}"
)
await db.commit() |
||
|
|
||
| @override | ||
| async def delete_session( | ||
| self, *, app_name: str, user_id: str, session_id: str | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.