samples updating with AgentScope-Runtime 1.0.0 (#43)
This commit is contained in:
committed by
GitHub
parent
67469f1caa
commit
68450961bb
@@ -1,56 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import functools
|
||||
import os
|
||||
import threading
|
||||
|
||||
from typing import List, Dict, AsyncGenerator
|
||||
|
||||
from openai import OpenAI
|
||||
|
||||
from agentscope.agent import ReActAgent
|
||||
from agentscope.formatter import DashScopeChatFormatter
|
||||
from agentscope.message import TextBlock
|
||||
from agentscope.model import DashScopeChatModel
|
||||
from agentscope_runtime.engine import Runner
|
||||
from agentscope_runtime.engine.agents.agentscope_agent import AgentScopeAgent
|
||||
from agentscope_runtime.engine.schemas.agent_schemas import (
|
||||
AgentRequest,
|
||||
RunStatus,
|
||||
)
|
||||
from agentscope_runtime.engine.services import SandboxService
|
||||
from agentscope_runtime.engine.services.context_manager import ContextManager
|
||||
from agentscope_runtime.engine.services.environment_manager import (
|
||||
EnvironmentManager,
|
||||
)
|
||||
from agentscope_runtime.engine.services.memory_service import (
|
||||
InMemoryMemoryService,
|
||||
)
|
||||
from agentscope_runtime.engine.services.session_history_service import (
|
||||
InMemorySessionHistoryService,
|
||||
)
|
||||
from agentscope_runtime.sandbox.tools.browser import (
|
||||
browser_click,
|
||||
browser_close,
|
||||
browser_console_messages,
|
||||
browser_drag,
|
||||
browser_file_upload,
|
||||
browser_handle_dialog,
|
||||
browser_hover,
|
||||
browser_navigate,
|
||||
browser_navigate_back,
|
||||
browser_navigate_forward,
|
||||
browser_network_requests,
|
||||
browser_pdf_save,
|
||||
browser_press_key,
|
||||
browser_resize,
|
||||
browser_select_option,
|
||||
browser_snapshot,
|
||||
browser_tab_close,
|
||||
browser_tab_list,
|
||||
browser_tab_new,
|
||||
browser_tab_select,
|
||||
browser_take_screenshot,
|
||||
browser_type,
|
||||
browser_wait_for,
|
||||
run_ipython_cell,
|
||||
run_shell_command,
|
||||
)
|
||||
from agentscope.pipeline import stream_printing_messages
|
||||
from agentscope.tool import Toolkit, ToolResponse
|
||||
|
||||
from prompts import SYSTEM_PROMPT
|
||||
|
||||
from agentscope_runtime.adapters.agentscope.memory import (
|
||||
AgentScopeSessionHistoryMemory,
|
||||
)
|
||||
from agentscope_runtime.engine import AgentApp
|
||||
from agentscope_runtime.engine.schemas.agent_schemas import (
|
||||
AgentRequest,
|
||||
)
|
||||
from agentscope_runtime.engine.services.agent_state.state_service import (
|
||||
InMemoryStateService,
|
||||
)
|
||||
from agentscope_runtime.engine.services.sandbox.sandbox_service import (
|
||||
SandboxService,
|
||||
)
|
||||
|
||||
# flake8: noqa: E501
|
||||
from agentscope_runtime.engine.services.session_history.session_history_service import ( # pylint: disable=line-too-long
|
||||
InMemorySessionHistoryService, # pylint: disable=line-too-long
|
||||
)
|
||||
|
||||
|
||||
if os.path.exists(".env"):
|
||||
from dotenv import load_dotenv
|
||||
|
||||
@@ -59,116 +44,162 @@ if os.path.exists(".env"):
|
||||
USER_ID = "user_1"
|
||||
SESSION_ID = "session_001" # Using a fixed ID for simplicity
|
||||
|
||||
PORT = 8090
|
||||
|
||||
class AgentscopeBrowseruseAgent:
|
||||
def __init__(self) -> None:
|
||||
self.tools = [
|
||||
run_shell_command,
|
||||
run_ipython_cell,
|
||||
browser_close,
|
||||
browser_resize,
|
||||
browser_console_messages,
|
||||
browser_handle_dialog,
|
||||
browser_file_upload,
|
||||
browser_press_key,
|
||||
browser_navigate,
|
||||
browser_navigate_back,
|
||||
browser_navigate_forward,
|
||||
browser_network_requests,
|
||||
browser_pdf_save,
|
||||
browser_take_screenshot,
|
||||
browser_snapshot,
|
||||
browser_click,
|
||||
browser_drag,
|
||||
browser_hover,
|
||||
browser_type,
|
||||
browser_select_option,
|
||||
browser_tab_list,
|
||||
browser_tab_new,
|
||||
browser_tab_select,
|
||||
browser_tab_close,
|
||||
browser_wait_for,
|
||||
|
||||
def sandbox_tool_adapter(func):
|
||||
"""
|
||||
Sandbox Tool Adapter.
|
||||
Wraps a sandbox tool function so that its output is always converted
|
||||
into a ToolResponse object, which is required by the Toolkit.
|
||||
This adapter preserves the original function signature and docstring
|
||||
so that JSON schemas can be correctly generated by the Toolkit.
|
||||
Args:
|
||||
func: Original sandbox tool function (may return dict, string, etc.).
|
||||
Returns:
|
||||
A callable that produces ToolResponse instead of raw data.
|
||||
"""
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
res = func(*args, **kwargs)
|
||||
if isinstance(res, ToolResponse):
|
||||
return res
|
||||
# TODO: fix this
|
||||
return ToolResponse(content=[TextBlock(type="text", text=str(res))])
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
desktop_url = ""
|
||||
|
||||
|
||||
def init():
|
||||
agent_app = AgentApp(
|
||||
app_name="Friday",
|
||||
app_description="A helpful assistant",
|
||||
)
|
||||
|
||||
@agent_app.init
|
||||
async def init_func(self):
|
||||
self.state_service = InMemoryStateService()
|
||||
self.session_service = InMemorySessionHistoryService()
|
||||
self.sandbox_service = SandboxService()
|
||||
|
||||
await self.state_service.start()
|
||||
await self.session_service.start()
|
||||
await self.sandbox_service.start()
|
||||
|
||||
@agent_app.shutdown
|
||||
async def shutdown_func(self):
|
||||
await self.state_service.stop()
|
||||
await self.session_service.stop()
|
||||
await self.sandbox_service.stop()
|
||||
|
||||
@agent_app.query(framework="agentscope")
|
||||
async def query_func(
|
||||
self,
|
||||
msgs,
|
||||
request: AgentRequest = None,
|
||||
):
|
||||
session_id = request.session_id
|
||||
user_id = request.user_id
|
||||
|
||||
state = await self.state_service.export_state(
|
||||
session_id=session_id,
|
||||
user_id=user_id,
|
||||
)
|
||||
# Get sandbox
|
||||
sandboxes = self.sandbox_service.connect(
|
||||
session_id=session_id,
|
||||
user_id=user_id,
|
||||
sandbox_types=["browser"],
|
||||
)
|
||||
|
||||
sandbox = sandboxes[0]
|
||||
global desktop_url
|
||||
desktop_url = sandbox.desktop_url
|
||||
|
||||
browser_tools = [
|
||||
sandbox.browser_navigate,
|
||||
sandbox.browser_take_screenshot,
|
||||
sandbox.browser_snapshot,
|
||||
sandbox.browser_click,
|
||||
sandbox.browser_type,
|
||||
]
|
||||
self.agent = AgentScopeAgent(
|
||||
|
||||
toolkit = Toolkit()
|
||||
for tool in browser_tools:
|
||||
toolkit.register_tool_function(sandbox_tool_adapter(tool))
|
||||
|
||||
agent = ReActAgent(
|
||||
name="Friday",
|
||||
model=DashScopeChatModel(
|
||||
"qwen-max",
|
||||
api_key=os.getenv("DASHSCOPE_API_KEY"),
|
||||
enable_thinking=True,
|
||||
stream=True,
|
||||
),
|
||||
agent_config={
|
||||
"sys_prompt": SYSTEM_PROMPT,
|
||||
},
|
||||
tools=self.tools,
|
||||
agent_builder=ReActAgent,
|
||||
sys_prompt=SYSTEM_PROMPT,
|
||||
toolkit=toolkit,
|
||||
memory=AgentScopeSessionHistoryMemory(
|
||||
service=self.session_service,
|
||||
session_id=session_id,
|
||||
user_id=user_id,
|
||||
),
|
||||
formatter=DashScopeChatFormatter(),
|
||||
)
|
||||
|
||||
async def connect(self) -> None:
|
||||
session_history_service = InMemorySessionHistoryService()
|
||||
if state:
|
||||
agent.load_state_dict(state)
|
||||
|
||||
await session_history_service.create_session(
|
||||
user_id=USER_ID,
|
||||
session_id=SESSION_ID,
|
||||
async for msg, last in stream_printing_messages(
|
||||
agents=[agent],
|
||||
coroutine_task=agent(msgs),
|
||||
):
|
||||
yield msg, last
|
||||
|
||||
state = agent.state_dict()
|
||||
|
||||
await self.state_service.save_state(
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
state=state,
|
||||
)
|
||||
|
||||
self.mem_service = InMemoryMemoryService()
|
||||
await self.mem_service.start()
|
||||
self.sandbox_service = SandboxService()
|
||||
await self.sandbox_service.start()
|
||||
def run_agent_app():
|
||||
agent_app.run(host="127.0.0.1", port=PORT)
|
||||
|
||||
self.context_manager = ContextManager(
|
||||
memory_service=self.mem_service,
|
||||
session_history_service=session_history_service,
|
||||
)
|
||||
self.environment_manager = EnvironmentManager(
|
||||
sandbox_service=self.sandbox_service,
|
||||
)
|
||||
sandboxes = self.sandbox_service.connect(
|
||||
session_id=SESSION_ID,
|
||||
user_id=USER_ID,
|
||||
tools=self.tools,
|
||||
)
|
||||
threading.Thread(target=run_agent_app, daemon=True).start()
|
||||
return agent_app
|
||||
|
||||
if len(sandboxes) > 0:
|
||||
sandbox = sandboxes[0]
|
||||
self.desktop_url = sandbox.desktop_url
|
||||
else:
|
||||
self.desktop_url = ""
|
||||
|
||||
runner = Runner(
|
||||
agent=self.agent,
|
||||
context_manager=self.context_manager,
|
||||
environment_manager=self.environment_manager,
|
||||
)
|
||||
self.runner = runner
|
||||
class AgentscopeBrowseruseAgent:
|
||||
def __init__(self) -> None:
|
||||
self.agent = init()
|
||||
self.desktop_url = ""
|
||||
|
||||
async def chat(
|
||||
self,
|
||||
chat_messages: List[Dict],
|
||||
) -> AsyncGenerator[Dict, None]:
|
||||
convert_messages = []
|
||||
for chat_message in chat_messages:
|
||||
convert_messages.append(
|
||||
{
|
||||
"role": chat_message["role"],
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": chat_message["content"],
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
||||
request = AgentRequest(input=convert_messages, session_id=SESSION_ID)
|
||||
request.tools = []
|
||||
async for message in self.runner.stream_query(
|
||||
user_id=USER_ID,
|
||||
request=request,
|
||||
):
|
||||
if (
|
||||
message.object == "message"
|
||||
and RunStatus.Completed == message.status
|
||||
):
|
||||
yield message.content
|
||||
client = OpenAI(base_url=f"http://127.0.0.1:{PORT}/compatible-mode/v1")
|
||||
|
||||
stream = client.responses.create(
|
||||
model="any_name",
|
||||
input=chat_messages[-1]["content"],
|
||||
stream=True,
|
||||
)
|
||||
global desktop_url
|
||||
|
||||
self.desktop_url = desktop_url
|
||||
for chunk in stream:
|
||||
if hasattr(chunk, "delta"):
|
||||
yield chunk.delta
|
||||
else:
|
||||
yield {}
|
||||
# if chunk.choices[0].delta.content is not None:
|
||||
# yield chunk.choices[0].delta.content
|
||||
|
||||
async def close(self) -> None:
|
||||
await self.sandbox_service.stop()
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
|
||||
from quart import Quart, Response, jsonify, request
|
||||
from quart_cors import cors
|
||||
|
||||
from agentscope_browseruse_agent import AgentscopeBrowseruseAgent
|
||||
from agentscope_runtime.engine.schemas.agent_schemas import (
|
||||
DataContent,
|
||||
TextContent,
|
||||
)
|
||||
from quart import Quart, Response, jsonify, request
|
||||
from quart_cors import cors
|
||||
|
||||
|
||||
app = Quart(__name__)
|
||||
app = cors(app, allow_origin="*")
|
||||
@@ -35,9 +36,8 @@ if os.path.exists(".env"):
|
||||
async def user_mode(input_data):
|
||||
messages = input_data.get("messages", [])
|
||||
last_name = ""
|
||||
async for item_list in agent.chat(messages):
|
||||
if item_list:
|
||||
item = item_list[0]
|
||||
async for item in agent.chat(messages):
|
||||
if item:
|
||||
res = ""
|
||||
if isinstance(item, TextContent):
|
||||
res = item.text
|
||||
@@ -48,8 +48,9 @@ async def user_mode(input_data):
|
||||
continue
|
||||
res = "I will use the tool" + json.dumps(item.data["name"])
|
||||
last_name = json.dumps(item.data["name"])
|
||||
|
||||
yield simple_yield(res + "\n")
|
||||
elif isinstance(item, str):
|
||||
res = item
|
||||
yield simple_yield(res)
|
||||
else:
|
||||
yield simple_yield()
|
||||
|
||||
@@ -105,5 +106,5 @@ async def get_env_info():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(agent.connect())
|
||||
agent.chat([{"role": "user", "content": "hello"}])
|
||||
app.run(host="0.0.0.0", port=9000)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
pyyaml>=6.0.2
|
||||
quart>=0.8.0
|
||||
quart-cors>=0.8.0
|
||||
agentscope-runtime==0.2.0
|
||||
agentscope-runtime>=1.0.0
|
||||
agentscope[full]>=1.0.5
|
||||
openai>=2.8.1
|
||||
Reference in New Issue
Block a user