Skip to content

Commit 724c37a

Browse files
liqulShilinHe
andauthored
Add Recepta Role for CoT in Planner [Ready] (#455)
Co-authored-by: Shilin HE <[email protected]>
1 parent 8978d5d commit 724c37a

File tree

12 files changed

+731
-20
lines changed

12 files changed

+731
-20
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Unlike many agent frameworks that only track the chat history with LLMs in text,
2323

2424

2525
## 🆕 News
26+
- 📅2025-01-16: TaskWeaver has been enhanced with an experimental role called [Recepta](https://microsoft.github.io/TaskWeaver/blog/reasoning) for its reasoning power.🧠
2627
- 📅2024-12-23: TaskWeaver has been integrated with the [AgentOps](https://microsoft.github.io/TaskWeaver/docs/observability) for better observability and monitoring.🔍
2728
- 📅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.🧠
2829
- 📅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.📚
@@ -31,7 +32,7 @@ Unlike many agent frameworks that only track the chat history with LLMs in text,
3132
- 📅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.🐳
3233
- 📅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.🐳
3334
- 📅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.🔗
34-
- 📅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.🐳
35+
<!-- - 📅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.🐳 -->
3536
<!-- - 📅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.📟 -->
3637
<!-- - 📅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.📚 -->
3738
<!-- - 📅2024-01-30: TaskWeaver introduces a new plugin-only mode that securely generates calls to specified plugins without producing extraneous code.🪡 -->
@@ -54,7 +55,7 @@ Unlike many agent frameworks that only track the chat history with LLMs in text,
5455
- [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.
5556
- [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.
5657
- [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.
57-
- [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.
58+
- [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.
5859
- [x] **Easy extension** - TaskWeaver is easy to extend to accomplish more complex tasks with multiple agents as the plugins.
5960

6061
## ✨ Quick Start

project/examples/planner_examples/example-planner-2.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ rounds:
1111
send_from: Planner
1212
send_to: User
1313
attachment_list:
14-
- type: reasoning
14+
- type: plan_reasoning
1515
content: |-
1616
The user greets the Planner
1717
- type: init_plan
@@ -21,4 +21,6 @@ rounds:
2121
content: |-
2222
1. Respond to the user's greeting
2323
- type: current_plan_step
24-
content: 1. Respond to the user's greeting
24+
content: 1. Respond to the user's greeting
25+
- type: stop
26+
content: Completed

project/examples/planner_examples/example-planner-echo.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ rounds:
1111
send_from: Planner
1212
send_to: Echo
1313
attachment_list:
14-
- type: reasoning
14+
- type: plan_reasoning
1515
content: |-
1616
The user wants to echo the input 'Hello World'
1717
- type: init_plan
@@ -22,6 +22,8 @@ rounds:
2222
1. Ask Echo to echo the user's input, 'Hello World'
2323
- type: current_plan_step
2424
content: 1. Ask Echo to echo the user's input, 'Hello World'
25+
- type: stop
26+
content: InProcess
2527
- message: Hello World
2628
send_from: Echo
2729
send_to: Planner
@@ -30,7 +32,7 @@ rounds:
3032
send_from: Planner
3133
send_to: User
3234
attachment_list:
33-
- type: reasoning
35+
- type: plan_reasoning
3436
content: |-
3537
The user query is successfully answered
3638
- type: init_plan
@@ -41,4 +43,5 @@ rounds:
4143
1. Ask Echo to echo the user's input, 'Hello World'
4244
- type: current_plan_step
4345
content: 1. Ask Echo to echo the user's input, 'Hello World'
44-
46+
- type: stop
47+
content: Completed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
enabled: True
2+
rounds:
3+
- user_query: echo 'Generate Employee Report'
4+
state: created
5+
post_list:
6+
- message: |-
7+
please follow the instructions below to complete the task:
8+
9+
# Task Instructions
10+
## Step 1: Extract Employee Data
11+
Extract the following information from the employee summary:
12+
- `Employee ID`
13+
- `Department`
14+
- `Project Code`
15+
- `Role`
16+
- `Manager`
17+
- `Location`
18+
19+
### Employee Summary
20+
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."`
21+
22+
## Step 2: Validate the Role
23+
- Confirm if the role is recognized among the following: Software Engineer, Data Analyst, Project Manager, DevOps Specialist, QA Tester.
24+
- Check if the role is one of the recognized roles.
25+
26+
## Step 3: Construct SQL Query
27+
Prepare and print the SQL query using the extracted details:
28+
```sql
29+
SELECT EmployeeID, Department, ProjectCode, Role, Manager, Location
30+
FROM EmployeeRecords
31+
WHERE EmployeeID = '{EmployeeID}'
32+
AND Department = '{Department}'
33+
AND ProjectCode = '{ProjectCode}'
34+
AND Role = '{Role}'
35+
AND Manager = '{Manager}'
36+
AND Location = '{Location}'
37+
ORDER BY EmployeeID;
38+
```
39+
send_from: User
40+
send_to: Planner
41+
attachment_list:
42+
- message: |-
43+
Thought: I can read and comprehend the employee summary to extract the required information.
44+
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`.
45+
send_from: Planner
46+
send_to: Recepta
47+
attachment_list:
48+
- type: plan_reasoning
49+
content: |-
50+
The first step is to extract the following information from the employee summary: `Employee ID`, `Department`, `Project Code`, `Role`, `Manager`, `Location`.
51+
- type: init_plan
52+
content: |-
53+
1. extract the following information from the employee summary: `Employee ID`, `Department`, `Project Code`, `Role`, `Manager`, `Location`
54+
2. validate the role <interactively depends on 1>
55+
3. construct and print the SQL query using the extracted details <interactively depends on 1>
56+
4. check the execution result and report the result to the user <interactively depends on 1 and 3>
57+
- type: plan
58+
content: |-
59+
1. extract information from the employee summary
60+
2. validate the role
61+
3. construct SQL query using the extracted details
62+
4. report the result to the user
63+
- type: current_plan_step
64+
content: 1. extract information from the employee summary
65+
- type: stop
66+
content: InProcess
67+
- message: Got it! Please go ahead.
68+
send_from: Recepta
69+
send_to: Planner
70+
attachment_list:
71+
- message: |-
72+
Thought: I can verify if the role is one of the recognized roles with my pattern matching capability.
73+
Thought: The recognized roles are `Software Engineer, Data Analyst, Project Manager, DevOps Specialist, QA Tester`.
74+
Result: The role is `Software Engineer`, which is recognized.
75+
send_from: Planner
76+
send_to: Recepta
77+
attachment_list:
78+
- type: plan_reasoning
79+
content: |-
80+
I have extracted the information from the employee summary. The next step is to verify if the role is one of the recognized roles.
81+
- type: init_plan
82+
content: |-
83+
1. extract the following information from the employee summary: `Employee ID`, `Department`, `Project Code`, `Role`, `Manager`, `Location`
84+
2. validate the role <interactively depends on 1>
85+
3. construct and print the SQL query using the extracted details <interactively depends on 1>
86+
4. check the execution result and report the result to the user <interactively depends on 1 and 3>
87+
- type: plan
88+
content: |-
89+
1. extract information from the employee summary
90+
2. validate the role
91+
3. construct SQL query using the extracted details
92+
4. report the result to the user
93+
- type: current_plan_step
94+
content: 2. validate the role
95+
- type: stop
96+
content: InProcess
97+
- message: Got it! Please go ahead.
98+
send_from: Recepta
99+
send_to: Planner
100+
attachment_list:
101+
- message: |-
102+
The role is `Software Engineer`, which is recognized.
103+
104+
Here is the SQL query using the extracted details:
105+
```sql
106+
SELECT EmployeeID, Department, ProjectCode, Role, Manager, Location
107+
FROM EmployeeRecords
108+
WHERE EmployeeID = 'E12345'
109+
AND Department = 'Development'
110+
AND ProjectCode = 'X987'
111+
AND Role = 'Software Engineer'
112+
AND Manager = 'J. Doe'
113+
AND Location = 'Remote'
114+
ORDER BY EmployeeID;
115+
```
116+
send_from: Planner
117+
send_to: User
118+
attachment_list:
119+
- type: plan_reasoning
120+
content: |-
121+
I can prepare and print the SQL query using the extracted details to the User.
122+
- type: init_plan
123+
content: |-
124+
1. extract the following information from the employee summary: `Employee ID`, `Department`, `Project Code`, `Role`, `Manager`, `Location`
125+
2. validate the role <interactively depends on 1>
126+
3. construct and print the SQL query using the extracted details <interactively depends on 1>
127+
4. check the execution result and report the result to the user <interactively depends on 1 and 3>
128+
- type: plan
129+
content: |-
130+
1. extract information from the employee summary
131+
2. validate the role
132+
3. construct SQL query using the extracted details
133+
4. report the result to the user
134+
- type: current_plan_step
135+
content: 3. construct and print the SQL query using the extracted details and report the result to the user
136+
- type: stop
137+
content: Completed

project/examples/planner_examples/example-planner.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ rounds:
1111
send_from: Planner
1212
send_to: CodeInterpreter
1313
attachment_list:
14-
- type: reasoning
14+
- type: plan_reasoning
1515
content: |-
1616
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.
1717
- type: init_plan
@@ -25,6 +25,8 @@ rounds:
2525
2. Check the execution result and report the result to the user if it is correct
2626
- type: current_plan_step
2727
content: 1. Instruct CodeInterpreter to load the data file and count the rows of the loaded data
28+
- type: stop
29+
content: InProcess
2830
- message: Load the data file /home/data.csv successfully and there are 100 rows in the data file
2931
send_from: CodeInterpreter
3032
send_to: Planner
@@ -33,7 +35,7 @@ rounds:
3335
send_from: Planner
3436
send_to: User
3537
attachment_list:
36-
- type: reasoning
38+
- type: plan_reasoning
3739
content: |-
3840
The data file /home/data.csv is loaded and there are 100 rows in the data file
3941
The execution result is correct
@@ -49,3 +51,5 @@ rounds:
4951
2. Check the execution result and report the result to the user if it is correct
5052
- type: current_plan_step
5153
content: 2. report the result to the user
54+
- type: stop
55+
content: Completed

taskweaver/ces/runtime/executor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,9 @@ def load_lib(self, local_ns: Dict[str, Any]):
173173
# customize pandas display options
174174
pd.set_option("display.html.table_schema", False)
175175
pd.set_option("display.notebook_repr_html", False)
176-
pd.set_option("display.max_rows", 4)
176+
pd.set_option("display.max_rows", 5)
177177
pd.set_option("display.expand_frame_repr", False)
178+
pd.set_option("display.max_colwidth", None)
178179
local_ns["pd"] = pd
179180
except ImportError:
180181
self.log(

taskweaver/ext_role/recepta/__init__.py

Whitespace-only changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from injector import inject
2+
3+
from taskweaver.logging import TelemetryLogger
4+
from taskweaver.memory import Memory, Post
5+
from taskweaver.module.event_emitter import SessionEventEmitter
6+
from taskweaver.module.tracing import Tracing
7+
from taskweaver.role import Role
8+
from taskweaver.role.role import RoleConfig, RoleEntry
9+
10+
11+
class ReceptaConfig(RoleConfig):
12+
def _configure(self):
13+
self.decorator = self._get_str("decorator", "")
14+
15+
16+
class Recepta(Role):
17+
@inject
18+
def __init__(
19+
self,
20+
config: ReceptaConfig,
21+
logger: TelemetryLogger,
22+
tracing: Tracing,
23+
event_emitter: SessionEventEmitter,
24+
role_entry: RoleEntry,
25+
):
26+
super().__init__(config, logger, tracing, event_emitter, role_entry)
27+
28+
def reply(self, memory: Memory, **kwargs: ...) -> Post:
29+
rounds = memory.get_role_rounds(
30+
role=self.alias,
31+
include_failure_rounds=False,
32+
)
33+
34+
# obtain the query from the last round
35+
last_post = rounds[-1].post_list[-1]
36+
37+
post_proxy = self.event_emitter.create_post_proxy(self.alias)
38+
39+
post_proxy.update_send_to(last_post.send_from)
40+
post_proxy.update_message(
41+
"Got it. Now, please go ahead!",
42+
)
43+
44+
return post_proxy.end()
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
alias: Recepta
2+
module: taskweaver.ext_role.recepta.recepta.Recepta
3+
intro : |-
4+
- Recepta is responsible for helping the Planner to record the reasoning process.
5+
- When the Planner is reasoning and do not involve any Workers, it must send a message to Recepta to record the reasoning process.
6+
- 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...".
7+
- The reasoning result should be insights or conclusion derived for the task step, NOT a plan or a set of instructions for further action.

taskweaver/memory/attachment.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ class AttachmentType(Enum):
1212
init_plan = "init_plan"
1313
plan = "plan"
1414
current_plan_step = "current_plan_step"
15-
reasoning = "reasoning"
15+
plan_reasoning = "plan_reasoning"
16+
stop = "stop"
1617

1718
# CodeInterpreter - generate code
1819
thought = "thought"

0 commit comments

Comments
 (0)