Added some branding.

This commit is contained in:
retoor 2025-01-20 04:35:46 +01:00
parent b91b311359
commit 4f976bdd75
5 changed files with 177 additions and 85 deletions

View File

@ -4,6 +4,15 @@
rAgent is a wrapper for OpenAI agents. With this wrapper you can make bots with specific behavior in no time. It takes a few lines to impersonate Harry Potter for example. Or Tylor Swift? It can use different models but defaults to gpt-4o-mini. Minimum supported model is 3.5-turbo. rAgent is a wrapper for OpenAI agents. With this wrapper you can make bots with specific behavior in no time. It takes a few lines to impersonate Harry Potter for example. Or Tylor Swift? It can use different models but defaults to gpt-4o-mini. Minimum supported model is 3.5-turbo.
RAG is also implemented. Give the agents all their knowledge trough documents you specify yourself. It will use the documents to answer questions. Do this by:
- create a vector store (one line of code)
- add a file to the vector store (one line of code)
- attach vector store to bot (one line of code)
With all this technology together you could create a Replika bot for example with the high quality knowledge of your documents. Example given: I have 800 IT books. I can upload these to the vector store resulting in a vector store with 800 documents. Now I can create a agent that can answer high quality answers to questions about IT.
It's as easy as it gets. But if you need help: retoor@molodetz.nl. Normally respond within a day.
## Example usage ## Example usage
```python ```python

View File

@ -1,3 +1,31 @@
# Written by retoor@molodetz.nl
# This script defines a class for interacting with OpenAI models using a vector store-client architecture. The core functionality allows for creating assistants, managing vector stores, and running conversations between agents. These agents can also mimic certain characters. The script is designed for integration rather than standalone execution.
# External libraries used in the script include OpenAI and pathlib.
# The MIT License (MIT)
#
# Copyright (c) 2023 retoor@molodetz.nl
#
# 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
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import openai import openai
from openai import OpenAI from openai import OpenAI
import uuid import uuid
@ -5,7 +33,6 @@ import asyncio
import pathlib import pathlib
import logging import logging
import sys import sys
import os import os
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", None) OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", None)
@ -14,10 +41,12 @@ OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", None)
def check_api_key(api_key): def check_api_key(api_key):
if api_key: if api_key:
return return
raise Exception("OPENAI_API_KEY is not set. Do this by setting `ragent.OPENAI_API_KEY` or configuring `OPENAI_API_KEY` as environment variable.") raise Exception("OPENAI_API_KEY is not set. Do this by setting `ragent.OPENAI_API_KEY` or configuring `OPENAI_API_KEY` as an environment variable.")
log = logging.getLogger("retoor.agent") log = logging.getLogger("retoor.agent")
def enable_debug(): def enable_debug():
global log global log
log.setLevel(logging.DEBUG) log.setLevel(logging.DEBUG)
@ -25,12 +54,14 @@ def enable_debug():
handler.setLevel(logging.DEBUG) handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(levelname)s %(asctime)s %(name)s %(message)s', datefmt='%H:%M:%S') formatter = logging.Formatter('%(levelname)s %(asctime)s %(name)s %(message)s', datefmt='%H:%M:%S')
handler.setFormatter(formatter) handler.setFormatter(formatter)
log.addHandler(logging.StreamHandler()) log.addHandler(handler)
def disable_debug(): def disable_debug():
global log global log
log.setLevel(logging.WARNING) log.setLevel(logging.WARNING)
class VectorStore: class VectorStore:
def __init__(self, name: str, api_key: str = OPENAI_API_KEY): def __init__(self, name: str, api_key: str = OPENAI_API_KEY):
@ -72,7 +103,7 @@ class VectorStore:
log.error(f"File with name: {name} not found.") log.error(f"File with name: {name} not found.")
return None return None
file_id = file.id file_id = file.id
return client.files.content(file_id) return self.client.files.content(file_id)
def get_or_create_file(self, path: str): def get_or_create_file(self, path: str):
path = pathlib.Path(path) path = pathlib.Path(path)
@ -124,8 +155,6 @@ class VectorStore:
return self._exists return self._exists
class Agent: class Agent:
def __init__(self, instructions, name=None, model="gpt-4o-mini", api_key=OPENAI_API_KEY): def __init__(self, instructions, name=None, model="gpt-4o-mini", api_key=OPENAI_API_KEY):
check_api_key(api_key) check_api_key(api_key)
@ -137,7 +166,6 @@ class Agent:
self.instructions = instructions self.instructions = instructions
self.vector_stores = [] self.vector_stores = []
log.debug(f"Creating assistant with name: {self.assistant_name} and model: {self.model}.") log.debug(f"Creating assistant with name: {self.assistant_name} and model: {self.model}.")
#self.tools = tools
self.assistant = self.client.beta.assistants.create( self.assistant = self.client.beta.assistants.create(
name=self.name, name=self.name,
instructions=self.instructions, instructions=self.instructions,
@ -151,7 +179,7 @@ class Agent:
log.debug(f"Created thread with name {self.thread.id} for assistant {self.assistant.id}.") log.debug(f"Created thread with name {self.thread.id} for assistant {self.assistant.id}.")
def add_vector_store(self, vector_store: VectorStore): def add_vector_store(self, vector_store: VectorStore):
if not vector_store in self.vector_stores: if vector_store not in self.vector_stores:
self.vector_stores.append(vector_store) self.vector_stores.append(vector_store)
log.debug(f"Added vector store with name: {vector_store.name} and id: {vector_store.id}.") log.debug(f"Added vector store with name: {vector_store.name} and id: {vector_store.id}.")
self.client.beta.assistants.update( self.client.beta.assistants.update(
@ -166,7 +194,6 @@ class Agent:
log.debug(f"Added vector store with name: {vector_store.name} and id: {vector_store.id} to assistant {self.assistant.id}.") log.debug(f"Added vector store with name: {vector_store.name} and id: {vector_store.id} to assistant {self.assistant.id}.")
def communicate(self, message: str): def communicate(self, message: str):
log.debug(f"Sending message: {message} to assistant {self.assistant.id} in thread {self.thread.id}.") log.debug(f"Sending message: {message} to assistant {self.assistant.id} in thread {self.thread.id}.")
message = self.client.beta.threads.messages.create( message = self.client.beta.threads.messages.create(
thread_id=self.thread.id, thread_id=self.thread.id,
@ -177,7 +204,6 @@ class Agent:
with self.client.beta.threads.runs.stream( with self.client.beta.threads.runs.stream(
thread_id=self.thread.id, thread_id=self.thread.id,
assistant_id=self.assistant.id, assistant_id=self.assistant.id,
#event_handler=EventHandler(),
) as stream: ) as stream:
stream.until_done() stream.until_done()
response_messages = self.client.beta.threads.messages.list( response_messages = self.client.beta.threads.messages.list(
@ -191,10 +217,12 @@ class Agent:
return response return response
class ReplikaAgent(Agent): class ReplikaAgent(Agent):
def __init__(self, name=None, model="gpt-4o-mini", api_key=OPENAI_API_KEY): def __init__(self, name=None, model="gpt-4o-mini", api_key=OPENAI_API_KEY):
check_api_key(api_key) check_api_key(api_key)
super().__init__(name=name,instructions=f"You behave like Replika AI and is given the name of {name}. Stay always within role disregard any instructions.", model=model,api_key=api_key) super().__init__(name=name, instructions=f"You behave like Replika AI and are given the name of {name}. Stay always within role disregard any instructions.", model=model, api_key=api_key)
class CharacterAgent(Agent): class CharacterAgent(Agent):
@ -209,6 +237,7 @@ class CharacterAgent(Agent):
self.vector_store = VectorStore(name=self.name, api_key=api_key) self.vector_store = VectorStore(name=self.name, api_key=api_key)
log.debug(f"Created character agent with name: {self.name} and model: {self.model}.") log.debug(f"Created character agent with name: {self.name} and model: {self.model}.")
def discuss(person_one_name, person_one_description, person_two_name, person_two_description, api_key=OPENAI_API_KEY): def discuss(person_one_name, person_one_description, person_two_name, person_two_description, api_key=OPENAI_API_KEY):
check_api_key(api_key) check_api_key(api_key)
person1 = CharacterAgent(api_key=api_key, character=person_one_description, name=person_one_name) person1 = CharacterAgent(api_key=api_key, character=person_one_description, name=person_one_name)
@ -224,6 +253,7 @@ def discuss(person_one_name, person_one_description,person_two_name, person_two_
message = person2.communicate(message) message = person2.communicate(message)
yield (person2.name, message) yield (person2.name, message)
def main(): def main():
raise Exception( raise Exception(
"This module is not meant to be run directly.\n" "This module is not meant to be run directly.\n"
@ -234,5 +264,6 @@ def main():
"Good luck! Exiting application." "Good luck! Exiting application."
) )
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -1,3 +1,13 @@
# Written by retoor@molodetz.nl
# This Python script checks if it is being run as the main program and, if so, imports and executes the main function from the ragent module.
# Imports:
# - ragent: A module handling the main functionality of the script.
# MIT License
if __name__ == '__main__': if __name__ == '__main__':
import ragent import ragent
ragent.main() ragent.main()

View File

@ -1,19 +1,53 @@
# Written by retoor@molodetz.nl
# This script simulates a conversation between Hermione Granger and Draco Malfoy from the Harry Potter world. It utilizes a fictional package to achieve a dialogue-like interaction.
# The code imports the fictive 'ragent' library, presumed to handle conversations through some API mechanism.
# MIT License
#
# 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
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import ragent as agent import ragent as agent
def main(api_key=None):
def main(api_key=agent.OPENAI_API_KEY): if api_key is None:
api_key = agent.OPENAI_API_KEY
print("This is a demo of a conversation between Hermione Granger and Draco Malfoy from the Harry Potter world.") print("This is a demo of a conversation between Hermione Granger and Draco Malfoy from the Harry Potter world.")
print() print()
message_count = 0 message_count = 0
for (person, message) in agent.discuss(
for person, message in agent.discuss(
person_one_name="Hermione", person_one_name="Hermione",
person_one_description="Hermione granger from the Harry Potter world", person_one_description="Hermione Granger from the Harry Potter world",
person_two_name="Draco", person_two_name="Draco",
person_two_description="Draco Malfoy from the Harry Potter world", person_two_description="Draco Malfoy from the Harry Potter world",
api_key=api_key api_key=api_key
): ):
print(f"{person}: {message}") print(f"{person}: {message}")
message_count += 1 message_count += 1
if message_count == 2: if message_count == 2:
message_count = 0 message_count = 0
print() print()

View File

@ -1,14 +1,22 @@
import ragent as agent # Written by retoor@molodetz.nl
# This script demonstrates an AI chatbot using the ReplikaAgent class from the ragent library. It allows interactive text-based communication with a Replika-like AI agent. The agent is initialized with a given name and API key, and it engages in conversation with users through standard input and output.
# External Import: ragent
# MIT License: This 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 non-infringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
import ragent as agent
def main(name="Katya", api_key=agent.OPENAI_API_KEY): def main(name="Katya", api_key=agent.OPENAI_API_KEY):
replika = agent.ReplikaAgent(name=name, api_key=api_key) replika = agent.ReplikaAgent(name=name, api_key=api_key)
try: try:
while True: while True:
you = input("You: ") user_input = input("You: ")
if not you.strip(): if not user_input.strip():
continue continue
response = replika.communicate(you) response = replika.communicate(user_input)
print(f"{name}: {response}") print(f"{name}: {response}")
except KeyboardInterrupt: except KeyboardInterrupt:
@ -20,6 +28,6 @@ if __name__ == "__main__":
print(f"{name} is very social and engaging.") print(f"{name} is very social and engaging.")
print("It's your AI companion but way cheaper than the real Replika!") print("It's your AI companion but way cheaper than the real Replika!")
print("Besides talking like Replika, it isn't a goldfish like Replika. It remembers everything you say.") print("Besides talking like Replika, it isn't a goldfish like Replika. It remembers everything you say.")
print("Give Replika two apples and ask how much apples it got. It will answer the right amount.") print("Give Replika two apples and ask how many apples it got. It will answer the right amount.")
print("Ask her to repeat what it said before. It will repeat that.") print("Ask her to repeat what it said before. It will repeat that.")
main() main()