Skip to content

Commit c6a786f

Browse files
authored
Merge branch 'Josh-XT:main' into main
2 parents 3493ca1 + 541193e commit c6a786f

10 files changed

+319
-383
lines changed

agixt/Chains.py

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import os
2+
import logging
3+
from agixtsdk import AGiXTSDK
4+
from Extensions import Extensions
5+
from dotenv import load_dotenv
6+
7+
load_dotenv()
8+
9+
db_connected = True if os.getenv("DB_CONNECTED", "false").lower() == "true" else False
10+
if db_connected:
11+
from db.Chain import Chain
12+
else:
13+
from fb.Chain import Chain
14+
15+
ApiClient = AGiXTSDK(
16+
base_uri="http://localhost:7437", api_key=os.getenv("AGIXT_API_KEY", None)
17+
)
18+
19+
chain = Chain()
20+
21+
22+
class Chains:
23+
async def run_chain_step(
24+
self,
25+
step: dict = {},
26+
chain_name="",
27+
user_input="",
28+
agent_override="",
29+
chain_args={},
30+
):
31+
if step:
32+
if "prompt_type" in step:
33+
if agent_override != "":
34+
agent_name = agent_override
35+
else:
36+
agent_name = step["agent_name"]
37+
prompt_type = step["prompt_type"]
38+
step_number = step["step"]
39+
if "prompt_name" in step["prompt"]:
40+
prompt_name = step["prompt"]["prompt_name"]
41+
else:
42+
prompt_name = ""
43+
args = chain.get_step_content(
44+
chain_name=chain_name,
45+
prompt_content=step["prompt"],
46+
user_input=user_input,
47+
agent_name=step["agent_name"],
48+
)
49+
if chain_args != {}:
50+
for arg, value in chain_args.items():
51+
args[arg] = value
52+
53+
if "conversation_name" not in args:
54+
args["conversation_name"] = f"Chain Execution History: {chain_name}"
55+
if prompt_type == "Command":
56+
return await Extensions().execute_command(
57+
command_name=step["prompt"]["command_name"], command_args=args
58+
)
59+
elif prompt_type == "Prompt":
60+
result = ApiClient.prompt_agent(
61+
agent_name=agent_name,
62+
prompt_name=prompt_name,
63+
prompt_args={
64+
"chain_name": chain_name,
65+
"step_number": step_number,
66+
"user_input": user_input,
67+
**args,
68+
},
69+
)
70+
elif prompt_type == "Chain":
71+
result = ApiClient.run_chain(
72+
chain_name=args["chain"],
73+
user_input=args["input"],
74+
agent_name=agent_name,
75+
all_responses=args["all_responses"]
76+
if "all_responses" in args
77+
else False,
78+
from_step=args["from_step"] if "from_step" in args else 1,
79+
)
80+
if result:
81+
if isinstance(result, dict) and "response" in result:
82+
result = result["response"]
83+
if result == "Unable to retrieve data.":
84+
result = None
85+
return result
86+
else:
87+
return None
88+
89+
async def run_chain(
90+
self,
91+
chain_name,
92+
user_input=None,
93+
all_responses=True,
94+
agent_override="",
95+
from_step=1,
96+
chain_args={},
97+
):
98+
chain_data = ApiClient.get_chain(chain_name=chain_name)
99+
if chain_data == {}:
100+
return f"Chain `{chain_name}` not found."
101+
logging.info(f"Running chain '{chain_name}'")
102+
responses = {} # Create a dictionary to hold responses.
103+
last_response = ""
104+
for step_data in chain_data["steps"]:
105+
if int(step_data["step"]) >= int(from_step):
106+
if "prompt" in step_data and "step" in step_data:
107+
step = {}
108+
step["agent_name"] = (
109+
agent_override
110+
if agent_override != ""
111+
else step_data["agent_name"]
112+
)
113+
step["prompt_type"] = step_data["prompt_type"]
114+
step["prompt"] = step_data["prompt"]
115+
step["step"] = step_data["step"]
116+
logging.info(
117+
f"Running step {step_data['step']} with agent {step['agent_name']}."
118+
)
119+
try:
120+
step_response = await self.run_chain_step(
121+
step=step,
122+
chain_name=chain_name,
123+
user_input=user_input,
124+
agent_override=agent_override,
125+
chain_args=chain_args,
126+
) # Get the response of the current step.
127+
except Exception as e:
128+
logging.error(e)
129+
step_response = None
130+
if step_response == None:
131+
return f"Chain failed to complete, it failed on step {step_data['step']}. You can resume by starting the chain from the step that failed."
132+
step["response"] = step_response
133+
last_response = step_response
134+
logging.info(f"Last response: {last_response}")
135+
responses[step_data["step"]] = step # Store the response.
136+
logging.info(f"Step {step_data['step']} response: {step_response}")
137+
# Write the response to the chain responses file.
138+
await chain.update_chain_responses(
139+
chain_name=chain_name, responses=responses
140+
)
141+
if all_responses:
142+
return responses
143+
else:
144+
# Return only the last response in the chain.
145+
return last_response

