feat(backend): use sortable UUIDv7 for ID defaults - #12961
Conversation
Switches ID generation from random UUIDv4 to UUIDv7 so primary keys
land in roughly insert-time order. Better B-tree locality on writes,
sortable-by-id pagination, and easier debugging without an extra
createdAt column.
- Adds Postgres `uuid_generate_v7()` SQL function (RFC 9562, built on
pgcrypto's gen_random_uuid()).
- Migration ALTERs every model's id default to uuid_generate_v7(),
including AnalyticsDetails which was on gen_random_uuid().
- Schema flips `@default(uuid())` and the AnalyticsDetails dbgenerated
default to `@default(dbgenerated("uuid_generate_v7()"))`.
- Adds backend/util/ids.py:new_uuid() (uuid_utils.uuid7) for code that
needs the id before insert; rewires the explicit-id call sites in
graph.py and auth/{api_key,oauth}.py.
Existing UUIDv4 rows keep their values; only newly generated ids are
sortable.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughSwitches ID generation to UUIDv7 across the stack: adds a centralized Python ChangesUUIDv7 ID migration
sequenceDiagram
participant Client
participant App as Python App (new_uuid)
participant DB as PostgreSQL (uuid_generate_v7)
Client->>App: Create resource request
alt App generates id before insert
App->>App: new_uuid() → id
App->>DB: INSERT ... (id=<generated>)
DB-->>App: INSERT OK
else Let DB assign id
App->>DB: INSERT ... (no id)
DB-->>App: id=dbgenerated(uuid_generate_v7())
end
App-->>Client: Return resource with id
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
🔍 PR Overlap DetectionThis check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early. 🔴 Merge Conflicts DetectedThe following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.
🟢 Low Risk — File Overlap OnlyThese PRs touch the same files but different sections (click to expand)
Summary: 3 conflict(s), 0 medium risk, 7 low risk (out of 10 PRs with file overlap) Auto-generated on push. Ignores: |
- schema.prisma: add a comment in the generator block telling future
contributors to use dbgenerated("uuid_generate_v7()") on new id columns
- migration: mark uuid_generate_v7() as PARALLEL SAFE so query planners
can use parallel plans through INSERT ... RETURNING id paths
- ids.py: rewrite new_uuid() docstring to point callers at the schema
default first; helper is for cases where the id is needed pre-insert
- pyproject.toml: widen uuid-utils bound to >=0.14.1,<1.0.0 to match
langsmith's own constraint and avoid blocking transitive bumps
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
autogpt_platform/backend/backend/data/graph.py (1)
1708-1719:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPreserve link IDs between the returned fork result and the inserted rows.
fork_graph()returns the in-memorygraphafter__create_graph(), but this path always generates a fresh link ID here instead of persistinglink.id. Since_reassign_ids()does not rewriteLink.id, a forked graph can come back with stale link IDs from the source graph while the database rows have different ones. Either regenerateLink.idbefore insert and write that value here, or re-fetch before returning.🧩 One way to keep the model and DB in sync
diff --git a/autogpt_platform/backend/backend/data/graph.py b/autogpt_platform/backend/backend/data/graph.py @@ - for link in graph.links: + for link in graph.links: + link.id = new_uuid() if link.source_id in id_map: link.source_id = id_map[link.source_id] if link.sink_id in id_map: link.sink_id = id_map[link.sink_id] @@ AgentNodeLinkCreateInput( - id=new_uuid(), + id=link.id, sourceName=link.source_name, sinkName=link.sink_name, agentNodeSourceId=link.source_id, agentNodeSinkId=link.sink_id,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@autogpt_platform/backend/backend/data/graph.py` around lines 1708 - 1719, fork_graph() returns the in-memory graph produced by __create_graph(), but the create_many call in AgentNodeLink.prisma(tx).create_many is generating new UUIDs (new_uuid()) for each link which desynchronizes persisted rows from the in-memory Link.id (and _reassign_ids() does not rewrite Link.id); fix by using the existing link.id when building AgentNodeLinkCreateInput (or explicitly regenerate and assign link.id back to the in-memory link before inserting) so the persisted agent-node-link rows keep the same Link.id as the returned graph, alternatively re-fetch the inserted rows and update the in-memory graph’s Link.id values before returning.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@autogpt_platform/backend/backend/data/graph.py`:
- Around line 1708-1719: fork_graph() returns the in-memory graph produced by
__create_graph(), but the create_many call in
AgentNodeLink.prisma(tx).create_many is generating new UUIDs (new_uuid()) for
each link which desynchronizes persisted rows from the in-memory Link.id (and
_reassign_ids() does not rewrite Link.id); fix by using the existing link.id
when building AgentNodeLinkCreateInput (or explicitly regenerate and assign
link.id back to the in-memory link before inserting) so the persisted
agent-node-link rows keep the same Link.id as the returned graph, alternatively
re-fetch the inserted rows and update the in-memory graph’s Link.id values
before returning.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 20ec960f-69e0-405b-9303-227f16db9ff6
⛔ Files ignored due to path filters (1)
autogpt_platform/backend/poetry.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
autogpt_platform/backend/backend/data/auth/api_key.pyautogpt_platform/backend/backend/data/auth/oauth.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/util/ids.pyautogpt_platform/backend/migrations/20260430120000_use_uuidv7_for_id_defaults/migration.sqlautogpt_platform/backend/pyproject.tomlautogpt_platform/backend/schema.prisma
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: check API types
- GitHub Check: Seer Code Review
- GitHub Check: Check PR Status
- GitHub Check: test (3.11)
- GitHub Check: test (3.12)
- GitHub Check: type-check (3.13)
- GitHub Check: end-to-end tests
- GitHub Check: type-check (3.12)
- GitHub Check: type-check (3.11)
- GitHub Check: test (3.13)
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (6)
autogpt_platform/backend/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development
autogpt_platform/backend/**/*.py: Usepoetry run ...command for executing Python package dependencies
Use top-level imports only — avoid local/inner imports except for lazy imports of heavy optional dependencies likeopenpyxl
Use absolute imports withfrom backend.module import ...for cross-package imports; single-dot relative imports are acceptable for sibling modules within the same package; avoid double-dot relative imports
Do not use duck typing — avoidhasattr/getattr/isinstancefor type dispatch; use typed interfaces/unions/protocols instead
Use Pydantic models over dataclass/namedtuple/dict for structured data
Do not use linter suppressors — no# type: ignore,# noqa,# pyright: ignore; fix the type/code instead
Prefer list comprehensions over manual loop-and-append patterns
Use early return with guard clauses first to avoid deep nesting
Use%sfor deferred interpolation indebuglog statements for efficiency; use f-strings elsewhere for readability (e.g.,logger.debug("Processing %s items", count)vslogger.info(f"Processing {count} items"))
Sanitize error paths by usingos.path.basename()in error messages to avoid leaking directory structure
Be aware of TOCTOU (Time-Of-Check-Time-Of-Use) issues — avoid check-then-act patterns for file access and credit charging
Usetransaction=Truefor Redis pipelines to ensure atomicity on multi-step operations
Usemax(0, value)guards for computed values that should never be negative
Keep files under ~300 lines; if a file grows beyond this, split by responsibility (extract helpers, models, or a sub-module into a new file)
Keep functions under ~40 lines; extract named helpers when a function grows longer
...
Files:
autogpt_platform/backend/backend/util/ids.pyautogpt_platform/backend/backend/data/auth/api_key.pyautogpt_platform/backend/backend/data/auth/oauth.pyautogpt_platform/backend/backend/data/graph.py
autogpt_platform/{backend,autogpt_libs}/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Format Python code with
poetry run format
Files:
autogpt_platform/backend/backend/util/ids.pyautogpt_platform/backend/backend/data/auth/api_key.pyautogpt_platform/backend/backend/data/auth/oauth.pyautogpt_platform/backend/backend/data/graph.py
autogpt_platform/backend/**/*.{json,yaml,yml,toml,config}
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Include agent configuration in dedicated configuration files
Files:
autogpt_platform/backend/pyproject.toml
autogpt_platform/backend/backend/data/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
All data access in backend requires user ID checks; verify this for any 'data/*.py' changes
Files:
autogpt_platform/backend/backend/data/auth/api_key.pyautogpt_platform/backend/backend/data/auth/oauth.pyautogpt_platform/backend/backend/data/graph.py
autogpt_platform/**/data/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
For changes touching
data/*.py, validate user ID checks or explain why not needed
Files:
autogpt_platform/backend/backend/data/auth/api_key.pyautogpt_platform/backend/backend/data/auth/oauth.pyautogpt_platform/backend/backend/data/graph.py
autogpt_platform/backend/schema.prisma
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Run database migrations with 'poetry run prisma migrate dev' and 'poetry run prisma generate' after schema changes in backend
Files:
autogpt_platform/backend/schema.prisma
🧠 Learnings (32)
📓 Common learnings
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12284
File: autogpt_platform/frontend/src/app/api/openapi.json:11897-11900
Timestamp: 2026-03-04T23:58:18.476Z
Learning: Repo: Significant-Gravitas/AutoGPT — PR `#12284`
Backend/frontend OpenAPI codegen convention: In backend/api/features/store/model.py, the StoreSubmission and StoreSubmissionAdminView models define submitted_at: datetime | None, changes_summary: str | None, and instructions: str | None with no default. This is intentional to produce “required but nullable” fields in OpenAPI (properties appear in required[] and use anyOf [type, null]). This matches Prisma’s submittedAt DateTime? and changesSummary String?. Do not flag this as a required/nullable mismatch.
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12720
File: autogpt_platform/backend/backend/copilot/graphiti/client.py:20-46
Timestamp: 2026-04-09T08:47:32.750Z
Learning: In Significant-Gravitas/AutoGPT, `user_id` values passed to `derive_group_id` in `autogpt_platform/backend/backend/copilot/graphiti/client.py` are always system-generated UUIDv4s (e.g. `883cc9da-fe37-4863-839b-acba022bf3ef`). The character set `[0-9a-f-]` is fully within `[a-zA-Z0-9_-]`, so the sanitization regex never strips any characters and no collision between two different user IDs is possible. Do not flag `derive_group_id` for collision-resistance issues.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/api/openapi.json:9983-9995
Timestamp: 2026-02-27T15:59:00.370Z
Learning: Repo: Significant-Gravitas/AutoGPT PR: 12213 — Backend/frontend OpenAPI codegen
Learning: For MCP schema models, required OpenAPI fields must have no defaults in Pydantic. Specifically, MCPToolInfo.input_schema must be required (no Field(default_factory=dict)) so openapi.json emits it in "required", ensuring generated TS types treat input_schema as non-optional.
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/library/components/SitrepItem/SitrepItem.tsx:143-145
Timestamp: 2026-04-13T13:11:09.987Z
Learning: In Significant-Gravitas/AutoGPT `autogpt_platform/frontend`, `executionID` values used as URL query params (e.g. `activeItem=` in `SitrepItem.tsx`) are always UUIDs (e.g. `550e8400-e29b-41d4-a716-446655440000`). Their character set `[0-9a-f-]` contains no reserved URL characters, so `encodeURIComponent` or Next.js object-based `href` encoding is unnecessary. Do not flag direct UUID string interpolation into query strings as a URL-encoding issue.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/api/openapi.json:9983-9995
Timestamp: 2026-02-27T15:59:00.370Z
Learning: Repo: Significant-Gravitas/AutoGPT PR: 12213 — OpenAPI/codegen
Learning: Ensuring a field is required in generated TS types needs two sides: (1) no default value on the Pydantic field, and (2) the OpenAPI model's "required" array must list it. For MCPToolInfo, making input_schema required in OpenAPI and removing Field(default_factory=dict) in the backend prevents optional typing drift.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-28T03:31:29.696Z
Learning: In Significant-Gravitas/AutoGPT PR `#12933` (`fix/stripe-checkout-link-auth-loop`), the initial approach of pinning `payment_method_types=["card"]` in `top_up_intent` and `create_subscription_checkout` (in `autogpt_platform/backend/backend/data/credit.py`) was reverted in commit `584b43a71` as it patched a symptom. The true root cause was in `update_subscription_tier()` in `v1.py`: a `current_tier_price_id is not None` guard was gating admin-granted DB-tier flips and short-circuiting them when the BUSINESS tier was pruned from the price-id LaunchDarkly flag. Do NOT flag `payment_method_types` absence in these checkout helpers as a Stripe Link bypass issue; the fix lives in the subscription tier update guard logic.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12919
File: autogpt_platform/backend/backend/data/notifications_test.py:296-338
Timestamp: 2026-04-25T05:02:54.108Z
Learning: In `autogpt_platform/backend/backend/data/notifications.py`, `create_or_add_to_user_notification_batch` uses a Prisma `upsert` on the `(userId, type)` unique constraint. Because Prisma's `upsert` is internally find→INSERT/UPDATE (not a true SQL `ON CONFLICT`), two concurrent callers on an empty row can both miss the SELECT and both attempt INSERT, causing a `UniqueViolationError`. The helper retries once on `UniqueViolationError`; on retry the row exists, so the loser takes the UPDATE path deterministically. Do NOT flag the retry-on-`UniqueViolationError` pattern as unnecessary — it is the intentional TOCTOU mitigation for the non-atomic Prisma upsert. Covered by `test_upsert_retries_on_unique_violation` (monkeypatch) and `test_upsert_concurrent_invocations_no_unique_violation` (live-DB gather), added in PR `#12919` commit 7fcc50a.
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12536
File: autogpt_platform/frontend/src/app/api/openapi.json:5770-5790
Timestamp: 2026-03-24T21:25:15.983Z
Learning: Repo: Significant-Gravitas/AutoGPT — PR `#12536`
File: autogpt_platform/frontend/src/app/api/openapi.json
Learning: The OpenAPI spec file is auto-generated; per established convention, endpoints generally declare only 200/201, 401, and 422 responses. Do not suggest adding explicit 403/404 response entries for single operations unless planning a repo-wide spec update. Prefer clarifying such behaviors in endpoint descriptions/docstrings instead of altering response maps.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12566
File: autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts:968-974
Timestamp: 2026-03-26T00:32:06.673Z
Learning: In Significant-Gravitas/AutoGPT, the admin-facing methods in `autogpt_platform/frontend/src/lib/autogpt-server-api/client.ts` (e.g., `addUserCredits`, `getUsersHistory`, `getUserRateLimit`, `resetUserRateLimit`) intentionally follow the legacy `BackendAPI` pattern with manually defined types in `autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts`. Migrating these admin endpoints to the generated OpenAPI hooks (`@/app/api/__generated__/endpoints/`) is a planned separate effort covering all admin endpoints together, not done piecemeal per PR. Do not flag individual admin type additions in `types.ts` as blocking issues.
📚 Learning: 2026-02-05T04:11:15.945Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 11796
File: autogpt_platform/backend/backend/blocks/video/concat.py:3-4
Timestamp: 2026-02-05T04:11:15.945Z
Learning: Block IDs in autogpt_platform/backend/backend/blocks/**/*.py must be stable, hard-coded UUID strings. When initially creating a new block, generate a UUID once using `uuid.uuid4()` and then hard-code that UUID string as the block's `id` parameter. Do not call uuid.uuid4() dynamically at runtime, as block IDs must remain constant across all imports and runs.
Applied to files:
autogpt_platform/backend/backend/util/ids.pyautogpt_platform/backend/backend/data/auth/api_key.pyautogpt_platform/backend/backend/data/auth/oauth.pyautogpt_platform/backend/backend/data/graph.py
📚 Learning: 2026-04-09T08:47:32.750Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12720
File: autogpt_platform/backend/backend/copilot/graphiti/client.py:20-46
Timestamp: 2026-04-09T08:47:32.750Z
Learning: In Significant-Gravitas/AutoGPT, `user_id` values passed to `derive_group_id` in `autogpt_platform/backend/backend/copilot/graphiti/client.py` are always system-generated UUIDv4s (e.g. `883cc9da-fe37-4863-839b-acba022bf3ef`). The character set `[0-9a-f-]` is fully within `[a-zA-Z0-9_-]`, so the sanitization regex never strips any characters and no collision between two different user IDs is possible. Do not flag `derive_group_id` for collision-resistance issues.
Applied to files:
autogpt_platform/backend/backend/util/ids.pyautogpt_platform/backend/backend/data/auth/api_key.pyautogpt_platform/backend/backend/data/auth/oauth.pyautogpt_platform/backend/backend/data/graph.py
📚 Learning: 2026-04-08T17:28:23.439Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:23.439Z
Learning: Applies to autogpt_platform/backend/backend/blocks/**/*.py : When creating new blocks, inherit from `Block` base class, define input/output schemas using `BlockSchema`, implement async `run` method, and generate unique block ID using `uuid.uuid4()`
Applied to files:
autogpt_platform/backend/backend/util/ids.py
📚 Learning: 2026-04-08T17:28:23.439Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:23.439Z
Learning: Applies to autogpt_platform/backend/**/*.py : Use `poetry run ...` command for executing Python package dependencies
Applied to files:
autogpt_platform/backend/pyproject.toml
📚 Learning: 2026-01-31T18:44:56.328Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-01-31T18:44:56.328Z
Learning: In the AutoGPT backend Docker build with Poetry path dependencies, `autogpt_libs` requires a double-copy pattern: first COPY from builder brings the installed package state (so venv references work), then second COPY from build context overwrites with latest source (to ensure freshness). Both copies are necessary for correct functionality.
Applied to files:
autogpt_platform/backend/pyproject.toml
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/**/*.py : Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Applied to files:
autogpt_platform/backend/pyproject.toml
📚 Learning: 2026-01-31T18:44:56.328Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-01-31T18:44:56.328Z
Learning: In the AutoGPT backend Docker build, `setuptools` must be retained at runtime because it's a direct dependency declared in pyproject.toml and the `aioclamd` package uses `pkg_resources` from setuptools at runtime.
Applied to files:
autogpt_platform/backend/pyproject.toml
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/schema.prisma : Run database migrations with 'poetry run prisma migrate dev' and 'poetry run prisma generate' after schema changes in backend
Applied to files:
autogpt_platform/backend/pyproject.tomlautogpt_platform/backend/schema.prisma
📚 Learning: 2026-04-08T17:27:45.740Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:45.740Z
Learning: Applies to autogpt_platform/{backend,autogpt_libs}/**/*.py : Format Python code with `poetry run format`
Applied to files:
autogpt_platform/backend/pyproject.toml
📚 Learning: 2026-04-08T17:28:23.439Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/AGENTS.md:0-0
Timestamp: 2026-04-08T17:28:23.439Z
Learning: Applies to autogpt_platform/backend/**/*_test.py : When creating snapshots in tests, use `poetry run pytest path/to/test.py --snapshot-update`; always review snapshot changes with `git diff` before committing
Applied to files:
autogpt_platform/backend/pyproject.toml
📚 Learning: 2026-03-04T23:58:18.476Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12284
File: autogpt_platform/frontend/src/app/api/openapi.json:11897-11900
Timestamp: 2026-03-04T23:58:18.476Z
Learning: Repo: Significant-Gravitas/AutoGPT — PR `#12284`
Backend/frontend OpenAPI codegen convention: In backend/api/features/store/model.py, the StoreSubmission and StoreSubmissionAdminView models define submitted_at: datetime | None, changes_summary: str | None, and instructions: str | None with no default. This is intentional to produce “required but nullable” fields in OpenAPI (properties appear in required[] and use anyOf [type, null]). This matches Prisma’s submittedAt DateTime? and changesSummary String?. Do not flag this as a required/nullable mismatch.
Applied to files:
autogpt_platform/backend/backend/data/auth/api_key.pyautogpt_platform/backend/migrations/20260430120000_use_uuidv7_for_id_defaults/migration.sqlautogpt_platform/backend/schema.prisma
📚 Learning: 2026-04-08T17:27:45.740Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T17:27:45.740Z
Learning: Applies to autogpt_platform/**/data/**/*.py : For changes touching `data/*.py`, validate user ID checks or explain why not needed
Applied to files:
autogpt_platform/backend/backend/data/auth/api_key.pyautogpt_platform/backend/backend/data/graph.py
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/backend/data/**/*.py : All data access in backend requires user ID checks; verify this for any 'data/*.py' changes
Applied to files:
autogpt_platform/backend/backend/data/auth/api_key.pyautogpt_platform/backend/backend/data/graph.py
📚 Learning: 2026-03-07T07:43:15.754Z
Learnt from: kcze
Repo: Significant-Gravitas/AutoGPT PR: 12328
File: autogpt_platform/frontend/src/app/api/openapi.json:1116-1118
Timestamp: 2026-03-07T07:43:15.754Z
Learning: In Significant-Gravitas/AutoGPT, v2 chat endpoints often declare HTTPBearerJWT at the router level while using Depends(auth.get_user_id) that returns None for unauthenticated users; effective behavior is optional auth. Keep this convention unless doing a repo-wide OpenAPI update; prefer clarifying descriptions over per-operation security changes.
Applied to files:
autogpt_platform/backend/backend/data/auth/oauth.py
📚 Learning: 2026-03-13T15:49:44.961Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12385
File: autogpt_platform/backend/backend/copilot/rate_limit.py:0-0
Timestamp: 2026-03-13T15:49:44.961Z
Learning: In `autogpt_platform/backend/backend/copilot/rate_limit.py`, the original per-session token window (with a TTL-based reset) was replaced with fixed daily and weekly windows. `resets_at` is now derived from `_daily_reset_time()` (midnight UTC) and `_weekly_reset_time()` (next Monday 00:00 UTC) — deterministic fixed-boundary calculations that require no Redis TTL introspection.
Applied to files:
autogpt_platform/backend/backend/data/auth/oauth.py
📚 Learning: 2026-03-31T14:22:29.127Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12622
File: autogpt_platform/backend/backend/copilot/tools/agent_search.py:223-236
Timestamp: 2026-03-31T14:22:29.127Z
Learning: When reviewing code under autogpt_platform/backend/backend/copilot/tools/, the `AgentInfo.graph` field (in agent_search.py / models.py) uses `Graph | None` (the typed `backend.data.graph.Graph` Pydantic model), NOT `dict[str, Any]`. The enrichment function `_enrich_agents_with_graph` calls `graph_db().get_graph(graph_id, version=None, user_id=user_id)` directly rather than going through `get_agent_as_json()` / `graph_to_json()`. This was updated in PR `#12622` (commit 22d05bc).
Applied to files:
autogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/schema.prisma
📚 Learning: 2026-04-14T21:27:04.525Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12765
File: autogpt_platform/backend/backend/copilot/tools/graphiti_forget.py:227-234
Timestamp: 2026-04-14T21:27:04.525Z
Learning: In `autogpt_platform/backend/backend/copilot/tools/graphiti_forget.py`, the `getattr(client, "graph_driver", None) or getattr(client, "driver", None)` pattern for accessing the Neo4j driver from a `graphiti_core.Graphiti` instance is intentional and correct. `graphiti_core.Graphiti` does not expose `driver` as a stable public property (`dir(Graphiti)` shows no `driver` or `graph_driver` public property); the attribute name has varied across library versions. The fallback chain handles cross-version compatibility. Do NOT flag this as a duck-typing violation. Additionally, soft delete (temporal invalidation), per-UUID success/failure reporting, and episode back-reference cleanup all require raw Cypher queries — the `EntityEdge.delete_by_uuids` batch API does not cover these cases.
Applied to files:
autogpt_platform/backend/backend/data/graph.py
📚 Learning: 2026-03-10T08:39:22.025Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12356
File: autogpt_platform/backend/backend/copilot/constants.py:9-12
Timestamp: 2026-03-10T08:39:22.025Z
Learning: In Significant-Gravitas/AutoGPT PR `#12356`, the `COPILOT_SYNTHETIC_ID_PREFIX = "copilot-"` check in `create_auto_approval_record` (human_review.py) is intentional and safe. The `graph_exec_id` passed to this function comes from server-side `PendingHumanReview` DB records (not from user input); the API only accepts `node_exec_id` from users. Synthetic `copilot-*` IDs are only ever created server-side in `run_block.py`. The prefix skip avoids a DB lookup for a `AgentGraphExecution` record that legitimately does not exist for CoPilot sessions, while `user_id` scoping is enforced at the auth layer and on the resulting auto-approval record.
Applied to files:
autogpt_platform/backend/backend/data/graph.py
📚 Learning: 2026-04-15T14:10:31.685Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: autogpt_platform/backend/backend/copilot/graphiti/AGENTS.md:0-0
Timestamp: 2026-04-15T14:10:31.685Z
Learning: Applies to autogpt_platform/backend/backend/copilot/graphiti/backend/copilot/graphiti/**/*.py : Preserve per-user isolation through group_id-scoped databases and clients
Applied to files:
autogpt_platform/backend/backend/data/graph.py
📚 Learning: 2026-04-03T11:14:16.378Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/backend/backend/copilot/transcript_builder.py:30-34
Timestamp: 2026-04-03T11:14:16.378Z
Learning: In `autogpt_platform/backend/backend/copilot/transcript_builder.py` (and its re-export shim at `sdk/transcript_builder.py`), `TranscriptEntry.parentUuid` is typed `str` (not `str | None`) and root entries use `parentUuid=""` (empty string) to match the canonical `_messages_to_transcript` JSONL format. `_parse_entry`, `append_user`, and `append_assistant` all coerce `None` to `""`. Do NOT flag `parentUuid=""` as incorrect — it is the correct root marker. This was fixed in PR `#12623`, commit b753cb7d0b.
Applied to files:
autogpt_platform/backend/backend/data/graph.py
📚 Learning: 2026-03-05T00:13:52.412Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12284
File: autogpt_platform/backend/schema.prisma:284-284
Timestamp: 2026-03-05T00:13:52.412Z
Learning: In `autogpt_platform/backend/schema.prisma`, the `AgentGraph` ↔ `StoreListing` relation uses the pattern: `AgentGraph` declares `StoreListing? relation(fields: [id], references: [agentGraphId], onDelete: NoAction)` and `StoreListing` declares `AgentGraph AgentGraph[]` with `agentGraphId String unique`. This is intentional and valid because `AgentGraph` has a composite PK `@id([id, version])` (multiple rows per graph id, one per version), while `StoreListing.agentGraphId` is `unique` (one listing per graph id). The `fields: [id], references: [agentGraphId]` on the `AgentGraph` side joins `AgentGraph.id` against `StoreListing.agentGraphId`. Do NOT flag this as a cardinality mismatch or malformed relation — `prisma validate` passes cleanly.
Applied to files:
autogpt_platform/backend/schema.prisma
📚 Learning: 2026-02-27T15:59:00.370Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/api/openapi.json:9983-9995
Timestamp: 2026-02-27T15:59:00.370Z
Learning: Repo: Significant-Gravitas/AutoGPT PR: 12213 — Backend/frontend OpenAPI codegen
Learning: For MCP schema models, required OpenAPI fields must have no defaults in Pydantic. Specifically, MCPToolInfo.input_schema must be required (no Field(default_factory=dict)) so openapi.json emits it in "required", ensuring generated TS types treat input_schema as non-optional.
Applied to files:
autogpt_platform/backend/schema.prisma
📚 Learning: 2026-03-26T00:32:06.673Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12566
File: autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts:968-974
Timestamp: 2026-03-26T00:32:06.673Z
Learning: In Significant-Gravitas/AutoGPT, the admin-facing methods in `autogpt_platform/frontend/src/lib/autogpt-server-api/client.ts` (e.g., `addUserCredits`, `getUsersHistory`, `getUserRateLimit`, `resetUserRateLimit`) intentionally follow the legacy `BackendAPI` pattern with manually defined types in `autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts`. Migrating these admin endpoints to the generated OpenAPI hooks (`@/app/api/__generated__/endpoints/`) is a planned separate effort covering all admin endpoints together, not done piecemeal per PR. Do not flag individual admin type additions in `types.ts` as blocking issues.
Applied to files:
autogpt_platform/backend/schema.prisma
📚 Learning: 2026-04-22T05:58:31.684Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12879
File: autogpt_platform/frontend/src/app/api/openapi.json:14576-14577
Timestamp: 2026-04-22T05:58:31.684Z
Learning: Repo: Significant-Gravitas/AutoGPT — autogpt_platform
Process convention: When adding new CoPilot tool response models and updating ToolResponseUnion in backend/api/features/chat/routes.py, regenerate the frontend OpenAPI schema via `poetry run export-api-schema` (do not hand-edit autogpt_platform/frontend/src/app/api/openapi.json).
Applied to files:
autogpt_platform/backend/schema.prisma
📚 Learning: 2026-03-11T16:50:45.654Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12367
File: autogpt_platform/backend/generate_views.py:146-150
Timestamp: 2026-03-11T16:50:45.654Z
Learning: In Significant-Gravitas/AutoGPT PR `#12367` (`autogpt_platform/backend/generate_views.py`), the `security_invoker = false` setting on analytics views is intentional. `analytics_readonly` is granted access only to the `analytics` schema. The views execute as their owner (postgres) to read `auth.*` and `platform.*` tables, but expose only curated, scrubbed columns via their SELECT lists. This is the correct PostgreSQL "view as security boundary" pattern — equivalent to a stored-procedure security definer. Do not flag this as a privilege escalation; switching to `security_invoker = true` would require granting `analytics_readonly` direct SELECT on `auth.sessions`, `auth.audit_log_entries`, `platform.AgentGraphExecution`, etc., which is a much wider blast radius than the current design.
Applied to files:
autogpt_platform/backend/schema.prisma
📚 Learning: 2026-02-27T15:59:00.370Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12213
File: autogpt_platform/frontend/src/app/api/openapi.json:9983-9995
Timestamp: 2026-02-27T15:59:00.370Z
Learning: Repo: Significant-Gravitas/AutoGPT PR: 12213 — OpenAPI/codegen
Learning: Ensuring a field is required in generated TS types needs two sides: (1) no default value on the Pydantic field, and (2) the OpenAPI model's "required" array must list it. For MCPToolInfo, making input_schema required in OpenAPI and removing Field(default_factory=dict) in the backend prevents optional typing drift.
Applied to files:
autogpt_platform/backend/schema.prisma
📚 Learning: 2026-04-21T04:35:39.024Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12865
File: autogpt_platform/backend/backend/data/credit.py:1584-1584
Timestamp: 2026-04-21T04:35:39.024Z
Learning: In Significant-Gravitas/AutoGPT, `get_user_by_id(user_id: str)` in `autogpt_platform/backend/backend/data/user.py` returns an application-layer Pydantic `User` model (defined in `autogpt_platform/backend/backend/data/model.py`), NOT the raw Prisma `User` object. This Pydantic model uses snake_case field names (e.g., `subscription_tier`, `stripe_customer_id`, `top_up_config`), which are mapped from camelCase Prisma fields (e.g., `subscriptionTier`, `stripeCustomerId`) inside `User.from_db()`. Do not flag `user.subscription_tier` as a wrong field name — it is correct on the app-layer model.
Applied to files:
autogpt_platform/backend/schema.prisma
📚 Learning: 2026-04-13T13:11:09.987Z
Learnt from: 0ubbe
Repo: Significant-Gravitas/AutoGPT PR: 12764
File: autogpt_platform/frontend/src/app/(platform)/library/components/SitrepItem/SitrepItem.tsx:143-145
Timestamp: 2026-04-13T13:11:09.987Z
Learning: In Significant-Gravitas/AutoGPT `autogpt_platform/frontend`, `executionID` values used as URL query params (e.g. `activeItem=` in `SitrepItem.tsx`) are always UUIDs (e.g. `550e8400-e29b-41d4-a716-446655440000`). Their character set `[0-9a-f-]` contains no reserved URL characters, so `encodeURIComponent` or Next.js object-based `href` encoding is unnecessary. Do not flag direct UUID string interpolation into query strings as a URL-encoding issue.
Applied to files:
autogpt_platform/backend/schema.prisma
📚 Learning: 2026-04-02T14:27:41.807Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12651
File: autogpt_platform/frontend/src/app/api/openapi.json:8653-8696
Timestamp: 2026-04-02T14:27:41.807Z
Learning: Repo: Significant-Gravitas/AutoGPT — Platform costs
The PlatformCostLog.duration is stored in DB but intentionally omitted from the CostLogRow API response to keep the raw logs compact. Do not flag this omission; suggest documenting the intent in the route description if needed.
Applied to files:
autogpt_platform/backend/schema.prisma
📚 Learning: 2026-04-23T13:55:28.873Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1112-1119
Timestamp: 2026-04-23T13:55:28.873Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `AIVideoGeneratorBlock` is intentionally billed by walltime seconds (`BlockCostType.SECOND`, `cost_amount=3`, no `cost_divisor`) using `fal_credentials`. The FAL SDK does not currently expose per-request `provider_cost` or output duration in the response path used; walltime is the best available billing signal. Do NOT flag the absence of `COST_USD` or output-duration billing as a bug. Migration to `BlockCostType.COST_USD` against FAL-reported spend would require an SDK upgrade or a new stats-scraping path and is deferred until the FAL SDK exposes that signal. Established in PR `#12894`.
Applied to files:
autogpt_platform/backend/schema.prisma
📚 Learning: 2026-03-05T00:13:36.338Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12284
File: autogpt_platform/backend/backend/api/features/store/db.py:1206-1221
Timestamp: 2026-03-05T00:13:36.338Z
Learning: In `autogpt_platform/backend/backend/api/features/store/db.py`, the `_approve_sub_agent` helper intentionally does NOT set `ActiveVersion` on the `StoreListing` when auto-approving sub-agents. Sub-agents are created with `isAvailable=False` (see `_create_sub_agent_version_data`), so they do not appear in public store views and do not need an active version connected. Do not flag the absence of `ActiveVersion` assignment in this function as a bug.
Applied to files:
autogpt_platform/backend/schema.prisma
🔇 Additional comments (2)
autogpt_platform/backend/backend/util/ids.py (1)
6-14: Nice centralization of app-side UUID generation.This keeps Python-created IDs aligned with the new DB defaults and makes future ID policy changes one-touch.
autogpt_platform/backend/migrations/20260430120000_use_uuidv7_for_id_defaults/migration.sql (1)
4-25: Please smoke-test the UUID bit layout before merging.This implementation depends on
set_bit(..., 52/53)landing on the version nibble. If those offsets are off, Postgres will still return UUIDs, but not RFC 9562 v7 values. I’d add a quick migration-level check that the generated values always serialize with a7version nibble and preserve rough timestamp ordering.-- Version nibble should always be 7. SELECT bool_and(substring(uuid_generate_v7()::text FROM 15 FOR 1) = '7') AS all_v7 FROM generate_series(1, 1000); -- Sanity-check emitted values. SELECT uuid_generate_v7() AS sample_uuid FROM generate_series(1, 10);
coderabbit caught that __create_graph mints a fresh id for each AgentNodeLink while the in-memory link object keeps its old id, so callers (e.g. fork_graph) get back a graph whose link.ids no longer match the database rows. - BaseDbModel.id default_factory now uses new_uuid() so in-memory ids are also v7 (was UUIDv4 from the local uuid4() default). - _reassign_ids() now also regenerates link.id during fork. - __create_graph's AgentNodeLink.create_many uses link.id instead of minting a separate one — single source of truth.
|
🤖 @coderabbitai fixed in ae83c3a8f: |
|
Tip For best results, initiate chat on the files or code changes.
✏️ Learnings added
🧠 Learnings usedIf you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## dev #12961 +/- ##
==========================================
- Coverage 70.74% 70.44% -0.31%
==========================================
Files 2200 2201 +1
Lines 165664 166169 +505
Branches 16900 17063 +163
==========================================
- Hits 117206 117052 -154
- Misses 45067 45695 +628
- Partials 3391 3422 +31
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
🧪 E2E Test Report (local, native mode)
Environment
ScenariosA — Migration smoke
B — Schema-default insert path
C — Application-helper / pydantic-default path
D — Existing flow regression
Bugs foundNone. Notes for the reviewer
Summary
|
|
Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly. |
The previous merge resolution took schema.prisma wholesale from HEAD (`git checkout --ours`), which dropped fields that landed on dev between this PR opening and the merge:
- `ChatSession.chatStatus` + `ChatSessionStatus` enum + composite index
- `ChatMessage.metadata`
- `LibraryAgent.isHidden`
Rebuilt schema.prisma from dev's tree, then re-applied this PR's v7 sweep:
- All 40 `@default(uuid())` → `@default(dbgenerated("uuid_generate_v7()"))`
- AnalyticsDetails `gen_random_uuid()` → `uuid_generate_v7()`
- Restored the schema-top contributor note.
|
This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request. |
Why / What / How
Why — random UUIDv4 primary keys insert at random positions in B-tree indexes, which fragments WAL/IO patterns on busy tables (executions, library, audit) and forces every "latest N" query to sort by
createdAtinstead ofid. UUIDv7 puts a millisecond timestamp in the high 48 bits so values are roughly insert-ordered.What — flips every Prisma id default from random
uuid()(and the onegen_random_uuid()site onAnalyticsDetails) to a Postgresuuid_generate_v7()function. Adds a Python helper for code that mints ids before insert.How —
uuid_generate_v7()in a single migration. RFC 9562 layout, built on pgcrypto'sgen_random_uuid()(already in use), millisecond timestamp fromclock_timestamp(). ALTERs every id column's DEFAULT to call it.schema.prismaswitches all@default(uuid())(and theAnalyticsDetailsgen_random_uuid()) to@default(dbgenerated("uuid_generate_v7()")).backend/util/ids.pyexposesnew_uuid()returninguuid_utils.uuid7()as a string.uuid_utilsis promoted from a transitive dep (via langsmith) to a direct dep so the API stays stable.new_uuid():data/graph.py(reassign_ids,_reassign_ids, linkcreate_many),data/auth/api_key.py,data/auth/oauth.py(authorization code, access token, refresh token).Existing UUIDv4 rows are untouched — they remain valid UUIDs and continue to sort lexicographically as before. Only newly generated ids are sortable.
Changes
schema.prisma: ~40@defaultflips todbgenerated("uuid_generate_v7()")migrations/20260430120000_use_uuidv7_for_id_defaults/migration.sql: definesuuid_generate_v7()andALTER TABLE … SET DEFAULTfor every id column (andCreditTransaction.transactionKey)backend/util/ids.py: newnew_uuid()helperbackend/data/graph.py,backend/data/auth/api_key.py,backend/data/auth/oauth.py: route explicit id generation throughnew_uuid(); drop unusedimport uuidpyproject.toml:uuid-utils = "^0.14.1"as a direct depChecklist
For code changes:
poetry run prisma migrate devapplies the new migration cleanly on a fresh dbSELECT uuid_generate_v7();returns a valid v7 (version nibble = 7, variant = 10xx)AgentGraph,LibraryAgent,OAuthAccessToken)reassign_ids,generate_api_key, OAuth code/token creation) writes v7 ids