Skip to content

Commit c4020cb

Browse files
committed
rename writer to deep research
1 parent ade3e2b commit c4020cb

File tree

5 files changed

+53
-42
lines changed

5 files changed

+53
-42
lines changed

templates/components/agents/python/deep_research/README-template.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ The workflow writes blog posts based on documents in the [data](./data) director
3030
After starting the server, go to [http://localhost:8000](http://localhost:8000) and send a message to the agent to write a blog post.
3131
E.g: "Write a post about AI investment in 2024"
3232

33-
To update the workflow, you can edit the [writer.py](./app/workflows/writer.py) file.
33+
To update the workflow, you can edit the [deep_research.py](./app/workflows/deep_research.py) file.
3434

3535
By default, the workflow retrieves 10 results from your documents. To customize the amount of information covered in the answer, you can adjust the `TOP_K` environment variable in the `.env` file. A higher value will retrieve more results from your documents, potentially providing more comprehensive answers.
3636

templates/components/agents/python/deep_research/app/workflows/deep_research.py

+17-17
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818

1919
from app.engine.index import IndexConfig, get_index
2020
from app.workflows.agents import plan_research, research, write_report
21+
from app.workflows.events import SourceNodesEvent
2122
from app.workflows.models import (
2223
CollectAnswersEvent,
2324
DataEvent,
2425
PlanResearchEvent,
26+
ReportEvent,
2527
ResearchEvent,
26-
WriteReportEvent,
2728
)
28-
from app.workflows.events import SourceNodesEvent
2929

3030
logger = logging.getLogger("uvicorn")
3131
logger.setLevel(logging.INFO)
@@ -43,16 +43,16 @@ def create_workflow(
4343
"Index is not found. Try run generation script to create the index first."
4444
)
4545

46-
return WriterWorkflow(
46+
return DeepResearchWorkflow(
4747
index=index,
4848
chat_history=chat_history,
4949
timeout=120.0,
5050
)
5151

5252

53-
class WriterWorkflow(Workflow):
53+
class DeepResearchWorkflow(Workflow):
5454
"""
55-
A workflow to research and write a post for a specific topic.
55+
A workflow to research and analyze documents from multiple perspectives and write a comprehensive report.
5656
5757
Requirements:
5858
- An indexed documents containing the knowledge base related to the topic
@@ -61,7 +61,7 @@ class WriterWorkflow(Workflow):
6161
1. Retrieve information from the knowledge base
6262
2. Analyze the retrieved information and provide questions for answering
6363
3. Answer the questions
64-
4. Write the post based on the research results
64+
4. Write the report based on the research results
6565
"""
6666

6767
memory: SimpleComposableMemory
@@ -104,7 +104,7 @@ def retrieve(self, ctx: Context, ev: StartEvent) -> PlanResearchEvent:
104104
)
105105
ctx.write_event_to_stream(
106106
DataEvent(
107-
type="writer_card",
107+
type="deep_research_event",
108108
data={
109109
"event": "retrieve",
110110
"state": "inprogress",
@@ -118,7 +118,7 @@ def retrieve(self, ctx: Context, ev: StartEvent) -> PlanResearchEvent:
118118
self.context_nodes.extend(nodes)
119119
ctx.write_event_to_stream(
120120
DataEvent(
121-
type="writer_card",
121+
type="deep_research_event",
122122
data={
123123
"event": "retrieve",
124124
"state": "done",
@@ -139,14 +139,14 @@ def retrieve(self, ctx: Context, ev: StartEvent) -> PlanResearchEvent:
139139
@step
140140
async def analyze(
141141
self, ctx: Context, ev: PlanResearchEvent
142-
) -> ResearchEvent | WriteReportEvent | StopEvent:
142+
) -> ResearchEvent | ReportEvent | StopEvent:
143143
"""
144144
Analyze the retrieved information
145145
"""
146146
logger.info("Analyzing the retrieved information")
147147
ctx.write_event_to_stream(
148148
DataEvent(
149-
type="writer_card",
149+
type="deep_research_event",
150150
data={
151151
"event": "analyze",
152152
"state": "inprogress",
@@ -169,7 +169,7 @@ async def analyze(
169169
content="No more idea to analyze. We should report the answers.",
170170
)
171171
)
172-
ctx.send_event(WriteReportEvent())
172+
ctx.send_event(ReportEvent())
173173
else:
174174
await ctx.set("n_questions", len(res.research_questions))
175175
self.memory.put(
@@ -183,7 +183,7 @@ async def analyze(
183183
question_id = str(uuid.uuid4())
184184
ctx.write_event_to_stream(
185185
DataEvent(
186-
type="writer_card",
186+
type="deep_research_event",
187187
data={
188188
"event": "answer",
189189
"state": "pending",
@@ -202,7 +202,7 @@ async def analyze(
202202
)
203203
ctx.write_event_to_stream(
204204
DataEvent(
205-
type="writer_card",
205+
type="deep_research_event",
206206
data={
207207
"event": "analyze",
208208
"state": "done",
@@ -218,7 +218,7 @@ async def answer(self, ctx: Context, ev: ResearchEvent) -> CollectAnswersEvent:
218218
"""
219219
ctx.write_event_to_stream(
220220
DataEvent(
221-
type="writer_card",
221+
type="deep_research_event",
222222
data={
223223
"event": "answer",
224224
"state": "inprogress",
@@ -237,7 +237,7 @@ async def answer(self, ctx: Context, ev: ResearchEvent) -> CollectAnswersEvent:
237237
answer = f"Got error when answering the question: {ev.question}"
238238
ctx.write_event_to_stream(
239239
DataEvent(
240-
type="writer_card",
240+
type="deep_research_event",
241241
data={
242242
"event": "answer",
243243
"state": "done",
@@ -257,7 +257,7 @@ async def answer(self, ctx: Context, ev: ResearchEvent) -> CollectAnswersEvent:
257257
@step
258258
async def collect_answers(
259259
self, ctx: Context, ev: CollectAnswersEvent
260-
) -> WriteReportEvent:
260+
) -> ReportEvent:
261261
"""
262262
Collect answers to all questions
263263
"""
@@ -285,7 +285,7 @@ async def collect_answers(
285285
return PlanResearchEvent()
286286

287287
@step
288-
async def report(self, ctx: Context, ev: WriteReportEvent) -> StopEvent:
288+
async def report(self, ctx: Context, ev: ReportEvent) -> StopEvent:
289289
"""
290290
Report the answers
291291
"""

templates/components/agents/python/deep_research/app/workflows/models.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ class CollectAnswersEvent(Event):
2222
answer: str
2323

2424

25-
class WriteReportEvent(Event):
25+
class ReportEvent(Event):
2626
pass
2727

2828

2929
# Events that are streamed to the frontend and rendered there
30-
class WriterEventData(BaseModel):
30+
class DeepResearchEventData(BaseModel):
3131
event: Literal["retrieve", "analyze", "answer"]
3232
state: Literal["pending", "inprogress", "done", "error"]
3333
id: Optional[str] = None
@@ -36,8 +36,8 @@ class WriterEventData(BaseModel):
3636

3737

3838
class DataEvent(Event):
39-
type: Literal["writer_card"]
40-
data: WriterEventData
39+
type: Literal["deep_research_event"]
40+
data: DeepResearchEventData
4141

4242
def to_response(self):
4343
return self.model_dump()

templates/types/streaming/nextjs/app/components/ui/chat/chat-message-content.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import {
55
useChatMessage,
66
useChatUI,
77
} from "@llamaindex/chat-ui";
8+
import { DeepResearchCard } from "./custom/deep-research-card";
89
import { Markdown } from "./custom/markdown";
9-
import { WriterCard } from "./custom/writer-card";
1010
import { ToolAnnotations } from "./tools/chat-tools";
1111

1212
export function ChatMessageContent() {
@@ -23,10 +23,10 @@ export function ChatMessageContent() {
2323
/>
2424
),
2525
},
26-
// add the writer card
26+
// add the deep research card
2727
{
2828
position: ContentPosition.CHAT_EVENTS,
29-
component: <WriterCard message={message} />,
29+
component: <DeepResearchCard message={message} />,
3030
},
3131
{
3232
// add the tool annotations after events

templates/types/streaming/nextjs/app/components/ui/chat/custom/writer-card.tsx renamed to templates/types/streaming/nextjs/app/components/ui/chat/custom/deep-research-card.tsx

+28-17
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ import { Markdown } from "./markdown";
2222
// Streaming event types
2323
type EventState = "pending" | "inprogress" | "done" | "error";
2424

25-
type WriterEvent = {
26-
type: "writer_card";
25+
type DeepResearchEvent = {
26+
type: "deep_research_event";
2727
data: {
2828
event: "retrieve" | "analyze" | "answer";
2929
state: EventState;
@@ -42,7 +42,7 @@ type QuestionState = {
4242
isOpen: boolean;
4343
};
4444

45-
type WriterState = {
45+
type DeepResearchCardState = {
4646
retrieve: {
4747
state: EventState | null;
4848
};
@@ -52,7 +52,7 @@ type WriterState = {
5252
};
5353
};
5454

55-
interface WriterCardProps {
55+
interface DeepResearchCardProps {
5656
message: Message;
5757
className?: string;
5858
}
@@ -66,9 +66,9 @@ const stateIcon: Record<EventState, React.ReactNode> = {
6666

6767
// Transform the state based on the event without mutations
6868
const transformState = (
69-
state: WriterState,
70-
event: WriterEvent,
71-
): WriterState => {
69+
state: DeepResearchCardState,
70+
event: DeepResearchEvent,
71+
): DeepResearchCardState => {
7272
switch (event.data.event) {
7373
case "answer": {
7474
const { id, question, answer } = event.data;
@@ -119,35 +119,46 @@ const transformState = (
119119
}
120120
};
121121

122-
// Convert writer events to state
123-
const writeEventsToState = (events: WriterEvent[] | undefined): WriterState => {
122+
// Convert deep research events to state
123+
const deepResearchEventsToState = (
124+
events: DeepResearchEvent[] | undefined,
125+
): DeepResearchCardState => {
124126
if (!events?.length) {
125127
return {
126128
retrieve: { state: null },
127129
analyze: { state: null, questions: [] },
128130
};
129131
}
130132

131-
const initialState: WriterState = {
133+
const initialState: DeepResearchCardState = {
132134
retrieve: { state: null },
133135
analyze: { state: null, questions: [] },
134136
};
135137

136138
return events.reduce(
137-
(acc: WriterState, event: WriterEvent) => transformState(acc, event),
139+
(acc: DeepResearchCardState, event: DeepResearchEvent) =>
140+
transformState(acc, event),
138141
initialState,
139142
);
140143
};
141144

142-
export function WriterCard({ message, className }: WriterCardProps) {
143-
const writerEvents = message.annotations as WriterEvent[] | undefined;
144-
const hasWriterEvents = writerEvents?.some(
145-
(event) => event.type === "writer_card",
145+
export function DeepResearchCard({
146+
message,
147+
className,
148+
}: DeepResearchCardProps) {
149+
const deepResearchEvents = message.annotations as
150+
| DeepResearchEvent[]
151+
| undefined;
152+
const hasDeepResearchEvents = deepResearchEvents?.some(
153+
(event) => event.type === "deep_research_event",
146154
);
147155

148-
const state = useMemo(() => writeEventsToState(writerEvents), [writerEvents]);
156+
const state = useMemo(
157+
() => deepResearchEventsToState(deepResearchEvents),
158+
[deepResearchEvents],
159+
);
149160

150-
if (!hasWriterEvents) {
161+
if (!hasDeepResearchEvents) {
151162
return null;
152163
}
153164

0 commit comments

Comments
 (0)