Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Unlike many agent frameworks that only track the chat history with LLMs in text,


## 🆕 News
- 📅2025-01-16: TaskWeaver has been enhanced with an experimental role called [Recepta](https://microsoft.github.io/TaskWeaver/blog/reasoning) for its reasoning power.🧠
- 📅2024-12-23: TaskWeaver has been integrated with the [AgentOps](https://microsoft.github.io/TaskWeaver/docs/observability) for better observability and monitoring.🔍
- 📅2024-09-13: We introduce the shared memory to store information that is shared between the roles in TaskWeaver. Please check the [memory](https://microsoft.github.io/TaskWeaver/docs/memory) for more details.🧠
- 📅2024-09-13: We have enhanced the experience feature by allowing static and dynamic experience selection. Please check the [experience](https://microsoft.github.io/TaskWeaver/blog/experience) for more details.📚
Expand All @@ -31,7 +32,7 @@ Unlike many agent frameworks that only track the chat history with LLMs in text,
- 📅2024-03-28: TaskWeaver now offers all-in-one Docker image, providing a convenient one-stop experience for users. Please check the [docker](https://microsoft.github.io/TaskWeaver/docs/usage/docker) for more details.🐳
- 📅2024-03-27: TaskWeaver now switches to `container` mode by default for code execution. Please check the [code execution](https://microsoft.github.io/TaskWeaver/docs/code_execution) for more details.🐳
- 📅2024-03-07: TaskWeaver now supports configuration of different LLMs for various components, such as the Planner and CodeInterpreter. Please check the [multi-llm](https://microsoft.github.io/TaskWeaver/docs/llms/multi-llm) for more details.🔗
- 📅2024-03-04: TaskWeaver now supports a [container](https://microsoft.github.io/TaskWeaver/docs/code_execution) mode, which provides a more secure environment for code execution.🐳
<!-- - 📅2024-03-04: TaskWeaver now supports a [container](https://microsoft.github.io/TaskWeaver/docs/code_execution) mode, which provides a more secure environment for code execution.🐳 -->
<!-- - 📅2024-02-28: TaskWeaver now offers a [CLI-only](https://microsoft.github.io/TaskWeaver/docs/advanced/cli_only) mode, enabling users to interact seamlessly with the Command Line Interface (CLI) using natural language.📟 -->
<!-- - 📅2024-02-01: TaskWeaver now has a plugin [document_retriever](https://github.com/microsoft/TaskWeaver/blob/main/project/plugins/README.md#document_retriever) for RAG based on a knowledge base.📚 -->
<!-- - 📅2024-01-30: TaskWeaver introduces a new plugin-only mode that securely generates calls to specified plugins without producing extraneous code.🪡 -->
Expand All @@ -54,7 +55,7 @@ Unlike many agent frameworks that only track the chat history with LLMs in text,
- [x] **Code verification** - TaskWeaver is designed to verify the generated code before execution. It can detect potential issues in the generated code and provide suggestions to fix them.
- [x] **Easy to use** - TaskWeaver is easy to use with sample plugins, examples and tutorials to help you get started. TaskWeaver offers an open-box experience, allowing users to run it immediately after installation.
- [x] **Easy to debug** - TaskWeaver is easy to debug with detailed and transparent logs to help you understand the entire process, including LLM prompts, the code generation, and execution process.
- [x] **Security consideration** - TaskWeaver supports a basic session management to keep different users' data separate. The code execution is separated into different processes to avoid mutal interference.
- [x] **Security consideration** - TaskWeaver supports a basic session management to keep different users' data separate. The code execution is separated into different processes to avoid mutual interference.
- [x] **Easy extension** - TaskWeaver is easy to extend to accomplish more complex tasks with multiple agents as the plugins.

## ✨ Quick Start
Expand Down
6 changes: 4 additions & 2 deletions project/examples/planner_examples/example-planner-2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ rounds:
send_from: Planner
send_to: User
attachment_list:
- type: reasoning
- type: plan_reasoning
content: |-
The user greets the Planner
- type: init_plan
Expand All @@ -21,4 +21,6 @@ rounds:
content: |-
1. Respond to the user's greeting
- type: current_plan_step
content: 1. Respond to the user's greeting
content: 1. Respond to the user's greeting
- type: stop
content: Completed
9 changes: 6 additions & 3 deletions project/examples/planner_examples/example-planner-echo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ rounds:
send_from: Planner
send_to: Echo
attachment_list:
- type: reasoning
- type: plan_reasoning
content: |-
The user wants to echo the input 'Hello World'
- type: init_plan
Expand All @@ -22,6 +22,8 @@ rounds:
1. Ask Echo to echo the user's input, 'Hello World'
- type: current_plan_step
content: 1. Ask Echo to echo the user's input, 'Hello World'
- type: stop
content: InProcess
- message: Hello World
send_from: Echo
send_to: Planner
Expand All @@ -30,7 +32,7 @@ rounds:
send_from: Planner
send_to: User
attachment_list:
- type: reasoning
- type: plan_reasoning
content: |-
The user query is successfully answered
- type: init_plan
Expand All @@ -41,4 +43,5 @@ rounds:
1. Ask Echo to echo the user's input, 'Hello World'
- type: current_plan_step
content: 1. Ask Echo to echo the user's input, 'Hello World'

- type: stop
content: Completed
137 changes: 137 additions & 0 deletions project/examples/planner_examples/example-planner-recepta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
enabled: True
rounds:
- user_query: echo 'Generate Employee Report'
state: created
post_list:
- message: |-
please follow the instructions below to complete the task:

# Task Instructions
## Step 1: Extract Employee Data
Extract the following information from the employee summary:
- `Employee ID`
- `Department`
- `Project Code`
- `Role`
- `Manager`
- `Location`

### Employee Summary
On April 10, 2025, a review was conducted for an employee with ID `E12345`. The employee is part of the `Development` department and is currently assigned to project code `"X987"`. The role held is `"Software Engineer"` under the supervision of manager `"J. Doe."` The primary work location is `"Remote."`

## Step 2: Validate the Role
- Confirm if the role is recognized among the following: Software Engineer, Data Analyst, Project Manager, DevOps Specialist, QA Tester.
- Check if the role is one of the recognized roles.

## Step 3: Construct SQL Query
Prepare and print the SQL query using the extracted details:
```sql
SELECT EmployeeID, Department, ProjectCode, Role, Manager, Location
FROM EmployeeRecords
WHERE EmployeeID = '{EmployeeID}'
AND Department = '{Department}'
AND ProjectCode = '{ProjectCode}'
AND Role = '{Role}'
AND Manager = '{Manager}'
AND Location = '{Location}'
ORDER BY EmployeeID;
```
send_from: User
send_to: Planner
attachment_list:
- message: |-
Thought: I can read and comprehend the employee summary to extract the required information.
Result: the `Employee ID` is `E12345`, the `Department` is `Development`, the `Project Code` is `X987`, the `Role` is `Software Engineer`, the `Manager` is `J. Doe`, and the `Location` is `Remote`.
send_from: Planner
send_to: Recepta
attachment_list:
- type: plan_reasoning
content: |-
The first step is to extract the following information from the employee summary: `Employee ID`, `Department`, `Project Code`, `Role`, `Manager`, `Location`.
- type: init_plan
content: |-
1. extract the following information from the employee summary: `Employee ID`, `Department`, `Project Code`, `Role`, `Manager`, `Location`
2. validate the role <interactively depends on 1>
3. construct and print the SQL query using the extracted details <interactively depends on 1>
4. check the execution result and report the result to the user <interactively depends on 1 and 3>
- type: plan
content: |-
1. extract information from the employee summary
2. validate the role
3. construct SQL query using the extracted details
4. report the result to the user
- type: current_plan_step
content: 1. extract information from the employee summary
- type: stop
content: InProcess
- message: Got it! Please go ahead.
send_from: Recepta
send_to: Planner
attachment_list:
- message: |-
Thought: I can verify if the role is one of the recognized roles with my pattern matching capability.
Thought: The recognized roles are `Software Engineer, Data Analyst, Project Manager, DevOps Specialist, QA Tester`.
Result: The role is `Software Engineer`, which is recognized.
send_from: Planner
send_to: Recepta
attachment_list:
- type: plan_reasoning
content: |-
I have extracted the information from the employee summary. The next step is to verify if the role is one of the recognized roles.
- type: init_plan
content: |-
1. extract the following information from the employee summary: `Employee ID`, `Department`, `Project Code`, `Role`, `Manager`, `Location`
2. validate the role <interactively depends on 1>
3. construct and print the SQL query using the extracted details <interactively depends on 1>
4. check the execution result and report the result to the user <interactively depends on 1 and 3>
- type: plan
content: |-
1. extract information from the employee summary
2. validate the role
3. construct SQL query using the extracted details
4. report the result to the user
- type: current_plan_step
content: 2. validate the role
- type: stop
content: InProcess
- message: Got it! Please go ahead.
send_from: Recepta
send_to: Planner
attachment_list:
- message: |-
The role is `Software Engineer`, which is recognized.

Here is the SQL query using the extracted details:
```sql
SELECT EmployeeID, Department, ProjectCode, Role, Manager, Location
FROM EmployeeRecords
WHERE EmployeeID = 'E12345'
AND Department = 'Development'
AND ProjectCode = 'X987'
AND Role = 'Software Engineer'
AND Manager = 'J. Doe'
AND Location = 'Remote'
ORDER BY EmployeeID;
```
send_from: Planner
send_to: User
attachment_list:
- type: plan_reasoning
content: |-
I can prepare and print the SQL query using the extracted details to the User.
- type: init_plan
content: |-
1. extract the following information from the employee summary: `Employee ID`, `Department`, `Project Code`, `Role`, `Manager`, `Location`
2. validate the role <interactively depends on 1>
3. construct and print the SQL query using the extracted details <interactively depends on 1>
4. check the execution result and report the result to the user <interactively depends on 1 and 3>
- type: plan
content: |-
1. extract information from the employee summary
2. validate the role
3. construct SQL query using the extracted details
4. report the result to the user
- type: current_plan_step
content: 3. construct and print the SQL query using the extracted details and report the result to the user
- type: stop
content: Completed
8 changes: 6 additions & 2 deletions project/examples/planner_examples/example-planner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ rounds:
send_from: Planner
send_to: CodeInterpreter
attachment_list:
- type: reasoning
- type: plan_reasoning
content: |-
The user wants to count the rows of the data file /home/data.csv. The first step is to load the data file and count the rows of the loaded data.
- type: init_plan
Expand All @@ -25,6 +25,8 @@ rounds:
2. Check the execution result and report the result to the user if it is correct
- type: current_plan_step
content: 1. Instruct CodeInterpreter to load the data file and count the rows of the loaded data
- type: stop
content: InProcess
- message: Load the data file /home/data.csv successfully and there are 100 rows in the data file
send_from: CodeInterpreter
send_to: Planner
Expand All @@ -33,7 +35,7 @@ rounds:
send_from: Planner
send_to: User
attachment_list:
- type: reasoning
- type: plan_reasoning
content: |-
The data file /home/data.csv is loaded and there are 100 rows in the data file
The execution result is correct
Expand All @@ -49,3 +51,5 @@ rounds:
2. Check the execution result and report the result to the user if it is correct
- type: current_plan_step
content: 2. report the result to the user
- type: stop
content: Completed
3 changes: 2 additions & 1 deletion taskweaver/ces/runtime/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,9 @@ def load_lib(self, local_ns: Dict[str, Any]):
# customize pandas display options
pd.set_option("display.html.table_schema", False)
pd.set_option("display.notebook_repr_html", False)
pd.set_option("display.max_rows", 4)
pd.set_option("display.max_rows", 5)
pd.set_option("display.expand_frame_repr", False)
pd.set_option("display.max_colwidth", None)
local_ns["pd"] = pd
except ImportError:
self.log(
Expand Down
Empty file.
44 changes: 44 additions & 0 deletions taskweaver/ext_role/recepta/recepta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from injector import inject

from taskweaver.logging import TelemetryLogger
from taskweaver.memory import Memory, Post
from taskweaver.module.event_emitter import SessionEventEmitter
from taskweaver.module.tracing import Tracing
from taskweaver.role import Role
from taskweaver.role.role import RoleConfig, RoleEntry


class ReceptaConfig(RoleConfig):
def _configure(self):
self.decorator = self._get_str("decorator", "")


class Recepta(Role):
@inject
def __init__(
self,
config: ReceptaConfig,
logger: TelemetryLogger,
tracing: Tracing,
event_emitter: SessionEventEmitter,
role_entry: RoleEntry,
):
super().__init__(config, logger, tracing, event_emitter, role_entry)

def reply(self, memory: Memory, **kwargs: ...) -> Post:
rounds = memory.get_role_rounds(
role=self.alias,
include_failure_rounds=False,
)

# obtain the query from the last round
last_post = rounds[-1].post_list[-1]

post_proxy = self.event_emitter.create_post_proxy(self.alias)

post_proxy.update_send_to(last_post.send_from)
post_proxy.update_message(
"Got it. Now, please go ahead!",
)

return post_proxy.end()
7 changes: 7 additions & 0 deletions taskweaver/ext_role/recepta/recepta.role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
alias: Recepta
module: taskweaver.ext_role.recepta.recepta.Recepta
intro : |-
- Recepta is responsible for helping the Planner to record the reasoning process.
- When the Planner is reasoning and do not involve any Workers, it must send a message to Recepta to record the reasoning process.
- When Planner needs to reason in the middle of the task and is not ready to talk to the User, it can send a message to `Recepta` to record the reasoning process and result. The message should be formatted as "Thought 1: reasoning...\nThought 2: reasoning...\n...Result: result...".
- The reasoning result should be insights or conclusion derived for the task step, NOT a plan or a set of instructions for further action.
3 changes: 2 additions & 1 deletion taskweaver/memory/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ class AttachmentType(Enum):
init_plan = "init_plan"
plan = "plan"
current_plan_step = "current_plan_step"
reasoning = "reasoning"
plan_reasoning = "plan_reasoning"
stop = "stop"

# CodeInterpreter - generate code
thought = "thought"
Expand Down
Loading
Loading