Skip to content

Commit

Permalink
Feat/tool service with git (#500)
Browse files Browse the repository at this point in the history
  • Loading branch information
zzhangpurdue authored Jun 24, 2024
1 parent 7cdbb74 commit 15521d1
Show file tree
Hide file tree
Showing 36 changed files with 431 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .dev_scripts/dockerci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pip install playwright
playwright install --with-deps chromium

# install package
pip install fastapi pydantic uvicorn docker sqlmodel
pip install fastapi pydantic uvicorn docker sqlmodel transformers ray

# run ci
pytest tests
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ MANIFEST
*.manifest
*.spec
release.sh
build.sh
*.html

# Installer logs
Expand Down
27 changes: 20 additions & 7 deletions apps/agentfabric/appBot.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import modelscope_studio as mgr
from config_utils import get_avatar_image, get_ci_dir, parse_configuration
from gradio_utils import format_cover_html
from modelscope_agent.constants import ApiNames
from modelscope_agent.schemas import Message
from modelscope_agent.utils.logger import agent_logger as logger
from modelscope_studio.components.Chatbot.llm_thinking_presets import qwen
Expand Down Expand Up @@ -42,10 +43,13 @@ def check_uuid(uuid_str):
return uuid_str


def init_user(state):
def init_user(state, _user_token=None):
try:
in_ms_studio = os.getenv('MODELSCOPE_ENVIRONMENT', 'None') == 'studio'
seed = state.get('session_seed', random.randint(0, 1000000000))
user_agent, user_memory = init_user_chatbot_agent(uuid_str)
# use tool api in ms studio
user_agent, user_memory = init_user_chatbot_agent(
uuid_str, use_tool_api=in_ms_studio, user_token=_user_token)
user_agent.seed = seed
state['user_agent'] = user_agent
state['user_memory'] = user_memory
Expand All @@ -72,6 +76,7 @@ def delete(state):
# 创建 Gradio 界面
demo = gr.Blocks(css='assets/appBot.css', theme=customTheme)
with demo:
user_token = gr.Textbox(label='modelscope_agent_tool_token', visible=False)
gr.Markdown(
'# <center class="agent_title"> \N{fire} AgentFabric powered by Modelscope-agent [github star](https://github.com/modelscope/modelscope-agent/tree/main)</center>' # noqa E501
)
Expand Down Expand Up @@ -111,10 +116,16 @@ def delete(state):
examples=suggests,
inputs=[user_chatbot_input])

def send_message(chatbot, input, _state):
def send_message(chatbot, input, _state, _user_token):
# 将发送的消息添加到聊天历史
if 'user_agent' not in _state:
init_user(_state)
init_user(_state, _user_token)

kwargs = {
name.lower(): os.getenv(value.value)
for name, value in ApiNames.__members__.items()
}

# 将发送的消息添加到聊天历史
_uuid_str = check_uuid(uuid_str)
user_agent = _state['user_agent']
Expand Down Expand Up @@ -149,7 +160,9 @@ def send_message(chatbot, input, _state):
input.text,
history=history,
ref_doc=ref_doc,
append_files=append_files):
append_files=append_files,
user_token=_user_token,
**kwargs):

# important! do not change this
response += frame
Expand Down Expand Up @@ -178,10 +191,10 @@ def send_message(chatbot, input, _state):

gr.on([user_chatbot_input.submit],
fn=send_message,
inputs=[user_chatbot, user_chatbot_input, state],
inputs=[user_chatbot, user_chatbot_input, state, user_token],
outputs=[user_chatbot, user_chatbot_input])

demo.load(init_user, inputs=[state], outputs=[state])
demo.load(init_user, inputs=[state, user_token], outputs=[state])

demo.queue()
demo.launch(show_error=True, max_threads=10)
7 changes: 6 additions & 1 deletion apps/agentfabric/config_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,14 @@ def parse_configuration(uuid_str=''):
tools_info = builder_cfg.tools
available_tool_list = []
for key, value in tools_info.items():
if key in tool_cfg:
tool_cfg[key]['use'] = value['use']
else:
# for tool hub only
if '/' in key:
tool_cfg[key] = value
if value['use']:
available_tool_list.append(key)
tool_cfg[key]['use'] = value['use']

