Corsair Exist 插件指南:接入 Exist.io 个人数据 API,打通 Agent 与用户量化自我数据

发布时间:2026/9/16 14:28:45
Corsair Exist 插件指南:接入 Exist.io 个人数据 API,打通 Agent 与用户量化自我数据 Corsair Exist 插件指南接入 Exist.io 个人数据 API打通 Agent 与用户量化自我数据【免费下载链接】corsairConnect your users to their apps项目地址: https://gitcode.com/GitHub_Trending/corsa/corsair导读本文围绕 corsair-dev/exist 插件展开讲解如何通过 Corsair 把 AI Agent 接入 Exist.io 的个人数据平台——读取用户的活动、睡眠、情绪、健康等属性分析平均值、相关性与洞察并基于属性所有权机制安全地写入数据。读完本文你将掌握该插件的全部 13 个端点、OAuth 2.0 授权流程、作用域scope与权限配置以及底层请求、限流、错误处理与本地持久化机制可直接在自己的 Corsair 项目中落地 Exist 集成。一、插件概览与安装Exist 是一个量化自我Quantified Self平台用户将 Fitbit、Apple Health、Strava、银行、天气等数据源汇聚起来形成以日为粒度的个人属性attributes再由平台计算周平均值、属性间相关性和自然语言洞察。Corsair 通过corsair-dev/exist插件把整条 Exist API v2 封装成一组类型安全、带风险分级、可持久化、可被 Agent 调用的端点。插件以标准 npm 包形式发布使用 pnpm 安装pnpm add corsair-dev/exist从 package.json 可以看到该插件以corsair0.1.0与zod^4.1.13为 peer 依赖构建产物为 ESM 的dist/index.js同时导出类型声明dist/index.d.ts。仓库内以 workspace 方式开发corsair: workspace:*也提供了build、typecheck、test三个脚本。二、端点全景13 个操作README 给出了完整的端点清单。根据 index.ts 中existEndpointsNested的注册结构这些端点按命名空间组织为users、attributes、averages、correlations、insights、oauth六组共 13 个操作。每个操作都带有操作 ID、风险等级read/write与描述并通过 endpointMeta 与 endpointSchemas 绑定 Zod 输入输出校验。2.1 用户与认证操作操作 ID风险说明users.getProfileexist.api.users.getProfileread获取已认证 Exist 用户的资料与单位偏好oauth.authorizeexist.api.oauth.authorizeread构造用户访问授权的 Exist OAuth2 授权 URL携带 CSRF state 值不发起任何 API 调用users.getProfile对应 GET/api/2/accounts/profile/响应由 ExistProfileSchema 校验包含用户名、时区、本地时间以及五组英制单位偏好距离、重量、能量、液体、温度还包含trial、delinquent等账户状态字段。oauth.authorize是一个本地构造操作它不访问网络而是用已配置的client_id、redirect_url、作用域和随机生成的state组装出授权 URL详见下文授权流程。2.2 属性attributes——插件的核心操作操作 ID风险说明attributes.listexist.api.attributes.listread列出用户的属性不包含值attributes.listOwnedexist.api.attributes.listOwnedread列出当前客户端已拥有的属性attributes.listTemplatesexist.api.attributes.listTemplatesread列出 Exist 支持的属性模板attributes.listWithValuesexist.api.attributes.listWithValuesread列出用户属性及其最近若干天的值attributes.acquireexist.api.attributes.acquirewrite取得属性所有权以便本客户端写入其值用户尚不存在的模板属性会被自动创建attributes.releaseexist.api.attributes.releasewrite释放属性所有权移交给其他服务或使其失效attributes.incrementexist.api.attributes.incrementwrite对已拥有属性在指定日期的值增加一个增量attributes.updateexist.api.attributes.updatewrite覆写已拥有属性在指定日期的总值单批最多 35 条属性所有权是 Exist 写入模型的核心要写入一个属性的值客户端必须先acquire获得该属性的所有权。源码中 AcquireAttributeSchema 要求每条记录要么提供template模板名如mood不存在则自动创建要么提供name已存在的属性名二者必居其一并可附带manual: true标记为手动更新。四个写操作的行为差异值得注意见 attributes.tsupdate是覆写当日总值UpdateAttributeSchema 强调 Exist 不会接受用一个null去覆盖已有非空值的属性以防误删数据。increment是增量累加适合步数、卡路里这类持续累加的指标客户端无需自己维护当日累计值但 IncrementAttributeSchema 注明字符串、scale、time-of-day 类型的属性无法增量且date缺省时使用用户当前日期。所有写操作的批量上限统一为 EXIST_MAX_BATCH_SIZE 35输入 schema 用.min(1).max(EXIST_MAX_BATCH_SIZE)强制约束。2.3 派生分析averages / correlations / insights操作操作 ID风险说明averages.listexist.api.averages.listread列出每个属性的周平均值correlations.listexist.api.correlations.listread列出 Exist 计算的用户属性之间的相关性insights.listexist.api.insights.listread列出 Exist 基于用户数据生成的洞察这三组操作是 Exist 相比普通可穿戴数据接口最有价值的部分averages.list返回每个属性按周周一至周日 总体overall统计的平均值支持date_min/date_max日期区间过滤与include_historical历史回溯开关见 AveragesListInputSchema。correlations.list返回两两属性间的 Pearson 相关系数value-1 到 1、p 值、置信星级stars1-5与强弱描述可用strong只返回强相关、confident只返回五星最可信相关和attribute只返回涉及某属性的相关过滤见 CorrelationsListInputSchema。insights.list返回 Exist 生成的文本/HTML 洞察可用date_min、date_max与priority1 为今天、4 为上个月过滤见 InsightsListInputSchema。三个列表的limit上限为 100CappedLimitSchema且所有列表响应都遵循统一的{ count, next, previous, results }分页信封paged()。三、授权OAuth 2.0 与作用域管理README 明确Auth: OAuth 2.0Corsair 会在首次使用时向你的租户索要凭据。插件把 OAuth 配置集中定义在 existAuthConfig账户维度tenant_external_id与oauthConfigindex.tsoauthConfig: { providerName: Exist, authUrl: EXIST_OAUTH_AUTHORIZE_URL, // https://exist.io/oauth2/authorize tokenUrl: EXIST_OAUTH_TOKEN_URL, // https://exist.io/oauth2/access_token scopes: options.scopes ?? EXIST_DEFAULT_SCOPES, requiresRegisteredRedirect: true, // Exist 要求回调 URI 预先注册且必须为 HTTPS tokenAuthMethod: body, // 客户端凭据放在请求体 }3.1 作用域ScopesExist 的作用域按属性分组组织每组同时有读、写两个版本。插件将其静态导出index.ts读作用域17 个activity_read、productivity_read、mood_read、sleep_read、workouts_read、events_read、finance_read、food_read、health_read、location_read、media_read、social_read、weather_read、symptoms_read、medication_read、custom_read、manual_read。写作用域17 个与读作用域一一对应的*_write版本用于 acquire / release / increment 相应分组的属性。默认情况下插件请求全部 34 个作用域EXIST_DEFAULT_SCOPES。但 Exist 官方建议只请求集成真正需要的作用域因此插件选项scopes允许收窄exist({ scopes: [sleep_read, activity_read], // 只读 sleep 与 activity })注意Exist 只会向你暴露与已授权作用域匹配的属性所以作用域越窄Agent 能看到的属性越少——这既是权限收敛也是数据最小化的手段。3.2 授权 URL 的构造oauth.authorize端点的完整实现见 oauth.ts。它按 Exist 官方流程构造response_typecode、client_id、redirect_uri、空格分隔的scope与state参数。源码在构造前做了三道防御性校验未配置client_id或redirect_url直接报错提示先到集成凭据中配置强制要求redirect_url以https://开头——因为 Exist 拒绝非 HTTPS 回调提前失败比把用户送到必然报错的授权页更好若最终作用域为空未配置且未传参则报错。state用crypto.randomUUID()生成作为标准的 OAuth2 CSRF 防护调用方需要保存它并在 Exist 重定向回redirect_url时比对回传的state。该端点返回{ url, state, scopes }事件日志只记录scopeCount避免把 client_id 和回调地址写进持久化日志。3.3 Token 的获取、刷新与直传插件通过keyBuilderindex.ts决定每次请求使用的访问令牌若在插件选项中传入了key且来源是endpoint则直接使用该预取令牌绕过 Corsair 存储的凭据否则在oauth_2模式下调用getOAuthAccessToken向https://exist.io/oauth2/access_token换取令牌tokenAuthMethod: body表示客户端凭据放在请求体若既无 key 又不是 OAuth 模式则抛出AuthMissingError。此外makeAuthenticatedExistRequest 实现了401 自动续期重试一旦请求返回 401令牌被吊销或过期会先通过_refreshAuth重新铸造一次令牌再重试。四、底层请求管线限流、批处理与错误处理所有端点最终都收敛到 makeExistRequest它基于corsair/http的request发起请求Base URL 为https://exist.io/api/2携带Authorization: Bearer token与Content-Type: application/json写操作POST的 body 是顶层 JSON 数组读操作GET不带 body。4.1 限流策略Exist 官方限制为每个用户令牌每小时 300 次请求超限时返回无响应体的429 Too Many Requests。插件在 client.ts 中对读写请求配置了差异化限流GET 请求启用限流最多重试 3 次初始退避 1000ms、退避倍数 2并识别retry-after、x-ratelimit-reset、x-ratelimit-remaining、x-ratelimit-limit响应头POST 写请求限流关闭、不重试——写操作重试有重复写入的风险宁可失败也不要幂等性不明的重放。4.2 参数序列化细节client.ts 暴露了两个容易被忽略的序列化规则toCommaListgroups、attributes、templates等数组过滤参数会以逗号分隔字符串发送toFlagstrong、confident、include_historical这类开关参数只有传true时才会以1出现在查询串中——因为 Exist 文档只定义了发1开启发0关闭是未定义行为所以false直接丢弃参数compactQuery统一剔除undefined项避免脏查询串。4.3 错误处理插件内置了一套错误分类处理器error-handlers.ts并在 index.ts 中允许通过options.errorHandlers覆盖或追加分类匹配条件处理策略RATE_LIMIT_ERROR429 或消息含too many requests/rate limit/429不重试按Retry-After头退避AUTH_ERROR401 或消息含unauthorized/invalid_token不重试记录警告令牌缺失/过期/吊销PERMISSION_ERROR403 或消息含forbidden/permission不重试提示检查 OAuth 作用域与属性所有权NOT_FOUND_ERROR404 或消息含not found不重试记录警告DEFAULT兜底记录错误不重试所有网络与 HTTP 错误最终都会被包装为统一的 ExistAPIError携带status、body与retryAfter字段响应体校验失败也会抛出该错误makeExistRequest中对outputSchema.safeParse失败的兜底。五、本地持久化为 Agent 缓存 Exist 数据Exist 数据以日为粒度变化分页读取代价高因此插件把值得缓存的实体镜像到本地数据库且持久化是 best-effort——本地写入失败绝不影响已成功的 API 读取。持久化逻辑在 persist.tspersistAttributes把attributes.list/listOwned返回的属性定义按nameupsert 到ctx.db.attributespersistAttributesWithValues在属性定义之外把listWithValues返回的每日值按attribute:date复合主键 upsert 到ctx.db.attributeValuesusers.getProfile端点内还会把资料按usernameupsert 到ctx.db.profile见 users.ts。对应的本地实体 schema 定义在 schema/database.ts共六类ExistProfile按用户名、ExistAttribute按 ASCII name、ExistAttributeValue按attribute:date、ExistAverage按attribute:date、ExistCorrelation按attribute:attribute2:date因为相关每周重新生成生成日期属于身份的一部分、ExistInsight按type name:target date。值得一提的是写操作的隐私处理在attributes.increment/update的操作日志中插件刻意不记录具体数值——属性值属于个人敏感分析数据日志只保留{ count, attributes, dates }形式的批处理摘要writeBatchSummary既能追溯操作又避免敏感值落库。六、权限配置约束 Agent 的读写边界插件选项中的permissions基于端点树使用点号路径dot-notation配置无效路径会在编译期报类型错误index.tsexist({ permissions: { // 只允许读取禁止一切写入 attributes.acquire: false, attributes.release: false, attributes.increment: false, attributes.update: false, }, })结合每个端点的riskLevelread/write元数据见 index.ts推荐的安全基线是Agent 只读场景禁用全部 4 个写端点需要写数据时再按业务需要放开acquire→increment/update→release的最小链路。七、Webhooks 与触发机制README 明确No webhooks.这一点在源码中得到印证——existWebhooksNested 被定义为空对象注释说明Exist 没有 webhook 或回调机制因此插件不暴露任何触发器插件的webhookHooks、webhookSchemas、pluginWebhookMatcher全部为undefined。这意味着 Agent 无法被 Exist 事件实时唤醒需要依赖定时轮询或按需调用拉取数据。八、快速上手示例综合以上机制一个最小可用集成的骨架如下import { exist } from corsair-dev/exist; import { corsair } from corsair; const app corsair({ plugins: [ exist({ // 只申请需要的分组遵循 Exist 最小作用域建议 scopes: [sleep_read, mood_read], // 按需收窄 Agent 权限例如禁止一切写入 permissions: { attributes.acquire: false, attributes.release: false, attributes.increment: false, attributes.update: false, }, }), ], });接入后Agent 可依次调用exist.users.getProfile—— 确认用户身份与单位偏好exist.oauth.authorize—— 若需授权获得授权 URL 与state完成 OAuth 2.0 授权码流程exist.attributes.listWithValues—— 拉取睡眠、情绪等属性的近期日值days最大 31默认 1exist.averages.list/exist.correlations.list/exist.insights.list—— 获得周均值、属性相关性与可读洞察作为 Agent 分析回答的事实依据如需写入先exist.attributes.acquire取得所有权再以每批 ≤ 35 条调用exist.attributes.increment累加或exist.attributes.update覆写。九、测试与验证仓库为该插件提供了完整的测试保障可自行运行验证api.test.ts —— 端点级行为测试error-handlers.test.ts —— 错误分类与重试策略测试schema.test.ts —— 本地实体 schema 测试validation.test.ts —— Zod 输入校验测试如attributes/templates互斥、日期合法性、批量上限等。运行pnpm test或pnpm typecheck即可在本地复现。这些测试与 README、index.ts、endpoints/types.ts 共同构成了理解该插件行为最权威的参考资料。十、小结corsair-dev/exist把 Exist.io 的属性 所有权数据模型完整映射为 13 个类型安全、风险分级的 Corsair 端点读侧覆盖属性、周均值、相关性与洞察写侧通过 acquire/release/increment/update 四件套实现受控的数据回写OAuth 2.0 授权、最小作用域、批量上限35、小时限流300与 401 自动续期等细节都在源码层做了硬化处理。它没有 webhook 触发能力适合轮询或按需调用的 Agent 集成场景是 Corsair 生态中把个人数据分析能力交给 AI Agent 的现成方案。【免费下载链接】corsairConnect your users to their apps项目地址: https://gitcode.com/GitHub_Trending/corsa/corsair创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考