feat(backend): agent-graph grants — share with teams (SECRT-2448, v1) - #13599
feat(backend): agent-graph grants — share with teams (SECRT-2448, v1)#13599ntindle wants to merge 4 commits into
Conversation
|
/batch |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds team-scoped Agent Graph grants with Prisma persistence, organization APIs for creating, listing, receiving, and revoking grants, and authorization support for viewing and executing pinned or latest graph versions. ChangesTeam graph grant access
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant GrantRoutes
participant GrantDB
participant Prisma
participant GraphAuthorization
Client->>GrantRoutes: create team grant
GrantRoutes->>GrantDB: validate and upsert grant
GrantDB->>Prisma: persist AgentGraphGrant
Prisma-->>GrantDB: grant record
GrantDB-->>GrantRoutes: GrantResponse
Client->>GraphAuthorization: access graph
GraphAuthorization->>GrantDB: resolve team grant
GrantDB->>Prisma: query grants and active memberships
Prisma-->>GrantDB: matching grant
GrantDB-->>GraphAuthorization: VIEW or EXECUTE grant
GraphAuthorization-->>Client: graph or authorization result
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
autogpt_platform/backend/backend/api/features/orgs/grant_model.py (1)
8-17: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winModel grant options as constrained values.
These free-form strings make OpenAPI advertise arbitrary values and defer invalid requests to database-layer validation. Use
Literalor API enums, withprincipal_typerestricted to"TEAM"for v1.Proposed change
+from typing import Literal + class CreateGrantRequest(BaseModel): - principal_type: str = "TEAM" + principal_type: Literal["TEAM"] = "TEAM" principal_id: str = Field(..., min_length=1) graph_version: int | None = None - capability: str = "EXECUTE" - credential_mode: str = "CONSUMER" + capability: Literal["VIEW", "EXECUTE"] = "EXECUTE" + credential_mode: Literal["CONSUMER", "OWNER"] = "CONSUMER"🤖 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/orgs/grant_model.py` around lines 8 - 17, Update CreateGrantRequest to model principal_type, capability, and credential_mode as constrained Literal values or API enums instead of free-form strings. Restrict principal_type to "TEAM" for v1, capability to "VIEW" or "EXECUTE", and credential_mode to "CONSUMER" or "OWNER", while preserving their current defaults and graph_version behavior.autogpt_platform/backend/backend/api/features/orgs/grant_db.py (1)
15-103: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSplit grant validation, graph resolution, and persistence.
upsert_grantsubstantially exceeds the repository’s ~40-line limit. Extract option validation and the team/graph authorization lookup into named helpers.As per coding guidelines, “Keep functions under ~40 lines; extract named helpers when a function grows longer.”
🤖 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/orgs/grant_db.py` around lines 15 - 103, Refactor upsert_grant to stay under the repository’s ~40-line function limit by extracting option validation and team/graph authorization lookup into named helpers. Move the principal_type, capability, and credential_mode checks into one helper, and move the team lookup, graph resolution, and owner/admin authorization into another helper that returns the resolved graph. Keep upsert_grant focused on orchestration and grant persistence while preserving all existing errors and 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/orgs/grant_db.py`:
- Around line 42-46: Update the credential-mode validation in the grant creation
flow around GrantCredentialMode to reject OWNER, allowing only the currently
supported consumer mode until execution uses credentialMode. Preserve the
existing unknown-mode ValueError behavior and ensure OWNER is not persisted as
an accepted option.
- Around line 157-165: Update the authorization check in the grant-revocation
flow to load and validate the graph version pinned by the grant, rather than the
latest version returned by `prisma.agentgraph.find_first`. Compare that
version’s userId with revoked_by_user_id while preserving the org-admin bypass
and existing denial behavior.
In `@autogpt_platform/backend/backend/api/features/orgs/grant_routes.py`:
- Around line 47-50: Update the exception handling in grant sharing at
autogpt_platform/backend/backend/api/features/orgs/grant_routes.py lines 47-50
so owner/admin authorization failures map to HTTP 403 while ValueError cases for
invalid grant options remain HTTP 400. Apply the same authorization-specific
mapping to the grant revocation handler at
autogpt_platform/backend/backend/api/features/orgs/grant_routes.py lines 96-99.
In `@autogpt_platform/backend/backend/data/graph.py`:
- Around line 1332-1341: Constrain grant resolution and execution to the grant’s
organization. In autogpt_platform/backend/backend/data/graph.py:1332-1341,
update grant_where in the graph lookup to include grant.organizationId; in
autogpt_platform/backend/backend/data/graph.py:1672-1677, update the execution
validation to require graph.organizationId equals exec_grant.organizationId
before granting execution.
---
Nitpick comments:
In `@autogpt_platform/backend/backend/api/features/orgs/grant_db.py`:
- Around line 15-103: Refactor upsert_grant to stay under the repository’s
~40-line function limit by extracting option validation and team/graph
authorization lookup into named helpers. Move the principal_type, capability,
and credential_mode checks into one helper, and move the team lookup, graph
resolution, and owner/admin authorization into another helper that returns the
resolved graph. Keep upsert_grant focused on orchestration and grant persistence
while preserving all existing errors and behavior.
In `@autogpt_platform/backend/backend/api/features/orgs/grant_model.py`:
- Around line 8-17: Update CreateGrantRequest to model principal_type,
capability, and credential_mode as constrained Literal values or API enums
instead of free-form strings. Restrict principal_type to "TEAM" for v1,
capability to "VIEW" or "EXECUTE", and credential_mode to "CONSUMER" or "OWNER",
while preserving their current defaults and graph_version 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
Run ID: e6dee616-2043-4658-a524-a97e8564bccc
📒 Files selected for processing (10)
autogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_test.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/rest_api.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/migrations/20260717151612_agent_graph_grants/migration.sqlautogpt_platform/backend/schema.prisma
📜 Review details
⏰ Context from checks skipped due to timeout. (15)
- GitHub Check: check API types
- GitHub Check: Cursor Bugbot
- GitHub Check: types
- GitHub Check: lint
- GitHub Check: test (3.13)
- GitHub Check: type-check (3.11)
- GitHub Check: end-to-end tests
- GitHub Check: type-check (3.12)
- GitHub Check: test (3.12)
- GitHub Check: type-check (3.13)
- GitHub Check: test (3.11)
- GitHub Check: lint
- GitHub Check: Analyze (python)
- GitHub Check: Check PR Status
- GitHub Check: Analyze (typescript)
🧰 Additional context used
📓 Path-based instructions (8)
autogpt_platform/backend/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development
autogpt_platform/backend/**/*.py: Usepoetry run ...command for executing Python package dependencies
Use top-level imports only — avoid local/inner imports except for lazy imports of heavy optional dependencies likeopenpyxl
Use absolute imports withfrom backend.module import ...for cross-package imports; single-dot relative imports are acceptable for sibling modules within the same package; avoid double-dot relative imports
Do not use duck typing — avoidhasattr/getattr/isinstancefor type dispatch; use typed interfaces/unions/protocols instead
Use Pydantic models over dataclass/namedtuple/dict for structured data
Do not use linter suppressors — no# type: ignore,# noqa,# pyright: ignore; fix the type/code instead
Prefer list comprehensions over manual loop-and-append patterns
Use early return with guard clauses first to avoid deep nesting
Use%sfor deferred interpolation indebuglog statements for efficiency; use f-strings elsewhere for readability (e.g.,logger.debug("Processing %s items", count)vslogger.info(f"Processing {count} items"))
Sanitize error paths by usingos.path.basename()in error messages to avoid leaking directory structure
Be aware of TOCTOU (Time-Of-Check-Time-Of-Use) issues — avoid check-then-act patterns for file access and credit charging
Usetransaction=Truefor Redis pipelines to ensure atomicity on multi-step operations
Usemax(0, value)guards for computed values that should never be negative
Keep files under ~300 lines; if a file grows beyond this, split by responsibility (extract helpers, models, or a sub-module into a new file)
Keep functions under ~40 lines; extract named helpers when a function grows longer
...
Files:
autogpt_platform/backend/backend/api/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_test.py
autogpt_platform/backend/**/api/**/*.py
📄 CodeRabbit inference engine (autogpt_platform/backend/AGENTS.md)
autogpt_platform/backend/**/api/**/*.py: UseSecurity()instead ofDepends()for authentication dependencies to get proper OpenAPI security specification
Follow SSE (Server-Sent Events) protocol: usedata:lines for frontend-parsed events (must match Zod schema) and: commentlines for heartbeats/status
Files:
autogpt_platform/backend/backend/api/rest_api.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_test.py
autogpt_platform/backend/backend/data/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
All data access in backend requires user ID checks; verify this for any 'data/*.py' changes
Files:
autogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/data/graph.py
autogpt_platform/**/data/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
For changes touching
data/*.py, validate user ID checks or explain why not needed
Files:
autogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/data/graph.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.pynaming 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
UseAsyncMockfromunittest.mockfor async functions in tests
When writing tests, use Test-Driven Development (TDD): write failing tests marked with@pytest.mark.xfailbefore implementation, then remove the marker once the implementation is complete
When creating snapshots in tests, usepoetry run pytest path/to/test.py --snapshot-update; always review snapshot changes withgit diffbefore committing
Files:
autogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_test.py
autogpt_platform/backend/schema.prisma
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Run database migrations with 'poetry run prisma migrate dev' and 'poetry run prisma generate' after schema changes in backend
Files:
autogpt_platform/backend/schema.prisma
🧠 Learnings (15)
📚 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/20260717151612_agent_graph_grants/migration.sqlautogpt_platform/backend/backend/api/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/schema.prismaautogpt_platform/backend/backend/api/features/orgs/grant_db_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/20260717151612_agent_graph_grants/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/20260717151612_agent_graph_grants/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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_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/rest_api.pyautogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/api/features/orgs/grant_model.pyautogpt_platform/backend/backend/api/features/orgs/grant_db.pyautogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/features/orgs/grant_routes.pyautogpt_platform/backend/backend/api/features/orgs/grant_db_test.py
📚 Learning: 2026-04-21T04:35:34.710Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12865
File: autogpt_platform/backend/backend/data/credit.py:1584-1584
Timestamp: 2026-04-21T04:35:34.710Z
Learning: When reviewing this codebase, don’t flag snake_case attribute names (e.g., `subscription_tier`, `stripe_customer_id`, `top_up_config`) on the app-layer Pydantic `User` model as “wrong” field names. These are correct for the app-layer model and are expected to be mapped from the Prisma-layer camelCase fields (e.g., `subscriptionTier`, `stripeCustomerId`) inside methods like `User.from_db()`. Only Prisma-returned/raw objects would use camelCase, but functions like `get_user_by_id(user_id: str)` are expected to return the Pydantic app-layer model.
Applied to files:
autogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/data/graph.py
📚 Learning: 2026-05-07T15:32:39.703Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 13033
File: autogpt_platform/backend/backend/data/generate_data.py:111-117
Timestamp: 2026-05-07T15:32:39.703Z
Learning: When reviewing the Python data-generation layer, do not treat missing `user_id`/user filtering in calls to graph-metadata resolvers as a security issue if the `graph_id` inputs are already guaranteed to be user-scoped by earlier upstream SQL (e.g., `WHERE "userId" = ...`). In particular, `_resolve_agent_name(graph_id)` in `generate_data.py` correctly calls `get_graph_metadata(graph_id=graph_id)` without a `user_id` parameter by design, because name resolution must also work for user-executed shared/marketplace agents that the user may not own.
Applied to files:
autogpt_platform/backend/backend/data/grants_test.pyautogpt_platform/backend/backend/data/grants.pyautogpt_platform/backend/backend/data/graph.py
🔇 Additional comments (10)
autogpt_platform/backend/schema.prisma (1)
464-464: LGTM!Also applies to: 1087-1105, 1785-1785, 1942-1977
autogpt_platform/backend/migrations/20260717151612_agent_graph_grants/migration.sql (1)
1-45: LGTM!autogpt_platform/backend/backend/api/features/orgs/grant_model.py (1)
20-77: LGTM!autogpt_platform/backend/backend/api/features/orgs/grant_db.py (1)
106-139: LGTM!autogpt_platform/backend/backend/api/features/orgs/grant_routes.py (1)
53-68: LGTM!Also applies to: 102-113
autogpt_platform/backend/backend/api/rest_api.py (1)
38-38: LGTM!Also applies to: 471-475
autogpt_platform/backend/backend/api/features/orgs/grant_db_test.py (1)
1-197: LGTM!autogpt_platform/backend/backend/data/grants.py (1)
1-82: LGTM!autogpt_platform/backend/backend/data/graph.py (1)
8-8: LGTM!Also applies to: 31-31
autogpt_platform/backend/backend/data/grants_test.py (1)
1-146: LGTM!
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## feat/team-field-alignment #13599 +/- ##
=============================================================
+ Coverage 80.46% 80.48% +0.01%
=============================================================
Files 3327 3333 +6
Lines 254787 255154 +367
Branches 23535 23560 +25
=============================================================
+ Hits 205014 205352 +338
- Misses 44484 44508 +24
- Partials 5289 5294 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request. |
9f1bbcf to
85441e3
Compare
|
Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly. |
🔍 PR Overlap DetectionThis check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early. 🔴 Merge Conflicts DetectedThe following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.
🟡 Medium Risk — Some Line OverlapThese PRs have some overlapping changes:
🟢 Low Risk — File Overlap OnlyThese PRs touch the same files but different sections (click to expand)
Summary: 6 conflict(s), 5 medium risk, 8 low risk (out of 19 PRs with file overlap) Auto-generated on push. Ignores: |
Grant table with a polymorphic principal (TEAM enforced, USER reserved, room for PERSONA), version-pinned by default with opt-in followLatest, per-grant capability (VIEW/EXECUTE) and credential mode. Enforcement: grant fallback in get_graph and an EXECUTE-grant path in validate_graph_execution_permissions; non-TEAM principals raise loudly rather than silently half-supporting an unshipped principal type. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm3mCG9okfdGtAXtFaDF9A
…ts, 403 authz - resolve_graph_grant + list_received_grants now exclude archived workspaces, matching upsert_grant's create-time rule and list_teams visibility - grant resolution/execution in graph.py constrained to the grant's organizationId so a followLatest grant can't follow a graph moved to another org - owner/admin authorization failures raise NotAuthorizedError (mapped to 403) instead of a plain ValueError (400) Co-Authored-By: Claude Opus <noreply@anthropic.com>
…s tests Dev's new get_graph/validate tests mock the AgentGraph/StoreListingVersion/ LibraryAgent prisma clients but not backend.data.grants.prisma, so the team-grant fallback in get_graph (and the exec-grant check in validate_graph_execution_permissions) hit the real, unconnected client and raised RuntimeError. - graph_test.py: add a file-wide autouse fixture patching backend.data.grants.prisma with agentgraphgrant.find_many -> [] so resolve_graph_grant returns None (no-grant path is explicit). No assertions weakened. - orgs/regression_test.py: patch backend.data.grants.prisma inline in the one non-owner get_graph test (test_regression_get_graph_wrong_org_returns_none), matching the file's per-test patch style. Co-Authored-By: Claude Opus <noreply@anthropic.com>
…d/add collision with the memory-governance mount in the batch rollup Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
85441e3 to
a6c2445
Compare
|
|
||
| agentGraphId String | ||
| agentGraphVersion Int | ||
| AgentGraph AgentGraph @relation(fields: [agentGraphId, agentGraphVersion], references: [id, version], onDelete: Restrict) |
There was a problem hiding this comment.
Bug: Deleting a graph that has been granted to a team causes an unhandled database exception due to an onDelete: Restrict constraint.
Severity: HIGH
Suggested Fix
Wrap the AgentGraph.prisma().delete_many() call within a try...except block to catch the database constraint violation and return a user-friendly error message. Alternatively, consider changing the schema to use onDelete: Cascade or explicitly deleting associated AgentGraphGrant records before deleting the AgentGraph.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: autogpt_platform/backend/schema.prisma#L2362
Potential issue: The `delete_graph` function attempts to delete an `AgentGraph` from the
database. However, the Prisma schema includes an `onDelete: Restrict` constraint on the
`AgentGraphGrant` model, which is related to `AgentGraph`. If a user attempts to delete
a graph that has been shared with a team (and thus has an associated `AgentGraphGrant`),
the database will raise a foreign key constraint violation. This violation is not
handled in the `delete_graph` function or the corresponding API route, causing an
unhandled exception and a 500 server error to be returned to the user.
Also affects:
autogpt_platform/backend/backend/data/graph.pyautogpt_platform/backend/backend/api/v1.py
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a6c2445. Configure here.
| for row in eligible: | ||
| if row.principalId == membership.teamId: | ||
| return row | ||
| return None |
There was a problem hiding this comment.
Arbitrary grant chosen among several
Medium Severity
resolve_graph_grant returns a single grant from an arbitrary matching TeamMember row. When the same graph is shared with two of the caller's teams under different pins or followLatest settings, get_graph and execution authz only honor that one grant, so a version the other grant covers can be denied.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit a6c2445. Configure here.
|
|
||
| agentGraphId String | ||
| agentGraphVersion Int | ||
| AgentGraph AgentGraph @relation(fields: [agentGraphId, agentGraphVersion], references: [id, version], onDelete: Restrict) |
There was a problem hiding this comment.
Shared graphs cannot be deleted
Medium Severity
AgentGraphGrant references AgentGraph with onDelete: Restrict, and nothing clears grants when a graph is removed. Deleting a shared graph (or the pinned version a followLatest grant still points at) fails with a foreign-key error instead of revoking the shares.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit a6c2445. Configure here.


Why
SECRT-2448: teams exist, but there is no way to share an agent across team lines — the tenancy model is a single
teamIdFK, so a graph belongs to exactly one team and everyone else is locked out. Decision (2026-07-17): grants sit on top of roles, teams-only in v1, on a schema that is polymorphic from day one so USER/PERSONA principals arrive as an enum value + code path, not a table migration.What
AgentGraphGrant— composite FK toAgentGraph(id, version)(share = reference pinned to a version, never a copy;followLatestopts into tracking the active version), polymorphicprincipalType/principalId(TEAM enforced; USER reserved),capability(VIEW/EXECUTE, EXECUTE ⊇ VIEW),credentialMode(CONSUMER/OWNER, room for RESTRICTED), org-scoped, unique per (graph, principal) so re-sharing updates the pin. Revoke = hard delete.backend/data/grants.py):get_graphgains a grant fallback after store-listing and library: pinned grants open exactly the pinned version, followLatest opens the active version.validate_graph_execution_permissionsaccepts an EXECUTE grant covering the exact version (followLatest additionally requires the version be active); a grant also satisfies the library requirement since granted agents aren't library entries.GrantPrincipalNotSupportedErrorloudly — a row like that can only exist by bypassing the API, and silent skipping would hide both the bypass and an unenforced principal type./api/orgs/{org_id}, gated by the previously-unusedOrgAction.SHARE_RESOURCES): create/upsert grant on a graph, list a graph's grants, revoke (204), andGET /grants/receivedfor agents shared with my teams. Sharer must be the graph's owner or an org admin; team and graph must both live in the caller's org.How
Enforcement is two additive seams in
graph.py— a fallback in theget_graphchain and one extra disjunct in the execution check — so no existing access path changes behavior. CRUD mirrorsteam_db/team_routesconventions (RequestContext + Security deps, path/ctx re-verification, NotFoundError→404 / ValueError→400).Testing
backend/data/grants_test.py(9): membership resolution, ACTIVE-only, VIEW/EXECUTE implication, version-pin coverage, and the loud non-TEAM throw.backend/api/features/orgs/grant_db_test.py(13): USER principal rejected at create, org-scoping of team/graph, owner/admin share+revoke authz, default-pin-to-active-version, explicit pin, received-grants scoping.Checklist
data/*.pyuser-ID checks:resolve_graph_grantfilters by the caller's ACTIVE TeamMember rows; CRUD validates org scope + owner/admin; routes re-verifyctx.org_idagainst the path.🤖 Generated with Claude Code
https://claude.ai/code/session_01Jm3mCG9okfdGtAXtFaDF9A
Note
High Risk
Changes authorization for graph read and execute paths; incorrect grant resolution or version/org checks could expose or block agents across teams.
Overview
Adds team-scoped agent graph sharing via a new
AgentGraphGrantmodel (version pin orfollowLatest, VIEW/EXECUTE, credential mode stored for later use). Org members withSHARE_RESOURCEScan upsert/list/revoke grants on a graph and list grants received through their active team memberships.Enforcement is wired into existing graph access:
get_graphcan load a graph when the user has a VIEW grant (org-aligned, pinned or active version); execution validation treats a matching EXECUTE grant like library access. Grant resolution is teams-only in v1—non-TEAM principal rows error loudly rather than being ignored.New org routes live under
/api/orgs/{org_id}; share/revoke require graph owner or org admin. Unit/regression tests mock the grants Prisma client so prior graph tests keep the no-grant baseline.Reviewed by Cursor Bugbot for commit a6c2445. Bugbot is set up for automated code reviews on this repo. Configure here.