openapi_plugin_file = get_user_openapi_plugin_cfg_file(uuid_str)
plugin_cfg = {}
Expand Down
2 changes: 1 addition & 1 deletion apps/agentfabric/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
dashscope
faiss-cpu
gradio==4.36.1
https://modelscope-agent.oss-cn-hangzhou.aliyuncs.com/releases/v0.6.2/modelscope_agent-0.6.2-py3-none-any.whl
langchain
markdown-cjk-spacing
mdx_truly_sane_lists
modelscope-agent==0.4.1
modelscope_studio
pymdown-extensions
python-slugify
Expand Down
60 changes: 46 additions & 14 deletions apps/agentfabric/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
is_valid_plugin_configuration, parse_configuration,
save_builder_configuration,
save_plugin_configuration)
from flask import (Flask, Response, jsonify, make_response, request,
from flask import (Flask, Response, g, jsonify, make_response, request,
send_from_directory)
from modelscope_agent.constants import (MODELSCOPE_AGENT_TOKEN_HEADER_NAME,
ApiNames)
from modelscope_agent.schemas import Message
from publish_util import (pop_user_info_from_config, prepare_agent_zip,
reload_agent_dir)
Expand All @@ -29,6 +31,28 @@
app.session_manager = SessionManager()


def get_auth_token():
auth_header = request.headers.get('Authorization')
if auth_header and auth_header.startswith('Bearer '):
return auth_header[7:] # Slice off the 'Bearer ' prefix
return None


def get_modelscope_agent_token():
token = None
# Check if authorization header is present
if MODELSCOPE_AGENT_TOKEN_HEADER_NAME in request.headers:
auth_header = request.headers[MODELSCOPE_AGENT_TOKEN_HEADER_NAME]
# Check if the value of the header starts with 'Bearer'
if auth_header.startswith('Bearer '):
# Extract the token part from 'Bearer token_value'
token = auth_header[7:]
else:
# Extract the token part from auth_header
token = auth_header
return token


@app.before_request
def set_request_id():
request_id = request.headers.get('X-Modelscope-Request-Id', 'unknown')
Expand Down Expand Up @@ -94,8 +118,6 @@ def generate():
llm_result = frame.get('llm_text', '')
exec_result = frame.get('exec_result', '')
step_result = frame.get('step', '')
logger.info('frame, {}'.format(
str(frame).replace('\n', '\\n')))
if len(exec_result) != 0:
if isinstance(exec_result, dict):
exec_result = exec_result['result']
Expand Down Expand Up @@ -285,14 +307,6 @@ def save_builder_config(uuid_str):
builder_config_str = request.form.get('builder_config')
logger.info(f'builder_config: {builder_config_str}')
builder_config = json.loads(builder_config_str)
if 'tools' in builder_config:
if 'code_interpreter' in builder_config['tools']:
return jsonify({
'success': False,
'status': 404,
'message': 'Using code_interpreter.',
'request_id': request_id_var.get('')
}), 404
if 'knowledge' in builder_config:
builder_config['knowledge'] = [
os.path.join(get_user_dir(uuid_str), os.path.basename(k))
Expand Down Expand Up @@ -367,6 +381,11 @@ def preview_publish_get_zip(uuid_str):
@app.route('/preview/chat/<uuid_str>/<session_str>', methods=['POST'])
@with_request_id
def preview_chat(uuid_str, session_str):
user_token = get_modelscope_agent_token()
if not user_token:
# If token is not found, return 401 Unauthorized response
return jsonify({'message': 'Token is missing!'}), 401

logger.info(f'preview_chat: uuid_str_{uuid_str}_session_str_{session_str}')

params_str = request.form.get('params')
Expand All @@ -383,13 +402,18 @@ def preview_chat(uuid_str, session_str):
file.save(file_path)
file_paths.append(file_path)
logger.info(f'/preview/chat/{uuid_str}/{session_str}: files: {file_paths}')
# Generating the kwargs dictionary
kwargs = {
name.lower(): os.getenv(value.value)
for name, value in ApiNames.__members__.items()
}

def generate():
try:
start_time = time.time()
seed = random.randint(0, 1000000000)
user_agent, user_memory = app.session_manager.get_user_bot(
uuid_str, session_str)
uuid_str, session_str, user_token=user_token)
user_agent.seed = seed
logger.info(
f'get method: time consumed {time.time() - start_time}')
Expand Down Expand Up @@ -422,12 +446,15 @@ def generate():
'request_id': request_id_var.get('')
},
ensure_ascii=False)

for frame in user_agent.run(
input_content,
history=history,
ref_doc=ref_doc,
append_files=file_paths,
uuid_str=uuid_str):
uuid_str=uuid_str,
user_token=user_token,
**kwargs):
logger.info('frame, {}'.format(
str(frame).replace('\n', '\\n')))
# important! do not change this
Expand Down Expand Up @@ -486,8 +513,13 @@ def get_preview_chat_history(uuid_str, session_str):
logger.info(
f'get_preview_chat_history: uuid_str_{uuid_str}_session_str_{session_str}'
)
user_token = get_modelscope_agent_token()
if not user_token:
# If token is not found, return 401 Unauthorized response
return jsonify({'message': 'Token is missing!'}), 401

