Skip to content

[feat] Order and search the session list by last activity (2/12) - #5681

Merged
mmabrouk merged 9 commits into
release/v0.111.0from
feat/api-sessions-list-ordering
Aug 7, 2026
Merged

[feat] Order and search the session list by last activity (2/12)#5681
mmabrouk merged 9 commits into
release/v0.111.0from
feat/api-sessions-list-ordering

Conversation

@ardaerzin

Copy link
Copy Markdown
Contributor

Context

The session list had no useful order. /sessions/query returned rows by creation date, so a session you worked in five minutes ago sat below one you created last week and never touched. There was also no way to find a session by name, and a row carried no hint of what it was about.

This is lane 2 of a 12-PR stack (see #5679 for the shape). It is backend work that stands on its own: the desktop list benefits from it immediately, and the mobile app in later lanes depends on it.

Changes

Ordering moves to last activity. The window is coalesce(updated_at, created_at) rather than updated_at alone, because a session that has never been updated has a null there and would sort as if it were the oldest thing in the project. The id tiebreak follows the sort direction, so a page boundary that lands mid-tie does not repeat or skip a row.

/sessions/query gains a free-text search over the session title, and rows now carry their latest turn's references so a list can label a row without a second round trip per session.

The desktop's client-side sort in AgentChatSlice/state/projectSessions.ts is deleted. The server is now authoritative for order, and keeping a client sort on top of it means two implementations that can disagree.

Tests / notes

  • New pytest coverage for windowing, the direction-matched tiebreak, search, and reference enrichment.
  • @agenta/entities gains a wire-shape test pinned to a server-faithful fixture, so a backend change that alters the row shape fails on the frontend side too.
  • No migration. The ordering change is a query change; existing rows need nothing.

@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview Aug 5, 2026 11:09pm

Request Review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added case-insensitive session title search.
    • Added cursor-based session pagination.
    • Session results now include references from the latest activity.
    • Improved ordering by recent activity with stable tie-breaking.
  • Bug Fixes

    • Improved handling of special characters and empty searches.
    • Preserved consistent ordering across paginated and non-paginated results.
  • Tests

    • Added coverage for search, references, pagination ordering, and response validation.

Walkthrough

Session queries now support case-insensitive title search, cursor pagination, updated activity ordering, and latest-turn reference enrichment. Backend DTOs, services, DAOs, API models, frontend request types, schemas, and tests were updated.

Changes

Session query enhancements

Layer / File(s) Summary
Query contracts and enrichment orchestration
api/oss/src/apis/fastapi/sessions/*, api/oss/src/core/sessions/*, api/oss/tests/pytest/unit/sessions/test_query_sessions_references.py, api/oss/tests/pytest/unit/sessions/test_sessions_root_service.py
Session responses now use SessionListItem. Queries forward search. Services batch-load the latest turn and expose its references.
Search, ordering, and latest-turn storage
api/oss/src/dbs/postgres/sessions/*, api/oss/src/dbs/postgres/shared/utils.py, api/oss/tests/pytest/unit/sessions/test_query_sessions_search.py, api/oss/tests/pytest/unit/sessions/test_query_sessions_windowing.py
Postgres queries add escaped title search, updated_at ordering with fallback, matching cursor tie-breakers, and highest-index turn lookup per session.
Frontend query API and response schema
web/packages/agenta-entities/src/session/api/api.ts, web/packages/agenta-entities/src/session/core/schema.ts, web/packages/agenta-entities/tests/unit/session-query-schema.test.ts, web/oss/src/components/AgentChatSlice/state/projectSessions.ts
Frontend requests send search and pagination parameters. Session schemas accept optional references. Activity documentation describes server-side ordering.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant SessionsRouter
  participant SessionsService
  participant SessionStreamsDAO
  participant SessionTurnsService
  participant SessionTurnsDAO
  Client->>SessionsRouter: Query sessions with search and pagination
  SessionsRouter->>SessionsService: Build SessionQuery
  SessionsService->>SessionStreamsDAO: Fetch filtered, ordered streams
  SessionStreamsDAO-->>SessionsService: Return session streams
  SessionsService->>SessionTurnsService: Fetch latest turn per session
  SessionTurnsService->>SessionTurnsDAO: Query highest-index turns
  SessionTurnsDAO-->>SessionTurnsService: Return references by session ID
  SessionsService-->>Client: Return SessionListItem response
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.86% which is insufficient. The required threshold is 60.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main changes: ordering the session list by last activity and adding search.
Description check ✅ Passed The description accurately explains session ordering, search, reference enrichment, client sorting removal, and test coverage.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/api-sessions-list-ordering

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
api/oss/tests/pytest/unit/sessions/test_query_sessions_search.py (1)

30-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the duplicated dummy-engine test doubles into a shared helper. Both new test files define identical _DummyScalars, _DummyResult, _DummySession, and _DummySessionContext classes to intercept the compiled SQLAlchemy statement. The shared root cause is the lack of a common test helper for this statement-compilation pattern.

  • api/oss/tests/pytest/unit/sessions/test_query_sessions_search.py#L30-L58: move these four classes into a shared module (for example a conftest.py fixture or a _dummy_engine.py test helper under api/oss/tests/pytest/unit/sessions/) and import them here.
  • api/oss/tests/pytest/unit/sessions/test_query_sessions_windowing.py#L135-L163: import the same shared classes instead of redefining them.
web/packages/agenta-entities/src/session/api/api.ts (1)

294-308: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

Regenerate the Fern client to include search before merge.

querySessions forwards the request object with body: request, so search will reach the wire in the current SDK; regenerate SessionQueryRequest so the cast grows the generated type instead of relying on this one-off widening.

api/oss/src/core/sessions/turns/service.py (1)

112-124: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

latest_turn_per_session returns a raw dict instead of a DTO.

latest_turn_per_session returns Dict[str, SessionTurn]. The coding guideline requires service methods to return typed DTOs, not raw dicts. Every other method in this service (query_turns, latest_turn, latest_turn_per_harness_kind) follows List[DTO]/Optional[DTO]. This method is the exception.

A full fix wraps the mapping in a small DTO (for example LatestTurnsBySession with a turns: Dict[str, SessionTurn] field). This also touches SessionTurnsDAOInterface.latest_turn_per_session, SessionTurnsDAO.latest_turn_per_session, and the consumer in SessionsService.query_sessions, plus the test fixtures that assert on the bare dict today.

Given the wide blast radius versus the marginal type-safety gain over an already-typed Dict[str, SessionTurn], treat this as deferable.

As per coding guidelines: "Service methods must return typed DTOs (Pydantic BaseModel subclasses), not raw dicts, tuples, or Any; use Optional[DTO] for missing entities and List[DTO] for collections."

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 93a2da23-f32a-427c-8806-56d84f4b6b15

📥 Commits

Reviewing files that changed from the base of the PR and between a8ad264 and 4c9c4be.

📒 Files selected for processing (18)
  • api/oss/src/apis/fastapi/sessions/models.py
  • api/oss/src/apis/fastapi/sessions/router.py
  • api/oss/src/core/sessions/dtos.py
  • api/oss/src/core/sessions/service.py
  • api/oss/src/core/sessions/streams/dtos.py
  • api/oss/src/core/sessions/turns/interfaces.py
  • api/oss/src/core/sessions/turns/service.py
  • api/oss/src/dbs/postgres/sessions/streams/dao.py
  • api/oss/src/dbs/postgres/sessions/turns/dao.py
  • api/oss/src/dbs/postgres/shared/utils.py
  • api/oss/tests/pytest/unit/sessions/test_query_sessions_references.py
  • api/oss/tests/pytest/unit/sessions/test_query_sessions_search.py
  • api/oss/tests/pytest/unit/sessions/test_query_sessions_windowing.py
  • api/oss/tests/pytest/unit/sessions/test_sessions_root_service.py
  • web/oss/src/components/AgentChatSlice/state/projectSessions.ts
  • web/packages/agenta-entities/src/session/api/api.ts
  • web/packages/agenta-entities/src/session/core/schema.ts
  • web/packages/agenta-entities/tests/unit/session-query-schema.test.ts

Comment on lines +1 to +16
/**
* Pins the `/sessions/query` wire shape for `sessionStreamSchema`/`sessionsQueryResponseSchema`.
*
* Fern's compile-time types under-declare backend `extra="allow"` fields and don't catch
* server-side field renames, and zod silently STRIPS unknown wire keys to `undefined` on a
* `.nullish()` field — so a renamed backend key (e.g. `name`, `references`) tsc-passes and
* parse-succeeds while the FE session list silently loses the data (this class of drift has
* bitten the session schemas twice: see `session-record-schema.test.ts`). These tests assert
* a realistic wire payload survives parsing with its values intact, and document — via a
* deliberately-renamed fixture — that a real rename would slip past zod undetected unless
* this fixture is kept in sync with an actual backend payload.
*/
import {describe, expect, it} from "vitest"

import {sessionsQueryResponseSchema, sessionStreamSchema} from "../../src/session/core/schema"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the Prettier formatting failure reported by CI.

The pipeline log reports a Prettier formatting failure for cd web && pnpm run format in this change. Run pnpm lint-fix (or prettier --write) from web on this file and commit the result.

As per coding guidelines: "Run pnpm lint-fix from the web directory before committing."

🧰 Tools
🪛 GitHub Actions: 11 - check code styling / 3_TypeScript format.txt

[error] 1-1: Prettier formatting check failed. Run 'prettier --write' to fix code style issues. Command 'cd web && pnpm run format' failed with exit code 1.

🪛 GitHub Actions: 11 - check code styling / TypeScript format

[error] 1-1: Prettier formatting check failed during 'cd web && pnpm run format'. Run Prettier with --write to fix code style issues.

Sources: Coding guidelines, Pipeline failures

@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@ardaerzin

Copy link
Copy Markdown
Contributor Author

Prettier on session-query-schema.test.ts — stale. The file passes prettier --check on this branch and the "11 - check code styling / TypeScript format" job is green on this PR. The cited pipeline log predates the format sweep.

@ardaerzin
ardaerzin force-pushed the feat/api-sessions-list-ordering branch from a024cad to 75be3f7 Compare August 3, 2026 22:29
@ardaerzin
ardaerzin force-pushed the feat/mobile-app-scaffold branch from b0ee688 to bfbd241 Compare August 4, 2026 18:25
@ardaerzin
ardaerzin force-pushed the feat/api-sessions-list-ordering branch from 75be3f7 to 40fd6b4 Compare August 4, 2026 18:25
@ardaerzin
ardaerzin force-pushed the feat/mobile-app-scaffold branch from bfbd241 to 2be5bd8 Compare August 4, 2026 19:25
@ardaerzin
ardaerzin force-pushed the feat/api-sessions-list-ordering branch from 40fd6b4 to 6ce2096 Compare August 4, 2026 19:25
@mmabrouk
mmabrouk marked this pull request as ready for review August 5, 2026 08:21
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. Backend Feature Request New feature or request labels Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Status Destroyed (PR closed)

Updated at 2026-08-07T18:06:32.657Z

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Aug 6, 2026
@mmabrouk
mmabrouk changed the base branch from feat/mobile-app-scaffold to release/v0.111.0 August 7, 2026 18:06
@mmabrouk
mmabrouk merged commit ff8ac00 into release/v0.111.0 Aug 7, 2026
62 of 63 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backend Feature Request New feature or request lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants