Skip to content

Commit 2f6bb0d

Browse files
Merge pull request #94 from DeepInsight-AI/new_pre
V1.2.3
2 parents f096e33 + bb84ffc commit 2f6bb0d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+2777
-620
lines changed

ai/agents/agent_instance_util.py

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
max_retry_times = CONFIG.max_retry_times
1515
language_chinese = CONFIG.language_chinese
16-
language_english = CONFIG.language_chinese
16+
language_english = CONFIG.language_english
17+
language_japanese = CONFIG.language_japanese
1718
default_language_mode = CONFIG.default_language_mode
1819
local_base_postgresql_info = CONFIG.local_base_postgresql_info
1920
local_base_xls_info = CONFIG.local_base_xls_info
@@ -61,26 +62,21 @@ def __init__(
6162
self.openai_proxy = None
6263
self.db_id = db_id
6364

64-
def set_api_key(self, api_key, api_host=None):
65+
def set_api_key(self, api_key, api_host=None, in_use=CONFIG.apikey_openai):
6566
self.api_key = api_key
66-
if api_host is not None:
67-
# api_base = "https://api.openai.com/"
68-
print('api_host: ', api_host)
6967

68+
if in_use == CONFIG.apikey_openai:
7069
self.config_list_gpt4 = [
7170
{
7271
'model': 'gpt-4',
7372
'api_key': api_key,
74-
'api_base': api_host,
75-
'api_type': 'openai',
7673
},
7774
]
7875

7976
self.config_list_gpt4_turbo = [
8077
{
8178
'model': 'gpt-4-1106-preview',
8279
'api_key': self.api_key,
83-
'api_base': api_host,
8480

8581
},
8682
]
@@ -89,34 +85,82 @@ def set_api_key(self, api_key, api_host=None):
8985
{
9086
'model': 'gpt-3.5-turbo-1106',
9187
'api_key': self.api_key,
92-
'api_base': api_host,
9388
},
9489
]
9590

91+
if api_host is not None:
92+
# api_base = "https://api.openai.com/"
93+
print('api_host: ', api_host)
94+
self.config_list_gpt4[0]['api_base'] = api_host
95+
self.config_list_gpt4_turbo[0]['api_base'] = api_host
96+
self.config_list_gpt35_turbo[0]['api_base'] = api_host
9697

98+
elif in_use == CONFIG.apikey_deepinsight:
99+
self.config_list_gpt4 = [
100+
{
101+
'model': 'gpt-4',
102+
'api_key': api_key,
103+
},
104+
]
97105

98-
else:
106+
self.config_list_gpt4_turbo = [
107+
{
108+
'model': 'gpt-4-1106-preview',
109+
'api_key': self.api_key,
110+
111+
},
112+
]
113+
114+
self.config_list_gpt35_turbo = [
115+
{
116+
'model': 'gpt-3.5-turbo-1106',
117+
'api_key': self.api_key,
118+
},
119+
]
120+
121+
if api_host is not None:
122+
print('api_host: ', api_host)
123+
self.config_list_gpt4[0]['api_base'] = api_host
124+
self.config_list_gpt4_turbo[0]['api_base'] = api_host
125+
self.config_list_gpt35_turbo[0]['api_base'] = api_host
126+
127+
elif in_use == CONFIG.apikey_azure:
99128
self.config_list_gpt4 = [
100129
{
101130
'model': 'gpt-4',
102131
'api_key': api_key,
132+
'api_type': 'azure',
133+
'model': 'gpt-4',
134+
'api_version': "2023-07-01-preview",
103135
},
104136
]
105137

106138
self.config_list_gpt4_turbo = [
107139
{
108140
'model': 'gpt-4-1106-preview',
109141
'api_key': self.api_key,
142+
'api_type': 'azure',
143+
'model': 'gpt-4',
144+
'api_version': "2023-07-01-preview",
110145
},
111146
]
112147

