Skip to content

Commit 3ad6599

Browse files
pkarwgrabbou
andauthored
feat: github trending vector + fixes (#81)
Co-authored-by: Mike Grabowski <[email protected]>
1 parent b7e9188 commit 3ad6599

File tree

8 files changed

+312
-36
lines changed

8 files changed

+312
-36
lines changed

example/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ Scrapes and analyzes trending Python projects from GitHub, creating a markdown s
5656

5757
**Actors:** Github Researcher, Redactor
5858

59+
## 📈 GitHub Trending with Vector Store
60+
61+
> `src/github_trending_vector.ts`
62+
63+
Scrapes and analyzes trending Typescript projects from GitHub. Then: asks user about which project he/she wants top learn more - and creates a markdown summary report.
64+
65+
**Actors:** Github Researcher, Redactor
66+
5967
## Running
6068

6169
Each example is a self-contained TypeScript file that can be run with Bun, or with `tsx`

example/src/github_trending.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import { agent } from '@dead-simple-ai-agent/framework/agent'
2-
import { teamwork } from '@dead-simple-ai-agent/framework/teamwork'
3-
import { logger } from '@dead-simple-ai-agent/framework/telemetry'
4-
import { solution, workflow } from '@dead-simple-ai-agent/framework/workflow'
1+
import { createFireCrawlTool } from '@fabrice-ai/tools/firecrawl'
52
import { getApiKey } from '@fabrice-ai/tools/utils'
6-
7-
import { createFireCrawlTool } from './tools/firecrawlScrape.js'
3+
import { agent } from 'fabrice-ai/agent'
4+
import { teamwork } from 'fabrice-ai/teamwork'
5+
import { logger } from 'fabrice-ai/telemetry'
6+
import { solution, workflow } from 'fabrice-ai/workflow'
87

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

11-
const { firecrawlScrape } = createFireCrawlTool({
10+
const { firecrawl } = createFireCrawlTool({
1211
apiKey,
1312
})
1413

@@ -18,7 +17,7 @@ const githubResearcher = agent({
1817
You are skilled at browsing what's hot on Github trending page.
1918
`,
2019
tools: {
21-
firecrawlScrape,
20+
firecrawl,
2221
},
2322
})
2423

example/src/github_trending_vector.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { createFireCrawlTool } from '@fabrice-ai/tools/firecrawl'
2+
import { getApiKey } from '@fabrice-ai/tools/utils'
3+
import { createVectorStoreTools } from '@fabrice-ai/tools/vector'
4+
import { agent } from 'fabrice-ai/agent'
5+
import { teamwork } from 'fabrice-ai/teamwork'
6+
import { logger } from 'fabrice-ai/telemetry'
7+
import { tool } from 'fabrice-ai/tool'
8+
import { solution, workflow } from 'fabrice-ai/workflow'
9+
import { z } from 'zod'
10+
11+
import { askUser } from './tools/askUser.js'
12+
13+
const apiKey = await getApiKey('Firecrawl.dev API Key', 'FIRECRAWL_API_KEY')
14+
15+
const printTool = tool({
16+
description: 'Display information to the user',
17+
parameters: z.object({
18+
message: z.string().describe('The information to be displayed'),
19+
}),
20+
execute: async ({ message }) => {
21+
console.log(message)
22+
return ''
23+
},
24+
})
25+
26+
const { saveDocumentInVectorStore, searchInVectorStore } = createVectorStoreTools()
27+
28+
const { firecrawl } = createFireCrawlTool({
29+
apiKey,
30+
})
31+
32+
const githubResearcher = agent({
33+
role: 'Github Researcher',
34+
description: `
35+
You are skilled at browsing what's hot on Github trending page.
36+
You are saving the documents to vector store for later usage
37+
`,
38+
tools: {
39+
firecrawl,
40+
saveDocumentInVectorStore,
41+
},
42+
})
43+
44+
const wrapupRedactor = agent({
45+
role: 'Redactor',
46+
description: `
47+
Your role is to wrap up reports.
48+
You ask users for which topic to focus on if it's defined in the task.
49+
You're famous of beautiful Markdown formatting.
50+
`,
51+
tools: {
52+
printTool,
53+
askUser,
54+
searchInVectorStore,
55+
},
56+
})
57+
58+
const wrapUpTrending = workflow({
59+
members: [githubResearcher, wrapupRedactor],
60+
description: `
61+
Research the URL "https://github.com/trending/typescript" page using scraper tool
62+
Get 3 top projects. You can get the title and description from the project page.
63+
Then summarize it all into a comprehensive report markdown output.
64+
65+
Ask user about which project he wants to learn more.
66+
Search for the project in the vector store and provide more details in the report.
67+
68+
Here are some ground rules to follow:
69+
- Include one sentence summary for each project.
70+
- Print the list of projects to the user.
71+
- Ask user about which project he wants to learn more.
72+
- Display more information about this specific project from the vector store.
73+
`,
74+
output: `
75+
Comprehensive markdown report with the top trending Typescript projects.
76+
Detailed report about the project selected by the user.
77+
`,
78+
snapshot: logger,
79+
})
80+
81+
const result = await teamwork(wrapUpTrending)
82+
83+
console.log(solution(result))

example/src/medical_survey/workflow.ts

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,8 @@
11
import { agent } from 'fabrice-ai/agent'
2-
import { tool } from 'fabrice-ai/tool'
32
import { workflow } from 'fabrice-ai/workflow'
4-
import { z } from 'zod'
53

6-
async function requestUserInput(prompt: string): Promise<string> {
7-
return new Promise((resolve) => {
8-
console.log('❔' + prompt)
9-
process.stdin.resume()
10-
process.stdin.once('data', (data) => {
11-
process.stdin.pause()
12-
resolve(data.toString().trim())
13-
})
14-
})
15-
}
4+
import { askUser } from '../tools/askUser.js'
165

17-
const askPatient = tool({
18-
description: 'Tool for asking patient a question',
19-
parameters: z.object({
20-
query: z.string().describe('The question to ask the patient'),
21-
}),
22-
execute: ({ query }): Promise<string> => {
23-
return requestUserInput(query)
24-
},
25-
})
266

277
const nurse = agent({
288
role: 'Nurse',
@@ -33,7 +13,7 @@ const nurse = agent({
3313
Ask one question at time up to 5 questions.
3414
`,
3515
tools: {
36-
askPatient,
16+
askPatient: askUser,
3717
},
3818
})
3919

example/src/tools/askUser.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { tool } from 'fabrice-ai/tool'
2+
import { z } from 'zod'
3+
4+
async function requestUserInput(prompt: string): Promise<string> {
5+
return new Promise((resolve) => {
6+
console.log('❔' + prompt)
7+
process.stdin.resume()
8+
process.stdin.once('data', (data) => {
9+
process.stdin.pause()
10+
resolve(data.toString().trim())
11+
})
12+
})
13+
}
14+
15+
export const askUser = tool({
16+
description: 'Tool for asking user a question',
17+
parameters: z.object({
18+
query: z.string().describe('The question to ask the user'),
19+
}),
20+
execute: ({ query }): Promise<string> => {
21+
return requestUserInput(query)
22+
},
23+
})

packages/create-fabrice-ai/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ const template = await select({
100100
},
101101
{
102102
value: {
103-
files: ['src/github_trending.ts', 'src/tools/firecrawlScrape.ts'],
103+
files: ['src/github_trending.ts', 'src/tools/firecrawl.ts'],
104104
},
105105
label: 'GitHub Trending - Track and summarize hot Python projects on GitHub',
106106
},

packages/tools/README.md

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,189 @@
11
@fabrice-ai/tools
22
====
33

4+
## 📅 Get Current Date
5+
6+
> `packages/tools/src/date.ts`
7+
8+
Retrieves the current date in ISO format.
9+
10+
### Example
11+
```typescript
12+
import { getCurrentDate } from '@fabrice-ai/tools/date'
13+
14+
const exampleAgent = agent({
15+
role: '...',
16+
description: '...',
17+
tools: {
18+
getCurrentDate,
19+
},
20+
})
21+
```
22+
23+
## 🔍 Google Search with Serply.io
24+
25+
> `packages/tools/src/webSearch.ts`
26+
27+
Performs a Google search with a search query using the Serply API.
28+
29+
### Example
30+
```typescript
31+
import { createWebSearchTools } from '@fabrice-ai/tools/webSearch'
32+
33+
const apiKey = 'your-serply-api-key'
34+
const { googleSearch } = createWebSearchTools({ apiKey })
35+
36+
const exampleAgent = agent({
37+
role: '...',
38+
description: '...',
39+
tools: {
40+
googleSearch,
41+
},
42+
})
43+
```
44+
45+
## 🖼️ Google Image Search
46+
47+
> `packages/tools/src/webSearch.ts`
48+
49+
Performs a Google Image search with a search query using the Serply API.
50+
51+
### Example
52+
```typescript
53+
import { createWebSearchTools } from '@fabrice-ai/tools/webSearch'
54+
55+
const apiKey = 'your-serply-api-key'
56+
const { googleImageSearch } = createWebSearchTools({ apiKey })
57+
58+
const exampleAgent = agent({
59+
role: '...',
60+
description: '...',
61+
tools: {
62+
googleImageSearch,
63+
},
64+
})
65+
```
66+
67+
## 🌐 Web Scraper
68+
69+
> `packages/tools/src/firecrawl.ts`
70+
71+
Scrapes a website using Firecrawl.dev to extract metadata and content.
72+
73+
### Example
74+
```typescript
75+
import { createFireCrawlTool } from '@fabrice-ai/tools/firecrawl'
76+
77+
const exampleAgent = agent({
78+
role: '...',
79+
description: '...',
80+
tools: {
81+
createFireCrawlTool({
82+
apiKey: 'Firecrawl API key ...'
83+
}),
84+
},
85+
})
86+
```
87+
88+
## 🫙 Vector Store
89+
90+
> `packages/tools/src/vector.ts`
91+
92+
Save documents with embeddings, perform vector search.
93+
94+
### Example
95+
```typescript
96+
import { createVectorStoreTools } from '@fabrice-ai/tools/vector'
97+
98+
const { saveDocumentInVectorStore, searchInVectorStore } = createVectorStoreTools()
99+
100+
const exampleAgent = agent({
101+
role: '...',
102+
description: '...',
103+
tools: {
104+
saveDocumentInVectorStore,
105+
searchInVectorStore
106+
},
107+
})
108+
```
109+
110+
### Example with custom VectorStore
111+
```typescript
112+
import { createVectorStoreTools } from '@fabrice-ai/tools/vector'
113+
114+
/**
115+
* createVectorStore accepts a `vectorStore` adapter.
116+
* This is a way to switch the default - in-memory store to Pinecone or others of your choice.
117+
*/
118+
const createPineconeVectorStore = () => {
119+
const store = new Map<string, EmbeddingResult>()
120+
121+
const set = async (id: string, value: EmbeddingResult): Promise<void> => {
122+
// @tbd: implement storing document in Pinecone
123+
}
124+
125+
const entries = async (): Promise<[string, EmbeddingResult][]> => {
126+
// @tbd: implement searching documents in Pinecone
127+
}
128+
129+
return {
130+
set,
131+
entries,
132+
}
133+
}
134+
135+
const { saveDocumentInVectorStore, searchInVectorStore } = createVectorStoreTools(createPineconeVectorStore())
136+
137+
const exampleAgent = agent({
138+
role: '...',
139+
description: '...',
140+
tools: {
141+
saveDocumentInVectorStore,
142+
searchInVectorStore
143+
},
144+
})
145+
```
146+
147+
## 🖼️ Vision tool
148+
149+
> `packages/tools/src/vision.ts`
150+
151+
Uses LLM as a OCR / Vision tool. Extract text or features from a picture.
152+
153+
### Example
154+
```typescript
155+
import { visionTool } from '@fabrice-ai/tools/vision'
156+
157+
const exampleAgent = agent({
158+
role: '...',
159+
description: '...',
160+
tools: {
161+
visionTool
162+
},
163+
})
164+
```
165+
166+
## 🗄️ FileSystem tools
167+
168+
> `packages/tools/src/filesystem.ts`
169+
170+
File system tools for reading, writing and listing files. The tools are sandboxed into `workingDir` for safety.
171+
172+
### Example
173+
```typescript
174+
import { createFileSystemTools } from '@fabrice-ai/tools/filesystem'
175+
176+
const workingDir = path.resolve(__dirname, '../assets/')
177+
178+
const { saveFile, readFile, listFilesFromDirectory } = createFileSystemTools({
179+
workingDir,
180+
})
181+
182+
const exampleAgent = agent({
183+
role: '...',
184+
description: '...',
185+
tools: {
186+
visionTool
187+
},
188+
})
189+
```

0 commit comments

Comments
 (0)