promote: test → main (GET /api/ai/models)#498
Conversation
* chore: update Prettier configuration and add new dependencies
- Added "endOfLine": "lf" to the Prettier configuration for consistent line endings.
- Introduced "stripe" and "uuid" packages in package.json for enhanced functionality.
- Updated pnpm-lock.yaml to reflect the addition of new dependencies.
* refactor(stripe): rename mapToSubscriptionSessionErrorResponse to mapToSubscriptionSessionError
- Updated the function name from `mapToSubscriptionSessionErrorResponse` to `mapToSubscriptionSessionError` for consistency and clarity.
- Adjusted import statements and references in related files to reflect the new function name.
* fix(tests): update ACCOUNT UUID in route.test.ts for consistency
- Changed the ACCOUNT constant in route.test.ts from "123e4567-e89b-12d3-a456-426614174000" to "123e4567-e89b-12d3-a456-426614174001" to ensure consistency in test cases.
* feat(stripe): add STRIPE_SK environment variable and improve error handling
- Introduced the STRIPE_SK environment variable in .env.example to ensure proper configuration for Stripe integration.
- Updated the Stripe client initialization to throw an error if STRIPE_SK is not set, enhancing robustness.
- Modified error handling in createSubscriptionSessionHandler to return a 500 status with a generic error message for internal server errors.
- Adjusted validation logic in validateCreateSubscriptionSessionRequest to remove the optional accountId field, simplifying the request structure.
- Enhanced mapToSubscriptionSessionError to mask upstream error messages for 5xx responses, improving security.
- Updated tests to reflect changes in error handling and validation logic.
* fix(connectors): unify action catalog and execution paths for consistent access
- Merged shared and artist toolkits into the actions catalog to ensure all executable actions are listed, reflecting the full access available to the chat agent.
- Updated the executeConnectorAction function to also utilize the merged toolkit, ensuring that all actions listed in the catalog are executable.
- Extracted ConnectorActionNotFoundError into a separate file for cleaner error handling and improved test organization.
- Rewritten tests to mock the new toolkit structure, ensuring comprehensive coverage of the updated functionality.
* feat(stripe): refactor createStripeSession to use configuration constants
- Updated createStripeSession to utilize STRIPE_SUBSCRIPTION_PRICE_ID and STRIPE_SUBSCRIPTION_TRIAL_PERIOD_DAYS constants for better maintainability and configuration management.
- Enhanced tests for createStripeSession to reflect these changes, ensuring consistency in the subscription parameters.
- Improved error handling in client tests by refining the management of the STRIPE_SK environment variable.
* chore: remove .gitattributes and update Prettier configuration
- Deleted the .gitattributes file to simplify project configuration.
- Updated .prettierrc by removing the "endOfLine" setting for cleaner formatting consistency.
* chore(stripe): drop uuid dep, use accountId as client_reference_id
YAGNI: client_reference_id is a soft-convenience pointer string with no
readers in either api or chat — never round-trips, never queried via the
sessions.list API (it isn't a filterable param). The migration was
generating a throwaway random uuid that mapped to nothing internally.
Setting it to accountId instead:
- removes the uuid dep entirely (only callsite in this repo)
- makes the Stripe dashboard's "Client reference" column actually
useful for support/debugging
- matches metadata.accountId so reconciliation is consistent
Drop the uuid mock from createStripeSession.test.ts and flip the
not.toBe("acc-1") assertion to toBe("acc-1") — encoding the new
contract instead of the old "value must be a random UUID" stance.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Sweets Sweetman <sweetmantech@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(api): migrate misc-reads endpoints (email, ai/models, youtube/channel-info)
Adds api parity for chat's /api/email, /api/ai/models, /api/youtube/channel-info
ahead of the chat-side cutover.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(api): address AI review on misc-reads PR
- updateContact: switch to loops v6 object-arg signature (fixes Vercel build)
- handlers: stop leaking raw exception text in 500 responses
- loopsClient: convert singleton to factory function matching filename
- youtubeErrors: align export name with filename
- getYouTubeChannelHandler: explicit boolean discriminator narrowing for build
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(api): change /api/email from GET to POST
Email tracking upserts a Loops contact — a write — so it should not be
exposed as GET with email in query params (PII in URLs, cacheable
responses). Switches to POST with `{ email }` JSON body.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* revert(api): drop /api/email endpoint
Loops is no longer used; the email tracking endpoint is removed
from this migration entirely.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(api): simplify youtube channel-info flow
- Fold token validation into validateYouTubeChannelInfoRequest so the
handler is a thin fetch+respond orchestrator
- Rename validateYouTubeChannelQuery → validateYouTubeChannelInfoRequest
(matches validateArtistRequest / validateChatRequest convention)
- Drop buildYouTubeUtilityError + error code catalog: every token-level
failure collapses to the same {success:false, tokenStatus:"invalid"}
response, so the typed codes carried no information out
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(api): throw from youtube libs, single catch at validator
- refreshStoredYouTubeToken now throws on every failure (no more
catch-log-return-null); the deep invalid_grant type guard is gone
since the general console.error already logs the full error
- validateYouTubeTokens lets errors propagate; null is reserved for
the legitimate "no tokens row / no refresh_token" cases
- validateYouTubeChannelInfoRequest is the single catch boundary;
thrown errors and null both collapse to the same tokenStatus:invalid
response, matching chat parity
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(api): drop redundant explicit return types from misc-reads libs
TS inference already produces the same types for these helpers; explicit
annotations were noise. Kept annotations on discriminated-union returns
(validators, route handlers) and anywhere inference would widen.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(api): drop more redundant return types from misc-reads libs
Continues 7f64027 — TS inference produces the same types for these
helpers; explicit annotations were noise. Kept the discriminated-union
annotation on validateYouTubeChannelInfoRequest where it documents an
intentional contract.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(api): slim youtube channel-info response and validator
- drop response fields that no chat consumer reads
- validateYouTubeTokens throws on every unusable case; the request
validator's catch is the single failure boundary (no more let/null)
- drop now-unnecessary explicit return types
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(api): trim youtube tests, jsdocs, type duplication, response
- Drop `success` from /api/youtube/channel-info; conform to the
`{ status: "success", channels }` envelope used across the rest of
the api (lib/networking/successResponse.ts, songs, posts, accounts,
chats, artists). Clients infer "needs re-auth" from
`channels === null`.
- Keep only validator + handler tests; cover no-token, expired-no-refresh,
refresh-failure, and db-update-failure cases at the validator boundary
via it.each on the thrown-error contract.
- Trim jsdocs to information-bearing lines only; drop stale
"mirrors chat" notes and self-evident @param/@returns lines on lib
helpers.
- Dedupe YouTubeTokensRow: keep the export in validateYouTubeTokens.ts
(the contract owner) and import it in refreshStoredYouTubeToken.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(api): return proper status codes for youtube channel-info errors
- 401 + {status:"error",message} when stored YouTube tokens can't be
validated/refreshed (re-auth needed)
- 502 + {status:"error",message} for upstream YouTube API failures
- Drops the inconsistent "200 status:success channels:null" shape
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(api): drop YouTubeTokensRow alias and return type
validateYouTubeTokens lets TS infer the return type; the alias is gone
(only refreshStoredYouTubeToken used it, now inlined as Tables<>).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(api): bypass @ai-sdk/gateway SDK for model catalog
The SDK's getAvailableModels() rejects valid responses with a Zod error
("expected error.object"), which silenced 194 models behind an empty
array. Match chat's direct fetch to /v1/ai/config — same approach,
same payload, same parity.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(api): pin @ai-sdk/gateway to 2.x for catalog reads
The 3.x SDK requires specificationVersion:"v3" via a strict Zod literal,
but the live /v1/ai/config endpoint still emits "v2" descriptors. Pin
to 2.0.83 (latest 2.x, expects "v2") so gateway.getAvailableModels()
works as designed. This is a catalog-read-only consumer; api never uses
gateway() as a model factory, so 2.x's LanguageModelV2 surface doesn't
collide with the rest of the codebase on @ai-sdk/provider@3.
Restore the SDK call site (no more direct fetch hack); a comment
flags when to bump back to 3.x.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(api): drop redundant jsdoc on getAvailableModels
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(api): restore original jsdoc on getAvailableModels
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(api): gate /api/youtube/channel-info behind auth + artist access
Layers in validateAuthContext + checkAccountArtistAccess so anonymous
callers can no longer probe stored YouTube tokens by guessing UUIDs.
Returns 401 on missing/invalid auth, 403 when the authed caller has no
access to the requested artist.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* revert(api): drop /api/youtube/channel-info from this migration
YouTube channel-info will migrate via Composio in a separate PR.
Reduces Group 1 scope to just /api/ai/models.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Sweets Sweetman <sweetmantech@gmail.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (4)
📒 Files selected for processing (3)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Review rate limit: 0/1 reviews remaining, refill in 22 minutes and 26 seconds.Comment |
Promotes #491 (GET /api/ai/models migration) from `test` to `main`.
New content vs main
(The other commits showing on the diff — `7d4611c` and `d74037b` — are the already-promoted #493 and the test-from-main sync merge; their tree content is already on main via squash commit `bea4d3e5`.)
Verification
PR #491 was manually verified end-to-end on its preview deployment — see #491 (comment) for the full test results: 6/6 cases pass, 194 model ids identical to chat prod, response shape matches the documented contract at developers.recoupable.com/api-reference/ai/models exactly.
Notes
The api uses `@ai-sdk/gateway 2.0.83`; chat uses `^3.0.96`. The newer 3.x adds a `tags` field per model that api doesn't return. Not consumed by any chat code path (verified). Optional follow-up to bump api's gateway if exact byte-parity is desired.