Skip to content

Commit ed59927

Browse files
feat: Add form filling use case for Python (#403)
--------- Co-authored-by: Marcus Schiesser <[email protected]>
1 parent 9f866aa commit ed59927

File tree

25 files changed

+1043
-128
lines changed

25 files changed

+1043
-128
lines changed

.changeset/large-parents-exercise.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"create-llama": patch
3+
---
4+
5+
Add form filling use case (Python)

helpers/tools.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,22 @@ For better results, you can specify the region parameter to get results from a s
267267
},
268268
],
269269
},
270+
{
271+
display: "Form Filling",
272+
name: "form_filling",
273+
supportedFrameworks: ["fastapi"],
274+
type: ToolType.LOCAL,
275+
dependencies: [
276+
{
277+
name: "pandas",
278+
version: "^2.2.3",
279+
},
280+
{
281+
name: "tabulate",
282+
version: "^0.9.0",
283+
},
284+
],
285+
},
270286
];
271287

272288
export const getTool = (toolName: string): Tool | undefined => {

helpers/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export type TemplateDataSource = {
4848
};
4949
export type TemplateDataSourceType = "file" | "web" | "db";
5050
export type TemplateObservability = "none" | "traceloop" | "llamatrace";
51-
export type TemplateAgents = "financial_report" | "blog";
51+
export type TemplateAgents = "financial_report" | "blog" | "form_filling";
5252
// Config for both file and folder
5353
export type FileSourceConfig =
5454
| {

questions/questions.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,34 @@ export const askProQuestions = async (program: QuestionArgs) => {
177177
program.observability = observability;
178178
}
179179

180+
// Ask agents
181+
if (program.template === "multiagent" && !program.agents) {
182+
const { agents } = await prompts(
183+
{
184+
type: "select",
185+
name: "agents",
186+
message: "Which agents would you like to use?",
187+
choices: [
188+
{
189+
title: "Financial report (generate a financial report)",
190+
value: "financial_report",
191+
},
192+
{
193+
title: "Form filling (fill missing value in a CSV file)",
194+
value: "form_filling",
195+
},
196+
{
197+
title: "Blog writer (Write a blog post)",
198+
value: "blog_writer",
199+
},
200+
],
201+
initial: 0,
202+
},
203+
questionHandlers,
204+
);
205+
program.agents = agents;
206+
}
207+
180208
if (!program.modelConfig) {
181209
const modelConfig = await askModelConfig({
182210
openAiKey: program.openAiKey,

questions/simple.ts

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ type AppType =
1010
| "rag"
1111
| "code_artifact"
1212
| "financial_report_agent"
13+
| "form_filling"
1314
| "extractor"
1415
| "data_scientist";
1516

@@ -35,8 +36,12 @@ export const askSimpleQuestions = async (
3536
title: "Financial Report Generator (using Workflows)",
3637
value: "financial_report_agent",
3738
},
39+
{
40+
title: "Form Filler (using Workflows)",
41+
value: "form_filling",
42+
},
3843
{ title: "Code Artifact Agent", value: "code_artifact" },
39-
{ title: "Structured extraction", value: "extractor" },
44+
{ title: "Information Extractor", value: "extractor" },
4045
],
4146
},
4247
questionHandlers,
@@ -47,19 +52,22 @@ export const askSimpleQuestions = async (
4752
let useLlamaCloud = false;
4853

4954
if (appType !== "extractor") {
50-
const { language: newLanguage } = await prompts(
51-
{
52-
type: "select",
53-
name: "language",
54-
message: "What language do you want to use?",
55-
choices: [
56-
{ title: "Python (FastAPI)", value: "fastapi" },
57-
{ title: "Typescript (NextJS)", value: "nextjs" },
58-
],
59-
},
60-
questionHandlers,
61-
);
62-
language = newLanguage;
55+
// TODO: Add TS support for form filling use case
56+
if (appType !== "form_filling") {
57+
const { language: newLanguage } = await prompts(
58+
{
59+
type: "select",
60+
name: "language",
61+
message: "What language do you want to use?",
62+
choices: [
63+
{ title: "Python (FastAPI)", value: "fastapi" },
64+
{ title: "Typescript (NextJS)", value: "nextjs" },
65+
],
66+
},
67+
questionHandlers,
68+
);
69+
language = newLanguage;
70+
}
6371

6472
const { useLlamaCloud: newUseLlamaCloud } = await prompts(
6573
{
@@ -152,6 +160,14 @@ const convertAnswers = async (
152160
frontend: true,
153161
modelConfig: MODEL_GPT4o,
154162
},
163+
form_filling: {
164+
template: "multiagent",
165+
agents: "form_filling",
166+
tools: getTools(["form_filling"]),
167+
dataSources: EXAMPLE_10K_SEC_FILES,
168+
frontend: true,
169+
modelConfig: MODEL_GPT4o,
170+
},
155171
extractor: {
156172
template: "extractor",
157173
tools: [],

templates/components/agents/python/blog/app/agents/publisher.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ def get_publisher_tools() -> Tuple[List[FunctionTool], str, str]:
1111
tools = []
1212
# Get configured tools from the tools.yaml file
1313
configured_tools = ToolFactory.from_env(map_result=True)
14-
if "document_generator" in configured_tools.keys():
15-
tools.extend(configured_tools["document_generator"])
14+
if "generate_document" in configured_tools.keys():
15+
tools.append(configured_tools["generate_document"])
1616
prompt_instructions = dedent("""
1717
Normally, reply the blog post content to the user directly.
18-
But if user requested to generate a file, use the document_generator tool to generate the file and reply the link to the file.
18+
But if user requested to generate a file, use the generate_document tool to generate the file and reply the link to the file.
1919
""")
2020
description = "Expert in publishing the blog post, able to publish the blog post in PDF or HTML format."
2121
else:

templates/components/agents/python/blog/app/agents/researcher.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,15 @@ def _get_research_tools(**kwargs) -> QueryEngineTool:
4242
query_engine_tool = _create_query_engine_tool(**kwargs)
4343
if query_engine_tool is not None:
4444
tools.append(query_engine_tool)
45-
researcher_tool_names = ["duckduckgo", "wikipedia.WikipediaToolSpec"]
45+
researcher_tool_names = [
46+
"duckduckgo_search",
47+
"duckduckgo_image_search",
48+
"wikipedia.WikipediaToolSpec",
49+
]
4650
configured_tools = ToolFactory.from_env(map_result=True)
4751
for tool_name, tool in configured_tools.items():
4852
if tool_name in researcher_tool_names:
49-
tools.extend(tool)
53+
tools.append(tool)
5054
return tools
5155

5256

templates/components/agents/python/financial_report/app/agents/analyst.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ def _get_analyst_params() -> Tuple[List[type[FunctionTool]], str, str]:
2222
description = "Expert in analyzing financial data"
2323
configured_tools = ToolFactory.from_env(map_result=True)
2424
# Check if the interpreter tool is configured
25-
if "interpreter" in configured_tools.keys():
26-
tools.extend(configured_tools["interpreter"])
25+
if "interpret" in configured_tools.keys():
26+
tools.append(configured_tools["interpret"])
2727
prompt_instructions += dedent("""
2828
You are able to visualize the financial data using code interpreter tool.
2929
It's very useful to create and include visualizations to the report (make sure you include the right code and data for the visualization).

templates/components/agents/python/financial_report/app/agents/reporter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ def _get_reporter_params(
2424
"""
2525
)
2626
configured_tools = ToolFactory.from_env(map_result=True)
27-
if "document_generator" in configured_tools: # type: ignore
28-
tools.extend(configured_tools["document_generator"]) # type: ignore
27+
if "generate_document" in configured_tools: # type: ignore
28+
tools.append(configured_tools["generate_document"]) # type: ignore
2929
prompt_instructions += (
3030
"\nYou are also able to generate a file document (PDF/HTML) of the report."
3131
)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
This is a [LlamaIndex](https://www.llamaindex.ai/) multi-agents project using [Workflows](https://docs.llamaindex.ai/en/stable/understanding/workflows/).
2+
3+
## Getting Started
4+
5+
First, setup the environment with poetry:
6+
7+
> **_Note:_** This step is not needed if you are using the dev-container.
8+
9+
```shell
10+
poetry install
11+
```
12+
13+
Then check the parameters that have been pre-configured in the `.env` file in this directory.
14+
Make sure you have the `OPENAI_API_KEY` set.
15+
16+
Second, run the development server:
17+
18+
```shell
19+
poetry run python main.py
20+
```
21+
22+
## Use Case: Filling Financial CSV Template
23+
24+
To reproduce the use case, start the [frontend](../frontend/README.md) and follow these steps in the frontend:
25+
26+
1. Upload the Apple and Tesla financial reports from the [data](./data) directory. Just send an empty message.
27+
2. Upload the CSV file [sec_10k_template.csv](./sec_10k_template.csv) and send the message "Fill the missing cells in the CSV file".
28+
29+
The agent will fill the missing cells by retrieving the information from the uploaded financial reports and return a new CSV file with the filled cells.
30+
31+
### API endpoints
32+
33+
The example provides one streaming API endpoint `/api/chat`.
34+
You can test the endpoint with the following curl request:
35+
36+
```
37+
curl --location 'localhost:8000/api/chat' \
38+
--header 'Content-Type: application/json' \
39+
--data '{ "messages": [{ "role": "user", "content": "What can you do?" }] }'
40+
```
41+
42+
You can start editing the API by modifying `app/api/routers/chat.py` or `app/agents/form_filling.py`. The API auto-updates as you save the files.
43+
44+
Open [http://localhost:8000/docs](http://localhost:8000/docs) with your browser to see the Swagger UI of the API.
45+
46+
The API allows CORS for all origins to simplify development. You can change this behavior by setting the `ENVIRONMENT` environment variable to `prod`:
47+
48+
```
49+
ENVIRONMENT=prod poetry run python main.py
50+
```
51+
52+
## Learn More
53+
54+
To learn more about LlamaIndex, take a look at the following resources:
55+
56+
- [LlamaIndex Documentation](https://docs.llamaindex.ai) - learn about LlamaIndex.
57+
- [Workflows Introduction](https://docs.llamaindex.ai/en/stable/understanding/workflows/) - learn about LlamaIndex workflows.
58+
59+
You can check out [the LlamaIndex GitHub repository](https://github.com/run-llama/llama_index) - your feedback and contributions are welcome!

0 commit comments

Comments
 (0)