Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a deep thinking reasoner model (o1-preview/mini) #68

Merged
merged 18 commits into from
Oct 10, 2024
Merged
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
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ developer = "goose.toolkit.developer:Developer"
github = "goose.toolkit.github:Github"
jira = "goose.toolkit.jira:Jira"
screen = "goose.toolkit.screen:Screen"
reasoner = "goose.toolkit.reasoner:Reasoner"
repo_context = "goose.toolkit.repo_context.repo_context:RepoContext"

[project.entry-points."goose.profile"]
Expand Down
5 changes: 5 additions & 0 deletions src/goose/toolkit/prompts/reasoner.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
It is important to use deep reasoning and thinking tools when working with code, especially solving problems or new issues.
Writing code requires deep thinking and reasoning at times, which can be used to provide ideas, solutions, and to check other solutions.
Always use your generate_code tool when writing code especially on a new problem,
and use deep_reason to check solutions or when there have been errors or solutions are not clear.
Consider these tools as expert consultants that can provide advice and code that you may use.
77 changes: 77 additions & 0 deletions src/goose/toolkit/reasoner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from exchange import Exchange, Message, Text
from exchange.content import Content
from exchange.providers import OpenAiProvider
from goose.toolkit.base import Toolkit, tool
from goose.utils.ask import ask_an_ai


class Reasoner(Toolkit):
"""Deep thinking toolkit for reasoning through problems and solutions"""

def message_content(self, content: Content) -> Text:
if isinstance(content, Text):
return content
else:
return Text(str(content))

@tool
def deep_reason(self, problem: str) -> str:
"""
Debug or reason about challenges or problems.
It will take a minute to think about it and consider solutions.

Args:
problem (str): description of problem or errors seen.

Returns:
response (str): A solution, which may include a suggestion or code snippet.
"""
# Create an instance of Exchange with the inlined OpenAI provider
self.notifier.status("thinking...")
provider = OpenAiProvider.from_env()

# Create messages list
existing_messages_copy = [
Message(role=msg.role, content=[self.message_content(content) for content in msg.content])
for msg in self.exchange_view.processor.messages
]
exchange = Exchange(provider=provider, model="o1-preview", messages=existing_messages_copy, system=None)

response = ask_an_ai(input="please help reason about this: " + problem, exchange=exchange, no_history=False)
return response.content[0].text

@tool
def generate_code(self, instructions: str) -> str:
"""
reason about and write code based on instructions given.
this will consider and reason about the instructions and come up with code to solve it.

Args:
instructions (str): instructions of what code to write or how to modify it.

Returns:
response (str): generated code to be tested or applied. Not it will not write directly to files so you have to take it and process it if it is suitable.
""" # noqa: E501
# Create an instance of Exchange with the inlined OpenAI provider
provider = OpenAiProvider.from_env()

# clone messages, converting to text for context
existing_messages_copy = [
Message(role=msg.role, content=[self.message_content(content) for content in msg.content])
for msg in self.exchange_view.processor.messages
]
exchange = Exchange(provider=provider, model="o1-mini", messages=existing_messages_copy, system=None)

self.notifier.status("generating code...")
response = ask_an_ai(
input="Please follow the instructions, "
+ "and ideally return relevant code and little commentary:"
+ instructions,
exchange=exchange,
no_history=False,
)
return response.content[0].text

def system(self) -> str:
"""Retrieve instructions on how to use this reasoning and code generation tool"""
return Message.load("prompts/reasoner.jinja").text