Skip to content

feat(backend): use sortable UUIDv7 for ID defaults - #12961

Closed
majdyz wants to merge 11 commits into
devfrom
feat/sortable-uuid-v7-defaults
Closed

feat(backend): use sortable UUIDv7 for ID defaults#12961
majdyz wants to merge 11 commits into
devfrom
feat/sortable-uuid-v7-defaults

Conversation

@majdyz

@majdyz majdyz commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

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 createdAt instead of id. 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 one gen_random_uuid() site on AnalyticsDetails) to a Postgres uuid_generate_v7() function. Adds a Python helper for code that mints ids before insert.

How

  1. New SQL function uuid_generate_v7() in a single migration. RFC 9562 layout, built on pgcrypto's gen_random_uuid() (already in use), millisecond timestamp from clock_timestamp(). ALTERs every id column's DEFAULT to call it.
  2. schema.prisma switches all @default(uuid()) (and the AnalyticsDetails gen_random_uuid()) to @default(dbgenerated("uuid_generate_v7()")).
  3. backend/util/ids.py exposes new_uuid() returning uuid_utils.uuid7() as a string. uuid_utils is promoted from a transitive dep (via langsmith) to a direct dep so the API stays stable.
  4. The three call sites that mint ids in Python before insert switch to new_uuid(): data/graph.py (reassign_ids, _reassign_ids, link create_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 @default flips to dbgenerated("uuid_generate_v7()")
  • migrations/20260430120000_use_uuidv7_for_id_defaults/migration.sql: defines uuid_generate_v7() and ALTER TABLE … SET DEFAULT for every id column (and CreditTransaction.transactionKey)
  • backend/util/ids.py: new new_uuid() helper
  • backend/data/graph.py, backend/data/auth/api_key.py, backend/data/auth/oauth.py: route explicit id generation through new_uuid(); drop unused import uuid
  • pyproject.toml: uuid-utils = "^0.14.1" as a direct dep

Checklist

For code changes:

  • I have clearly listed my changes in the PR description
  • I have made a test plan
  • I have tested my changes according to the test plan:
    • poetry run prisma migrate dev applies the new migration cleanly on a fresh db
    • SELECT uuid_generate_v7(); returns a valid v7 (version nibble = 7, variant = 10xx)
    • Inserting via Prisma without an explicit id populates a v7 from the db default (e.g. create an AgentGraph, LibraryAgent, OAuthAccessToken)
    • Inserting via the Python helper paths (reassign_ids, generate_api_key, OAuth code/token creation) writes v7 ids
    • /pr-test golden path still green

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.
@majdyz
majdyz requested a review from a team as a code owner April 30, 2026 14:46
@majdyz
majdyz requested review from Bentlybro and Pwuts and removed request for a team April 30, 2026 14:46
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Apr 30, 2026
@github-actions github-actions Bot added platform/backend AutoGPT Platform - Back end size/l labels Apr 30, 2026
@coderabbitai

coderabbitai Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Switches ID generation to UUIDv7 across the stack: adds a centralized Python new_uuid() helper, updates Python modules to use it for pre-insert IDs, adds a DB migration implementing uuid_generate_v7(), and repoints many Prisma model defaults to that DB function.

Changes

UUIDv7 ID migration

Layer / File(s) Summary
ID Utility
autogpt_platform/backend/backend/util/ids.py
Add new_uuid() returning a sortable UUIDv7 string via uuid_utils.uuid7.
Python model defaults / validators
autogpt_platform/backend/backend/data/db.py
BaseDbModel.id default factory changed to new_uuid; validator fallback updated to new_uuid(); removed direct uuid4 usage.
Pre-insert ID usage
autogpt_platform/backend/backend/data/auth/api_key.py, autogpt_platform/backend/backend/data/auth/oauth.py, autogpt_platform/backend/backend/data/graph.py, autogpt_platform/backend/backend/integrations/webhooks/_base.py
Replace uuid.uuid4()/uuid4() stringified usage with new_uuid(); graph reassignments regenerate node IDs and link IDs via new_uuid(); link row inserts use in-memory link.id.
Database migration
autogpt_platform/backend/migrations/20260430120000_use_uuidv7_for_id_defaults/migration.sql
Add PL/pgSQL uuid_generate_v7() function and update DEFAULT expressions for many id columns and CreditTransaction.transactionKey to use uuid_generate_v7().
Prisma schema defaults
autogpt_platform/backend/schema.prisma
Change many model PK defaults (and CreditTransaction.transactionKey, AnalyticsDetails) from uuid()/gen_random_uuid() to dbgenerated("uuid_generate_v7()"); no other field/type changes.
Dependencies
autogpt_platform/backend/pyproject.toml
Add runtime dependency uuid-utils (>=0.14.1,<1.0.0) to support UUIDv7 generation.
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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

🐇 I hopped through code and spun a clue,

V7 now sorts each id anew,
From helper den to database song,
Tiny hops made changes strong,
A rabbit's cheer — concise and true.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: switching to sortable UUIDv7 for database ID defaults.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, clearly explaining the 'Why/What/How', listing all changes, and including a test plan.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sortable-uuid-v7-defaults

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

🔍 PR Overlap Detection

This check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early.

🔴 Merge Conflicts Detected

The following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.

🟢 Low Risk — File Overlap Only

These 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: openapi.json, lock files.

Comment thread autogpt_platform/backend/pyproject.toml Outdated
Comment thread autogpt_platform/backend/backend/util/ids.py
Comment thread autogpt_platform/backend/schema.prisma
- 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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Preserve link IDs between the returned fork result and the inserted rows.

fork_graph() returns the in-memory graph after __create_graph(), but this path always generates a fresh link ID here instead of persisting link.id. Since _reassign_ids() does not rewrite Link.id, a forked graph can come back with stale link IDs from the source graph while the database rows have different ones. Either regenerate Link.id before 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

📥 Commits

Reviewing files that changed from the base of the PR and between 6ead5a2 and ea62012.

⛔ Files ignored due to path filters (1)
  • autogpt_platform/backend/poetry.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • autogpt_platform/backend/backend/data/auth/api_key.py
  • autogpt_platform/backend/backend/data/auth/oauth.py
  • autogpt_platform/backend/backend/data/graph.py
  • autogpt_platform/backend/backend/util/ids.py
  • autogpt_platform/backend/migrations/20260430120000_use_uuidv7_for_id_defaults/migration.sql
  • autogpt_platform/backend/pyproject.toml
  • autogpt_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: Use poetry run ... command for executing Python package dependencies
Use top-level imports only — avoid local/inner imports except for lazy imports of heavy optional dependencies like openpyxl
Use absolute imports with from 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 — avoid hasattr/getattr/isinstance for 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 %s for deferred interpolation in debug log statements for efficiency; use f-strings elsewhere for readability (e.g., logger.debug("Processing %s items", count) vs logger.info(f"Processing {count} items"))
Sanitize error paths by using os.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
Use transaction=True for Redis pipelines to ensure atomicity on multi-step operations
Use max(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.py
  • autogpt_platform/backend/backend/data/auth/api_key.py
  • autogpt_platform/backend/backend/data/auth/oauth.py
  • autogpt_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.py
  • autogpt_platform/backend/backend/data/auth/api_key.py
  • autogpt_platform/backend/backend/data/auth/oauth.py
  • autogpt_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.py
  • autogpt_platform/backend/backend/data/auth/oauth.py
  • autogpt_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.py
  • autogpt_platform/backend/backend/data/auth/oauth.py
  • autogpt_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.py
  • autogpt_platform/backend/backend/data/auth/api_key.py
  • autogpt_platform/backend/backend/data/auth/oauth.py
  • autogpt_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.py
  • autogpt_platform/backend/backend/data/auth/api_key.py
  • autogpt_platform/backend/backend/data/auth/oauth.py
  • autogpt_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.toml
  • autogpt_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.py
  • autogpt_platform/backend/migrations/20260430120000_use_uuidv7_for_id_defaults/migration.sql
  • autogpt_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.py
  • autogpt_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.py
  • autogpt_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.py
  • autogpt_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 a 7 version 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.
@majdyz

majdyz commented Apr 30, 2026

Copy link
Copy Markdown
Contributor Author

🤖 @coderabbitai fixed in ae83c3a8f: _reassign_ids() now regenerates link.id during fork, and __create_graph uses link.id instead of minting a separate one — keeps the returned graph and the persisted rows in sync. Also bumped BaseDbModel.id default_factory to new_uuid() so all in-memory model ids are v7 too.

@coderabbitai

coderabbitai Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@majdyz Thanks for the detailed summary! The fix looks thorough:

  • _reassign_ids() regenerating link.id during fork closes the ID mismatch between the in-memory graph and persisted rows.
  • ✅ Having __create_graph reuse link.id (rather than minting a separate one) eliminates the double-mint inconsistency.
  • ✅ Bumping BaseDbModel.id default_factory to new_uuid() ensures all in-memory model IDs are UUIDv7 from the start, keeping the Python-side and DB-side defaults aligned.

✏️ Learnings added
Learnt from: majdyz
URL: https://github.com/Significant-Gravitas/AutoGPT/pull/12961

Timestamp: 2026-04-30T15:01:23.981Z
Learning: In Significant-Gravitas/AutoGPT PR `#12961` (feat/sortable-uuid-v7-defaults, commit ae83c3a8f): `BaseDbModel.id` `default_factory` was updated from `uuid.uuid4` to `new_uuid()` (from `backend.util.ids`) so that all in-memory Pydantic model IDs are UUIDv7. Also, `_reassign_ids()` regenerates `link.id` during graph fork and `__create_graph` reuses `link.id` directly instead of minting a separate UUID, keeping the returned graph object and persisted DB rows in sync.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
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: 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: 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).

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: 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.

If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@codecov

codecov Bot commented Apr 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.44%. Comparing base (12cc0f6) to head (d787b67).
⚠️ Report is 45 commits behind head on dev.

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     
Flag Coverage Δ
platform-backend 79.68% <80.00%> (+<0.01%) ⬆️
platform-frontend-e2e 31.39% <ø> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Platform Backend 79.68% <80.00%> (+<0.01%) ⬆️
Platform Frontend 37.19% <ø> (-1.14%) ⬇️
AutoGPT Libs ∅ <ø> (∅)
Classic AutoGPT 28.43% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@majdyz

majdyz commented Apr 30, 2026

Copy link
Copy Markdown
Contributor Author

🧪 E2E Test Report (local, native mode)

  • Date: 2026-04-30
  • Branch: feat/sortable-uuid-v7-defaults @ ae83c3a
  • Worktree: /Users/majdyz/Code/AutoGPT15
  • Mode: native (poetry / shared infra) — backend port-shared with sibling AutoGPT13 stack, so the e2e UI run was substituted by direct DB + import smoke + sibling-stack regression check.

Environment

  • Postgres (supabase-db): healthy, schema platform
  • Redis cluster: healthy (3 nodes)
  • RabbitMQ: healthy
  • Clamav, supabase-auth, supabase-kong: healthy
  • Sibling backend (AutoGPT13) was already bound on :8001/:8002/:8005/:8006/:8008. Shared the same DB after migration; logs show no errors post-apply (only pre-existing Pydantic deprecation warnings).

Scenarios

A — Migration smoke

# Step Result
A.1 poetry run prisma migrate deploy PASS — applied 20260430120000_use_uuidv7_for_id_defaults cleanly on top of dev (3 prior migrations also applied without error).
A.2 SELECT uuid_generate_v7(); returns version=7, variant=8/9/a/b PASS — sample: 019ddef1-c344-7af1-9870-a7537807f65c (version nibble 7, variant a ∈ {8,9,a,b}).
A.3 3 consecutive calls return strictly increasing strings (k-sortable) PASS[c344-7af1-…, c349-749b-…, c34a-736c-…] is already sorted.
A.4 pg_proc shows proparallel='s' (PARALLEL SAFE), provolatile='v' PASS — function is correctly marked PARALLEL SAFE.
A.5 Total columns now defaulting to uuid_generate_v7() PASS40 (matches all 39 id columns + CreditTransaction.transactionKey).

B — Schema-default insert path

# Step Result
B.1 INSERT INTO "BuilderSearchHistory" (...) without an explicit id, RETURNING id PASS — id 019ddef3-1cb8-717b-94f0-bdb2906be338, version=7. Confirms Postgres default now mints v7.

C — Application-helper / pydantic-default path

# Step Result
C.1 from backend.util.ids import new_uuid; new_uuid() PASS — version=7.
C.2 BaseDbModel().id (default_factory) PASS — version=7.
C.3 Link(...) (extends BaseDbModel) PASS — version=7.
C.4 Node(...) and Graph(...) likewise PASS — both v7.

D — Existing flow regression

# Step Result
D.1 Pre-PR rows still load (sample AgentGraph, LibraryAgent, AgentNodeLink rows) PASS — existing UUIDv4 ids load fine; mixed v4/v7 cohabitation in the same column is supported.
D.2 Sibling backend (AutoGPT13) running against the migrated DB stays healthy PASS/docs 200 on rest/websocket, error grep on .ign.application.logs returns only Pydantic deprecation warnings (pre-existing).
D.3 Full UI signup → build → run flow SKIPPED — sibling stack held the app ports. The pieces D.1+D.2 plus A/B/C cover the runtime surface this PR actually touches; killing the sibling stack to re-run the same code path was not justified.

Bugs found

None.

Notes for the reviewer

  • The PR is purely "shape of newly minted ids changes from v4 → v7". Existing rows are untouched and continue to sort lexicographically as before.
  • coderabbit's late finding (link.id stale-vs-DB) was addressed in ae83c3a8f_reassign_ids() now also reassigns link.id, and __create_graph uses link.id directly. BaseDbModel.id default_factory was also bumped to new_uuid() so in-memory model ids are v7 too.
  • Function is marked PARALLEL SAFE, which lets query planners use parallel plans through INSERT … RETURNING id paths.

Summary

  • 11 of 11 in-scope scenarios PASS
  • 1 scenario skipped (full UI flow) due to port-share with sibling agent's stack; covered indirectly by D.2
  • 0 bugs found

@github-actions github-actions Bot removed the conflicts Automatically applied to PRs with merge conflicts label May 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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.
@CLAassistant

CLAassistant commented May 11, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conflicts Automatically applied to PRs with merge conflicts platform/backend AutoGPT Platform - Back end size/l

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants