Skip to content

fix(backend): carry marketplace name/description/image to downloaded library agents - #13680

Merged
Abhi1992002 merged 6 commits into
devfrom
abhimanyuyadav/open-2478-marketplace-data-should-be-downloaded-with-agent
Jul 29, 2026
Merged

fix(backend): carry marketplace name/description/image to downloaded library agents#13680
Abhi1992002 merged 6 commits into
devfrom
abhimanyuyadav/open-2478-marketplace-data-should-be-downloaded-with-agent

Conversation

@Abhi1992002

Copy link
Copy Markdown
Member

Why / What / How

Why: When you add an agent from the marketplace to your library, it shows up with the creator's original graph title and description — not the title/description it was published under — and with no image. The intended behaviour (OPEN-2478 / #9879) is that a downloaded agent appears in your library just as it does in the marketplace.

What: Snapshot the marketplace listing's published name, description and image onto the LibraryAgent at download time, and surface them in the library.

How: LibraryAgent already had an imageUrl column that was never populated on marketplace downloads. This PR follows that same snapshot-at-download pattern:

  • Adds nullable name / description columns to LibraryAgent (migration included). Null for user-created agents, which keep falling back to the graph's own values.
  • add_graph_to_library now reads the StoreListingVersion and writes its name, description and first imageUrls entry onto the LibraryAgent — on both the create and the restore-existing (soft-deleted) paths, so re-downloading also refreshes the snapshot.
  • LibraryAgent.from_db prefers the snapshotted name/description, falling back to graph.name/graph.description.

This is scoped to the "Add to Library" download path; user-created agents (via create_library_agent) are unaffected.

Changes 🏗️

  • schema.prisma: add name / description (both String?) to LibraryAgent; new migration 20260727120000_add_library_agent_marketplace_metadata.
  • _add_to_library.py: new _get_marketplace_metadata() helper; add_graph_to_library snapshots name/description/imageUrl on create and update.
  • library/model.py: from_db uses agent.name or graph.name and agent.description or graph.description.
  • Tests: _add_to_library_test.py (snapshot written on create + restore; helper edge cases) and model_test.py (override precedence + fallback).

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 pytest backend/api/features/library/_add_to_library_test.py backend/api/features/library/model_test.py — 9 passed
    • Verified the from_db fallback path keeps user-created agents on their graph name/description
    • Publish an agent to the marketplace under a different title/description + image, add it to a fresh account's library, confirm the library card shows the published title/description/image

…library agents

When a marketplace agent is added to a user's library, LibraryAgent was
created from the graph alone, so it showed the creator's original graph
title/description and no image instead of the published marketplace values.

Snapshot the StoreListingVersion name, description and first image URL onto
the LibraryAgent at download time (mirroring the existing imageUrl column),
and prefer them in LibraryAgent.from_db, falling back to the graph's own
values for user-created agents.

Closes #9879
@Abhi1992002
Abhi1992002 requested a review from a team as a code owner July 27, 2026 07:53
@Abhi1992002
Abhi1992002 requested review from 0ubbe and ntindle and removed request for a team July 27, 2026 07:53
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Jul 27, 2026
@Abhi1992002

Copy link
Copy Markdown
Member Author

/review

@github-actions github-actions Bot added platform/backend AutoGPT Platform - Back end size/l labels Jul 27, 2026
@autogpt-pr-reviewer

Copy link
Copy Markdown

Queued a review for PR #13680 at c877228.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e470193a-7ee9-4bb9-9a93-f635fc97b0fc

📥 Commits

Reviewing files that changed from the base of the PR and between d2ab404 and 2a0f300.

📒 Files selected for processing (2)
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/model.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📜 Recent review details
⏰ Context from checks skipped due to timeout. (13)
  • GitHub Check: check API types
  • GitHub Check: Seer Code Review
  • GitHub Check: Check PR Status
  • GitHub Check: Analyze (python)
  • GitHub Check: end-to-end tests
  • GitHub Check: Analyze (typescript)
  • GitHub Check: type-check (3.12)
  • GitHub Check: type-check (3.13)
  • GitHub Check: type-check (3.11)
  • GitHub Check: lint
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)

Walkthrough

Library agents now snapshot marketplace name, description, and first image when added or restored. Library responses prefer stored marketplace metadata, and searches match both snapshots and graph metadata.

Changes

Marketplace metadata snapshots

Layer / File(s) Summary
LibraryAgent metadata schema
autogpt_platform/backend/schema.prisma, autogpt_platform/backend/migrations/...
Adds nullable name and description columns to LibraryAgent.
Marketplace metadata capture and persistence
autogpt_platform/backend/backend/api/features/library/_add_to_library.py, autogpt_platform/backend/backend/api/features/library/db.py, autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py, autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
Passes the resolved listing version through library-add flows, snapshots its metadata, persists snapshots on creation, and refreshes them during restoration updates.
Snapshot-aware library responses and search
autogpt_platform/backend/backend/api/features/library/model.py, autogpt_platform/backend/backend/api/features/library/model_test.py, autogpt_platform/backend/backend/api/features/library/db.py, autogpt_platform/backend/backend/api/features/library/db_test.py
Prefers stored marketplace name and description, falls back to graph values when unset, and searches snapshot fields alongside graph metadata.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant add_store_agent_to_library
  participant resolve_graph_for_library
  participant add_graph_to_library
  participant StoreListingVersion
  participant LibraryAgent
  Client->>add_store_agent_to_library: add graph to library
  add_store_agent_to_library->>resolve_graph_for_library: resolve graph and listing version
  resolve_graph_for_library-->>add_store_agent_to_library: GraphModel and StoreListingVersion
  add_store_agent_to_library->>add_graph_to_library: pass resolved listing version
  add_graph_to_library->>StoreListingVersion: read marketplace metadata
  add_graph_to_library->>LibraryAgent: create or refresh snapshot
  LibraryAgent-->>Client: return marketplace-preferred metadata
Loading

Suggested reviewers: 0ubbe, ntindle

Poem

A rabbit hops through fields of code,
And stores the names the market showed.
First image bright, descriptions neat,
Restored agents get snapshots sweet.
Graph or market? The burrow sings—
The stored listing leads the strings.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.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 summarizes the main change: carrying marketplace metadata onto downloaded library agents.
Description check ✅ Passed The description is detailed and directly matches the changeset, including metadata snapshotting, schema updates, and tests.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch abhimanyuyadav/open-2478-marketplace-data-should-be-downloaded-with-agent

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.

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
autogpt_platform/backend/backend/api/features/library/_add_to_library.py (1)

58-77: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use a Pydantic model for marketplace metadata.

_get_marketplace_metadata returns fixed-shape structured data as a raw dict, requiring string-key indexing at every call site. Return a small Pydantic model and access typed attributes instead.

As per coding guidelines, structured data should use Pydantic models over dictionaries.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@autogpt_platform/backend/backend/api/features/library/_add_to_library.py`
around lines 58 - 77, The _get_marketplace_metadata function returns fixed-shape
marketplace data as a raw dictionary. Define a small Pydantic model for the
name, description, and imageUrl fields, return that model from
_get_marketplace_metadata including the missing-listing fallback, and update its
call sites to use typed attributes instead of string-key indexing.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@autogpt_platform/backend/backend/api/features/library/model.py`:
- Around line 352-355: Update the marketplace snapshot fallback assignments for
name and description to use explicit None checks instead of truthiness. Preserve
intentionally empty agent.name and agent.description values, falling back to
graph.name or graph.description only when the corresponding marketplace field is
None.

---

Nitpick comments:
In `@autogpt_platform/backend/backend/api/features/library/_add_to_library.py`:
- Around line 58-77: The _get_marketplace_metadata function returns fixed-shape
marketplace data as a raw dictionary. Define a small Pydantic model for the
name, description, and imageUrl fields, return that model from
_get_marketplace_metadata including the missing-listing fallback, and update its
call sites to use typed attributes instead of string-key indexing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7dd2854c-984d-47f7-8a89-34cfa1ad578f

📥 Commits

Reviewing files that changed from the base of the PR and between 6ccfa17 and c877228.

