Skip to content

Conversation

@tgmendes
Copy link
Contributor

@tgmendes tgmendes commented Jan 30, 2026

This adds an endpoint to list chats (by grouping them by chat ID).

First step into having the full view of chat traces.

image
Open with Devin

@tgmendes tgmendes requested a review from a team as a code owner January 30, 2026 21:41
@changeset-bot
Copy link

changeset-bot bot commented Jan 30, 2026

🦋 Changeset detected

Latest commit: 86a54e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@gram/client Patch
server Patch
dashboard Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Jan 30, 2026

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

Project Deployment Actions Updated (UTC)
gram Ready Ready Preview, Comment Jan 30, 2026 10:20pm
gram-docs-redirect Ready Ready Preview, Comment Jan 30, 2026 10:20pm

Request Review

@speakeasybot
Copy link
Collaborator

speakeasybot commented Jan 30, 2026

Preview Environment (PR #1425)

Preview environment scaled down after 12h of inactivity.
Re-add the preview label to restart.

Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 new potential issues.

Open in Devin Review

Comment on lines 423 to 435
HAVING if(
? = '',
true,
if(
? = 'asc',
min(time_unix_nano) > (SELECT min(time_unix_nano) FROM telemetry_logs WHERE gram_chat_id = ? GROUP BY gram_chat_id LIMIT 1),
min(time_unix_nano) < (SELECT min(time_unix_nano) FROM telemetry_logs WHERE gram_chat_id = ? GROUP BY gram_chat_id LIMIT 1)
)
)
ORDER BY
IF(? = 'asc', start_time_unix_nano, 0) ASC,
IF(? = 'desc', start_time_unix_nano, 0) DESC
LIMIT ?

Choose a reason for hiding this comment

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

🔴 ListChats pagination is unstable and can skip/duplicate results because ORDER BY lacks a tie-breaker

ListChats paginates by comparing min(time_unix_nano) against the cursor chat's min(time_unix_nano) and orders only by start_time_unix_nano. If multiple chats share the same min(time_unix_nano) (likely with batched ingestion or coarse timestamps), pagination becomes non-deterministic:

  • Page 1 might end with a chat whose start_time_unix_nano ties with other chats.
  • Page 2 uses >/< on only the timestamp, so tied chats can be skipped (never appear) or duplicated depending on ordering.

Actual: pagination may miss chats or return duplicates across pages.
Expected: deterministic pagination with a stable sort key and cursor that matches the sort.

Evidence
  • Cursor predicate compares only min(time_unix_nano):
    server/internal/telemetry/repo/queries.sql.go:423-431
  • ORDER BY only uses start_time_unix_nano and no secondary key:
    server/internal/telemetry/repo/queries.sql.go:432-435

Recommendation: Add a deterministic tie-breaker to the sort and cursor comparison (e.g., (start_time_unix_nano, gram_chat_id)), and compute next_cursor based on the same composite key (or make cursor a composite token).

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View issue and 5 additional flags in Devin Review.

Open in Devin Review

Comment on lines +414 to +431
FROM telemetry_logs
WHERE gram_project_id = ?
AND time_unix_nano >= ?
AND time_unix_nano <= ?
AND gram_chat_id IS NOT NULL
AND gram_chat_id != ''
AND (? = '' OR gram_deployment_id = toUUIDOrNull(?))
AND if(? = '', true, position(telemetry_logs.gram_urn, ?) > 0)
GROUP BY gram_chat_id
HAVING if(
? = '',
true,
if(
? = 'asc',
min(time_unix_nano) > (SELECT min(time_unix_nano) FROM telemetry_logs WHERE gram_chat_id = ? GROUP BY gram_chat_id LIMIT 1),
min(time_unix_nano) < (SELECT min(time_unix_nano) FROM telemetry_logs WHERE gram_chat_id = ? GROUP BY gram_chat_id LIMIT 1)
)
)

Choose a reason for hiding this comment

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

🟡 Chat cursor subquery is not scoped by project/time filters, making pagination unstable if gram_chat_id is not globally unique

The cursor boundary subquery used in ListChats looks up the cursor chat’s min(time_unix_nano) by gram_chat_id only:

SELECT min(time_unix_nano) FROM telemetry_logs WHERE gram_chat_id = ? GROUP BY gram_chat_id

Actual behavior: if gram_chat_id can collide across projects (or if there are logs for the same gram_chat_id outside the requested time window), the cursor’s start time may be computed from unrelated rows. This makes pagination jump backwards/forwards unexpectedly.

Expected behavior: the cursor lookup should be scoped consistently with the main query (at minimum by gram_project_id, and ideally also by the same time range / filters).

Click to expand

The main query scopes to a project/time window:
WHERE gram_project_id = ? AND time_unix_nano >= ? AND time_unix_nano <= ? ...

But the cursor subquery does not.

Recommendation: Add gram_project_id = ? (and optionally time_unix_nano bounds / same filters) to the cursor subquery so it computes the cursor boundary in the same domain as the main result set.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@speakeasybot speakeasybot removed the preview Spawn a preview environment label Jan 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants