Skip to content

Commit afac7d0

Browse files
committed
Addition of btrees and several updates
1 parent 0d941ce commit afac7d0

23 files changed

+428
-194
lines changed

‎.env.default

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
1-
OPENAI_API_KEY="your openai api key here"
1+
OPENAI_API_KEY="your openai api key here"
2+
3+
AGENTOPS_API_KEY = "your agentops api key here"
4+
5+
X_EMAIL = "twitter email here"
6+
X_USERNAME = "twitter username here"
7+
X_PASSWORD = "twitter password here"
8+
9+

‎.vscode/settings.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
"[python]": {
33
"editor.formatOnSave": true,
44
"editor.codeActionsOnSave": {
5-
"source.fixAll": "explicit",
6-
"source.organizeImports": "explicit"
5+
"source.fixAll": "explicit"
76
},
87
"editor.defaultFormatter": "charliermarsh.ruff"
98
},

‎btree.py

Lines changed: 68 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,84 @@
1-
import threading
21
import time
32

43
import py_trees
54

6-
from playground.assistants_api import api
7-
8-
9-
# Define the ActionWithThread class
10-
class ActionWrapper(py_trees.behaviour.Behaviour):
11-
def __init__(self, name, action_function=None):
12-
super(ActionWrapper, self).__init__(name=name)
13-
self.thread = None
14-
self.thread_running = False
15-
self.thread_success = False
16-
self.action_function = action_function
17-
18-
def setup(self):
19-
# This is called once at the beginning to setup any necessary state or resources
20-
print("%s.setup()" % self.name)
21-
return py_trees.common.Status.SUCCESS
22-
23-
def initialise(self):
24-
# This is called once each time the behavior is started
25-
print("%s.initialise()" % self.name)
26-
self.thread_running = True
27-
self.thread_success = False
28-
self.thread = threading.Thread(target=self.long_running_process)
29-
self.thread.start()
30-
31-
def long_running_process(self):
32-
# Simulate a long-running process
33-
try:
34-
print("%s: Thread started, running process..." % self.name)
35-
result = self.action_function()
36-
print(result)
37-
self.thread_success = True
38-
print("%s: Thread completed successfully." % self.name)
39-
except Exception as e:
40-
print("%s: Exception in thread: %s" % (self.name, str(e)))
41-
finally:
42-
self.thread_running = False
43-
44-
def update(self):
45-
# This is called every tick to update the status of the behavior
46-
print("%s.update()" % self.name)
47-
if self.thread_running:
48-
return py_trees.common.Status.RUNNING
49-
else:
50-
return (
51-
py_trees.common.Status.SUCCESS
52-
if self.thread_success
53-
else py_trees.common.Status.FAILURE
54-
)
55-
56-
def terminate(self, new_status):
57-
# This is called once each time the behavior terminates
58-
print("%s.terminate(%s)" % (self.name, new_status))
59-
if self.thread is not None:
60-
self.thread.join()
61-
self.thread = None
62-
self.thread_running = False
63-
self.thread_success = False
64-
5+
from playground.behavior_trees import (
6+
create_assistant_action,
7+
create_assistant_condition,
8+
)
659

10+
search_term = "GPT Agents"
6611
# Create the root node (sequence)
6712
root = py_trees.composites.Sequence("RootSequence", memory=True)
6813

