Skip to content

Commit

Permalink
feat(blocks): Add blocks for GitHub checks & statuses (#9271)
Browse files Browse the repository at this point in the history
<!-- Clearly explain the need for these changes: -->
We really want to be able to automate with our agents some behaviors
that involve blocking PRs or unblocking them based on automations.

### Changes 🏗️

<!-- Concisely describe all of the changes made in this pull request:
-->
- Adds Status Blocks for github
- Modifies the pull requests block to not have include pr changes as
advanced because that's a wild place to hide it
- Adds some disabled checks blocks that require github app
- Added IfMatches Block to make using stuff easier

### 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] Built agent using

---------

Co-authored-by: Aarushi <[email protected]>
  • Loading branch information
ntindle and aarushik93 authored Jan 28, 2025
1 parent e0d153b commit 7609969
Show file tree
Hide file tree
Showing 6 changed files with 655 additions and 2 deletions.
80 changes: 80 additions & 0 deletions autogpt_platform/backend/backend/blocks/branching.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,83 @@ def run(self, input_data: Input, **kwargs) -> BlockOutput:
yield "yes_output", yes_value
else:
yield "no_output", no_value


class IfInputMatchesBlock(Block):
class Input(BlockSchema):
input: Any = SchemaField(
description="The input to match against",
placeholder="For example: 10 or 'hello' or True",
)
value: Any = SchemaField(
description="The value to output if the input matches",
placeholder="For example: 'Greater' or 20 or False",
)
yes_value: Any = SchemaField(
description="The value to output if the input matches",
placeholder="For example: 'Greater' or 20 or False",
default=None,
)
no_value: Any = SchemaField(
description="The value to output if the input does not match",
placeholder="For example: 'Greater' or 20 or False",
default=None,
)

class Output(BlockSchema):
result: bool = SchemaField(
description="The result of the condition evaluation (True or False)"
)
yes_output: Any = SchemaField(
description="The output value if the condition is true"
)
no_output: Any = SchemaField(
description="The output value if the condition is false"
)

def __init__(self):
super().__init__(
id="6dbbc4b3-ca6c-42b6-b508-da52d23e13f2",
input_schema=IfInputMatchesBlock.Input,
output_schema=IfInputMatchesBlock.Output,
description="Handles conditional logic based on comparison operators",
categories={BlockCategory.LOGIC},
test_input=[
{
"input": 10,
"value": 10,
"yes_value": "Greater",
"no_value": "Not greater",
},
{
"input": 10,
"value": 20,
"yes_value": "Greater",
"no_value": "Not greater",
},
{
"input": 10,
"value": None,
"yes_value": "Yes",
"no_value": "No",
},
],
test_output=[
("result", True),
("yes_output", "Greater"),
("result", False),
("no_output", "Not greater"),
("result", False),
("no_output", "No"),
# ("result", True),
# ("yes_output", "Yes"),
],
)

def run(self, input_data: Input, **kwargs) -> BlockOutput:
if input_data.input == input_data.value or input_data.input is input_data.value:
yield "result", True
yield "yes_output", input_data.yes_value
else:
yield "result", False
yield "no_output", input_data.no_value
10 changes: 8 additions & 2 deletions autogpt_platform/backend/backend/blocks/github/_api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from urllib.parse import urlparse

from backend.blocks.github._auth import GithubCredentials
from backend.blocks.github._auth import (
GithubCredentials,
GithubFineGrainedAPICredentials,
)
from backend.util.request import Requests


Expand Down Expand Up @@ -35,7 +38,10 @@ def _get_headers(credentials: GithubCredentials) -> dict[str, str]:
}


def get_api(credentials: GithubCredentials, convert_urls: bool = True) -> Requests:
def get_api(
credentials: GithubCredentials | GithubFineGrainedAPICredentials,
convert_urls: bool = True,
) -> Requests:
return Requests(
trusted_origins=["https://api.github.com", "https://github.com"],
extra_url_validator=_convert_to_api_url if convert_urls else None,
Expand Down
30 changes: 30 additions & 0 deletions autogpt_platform/backend/backend/blocks/github/_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
Literal["api_key", "oauth2"] if GITHUB_OAUTH_IS_CONFIGURED else Literal["api_key"],
]

GithubFineGrainedAPICredentials = APIKeyCredentials
GithubFineGrainedAPICredentialsInput = CredentialsMetaInput[
Literal[ProviderName.GITHUB], Literal["api_key"]
]


def GithubCredentialsField(scope: str) -> GithubCredentialsInput:
"""
Expand All @@ -37,6 +42,16 @@ def GithubCredentialsField(scope: str) -> GithubCredentialsInput:
)


def GithubFineGrainedAPICredentialsField(
scope: str,
) -> GithubFineGrainedAPICredentialsInput:
return CredentialsField(
required_scopes={scope},
description="The GitHub integration can be used with OAuth, "
"or any API key with sufficient permissions for the blocks it is used on.",
)


TEST_CREDENTIALS = APIKeyCredentials(
id="01234567-89ab-cdef-0123-456789abcdef",
provider="github",
Expand All @@ -50,3 +65,18 @@ def GithubCredentialsField(scope: str) -> GithubCredentialsInput:
"type": TEST_CREDENTIALS.type,
"title": TEST_CREDENTIALS.type,
}

TEST_FINE_GRAINED_CREDENTIALS = APIKeyCredentials(
id="01234567-89ab-cdef-0123-456789abcdef",
provider="github",
api_key=SecretStr("mock-github-api-key"),
title="Mock GitHub API key",
expires_at=None,
)

TEST_FINE_GRAINED_CREDENTIALS_INPUT = {
"provider": TEST_FINE_GRAINED_CREDENTIALS.provider,
"id": TEST_FINE_GRAINED_CREDENTIALS.id,
"type": TEST_FINE_GRAINED_CREDENTIALS.type,
"title": TEST_FINE_GRAINED_CREDENTIALS.type,
}
Loading

0 comments on commit 7609969

Please sign in to comment.