Skip to content

Commit

Permalink
Merge pull request #138 from alipay/dev
Browse files Browse the repository at this point in the history
 feat: Version 0.0.12 Release
  • Loading branch information
LandJerry authored Aug 14, 2024
2 parents cf15bea + 11efe76 commit c5c3af5
Show file tree
Hide file tree
Showing 123 changed files with 2,559 additions and 90 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ Note - Additional remarks regarding the version.
***************************************************

# Version Update History
## [0.0.12] - 2024-08-14
### Added
- agentUniverse Product Version Offering
- The current version provides basic capabilities for agent construction, modification, and debugging, jointly launched by the difizen project. For more details, please refer to the documentation in the product platform section.
- Monitor Component: Added knowledge and tool instance collection, supporting full-link trace sequence concatenation and providing token consumption monitoring.
- New Web Session Module: Provides session and message persistence management capabilities.

### Note
- Optimized Knowledge Component: Users can configure and specify any number of recall results (similarity_top_k).
- Fixed Chroma Component: Resolved issues where the embedding module was not specified.
- Various code optimizations and documentation updates.

## [0.0.11] - 2024-07-11
### Added
- DataAgent Autonomous Data Agent MVP Version Released
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ Note - 对于版本的额外说明。
***************************************************

# 版本更新记录
## [0.0.12] - 2024-08-14
### Added
- agentUniverse产品化版本提供
- 当前版本提供智能体构建、修改、调试等基础能力,由difizen项目联合推出,更多详情请见文档产品化平台部分。
- monitor组件新增对于知识、工具实例采集,支持全链路trace时序串联并提供token消耗监控
- 新增web会话模块,提供session与message持久化管理能力

### Note
- 优化知识组件,可由用户配置指定任意召回结果数量(similarity_top_k)
- 修复chroma组件未指定embedding模块出现异常
- 其他部分代码优化与文档更新