_, user_memory = app.session_manager.get_user_bot(uuid_str, session_str)
_, user_memory = app.session_manager.get_user_bot(
uuid_str, session_str, user_token=user_token)
return jsonify({
'history': user_memory.get_history(),
'success': True,
Expand Down
22 changes: 5 additions & 17 deletions apps/agentfabric/server_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,29 +137,17 @@ def get_user_bot(
self,
builder_id,
session,
renew=False) -> Tuple[RolePlay, MemoryWithRetrievalKnowledge]:
renew=False,
user_token=None) -> Tuple[RolePlay, MemoryWithRetrievalKnowledge]:
unique_id = builder_id + '_' + session
user_agent = self.user_bots[unique_id]
if renew or user_agent is None:
logger.info(f'init_user_chatbot_agent: {builder_id} {session}')

# check code_interpreter
builder_cfg, _, tool_cfg, _, _, _ = parse_configuration(builder_id)
if 'tools' in builder_cfg and 'code_interpreter' in builder_cfg[
'tools']:
if builder_cfg['tools']['code_interpreter'].get(
'is_active', False
) and builder_cfg['tools']['code_interpreter'].get(
'use', False):
raise ValueError('Using code interpreter.')
if 'code_interpreter' in tool_cfg:
if tool_cfg['code_interpreter'].get(
'is_active',
False) and tool_cfg['code_interpreter'].get(
'use', False):
raise ValueError('Using code interpreter.')

user_agent = init_user_chatbot_agent(builder_id, session)

user_agent = init_user_chatbot_agent(
builder_id, session, use_tool_api=True, user_token=user_token)
self.user_bots[unique_id] = user_agent
return user_agent

Expand Down
23 changes: 15 additions & 8 deletions apps/agentfabric/user_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@


# init user chatbot_agent
def init_user_chatbot_agent(uuid_str='', session='default'):
def init_user_chatbot_agent(uuid_str='',
session='default',
use_tool_api=False,
user_token=None):
builder_cfg, model_cfg, tool_cfg, _, plugin_cfg, _ = parse_configuration(
uuid_str)
# set top_p and stop_words for role play
Expand All @@ -21,17 +24,18 @@ def init_user_chatbot_agent(uuid_str='', session='default'):
model_cfg[builder_cfg.model]['generate_cfg']['top_p'] = 0.5
model_cfg[builder_cfg.model]['generate_cfg']['stop'] = 'Observation'

# build model
logger.query_info(
uuid=uuid_str,
message=f'using model {builder_cfg.model}',
details={'model_config': model_cfg[builder_cfg.model]})

# update function_list
function_list = parse_tool_cfg(tool_cfg)
function_list = add_openapi_plugin_to_additional_tool(
plugin_cfg, function_list)

# build model
logger.query_info(
uuid=uuid_str,
message=
f'using model {builder_cfg.model} with tool {tool_cfg} and function list {function_list}',
details={'model_config': model_cfg[builder_cfg.model]})

llm_config = copy.deepcopy(model_cfg[builder_cfg.model])
llm_config['model_server'] = llm_config.pop('type')
instruction = {
Expand All @@ -43,7 +47,10 @@ def init_user_chatbot_agent(uuid_str='', session='default'):
function_list=function_list,
llm=llm_config,
instruction=instruction,
uuid_str=uuid_str)
uuid_str=uuid_str,
use_tool_api=use_tool_api,
user_token=user_token,
)

# build memory
preview_history_dir = get_user_preview_history_dir(uuid_str, session)
Expand Down
2 changes: 1 addition & 1 deletion apps/agentfabric/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.2.1rc0'
__version__ = '0.3.0rc0'
4 changes: 0 additions & 4 deletions build.sh

This file was deleted.

4 changes: 3 additions & 1 deletion docker/tool_node.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ ENV BASE_TOOL_DIR /app/assets
# install tool_node
COPY modelscope_agent_servers /app/modelscope_agent_servers


# start up script file
COPY scripts/run_tool_node.sh /app/run_tool_node.sh
RUN chmod +x /app/run_tool_node.sh
#ENTRYPOINT exec uvicorn tool_service.tool_node.api:app --host 0.0.0.0 --port $PORT


Expand Down
Loading

0 comments on commit 15521d1

Please sign in to comment.