Skip to content
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

refactor: rewrite underlying architecture of the framework to recursive object #105

Merged
merged 22 commits into from
Dec 12, 2024
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
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,16 @@ import { solution, workflow } from 'fabrice-ai/workflow'
import { lookupWikipedia } from './tools/wikipedia.js'

const activityPlanner = agent({
role: 'Activity Planner',
description: `You are skilled at creating personalized itineraries...`,
})

const landmarkScout = agent({
role: 'Landmark Scout',
description: `You research interesting landmarks...`,
tools: { lookupWikipedia },
})

const workflow = workflow({
members: [activityPlanner, landmarkScout],
team: { activityPlanner, landmarkScout },
description: `Plan a trip to Wrocław, Poland...`,
})

Expand Down Expand Up @@ -129,16 +127,15 @@ const state = await teamwork(workflow)

#### Server-side Teamwork

The server-side version of teamwork is perfectly suited for long-running workflows that require external tool execution or manual intervention. It will not wait for the tool to be executed, but will return the state of the workflow.
We provide a server-side version of `teamwork` that is perfectly suited for long-running workflows that require external tool execution or manual intervention. It will not wait for the tool to be executed, but will return the state of the workflow.

You can then handle tool calls on your own, and call `teamwork` again when ready.

```typescript
import { teamwork } from 'fabrice-ai/server'
import { teamwork } from 'fabrice-ai/teamwork'

// If status is `assigned`, you need to handle tool calls on your own.
// Otherwise, status is `finished` and you can read the result.
const nextState = await teamwork(workflow)
// Setting third argumenet to `false` will stop waiting for the tool to be executed.
const nextState = await teamwork(workflow, prevState, false)
```

This pattern is especially useful for:
Expand Down
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Researches and summarizes the top news from the past week into a comprehensive r

> `src/github_trending.ts`
Scrapes and analyzes trending Python projects from GitHub, creating a markdown summary report.
Scrapes and analyzes trending Typescript projects from GitHub, creating a markdown summary report.

**Actors:** Github Researcher, Redactor

Expand Down
7 changes: 3 additions & 4 deletions example/src/ecommerce_product_description.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { visionTool } from '@fabrice-ai/tools/vision'
import { agent } from 'fabrice-ai/agent'
import { solution } from 'fabrice-ai/solution'
import { teamwork } from 'fabrice-ai/teamwork'
import { logger } from 'fabrice-ai/telemetry'
import { solution, workflow } from 'fabrice-ai/workflow'
import { workflow } from 'fabrice-ai/workflow'
import path from 'path'