## [0.0.11] - 2024-07-11
### Added
- DataAgent数据自治智能体MVP版本发布
Expand Down
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Language version: [English](./README.md) | [中文](./README_zh.md) | [日本語
![](https://img.shields.io/badge/framework-agentUniverse-pink)
![](https://img.shields.io/badge/python-3.10%2B-blue?logo=Python)
[![](https://img.shields.io/badge/%20license-Apache--2.0-yellow)](LICENSE)
[![Static Badge](https://img.shields.io/badge/pypi-v0.0.11-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)
[![Static Badge](https://img.shields.io/badge/pypi-v0.0.12-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)

![](docs/guidebook/_picture/logo_bar.jpg)
****************************************
Expand Down Expand Up @@ -55,6 +55,24 @@ We will show you how to:
For more details, please read the [Quick Start](./docs/guidebook/en/1_3_Quick_Start.md).

****************************************
## Using the Product Platform
agentUniverse provides a local product platform capability. Please follow the steps below for a quick start:

**Install via pip**
```shell
pip install magent-ui ruamel.yaml
```

**One-click Run**

Run the [product_application.py](sample_standard_app/app/bootstrap/product_application.py) file located in sample_standard_app/app/bootstrap for a one-click start.

For more details, refer to [Quick Start for Product Platform](./docs/guidebook/en/10_1_1_Product%20Platform%20Quick%20Start.md).

This feature is jointly launched by [difizen](https://github.com/difizen/magent) and agentUniverse.

****************************************

## Cases and Example Projects
### 🌟 Use Cases
[Legal Consultation Agent](./docs/guidebook/en/7_1_1_Legal_Consultation_Case.md)
Expand Down
19 changes: 18 additions & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
![](https://img.shields.io/badge/framework-agentUniverse-pink)
![](https://img.shields.io/badge/python-3.10%2B-blue?logo=Python)
[![](https://img.shields.io/badge/%20license-Apache--2.0-yellow)](LICENSE)
[![Static Badge](https://img.shields.io/badge/pypi-v0.0.11-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)
[![Static Badge](https://img.shields.io/badge/pypi-v0.0.12-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)

![](docs/guidebook/_picture/logo_bar.jpg)
****************************************
Expand Down Expand Up @@ -51,6 +51,23 @@ pip install agentUniverse
* 对agent进行快速服务化

详情请阅读[快速开始](docs/guidebook/zh/1_3_%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.md)
****************************************
## 产品化平台使用
agentUniverse提供基于本地的产品化平台能力,请按照如下步骤快速启动

**通过pip安装**
```shell
pip install magent-ui ruamel.yaml
```

**一键运行**

运行sample_standard_app/app/boostrap下的[product_application.py](sample_standard_app/app/bootstrap/product_application.py)文件,一键启动。

更多详情参考 [产品化平台快速开始](./docs/guidebook/zh/10_1_1_产品化平台快速开始.md)

本功能由 [difizen](https://github.com/difizen/magent) X agentUniverse联合推出。

****************************************
## 案例与样例工程
### 🌟 使用案例
Expand Down
2 changes: 2 additions & 0 deletions agentuniverse/agent/action/knowledge/knowledge.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from agentuniverse.agent.action.knowledge.store.document import Document
from agentuniverse.agent.action.knowledge.store.query import Query
from agentuniverse.agent.action.knowledge.store.store import Store
from agentuniverse.base.annotation.trace import trace_knowledge
from agentuniverse.base.component.component_base import ComponentBase
from agentuniverse.base.component.component_enum import ComponentEnum
from agentuniverse.base.config.application_configer.application_config_manager import ApplicationConfigManager
Expand Down Expand Up @@ -53,6 +54,7 @@ def insert_knowledge(self, **kwargs) -> None:
document_list: List[Document] = self.reader.load_data()
self.store.insert_documents(document_list, **kwargs)

@trace_knowledge
def query_knowledge(self, **kwargs) -> List[Document]:
"""Query the knowledge.
Expand Down
2 changes: 1 addition & 1 deletion agentuniverse/agent/action/knowledge/store/chroma_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def insert_documents(self, documents: List[Document], **kwargs: Any):
self.collection.add(
documents=[document.text],
metadatas=[document.metadata],
embeddings=[embedding] if embedding is not None else None,
embeddings=[embedding] if len(embedding) > 0 else None,
ids=[document.id]
)

Expand Down
3 changes: 3 additions & 0 deletions agentuniverse/agent/action/tool/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from langchain.tools import Tool as LangchainTool

from agentuniverse.agent.action.tool.enum import ToolTypeEnum
from agentuniverse.base.annotation.trace import trace_tool
from agentuniverse.base.component.component_base import ComponentBase
from agentuniverse.base.component.component_enum import ComponentEnum
from agentuniverse.base.config.application_configer.application_config_manager import ApplicationConfigManager
Expand Down Expand Up @@ -61,6 +62,7 @@ class Tool(ComponentBase):
def __init__(self, **kwargs):
super().__init__(component_type=ComponentEnum.TOOL, **kwargs)

@trace_tool
def run(self, **kwargs):
"""The callable method that runs the tool."""
self.input_check(kwargs)
Expand All @@ -73,6 +75,7 @@ def input_check(self, kwargs: dict) -> None:
if key not in kwargs.keys():
raise Exception(f'{self.get_instance_code()} - The input must include key: {key}.')

@trace_tool
def langchain_run(self, *args, callbacks=None, **kwargs):
"""The callable method that runs the tool."""
kwargs["callbacks"] = callbacks
Expand Down
39 changes: 36 additions & 3 deletions agentuniverse/agent/default/executing_agent/executing_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@
# @Email : lc299034@antgroup.com
# @FileName: executing_agent.py
"""Executing Agent module."""
import copy
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED
from typing import Optional, Any

from agentuniverse.agent.action.tool.tool_manager import ToolManager
from agentuniverse.agent.agent import Agent
from agentuniverse.agent.agent_model import AgentModel
from agentuniverse.agent.input_object import InputObject
from agentuniverse.agent.plan.planner.planner import Planner
from agentuniverse.agent.plan.planner.planner_manager import PlannerManager
from agentuniverse.base.context.framework_context_manager import FrameworkContextManager


class ExecutingAgent(Agent):
"""Executing Agent class."""

executor: Optional[Any] = ThreadPoolExecutor(max_workers=10, thread_name_prefix="executing_agent")
_context_values: Optional[dict] = {}

def input_keys(self) -> list[str]:
"""Return the input keys of the Agent."""
Expand Down Expand Up @@ -54,12 +56,16 @@ def parse_result(self, planner_result: dict) -> dict:
llm_result = []
executing_result = []
futures = planner_result.get('futures')
index = 1
# assemble results of the execution process.
for future in futures:
task_result = future.result()
llm_result.append(task_result)
executing_result.append({
'input': task_result['input'], 'output': task_result['output']
'input': f"Question {index}: " + task_result.get('input', ''),
'output': f"Answer {index}: " + task_result.get('output', '')
})
index += 1

return {'executing_result': executing_result, 'llm_result': llm_result}

Expand All @@ -73,6 +79,7 @@ def execute(self, input_object: InputObject, agent_input: dict) -> dict:
Returns:
dict: Agent result object.
"""
self._context_values: dict = FrameworkContextManager().get_all_contexts()
framework = agent_input.get('framework', [])
futures = []
for task in framework:
Expand All @@ -81,11 +88,37 @@ def execute(self, input_object: InputObject, agent_input: dict) -> dict:
agent_input_copy['input'] = task
planner: Planner = PlannerManager().get_instance_obj(self.agent_model.plan.get('planner').get('name'))
futures.append(
self.executor.submit(planner.invoke, self.agent_model, agent_input_copy,
self.executor.submit(self.run_in_executor, planner, self.agent_model, agent_input_copy,
self.process_intput_object(input_object, task, planner.input_key)))
wait(futures, return_when=ALL_COMPLETED)
return {'futures': futures}

def run_in_executor(self, planner: Planner, agent_model: AgentModel, planner_input: dict,
input_object: InputObject) -> dict:
"""The execution function of the thread pool.
Args:
planner(Planner): The planner object.
agent_model (AgentModel): The agent model object.
planner_input (dict): The planner input dict.
input_object (InputObject): The input parameters passed by the user.
Returns:
dict: The planner execution result.
"""
context_tokens = {}
try:
# pass the framework context into the thread.
for var_name, var_value in self._context_values.items():
token = FrameworkContextManager().set_context(var_name, var_value)
context_tokens[var_name] = token
# invoke planner
res = planner.invoke(agent_model, planner_input, input_object)
return res
finally:
# clear the framework context.
for var_name, token in context_tokens.items():
FrameworkContextManager().reset_context(var_name, token)

def process_intput_object(self, input_object: InputObject, subtask: str, planner_input_key: str) -> InputObject:
"""Process input object for the executing agent.
Expand Down
2 changes: 1 addition & 1 deletion agentuniverse/agent/memory/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Message(BaseModel):
"""

type: Optional[str] = None
content: Union[str, List[Union[str, Dict]]] = None
content: Optional[Union[str, List[Union[str, Dict]]]] = None

def as_langchain(self):
"""Convert the agentUniverse(aU) message class to the langchain message class."""
Expand Down
55 changes: 36 additions & 19 deletions agentuniverse/agent/plan/planner/peer_planner/peer_planner.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# @FileName: peer_planner.py
"""Peer planner module."""
from agentuniverse.agent.action.tool.tool_manager import ToolManager
from agentuniverse.agent.agent import Agent
from agentuniverse.agent.agent_manager import AgentManager
from agentuniverse.agent.agent_model import AgentModel
from agentuniverse.agent.input_object import InputObject
Expand Down Expand Up @@ -42,7 +43,7 @@ def invoke(self, agent_model: AgentModel, planner_input: dict, input_object: Inp
"""
planner_config = agent_model.plan.get('planner')
sub_agents = self.generate_sub_agents(planner_config)
return self.agents_run(agent_model, sub_agents, planner_config, planner_input, input_object)
return self.agents_run(sub_agents, planner_config, planner_input, input_object)

@staticmethod
def generate_sub_agents(planner_config: dict) -> dict:
Expand Down Expand Up @@ -79,7 +80,7 @@ def build_expert_framework(planner_config: dict, input_object: InputObject):
elif context:
input_object.add_data('expert_framework', context)

def agents_run(self, agent_mode: AgentModel, agents: dict, planner_config: dict, agent_input: dict,
def agents_run(self, agents: dict, planner_config: dict, agent_input: dict,
input_object: InputObject) -> dict:
"""Planner agents run.
Expand All @@ -105,10 +106,10 @@ def agents_run(self, agent_mode: AgentModel, agents: dict, planner_config: dict,

self.build_expert_framework(planner_config, input_object)

planningAgent = agents.get('planning')
executingAgent = agents.get('executing')
expressingAgent = agents.get('expressing')
reviewingAgent = agents.get('reviewing')
planningAgent: Agent = agents.get('planning')
executingAgent: Agent = agents.get('executing')
expressingAgent: Agent = agents.get('expressing')
reviewingAgent: Agent = agents.get('reviewing')

for _ in range(retry_count):
LOGGER.info(f"Starting peer agents, retry_count is {_ + 1}.")
Expand All @@ -126,10 +127,13 @@ def agents_run(self, agent_mode: AgentModel, agents: dict, planner_config: dict,
for index, one_framework in enumerate(planning_result.get_data('framework')):
logger_info += f"[{index + 1}] {one_framework} \n"
LOGGER.info(logger_info)
self.stream_output(input_object, {"data": {
'output': planning_result.to_dict(),
"agent_info": agent_mode.info
}, "type": "planning"})

# add planning agent intermediate steps
if planningAgent:
self.stream_output(input_object, {"data": {
'output': planning_result.get_data('framework'),
"agent_info": planningAgent.agent_model.info
}, "type": "planning"})

if not executing_result or jump_step in ["planning", "executing"]:
if not executingAgent:
Expand All @@ -148,10 +152,13 @@ def agents_run(self, agent_mode: AgentModel, agents: dict, planner_config: dict,
one_exec_log_info += f"[{index + 1}] output: {one_exec_res['output']}\n"
logger_info += one_exec_log_info
LOGGER.info(logger_info)
self.stream_output(input_object, {"data": {
'output': executing_result.to_dict(),
"agent_info": agent_mode.info
}, "type": "executing"})

# add executing agent intermediate steps
if executingAgent:
self.stream_output(input_object, {"data": {
'output': executing_result.get_data('executing_result'),
"agent_info": executingAgent.agent_model.info
}, "type": "executing"})

if not expressing_result or jump_step in ["planning", "executing", "expressing"]:
if not expressingAgent:
Expand All @@ -166,10 +173,13 @@ def agents_run(self, agent_mode: AgentModel, agents: dict, planner_config: dict,
logger_info = f"\nExpressing agent execution result is :\n"
logger_info += f"{expressing_result.get_data('output')}"
LOGGER.info(logger_info)
self.stream_output(input_object, {"data": {
'output': expressing_result.get_data('output'),
"agent_info": agent_mode.info
}, "type": "expressing"})

# add expressing agent intermediate steps
if expressingAgent:
self.stream_output(input_object, {"data": {
'output': expressing_result.get_data('output'),
"agent_info": expressingAgent.agent_model.info
}, "type": "expressing"})

if not reviewing_result or jump_step in ["planning", "executing", "expressing", "reviewing"]:
if not reviewingAgent:
Expand All @@ -193,7 +203,14 @@ def agents_run(self, agent_mode: AgentModel, agents: dict, planner_config: dict,
reviewing_info_str = f"review suggestion: {reviewing_result.get_data('suggestion')} \n"
reviewing_info_str += f"review score: {reviewing_result.get_data('score')} \n"
LOGGER.info(logger_info + reviewing_info_str)
self.stream_output(input_object, {"data": reviewing_result.to_dict(), "type": "reviewing"})

# add reviewing agent intermediate steps
self.stream_output(input_object,
{"data": {
'output': reviewing_result.get_data('suggestion'),
"agent_info": reviewingAgent.agent_model.info
}, "type": "reviewing"})

if reviewing_result.get_data('score') and reviewing_result.get_data('score') >= eval_threshold:
loopResults.append({
"planning_result": planning_result,
Expand Down
Loading

0 comments on commit c5c3af5

Please sign in to comment.