Skip to content

feat: Add form filling use case #403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from 22 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: 5 additions & 0 deletions .changeset/large-parents-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"create-llama": patch
---

Add form filling use case (Python)
16 changes: 16 additions & 0 deletions helpers/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,22 @@ For better results, you can specify the region parameter to get results from a s
},
],
},
{
display: "Form Filling",
name: "form_filling",
supportedFrameworks: ["fastapi"],
type: ToolType.LOCAL,
dependencies: [
{
name: "pandas",
version: "^2.2.3",
},
{
name: "tabulate",
version: "^0.9.0",
},
],
},
];

export const getTool = (toolName: string): Tool | undefined => {
Expand Down
2 changes: 1 addition & 1 deletion helpers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export type TemplateDataSource = {
};
export type TemplateDataSourceType = "file" | "web" | "db";
export type TemplateObservability = "none" | "traceloop" | "llamatrace";
export type TemplateAgents = "financial_report" | "blog";
export type TemplateAgents = "financial_report" | "blog" | "form_filling";
// Config for both file and folder
export type FileSourceConfig =
| {
Expand Down
28 changes: 28 additions & 0 deletions questions/questions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,34 @@ export const askProQuestions = async (program: QuestionArgs) => {
program.observability = observability;
}

// Ask agents
if (program.template === "multiagent" && !program.agents) {
const { agents } = await prompts(
{
type: "select",
name: "agents",
message: "Which agents would you like to use?",
choices: [
{
title: "Financial report (generate a financial report)",
value: "financial_report",
},
{
title: "Form filling (fill missing value in a CSV file)",
value: "form_filling",
},
{
title: "Blog writer (Write a blog post)",
value: "blog_writer",
},
],
initial: 0,
},
questionHandlers,
);
program.agents = agents;
}

if (!program.modelConfig) {
const modelConfig = await askModelConfig({
openAiKey: program.openAiKey,
Expand Down
44 changes: 30 additions & 14 deletions questions/simple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type AppType =
| "rag"
| "code_artifact"
| "financial_report_agent"
| "form_filling"
| "extractor"
| "data_scientist";

Expand All @@ -35,8 +36,12 @@ export const askSimpleQuestions = async (
title: "Financial Report Generator (using Workflows)",
value: "financial_report_agent",
},
{
title: "Form Filler (using Workflows)",
value: "form_filling",
},
{ title: "Code Artifact Agent", value: "code_artifact" },
{ title: "Structured extraction", value: "extractor" },
{ title: "Information Extractor", value: "extractor" },
],
},
questionHandlers,
Expand All @@ -47,19 +52,22 @@ export const askSimpleQuestions = async (
let useLlamaCloud = false;

if (appType !== "extractor") {
const { language: newLanguage } = await prompts(
{
type: "select",
name: "language",
message: "What language do you want to use?",
choices: [
{ title: "Python (FastAPI)", value: "fastapi" },
{ title: "Typescript (NextJS)", value: "nextjs" },
],
},
questionHandlers,
);
language = newLanguage;
// TODO: Add TS support for form filling use case
if (appType !== "form_filling") {
const { language: newLanguage } = await prompts(
{
type: "select",
name: "language",
message: "What language do you want to use?",
choices: [
{ title: "Python (FastAPI)", value: "fastapi" },
{ title: "Typescript (NextJS)", value: "nextjs" },
],
},
questionHandlers,
);
language = newLanguage;
}

const { useLlamaCloud: newUseLlamaCloud } = await prompts(
{
Expand Down Expand Up @@ -152,6 +160,14 @@ const convertAnswers = async (
frontend: true,
modelConfig: MODEL_GPT4o,
},
form_filling: {
template: "multiagent",
agents: "form_filling",
tools: getTools(["form_filling"]),
dataSources: EXAMPLE_10K_SEC_FILES,
frontend: true,
modelConfig: MODEL_GPT4o,
},
extractor: {
template: "extractor",
tools: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ def get_publisher_tools() -> Tuple[List[FunctionTool], str, str]:
tools = []
# Get configured tools from the tools.yaml file
configured_tools = ToolFactory.from_env(map_result=True)
if "document_generator" in configured_tools.keys():
tools.extend(configured_tools["document_generator"])
if "generate_document" in configured_tools.keys():
tools.append(configured_tools["generate_document"])
prompt_instructions = dedent("""
Normally, reply the blog post content to the user directly.
But if user requested to generate a file, use the document_generator tool to generate the file and reply the link to the file.
But if user requested to generate a file, use the generate_document tool to generate the file and reply the link to the file.
""")
description = "Expert in publishing the blog post, able to publish the blog post in PDF or HTML format."
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,15 @@ def _get_research_tools(**kwargs) -> QueryEngineTool:
query_engine_tool = _create_query_engine_tool(**kwargs)
if query_engine_tool is not None:
tools.append(query_engine_tool)
researcher_tool_names = ["duckduckgo", "wikipedia.WikipediaToolSpec"]
researcher_tool_names = [
"duckduckgo_search",
"duckduckgo_image_search",
"wikipedia.WikipediaToolSpec",
]
configured_tools = ToolFactory.from_env(map_result=True)
for tool_name, tool in configured_tools.items():
if tool_name in researcher_tool_names:
tools.extend(tool)
tools.append(tool)
return tools


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ def _get_analyst_params() -> Tuple[List[type[FunctionTool]], str, str]:
description = "Expert in analyzing financial data"
configured_tools = ToolFactory.from_env(map_result=True)
# Check if the interpreter tool is configured
if "interpreter" in configured_tools.keys():
tools.extend(configured_tools["interpreter"])
if "interpret" in configured_tools.keys():
tools.append(configured_tools["interpret"])
prompt_instructions += dedent("""
You are able to visualize the financial data using code interpreter tool.
It's very useful to create and include visualizations to the report (make sure you include the right code and data for the visualization).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ def _get_reporter_params(
"""
)
configured_tools = ToolFactory.from_env(map_result=True)
if "document_generator" in configured_tools: # type: ignore
tools.extend(configured_tools["document_generator"]) # type: ignore
if "generate_document" in configured_tools: # type: ignore
tools.append(configured_tools["generate_document"]) # type: ignore
prompt_instructions += (
"\nYou are also able to generate a file document (PDF/HTML) of the report."
)
Expand Down
54 changes: 54 additions & 0 deletions templates/components/agents/python/form_filling/README-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
This is a [LlamaIndex](https://www.llamaindex.ai/) multi-agents project using [Workflows](https://docs.llamaindex.ai/en/stable/understanding/workflows/).

## Getting Started

First, setup the environment with poetry:

> **_Note:_** This step is not needed if you are using the dev-container.

```shell
poetry install
```

Then check the parameters that have been pre-configured in the `.env` file in this directory.
Make sure you have the `OPENAI_API_KEY` set.

Second, run the development server:

```shell
poetry run python main.py
```

The example provides one streaming API endpoint `/api/chat`.
You can test the endpoint with the following curl request:

```
curl --location 'localhost:8000/api/chat' \
--header 'Content-Type: application/json' \
--data '{ "messages": [{ "role": "user", "content": "What can you do?" }] }'
```

You can start editing the API by modifying `app/api/routers/chat.py` or `app/financial_report/workflow.py`. The API auto-updates as you save the files.

Open [http://localhost:8000/docs](http://localhost:8000/docs) with your browser to see the Swagger UI of the API.

The API allows CORS for all origins to simplify development. You can change this behavior by setting the `ENVIRONMENT` environment variable to `prod`:

```
ENVIRONMENT=prod poetry run python main.py
```

## Use Case: Filling Financial CSV Template

The project already includes the Apple and Tesla financial reports in the [data](./data) directory and a CSV template [sec_10k_template.csv](./sec_10k_template.csv).

You can upload the files to the app and ask it to fill the missing cells in the CSV file.

## Learn More

To learn more about LlamaIndex, take a look at the following resources:

- [LlamaIndex Documentation](https://docs.llamaindex.ai) - learn about LlamaIndex.
- [Workflows Introduction](https://docs.llamaindex.ai/en/stable/understanding/workflows/) - learn about LlamaIndex workflows.

You can check out [the LlamaIndex GitHub repository](https://github.com/run-llama/llama_index) - your feedback and contributions are welcome!
Loading
Loading