Skip to content

Commit

Permalink
Merge branch 'master' into aarushikansal/fix-marketplace-secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
aarushik93 authored Oct 8, 2024
2 parents c805579 + 04473ca commit c03332e
Show file tree
Hide file tree
Showing 26 changed files with 315 additions and 78 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Also check out our [🚀 Roadmap][roadmap] for information about our priorities
[kanban board]: https://github.com/orgs/Significant-Gravitas/projects/1

## Contributing to the AutoGPT Platform Folder
All contributions to [the autogpt_platform folder](https://github.com/Significant-Gravitas/AutoGPT/blob/master/autogpt_platform) will be under our [Contribution License Agreement](https://github.com/Significant-Gravitas/AutoGPT/blob/master/autogpt_platform/Contributor%20License%20Agreement%20(CLA).md). By making a pull request contributing to this folder, you agree to the terms of our CLA for your contribution.
All contributions to [the autogpt_platform folder](https://github.com/Significant-Gravitas/AutoGPT/blob/master/autogpt_platform) will be under our [Contribution License Agreement](https://github.com/Significant-Gravitas/AutoGPT/blob/master/autogpt_platform/Contributor%20License%20Agreement%20(CLA).md). By making a pull request contributing to this folder, you agree to the terms of our CLA for your contribution. All contributions to other folders will be under the MIT license.

## In short
1. Avoid duplicate work, issues, PRs etc.
Expand Down
8 changes: 8 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
All portions of this repository are under one of two licenses. The majority of the AutoGPT repository is under the MIT License below. The autogpt_platform folder is under the
Polyform Shield License.


MIT License


Copyright (c) 2023 Toran Bruce Richards


Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:


The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Here are two examples of what you can do with AutoGPT:
These examples show just a glimpse of what you can achieve with AutoGPT! You can create customized workflows to build agents for any use case.

---
### Mission and Licencing
Our mission is to provide the tools, so that you can focus on what matters:

- 🏗️ **Building** - Lay the foundation for something amazing.
Expand All @@ -77,6 +78,13 @@ Be part of the revolution! **AutoGPT** is here to stay, at the forefront of AI i
 | 
**🚀 [Contributing](CONTRIBUTING.md)**

**Licensing:**

MIT License: The majority of the AutoGPT repository is under the MIT License.

Polyform Shield License: This license applies to the autogpt_platform folder.

For more information, see https://agpt.co/blog/introducing-the-autogpt-platform

---
## 🤖 AutoGPT Classic
Expand Down
4 changes: 4 additions & 0 deletions autogpt_platform/backend/backend/blocks/github/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
)


# --8<-- [start:GithubCommentBlockExample]
class GithubCommentBlock(Block):
class Input(BlockSchema):
credentials: GithubCredentialsInput = GithubCredentialsField("repo")
Expand Down Expand Up @@ -104,6 +105,9 @@ def run(
yield "error", f"Failed to post comment: {str(e)}"


# --8<-- [end:GithubCommentBlockExample]


class GithubMakeIssueBlock(Block):
class Input(BlockSchema):
credentials: GithubCredentialsInput = GithubCredentialsField("repo")
Expand Down
3 changes: 2 additions & 1 deletion autogpt_platform/backend/backend/blocks/google/_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
from backend.data.model import CredentialsField, CredentialsMetaInput
from backend.util.settings import Secrets

# --8<-- [start:GoogleOAuthIsConfigured]
secrets = Secrets()
GOOGLE_OAUTH_IS_CONFIGURED = bool(
secrets.google_client_id and secrets.google_client_secret
)

# --8<-- [end:GoogleOAuthIsConfigured]
GoogleCredentials = OAuth2Credentials
GoogleCredentialsInput = CredentialsMetaInput[Literal["google"], Literal["oauth2"]]

Expand Down
9 changes: 9 additions & 0 deletions autogpt_platform/backend/backend/data/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,15 @@ async def get_graph_all_versions(graph_id: str, user_id: str) -> list[Graph]:
return [Graph.from_db(graph) for graph in graph_versions]


async def delete_graph(graph_id: str, user_id: str) -> int:
entries_count = await AgentGraph.prisma().delete_many(
where={"id": graph_id, "userId": user_id}
)
if entries_count:
logger.info(f"Deleted {entries_count} graph entries for Graph #{graph_id}")
return entries_count


async def create_graph(graph: Graph, user_id: str) -> Graph:
async with transaction() as tx:
await __create_graph(tx, graph, user_id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from .google import GoogleOAuthHandler
from .notion import NotionOAuthHandler

# --8<-- [start:HANDLERS_BY_NAMEExample]
HANDLERS_BY_NAME: dict[str, type[BaseOAuthHandler]] = {
handler.PROVIDER_NAME: handler
for handler in [
Expand All @@ -11,5 +12,6 @@
NotionOAuthHandler,
]
}
# --8<-- [end:HANDLERS_BY_NAMEExample]

__all__ = ["HANDLERS_BY_NAME"]
11 changes: 11 additions & 0 deletions autogpt_platform/backend/backend/integrations/oauth/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,37 @@


class BaseOAuthHandler(ABC):
# --8<-- [start:BaseOAuthHandler1]
PROVIDER_NAME: ClassVar[str]
DEFAULT_SCOPES: ClassVar[list[str]] = []
# --8<-- [end:BaseOAuthHandler1]

@abstractmethod
# --8<-- [start:BaseOAuthHandler2]
def __init__(self, client_id: str, client_secret: str, redirect_uri: str): ...

# --8<-- [end:BaseOAuthHandler2]

@abstractmethod
# --8<-- [start:BaseOAuthHandler3]
def get_login_url(self, scopes: list[str], state: str) -> str:
# --8<-- [end:BaseOAuthHandler3]
"""Constructs a login URL that the user can be redirected to"""
...

@abstractmethod
# --8<-- [start:BaseOAuthHandler4]
def exchange_code_for_tokens(
self, code: str, scopes: list[str]
) -> OAuth2Credentials:
# --8<-- [end:BaseOAuthHandler4]
"""Exchanges the acquired authorization code from login for a set of tokens"""
...

@abstractmethod
# --8<-- [start:BaseOAuthHandler5]
def _refresh_tokens(self, credentials: OAuth2Credentials) -> OAuth2Credentials:
# --8<-- [end:BaseOAuthHandler5]
"""Implements the token refresh mechanism"""
...

Expand Down
4 changes: 4 additions & 0 deletions autogpt_platform/backend/backend/integrations/oauth/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .base import BaseOAuthHandler


# --8<-- [start:GithubOAuthHandlerExample]
class GitHubOAuthHandler(BaseOAuthHandler):
"""
Based on the documentation at:
Expand Down Expand Up @@ -119,3 +120,6 @@ def _request_username(self, access_token: str) -> str | None:

# Get the login (username)
return response.json().get("login")


# --8<-- [end:GithubOAuthHandlerExample]
2 changes: 2 additions & 0 deletions autogpt_platform/backend/backend/integrations/oauth/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
logger = logging.getLogger(__name__)


# --8<-- [start:GoogleOAuthHandlerExample]
class GoogleOAuthHandler(BaseOAuthHandler):
"""
Based on the documentation at https://developers.google.com/identity/protocols/oauth2/web-server
Expand All @@ -26,6 +27,7 @@ class GoogleOAuthHandler(BaseOAuthHandler):
"https://www.googleapis.com/auth/userinfo.profile",
"openid",
]
# --8<-- [end:GoogleOAuthHandlerExample]

def __init__(self, client_id: str, client_secret: str, redirect_uri: str):
self.client_id = client_id
Expand Down
18 changes: 18 additions & 0 deletions autogpt_platform/backend/backend/server/rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from fastapi import APIRouter, Body, Depends, FastAPI, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from typing_extensions import TypedDict

from backend.data import block, db
from backend.data import execution as execution_db
Expand Down Expand Up @@ -168,6 +169,12 @@ def run_service(self):
methods=["PUT"],
tags=["templates", "graphs"],
)
api_router.add_api_route(
path="/graphs/{graph_id}",
endpoint=self.delete_graph,
methods=["DELETE"],
tags=["graphs"],
)
api_router.add_api_route(
path="/graphs/{graph_id}/versions",
endpoint=self.get_graph_all_versions,
Expand Down Expand Up @@ -398,6 +405,17 @@ async def create_new_template(
) -> graph_db.Graph:
return await cls.create_graph(create_graph, is_template=True, user_id=user_id)

class DeleteGraphResponse(TypedDict):
version_counts: int

@classmethod
async def delete_graph(
cls, graph_id: str, user_id: Annotated[str, Depends(get_user_id)]
) -> DeleteGraphResponse:
return {
"version_counts": await graph_db.delete_graph(graph_id, user_id=user_id)
}

@classmethod
async def create_graph(
cls,
Expand Down
2 changes: 2 additions & 0 deletions autogpt_platform/backend/backend/util/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,12 @@ class Secrets(UpdateTrackingModel["Secrets"], BaseSettings):
)

# OAuth server credentials for integrations
# --8<-- [start:OAuthServerCredentialsExample]
github_client_id: str = Field(default="", description="GitHub OAuth client ID")
github_client_secret: str = Field(
default="", description="GitHub OAuth client secret"
)
# --8<-- [end:OAuthServerCredentialsExample]
google_client_id: str = Field(default="", description="Google OAuth client ID")
google_client_secret: str = Field(
default="", description="Google OAuth client secret"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- DropForeignKey
ALTER TABLE "AgentGraph" DROP CONSTRAINT "AgentGraph_agentGraphParentId_version_fkey";

-- AddForeignKey
ALTER TABLE "AgentGraph" ADD CONSTRAINT "AgentGraph_agentGraphParentId_version_fkey" FOREIGN KEY ("agentGraphParentId", "version") REFERENCES "AgentGraph"("id", "version") ON DELETE CASCADE ON UPDATE CASCADE;
4 changes: 2 additions & 2 deletions autogpt_platform/backend/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ model AgentGraph {
// All sub-graphs are defined within this 1-level depth list (even if it's a nested graph).
AgentSubGraphs AgentGraph[] @relation("AgentSubGraph")
agentGraphParentId String?
AgentGraphParent AgentGraph? @relation("AgentSubGraph", fields: [agentGraphParentId, version], references: [id, version])
AgentGraphParent AgentGraph? @relation("AgentSubGraph", fields: [agentGraphParentId, version], references: [id, version], onDelete: Cascade)
@@id(name: "graphVersionId", [id, version])
}
Expand All @@ -63,7 +63,7 @@ model AgentNode {
id String @id @default(uuid())
agentBlockId String
AgentBlock AgentBlock @relation(fields: [agentBlockId], references: [id])
AgentBlock AgentBlock @relation(fields: [agentBlockId], references: [id], onUpdate: Cascade)
agentGraphId String
agentGraphVersion Int @default(1)
Expand Down
25 changes: 25 additions & 0 deletions autogpt_platform/backend/test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,28 @@
async def server():
async with SpinTestServer() as server:
yield server


@pytest.fixture(scope="session", autouse=True)
async def graph_cleanup(server):
created_graph_ids = []
original_create_graph = server.agent_server.create_graph

async def create_graph_wrapper(*args, **kwargs):
created_graph = await original_create_graph(*args, **kwargs)
# Extract user_id correctly
user_id = kwargs.get("user_id", args[2] if len(args) > 2 else None)
created_graph_ids.append((created_graph.id, user_id))
return created_graph

try:
server.agent_server.create_graph = create_graph_wrapper
yield # This runs the test function
finally:
server.agent_server.create_graph = original_create_graph

# Delete the created graphs and assert they were deleted
for graph_id, user_id in created_graph_ids:
resp = await server.agent_server.delete_graph(graph_id, user_id)
num_deleted = resp["version_counts"]
assert num_deleted > 0, f"Graph {graph_id} was not deleted."
12 changes: 8 additions & 4 deletions autogpt_platform/backend/test/executor/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
from backend.blocks.maths import CalculatorBlock, Operation
from backend.data import execution, graph
from backend.server import AgentServer
from backend.server.model import CreateGraph
from backend.usecases.sample import create_test_graph, create_test_user
from backend.util.test import SpinTestServer, wait_execution


async def create_graph(s: SpinTestServer, g: graph.Graph, u: User) -> graph.Graph:
return await s.agent_server.create_graph(CreateGraph(graph=g), False, u.id)


async def execute_graph(
agent_server: AgentServer,
test_graph: graph.Graph,
Expand Down Expand Up @@ -99,9 +104,8 @@ async def assert_sample_graph_executions(

@pytest.mark.asyncio(scope="session")
async def test_agent_execution(server: SpinTestServer):
test_graph = create_test_graph()
test_user = await create_test_user()
await graph.create_graph(test_graph, user_id=test_user.id)
test_graph = await create_graph(server, create_test_graph(), test_user)
data = {"input_1": "Hello", "input_2": "World"}
graph_exec_id = await execute_graph(
server.agent_server,
Expand Down Expand Up @@ -163,7 +167,7 @@ async def test_input_pin_always_waited(server: SpinTestServer):
links=links,
)
test_user = await create_test_user()
test_graph = await graph.create_graph(test_graph, user_id=test_user.id)
test_graph = await create_graph(server, test_graph, test_user)
graph_exec_id = await execute_graph(
server.agent_server, test_graph, test_user, {}, 3
)
Expand Down Expand Up @@ -244,7 +248,7 @@ async def test_static_input_link_on_graph(server: SpinTestServer):
links=links,
)
test_user = await create_test_user()
test_graph = await graph.create_graph(test_graph, user_id=test_user.id)
test_graph = await create_graph(server, test_graph, test_user)
graph_exec_id = await execute_graph(
server.agent_server, test_graph, test_user, {}, 8
)
Expand Down
9 changes: 7 additions & 2 deletions autogpt_platform/backend/test/executor/test_scheduler.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import pytest

from backend.data import db, graph
from backend.data import db
from backend.executor import ExecutionScheduler
from backend.server.model import CreateGraph
from backend.usecases.sample import create_test_graph, create_test_user
from backend.util.service import get_service_client
from backend.util.settings import Config
Expand All @@ -12,7 +13,11 @@
async def test_agent_schedule(server: SpinTestServer):
await db.connect()
test_user = await create_test_user()
test_graph = await graph.create_graph(create_test_graph(), user_id=test_user.id)
test_graph = await server.agent_server.create_graph(
create_graph=CreateGraph(graph=create_test_graph()),
is_template=False,
user_id=test_user.id,
)

scheduler = get_service_client(
ExecutionScheduler, Config().execution_scheduler_port
Expand Down
5 changes: 5 additions & 0 deletions autogpt_platform/frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ const Monitor = () => {
flow={selectedFlow}
flowRuns={flowRuns.filter((r) => r.graphID == selectedFlow.id)}
className={column3}
refresh={() => {
fetchAgents();
setSelectedFlow(null);
setSelectedRun(null);
}}
/>
)) || (
<Card className={`p-6 ${column3}`}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ import {
SelectValue,
} from "@/components/ui/select";

// --8<-- [start:ProviderIconsEmbed]
const providerIcons: Record<string, React.FC<{ className?: string }>> = {
github: FaGithub,
google: FaGoogle,
notion: NotionLogoIcon,
};
// --8<-- [end:ProviderIconsEmbed]

export type OAuthPopupResultMessage = { message_type: "oauth_popup_result" } & (
| {
Expand Down
Loading

0 comments on commit c03332e

Please sign in to comment.