📒 Files selected for processing (6)
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/migrations/20260727120000_add_library_agent_marketplace_metadata/migration.sql
  • autogpt_platform/backend/schema.prisma
📜 Review details
⏰ Context from checks skipped due to timeout. (15)
  • GitHub Check: check API types
  • GitHub Check: Seer Code Review
  • GitHub Check: test (3.11)
  • GitHub Check: end-to-end tests
  • GitHub Check: lint
  • GitHub Check: test (3.13)
  • GitHub Check: type-check (3.11)
  • GitHub Check: type-check (3.13)
  • GitHub Check: test (3.12)
  • GitHub Check: type-check (3.12)
  • GitHub Check: Check PR Status
  • GitHub Check: types
  • GitHub Check: Analyze (typescript)
  • GitHub Check: lint
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (6)
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
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/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
autogpt_platform/backend/backend/api/features/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Update routes in '/backend/backend/api/features/' and add/update Pydantic models in the same directory for API development

Files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
autogpt_platform/{backend,autogpt_libs}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
autogpt_platform/backend/**/api/**/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/AGENTS.md)

autogpt_platform/backend/**/api/**/*.py: Use Security() instead of Depends() for authentication dependencies to get proper OpenAPI security specification
Follow SSE (Server-Sent Events) protocol: use data: lines for frontend-parsed events (must match Zod schema) and : comment lines for heartbeats/status

Files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
autogpt_platform/backend/**/*_test.py

📄 CodeRabbit inference engine (autogpt_platform/backend/AGENTS.md)

autogpt_platform/backend/**/*_test.py: Use pytest with snapshot testing for API responses
Colocate test files with source files using *_test.py naming convention
Mock at boundaries — mock where the symbol is used, not where it's defined; after refactoring, update mock targets to match new module paths
Use AsyncMock from unittest.mock for async functions in tests
When writing tests, use Test-Driven Development (TDD): write failing tests marked with @pytest.mark.xfail before implementation, then remove the marker once the implementation is complete
When creating snapshots in tests, use poetry run pytest path/to/test.py --snapshot-update; always review snapshot changes with git diff before committing

Files:

  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
🧠 Learnings (14)
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.

Applied to files:

  • autogpt_platform/backend/migrations/20260727120000_add_library_agent_marketplace_metadata/migration.sql
  • autogpt_platform/backend/schema.prisma
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-05-09T10:56:21.839Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 13069
File: autogpt_platform/backend/migrations/20260509120000_add_chat_message_queue_status/migration.sql:1-13
Timestamp: 2026-05-09T10:56:21.839Z
Learning: In autogpt_platform/backend migrations (PostgreSQL), assume the `platform` schema is created/bootstrapped by the surrounding deployment infrastructure before Prisma migrations run. Therefore, individual migration SQL files should NOT include `CREATE SCHEMA IF NOT EXISTS "platform"` (or similar schema-creation statements); the schema should already exist, and adding it in each migration can cause unnecessary/incorrect expectations. Flag this as a review issue if present in migration `.sql` files.

Applied to files:

  • autogpt_platform/backend/migrations/20260727120000_add_library_agent_marketplace_metadata/migration.sql
📚 Learning: 2026-06-15T09:07:09.084Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 13359
File: autogpt_platform/backend/migrations/20260615120000_add_user_workspace_folders/migration.sql:21-22
Timestamp: 2026-06-15T09:07:09.084Z
Learning: When reviewing Prisma-managed schema changes/migrations in this repository, do not recommend adding partial/expression unique indexes (e.g., `CREATE UNIQUE INDEX ... WHERE "parentId" IS NULL`) because Prisma cannot represent them in `schema.prisma`; adding them via raw SQL will create schema drift and repeated changes on future `prisma migrate dev` runs. For root-folder name uniqueness, the intended approach is the existing application-layer guard (`_root_name_taken` checks in `create_folder`/`update_folder` in `autogpt_platform/backend/backend/data/workspace_folder.py`) rather than a DB partial/index-based constraint. Prefer Prisma-supported uniqueness constraints, and if a uniqueness rule requires conditional logic, implement it at the application layer.

Applied to files:

  • autogpt_platform/backend/migrations/20260727120000_add_library_agent_marketplace_metadata/migration.sql
📚 Learning: 2026-07-20T23:28:10.519Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 13621
File: autogpt_platform/backend/migrations/20260718120000_add_llm_catalog_runtime_tables/migration.sql:28-29
Timestamp: 2026-07-20T23:28:10.519Z
Learning: When reviewing SQL migration files under autogpt_platform/backend/migrations, do not treat DB constructs (e.g., raw-SQL partial unique indexes and CHECK constraints) as “Prisma schema drift” solely because Prisma cannot model them, as long as they follow the repo’s established workflow (`migrate deploy`/`migrate reset`) and are documented/intentional in `schema.prisma`.

For concurrency-sensitive invariants, keep the database-enforced mechanism (e.g., a partial unique index preventing simultaneous active `LlmModelMigration` rows per `sourceModelSlug`) and avoid recommending application-level check-then-insert logic, since it is vulnerable to TOCTOU races.

Applied to files:

  • autogpt_platform/backend/migrations/20260727120000_add_library_agent_marketplace_metadata/migration.sql
📚 Learning: 2026-03-05T15:42:08.207Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12297
File: .claude/skills/backend-check/SKILL.md:14-16
Timestamp: 2026-03-05T15:42:08.207Z
Learning: In Python files under autogpt_platform/backend (recursively), rely on poetry run format to perform formatting (Black + isort) and linting (ruff). Do not run poetry run lint as a separate step after poetry run format, since format already includes linting checks.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-03-16T16:35:40.236Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/api/features/workflow_import.py:54-63
Timestamp: 2026-03-16T16:35:40.236Z
Learning: Avoid using the word 'competitor' in public-facing identifiers and text. Use neutral naming for API paths, model names, function names, and UI text. Examples: rename 'CompetitorFormat' to 'SourcePlatform', 'convert_competitor_workflow' to 'convert_workflow', '/competitor-workflow' to '/workflow'. Apply this guideline to files under autogpt_platform/backend and autogpt_platform/frontend.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-03-31T15:37:38.626Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/backend/backend/copilot/tools/agent_generator/fixer.py:37-47
Timestamp: 2026-03-31T15:37:38.626Z
Learning: When validating/constructing Anthropic API model IDs in Significant-Gravitas/AutoGPT, allow the hyphen-separated Claude Opus 4.6 model ID `claude-opus-4-6` (it corresponds to `LlmModel.CLAUDE_4_6_OPUS` in `autogpt_platform/backend/backend/blocks/llm.py`). Do NOT require the dot-separated form in Anthropic contexts. Only OpenRouter routing variants should use the dot separator (e.g., `anthropic/claude-opus-4.6`); `claude-opus-4-6` should be treated as correct when passed to Anthropic, and flagged only if it’s used in the OpenRouter path where the dot form is expected.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-04-15T02:43:36.890Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12780
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:0-0
Timestamp: 2026-04-15T02:43:36.890Z
Learning: When reviewing Python exception handlers, do not flag `isinstance(e, X)` checks as dead/unreachable if the caught exception `X` is a subclass of the exception type being handled. For example, if `X` (e.g., `VirusScanError`) inherits from `ValueError` (directly or via an intermediate class) and it can be raised within an `except ValueError:` block, then `isinstance(e, X)` inside that handler is reachable and should not be treated as dead code.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-05-23T05:29:43.085Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 13200
File: autogpt_platform/backend/backend/executor/scheduler.py:590-593
Timestamp: 2026-05-23T05:29:43.085Z
Learning: When reviewing Python code that uses Pydantic discriminated/tagged unions (e.g., `Annotated[Union[...], Field(discriminator="kind")]`), recognize that using `isinstance(x, SomeVariantInfo)` to narrow the union is an intentional and correct runtime guard and should also enable static type narrowing in tools like Pyright. Do not recommend replacing such `isinstance`-based narrowing with `cast(...)` when the check already proves the variant at runtime.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-04-22T11:46:04.431Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/config.py:0-0
Timestamp: 2026-04-22T11:46:04.431Z
Learning: Do not flag the Claude Sonnet 4.6 model ID as incorrect when it uses the project’s established hyphenated convention: `anthropic/claude-sonnet-4-6`. This hyphen form is the intentional, production convention and should be treated as valid (including in files like llm.py, blocks tests, reasoning.py, `_is_anthropic_model` tests, and config defaults). Note that OpenRouter also accepts the dot variant `anthropic/claude-sonnet-4.6`, so either form may be tolerated, but `anthropic/claude-sonnet-4-6` should be considered the standard to match project usage.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-04-22T11:46:12.892Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/baseline/service.py:322-332
Timestamp: 2026-04-22T11:46:12.892Z
Learning: In this codebase (Significant-Gravitas/AutoGPT), OpenRouter-routed Anthropic model IDs should use the hyphen-separated convention (e.g., `anthropic/claude-sonnet-4-6`, `anthropic/claude-opus-4-6`). Although OpenRouter may accept both hyphen and dot variants, treat the hyphen-separated form as the intended, correct codebase-wide convention and do not flag it as an error. Only flag the dot-separated variant (e.g., `anthropic/claude-sonnet-4.6`) as incorrect when reviewing/validating model ID strings for OpenRouter-routed Anthropic models.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-05-07T18:48:14.242Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 13040
File: autogpt_platform/backend/backend/blocks/llm.py:0-0
Timestamp: 2026-05-07T18:48:14.242Z
Learning: In this repository, isort may split imports from the same module into separate blocks when some imports are aliased (e.g., `from module import X as Y`) and others are not. Preserve the two-block layout when it results from isort (such as keeping `from openai.types.chat import ChatCompletion as OpenAIChatCompletion` separate from non-aliased imports from `openai.types.chat`). Do not treat that split as a style issue during review; merging them into a single block can fail CI with `Imports are incorrectly sorted and/or formatted`.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-05-26T14:24:34.866Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 13217
File: autogpt_platform/backend/backend/api/features/search/service.py:137-137
Timestamp: 2026-05-26T14:24:34.866Z
Learning: In the Significant-Gravitas/AutoGPT backend, treat `user_id` (an opaque UUID used only for correlation/tracing) as non-PII. Do not flag direct logging of `user_id` in `logger.warning`/`logger.info` statements as a PII exposure issue, as the established convention is to log `user_id` for tracing while reserving PII for fields like email or display name.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-06-11T19:39:10.493Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 13337
File: autogpt_platform/backend/backend/copilot/graphiti/reranker.py:0-0
Timestamp: 2026-06-11T19:39:10.493Z
Learning: In the Significant-Gravitas/AutoGPT Python backend, when calling the OpenAI Python client `chat.completions.create`, construct the `messages` payload using the concrete typed-dict variants from `openai.types.chat` (e.g., `ChatCompletionSystemMessageParam`, `ChatCompletionUserMessageParam`, etc.) rather than trying to instantiate `ChatCompletionMessageParam` directly. `ChatCompletionMessageParam` is a `Union` alias and is not constructible, so `ChatCompletionMessageParam(role=..., content=...)` should fail type checking. Build each message element with the appropriate concrete typed dict and then annotate the resulting list as `list[ChatCompletionMessageParam]` (e.g., `messages: list[ChatCompletionMessageParam] = [ChatCompletionSystemMessageParam(...), ...]`).

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
🔇 Additional comments (5)
autogpt_platform/backend/migrations/20260727120000_add_library_agent_marketplace_metadata/migration.sql (1)

1-7: LGTM!

autogpt_platform/backend/schema.prisma (1)

611-616: LGTM!

autogpt_platform/backend/backend/api/features/library/_add_to_library.py (1)

96-96: LGTM!

Also applies to: 113-121, 134-136

autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py (1)

6-12: LGTM!

Also applies to: 34-37, 54-57, 79-82, 107-110, 113-146

autogpt_platform/backend/backend/api/features/library/model_test.py (1)

14-15: LGTM!

Also applies to: 27-28, 48-68

Comment thread autogpt_platform/backend/backend/api/features/library/model.py Outdated
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.72131% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.59%. Comparing base (bdc2b5f) to head (2a0f300).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #13680      +/-   ##
==========================================
- Coverage   76.64%   76.59%   -0.05%     
==========================================
  Files        2715     2715              
  Lines      207923   207926       +3     
  Branches    19947    19934      -13     
==========================================
- Hits       159370   159270     -100     
- Misses      44153    44253     +100     
- Partials     4400     4403       +3     
Flag Coverage Δ
platform-backend 83.25% <96.72%> (-0.01%) ⬇️
platform-frontend-e2e 31.02% <ø> (-0.22%) ⬇️

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

Components Coverage Δ
Platform Backend 83.25% <96.72%> (-0.01%) ⬇️
Platform Frontend 51.07% <ø> (-0.33%) ⬇️
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.

@autogpt-pr-reviewer autogpt-pr-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📋 Automated Review — PR #13680

PR #13680 — fix(backend): carry marketplace name/description/image to downloaded library agents
Author: Abhi1992002 | Files: 6

🎯 Verdict: REQUEST_CHANGES

PR Description Quality

✅ Has Why + What + How — the snapshot-at-download rationale is clear. ⚠️ One gap: the final end-to-end verification checkbox (publish under a different title → add to fresh account → confirm card) is left unchecked, and that omission is what let the CI regression below slip through locally.

What This PR Does

When a user adds a marketplace agent to their library, the library card previously showed the creator's original graph title/description/image rather than the published marketplace values. This PR snapshots the published name/description/imageUrl from the StoreListingVersion onto the LibraryAgent row at download time (two new nullable columns + read-time fallback to the graph), so the card reflects what was published. The snapshot is written on both the create and re-download/restore paths.

Specialist Findings

🛡️ Security ✅ — Traced the full download path (add_store_agent_to_libraryresolve_graph_for_libraryget_graph APPROVED gate → snapshot). No auth/authz boundary, SQL injection, or secrets issues; migration only adds two nullable TEXT columns.
🟡 Snapshot helper (_add_to_library.py:68) doesn't re-assert submissionStatus == APPROVED, so an owned/mismatched SLV could snapshot unreviewed text/image — but blast radius is the requesting user's own, React-escaped library card. Defense-in-depth only.

🏗️ Architecture ⚠️ — Snapshot-at-download design is sound and consistent with the existing imageUrl precedent; layering is fine.
🟠 _get_marketplace_metadata re-fetches the same StoreListingVersion already loaded by resolve_graph_for_library (_add_to_library.py:68 vs :35) — the root cause of the CI failure below.
🟠 Restore/update path can overwrite a populated snapshot with all-NULLs if the listing lookup returns nothing (_add_to_library.py:~131).

Performance ⚠️ — All operations O(1), no N+1. One avoidable duplicate StoreListingVersion PK read per add-to-library call, since the scalar name/description/imageUrls are already on the upstream-loaded slv. Zero-cost to eliminate.

🧪 Testing ⚠️ — Create, restore, and helper edge cases are covered with meaningful (value-checking) assertions — not slop. Gaps: the empty-imageUrls branch (_add_to_library.py:78), per-field mixed fallback in from_db, and empty-string semantics are untested.

📖 Quality ✅ — Clean, well-commented change explaining why. Nits: cryptic slv local; dict[str, str|None] return indexed by magic-string keys would be safer as a TypedDict/dataclass.

📦 Product ⚠️ — Display fix is correct, but library search still indexes the original graph name/description (db.py:192, embeddings.py:39), so a downloaded agent may not be findable by the published title the user now sees — the exact population this PR targets.

📬 Discussion ❌ — GitHub CI is red: test (3.11) and test (3.13) fail on db_test.py::test_add_agent_to_library ("Expected find_unique to be called once. Called 2 times."). One open CodeRabbit nitpick (empty-string fallback) unaddressed; 0 human reviews.

🔎 QA ✅ — Exercised the real add-to-library path end-to-end with sentinel published values differing from the graph. Create (201), DB snapshot, list API, restore/re-download refresh, null-fallback, and negatives (401/404/422) all PASS; the rendered card shows "PUBLISHED Calculator Title", not the graph name.

🔴 Blockers

  1. New second find_unique breaks existing test — GitHub CI red (autogpt_platform/backend/backend/api/features/library/_add_to_library.py:66) — _get_marketplace_metadata issues a second StoreListingVersion.find_unique(), but the unmodified db_test.py::test_add_agent_to_library asserts it's called exactly once. test (3.11) and test (3.13) fail on this PR's own change. Reusing the row already loaded by resolve_graph_for_library (with include: {AgentGraph: True}) fixes both the failing test and the redundant query. (Flagged by: discussion, architect, performance, quality — 4 specialists)

🟠 Should Fix

  1. Restore path can wipe a good snapshot with NULLs (_add_to_library.py:~131) — if the metadata lookup returns all-None (missing listing/race), the update overwrites a previously populated name/description/imageUrl with NULL. Write snapshot fields only when non-null on the update path. (architect)
  2. Search desyncs from display (db.py:192, embeddings.py:39) — lexical filter and semantic embedding still key off graph.name/graph.description, so an agent shown as "SEO Optimizer Pro" but graph-named "my-test-graph-v2" won't surface when searched by its visible title. COALESCE the snapshot over the graph values in both surfaces, or explicitly scope search as an accepted follow-up. (product — 2 findings)
  3. Empty-string or fallback (model.py:355) — agent.name or graph.name (and description) treats a published "" as unset and falls back to the graph. Use agent.name if agent.name is not None else graph.name to honor the snapshot contract, and reply to the open CodeRabbit comment. (Flagged by: architect, quality, testing, product, discussion + CodeRabbit — 5 specialists)
  4. Untested branches (_add_to_library.py:78, model_test.py:48) — add coverage for listing-with-empty-imageUrls (imageUrl null while name/desc populated) and per-field mixed fallback in from_db. Cheap to add and would have surfaced item #3. (testing)

🟡 Nice to Have

  1. Typed metadata return (_add_to_library.py:58) — replace dict[str, str|None] + magic-string keys with a TypedDict/dataclass for typo protection. (quality)
  2. Migration is non-retroactive (migration.sql:6) — already-downloaded agents keep NULL snapshots until re-downloaded; note in the changelog or add a backfill if retroactive correctness is desired. (architect)
  3. Approval-gate hardening (_add_to_library.py:68) — assert slv.agentGraphId == graph_model.id / submissionStatus == APPROVED on the non-admin path as defense-in-depth. (security)

🔵 Nits

  1. slv abbreviation (_add_to_library.py:66) — spell out as store_listing_version to match the parameter name. (quality)

Human Review Needed

NO — This is an isolated backend data-layer change with no auth/authz, credential, or trust-boundary impact; QA has proven the user-visible behavior end-to-end. It needs the CI regression fixed, not human eyes on the security boundary.

Risk Assessment

Merge risk: MEDIUM (CI currently red; additive nullable columns make the data change itself low-risk) | Rollback: EASY — additive migration, read-time fallback, no destructive changes.

CI Status

GitHub CI: ❌ FAILINGtest (3.11) and test (3.13) fail on db_test.py::test_add_agent_to_library (duplicate find_unique), per the discussion specialist; test (3.12) pending. ~35 other checks green (lint, type-check, CodeQL, E2E, CLA, size/scope).
Local harness (review sandbox): frontend lint ✅, backend poetry run lint ✅, frontend types ✅, frontend test:unit ✅, frontend build ✅ — backend pytest was not run locally.


UI Testing — Variant Results

✅ local: Verified end-to-end: marketplace name/description/image snapshot onto LibraryAgent on add and on re-download restore, fall back to graph values when null, and render in the library card; all negative cases behave correctly.

✅ hosted: Snapshot of marketplace name/description/image onto downloaded library agents works correctly on create, restore, and fallback paths (verified via API, DB, and UI); one non-blocking concern that the displayed snapshot title is not searchable because library search still matches only the graph name.

  • medium: The library card now displays the snapshotted marketplace name/description (agent.name or graph.name), but library search still matches only the graph's name/description, not the new LibraryAgent.name/description columns. A user who searches the exact title shown on the card ('QA REFRESHED TITLE v2') gets 0 results; the agent is only findable via the graph name they never see (search_term=Calculator -> 1 result, search_term=QA REFRESHED -> 0 results).

Comment thread autogpt_platform/backend/backend/api/features/library/_add_to_library.py Outdated
Comment thread autogpt_platform/backend/backend/api/features/library/_add_to_library.py Outdated
Comment thread autogpt_platform/backend/backend/api/features/library/_add_to_library.py Outdated
Comment thread autogpt_platform/backend/backend/api/features/library/model.py Outdated
Comment thread autogpt_platform/backend/backend/api/features/library/model.py Outdated
Comment thread autogpt_platform/backend/backend/api/features/library/model.py
Comment thread autogpt_platform/backend/backend/api/features/library/_add_to_library.py Outdated
Comment thread autogpt_platform/backend/backend/api/features/library/model.py Outdated
Comment thread autogpt_platform/backend/backend/api/features/library/model.py
@github-project-automation github-project-automation Bot moved this from 🆕 Needs initial review to 🚧 Needs work in AutoGPT development kanban Jul 27, 2026
…pshot

Thread the StoreListingVersion already fetched by resolve_graph_for_library
into add_graph_to_library instead of re-querying it, removing a redundant DB
round-trip (and fixing db_test's single-find_unique assertion). Also preserve
an intentionally-empty published name/description in from_db by falling back
only when the snapshot is None, not when it is an empty string.
Comment thread autogpt_platform/backend/backend/api/features/library/model.py

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
autogpt_platform/backend/backend/api/features/library/_add_to_library.py (1)

149-149: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Use deferred interpolation for this debug log.

The f-string formats values even when debug logging is disabled. Use %s placeholders for the complete log statement.

Proposed fix
-    logger.debug(
-        f"Added graph #{graph_model.id} v{graph_model.version} "
-        f"for store listing version #{store_listing_version.id} "
-        f"to library for user #{user_id}"
-    )
+    logger.debug(
+        "Added graph #%s v%s for store listing version #%s to library for user #%s",
+        graph_model.id,
+        graph_model.version,
+        store_listing_version.id,
+        user_id,
+    )

As per coding guidelines, use %s for deferred interpolation in debug logs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@autogpt_platform/backend/backend/api/features/library/_add_to_library.py` at
line 149, Update the debug log statement containing the store listing version
message to use %s placeholders throughout, passing dynamic values as logger
arguments instead of using an f-string; preserve the existing message and
logging behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@autogpt_platform/backend/backend/api/features/library/_add_to_library.py`:
- Around line 70-76: Validate creator-controlled image URLs before the library
snapshot is persisted, covering the imageUrls handling in the returned
LibraryAgent data. Allow only HTTPS URLs from the configured trusted-origin
allowlist, and reject or omit disallowed values so untrusted origins are never
copied into users’ LibraryAgent records.
- Around line 35-36: Update the non-admin path in get_graph so the selected
StoreListingVersion is authorized together with the graph: require approved and
non-deleted status and verify its association with that graph before returning
it. Preserve the separate admin bypass, and ensure the returned listing is the
exact authorized version used for marketplace metadata snapshots.

---

Nitpick comments:
In `@autogpt_platform/backend/backend/api/features/library/_add_to_library.py`:
- Line 149: Update the debug log statement containing the store listing version
message to use %s placeholders throughout, passing dynamic values as logger
arguments instead of using an f-string; preserve the existing message and
logging behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cc21f199-579d-47bd-8021-a2900ebf8a0c

📥 Commits

Reviewing files that changed from the base of the PR and between c877228 and 91a828f.

📒 Files selected for processing (6)
  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • autogpt_platform/backend/backend/api/features/library/model.py
  • autogpt_platform/backend/backend/api/features/library/model_test.py
📜 Review details
⏰ Context from checks skipped due to timeout. (15)
  • GitHub Check: check API types
  • GitHub Check: Seer Code Review
  • GitHub Check: lint
  • GitHub Check: end-to-end tests
  • GitHub Check: types
  • GitHub Check: type-check (3.11)
  • GitHub Check: lint
  • GitHub Check: test (3.11)
  • GitHub Check: type-check (3.13)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.13)
  • GitHub Check: type-check (3.12)
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (typescript)
  • GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (5)
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/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
autogpt_platform/backend/backend/api/features/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Update routes in '/backend/backend/api/features/' and add/update Pydantic models in the same directory for API development

Files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
autogpt_platform/{backend,autogpt_libs}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
autogpt_platform/backend/**/api/**/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/AGENTS.md)

autogpt_platform/backend/**/api/**/*.py: Use Security() instead of Depends() for authentication dependencies to get proper OpenAPI security specification
Follow SSE (Server-Sent Events) protocol: use data: lines for frontend-parsed events (must match Zod schema) and : comment lines for heartbeats/status

Files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
autogpt_platform/backend/**/*_test.py

📄 CodeRabbit inference engine (autogpt_platform/backend/AGENTS.md)

autogpt_platform/backend/**/*_test.py: Use pytest with snapshot testing for API responses
Colocate test files with source files using *_test.py naming convention
Mock at boundaries — mock where the symbol is used, not where it's defined; after refactoring, update mock targets to match new module paths
Use AsyncMock from unittest.mock for async functions in tests
When writing tests, use Test-Driven Development (TDD): write failing tests marked with @pytest.mark.xfail before implementation, then remove the marker once the implementation is complete
When creating snapshots in tests, use poetry run pytest path/to/test.py --snapshot-update; always review snapshot changes with git diff before committing

Files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
🧠 Learnings (12)
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-03-05T15:42:08.207Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12297
File: .claude/skills/backend-check/SKILL.md:14-16
Timestamp: 2026-03-05T15:42:08.207Z
Learning: In Python files under autogpt_platform/backend (recursively), rely on poetry run format to perform formatting (Black + isort) and linting (ruff). Do not run poetry run lint as a separate step after poetry run format, since format already includes linting checks.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-03-16T16:35:40.236Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/api/features/workflow_import.py:54-63
Timestamp: 2026-03-16T16:35:40.236Z
Learning: Avoid using the word 'competitor' in public-facing identifiers and text. Use neutral naming for API paths, model names, function names, and UI text. Examples: rename 'CompetitorFormat' to 'SourcePlatform', 'convert_competitor_workflow' to 'convert_workflow', '/competitor-workflow' to '/workflow'. Apply this guideline to files under autogpt_platform/backend and autogpt_platform/frontend.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-03-24T21:27:19.455Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12536
File: autogpt_platform/frontend/src/app/api/openapi.json:5732-5752
Timestamp: 2026-03-24T21:27:19.455Z
Learning: For FastAPI admin endpoints, avoid adding explicit 403/404 status-code entries in the route decorator (e.g., for the OpenAPI schema) solely to shape OpenAPI output. Keep openapi.json generation automatic, and instead document admin-only (403) and not-found (404) behavior via route docstrings. Enforce the actual behavior with automated tests rather than relying on decorator OpenAPI overrides.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
📚 Learning: 2026-03-31T15:37:38.626Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/backend/backend/copilot/tools/agent_generator/fixer.py:37-47
Timestamp: 2026-03-31T15:37:38.626Z
Learning: When validating/constructing Anthropic API model IDs in Significant-Gravitas/AutoGPT, allow the hyphen-separated Claude Opus 4.6 model ID `claude-opus-4-6` (it corresponds to `LlmModel.CLAUDE_4_6_OPUS` in `autogpt_platform/backend/backend/blocks/llm.py`). Do NOT require the dot-separated form in Anthropic contexts. Only OpenRouter routing variants should use the dot separator (e.g., `anthropic/claude-opus-4.6`); `claude-opus-4-6` should be treated as correct when passed to Anthropic, and flagged only if it’s used in the OpenRouter path where the dot form is expected.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-04-15T02:43:36.890Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12780
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:0-0
Timestamp: 2026-04-15T02:43:36.890Z
Learning: When reviewing Python exception handlers, do not flag `isinstance(e, X)` checks as dead/unreachable if the caught exception `X` is a subclass of the exception type being handled. For example, if `X` (e.g., `VirusScanError`) inherits from `ValueError` (directly or via an intermediate class) and it can be raised within an `except ValueError:` block, then `isinstance(e, X)` inside that handler is reachable and should not be treated as dead code.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-05-23T05:29:43.085Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 13200
File: autogpt_platform/backend/backend/executor/scheduler.py:590-593
Timestamp: 2026-05-23T05:29:43.085Z
Learning: When reviewing Python code that uses Pydantic discriminated/tagged unions (e.g., `Annotated[Union[...], Field(discriminator="kind")]`), recognize that using `isinstance(x, SomeVariantInfo)` to narrow the union is an intentional and correct runtime guard and should also enable static type narrowing in tools like Pyright. Do not recommend replacing such `isinstance`-based narrowing with `cast(...)` when the check already proves the variant at runtime.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-04-22T11:46:04.431Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/config.py:0-0
Timestamp: 2026-04-22T11:46:04.431Z
Learning: Do not flag the Claude Sonnet 4.6 model ID as incorrect when it uses the project’s established hyphenated convention: `anthropic/claude-sonnet-4-6`. This hyphen form is the intentional, production convention and should be treated as valid (including in files like llm.py, blocks tests, reasoning.py, `_is_anthropic_model` tests, and config defaults). Note that OpenRouter also accepts the dot variant `anthropic/claude-sonnet-4.6`, so either form may be tolerated, but `anthropic/claude-sonnet-4-6` should be considered the standard to match project usage.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-04-22T11:46:12.892Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/baseline/service.py:322-332
Timestamp: 2026-04-22T11:46:12.892Z
Learning: In this codebase (Significant-Gravitas/AutoGPT), OpenRouter-routed Anthropic model IDs should use the hyphen-separated convention (e.g., `anthropic/claude-sonnet-4-6`, `anthropic/claude-opus-4-6`). Although OpenRouter may accept both hyphen and dot variants, treat the hyphen-separated form as the intended, correct codebase-wide convention and do not flag it as an error. Only flag the dot-separated variant (e.g., `anthropic/claude-sonnet-4.6`) as incorrect when reviewing/validating model ID strings for OpenRouter-routed Anthropic models.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-05-07T18:48:14.242Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 13040
File: autogpt_platform/backend/backend/blocks/llm.py:0-0
Timestamp: 2026-05-07T18:48:14.242Z
Learning: In this repository, isort may split imports from the same module into separate blocks when some imports are aliased (e.g., `from module import X as Y`) and others are not. Preserve the two-block layout when it results from isort (such as keeping `from openai.types.chat import ChatCompletion as OpenAIChatCompletion` separate from non-aliased imports from `openai.types.chat`). Do not treat that split as a style issue during review; merging them into a single block can fail CI with `Imports are incorrectly sorted and/or formatted`.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-05-26T14:24:34.866Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 13217
File: autogpt_platform/backend/backend/api/features/search/service.py:137-137
Timestamp: 2026-05-26T14:24:34.866Z
Learning: In the Significant-Gravitas/AutoGPT backend, treat `user_id` (an opaque UUID used only for correlation/tracing) as non-PII. Do not flag direct logging of `user_id` in `logger.warning`/`logger.info` statements as a PII exposure issue, as the established convention is to log `user_id` for tracing while reserving PII for fields like email or display name.

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
📚 Learning: 2026-06-11T19:39:10.493Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 13337
File: autogpt_platform/backend/backend/copilot/graphiti/reranker.py:0-0
Timestamp: 2026-06-11T19:39:10.493Z
Learning: In the Significant-Gravitas/AutoGPT Python backend, when calling the OpenAI Python client `chat.completions.create`, construct the `messages` payload using the concrete typed-dict variants from `openai.types.chat` (e.g., `ChatCompletionSystemMessageParam`, `ChatCompletionUserMessageParam`, etc.) rather than trying to instantiate `ChatCompletionMessageParam` directly. `ChatCompletionMessageParam` is a `Union` alias and is not constructible, so `ChatCompletionMessageParam(role=..., content=...)` should fail type checking. Build each message element with the appropriate concrete typed dict and then annotate the resulting list as `list[ChatCompletionMessageParam]` (e.g., `messages: list[ChatCompletionMessageParam] = [ChatCompletionSystemMessageParam(...), ...]`).

