Skip to content

Commit 9daf9c3

Browse files
committed
feat: add cursor-based pagination support for messages
BREAKING CHANGE: messages.list() now returns PaginatedMessagesResponse with {data, next_cursor, has_more} instead of list[TaskMessage]. Changes: - Add cursor and direction params to MessageListParams - Add PaginatedMessagesResponse type with data, next_cursor, has_more - Update list() method signature in Messages resource - Update tests for new response format
1 parent 3a64af1 commit 9daf9c3

File tree

5 files changed

+130
-8
lines changed

5 files changed

+130
-8
lines changed

src/agentex/resources/messages/messages.py

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,11 @@ def list(
181181
*,
182182
task_id: str,
183183
limit: int | Omit = omit,
184+
cursor: str | Omit = omit,
185+
direction: str | Omit = omit,
184186
page_number: int | Omit = omit,
187+
order_by: str | Omit = omit,
188+
order_direction: str | Omit = omit,
185189
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
186190
# The extra values given here take precedence over values defined on the client or passed to this method.
187191
extra_headers: Headers | None = None,
@@ -190,18 +194,47 @@ def list(
190194
timeout: float | httpx.Timeout | None | NotGiven = not_given,
191195
) -> MessageListResponse:
192196
"""
193-
List Messages
197+
List Messages with cursor-based pagination.
198+
199+
Returns messages for a task with pagination metadata.
200+
Use the `next_cursor` from the response to fetch the next page.
194201
195202
Args:
196203
task_id: The task ID
197204
205+
limit: Maximum number of messages to return (default: 50)
206+
207+
cursor: Opaque cursor string for pagination. Pass the `next_cursor` from
208+
a previous response to get the next page.
209+
210+
direction: Pagination direction - "older" to get older messages (default),
211+
"newer" to get newer messages.
212+
213+
page_number: [DEPRECATED] Use cursor instead. Page number for offset pagination.
214+
215+
order_by: Field to order by (default: created_at)
216+
217+
order_direction: Order direction - "asc" or "desc" (default: desc)
218+
198219
extra_headers: Send extra headers
199220
200221
extra_query: Add additional query parameters to the request
201222
202223
extra_body: Add additional JSON properties to the request
203224
204225
timeout: Override the client-level default timeout for this request, in seconds
226+
227+
Example:
228+
# First request
229+
response = client.messages.list(task_id="xxx", limit=50)
230+
231+
# Next page
232+
if response.has_more:
233+
next_page = client.messages.list(
234+
task_id="xxx",
235+
limit=50,
236+
cursor=response.next_cursor
237+
)
205238
"""
206239
return self._get(
207240
"/messages",
@@ -214,7 +247,11 @@ def list(
214247
{
215248
"task_id": task_id,
216249
"limit": limit,
250+
"cursor": cursor,
251+
"direction": direction,
217252
"page_number": page_number,
253+
"order_by": order_by,
254+
"order_direction": order_direction,
218255
},
219256
message_list_params.MessageListParams,
220257
),
@@ -370,7 +407,11 @@ async def list(
370407
*,
371408
task_id: str,
372409
limit: int | Omit = omit,
410+
cursor: str | Omit = omit,
411+
direction: str | Omit = omit,
373412
page_number: int | Omit = omit,
413+
order_by: str | Omit = omit,
414+
order_direction: str | Omit = omit,
374415
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
375416
# The extra values given here take precedence over values defined on the client or passed to this method.
376417
extra_headers: Headers | None = None,
@@ -379,18 +420,47 @@ async def list(
379420
timeout: float | httpx.Timeout | None | NotGiven = not_given,
380421
) -> MessageListResponse:
381422
"""
382-
List Messages
423+
List Messages with cursor-based pagination.
424+
425+
Returns messages for a task with pagination metadata.
426+
Use the `next_cursor` from the response to fetch the next page.
383427
384428
Args:
385429
task_id: The task ID
386430
431+
limit: Maximum number of messages to return (default: 50)
432+
433+
cursor: Opaque cursor string for pagination. Pass the `next_cursor` from
434+
a previous response to get the next page.
435+
436+
direction: Pagination direction - "older" to get older messages (default),
437+
"newer" to get newer messages.
438+
439+
page_number: [DEPRECATED] Use cursor instead. Page number for offset pagination.
440+
441+
order_by: Field to order by (default: created_at)
442+
443+
order_direction: Order direction - "asc" or "desc" (default: desc)
444+
387445
extra_headers: Send extra headers
388446
389447
extra_query: Add additional query parameters to the request
390448
391449
extra_body: Add additional JSON properties to the request
392450
393451
timeout: Override the client-level default timeout for this request, in seconds
452+
453+
Example:
454+
# First request
455+
response = await client.messages.list(task_id="xxx", limit=50)
456+
457+
# Next page
458+
if response.has_more:
459+
next_page = await client.messages.list(
460+
task_id="xxx",
461+
limit=50,
462+
cursor=response.next_cursor
463+
)
394464
"""
395465
return await self._get(
396466
"/messages",
@@ -403,7 +473,11 @@ async def list(
403473
{
404474
"task_id": task_id,
405475
"limit": limit,
476+
"cursor": cursor,
477+
"direction": direction,
406478
"page_number": page_number,
479+
"order_by": order_by,
480+
"order_direction": order_direction,
407481
},
408482
message_list_params.MessageListParams,
409483
),

src/agentex/types/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
from .tool_request_content import ToolRequestContent as ToolRequestContent
5151
from .message_create_params import MessageCreateParams as MessageCreateParams
5252
from .message_list_response import MessageListResponse as MessageListResponse
53+
from .message_list_response import PaginatedMessagesResponse as PaginatedMessagesResponse
5354
from .message_update_params import MessageUpdateParams as MessageUpdateParams
5455
from .tool_response_content import ToolResponseContent as ToolResponseContent
5556
from .tracker_list_response import TrackerListResponse as TrackerListResponse

src/agentex/types/message_list_params.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,21 @@ class MessageListParams(TypedDict, total=False):
1212
"""The task ID"""
1313

1414
limit: int
15+
"""Maximum number of messages to return (default: 50)"""
16+
17+
cursor: str
18+
"""Opaque cursor string for pagination. Pass the `next_cursor` from
19+
a previous response to get the next page."""
20+
21+
direction: str
22+
"""Pagination direction - "older" to get older messages (default),
23+
"newer" to get newer messages."""
1524

1625
page_number: int
26+
"""[DEPRECATED] Use cursor instead. Page number for offset-based pagination (default: 1)"""
27+
28+
order_by: str
29+
"""Field to order by (default: created_at)"""
30+
31+
order_direction: str
32+
"""Order direction - "asc" or "desc" (default: desc)"""
Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

3-
from typing import List
4-
from typing_extensions import TypeAlias
3+
from typing import List, Optional
54

5+
from .._models import BaseModel
66
from .task_message import TaskMessage
77

8-
__all__ = ["MessageListResponse"]
8+
__all__ = ["MessageListResponse", "PaginatedMessagesResponse"]
99

10-
MessageListResponse: TypeAlias = List[TaskMessage]
10+
11+
class PaginatedMessagesResponse(BaseModel):
12+
"""Response with cursor pagination metadata."""
13+
14+
data: List[TaskMessage]
15+
"""List of messages"""
16+
17+
next_cursor: Optional[str] = None
18+
"""Cursor for fetching the next page of older messages.
19+
Pass this as the `cursor` parameter in the next request.
20+
None if there are no more messages."""
21+
22+
has_more: bool = False
23+
"""Whether there are more messages to fetch"""
24+
25+
26+
# Alias for backwards compatibility
27+
MessageListResponse = PaginatedMessagesResponse

tests/api_resources/test_messages.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,17 @@ def test_method_list(self, client: Agentex) -> None:
240240
def test_method_list_with_all_params(self, client: Agentex) -> None:
241241
message = client.messages.list(
242242
task_id="task_id",
243-
limit=0,
243+
limit=50,
244+
cursor="eyJ2IjoxLCJpZCI6Im1zZ18xMjMiLCJjcmVhdGVkX2F0IjoiMjAyNC0wMS0xNVQxMDozMDowMCJ9",
245+
direction="older",
244246
page_number=0,
247+
order_by="created_at",
248+
order_direction="desc",
245249
)
246250
assert_matches_type(MessageListResponse, message, path=["response"])
251+
# Response should have data, next_cursor, and has_more
252+
assert hasattr(message, "data")
253+
assert hasattr(message, "has_more")
247254

248255
@pytest.mark.skip(reason="Prism tests are disabled")
249256
@parametrize
@@ -496,10 +503,17 @@ async def test_method_list(self, async_client: AsyncAgentex) -> None:
496503
async def test_method_list_with_all_params(self, async_client: AsyncAgentex) -> None:
497504
message = await async_client.messages.list(
498505
task_id="task_id",
499-
limit=0,
506+
limit=50,
507+
cursor="eyJ2IjoxLCJpZCI6Im1zZ18xMjMiLCJjcmVhdGVkX2F0IjoiMjAyNC0wMS0xNVQxMDozMDowMCJ9",
508+
direction="older",
500509
page_number=0,
510+
order_by="created_at",
511+
order_direction="desc",
501512
)
502513
assert_matches_type(MessageListResponse, message, path=["response"])
514+
# Response should have data, next_cursor, and has_more
515+
assert hasattr(message, "data")
516+
assert hasattr(message, "has_more")
503517

504518
@pytest.mark.skip(reason="Prism tests are disabled")
505519
@parametrize

0 commit comments

Comments
 (0)