agixt/Hub.py

+24-26
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ def import_agixt_hub():
4242
response = requests.get(repo_url, auth=(github_user, github_token))
4343
response.raise_for_status()
4444

45-
# Check if previous zip exists and compare it with the new one
4645
new_zip_hash = hashlib.sha256(response.content).hexdigest()
4746
if os.path.exists(zip_file_name):
4847
with open(zip_file_name, "rb") as f:
@@ -53,62 +52,61 @@ def import_agixt_hub():
5352
)
5453
return
5554

56-
# Save the new zip file
5755
with open(zip_file_name, "wb") as f:
5856
f.write(response.content)
5957

6058
zip_ref = zipfile.ZipFile(io.BytesIO(response.content))
6159
zip_ref.extractall(".")
6260
zip_ref.close()
63-
# Set permissions for the extracted files and directories
61+
6462
for root, dirs, files in os.walk(f"{repo_name}-main"):
6563
for dir_name in dirs:
6664
dir_path = os.path.join(root, dir_name)
67-
os.chmod(
68-
dir_path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
69-
) # Set permissions to read, write, and execute for all
65+
os.chmod(dir_path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
7066
for file_name in files:
7167
file_path = os.path.join(root, file_name)
7268
os.chmod(
7369
file_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
74-
) # Set permissions to read for owner and group, read-only for others
70+
)
7571

7672
print(f"Updating AGiXT Hub from {github_repo}")
77-
# Move the files and directories from the reponame-main directory to the current directory
73+
7874
for file in os.listdir(f"{repo_name}-main"):
7975
src_file = os.path.join(f"{repo_name}-main", file)
8076
dest_file = os.path.join(".", file)
8177

8278
if os.path.isdir(src_file):
83-
if os.path.exists(dest_file):
84-
for item in os.listdir(dest_file):
85-
dest_item = os.path.join(dest_file, item)
86-
if os.path.isfile(dest_item) and "config.json" not in dest_item:
87-
os.remove(dest_item)
88-
else:
79+
if not os.path.exists(dest_file):
8980
os.makedirs(dest_file, exist_ok=True)
90-
9181
for item in os.listdir(src_file):
9282
src_item = os.path.join(src_file, item)
9383
dest_item = os.path.join(dest_file, item)
9484
if os.path.isdir(src_item):
95-
if os.path.exists(dest_item):
96-
shutil.rmtree(dest_item)
97-
shutil.copytree(src_item, dest_item)
85+
if not os.path.exists(dest_item):
86+
os.makedirs(dest_item, exist_ok=True)
87+
for dirpath, dirnames, filenames in os.walk(src_item):
88+
destination = dirpath.replace(src_item, dest_item, 1)
89+
if not os.path.exists(destination):
90+
os.makedirs(destination)
91+
for filename in filenames:
92+
if filename != "config.json" or not os.path.exists(
93+
os.path.join(destination, filename)
94+
):
95+
shutil.copy2(
96+
os.path.join(dirpath, filename), destination
97+
)
9898
else:
9999
if not (
100-
"config.json" not in dest_item and os.path.exists(dest_item)
101-
): # Don't overwrite existing config.json
100+
dest_item.endswith("config.json")
101+
and os.path.exists(dest_item)
102+
):
102103
shutil.copy2(src_item, dest_item)
103104
else:
104-
if "config.json" not in dest_file and not os.path.exists(
105-
dest_file
106-
): # Don't overwrite existing config.json
107-
if os.path.exists(dest_file):
108-
os.remove(dest_file)
105+
if not (
106+
dest_file.endswith("config.json") and os.path.exists(dest_file)
107+
):
109108
shutil.move(src_file, dest_file)
110109

111-
# Remove the reponame-main directory
112110
shutil.rmtree(f"{repo_name}-main")
113111
print(f"Updated AGiXT Hub from {github_repo}")
114112
except Exception as e:

agixt/Interactions.py

+16-16
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import json
55
import time
66
import logging
7-
import asyncio
87
from datetime import datetime
98
from dotenv import load_dotenv
109