Applied to files:

  • autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library.py
  • autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py
🔇 Additional comments (5)
autogpt_platform/backend/backend/api/features/library/_add_to_library.py (2)

61-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use a typed snapshot model instead of a string-keyed dict.

Callers access marketplace["name"], marketplace["description"], and marketplace["imageUrl"], so typos become runtime failures. Return a small Pydantic model and use attribute access.

As per coding guidelines, use Pydantic models over dicts for structured data.

Source: Coding guidelines


81-84: LGTM!

Also applies to: 97-97, 114-116, 121-122, 135-137

autogpt_platform/backend/backend/api/features/library/db.py (1)

1154-1157: LGTM!

Also applies to: 1171-1174

autogpt_platform/backend/backend/api/features/library/_add_to_library_test.py (1)

6-23: LGTM!

Also applies to: 48-48, 61-64, 94-94, 110-113, 116-140

autogpt_platform/backend/backend/api/features/admin/store_admin_routes_test.py (1)

252-257: LGTM!

Also applies to: 292-297

Library search matched only the graph's name/description, so searching the
marketplace title shown on a downloaded agent's card returned no results.
Also match the snapshotted LibraryAgent name/description columns.

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
autogpt_platform/backend/backend/api/features/library/db_test.py (1)

140-150: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use AsyncMock from unittest.mock.

The test currently uses mocker.AsyncMock; import AsyncMock from unittest.mock and use it for these async mocks, as required by the backend test guidelines.

Proposed change
+from unittest.mock import AsyncMock
+
-mock_agent_graph.return_value.find_many = mocker.AsyncMock(return_value=[])
+mock_agent_graph.return_value.find_many = AsyncMock(return_value=[])

-mock_find_many = mocker.AsyncMock(return_value=[])
+mock_find_many = AsyncMock(return_value=[])

-mock_library_agent.return_value.count = mocker.AsyncMock(return_value=0)
+mock_library_agent.return_value.count = AsyncMock(return_value=0)

-    new=mocker.AsyncMock(return_value={}),
+    new=AsyncMock(return_value={}),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@autogpt_platform/backend/backend/api/features/library/db_test.py` around
lines 140 - 150, Update the test mocks around mock_agent_graph,
mock_library_agent, and _fetch_execution_counts to use AsyncMock imported from
unittest.mock instead of mocker.AsyncMock. Preserve the existing return values
and patch targets.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@autogpt_platform/backend/backend/api/features/library/db_test.py`:
- Around line 153-166: Add an assertion in the list_library_agents search test
for the fourth where["OR"] branch, verifying AgentGraph.is.description contains
"Published Title" with insensitive matching. Keep the existing assertions
unchanged.

---

Nitpick comments:
In `@autogpt_platform/backend/backend/api/features/library/db_test.py`:
- Around line 140-150: Update the test mocks around mock_agent_graph,
mock_library_agent, and _fetch_execution_counts to use AsyncMock imported from
unittest.mock instead of mocker.AsyncMock. Preserve the existing return values
and patch targets.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f46cbe49-2982-47d5-9120-7726a78ca13e

📥 Commits

Reviewing files that changed from the base of the PR and between 91a828f and cd4d995.

📒 Files selected for processing (2)
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/api/features/library/db_test.py
📜 Review details
⏰ Context from checks skipped due to timeout. (15)
  • GitHub Check: check API types
  • GitHub Check: end-to-end tests
  • GitHub Check: test (3.13)
  • GitHub Check: type-check (3.13)
  • GitHub Check: test (3.12)
  • GitHub Check: type-check (3.11)
  • GitHub Check: lint
  • GitHub Check: type-check (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: Seer Code Review
  • GitHub Check: Check PR Status
  • GitHub Check: Analyze (typescript)
  • GitHub Check: Analyze (python)
  • GitHub Check: types
  • GitHub Check: lint
🧰 Additional context used
📓 Path-based instructions (5)
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/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
autogpt_platform/backend/backend/api/features/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Update routes in '/backend/backend/api/features/' and add/update Pydantic models in the same directory for API development

Files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
autogpt_platform/{backend,autogpt_libs}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
autogpt_platform/backend/**/api/**/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/AGENTS.md)

autogpt_platform/backend/**/api/**/*.py: Use Security() instead of Depends() for authentication dependencies to get proper OpenAPI security specification
Follow SSE (Server-Sent Events) protocol: use data: lines for frontend-parsed events (must match Zod schema) and : comment lines for heartbeats/status

Files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
autogpt_platform/backend/**/*_test.py

📄 CodeRabbit inference engine (autogpt_platform/backend/AGENTS.md)

autogpt_platform/backend/**/*_test.py: Use pytest with snapshot testing for API responses
Colocate test files with source files using *_test.py naming convention
Mock at boundaries — mock where the symbol is used, not where it's defined; after refactoring, update mock targets to match new module paths
Use AsyncMock from unittest.mock for async functions in tests
When writing tests, use Test-Driven Development (TDD): write failing tests marked with @pytest.mark.xfail before implementation, then remove the marker once the implementation is complete
When creating snapshots in tests, use poetry run pytest path/to/test.py --snapshot-update; always review snapshot changes with git diff before committing

