Conversation
SECRT-1880 - Add state field (with id, name, type) to Issue model for duplicate detection - Add State model for workflow state information - Update try_search_issues() to return createdAt, state, project, and assignee - Add max_results parameter (default 10, was ~50) to reduce token usage - Add team_name filter to scope results to specific team - Fix try_get_team_by_name() to return descriptive error when team not found - Add error output to LinearSearchIssuesBlock for graceful error handling - Add categories to LinearSearchIssuesBlock (PRODUCTIVITY, ISSUE_TRACKING)
WalkthroughThe changes enhance the Linear search block with filtering and enriched issue data. The API client now accepts optional max_results and team_id parameters, returns additional issue fields (state, createdAt, project, assignee), and validates team lookups. The block layer exposes these capabilities through max_results and team_name input parameters, resolving team names to IDs before querying. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@autogpt_platform/backend/backend/blocks/linear/issues.py`:
- Around line 204-219: Remove the inline comments inside the search_issues
implementation: delete the comment lines "// Resolve team name to ID if
provided" and "// Raises LinearAPIException with descriptive message if team not
found" so the function body only contains the logic that instantiates
LinearClient, conditionally sets team_id via
client.try_get_team_by_name(team_name=team_name), and returns
client.try_search_issues(term=term, max_results=max_results, team_id=team_id);
keep all variables and calls (LinearClient, try_get_team_by_name,
try_search_issues, team_id) unchanged.
- Around line 138-152: The Output schema overrides BlockSchemaOutput by
declaring error: str as required while the success path only yields issues; make
the error field optional so successful yields can include None or omit it:
update the Output class (Output, issues, error) to set error's default to None
and type to str | None (e.g., error: str | None = SchemaField(default=None,
description="Error message if the search failed")), or remove the error override
entirely to inherit the base definition from BlockSchemaOutput; adjust any
yields to explicitly yield error=None on success if you choose the optional
field approach.
In `@autogpt_platform/backend/backend/blocks/linear/models.py`:
- Around line 39-44: Remove the inline comment on the State.type field: in the
State model (class State) remove the trailing comment after the default
assignment so the declaration reads with the default value only (retain type
annotation str | None and default = None); no other changes required.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
autogpt_platform/backend/backend/blocks/linear/_api.pyautogpt_platform/backend/backend/blocks/linear/issues.pyautogpt_platform/backend/backend/blocks/linear/models.py
🧰 Additional context used
📓 Path-based instructions (3)
autogpt_platform/backend/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/backend/**/*.py: Always run backend setup commands in order: poetry install, poetry run prisma migrate dev, poetry run prisma generate before backend development
Always run poetry run format (Black + isort) before poetry run lint (ruff) for backend code
Use Python 3.10-3.13 with Python 3.11 required for development (managed by Poetry via pyproject.toml)
autogpt_platform/backend/**/*.py: Use FastAPI with async support for API endpoints in the backend
Use Prisma ORM for database operations with PostgreSQL
Use RabbitMQ for async task processing in the backend
Use JWT-based authentication with Supabase integration
Usepoetry run format(Black + isort) to format code andpoetry run lint(ruff) for linting in the backend
Use ClamAV integration for file upload security
autogpt_platform/backend/**/*.py: Format Python code withpoetry run format
Runpoetry run test(runs pytest with a docker based postgres + prisma) before committing backend changes
Files:
autogpt_platform/backend/backend/blocks/linear/models.pyautogpt_platform/backend/backend/blocks/linear/issues.pyautogpt_platform/backend/backend/blocks/linear/_api.py
autogpt_platform/backend/backend/blocks/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Agent blocks in backend/blocks/ must include: block definition with input/output schemas, execution logic with proper error handling, and tests validating functionality. Blocks inherit from Block base class with input/output schemas, implement run method, use uuid.uuid4() for block UUID, and be registered in block registry
Files:
autogpt_platform/backend/backend/blocks/linear/models.pyautogpt_platform/backend/backend/blocks/linear/issues.pyautogpt_platform/backend/backend/blocks/linear/_api.py
autogpt_platform/**/*.{ts,tsx,js,py}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid comments at all times unless the code is very complex
Files:
autogpt_platform/backend/backend/blocks/linear/models.pyautogpt_platform/backend/backend/blocks/linear/issues.pyautogpt_platform/backend/backend/blocks/linear/_api.py
🧬 Code graph analysis (2)
autogpt_platform/backend/backend/blocks/linear/models.py (1)
autogpt_platform/backend/backend/blocks/apollo/models.py (1)
BaseModel(10-20)
autogpt_platform/backend/backend/blocks/linear/_api.py (1)
autogpt_platform/backend/backend/blocks/linear/models.py (1)
Issue(47-57)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Seer Code Review
- GitHub Check: types
- GitHub Check: test (3.12)
- GitHub Check: test (3.13)
- GitHub Check: test (3.11)
- GitHub Check: Check PR Status
🔇 Additional comments (5)
autogpt_platform/backend/backend/blocks/linear/models.py (1)
47-55: State linkage onIssuelooks good.This aligns cleanly with the expanded API response fields.
autogpt_platform/backend/backend/blocks/linear/_api.py (2)
165-174: Team lookup now fails fast with a clear 404 — nice.
251-298: Search query extensions formax_results/teamIdand extra fields look solid.autogpt_platform/backend/backend/blocks/linear/issues.py (2)
20-20:Stateimport is appropriate for the expanded fixtures and output.
159-196: Updated categories and fixtures align with the new fields.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| max_results: int = SchemaField( | ||
| description="Maximum number of results to return", | ||
| default=10, | ||
| ge=1, | ||
| le=100, | ||
| ) | ||
| team_name: str | None = SchemaField( | ||
| description="Optional team name to filter results (e.g., 'Internal', 'Open Source')", | ||
| default=None, | ||
| ) | ||
|
|
||
| class Output(BlockSchemaOutput): | ||
| issues: list[Issue] = SchemaField(description="List of issues") | ||
| error: str = SchemaField(description="Error message if the search failed") | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's find and read the file
find . -type f -name "issues.py" -path "*/backend/blocks/linear/*"Repository: Significant-Gravitas/AutoGPT
Length of output: 130
🏁 Script executed:
# Check the file size to understand what we're dealing with
wc -l autogpt_platform/backend/backend/blocks/linear/issues.py 2>/dev/null || find . -type f -name "issues.py" -path "*backend*blocks*linear*" -exec wc -l {} \;Repository: Significant-Gravitas/AutoGPT
Length of output: 132
🏁 Script executed:
# Read the specific lines mentioned in the review (138-152) and surrounding context
cat -n autogpt_platform/backend/backend/blocks/linear/issues.py 2>/dev/null | sed -n '130,240p' || find . -type f -name "issues.py" -path "*backend*blocks*linear*" -exec sh -c 'cat -n "$1" | sed -n "130,240p"' _ {} \;Repository: Significant-Gravitas/AutoGPT
Length of output: 4880
🏁 Script executed:
# Find the Block base class
find . -type f -name "*.py" -path "*/backend/blocks/*" | head -5
fd -t f "block.py" "backend"Repository: Significant-Gravitas/AutoGPT
Length of output: 481
🏁 Script executed:
# Look for the Block base class definition
rg -t py "class Block" --type py -A 10 | head -100Repository: Significant-Gravitas/AutoGPT
Length of output: 8545
🏁 Script executed:
# Check other blocks in the same directory to see how they handle error outputs
ls -la autogpt_platform/backend/backend/blocks/linear/Repository: Significant-Gravitas/AutoGPT
Length of output: 679
🏁 Script executed:
# Search for output validation in the Block framework
rg -t py "BlockOutput" --type py autogpt_platform/backend/backend | head -20Repository: Significant-Gravitas/AutoGPT
Length of output: 1865
🏁 Script executed:
# Find the BlockOutput type definition
rg -t py "BlockOutput\s*=" autogpt_platform/backend/backend/sdk --type py -B 2 -A 5Repository: Significant-Gravitas/AutoGPT
Length of output: 54
🏁 Script executed:
# Look for how outputs are validated in the executor
cat -n autogpt_platform/backend/backend/executor/manager.py | head -150Repository: Significant-Gravitas/AutoGPT
Length of output: 5933
🏁 Script executed:
# Search for output schema validation
rg -t py "output_schema" autogpt_platform/backend/backend/sdk -A 5 -B 2Repository: Significant-Gravitas/AutoGPT
Length of output: 54
🏁 Script executed:
# Check one other block with error handling to see the pattern
cat -n autogpt_platform/backend/backend/blocks/agent.py | grep -A 30 "class Output"Repository: Significant-Gravitas/AutoGPT
Length of output: 1407
🏁 Script executed:
# Find BlockSchema and BlockSchemaOutput definitions
find . -type f -name "*.py" -path "*/backend/*" -exec grep -l "class BlockSchema\|class BlockSchemaOutput" {} \;Repository: Significant-Gravitas/AutoGPT
Length of output: 120
🏁 Script executed:
# Look at the block.py or models.py in the sdk
ls -la autogpt_platform/backend/backend/sdk/Repository: Significant-Gravitas/AutoGPT
Length of output: 502
🏁 Script executed:
# Get more context on BlockOutput and output validation
rg -t py "class BlockOutput|class BlockSchemaOutput|class BlockSchema" autogpt_platform/backend --type py -A 10 | head -100Repository: Significant-Gravitas/AutoGPT
Length of output: 4419
🏁 Script executed:
# Check another block with error field to see if it always yields error
find . -type f -name "*.py" -path "*/backend/blocks/*" -exec grep -l "error.*SchemaField" {} \; | head -3Repository: Significant-Gravitas/AutoGPT
Length of output: 1898
🏁 Script executed:
# Look at the ai_condition.py block to see how it handles error
cat -n autogpt_platform/backend/backend/blocks/ai_condition.py | grep -A 20 "class Output"Repository: Significant-Gravitas/AutoGPT
Length of output: 1123
🏁 Script executed:
# Look at apollo/organization.py to see error handling
cat -n autogpt_platform/backend/backend/blocks/apollo/organization.py | grep -A 20 "class Output"Repository: Significant-Gravitas/AutoGPT
Length of output: 1045
🏁 Script executed:
# Read the full BlockSchemaOutput definition to understand default behavior
cat -n autogpt_platform/backend/backend/data/block.py | sed -n '1,100p'Repository: Significant-Gravitas/AutoGPT
Length of output: 3826
🏁 Script executed:
# Check the exact definition of BlockSchemaOutput including the error field
cat -n autogpt_platform/backend/backend/data/block.py | sed -n '95,115p'Repository: Significant-Gravitas/AutoGPT
Length of output: 924
🏁 Script executed:
# Look at how other blocks that extend BlockSchemaOutput handle the error field
rg -t py "class Output\(BlockSchemaOutput\)" autogpt_platform/backend/backend/blocks -A 5 | head -50Repository: Significant-Gravitas/AutoGPT
Length of output: 4428
🏁 Script executed:
# Check the issues.py run method more carefully to see all yield paths
cat -n autogpt_platform/backend/backend/blocks/linear/issues.py | sed -n '220,250p'Repository: Significant-Gravitas/AutoGPT
Length of output: 1314
🏁 Script executed:
# Get the complete BlockSchemaOutput definition
cat -n autogpt_platform/backend/backend/data/block.py | sed -n '140,175p'Repository: Significant-Gravitas/AutoGPT
Length of output: 1555
🏁 Script executed:
# Check how blocks yield output in error cases - do they yield both fields or just one?
cat -n autogpt_platform/backend/backend/blocks/data_manipulation.py | sed -n '1,50p'Repository: Significant-Gravitas/AutoGPT
Length of output: 2228
🏁 Script executed:
# Look at a block's run method to see the pattern for both success and error
rg -t py "async def run" autogpt_platform/backend/backend/blocks/data_manipulation.py -A 30 | head -80Repository: Significant-Gravitas/AutoGPT
Length of output: 3264
🏁 Script executed:
# Let me verify the complete picture - check all the Output schemas that override error
rg -t py "error.*SchemaField" autogpt_platform/backend/backend/blocks -B 5 | head -100Repository: Significant-Gravitas/AutoGPT
Length of output: 10319
🏁 Script executed:
# Check if there's output validation logic that would enforce required fields
rg -t py "validate.*output|required.*output" autogpt_platform/backend --type py -i | head -20Repository: Significant-Gravitas/AutoGPT
Length of output: 578
🏁 Script executed:
# Look at the CreateDictionaryBlock pattern more carefully - does it always yield error?
cat -n autogpt_platform/backend/backend/blocks/data_manipulation.py | sed -n '50,80p'Repository: Significant-Gravitas/AutoGPT
Length of output: 1377
🏁 Script executed:
# Get the exact BlockSchemaOutput definition to confirm the default
cat -n autogpt_platform/backend/backend/data/block.py | sed -n '190,210p'Repository: Significant-Gravitas/AutoGPT
Length of output: 1082
🏁 Script executed:
# Check if there's validation that enforces required outputs
cat -n autogpt_platform/backend/backend/data/block.py | sed -n '250,350p'Repository: Significant-Gravitas/AutoGPT
Length of output: 4541
🏁 Script executed:
# Get the complete BlockSchemaOutput definition
cat -n autogpt_platform/backend/backend/data/block.py | sed -n '350,365p'Repository: Significant-Gravitas/AutoGPT
Length of output: 722
🏁 Script executed:
# Now let's check how outputs are validated when a block finishes execution
rg -t py "validate.*output_name|validate_field" autogpt_platform/backend/backend/executor -A 5 -B 5Repository: Significant-Gravitas/AutoGPT
Length of output: 54
Make error output field optional and yield it on success.
The error: str field in the Output schema is required (overrides the base class default), but the success path only yields issues. Consider making error optional with default=None and yielding None on success, or remove the override entirely to use the base class definition.
Suggested fix
class Output(BlockSchemaOutput):
issues: list[Issue] = SchemaField(description="List of issues")
- error: str = SchemaField(description="Error message if the search failed")
+ error: str | None = SchemaField(
+ description="Error message if the search failed",
+ default=None,
+ ) issues = await self.search_issues(
credentials=credentials,
term=input_data.term,
max_results=input_data.max_results,
team_name=input_data.team_name,
)
yield "issues", issues
+ yield "error", None🤖 Prompt for AI Agents
In `@autogpt_platform/backend/backend/blocks/linear/issues.py` around lines 138 -
152, The Output schema overrides BlockSchemaOutput by declaring error: str as
required while the success path only yields issues; make the error field
optional so successful yields can include None or omit it: update the Output
class (Output, issues, error) to set error's default to None and type to str |
None (e.g., error: str | None = SchemaField(default=None, description="Error
message if the search failed")), or remove the error override entirely to
inherit the base definition from BlockSchemaOutput; adjust any yields to
explicitly yield error=None on success if you choose the optional field
approach.
| max_results: int = 10, | ||
| team_name: str | None = None, | ||
| ) -> list[Issue]: | ||
| client = LinearClient(credentials=credentials) | ||
| response: list[Issue] = await client.try_search_issues(term=term) | ||
| return response | ||
|
|
||
| # Resolve team name to ID if provided | ||
| # Raises LinearAPIException with descriptive message if team not found | ||
| team_id: str | None = None | ||
| if team_name: | ||
| team_id = await client.try_get_team_by_name(team_name=team_name) | ||
|
|
||
| return await client.try_search_issues( | ||
| term=term, | ||
| max_results=max_results, | ||
| team_id=team_id, | ||
| ) |
There was a problem hiding this comment.
Remove inline comments in search_issues to follow the no-comments rule.
The logic is clear without them.
As per coding guidelines, "autogpt_platform/**/*.{ts,tsx,js,py}: Avoid comments at all times unless the code is very complex".
🧹 Proposed cleanup
- # Resolve team name to ID if provided
- # Raises LinearAPIException with descriptive message if team not found
team_id: str | None = None📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| max_results: int = 10, | |
| team_name: str | None = None, | |
| ) -> list[Issue]: | |
| client = LinearClient(credentials=credentials) | |
| response: list[Issue] = await client.try_search_issues(term=term) | |
| return response | |
| # Resolve team name to ID if provided | |
| # Raises LinearAPIException with descriptive message if team not found | |
| team_id: str | None = None | |
| if team_name: | |
| team_id = await client.try_get_team_by_name(team_name=team_name) | |
| return await client.try_search_issues( | |
| term=term, | |
| max_results=max_results, | |
| team_id=team_id, | |
| ) | |
| max_results: int = 10, | |
| team_name: str | None = None, | |
| ) -> list[Issue]: | |
| client = LinearClient(credentials=credentials) | |
| team_id: str | None = None | |
| if team_name: | |
| team_id = await client.try_get_team_by_name(team_name=team_name) | |
| return await client.try_search_issues( | |
| term=term, | |
| max_results=max_results, | |
| team_id=team_id, | |
| ) |
🤖 Prompt for AI Agents
In `@autogpt_platform/backend/backend/blocks/linear/issues.py` around lines 204 -
219, Remove the inline comments inside the search_issues implementation: delete
the comment lines "// Resolve team name to ID if provided" and "// Raises
LinearAPIException with descriptive message if team not found" so the function
body only contains the logic that instantiates LinearClient, conditionally sets
team_id via client.try_get_team_by_name(team_name=team_name), and returns
client.try_search_issues(term=term, max_results=max_results, team_id=team_id);
keep all variables and calls (LinearClient, try_get_team_by_name,
try_search_issues, team_id) unchanged.
| class State(BaseModel): | ||
| id: str | ||
| name: str | ||
| type: str | None = ( | ||
| None # Workflow state type (e.g., "triage", "backlog", "started", "completed", "canceled") | ||
| ) |
There was a problem hiding this comment.
Remove inline comment from State.type to comply with the no-comments rule.
The comment isn’t essential for readability here. Consider leaving just the default value.
As per coding guidelines, "autogpt_platform/**/*.{ts,tsx,js,py}: Avoid comments at all times unless the code is very complex".
🧹 Proposed cleanup
- type: str | None = (
- None # Workflow state type (e.g., "triage", "backlog", "started", "completed", "canceled")
- )
+ type: str | None = None📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| class State(BaseModel): | |
| id: str | |
| name: str | |
| type: str | None = ( | |
| None # Workflow state type (e.g., "triage", "backlog", "started", "completed", "canceled") | |
| ) | |
| class State(BaseModel): | |
| id: str | |
| name: str | |
| type: str | None = None |
🤖 Prompt for AI Agents
In `@autogpt_platform/backend/backend/blocks/linear/models.py` around lines 39 -
44, Remove the inline comment on the State.type field: in the State model (class
State) remove the trailing comment after the default assignment so the
declaration reads with the default value only (retain type annotation str | None
and default = None); no other changes required.
Summary
Implements SECRT-1880 - Improve Linear Search Block
Changes
Models (
models.py)Statemodel withid,name, andtypefields for workflow state informationstate: State | Nonefield toIssuemodelAPI Client (
_api.py)try_search_issues()to:max_resultsparameter (default 10, was ~50) to reduce token usageteam_idparameter for team filteringcreatedAt,state,project, andassigneefields in resultstry_get_team_by_name()to return descriptive error message when team not found instead of crashing withIndexErrorBlock (
issues.py)max_resultsinput parameter (1-100, default 10)team_nameinput parameter for optional team filteringerroroutput field for graceful error handlingPRODUCTIVITY,ISSUE_TRACKING)Breaking Changes
max_resultsup to 100 if neededNon-Breaking Changes
statefield added toIssue(optional, defaults toNone)max_resultsparam added (has default value)team_nameparam added (optional, defaults toNone)erroroutput added (follows established pattern from GitHub blocks)Testing
Linear
SECRT-1880