theRealNG commited on
Commit
c232c71
·
1 Parent(s): a5a5e0b

Refactored to suggest articles based on user insights

Browse files

- Added callback functions to the task to capture required info.

.gitignore CHANGED
@@ -1,5 +1,9 @@
1
  __pycache__/
2
- privacy_policy.pkl.tar.gz
3
  .env
4
  .DS_Store
5
  venv
 
 
 
 
 
 
1
  __pycache__/
 
2
  .env
3
  .DS_Store
4
  venv
5
+ article_suggestions.json
6
+ evaluated_articles.json
7
+ final_articles.json
8
+ learning_profile.json
9
+ pitched_articles.json
agents/learning_profiler.py CHANGED
@@ -6,7 +6,6 @@ learning_profiler = Agent(
6
  role="Personal Learning Profiler",
7
  goal="Make sure to create an excellent learning profile of the user based on his interests and previous reading history.",
8
  verbose=True,
9
- # tools=[scrape_tool],
10
  backstory=(
11
  "As a Personal Learning Profiler, you excel at building a learning profile of a user. "
12
  "The profile you build gives a high level overview of what interests that the user has. "
 
6
  role="Personal Learning Profiler",
7
  goal="Make sure to create an excellent learning profile of the user based on his interests and previous reading history.",
8
  verbose=True,
 
9
  backstory=(
10
  "As a Personal Learning Profiler, you excel at building a learning profile of a user. "
11
  "The profile you build gives a high level overview of what interests that the user has. "
app.py CHANGED
@@ -2,6 +2,10 @@ from dotenv import load_dotenv
2
  load_dotenv()
3
 
4
  from crew.article_suggestion import article_recommendation_crew
 
 
 
 
5
 
6
  result = article_recommendation_crew.kickoff(inputs={
7
  "interests": "Ruby On Rails, Architecture, Go Lang",
@@ -23,3 +27,5 @@ result = article_recommendation_crew.kickoff(inputs={
23
 
24
  print(result)
25
  print("Usage Metrics:\n", article_recommendation_crew.usage_metrics)
 
 
 
2
  load_dotenv()
3
 
4
  from crew.article_suggestion import article_recommendation_crew
5
+ import utils.settings as settings
6
+ from utils.write_to_json import write_dict_to_json as write_dict_to_json
7
+
8
+ settings.init()
9
 
10
  result = article_recommendation_crew.kickoff(inputs={
11
  "interests": "Ruby On Rails, Architecture, Go Lang",
 
27
 
28
  print(result)
29
  print("Usage Metrics:\n", article_recommendation_crew.usage_metrics)
30
+
31
+ write_dict_to_json(settings.articles, filename="final_articles.json")
crew/article_suggestion.py CHANGED
@@ -23,12 +23,4 @@ article_recommendation_crew = Crew(
23
  "model": 'text-embedding-3-small'
24
  }
25
  }
26
- # embedder={
27
- # "provider": "google",
28
- # "config":{
29
- # "model": 'models/embedding-001',
30
- # "task_type": "retrieval_document",
31
- # "title": "Embeddings for Embedchain"
32
- # }
33
- # }
34
  )
 
23
  "model": 'text-embedding-3-small'
24
  }
25
  }
 
 
 
 
 
 
 
 
26
  )
tasks/create_article_pitch.py CHANGED
@@ -1,20 +1,45 @@
1
  from crewai import Task
2
  from agents.curiosity_catalyst import curiosity_catalyst
3
  from tools.scrape_website import scrape_tool
4
- from utils.recommended_article import RecommendedArticles
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  article_pitch_task = Task(
7
- description=(
8
- "Create a pitch only for the articles that have passed evaluation and none other links. "
9
- "Craft the pitch so to that it teases the article's most intriguing aspects, "
10
- "by posing questions that the article might answer or "
11
- "highlighting surprising facts to pique the user's curiosity "
12
- " to read the article for incremental learning."
13
- ),
14
- expected_output=(
15
- "List of all the artilces that have passed evaluation phase."
16
- ),
17
- output_json=RecommendedArticles,
18
- tools=[scrape_tool],
19
- agent=curiosity_catalyst
 
 
 
20
  )
 
1
  from crewai import Task
2
  from agents.curiosity_catalyst import curiosity_catalyst
3
  from tools.scrape_website import scrape_tool
4
+ from crewai.tasks.task_output import TaskOutput
5
+ import utils.settings as settings
6
+ from pydantic import BaseModel
7
+ from typing import List
8
+ import json
9
+
10
+
11
+ class PitchedArticle(BaseModel):
12
+ title: str
13
+ url: str
14
+ pitch: str
15
+
16
+
17
+ class PitchedArticles(BaseModel):
18
+ articles: List[PitchedArticle]
19
+
20
+
21
+ def callback_function(output: TaskOutput):
22
+ evaluated_articles = json.loads(output.exported_output)['articles']
23
+
24
+ for article in evaluated_articles:
25
+ settings.articles[article['url']]['pitch'] = article['pitch']
26
+
27
 
28
  article_pitch_task = Task(
29
+ description=(
30
+ "Create a pitch only for the articles that have passed evaluation and no other links. "
31
+ "Craft the pitch so to that it teases the article's most intriguing aspects, "
32
+ "by posing questions that the article might answer or "
33
+ "highlighting surprising facts to pique the user's curiosity "
34
+ " to read the article for incremental learning."
35
+ ),
36
+ expected_output=(
37
+ "List of all the artilces that have passed evaluation phase along with their url and pitch statement."
38
+ ),
39
+ output_json=PitchedArticles,
40
+ output_file="pitched_articles.json",
41
+ tools=[scrape_tool],
42
+ agent=curiosity_catalyst,
43
+ async_execution=False,
44
+ callback=callback_function,
45
  )
tasks/create_learning_profile.py CHANGED
@@ -1,25 +1,31 @@
1
  from crewai import Task
2
  from agents.learning_profiler import learning_profiler
3
- from utils.learning_profile import LearningProfile
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  learning_profile_task = Task(
6
  description=(
7
- # "Create a Learning profile of the user based on his following interests {interests} "
8
- # "and based on the following articles and insights he has read in the past: \n"
9
- # "{previous_article_insights}"
10
  "Create a Learning profile of the user based on "
11
  "the following articles and insights he has read in the past: \n"
12
  "{previous_article_insights}"
13
  ),
14
  expected_output=(
15
  "A structured learning profile of the user with his interests, topics he has read about "
16
- "and any other information you feel is relavant. Be precise."
17
- # "A structured learning profile. "
18
- # "The learning profile should only contain a section called 'Topics of interest' and 'Insights'. "
19
- # "It should not have any other sections such as summary or conclusion. "
20
- # "'Insights' section should contain the insights captured by the user and they should be grouped by topic."
21
  ),
22
  agent=learning_profiler,
23
  output_json=LearningProfile,
 
24
  async_execution=False
25
  )
 
1
  from crewai import Task
2
  from agents.learning_profiler import learning_profiler
3
+ from pydantic import BaseModel
4
+ from typing import List
5
+
6
+
7
+ class Topic(BaseModel):
8
+ name: str
9
+ insights: List[str]
10
+
11
+
12
+ class LearningProfile(BaseModel):
13
+ topics_of_interests: List[str]
14
+ learnings: List[Topic]
15
+
16
 
17
  learning_profile_task = Task(
18
  description=(
 
 
 
19
  "Create a Learning profile of the user based on "
20
  "the following articles and insights he has read in the past: \n"
21
  "{previous_article_insights}"
22
  ),
23
  expected_output=(
24
  "A structured learning profile of the user with his interests, topics he has read about "
25
+ "and insights he has captured on the topics."
 
 
 
 
26
  ),
27
  agent=learning_profiler,
28
  output_json=LearningProfile,
29
+ output_file="learning_profile.json",
30
  async_execution=False
31
  )
tasks/evaluate_articles.py CHANGED
@@ -1,15 +1,48 @@
1
  from crewai import Task
2
  from agents.article_evaluator import article_evaluator
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  evaluation_task = Task(
5
- description=(
6
- "Evaluate articles to ensure that they provide incremental learning for the user "
7
- "based on his interests and previous article summaries he has captured."
8
- ),
9
- expected_output=(
10
- "List of article titles along with their links and evaluation reason of why you "
11
- "think the article is a good recommendation for the user."
12
- ),
13
- agent=article_evaluator,
14
- async_execution=False
 
 
 
 
 
 
15
  )
 
1
  from crewai import Task
2
  from agents.article_evaluator import article_evaluator
3
+ from crewai.tasks.task_output import TaskOutput
4
+ import utils.settings as settings
5
+ from pydantic import BaseModel
6
+ from typing import List
7
+ import json
8
+
9
+
10
+ class EvaluatedArticle(BaseModel):
11
+ title: str
12
+ url: str
13
+ evaluation_score: int
14
+ evaluation_reason: str
15
+
16
+
17
+ class EvaluatedArticles(BaseModel):
18
+ articles: List[EvaluatedArticle]
19
+
20
+
21
+ def callback_function(output: TaskOutput):
22
+ evaluated_articles = json.loads(output.exported_output)['articles']
23
+
24
+ for article in evaluated_articles:
25
+ settings.articles[article['url']
26
+ ]['evaluation_score'] = article['evaluation_score']
27
+ settings.articles[article['url']
28
+ ]['evaluation_reason'] = article['evaluation_reason']
29
+
30
 
31
  evaluation_task = Task(
32
+ description=(
33
+ "Evaluate artilces based on the metric does the articles provide incremenrtal "
34
+ "learning w.r.t the insights captured by the user. "
35
+ "Score the articles on the scale of 1 to 10, "
36
+ "1 being doesn't provide incremental learning and "
37
+ "10 being provides incremental learning to the user."
38
+ ),
39
+ expected_output=(
40
+ "List of article titles along with their links, evaluation score and "
41
+ "evaluation reason w.r.t to insights captured by the user."
42
+ ),
43
+ output_json=EvaluatedArticles,
44
+ output_file="evaluated_articles.json",
45
+ agent=article_evaluator,
46
+ async_execution=False,
47
+ callback=callback_function,
48
  )
tasks/new_article_suggestion.py CHANGED
@@ -1,14 +1,40 @@
1
  from crewai import Task
2
  from agents.learning_curator import learning_curator
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  article_suggestion_task = Task(
5
- description=(
6
- "Suggest 5 recent articles (i.e published in last 10 days ) to the user based on his learning profile. "
7
- "The articles should provide incremental learning to the user."
8
- ),
9
- expected_output=(
10
- "List of article titles along with their links"
11
- ),
12
- agent=learning_curator,
13
- async_execution=False
 
 
 
14
  )
 
1
  from crewai import Task
2
  from agents.learning_curator import learning_curator
3
+ from crewai.tasks.task_output import TaskOutput
4
+ import utils.settings as settings
5
+ from pydantic import BaseModel
6
+ from typing import List
7
+ import json
8
+
9
+
10
+ class SuggestedArticle(BaseModel):
11
+ title: str
12
+ url: str
13
+ reason_for_recommendation: str
14
+
15
+
16
+ class SuggestedArticles(BaseModel):
17
+ articles: List[SuggestedArticle]
18
+
19
+
20
+ def callback_function(output: TaskOutput):
21
+ suggested_articles = json.loads(output.exported_output)['articles']
22
+
23
+ for article in suggested_articles:
24
+ settings.articles[article['url']] = article
25
+
26
 
27
  article_suggestion_task = Task(
28
+ description=(
29
+ "Find 5 articles from the past 10 days that align with the user's learning interests. "
30
+ "The articles should provide incremental learning to the user based on their insights."
31
+ ),
32
+ expected_output=(
33
+ "List of article titles along with their links. "
34
+ ),
35
+ output_json=SuggestedArticles,
36
+ output_file="article_suggestions.json",
37
+ agent=learning_curator,
38
+ async_execution=False,
39
+ callback=callback_function,
40
  )
utils/learning_profile.py DELETED
@@ -1,12 +0,0 @@
1
- from pydantic import BaseModel
2
- from typing import List
3
-
4
-
5
- class Topic(BaseModel):
6
- name: str
7
- insights: List[str]
8
-
9
-
10
- class LearningProfile(BaseModel):
11
- topics_of_interests: List[str]
12
- learnings: List[Topic]
 
 
 
 
 
 
 
 
 
 
 
 
 
utils/recommended_article.py DELETED
@@ -1,11 +0,0 @@
1
- from pydantic import BaseModel
2
- from typing import List
3
-
4
- class RecommendedArticle(BaseModel):
5
- title: str
6
- url: str
7
- pitch: str
8
- reason_for_recommendation: str
9
-
10
- class RecommendedArticles(BaseModel):
11
- articles: List[RecommendedArticle]
 
 
 
 
 
 
 
 
 
 
 
 
utils/settings.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ def init():
2
+ global articles
3
+ articles = {}
utils/write_to_json.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+
3
+ def write_dict_to_json(data, filename="data.json", indent=4):
4
+ try:
5
+ with open(filename, 'w') as json_file:
6
+ json.dump(data, json_file, indent=indent)
7
+ print(f"Successfully wrote dictionary to {filename}")
8
+ except (IOError, json.JSONDecodeError) as e:
9
+ print(f"Error writing to JSON file: {e}")