Composio 平台分页指南:端点级限制与 cursor 分页的完整实践
本指南以 Composio 平台的官方分页文档为核心,讲解其“分页上限随端点而定”的设计原则,并以 auth configs 列表接口(GET /api/v3/auth_configs 与 GET /api/v3.1/auth_configs)为实例,深入说明如何通过 next_cursor 驱动的 cursor 分页完整遍历数据。读完本文,你将掌握 Composio 各资源列表的正确分页姿势、SDK 内置的分页工具用法,以及如何规避文档描述与实际部署行为不一致的坑。
核心原则:分页限制是端点特定的
Composio 平台不存在一个全局统一的 page-size 上限。资源列表、目录、Tool Router、日志、计费(billing)等不同类别的端点,可以各自定义不同的单页大小;而 toolkit 的 actions 还会额外继承 provider(第三方服务商)特定的分页规则。
因此,在接入任何列表接口之前,正确做法是:
- 先检查该端点的精确 schema(字段定义、是否携带
cursor/limit参数); - 再通过真实请求验证线上行为(实际返回多少条、
next_cursor何时为空); - 最后才在代码里固化分页假设——不要凭经验假设“所有接口都是每页 100 条”或“所有接口都支持同样的 limit”。
这条原则在 SDK 源码中同样有体现:Composio 的 TypeScript SDK 在 ts/packages/core/src/utils/pagination.ts 中封装了统一的 getAllPages 工具,它内部固定以 limit: 100 发起请求(MAX_LIMIT_ALLOWED_BY_API = 100),并通过 next_cursor 不断翻页直到取完。也就是说:客户端默认请求 100 条,但服务端端点仍可能按自己的上限钳制返回数量——这正是“端点特定限制”在客户端与服务端两侧的完整表现。
auth configs 列表:每页最多 50 条
文档明确给出了当前(2026-07-16 时间戳标注的公开指南)实测限制:
GET /api/v3/auth_configs:每页最多返回 50 个 auth configs;GET /api/v3.1/auth_configs:同样最多返回 50 个。
(对应中文文档:docs/kb/source/platform/pagination/public.md,平台分页总览见 docs/api-overviews/auth-configs.mdx。)
必须完成的翻页循环
拿到每一页响应后,需要:
- 从响应中读取
next_cursor字段; - 将其作为下一次请求的
cursor查询参数传入; - 重复以上两步,直到
next_cursor为空(null/undefined/ 空字符串)为止。
伪代码形态如下:
cursor = null
loop:
response = GET /api/v3/auth_configs?cursor=<cursor>
process(response.items)
if response.next_cursor is empty: break
cursor = response.next_cursor
文档/运行时不一致:不要跳过 cursor 分页
部分由 schema 自动生成的接口描述文档,可能宣称 auth_configs 接口支持更大的单页限制(例如 100 甚至更多)。但已部署的端点仍会把每一页钳制到 50 条。
文档给出的处理建议是:把这种“文档宣传值 > 运行时实际值”的偏差视为产品问题(product issue),在集成侧则把它当作一个明确信号——绝不能因为文档写着更大的 limit 就跳过 cursor 分页。正确姿势永远是:信任 next_cursor,逐页拉取,直到游标耗尽。
从源码理解 cursor 分页的完整链路
TypeScript SDK:getAllPages 的类型安全翻页工具
Composio 的 TypeScript SDK 在 ts/packages/core/src/utils/pagination.ts 提供了开箱即用的全量拉取工具 getAllPages:
export async function getAllPages<TFn extends (
params: PaginationParams
) => Promise<{ items: Array<unknown>; next_cursor?: string | null }>,
>(fetchFn: TFn): Promise<Array<ExtractItemType<Awaited<ReturnType<TFn>>>>> {
const allItems = [];
let cursor: string | null | undefined = undefined;
const MAX_LIMIT_ALLOWED_BY_API = 100;
while (true) {
const params = {
...(cursor !== undefined && { cursor }),
limit: MAX_LIMIT_ALLOWED_BY_API,
};
const response = await fetchFn(params);
allItems.push(...response.items);
if (!response.next_cursor) break; // 游标为空即停止
cursor = response.next_cursor;
}
return allItems;
}
它的关键行为(与单元测试一一对应):
- 首次请求不携带
cursor,只带limit: 100(测试should not include cursor in first request); - 后续请求携带
cursor,值为上一页的next_cursor(测试should include cursor in subsequent requests); next_cursor为null或undefined均视为翻页结束(should stop pagination when next_cursor is null等用例);- 支持空
items但仍有游标、游标含特殊字符、超长游标、多页合并后保持元素顺序等边界场景; - 请求抛错时异常会向上传播,由调用方处理重试与错误(
should handle async fetch function errors)。
典型用法(来自该文件注释中的示例):
import { getAllPages } from './utils/pagination';
// 拉取全部工具列表,类型自动推断
const allTools = await getAllPages((params) =>
client.tools.list({
...params,
tool_slugs: 'tool1,tool2',
})
);
值得注意:getAllPages 请求 limit: 100,但 auth_configs 端点实际返回 50 条——这一组合正好印证了文档反复强调的“端点限制优先于客户端请求值”,SDK 靠游标机制保证了无论服务端返回多少条都不会丢数据。
响应字段的蛇形/驼峰转换
auth configs 列表响应的原始字段是蛇形命名(snake_case),SDK 在 ts/packages/core/src/utils/transformers/authConfigs.ts 中将其转换为 SDK 风格:
export function transformAuthConfigListResponse(response) {
return {
items: response.items.map(transformAuthConfigRetrieveResponse),
nextCursor: response.next_cursor ?? null, // next_cursor -> nextCursor
totalPages: response.total_pages,
};
}
也就是说,直接调用 HTTP API 时你看到的是 next_cursor / total_pages;而通过 TypeScript SDK 的高层接口使用时,字段名会变成 nextCursor / totalPages。理解这一层转换,能避免在“读 SDK 文档”与“读 OpenAPI 文档”之间切换时产生困惑。
Python SDK:透传 cursor 查询参数
Python SDK 侧,auth configs 的列表操作定义在 python/composio/core/models/auth_configs.py:
class AuthConfigs(Resource):
def list(self, **query: te.Unpack[auth_config_list_params.AuthConfigListParams]):
"""Lists authentication configurations based on provided filter criteria."""
return self._client.auth_configs.list(**query)
list() 将 cursor、limit 等查询参数原样透传给底层 HTTP 客户端,因此分页循环在 Python 中同样遵循“把上一页 next_cursor 作为下一页 cursor”的通用模式:
from composio import Composio
client = Composio()
cursor = None
all_configs = []
while True:
response = client.auth_configs.list(cursor=cursor, limit=50)
all_configs.extend(response.items)
if not response.next_cursor:
break
cursor = response.next_cursor
同样的 cursor 模式也贯穿其他资源:例如 Tool Router 的会话文件列表在 python/composio/core/models/tool_router_session_files.py 中接收 cursor 参数并返回 FileListResponse(含 items 与 next_cursor);Tool Router 会话列表在 python/composio/core/models/tool_router_session.py 中同样基于 next_cursor 做多页拼装。
实战检查清单
无论使用 REST 直连还是 SDK,接入任意 Composio 列表接口时建议按以下清单核对:
- 确认端点上限:查阅该端点的 schema 或实际发一次请求,记录真实单页条数(如 auth_configs 为 50);
- 携带游标翻页:每一页都读取
next_cursor(SDK 侧为nextCursor),非空则作为cursor继续请求,直到游标为空; - 不要硬编码信任文档数字:若文档声称的 limit 大于实际返回条数,以运行时行为为准,并把偏差反馈为产品问题;
- 边界场景自测:空列表、单页即止、恰好一页满、多页数据、游标特殊字符等情况,均可参考 ts/packages/core/test/utils/pagination.test.ts 中的用例设计自己的测试;
- 优先复用 SDK 工具:TypeScript 侧可直接使用
getAllPages完成全量拉取,避免手写循环遗漏终止条件。
小结
Composio 的分页设计围绕“端点特定限制 + cursor 游标翻页”展开:没有全局 page-size,auth configs 列表实测每页 50 条,Tool Router、日志、计费等其他端点则各有各的规则。无论文档如何描述,正确的集成方式始终是信任 next_cursor 并完整翻页——这一点既有官方文档背书(docs/kb/source/platform/pagination/public.md),也有 SDK 源码与测试用例的完整实现佐证,是构建可靠、不丢数据的 Agent 集成的基础能力。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.2 K634
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown300
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java101
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java60
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript60
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python280