69-
thread = api.create_thread()
70-
assistant = api.get_assistant_by_name("manager")
71-
message = "check the status of the thread, if there are no recent user messages, do nothing and return the word 'success'"
72-
73-
action_function = lambda: api.call_assistant_with_thread(thread, assistant.id, message)
74-
75-
# Create an instance of ActionWithThread and add it to the root node
76-
long_running_action = ActionWithThread(
77-
name="LongRunningAction", action_function=action_function
14+
file_condition = create_assistant_condition(
15+
condition_name="Check File Date",
16+
assistant_name="File Manager",
17+
assistant_instructions="""
18+
load the file youtube_current.txt.
19+
it will contain a date and time in the form HH-MM-DD-YY
20+
where HH (01-24) is the hour, DD is the month (01 - 31), MM is the day (01 - 12) and YY is the year (24)
21+
Return just the word SUCCESS if the date and time is earlier than the current date and time,
22+
Return just the word FAILURE if the date and time is the same or later than the current date and time.
23+
""",
24+
)
25+
root.add_child(file_condition)
26+
27+
search_youtube_action = create_assistant_action(
28+
action_name="Search YouTube",
29+
assistant_name="YouTube Researcher",
30+
assistant_instructions=f"""
31+
Search Term: {search_term}
32+
Use the query "{search_term}" to search for videos on YouTube.
33+
then for each video download the transcript and summarize it for relevance to {search_term}
34+
be sure to include a link to each of the videos,
35+
and then save all summarizations to a file called youtube_transcripts.txt
36+
""",
7837
)
79-
root.add_child(long_running_action)
38+
root.add_child(search_youtube_action)
39+
40+
write_post_action = create_assistant_action(
41+
action_name="Write Post",
42+
assistant_name="Twitter Post Writer",
43+
assistant_instructions=f"""
44+
Load the file called youtube_transcripts.txt,
45+
analyze the contents for references to {search_term} and then select
46+
the most exciting and relevant video to post on Twitter.
47+
Then write a Twitter post that is relevant to the video,
48+
and include a link to the video, along
49+
with exciting highlights or mentions,
50+
and save it to a file called youtube_twitter_post.txt.
51+
""",
52+
)
53+
root.add_child(write_post_action)
54+
55+
post_action = create_assistant_action(
56+
action_name="Post",
57+
assistant_name="Social Media Assistant",
58+
assistant_instructions="""
59+
Load the file called youtube_twitter_post.txt and post the content to Twitter.
60+
If the content is empty please do not post anything.
61+
""",
62+
)
63+
root.add_child(post_action)
64+
65+
file_write_action = create_assistant_action(
66+
action_name="Write File Date",
67+
assistant_name="File Manager",
68+
assistant_instructions="""
69+
write the current date and time to a file called youtube_current.txt.
70+
Format the date and time in the form HH-MM-DD-YY
71+
where HH (01-24) is the hour, DD is the month (01 - 31), MM is the day (01 - 12) and YY is the year (24)
72+
Be sure to increment the hour by 1 each time this action is called.
73+
""",
74+
)
75+
root.add_child(file_write_action)
8076

8177
# Create the behavior tree
8278
tree = py_trees.trees.BehaviourTree(root)
8379

8480
# Tick the tree to run it
85-
for i in range(100):
81+
for i in range(1000):
8682
print(f"Tick {i + 1}")
8783
tree.tick()
88-
time.sleep(5) # Simulate time between ticks
89-
90-
# Add a blackboard watcher to visualize the tree
91-
# py_trees.display.render_dot_tree(tree.root)
84+
time.sleep(300) # Simulate time between ticks

‎btree_examples/first_btree.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import py_trees
2+
3+
4+
# Define the conditions and actions
5+
class HasApple(py_trees.behaviour.Behaviour):
6+
def __init__(self, name):
7+
super(HasApple, self).__init__(name)
8+
9+
def update(self):
10+
# Condition check (placeholder for actual logic)
11+
if True: # Replace with actual condition
12+
return py_trees.common.Status.SUCCESS
13+
else:
14+
return py_trees.common.Status.FAILURE
15+
16+
17+
class EatApple(py_trees.behaviour.Behaviour):
18+
def __init__(self, name):
19+
super(EatApple, self).__init__(name)
20+
21+
def update(self):
22+
# Action (placeholder for actual action)
23+
print("Eating apple")
24+
return py_trees.common.Status.SUCCESS
25+
26+
27+
class HasPear(py_trees.behaviour.Behaviour):
28+
def __init__(self, name):
29+
super(HasPear, self).__init__(name)
30+
31+
def update(self):
32+
# Condition check (placeholder for actual logic)
33+
if True: # Replace with actual condition
34+
return py_trees.common.Status.SUCCESS
35+
else:
36+
return py_trees.common.Status.FAILURE
37+
38+
39+
class EatPear(py_trees.behaviour.Behaviour):
40+
def __init__(self, name):
41+
super(EatPear, self).__init__(name)
42+
43+
def update(self):
44+
# Action (placeholder for actual action)
45+
print("Eating pear")
46+
return py_trees.common.Status.SUCCESS
47+
48+
49+
# Create the behavior tree nodes
50+
has_apple = HasApple(name="Has apple")
51+
eat_apple = EatApple(name="Eat apple")
52+
sequence_1 = py_trees.composites.Sequence(name="Sequence 1", memory=True)
53+
sequence_1.add_children([has_apple, eat_apple])
54+
55+
has_pear = HasPear(name="Has pear")
56+
eat_pear = EatPear(name="Eat pear")
57+
sequence_2 = py_trees.composites.Sequence(name="Sequence 2", memory=True)
58+
sequence_2.add_children([has_pear, eat_pear])
59+
60+
root = py_trees.composites.Selector(name="Selector", memory=True)
61+
root.add_children([sequence_1, sequence_2])
62+
63+
# Create the behavior tree
64+
behavior_tree = py_trees.trees.BehaviourTree(root)
65+
66+
# Execute the behavior tree
67+
py_trees.logging.level = py_trees.logging.Level.DEBUG
68+
for i in range(1, 4):
69+
print("\n------------------ Tick {0} ------------------".format(i))
70+
behavior_tree.tick()

‎gradio_theme_builder.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import gradio as gr
2+
3+
gr.themes.builder()

‎logs/logs.txt

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,5 @@
1-
Running on local URL: http://127.0.0.1:7860
1+
Running on local URL: http://127.0.0.1:7861
22

33
To create a public link, set `share=True` in `launch()`.
4-
# >>> Code Interpreter
5-
import matplotlib.pyplot as plt
6-
import numpy as np
7-
8-
# Define the linear function
9-
def linear_function(x):
10-
return 3*x + 6
11-
12-
# Generate x values
13-
x = np.linspace(-10, 10, 400)
14-
# Generate y values
15-
y = linear_function(x)
16-
17-
# Create the plot
18-
plt.figure(figsize=(8, 6))
19-
plt.plot(x, y, label='y = 3x + 6', color='blue')
20-
plt.xlabel('x')
21-
plt.ylabel('y')
22-
plt.title('Plot of y = 3x + 6')
23-
plt.axhline(0, color='black',linewidth=0.5)
24-
plt.axvline(0, color='black',linewidth=0.5)
25-
plt.legend()
26-
plt.grid(True)
27-
plt.show()
28-
Output >
29-
assistant > File saved as assistant_outputs\file_20240526150025.png
30-
File saved as assistant_outputs\file_20240526150025.png
4+
action: post_to_twitter(args={"content":"Hello there from the OpenAI Assistants API, I am a Social Media Assistant."}) -> None
5+
assistant >

‎main.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,13 @@ def stream_worker(assistant_id, thread_id, event_handler):
165165
}
166166
"""
167167

168+
theme = gr.themes.Default()
168169

169-
with gr.Blocks(css=custom_css) as demo:
170+
# theme = gr.themes.Glass()
171+
# theme = gr.themes.Monochrome()
172+
# theme = gr.themes.Soft()
173+
174+
with gr.Blocks(css=custom_css, theme=theme) as demo:
170175
with gr.Tab(label="Playground"):
171176
with gr.Row():
172177
with gr.Column(scale=4):
@@ -213,6 +218,7 @@ def stream_worker(assistant_id, thread_id, event_handler):
213218
)
214219
demo.load(logger.read_logs, None, logs, every=1)
215220

221+
216222
demo.queue()
217223

218224

‎playground/__init__.py

Whitespace-only changes.

‎playground/actions_manager.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ def inspect_file_for_decorated_actions(self, file_contents, full_path):
190190
decorated_actions.append(
191191
{
192192
"name": node.name,
193+
"group": os.path.splitext(os.path.basename(full_path))[
194+
0
195+
],
193196
"pointer": function_pointer,
194197
"agent_action": getattr(
195198
function_pointer, "_agent_action", None

‎playground/actions_panel.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import gradio as gr
2+
3+
4+
def assistants_actions_panel(actions_manager):
5+
available_actions = actions_manager.get_actions()
6+
7+
# Group actions by their group property
8+
action_groups = {}
9+
for action in available_actions:
10+
group = action.get("group", "Ungrouped")
11+
if group not in action_groups:
12+
action_groups[group] = []
13+
action_groups[group].append(action["name"])
14+
15+
with gr.Accordion("Actions", open=False):
16+
group_accordions = []
17+
for group, actions in action_groups.items():
18+
with gr.Accordion(group, open=False) as group_accordion:
19+
group_checkbox = gr.CheckboxGroup(
20+
label=f"{group} Actions", choices=actions, interactive=True
21+
)
22+
group_accordions.append((group_accordion, group_checkbox))
23+
24+
# Hidden control to store all selected actions
25+
assistant_actions = gr.CheckboxGroup(
26+
label="All Selected Actions", choices=[], visible=False
27+
)
28+
29+
def sync_actions(selected_actions):
30+
# Update the assistant actions control with the new selection
31+
assistant_actions.update(value=selected_actions)
32+
return selected_actions
33+
34+
# Create a change listener for each group's checkbox group
35+
for _, group_checkbox in group_accordions:
36+
group_checkbox.change(
37+
fn=sync_actions, inputs=group_checkbox, outputs=assistant_actions
38+
)
39+
40+
return assistant_actions
41+
42+
43+
# Example usage
44+
if __name__ == "__main__":
45+
46+
class ActionsManager:
47+
def get_actions(self):
48+
return [
49+
{"name": "Action1", "group": "Group1"},
50+
{"name": "Action2", "group": "Group1"},
51+
{"name": "Action3", "group": "Group2"},
52+
{"name": "Action4", "group": "Group2"},
53+
{"name": "Action5", "group": "Group3"},
54+
]
55+
56+
actions_manager = ActionsManager()
57+
demo = gr.Interface(
58+
fn=lambda x: x, inputs=assistants_actions_panel(actions_manager), outputs="text"
59+
)
60+
demo.launch()

0 commit comments

Comments
 (0)