Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions golemgpt/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ def main():
memory.load(job_key)
goals = memory.goals

goals = [
"Get weather in Batumi, Georgia. Use Celsius. "
"Save results in human readable format."
]

# goals = [
# "Get best offers for dedicated servers in the USA, need at least 1 Tb "
# "of storage and 1 Gbps of bandwidth. Save results in human readable format."
# "Get weather in Batumi, Georgia. Use Celsius. "
# "Save results in human readable format."
# ]

goals = [
"Get best offers for dedicated servers in the USA, need at least 1 Tb "
"of storage and 1 Gbps of bandwidth. Save results in human readable format."
]

# goals = [
# "Get the price for LEGO collection 75342 (Star Wars). "
# "Verify the offers found via search are valid. "
Expand All @@ -51,13 +51,13 @@ def main():
# "Summarize results in human readable format with pricing details in a single file."
# ]

goals = [
"Find funny chess meme images about, use some creativity "
"in search queries. Get at least 10 images, and please avoid "
"downloading non-relevant images. Also avoid SVG and GIF files, "
"prefer PNG ad JPEG. If download failed just look for other sources. "
"Download images themselves and also put URLs it text file."
]
# goals = [
# "Find funny chess meme images about, use some creativity "
# "in search queries. Get at least 10 images, and please avoid "
# "downloading non-relevant images. Also avoid SVG and GIF files, "
# "prefer PNG ad JPEG. If download failed just look for other sources. "
# "Download images themselves and also put URLs it text file."
# ]

while not goals:
goal = input("Enter a goal for the Golem-GPT:\n?> ").strip()
Expand All @@ -69,7 +69,7 @@ def main():
job_key=job_key,
memory=memory,
settings=settings,
actions=GeneralActions.get_actions(),
actions=GeneralActions.get_actions(settings),
)

with chdir(outdir):
Expand Down
17 changes: 11 additions & 6 deletions golemgpt/actions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
from golemgpt.actions.read_file import read_file_action
from golemgpt.actions.reject_job import reject_job_action
from golemgpt.actions.run_script import run_script_action
from golemgpt.actions.search_text_via_brave import search_text_via_brave_action
# from golemgpt.actions.search_text_via_brave import search_text_via_brave_action
from golemgpt.actions.summarize_file import summarize_file_action
from golemgpt.actions.write_file import write_file_action
from golemgpt.handlers.base import BaseHandler
from golemgpt.handlers.extract_images import ExtractImagesHandler
from golemgpt.handlers.extract_links import ExtractLinksHandler
from golemgpt.handlers.http_download import HttpDownloadHandler
from golemgpt.handlers.search_text_via_brave_action import SearchTextHandler
from golemgpt.settings import Settings
from golemgpt.types import ActionFn