@@ -28,7 +27,7 @@
2827
from Websearch import Websearch
2928

3029
ApiClient = AGiXTSDK(
31-
base_uri="http://localhost:7437", api_key=os.getenv("AGIXT_API_KEY")
30+
base_uri="http://localhost:7437", api_key=os.getenv("AGIXT_API_KEY", None)
3231
)
3332
chain = Chain()
3433
cp = Prompts()
@@ -164,7 +163,7 @@ async def run(
164163
**kwargs,
165164
):
166165
shots = int(shots)
167-
disable_memory = True if str(disable_memory).lower() != "true" else False
166+
disable_memory = True if str(disable_memory).lower() == "true" else False
168167
browse_links = True if str(browse_links).lower() == "true" else False
169168
if conversation_name != "":
170169
conversation_name = f"{self.agent_name} History"
@@ -187,19 +186,20 @@ async def run(
187186
text_content, link_list = await self.memories.read_website(
188187
url=link
189188
)
190-
if link_list is not None and len(link_list) > 0:
191-
i = 0
192-
for sublink in link_list:
193-
if sublink[1] not in self.websearch.browsed_links:
194-
logging.info(f"Browsing link: {sublink[1]}")
195-
if i <= 10:
196-
(
197-
text_content,
198-
link_list,
199-
) = await self.memories.read_website(
200-
url=sublink[1]
201-
)
202-
i = i + 1
189+
if int(websearch_depth) > 0:
190+
if link_list is not None and len(link_list) > 0:
191+
i = 0
192+
for sublink in link_list:
193+
if sublink[1] not in self.websearch.browsed_links:
194+
logging.info(f"Browsing link: {sublink[1]}")
195+
if i <= websearch_depth:
196+
(
197+
text_content,
198+
link_list,
199+
) = await self.memories.read_website(
200+
url=sublink[1]
201+
)
202+
i = i + 1
203203
if websearch:
204204
if user_input == "":
205205
if "primary_objective" in kwargs and "task" in kwargs:

agixt/app.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from dotenv import load_dotenv
1414

1515
load_dotenv()
16-
AGIXT_API_KEY = os.getenv("AGIXT_API_KEY")
16+
AGIXT_API_KEY = os.getenv("AGIXT_API_KEY", None)
1717
db_connected = True if os.getenv("DB_CONNECTED", "false").lower() == "true" else False
1818
if db_connected:
1919
from db.Agent import Agent, add_agent, delete_agent, rename_agent, get_agents
@@ -43,7 +43,7 @@
4343
from Providers import get_provider_options, get_providers
4444
from Embedding import get_embedding_providers, get_tokens
4545
from Extensions import Extensions
46-
46+
from Chains import Chains
4747

4848
os.environ["TOKENIZERS_PARALLELISM"] = "false"
4949

@@ -161,11 +161,13 @@ class RunChain(BaseModel):
161161
agent_override: Optional[str] = ""
162162
all_responses: Optional[bool] = False
163163
from_step: Optional[int] = 1
164+
chain_args: Optional[dict] = {}
164165

165166

166167
class RunChainStep(BaseModel):
167168
prompt: str
168169
agent_override: Optional[str] = ""
170+
chain_args: Optional[dict] = {}
169171

170172

171173
class StepInfo(BaseModel):
@@ -686,12 +688,13 @@ async def get_chain_responses(chain_name: str):
686688
dependencies=[Depends(verify_api_key)],
687689
)
688690
async def run_chain(chain_name: str, user_input: RunChain):
689-
chain_response = await Chain().run_chain(
691+
chain_response = await Chains().run_chain(
690692
chain_name=chain_name,
691693
user_input=user_input.prompt,
692694
agent_override=user_input.agent_override,
693695
all_responses=user_input.all_responses,
694696
from_step=user_input.from_step,
697+
chain_args=user_input.chain_args,
695698
)
696699
return chain_response
697700

@@ -710,11 +713,12 @@ async def run_chain_step(chain_name: str, step_number: str, user_input: RunChain
710713
raise HTTPException(
711714
status_code=404, detail=f"Step {step_number} not found. {e}"
712715
)
713-
chain_step_response = await chain.run_chain_step(
716+
chain_step_response = await Chains().run_chain_step(
714717
step=step,
715718
chain_name=chain_name,
716719
user_input=user_input.prompt,
717720
agent_override=user_input.agent_override,
721+
chain_args=user_input.chain_args,
718722
)
719723
return chain_step_response
720724

0 commit comments

Comments
 (0)