Files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
🧠 Learnings (12)
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-03-05T15:42:08.207Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12297
File: .claude/skills/backend-check/SKILL.md:14-16
Timestamp: 2026-03-05T15:42:08.207Z
Learning: In Python files under autogpt_platform/backend (recursively), rely on poetry run format to perform formatting (Black + isort) and linting (ruff). Do not run poetry run lint as a separate step after poetry run format, since format already includes linting checks.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-03-16T16:35:40.236Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/api/features/workflow_import.py:54-63
Timestamp: 2026-03-16T16:35:40.236Z
Learning: Avoid using the word 'competitor' in public-facing identifiers and text. Use neutral naming for API paths, model names, function names, and UI text. Examples: rename 'CompetitorFormat' to 'SourcePlatform', 'convert_competitor_workflow' to 'convert_workflow', '/competitor-workflow' to '/workflow'. Apply this guideline to files under autogpt_platform/backend and autogpt_platform/frontend.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-03-31T15:37:38.626Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/backend/backend/copilot/tools/agent_generator/fixer.py:37-47
Timestamp: 2026-03-31T15:37:38.626Z
Learning: When validating/constructing Anthropic API model IDs in Significant-Gravitas/AutoGPT, allow the hyphen-separated Claude Opus 4.6 model ID `claude-opus-4-6` (it corresponds to `LlmModel.CLAUDE_4_6_OPUS` in `autogpt_platform/backend/backend/blocks/llm.py`). Do NOT require the dot-separated form in Anthropic contexts. Only OpenRouter routing variants should use the dot separator (e.g., `anthropic/claude-opus-4.6`); `claude-opus-4-6` should be treated as correct when passed to Anthropic, and flagged only if it’s used in the OpenRouter path where the dot form is expected.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-04-15T02:43:36.890Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12780
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:0-0
Timestamp: 2026-04-15T02:43:36.890Z
Learning: When reviewing Python exception handlers, do not flag `isinstance(e, X)` checks as dead/unreachable if the caught exception `X` is a subclass of the exception type being handled. For example, if `X` (e.g., `VirusScanError`) inherits from `ValueError` (directly or via an intermediate class) and it can be raised within an `except ValueError:` block, then `isinstance(e, X)` inside that handler is reachable and should not be treated as dead code.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-05-23T05:29:43.085Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 13200
File: autogpt_platform/backend/backend/executor/scheduler.py:590-593
Timestamp: 2026-05-23T05:29:43.085Z
Learning: When reviewing Python code that uses Pydantic discriminated/tagged unions (e.g., `Annotated[Union[...], Field(discriminator="kind")]`), recognize that using `isinstance(x, SomeVariantInfo)` to narrow the union is an intentional and correct runtime guard and should also enable static type narrowing in tools like Pyright. Do not recommend replacing such `isinstance`-based narrowing with `cast(...)` when the check already proves the variant at runtime.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-04-22T11:46:04.431Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/config.py:0-0
Timestamp: 2026-04-22T11:46:04.431Z
Learning: Do not flag the Claude Sonnet 4.6 model ID as incorrect when it uses the project’s established hyphenated convention: `anthropic/claude-sonnet-4-6`. This hyphen form is the intentional, production convention and should be treated as valid (including in files like llm.py, blocks tests, reasoning.py, `_is_anthropic_model` tests, and config defaults). Note that OpenRouter also accepts the dot variant `anthropic/claude-sonnet-4.6`, so either form may be tolerated, but `anthropic/claude-sonnet-4-6` should be considered the standard to match project usage.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-04-22T11:46:12.892Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/baseline/service.py:322-332
Timestamp: 2026-04-22T11:46:12.892Z
Learning: In this codebase (Significant-Gravitas/AutoGPT), OpenRouter-routed Anthropic model IDs should use the hyphen-separated convention (e.g., `anthropic/claude-sonnet-4-6`, `anthropic/claude-opus-4-6`). Although OpenRouter may accept both hyphen and dot variants, treat the hyphen-separated form as the intended, correct codebase-wide convention and do not flag it as an error. Only flag the dot-separated variant (e.g., `anthropic/claude-sonnet-4.6`) as incorrect when reviewing/validating model ID strings for OpenRouter-routed Anthropic models.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-05-07T18:48:14.242Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 13040
File: autogpt_platform/backend/backend/blocks/llm.py:0-0
Timestamp: 2026-05-07T18:48:14.242Z
Learning: In this repository, isort may split imports from the same module into separate blocks when some imports are aliased (e.g., `from module import X as Y`) and others are not. Preserve the two-block layout when it results from isort (such as keeping `from openai.types.chat import ChatCompletion as OpenAIChatCompletion` separate from non-aliased imports from `openai.types.chat`). Do not treat that split as a style issue during review; merging them into a single block can fail CI with `Imports are incorrectly sorted and/or formatted`.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-05-26T14:24:34.866Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 13217
File: autogpt_platform/backend/backend/api/features/search/service.py:137-137
Timestamp: 2026-05-26T14:24:34.866Z
Learning: In the Significant-Gravitas/AutoGPT backend, treat `user_id` (an opaque UUID used only for correlation/tracing) as non-PII. Do not flag direct logging of `user_id` in `logger.warning`/`logger.info` statements as a PII exposure issue, as the established convention is to log `user_id` for tracing while reserving PII for fields like email or display name.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-06-11T19:39:10.493Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 13337
File: autogpt_platform/backend/backend/copilot/graphiti/reranker.py:0-0
Timestamp: 2026-06-11T19:39:10.493Z
Learning: In the Significant-Gravitas/AutoGPT Python backend, when calling the OpenAI Python client `chat.completions.create`, construct the `messages` payload using the concrete typed-dict variants from `openai.types.chat` (e.g., `ChatCompletionSystemMessageParam`, `ChatCompletionUserMessageParam`, etc.) rather than trying to instantiate `ChatCompletionMessageParam` directly. `ChatCompletionMessageParam` is a `Union` alias and is not constructible, so `ChatCompletionMessageParam(role=..., content=...)` should fail type checking. Build each message element with the appropriate concrete typed dict and then annotate the resulting list as `list[ChatCompletionMessageParam]` (e.g., `messages: list[ChatCompletionMessageParam] = [ChatCompletionSystemMessageParam(...), ...]`).

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-06-22T15:12:38.754Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 13309
File: autogpt_platform/backend/backend/api/features/library/db_test.py:0-0
Timestamp: 2026-06-22T15:12:38.754Z
Learning: When constructing Prisma model instances in Significant-Gravitas/AutoGPT Python backend test code (e.g., `prisma.models.AgentNode`) for fields typed as Prisma `Json`, pass JSON-typed values as JSON-serialized strings (e.g., `json.dumps(some_dict)`) rather than passing a plain Python dict. Prisma/Pydantic expects the `Json` constructor input to be a string (`JSON input should be string` otherwise); the model will deserialize internally so the resulting attribute becomes a dict. If the field is annotated as `Json` but the constructor requires a `str`, keep the existing `# type: ignore` (or an equivalent, narrowly scoped typing adjustment) to satisfy the type checker without changing runtime behavior.

Applied to files:

  • autogpt_platform/backend/backend/api/features/library/db_test.py
🔇 Additional comments (1)
autogpt_platform/backend/backend/api/features/library/db.py (1)

192-197: LGTM!

Also applies to: 1159-1162, 1176-1179

Comment thread autogpt_platform/backend/backend/api/features/library/db_test.py
@Abhi1992002

Copy link
Copy Markdown
Member Author

All review threads have been addressed and resolved. Summary of changes since the first push:

  • Removed the redundant StoreListingVersion fetch (91a828f): resolve_graph_for_library now returns the listing it already fetched, and add_graph_to_library snapshots from it — no second find_unique. This also restored db_test.py::test_add_agent_to_library's single-fetch assertion (the CI failure).
  • Preserve empty published values (91a828f): from_db uses x if x is not None else graph.x, so an intentionally-empty marketplace name/description is kept rather than falling back to the graph.
  • Search discoverability (cd4d995): list_library_agents search now also matches the snapshotted LibraryAgent.name/description, so a downloaded agent is findable by the title shown on its card.
  • Tests (91a828f, 6a97073): added coverage for the empty-imageUrls branch, empty-string preservation, snapshot-vs-graph fallback, and all four search OR-clauses.

On the two security findings: the non-admin add-to-library path already resolves graph access through get_graph(user_id=...), which grants a non-owner access only via a StoreListingVersion that is APPROVED and non-deleted, gated on the same graph version — a pending/rejected listing raises NotFoundError before any snapshot. This PR doesn't change that authorization; it only reads cosmetic name/description/image fields from the already-resolved listing. Image-URL origin validation is a pre-existing, submission-time concern (these URLs are already stored and rendered in the marketplace UI) and out of scope here.

All checks are green (backend test (3.11/3.12/3.13), e2e, lint, types, migrations).

@Abhi1992002

Copy link
Copy Markdown
Member Author

/batch abhi-mon-prs

@autogpt-batch-bot autogpt-batch-bot Bot added the batch:abhi-mon-prs batch-bot batch membership label Jul 27, 2026
@autogpt-batch-bot

Copy link
Copy Markdown

🤖 Added #13680 to batch abhi-mon-prs. Batch abhi-mon-prs (1): #13680.

