-
Notifications
You must be signed in to change notification settings - Fork 56
feat: Pass activeCustomerId through AI Gateway for Stripe Token Billing #2239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Implement Stripe Customer ID header passing for both text generation and embeddings through the AI Gateway. Text generation changes: - Update generationModel function to accept xStripeCustomerId parameter - Add X-Stripe-Customer-ID header to gateway when xStripeCustomerId is provided Embeddings changes: - Add EmbeddingOptions interface with headers parameter - Update EmbedderFunction type to accept optional EmbeddingOptions on embed/embedMany - Support per-request headers in AI SDK embedder implementation This enables per-request customer tracking for Stripe Token Billing, allowing different customer IDs for each generation/embedding request.
Implement end-to-end data flow to pass team's activeCustomerId through the AI Gateway as X-Stripe-Customer-ID header for both text generation and embeddings. Metadata and type changes: - Add activeCustomerId to GenerationMetadata schema - Update TeamForPlan type to include activeCustomerId field Text generation flow: - Pass activeCustomerId from metadata.team to gateway options - Update generate-content-job to include activeCustomerId in schema - Update all job invocation sites to pass activeCustomerId Embeddings flow: - Add xStripeCustomerId parameter to GenerateEmbeddingsOptions - Pass activeCustomerId from telemetry context to embeddings generation - Support customer ID in document ingest process This completes the Stripe Token Billing integration by connecting team.activeCustomerId from the database to the actual LLM and embedding API requests.
|
|
Finished running flow.
|
||||||||||||||||||
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughThe pull request adds the Changes
Sequence DiagramsequenceDiagram
participant Meta as Generation Metadata
participant Ingest as Document Ingest
participant Embed as Embeddings Service
participant Trace as Trace Generation
Meta->>Ingest: telemetryContext.team{id, activeCustomerId, ...}
Ingest->>Embed: xStripeCustomerId: team.activeCustomerId
Embed->>Embed: headers: {"X-Stripe-Customer-ID": xStripeCustomerId}
Note over Embed: Request with customer ID header
Trace->>Trace: team{id, activeCustomerId, activeSubscriptionId, plan}
Note over Trace: Trace includes enriched team data
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ 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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements the Stripe Token Billing integration by passing the team's activeCustomerId through the entire data flow to AI Gateway as the X-Stripe-Customer-ID header for both text generation and embeddings requests.
Key Changes:
- Extended metadata schemas and type definitions to include
activeCustomerIdfield - Updated text generation flow to pass
activeCustomerIdfrom metadata through to gateway options - Added
xStripeCustomerIdparameter to embeddings generation and document ingestion flows
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| apps/studio.giselles.ai/lib/generation-metadata.ts | Added activeCustomerId field to GenerationMetadata schema |
| apps/studio.giselles.ai/lib/trace.ts | Updated TeamForPlan type to include activeCustomerId |
| apps/studio.giselles.ai/app/giselle.ts | Updated TeamForPlan type and passed activeCustomerId through generation metadata and trigger.dev job invocations |
| apps/studio.giselles.ai/trigger/generate-content-job.ts | Added activeCustomerId to job schema and passed it through to telemetry context |
| apps/studio.giselles.ai/lib/vector-stores/document/ingest/generate-embeddings.ts | Added xStripeCustomerId parameter and passed it as X-Stripe-Customer-ID header to embedder |
| apps/studio.giselles.ai/lib/vector-stores/document/ingest/ingest-document.ts | Passed activeCustomerId from telemetry context to embeddings generation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
|||||||||||||||||||||||||
PR Code Suggestions ✨No code suggestions found for the PR. |
🔍 QA Testing Assistant by Giselle📋 Manual QA ChecklistBased on the changes in this PR, here are the key areas to test manually:
✨ Prompt for AI AgentsUse the following prompts with Cursor or Claude Code to automate E2E testing: 📝 E2E Test Generation Prompt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const batchEmbeddings = await embedder.embedMany( | ||
| batch, | ||
| xStripeCustomerId | ||
| ? { | ||
| headers: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
embedMany call now violates @giselles-ai/rag signature
The new call to embedder.embedMany(batch, { headers: ... }) uses a second argument, but the public EmbedderFunction exported by @giselles-ai/rag still declares embedMany(texts: string[]): Promise<number[][]> (see packages/rag/dist/index.d.ts lines 173‑185). With the current package version in the workspace, this change will fail TypeScript compilation for the studio app with an “Expected 1 arguments, but got 2” error, blocking builds until the rag types are updated or the extra parameter is removed.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review!
The EmbedderFunction type was updated in PR #XXX (PR2) to include the optional EmbeddingOptions parameter on both embed and embedMany methods (see packages/rag/src/embedder/types.ts).
The build artifacts in packages/rag/dist/index.d.ts should reflect this change after running pnpm build-sdk. All type checks pass successfully:
- ✅ pnpm build-sdk
- ✅ pnpm check-types
- ✅ pnpm test
If you're seeing the old signature, it might be because the dist files need to be regenerated or the PR branch needs to be rebased.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/studio.giselles.ai/app/giselle.ts (1)
477-486: Missing activeCustomerId in run-task-job trigger.The
run-task-jobtrigger for the github-app flow (lines 481-485) doesn't includeactiveCustomerIdin the team object, while the generate-content triggers do. This inconsistency means task runs won't have customer billing context.Apply this diff to add the missing field:
await jobs.trigger<typeof runTaskJob>("run-task-job", { taskId: task.id, requestId, userId: "github-app", team: { id: team.id, subscriptionId: team.activeSubscriptionId, plan: team.plan, + activeCustomerId: team.activeCustomerId, }, });Note: The stage/studio flow (lines 496-505) also needs the same addition.
♻️ Duplicate comments (2)
apps/studio.giselles.ai/lib/trace.ts (1)
24-44: activeCustomerId not passed to traceGeneration metadata.The
traceGenerationForTeamfunction acceptsactiveCustomerIdvia theteamparameter but doesn't include it in themetadataobject passed totraceGeneration()(line 34-40). ThesubscriptionIdis included at line 38, butactiveCustomerIdis missing.Apply this diff to include it in metadata:
metadata: { generationId: args.generation.id, teamPlan, userId: args.userId, subscriptionId: args.team.activeSubscriptionId ?? "", + activeCustomerId: args.team.activeCustomerId ?? "", providerMetadata: args.providerMetadata, requestId: args.requestId, workspaceId: args.generation.context.origin.workspaceId, },apps/studio.giselles.ai/lib/vector-stores/document/ingest/generate-embeddings.ts (1)
122-131: embedMany call violates @giselles-ai/rag signature.The
embedder.embedMany()call now passes a second argument with headers, but theEmbedderFunctiontype from@giselles-ai/ragdeclaresembedMany(texts: string[]): Promise<number[][]>with only one parameter. This will cause TypeScript compilation errors unless the rag package types have been updated to support the second parameter.
🧹 Nitpick comments (1)
apps/studio.giselles.ai/lib/vector-stores/document/ingest/ingest-document.ts (1)
283-284: Redundant?? undefinedwith optional chaining.The
?? undefinedis redundant sincetelemetryContext?.team.activeCustomerIdalready evaluates toundefinedwhen the property is not accessible.Apply this diff to simplify:
- xStripeCustomerId: - telemetryContext?.team.activeCustomerId ?? undefined, + xStripeCustomerId: telemetryContext?.team.activeCustomerId,
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
apps/studio.giselles.ai/app/giselle.ts(4 hunks)apps/studio.giselles.ai/lib/generation-metadata.ts(1 hunks)apps/studio.giselles.ai/lib/trace.ts(1 hunks)apps/studio.giselles.ai/lib/vector-stores/document/ingest/generate-embeddings.ts(3 hunks)apps/studio.giselles.ai/lib/vector-stores/document/ingest/ingest-document.ts(1 hunks)apps/studio.giselles.ai/trigger/generate-content-job.ts(3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-08-19T02:30:10.738Z
Learnt from: satococoa
Repo: giselles-ai/giselle PR: 1663
File: packages/rag/src/query-service/postgres/index.ts:206-210
Timestamp: 2025-08-19T02:30:10.738Z
Learning: The multi-embedding backend currently only supports 3072 and 1536 dimensions. The hardcoded embedding cast logic in packages/rag/src/query-service/postgres/index.ts is intentionally limited to these two dimension sizes.
Applied to files:
apps/studio.giselles.ai/lib/vector-stores/document/ingest/generate-embeddings.ts
📚 Learning: 2025-11-13T08:16:38.293Z
Learnt from: shige
Repo: giselles-ai/giselle PR: 2172
File: packages/rag/src/embedder/gateway.ts:26-28
Timestamp: 2025-11-13T08:16:38.293Z
Learning: In packages/rag/src/embedder/gateway.ts, the toGatewayModelId function correctly uses forward slash format (provider/model) which matches the ai-sdk/gateway SDK's GatewayEmbeddingModelId type definition. Do not suggest changing this to colon format.
Applied to files:
apps/studio.giselles.ai/lib/vector-stores/document/ingest/generate-embeddings.ts
📚 Learning: 2025-11-13T08:16:38.293Z
Learnt from: shige
Repo: giselles-ai/giselle PR: 2172
File: packages/rag/src/embedder/gateway.ts:26-28
Timestamp: 2025-11-13T08:16:38.293Z
Learning: In packages/rag/src/embedder/profiles.ts, createEmbedderFromProfile already validates embedding profiles using isGatewaySupportedEmbeddingProfile before calling createGatewayEmbedder. Additional validation inside createGatewayEmbedder would be redundant.
Applied to files:
apps/studio.giselles.ai/lib/vector-stores/document/ingest/generate-embeddings.ts
🔇 Additional comments (7)
apps/studio.giselles.ai/lib/generation-metadata.ts (1)
10-10: LGTM!The
activeCustomerIdfield addition is properly typed as a nullable string, consistent with thesubscriptionIdfield above it.apps/studio.giselles.ai/trigger/generate-content-job.ts (2)
18-18: LGTM!The
activeCustomerIdfield addition to the schema is properly typed and consistent with theGenerationMetadataschema.
47-48: LGTM!The
activeCustomerIdis correctly propagated totraceGenerationForTeamin both success (onComplete) and error (onError) handlers.Also applies to: 63-64
apps/studio.giselles.ai/lib/trace.ts (1)
10-13: LGTM!The
TeamForPlantype correctly includesactiveCustomerIdin the picked fields fromCurrentTeam.apps/studio.giselles.ai/app/giselle.ts (3)
77-80: LGTM!The
TeamForPlantype correctly includesactiveCustomerId, consistent with the type definition inapps/studio.giselles.ai/lib/trace.ts.
283-284: LGTM!The
activeCustomerIdis correctly included when constructing the team object from parsed metadata in the embedding callback.
420-420: LGTM!The
activeCustomerIdis correctly propagated to the generate-content trigger in both github-app and stage/studio flows.Also applies to: 443-443
Include activeCustomerId in the metadata passed to traceGeneration and traceEmbedding functions, enabling customer-level tracking in Langfuse for both text generation and embedding operations. Changes: - Add customerId to traceGenerationForTeam metadata (lib/trace.ts) - Add customerId to traceEmbeddingForTeam baseMetadata (app/giselle.ts) This ensures Stripe Customer ID is tracked consistently across all telemetry data, alongside subscriptionId.
a4d4bd0 to
da4f6e0
Compare
User description
Implement end-to-end data flow to pass team's activeCustomerId through the AI Gateway as X-Stripe-Customer-ID header for both text generation and embeddings.
Metadata and type changes:
Text generation flow:
Embeddings flow:
This completes the Stripe Token Billing integration by connecting team.activeCustomerId from the database to the actual LLM and embedding API requests.
PR Type
Enhancement
Description
Add
activeCustomerIdfield to team metadata schemasPass
activeCustomerIdthrough text generation job invocationsPass
activeCustomerIdto embeddings generation with X-Stripe-Customer-ID headerSupport customer ID in document ingest telemetry context
Diagram Walkthrough
File Walkthrough
giselle.ts
Add activeCustomerId to team metadata in giselle appapps/studio.giselles.ai/app/giselle.ts
TeamForPlantype to includeactiveCustomerIdfieldactiveCustomerIdto team object in embeddings trace callactiveCustomerIdto team object in both generate-content jobinvocations
generation-metadata.ts
Add activeCustomerId to GenerationMetadata schemaapps/studio.giselles.ai/lib/generation-metadata.ts
activeCustomerIdas nullable string field to GenerationMetadataschema
trace.ts
Add activeCustomerId to trace TeamForPlan typeapps/studio.giselles.ai/lib/trace.ts
TeamForPlantype to includeactiveCustomerIdfieldgenerate-embeddings.ts
Add Stripe customer ID header to embeddings generationapps/studio.giselles.ai/lib/vector-stores/document/ingest/generate-embeddings.ts
xStripeCustomerIdoptional parameter toGenerateEmbeddingsOptionsinterfacexStripeCustomerIdto embedder.embedMany() call withX-Stripe-Customer-ID header
ingest-document.ts
Pass activeCustomerId to embeddings generationapps/studio.giselles.ai/lib/vector-stores/document/ingest/ingest-document.ts
activeCustomerIdfrom telemetry context to generateEmbeddingsfunction
generate-content-job.ts
Add activeCustomerId to generate-content job schemaapps/studio.giselles.ai/trigger/generate-content-job.ts
activeCustomerIdfield to generate-content job schemaactiveCustomerIdto traceGenerationForTeam in both onSuccess andonError handlers
Note
Propagates team.activeCustomerId end-to-end and sends it to the AI Gateway (including embeddings) via X-Stripe-Customer-ID, updating schemas, tracing, and job wiring.
team.activeCustomerIdtoGenerationMetadataand extendTeamForPlanto includeactiveCustomerId.customerIdin generation and embedding trace metadata intrace.tsandapp/giselle.ts.generate-contentjob schema to carryactiveCustomerIdand pass it through success/error handlers and all invocation sites.xStripeCustomerIdtogenerateEmbeddingsoptions and forward asX-Stripe-Customer-IDheader toembedder.embedMany.activeCustomerIdfrom ingest telemetry context to embeddings generation iningest-document.ts.Written by Cursor Bugbot for commit 26702eb. This will update automatically on new commits. Configure here.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.