feat!(blocks): Add Reddit OAuth2 integration and advanced Reddit blocks (#11623)

Replaces user/password Reddit credentials with OAuth2, adds
RedditOAuthHandler, and updates Reddit blocks to support OAuth2
authentication. Introduces new blocks for creating posts, fetching post
details, searching, editing posts, and retrieving subreddit info.
Updates test credentials and input handling to use OAuth2 tokens.

<!-- Clearly explain the need for these changes: -->

### Changes 🏗️
Rebuild the reddit blocks to support oauth2 rather than requiring users
to provide their password and username.
This is done via a swap from script based to web based authentication on
the reddit side faciliatated by the approval of an oauth app by reddit
on the account `ntindle`
<!-- Concisely describe all of the changes made in this pull request:
-->

### Checklist 📋

#### For code changes:
- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
  <!-- Put your test plan here: -->
  - [x] Build a super agent
  - [x] Upload the super agent and a video of it working

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduces full Reddit OAuth2 support and substantially expands Reddit
capabilities across the platform.
> 
> - Adds `RedditOAuthHandler` with token exchange, refresh, revoke;
registers handler in `integrations/oauth/__init__.py`
> - Refactors Reddit blocks to use `OAuth2Credentials` and `praw` via
refresh tokens; updates models (e.g., `post_id`, richer outputs) and
adds `strip_reddit_prefix`
> - New blocks: create/edit/delete posts, post/get/delete comments,
reply to comments, get post details, user posts (self/others), search,
inbox, subreddit info/rules/flairs, send messages
> - Updates default `settings.config.reddit_user_agent` and test
credentials; minor `.branchlet.json` addition
> - Docs: clarifies block error-handling with
`BlockInputError`/`BlockExecutionError` guidance
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4f1f26c7e7. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added OAuth2-based authentication for Reddit integration, replacing
legacy credential methods
* Expanded Reddit capabilities with new blocks for creating posts,
retrieving post details, managing comments, accessing inbox, and
fetching user/subreddit information
* Enhanced data models to support richer Reddit interactions and
chainable workflows

* **Documentation**
* Updated error handling guidance to distinguish between validation
errors and runtime errors with improved exception patterns

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
This commit is contained in:
Nicholas Tindle
2026-01-09 13:53:03 -07:00
committed by GitHub
parent a318832414
commit 43cbe2e011
7 changed files with 2625 additions and 32 deletions

View File

@@ -227,7 +227,7 @@ backend/blocks/my_provider/
## Best Practices
1. **Error Handling**: Error output pin is already defined on BlockSchemaOutput
1. **Error Handling**: Use `BlockInputError` for validation failures and `BlockExecutionError` for runtime errors (import from `backend.util.exceptions`). These inherit from `ValueError` so the executor treats them as user-fixable. See [Error Handling in new_blocks.md](new_blocks.md#error-handling) for details.
2. **Credentials**: Use the provider's `credentials_field()` method
3. **Validation**: Use SchemaField constraints (ge, le, min_length, etc.)
4. **Categories**: Choose appropriate categories for discoverability

View File

@@ -616,7 +616,59 @@ custom_requests = Requests(
### Error Handling
All blocks should have an error output that catches all reasonable errors that a user can handle, wrap them in a ValueError, and re-raise. Don't catch things the system admin would need to fix like being out of money or unreachable addresses.
Blocks should raise appropriate exceptions for errors that users can fix. The executor classifies errors based on whether they inherit from `ValueError` - these are treated as "expected failures" (user-fixable) rather than system errors.
#### Block Exception Classes
Import from `backend.util.exceptions`:
```python
from backend.util.exceptions import BlockInputError, BlockExecutionError
```
| Exception | Use Case | Example |
|-----------|----------|---------|
| `BlockInputError` | Invalid user input, validation failures, missing required fields | Bad API key format, invalid URL, missing credentials |
| `BlockExecutionError` | Runtime failures the user can address | API errors, auth failures, resource not found, rate limits |
| `ValueError` | Simple cases (auto-wrapped to `BlockExecutionError`) | Basic validation errors |
#### Raising Exceptions
```python
from backend.util.exceptions import BlockInputError, BlockExecutionError
class MyBlock(Block):
async def run(self, input_data: Input, **kwargs) -> BlockOutput:
# Input validation - use BlockInputError
if not input_data.api_key:
raise BlockInputError(
message="API key is required",
block_name=self.name,
block_id=self.id,
)
try:
result = await self.call_api(input_data)
yield "result", result
except AuthenticationError as e:
# API/runtime errors - use BlockExecutionError
raise BlockExecutionError(
message=f"Authentication failed: {e}",
block_name=self.name,
block_id=self.id,
) from e
```
#### What NOT to Catch
Don't catch errors that require system admin intervention:
- Out of money/credits
- Unreachable infrastructure
- Database connection failures
- Internal server errors from your own services
Let these propagate as unexpected errors so they get proper attention.
### Data Models