const techExpert = agent({
role: 'Technical expert',
description: `
You are skilled at extracting and describing most detailed
technical information about the product from the photo.
Expand All @@ -17,7 +17,6 @@ const techExpert = agent({
})

const marketingManager = agent({
role: 'Marketing content writer',
description: `
You are skilled at writing catchy product descriptions
making customers to instantly fall in love with the product.
Expand All @@ -26,7 +25,7 @@ const marketingManager = agent({
})

const productDescriptionWorkflow = workflow({
members: [techExpert, marketingManager],
team: { techExpert, marketingManager },
description: `
Based on the picture '${path.resolve(import.meta.dirname, '../assets/example-sneakers.jpg')}' make the eCommerce product to
list this product on the website.
Expand Down
17 changes: 8 additions & 9 deletions example/src/github_trending.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { createFireCrawlTool } from '@fabrice-ai/tools/firecrawl'
import { getApiKey } from '@fabrice-ai/tools/utils'
import { agent } from 'fabrice-ai/agent'
import { solution } from 'fabrice-ai/solution'
import { teamwork } from 'fabrice-ai/teamwork'
import { logger } from 'fabrice-ai/telemetry'
import { solution, workflow } from 'fabrice-ai/workflow'
import { workflow } from 'fabrice-ai/workflow'

const apiKey = await getApiKey('Firecrawl.dev API Key', 'FIRECRAWL_API_KEY')

Expand All @@ -12,7 +13,6 @@ const { firecrawl } = createFireCrawlTool({
})

const githubResearcher = agent({
role: 'Github Researcher',
description: `
You are skilled at browsing what's hot on Github trending page.
`,
Expand All @@ -22,25 +22,24 @@ const githubResearcher = agent({
})

const wrapupRedactor = agent({
role: 'Redactor',
description: `
Your role is to wrap up reports.
Your role is to compile and summarize information.
You're great at creating a wrap-up reports.
You're famous of beautiful Markdown formatting.
`,
})

const wrapUpTrending = workflow({
members: [githubResearcher, wrapupRedactor],
team: { githubResearcher, wrapupRedactor },
description: `
Research the URL "https://github.com/trending/python" page using scraper tool
Get 3 top projects. You can get the title and description from the project page.
Then summarize it all into a comprehensive report markdown output.
Research the URL "https://github.com/trending/typescript" page using firecrawl tool
Summarize information about 3 top projects into a comprehensive report markdown output.

Here are some ground rules to follow:
- Include one sentence summary for each project.
`,
output: `
Comprehensive markdown report with the top trending python projects.
Comprehensive markdown report with the top trending typescript projects.
`,
snapshot: logger,
})
Expand Down
48 changes: 19 additions & 29 deletions example/src/github_trending_vector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,28 @@ import { createFireCrawlTool } from '@fabrice-ai/tools/firecrawl'
import { getApiKey } from '@fabrice-ai/tools/utils'
import { createVectorStoreTools } from '@fabrice-ai/tools/vector'
import { agent } from 'fabrice-ai/agent'
import { solution } from 'fabrice-ai/solution'
import { teamwork } from 'fabrice-ai/teamwork'
import { logger } from 'fabrice-ai/telemetry'
import { tool } from 'fabrice-ai/tool'
import { solution, workflow } from 'fabrice-ai/workflow'
import { workflow } from 'fabrice-ai/workflow'
import { z } from 'zod'

import { askUser } from './tools/askUser.js'

const apiKey = await getApiKey('Firecrawl.dev API Key', 'FIRECRAWL_API_KEY')

const printTool = tool({
description: 'Display information to the user',
parameters: z.object({
message: z.string().describe('The information to be displayed'),
}),
execute: async ({ message }) => {
console.log(message)
return ''
},
})

const { saveDocumentInVectorStore, searchInVectorStore } = createVectorStoreTools()

const { firecrawl } = createFireCrawlTool({
apiKey,
})

const githubResearcher = agent({
role: 'Github Researcher',
description: `
You are skilled at browsing what's hot on Github trending page.
You are saving the documents to vector store for later usage
You are skilled at browsing Github pages.
You are saving the documents to vector store for later usage.
You don't do any other thing just these two tasks.
`,
tools: {
firecrawl,
Expand All @@ -42,38 +32,38 @@ const githubResearcher = agent({
})

const wrapupRedactor = agent({
role: 'Redactor',
description: `
Your role is to wrap up reports.
You ask users for which topic to focus on if it's defined in the task.
Then - you search relevant information in Vector Store and compile reports based on it.
You're famous of beautiful Markdown formatting.
`,
tools: {
printTool,
askUser,
searchInVectorStore,
},
})

const wrapUpTrending = workflow({
members: [githubResearcher, wrapupRedactor],
team: { githubResearcher, wrapupRedactor },
description: `
Research the URL "https://github.com/trending/typescript" page using scraper tool
Get 3 top projects. You can get the title and description from the project page.
Then summarize it all into a comprehensive report markdown output.
Research the URL "https://github.com/trending/typescript" page using firecrawl tool
Select 3 top projects. Browse for details about these projects on their subpages.
Save it all to the vector store.

Ask user about which project he wants to learn more.
Search for the project in the vector store and provide more details in the report.
reate a comprehensive report markdown output:
- create a one, two sentence summary about every project.
- include detailed summary about the project selected by the user.

Here are some ground rules to follow:
- Include one sentence summary for each project.
- Print the list of projects to the user.
- Ask user about which project he wants to learn more.
- Display more information about this specific project from the vector store.
- Browser the pages onle once and store content in Vector Store.
- Use Vector Store if you need information about the project.
- Before making up the record: ask user about which project he wants to learn more.
`,
output: `
Comprehensive markdown report with the top trending Typescript projects.
Detailed report about the project selected by the user.
Comprehensive markdown report including:
- summary on top trending Typescript projects.
- detailed info about the project selected by the user.
`,
snapshot: logger,
})
Expand Down
7 changes: 3 additions & 4 deletions example/src/library_photo_to_website.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { createFileSystemTools } from '@fabrice-ai/tools/filesystem'
import { visionTool } from '@fabrice-ai/tools/vision'
import { agent } from 'fabrice-ai/agent'
import { solution } from 'fabrice-ai/solution'
import { teamwork } from 'fabrice-ai/teamwork'
import { logger } from 'fabrice-ai/telemetry'
import { solution, workflow } from 'fabrice-ai/workflow'
import { workflow } from 'fabrice-ai/workflow'
import path from 'path'

const workingDir = path.resolve(import.meta.dirname, '../assets/')
Expand All @@ -13,7 +14,6 @@ const { saveFile, readFile, listFilesFromDirectory } = createFileSystemTools({
})

const librarian = agent({
role: 'Librarian',
description: `
You are skilled at scanning and identifying books in the library.
When asked, you will analyze the photo of the library and list all the books that you see, in details.
Expand All @@ -24,7 +24,6 @@ const librarian = agent({
})

const webmaster = agent({
role: 'HTML Webmaster',
description: `
You are skilled at creating HTML pages.
You are good at using templates for creating HTML pages.
Expand All @@ -41,7 +40,7 @@ const imagePath = path.join(workingDir, 'photo-library.jpg')
const outputPath = path.join(workingDir, 'library.html')

const bookLibraryWorkflow = workflow({
members: [librarian, webmaster],
team: { librarian, webmaster },
description: `
Analyze the photo of the library and list all the books in the library.
Generate a website that lists all the books in the library.
Expand Down
2 changes: 1 addition & 1 deletion example/src/medical_survey.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { solution } from 'fabrice-ai/solution'
import { teamwork } from 'fabrice-ai/teamwork'
import { solution } from 'fabrice-ai/workflow'

import { preVisitNoteWorkflow } from './medical_survey/workflow.js'

Expand Down
5 changes: 1 addition & 4 deletions example/src/medical_survey/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import { workflow } from 'fabrice-ai/workflow'

import { askUser } from '../tools/askUser.js'


const nurse = agent({
role: 'Nurse',
description: `
You are skille nurse / doctor assistant.
You role is to cooperate with reporter to create a pre-visit note for a patient that is about to come for a visit.
Expand All @@ -18,7 +16,6 @@ const nurse = agent({
})

const reporter = agent({
role: 'Reporter',
description: `
You are skilled at preparing great looking reports.
You can prepare a report for a patient that is about to come for a visit.
Expand All @@ -27,7 +24,7 @@ const reporter = agent({
})

export const preVisitNoteWorkflow = workflow({
members: [nurse, reporter],
team: { nurse, reporter },
description: `
Create a pre-visit note for a patient that is about to come for a visit.
The note should include the patient's health and symptoms.
Expand Down
Loading