__all__ = [
Expand All @@ -26,11 +29,13 @@ class GeneralActions:
"""General actions set to fulfil goals."""

@classmethod
def get_actions(cls) -> dict[str, ActionFn | type]:
def get_actions(cls, settings: Settings) -> dict[str, ActionFn | BaseHandler]:
brave_search_api_key = settings.BRAVE_SEARCH_API_KEY
return {
"extract_images": ExtractImagesHandler,
"extract_links": ExtractLinksHandler,
"http_download": HttpDownloadHandler,
"extract_images": ExtractImagesHandler(),
"extract_links": ExtractLinksHandler(),
"http_download": HttpDownloadHandler(),
"search_text_via_brave": SearchTextHandler(brave_search_api_key),
#
"read_file": read_file_action,
"summarize_file": summarize_file_action,
Expand All @@ -49,7 +54,7 @@ def get_actions(cls) -> dict[str, ActionFn | type]:
"finish_job": finish_job_action,
#
# "search_images_online": search_images_via_bing_action,
"search_text_via_brave": search_text_via_brave_action,
# "search_text_via_brave": search_text_via_brave_action,
}


Expand Down
22 changes: 4 additions & 18 deletions golemgpt/cognitron/openai.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import inspect
from json import loads as json_loads
from json import loads as json_loads, dumps as json_dumps
from typing import Any, Callable

from golemgpt.handlers.base import BaseHandler
Expand Down Expand Up @@ -127,6 +127,8 @@ def __init__(
self.tools = self.parse_actions_to_tools(self.actions)
self.verbosity = verbosity

console.info(json_dumps(self.tools, indent=2))

@classmethod
def parse_actions_to_tools(
cls, actions: dict[str, ActionFn | type]
Expand All @@ -139,26 +141,10 @@ def parse_actions_to_tools(
"""
tools = []

def _extract_type(annotation: Any) -> str:
if hasattr(annotation, "__args__"):
return annotation.__args__[0].__name__
return annotation.__name__

def _json_type(name: str) -> str:
types_map = {
"str": "string",
"float": "number",
"int": "number",
"bool": "boolean",
"dict": "object",
}
return types_map.get(name, "object")

for key in actions:
action_fn = actions[key]

if isinstance(action_fn, type):
assert issubclass(action_fn, BaseHandler)
if isinstance(action_fn, BaseHandler):
parameters = action_fn.get_params_jsonschema()
description = action_fn.get_description()
else:
Expand Down
6 changes: 3 additions & 3 deletions golemgpt/golems/general.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from golemgpt.codex import BaseCodex

# from golemgpt.handlers.base import BaseHandler
from golemgpt.handlers.base import BaseHandler
from golemgpt.runners.base import BaseRunner
from golemgpt.settings import Settings
from golemgpt.memory import BaseMemory
Expand Down Expand Up @@ -34,7 +34,7 @@ def __init__(
job_key: str,
memory: BaseMemory,
settings: Settings,
actions: dict[str, ActionFn | type],
actions: dict[str, ActionFn | BaseHandler],
) -> None:
self.name = name
self.actions = actions
Expand Down Expand Up @@ -103,7 +103,7 @@ def initialize(self) -> None:
self.memory.save()

def cognitron(
self, actions: dict[str, ActionFn | type], **options
self, actions: dict[str, ActionFn | BaseHandler], **options
) -> BaseCognitron:
"""Return a new Cognitron instance."""
assert self.settings, "Error: settings must be initialized first."
Expand Down
6 changes: 3 additions & 3 deletions golemgpt/handlers/http_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ class HttpDownloadHandler(BaseHandler[HttpDownloadParams]):
success_prompt = "Response saved to {out_filename} ({file_size} bytes)."

wrong_link_error = (
"Error trying to download '{output_ext}' file "
"from '{content_ext}' URL. Download file as {guess_ext} first "
"Error trying to download '{out_filename}' file "
"from '{content_ext}' URL. Download file as {content_ext} first "
"and then extract links using the provided summary tool."
)

Expand Down Expand Up @@ -83,7 +83,7 @@ def validate_params(self, params: dict[str, Any]) -> HttpDownloadParams:
if output_ext not in self.text_formats:
error = self.wrong_link_error.format(
content_ext=content_ext,
output_ext=output_ext,
out_filename=validated.out_filename,
)
raise RequestTypeError(error)

Expand Down
123 changes: 123 additions & 0 deletions golemgpt/handlers/search_text_via_brave_action.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
from json import dumps as json_dumps

from golemgpt.handlers.base import BaseHandler, BaseOutput, BaseParams
# from golemgpt.utils.http import get_content_type, is_http_url
# from golemgpt.utils.misc import workpath
from golemgpt.utils.http import http_request_as_json

BRAVE_SEARCH_API_URL = "https://api.search.brave.com/res/v1/web/search"


class SearchTextParams(BaseParams):
query: str
page_size: int = 20
page_offset: int = 0
# search_lang: str | None = None,
# country: str | None = None,


class SearchTextHandler(BaseHandler[SearchTextParams]):
params_cls = SearchTextParams

description = (
"Search online via Brave Search API, text only, "
"with pagination options."
)

def __init__(self, api_key: str) -> None:
super().__init__()
assert api_key, "Error: no `brave_search_api_key` provided"
self.api_key = api_key
self.client = BraveSearchClient(self.api_key)

def do_action(self, params: SearchTextParams | None) -> BaseOutput:
assert params
search_results = self.client.search(
query=params.query,
count=params.page_size,
offset=params.page_offset,
)
return BaseOutput(result=json_dumps(search_results))


class BraveSearchClient:
def __init__(
self,
api_key: str,
endpoint: str = BRAVE_SEARCH_API_URL,
) -> None:
self.api_key = api_key
self.endpoint = endpoint

def search(
self,
query: str,
count: int = 20,
offset: int = 0,
search_lang: str | None = None,
country: str | None = None,
) -> list:
headers = {
"Accept": "application/json",
"Accept-Encoding": "gzip",
"X-Subscription-Token": self.api_key,
}
params = {
"q": query,
"count": count,
"offset": offset,
}
if country:
params["country"] = country
if search_lang:
params["search_lang"] = search_lang
raw_results = http_request_as_json(
"GET",
self.endpoint,
headers=headers,
fields=params,
)
formatted_results = []
# 'query', 'mixed', 'type', 'web'
# raise Exception(raw_results.keys())

# print(raw_results["query"])
# {'original': 'Python API client example',
# 'show_strict_warning': False, 'is_navigational': False,
# 'is_news_breaking': False, 'spellcheck_off': True, 'country': 'us',
# 'bad_results': False, 'should_fallback': False, 'postal_code': '',
# 'city': '', 'header_country': '', 'more_results_available': True,
# 'state': ''}

# ['title', 'url', 'is_source_local', 'is_source_both', 'description',
# 'page_age', 'profile', 'language', 'family_friendly', 'type', 'subtype',
# 'is_live', 'meta_url', 'thumbnail', 'age', 'extra_snippets']

for item in raw_results.get("web", {}).get("results", []):
formatted_results.append(
{
"title": item["title"],
"url": item["url"],
"description": item["description"],
}
)

return formatted_results


if __name__ == "__main__":
import os

api_key = os.environ.get("BRAVE_SEARCH_API_KEY")
assert api_key, "Error: no BRAVE_SEARCH_API_KEY environment variable"

client = BraveSearchClient(api_key)
query = "Python API client example"
results = client.search(query)

for idx, result in enumerate(results):
print(
f"{idx + 1}. {result['title']}\n"
f"URL: {result['url']}\n"
f"Description: {result['description']}\n"
)
8 changes: 4 additions & 4 deletions golemgpt/runners/justdo.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ def __call__(self, action_item: ActionItem) -> Tuple[str, str]:

action_fn = self.known_actions[key]

if isinstance(action_fn, type):
assert issubclass(action_fn, BaseHandler)
handler = action_fn()
output = handler(params)
if isinstance(action_fn, BaseHandler):
# assert issubclass(action_fn, BaseHandler)
# handler = action_fn()
output = action_fn(params)
# TODO: Somehow distinguish errors vs OK result.
result = output.result or output.error_feedback
else:
Expand Down