feat(ai-integrations): cursor usage polling pipeline#2923
Conversation
Introduces an org-level AI Integrations product surface, with Cursor as the first provider. Adds CRUD endpoints + dashboard settings UI for managing provider integrations, an hourly Temporal workflow that polls the Cursor Admin API for token/cost usage events, and ClickHouse ingestion via the existing telemetry_logs schema so cost data shows up uniformly alongside Claude Code hook data on the dashboard. - New aiintegrations Goa service: getConfig / upsertConfig / deleteConfig - ai_integration_configs + ai_integration_syncs tables with encrypted API key storage (AES-256-GCM) and high-water-mark polling - AIIntegrationUsageSyncWorkflow coordinator + per-org/provider child workflow with stable workflow-ID mutex and 50min run budget - Cursor HTTP client with rate-limit-aware paging (429 Retry-After) - SHA-256 event hashing stored on each row for duplicate audit - Dashboard: AIIntegrationsSection in org settings, cost copy + employee-level cost card - SDK regenerated for the new endpoints Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
🦋 Changeset detectedLatest commit: 7a0f895 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🚀 Preview Environment (PR #2923)Preview URL: https://pr-2923.dev.getgram.ai
Gram Preview Bot |
| aiIntegrationUsageSyncWorkflowID = "v1:ai-integration-usage-sync" | ||
| aiIntegrationUsageSyncScheduleID = "v1:ai-integration-usage-sync-schedule" | ||
| aiIntegrationUsageSyncScheduledWorkflowID = aiIntegrationUsageSyncScheduleID + "/scheduled" | ||
| aiIntegrationUsageSyncInterval = time.Hour |
There was a problem hiding this comment.
Based on my initial reading, I think this workflow isn't set up quite right. Right now the schedule triggers a single workflow every hour. That one workflow them loops over every org and triggers a sync. This means that when I add in my cursor api key, it might take up to an hour before any data actually appears.
What should happen instead:
- The schedule should trigger the workflow every ~5 minutes (or something)
- The lastPolledAt should determine which orgs actually get syncs run in that particular job. This has the advantage of staggering load
- The workflow should be triggerable outside the schedule for a certain org, e.g. whenever a new api key is created trigger the workflow for JUST that org. Or if we add a manual button to the UI
| } | ||
| } | ||
|
|
||
| for len(active) < aiIntegrationUsageSyncConcurrency { |
There was a problem hiding this comment.
This feels like the kind of thing that should be handled natively by temporal. Is that not possible?
Summary
telemetry_logs.Test plan
aiintegrations, background workflow/activities, audit, Cursor HTTP client)gram_project_idRetry-Aftercauses activity sleep + heartbeat + resume🤖 Generated with Claude Code