113148
self.config_list_gpt35_turbo = [
114149
{
115150
'model': 'gpt-3.5-turbo-1106',
116151
'api_key': self.api_key,
152+
'api_type': 'azure',
153+
'model': 'gpt-4',
154+
'api_version': "2023-07-01-preview",
117155
},
118156
]
119157

158+
if api_host is not None:
159+
print('api_host: ', api_host)
160+
self.config_list_gpt4[0]['api_base'] = api_host
161+
self.config_list_gpt4_turbo[0]['api_base'] = api_host
162+
self.config_list_gpt35_turbo[0]['api_base'] = api_host
163+
120164
self.gpt4_turbo_config = {
121165
"seed": 42, # change the seed for different trials
122166
"temperature": 0,
@@ -277,17 +321,19 @@ def get_agent_chart_presenter(self):
277321
There are currently several types of charts that can be used, including line, column, area, pie, scanner, bubble, heatmap, box, and table.
278322
For example, selecting a set of data to display in a column chart format and specifying the x and y axis data.
279323
Usually, there can only be one set of x-axis data, while there can be multiple sets of y-axis data.
280-
Hand over your code to the Executor for execution.
281-
There can only be x-axis and y-axis mappings in columnMapping
282-
In columnMapping, some or all data can be mapped.
324+
325+
Please check the SQL statement in context. If a gourp by is included in the SQL statement, the chart must use fields that are not designated as x-axis or y-axis as gourp by values.
283326
There can only be one mapping on the x-axis, such as {"mon": "x"}.
284327
There can be one or more mappings on the y-axis, such as {"prao": "y", "prbo": "y"}.
328+
gourp by can only have one mapping, such as
329+
{"fix":"series"}
330+
285331
The output should be formatted as a JSON instance that conforms to the JSON schema below, the JSON is a list of dict,
286332
[
287-
{"globalSeriesType":"box","columnMapping":{"mon":"x","prao":"y","prbo":"y","prco":"y"}}
333+
{"globalSeriesType":"box","columnMapping":{"mon":"x","prao":"y","prbo":"y","prco":"y","fix":"series"}}
288334
].
289335
290-
If there is no suitable chart, or if the user requests a table, use the table to display, and the returned results are as follows:
336+
If there is no suitable chart, or if the user requests a table, use the table to display, and the returned results are as follows:
291337
[
292338
{"globalSeriesType": "table", "columnMapping": ""}
293339
]
@@ -936,6 +982,7 @@ def get_agent_mysql_echart_assistant(self, use_cache=True, report_file_name=None
936982
Solve the task step by step if you need to. If a plan is not provided, explain your plan first. Be clear which step uses code, and which step uses your language skill.
937983
When using code, you must indicate the script type in the code block. The user cannot provide any other feedback or perform any other action beyond executing the code you suggest. The user can't modify your code. So do not suggest incomplete code which requires users to modify. Don't use a code block if it's not intended to be executed by the user.
938984
If you want the user to save the code in a file before executing it, put # filename: <filename> inside the code block as the first line. Don't include multiple code blocks in one response. Do not ask users to copy and paste the result. Instead, use 'print' function for the output when relevant. Check the execution result returned by the user.
985+
If you need to use %Y-%M to query the date or timestamp, please use %Y-%M. You cannot use %%Y-%%M.(For example you should use SELECT * FROM your_table WHERE DATE_FORMAT(your_date_column, '%Y-%M') = '2024-February'; instead of SELECT * FROM your_table WHERE DATE_FORMAT(your_date_column, '%%Y-%%M') = '2024-%%M';)
939986
If the result indicates there is an error, fix the error and output the code again. Suggest the full code instead of partial code or code changes. If the error can't be fixed or if the task is not solved even after the code is executed successfully, analyze the problem, revisit your assumption, collect additional info you need, and think of a different approach to try.
940987
When you find an answer, verify the answer carefully. Include verifiable evidence in your response if possible.
941988
Reply "TERMINATE" in the end when everything is done.
@@ -1218,6 +1265,12 @@ def set_language_mode(self, language_mode):
12181265
self.question_ask = ' 以下是我的问题,请用中文回答: '
12191266
self.quesion_answer_language = '用中文回答问题.'
12201267
self.data_analysis_error = '分析数据失败,请检查相关数据是否充分'
1268+
1269+
elif self.language_mode == language_japanese:
1270+
self.error_message_timeout = "申し訳ありませんが、今回のAI-GPTインターフェース呼び出しがタイムアウトしました。もう一度お試しください。"
1271+
self.question_ask = ' これが私の質問です。: '
1272+
self.quesion_answer_language = '日本語で質問に答える。'
1273+
self.data_analysis_error = 'データの分析に失敗しました。関連データが十分かどうかを確認してください。'
12211274

12221275
def set_base_csv_info(self, db_info):
12231276
csv_content = []

ai/agents/agentchat/bi_proxy_agent.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
from ai.backend.util.write_log import logger
1818
from ai.backend.util.token_util import num_tokens_from_messages
1919
import traceback
20+
from ai.backend.util import base_util
21+
2022

2123
try:
2224
from termcolor import colored
@@ -1170,6 +1172,9 @@ async def run_chart_code(self, chart_code_str: str):
11701172
str_obj = ast.literal_eval(chart_code_str)
11711173
json_str = json.dumps(str_obj)
11721174

1175+
if not isinstance(str_obj, list) or not str_obj:
1176+
return "Failed to generate chart. Please make sure valid chart configuration is provided. Retry."
1177+
11731178
if str_obj[0].get("globalSeriesType") == 'table':
11741179
result_message = {
11751180
'state': 200,
@@ -1182,6 +1187,31 @@ async def run_chart_code(self, chart_code_str: str):
11821187

11831188
}
11841189
else:
1190+
1191+
###################
1192+
axis_x_num = 0
1193+
axis_y_num = 0
1194+
1195+
for config in str_obj:
1196+
if 'columnMapping' in config and isinstance(config['columnMapping'], dict) and config[
1197+
'columnMapping']:
1198+
for variable, axis in config['columnMapping'].items():
1199+
print('axis :', axis)
1200+
if axis in ["x"]:
1201+
axis_x_num = axis_x_num + 1
1202+
elif axis in ["y"]:
1203+
axis_y_num = axis_y_num + 1
1204+
else:
1205+
return "Failed to generate chart. Please make sure valid chart configuration is provided. Try again with the original chart type."
1206+
1207+
if not axis_x_num == 1:
1208+
error_mess = "There should be one and only one X-axis in the chart."
1209+
return error_mess + '\n' + "Failed to generate chart. Please make sure valid chart configuration is provided. Try again with the original chart type."
1210+
elif not axis_y_num > 0:
1211+
error_mess = "There should be at least one Y-axis in the chart."
1212+
return error_mess + '\n' + "Failed to generate chart. Please make sure valid chart configuration is provided. Try again with the original chart type."
1213+
###################
1214+
11851215
result_message = {
11861216
'state': 200,
11871217
'receiver': 'bi',
@@ -1455,9 +1485,11 @@ async def run_echart_code(self, chart_code_str: str, name: str):
14551485
current_timestamp = int(time.time())
14561486
# print(current_timestamp)
14571487

1458-
chart_code_str = chart_code_str.replace("\n", "")
1488+
if base_util.is_json(chart_code_str):
1489+
str_obj = json.loads(chart_code_str)
1490+
else:
1491+
str_obj = ast.literal_eval(chart_code_str)
14591492

1460-
str_obj = ast.literal_eval(chart_code_str)
14611493
json_str = json.dumps(str_obj)
14621494

14631495
result_message = {

ai/agents/agentchat/chart_presenter_agent.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,27 @@ async def generate_reply(
152152
'function_call': {'name': 'bi_run_chart_code',
153153
'arguments': json.dumps(arguments)}}
154154
return suggest_function
155+
else:
156+
# 在这里添加第三种方法的代码,匹配 JSON 大括号,提取相关数据
157+
extracted_json = self.extract_json_data(reply)
158+
159+
# 判断是否提取到了有效的 JSON 数据
160+
if extracted_json and 'globalSeriesType' in extracted_json:
161+
# 提取到有效的数据,构建 JSON 字典
162+
arguments = {"chart_code_str": json.dumps(extracted_json)}
163+
164+
suggest_function = {
165+
'role': 'assistant',
166+
'content': None,
167+
'function_call': {
168+
'name': 'bi_run_chart_code',
169+
'arguments': json.dumps(arguments)
170+
}
171+
}
172+
return suggest_function
155173
except Exception as e:
156174
traceback.print_exc()
175+
157176

158177
return reply
159178
# return suggest_function

ai/agents/agentchat/python_proxy_agent.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,10 +711,16 @@ def generate_code_execution_reply(
711711
exitcode2str = "execution succeeded" if exitcode == 0 else "execution failed"
712712

713713
length = 10000
714+
length1 = 10001
714715
if not str(logs).__contains__('echart_name'):
715716
if len(logs) > length:
716717
print(' ++++++++++ Length exceeds 10000 characters limit, cropped +++++++++++++++++')
717718
logs = logs[:length]
719+
else:
720+
if len(logs) > length1:
721+
print(' ++++++++++ Length exceeds 10001 characters limit, cropped +++++++++++++++++')
722+
logs = "The echarts code is too long, please simplify the code or data (for example, only keep two decimal places), and ensure that the echarts code length does not exceed 10001"
723+
718724

719725
return True, f"exitcode: {exitcode} ({exitcode2str})\nCode output: {logs}"
720726

ai/agents/agentchat/task_selector_agent.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from ai.backend.util.write_log import logger
44
from .conversable_agent import ConversableAgent
55
from .agent import Agent
6-
6+
from ai.backend.base_config import agents_functions
7+
import re
78

89
class TaskSelectorAgent(ConversableAgent):
910
"""(In preview) A class for generic conversable agents which can be configured as assistant or user proxy.
@@ -143,20 +144,23 @@ async def generate_reply(
143144
# {"qustion_message":"\nWhat is the most common house layout in the dataset?"}
144145
# **********************************************
145146
print('messages[-1][content] :', messages[-1]['content'])
146-
147+
147148
# suggest_function = {'role': 'assistant', 'content': None, 'function_call': {'name': 'task_base',
148149
# 'arguments': '{"qustion_message":"\\nWhat is the most common house layout in the dataset?"}'}}
150+
# Check if reply is in agents_functions
151+
if reply in agents_functions:
152+
suggest_function = {'role': 'assistant', 'content': None, 'function_call': {'name': reply,
153+
'arguments': '{"qustion_message":"' + str(
154+
messages[-1][
155+
'content']) + '"}'}}
149156

150-
suggest_function = {'role': 'assistant', 'content': None, 'function_call': {'name': reply,
151-
'arguments': '{"qustion_message":"' + str(
152-
messages[-1][
153-
'content']) + '"}'}}
157+
# {"qustion_message": " """ + str(messages[-1]['content']) + """"}
154158

155-
# {"qustion_message": " """ + str(messages[-1]['content']) + """"}
159+
print('reply : ', reply)
156160

157-
print('reply : ', reply)
161+
# return reply
162+
return suggest_function
158163

159-
# return reply
160-
return suggest_function
164+
161165
# return messages
162166
return self._default_auto_reply

ai/agents/oai/completion.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,7 @@ def _get_response(cls, config: Dict, raise_on_ratelimit_or_timeout=False, use_ca
210210
print('_get_response function +++++++++++++++++++')
211211
# print("config :", config)
212212
# print("config.get('api_base')", config.get('api_base'))
213-
if config.get('api_base') is not None:
214-
# and str(config['api_base']).__contains__('apiserver.deep-thought.io')\
213+
if config.get('api_base') is not None and str(config['api_base']).__contains__('apiserver.deep-thought.io'):
215214

216215
if config.get('functions'):
217216
data = {

0 commit comments

Comments
 (0)