Deploying the combined preview (#13691); /batch-merge lands them together.

@Abhi1992002

Copy link
Copy Markdown
Member Author

!deploy

@Abhi1992002

Copy link
Copy Markdown
Member Author

!deploy

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Deploying PR #13680 to development environment...

@Pwuts

Pwuts commented Jul 28, 2026

Copy link
Copy Markdown
Member

Preview environment is live (all services healthy)

  • Deployed: 2a0f3006ab9d1abd4bd6daf761883a354f70eb83 at 2026-07-28 12:37 UTC
  • Database: isolated Supabase branch pr-13680 (state persists across redeploys unless migration drift forces a reset)
  • URLs: posted in the team Discord

Push more commits, then comment !deploy to update · !undeploy or close the PR to tear down.

@Abhi1992002

Copy link
Copy Markdown
Member Author

/review

@autogpt-pr-reviewer

Copy link
Copy Markdown

Queued a review for PR #13680 at 2a0f300.

@autogpt-pr-reviewer autogpt-pr-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📋 Automated Review — PR #13680

PR #13680 — fix(backend): carry marketplace name/description/image to downloaded library agents
Author: Abhi1992002 | Files: 9

🎯 Verdict: APPROVE

PR Description Quality

✅ Has Why + What + How — the description explains the bug (downloaded agents showed the creator's original graph title/description instead of the published marketplace values), the fix (snapshot-at-download), and the mechanism. One checklist item — the manual E2E verification — remains unchecked, but QA has independently exercised that exact path (see below).

What This PR Does

When a user downloads a marketplace agent, their library card previously showed the creator's original graph name/description/image rather than the published marketplace listing values. This PR snapshots the StoreListingVersion's name, description, and first imageUrls entry onto the LibraryAgent at download time (create + restore paths), makes from_db prefer the snapshot with a graph fallback, and extends library search to match the snapshotted fields. Two nullable TEXT columns are added via an additive, non-blocking migration.

Specialist Findings

🛡️ Security ✅ — No critical/high issues. Correctly flags that publisher-authored name/description are now persisted and rendered in the consumer's authenticated library (model.py:355), a stored-XSS surface only if the frontend renders them as unescaped HTML/Markdown — React's default text escaping mitigates this. imageUrl from imageUrls[0] (_add_to_library.py:81) is persisted without scheme validation (tracking-beacon vector). Both mirror existing marketplace display behavior and are store-approval-gated.
🟡 Confirm library card renders name/description as plain text; optionally validate the image URL scheme.

🏗️ Architecture ✅ — Follows the pre-existing imageUrl snapshot-at-download pattern; create/restore handled symmetrically; migration is additive and backwards-compatible. resolve_graph_for_library now returns the already-fetched StoreListingVersion so callers avoid a re-query (no N+1). Notes generic column naming (LibraryAgent.name/description vs. marketplaceName) and an untyped dict[str, str | None] return as maintainability polish.
🟠 Generic column names could mislead future readers (schema.prisma:612).

Performance ✅ — Net positive: the refactor eliminates a second find_unique round-trip (the same one that caused the prior CI failure). Hot-path additions are O(1) null-coalescing checks. New ILIKE '%term%' search predicates on the unindexed name/description columns are non-sargable but not a regression (AgentGraph fields already search this way) and bounded by the userId-scoped index. Migration is metadata-only DDL — non-blocking on large tables.

🧪 Testing ✅/⚠️ — Genuinely good unit coverage: create, restore/update, from_db precedence (including the subtle empty-string is not None case), the search clause, and the empty-imageUrls branch all have dedicated tests. Gap: the one realistic-model integration test (db_test.py:277 test_add_agent_to_library) drives the full resolve→snapshot→create chain with a real StoreListingVersion but expected_create doesn't assert the new fields — it would pass even if the snapshot code were deleted.
🟠 Add snapshot asserts to the integration test; add a read-side image_url assertion in model_test.py.

📖 Quality ✅ — Grade A. Comments explain why (snapshot rationale), docstrings present, migration SQL annotated. Minor: helper named _marketplace_metadata (bare noun) vs. repo verb-prefix convention; untyped dict indexed with magic string keys in two write sites.

📦 Product ✅ — Fixes the reported UX issue (OPEN-2478/#9879) for the going-forward path end-to-end: title/description/image/search all covered. Notes no backfill for pre-existing downloads (they stay on graph values until re-added — by-design, non-retroactive) and that an empty published name could render a titleless card (low risk; likely validated non-empty at publish).

📬 Discussion ✅ — All 22 review threads resolved, MERGEABLE, no conflicts. Substantive bot findings were genuinely fixed in code: the empty-string or-fallback bug (is not None), search discoverability, and the prior critical double-find_unique (now a (graph, slv) tuple threaded through). Awaits human approval from @ntindle/@0ubbe (REVIEW_REQUIRED).

🔎 QA ✅ — Exercised the full download path live against a running stack. Because seed data had SLV name == graph name, QA set distinct published metadata to prove snapshot-over-graph precedence. All 10 scenarios passed: happy path, imageUrls[0] selection, DB persistence, restore-refresh, no-image edge (null image → graph wins), snapshot+graph search matching, and 401/404 negatives. No backend errors.

🟠 Should Fix

  1. Prior critical is resolved — verify it stays green ✅ Addressed — the second find_unique that broke db_test.py::test_add_agent_to_library was eliminated; resolve_graph_for_library returns (graph, slv) and threads it through (db.py:1161-1185, _add_to_library.py). Per repo rule 13, the repository's GitHub CI is authoritative; the only red check (test (3.13)) is a CI cancellation/timeout while tests streamed PASSED, with test (3.11) and test (3.12) green on the same commit. Re-run to clear the status rollup.
  2. Integration test doesn't assert the snapshot (autogpt_platform/backend/backend/api/features/library/db_test.py:277) — test_add_agent_to_library runs the full resolve→snapshot→create chain with a real StoreListingVersion but expected_create only checks pre-existing fields, so it would pass if the snapshot code were removed. Add name/description/imageUrl asserts to close the wiring gap. (Flagged by: testing)
  3. No read-side image_url coverage (autogpt_platform/backend/backend/api/features/library/model_test.py:48) — from_db tests assert name/description precedence but never that a snapshotted image surfaces as result.image_url. QA verified this live, but a unit assertion is cheap. (Flagged by: testing)

🟡 Nice to Have

  1. Rename columns to marketplaceName/marketplaceDescription (autogpt_platform/backend/schema.prisma:612) — generic names read as always-present display fields but are NULL for user-created agents. (architect)
  2. Type the snapshot return as a TypedDict/dataclass (autogpt_platform/backend/backend/api/features/library/_add_to_library.py:62) — replaces magic-string-keyed dict access at both write sites and enables spreading into the Prisma payloads. (architect, quality)
  3. Backfill or document non-retroactivity (.../migration.sql:6) — existing downloads keep showing graph values until re-added; note this as an accepted decision. (product)

🔵 Nits

  1. Helper naming (autogpt_platform/backend/backend/api/features/library/_add_to_library.py:63) — _marketplace_metadata vs. the repo's verb-prefix convention (_get_marketplace_metadata) and the PR description's own name. (quality)
  2. Empty-name title fallback (autogpt_platform/backend/backend/api/features/library/model.py:352) — consider agent.name or graph.name for the user-facing title while keeping is not None for description. (product)

QA Screenshots

Screenshot Description
after: library cards show published metadata Library page renders published titles (PUBLISHED QA Title V2, NoImage Published Title) and preview image — not the underlying graph names (This from test. Agents), proving snapshot-over-graph precedence end-to-end ✅

Human Review Needed

NO — This is an isolated backend data-snapshot fix with no changes to authentication, authorization, credential handling, or trust boundaries between services. The publisher-content surface is store-approval-gated and mirrors existing marketplace display behavior. Two human reviewers (@ntindle, @0ubbe) are already requested through the normal flow; this review is the independent check.

Risk Assessment

Merge risk: LOW | Rollback: EASY (additive nullable columns, no data migration, no destructive DDL)

Local Harness

✅ All 5 local checks pass: frontend lint, backend poetry run lint (85s), frontend typecheck, frontend test:unit, frontend build.
GitHub CI: 39/40 checks green on the head SHA; the single red test (3.13) is a CI cancellation/timeout (not an assertion failure) with test (3.11)/test (3.12) passing on the same commit — re-run recommended to clear the rollup.


UI Testing — Variant Results

✅ local: Snapshot-at-download works end-to-end: library agents show the published marketplace name/description/first-image (not the graph's), the restore path refreshes the snapshot, search matches both snapshot and graph values, and auth/validation negatives return 401/404 — all verified live with no backend errors.

✅ hosted: Marketplace name/description/image is correctly snapshotted onto downloaded library agents on both create and restore paths, surfaced in the API/UI, and searchable — all scenarios pass with no blocking defects.

@github-project-automation github-project-automation Bot moved this from 🚧 Needs work to 👍🏼 Mergeable in AutoGPT development kanban Jul 29, 2026
@Abhi1992002
Abhi1992002 added this pull request to the merge queue Jul 29, 2026
Merged via the queue into dev with commit fb1ad08 Jul 29, 2026
47 of 48 checks passed
@Abhi1992002
Abhi1992002 deleted the abhimanyuyadav/open-2478-marketplace-data-should-be-downloaded-with-agent branch July 29, 2026 11:42
@github-project-automation github-project-automation Bot moved this from 👍🏼 Mergeable to ✅ Done in AutoGPT development kanban Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

batch:abhi-mon-prs batch-bot batch membership platform/backend AutoGPT Platform - Back end size/l

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

3 participants