subashpoudel commited on
Commit
11bd168
·
1 Parent(s): 7a3f093

Next Commit

Browse files
.gitignore CHANGED
@@ -1,4 +1,5 @@
1
  .env
2
  myenv
3
  *.pyc
4
- __pycache__/
 
 
1
  .env
2
  myenv
3
  *.pyc
4
+ __pycache__/
5
+ logs
api/__pycache__/stored_data.cpython-313.pyc CHANGED
Binary files a/api/__pycache__/stored_data.cpython-313.pyc and b/api/__pycache__/stored_data.cpython-313.pyc differ
 
api/routers/ideation.py CHANGED
@@ -22,12 +22,10 @@ def ideation_endpoint():
22
  'image_caption': [stored_data['image_caption'] if 'image_caption' in stored_data else ""]
23
  },
24
  config=config)
25
-
26
- stored_data['final_ideation'] = result['top_4_ideas'][-1]
27
  # stored_data['final_ideation']=ast.literal_eval(stored_data['final_ideation'])
28
  app_logger.info('Executed the ideation pipeline.')
29
-
30
- return {'response':result['top_4_ideas'][-1]}
31
 
32
  except GraphRecursionError:
33
  error_logger.error('Ideation loop ran more than specified.')
 
22
  'image_caption': [stored_data['image_caption'] if 'image_caption' in stored_data else ""]
23
  },
24
  config=config)
25
+ stored_data['final_ideation'] = result['unique_selected_ideas'][-1]
 
26
  # stored_data['final_ideation']=ast.literal_eval(stored_data['final_ideation'])
27
  app_logger.info('Executed the ideation pipeline.')
28
+ return {'response':result['unique_selected_ideas'][-1]}
 
29
 
30
  except GraphRecursionError:
31
  error_logger.error('Ideation loop ran more than specified.')
api/stored_data.py CHANGED
@@ -1,12 +1,13 @@
1
  stored_data = {}
2
  stored_data['business_details'] = {
3
- "business_type": "fitness and gym",
4
  "platform": "Instagram, TikTok",
5
- "target_audience": "young Nepali adults (ages 18–40) who are health-conscious and active on social media",
6
- "business_goals": "to expand gym branches across all major cities of Nepal and build a strong fitness community",
7
- "offerings": "personal training, group fitness classes, modern workout equipment, nutrition guidance, and wellness programs",
8
- "Challenges_faced": "attracting loyal members, standing out in a competitive market, and promoting consistent engagement"
9
  }
 
10
  stored_data['human_ideation_interactions'] = []
11
  stored_data['brainstorming_response']={}
12
  stored_data['context_analysis_interactions']= []
 
1
  stored_data = {}
2
  stored_data['business_details'] = {
3
+ "business_type": "skin care products",
4
  "platform": "Instagram, TikTok",
5
+ "target_audience": "women and men (ages 18–50) who are conscious about their skin health and beauty",
6
+ "business_goals": "to build a trusted skin care brand, increase online sales, and educate customers on proper skin care routines",
7
+ "offerings": "natural and dermatologically-tested products, personalized skin care solutions, beauty tips, and skin care routines",
8
+ "Challenges_faced": "building trust in a crowded skin care market, showcasing product effectiveness, and educating customers about skin types and product usage"
9
  }
10
+
11
  stored_data['human_ideation_interactions'] = []
12
  stored_data['brainstorming_response']={}
13
  stored_data['context_analysis_interactions']= []
logs/access.log CHANGED
@@ -541,3 +541,46 @@
541
  2025-08-25 12:16:33,281 | INFO | access_logger | api/main.py:21 | Response status: 200
542
  2025-08-25 12:16:43,062 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/context-analysis
543
  2025-08-25 12:16:46,807 | INFO | access_logger | api/main.py:21 | Response status: 200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
  2025-08-25 12:16:33,281 | INFO | access_logger | api/main.py:21 | Response status: 200
542
  2025-08-25 12:16:43,062 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/context-analysis
543
  2025-08-25 12:16:46,807 | INFO | access_logger | api/main.py:21 | Response status: 200
544
+ 2025-08-25 12:52:30,777 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/show-analytics
545
+ 2025-08-25 12:52:45,581 | INFO | access_logger | api/main.py:21 | Response status: 200
546
+ 2025-08-25 12:53:00,389 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/orchestration
547
+ 2025-08-25 12:53:08,107 | INFO | access_logger | api/main.py:21 | Response status: 200
548
+ 2025-08-25 12:53:19,947 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
549
+ 2025-08-25 12:54:05,043 | INFO | access_logger | api/main.py:21 | Response status: 200
550
+ 2025-08-25 13:16:54,126 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
551
+ 2025-08-25 13:17:37,033 | INFO | access_logger | api/main.py:21 | Response status: 200
552
+ 2025-08-25 13:24:41,862 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
553
+ 2025-08-25 13:25:12,518 | INFO | access_logger | api/main.py:21 | Response status: 200
554
+ 2025-08-25 13:29:19,484 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
555
+ 2025-08-25 13:29:57,835 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
556
+ 2025-08-25 13:30:31,506 | INFO | access_logger | api/main.py:21 | Response status: 200
557
+ 2025-08-26 14:42:31,442 | INFO | access_logger | api/main.py:19 | Request: GET http://127.0.0.1:8000/docs
558
+ 2025-08-26 14:42:31,442 | INFO | access_logger | api/main.py:21 | Response status: 200
559
+ 2025-08-26 14:42:32,078 | INFO | access_logger | api/main.py:19 | Request: GET http://127.0.0.1:8000/openapi.json
560
+ 2025-08-26 14:42:32,081 | INFO | access_logger | api/main.py:21 | Response status: 200
561
+ 2025-08-26 14:42:39,039 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
562
+ 2025-08-26 14:47:18,462 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
563
+ 2025-08-26 14:50:06,446 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
564
+ 2025-08-26 14:56:57,798 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
565
+ 2025-08-26 14:58:41,923 | INFO | access_logger | api/main.py:21 | Response status: 200
566
+ 2025-08-26 15:11:40,020 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
567
+ 2025-08-26 15:14:53,164 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
568
+ 2025-08-26 15:18:50,734 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
569
+ 2025-08-26 15:20:48,693 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
570
+ 2025-08-26 15:22:21,301 | INFO | access_logger | api/main.py:21 | Response status: 200
571
+ 2025-08-27 10:21:58,368 | INFO | access_logger | api/main.py:19 | Request: GET http://127.0.0.1:8000/docs
572
+ 2025-08-27 10:21:58,369 | INFO | access_logger | api/main.py:21 | Response status: 200
573
+ 2025-08-27 10:21:59,075 | INFO | access_logger | api/main.py:19 | Request: GET http://127.0.0.1:8000/openapi.json
574
+ 2025-08-27 10:21:59,080 | INFO | access_logger | api/main.py:21 | Response status: 200
575
+ 2025-08-27 10:22:05,353 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
576
+ 2025-08-27 10:25:15,988 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
577
+ 2025-08-27 10:28:15,482 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
578
+ 2025-08-27 10:29:09,048 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
579
+ 2025-08-27 10:30:02,388 | INFO | access_logger | api/main.py:21 | Response status: 200
580
+ 2025-08-27 10:40:30,415 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
581
+ 2025-08-27 10:41:32,280 | INFO | access_logger | api/main.py:21 | Response status: 200
582
+ 2025-08-27 11:03:20,374 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
583
+ 2025-08-27 11:04:05,119 | INFO | access_logger | api/main.py:21 | Response status: 200
584
+ 2025-08-27 11:05:29,333 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
585
+ 2025-08-27 11:28:14,943 | INFO | access_logger | api/main.py:19 | Request: POST http://127.0.0.1:8000/api/ideation
586
+ 2025-08-27 11:29:21,723 | INFO | access_logger | api/main.py:21 | Response status: 200
logs/app.log CHANGED
@@ -66,3 +66,16 @@
66
  2025-08-22 16:34:17,796 | INFO | app_logger | api\routers\context_analysis.py:27 | Executed context analysis agent
67
  2025-08-22 16:34:33,195 | INFO | app_logger | api\routers\context_analysis.py:27 | Executed context analysis agent
68
  2025-08-22 16:34:51,470 | INFO | app_logger | api\routers\context_analysis.py:27 | Executed context analysis agent
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  2025-08-22 16:34:17,796 | INFO | app_logger | api\routers\context_analysis.py:27 | Executed context analysis agent
67
  2025-08-22 16:34:33,195 | INFO | app_logger | api\routers\context_analysis.py:27 | Executed context analysis agent
68
  2025-08-22 16:34:51,470 | INFO | app_logger | api\routers\context_analysis.py:27 | Executed context analysis agent
69
+ 2025-08-25 12:52:45,580 | INFO | app_logger | api/routers/show_analytics.py:14 | Influencer Analytics returned by orchestrator.
70
+ 2025-08-25 12:53:08,106 | INFO | app_logger | api/routers/orchestration.py:20 | Orchestrator executed
71
+ 2025-08-25 12:54:05,041 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
72
+ 2025-08-25 13:17:37,031 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
73
+ 2025-08-25 13:25:12,517 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
74
+ 2025-08-25 13:30:31,505 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
75
+ 2025-08-26 14:58:41,922 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
76
+ 2025-08-26 15:20:15,882 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
77
+ 2025-08-26 15:22:21,301 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
78
+ 2025-08-27 10:30:02,386 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
79
+ 2025-08-27 10:41:32,280 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
80
+ 2025-08-27 11:04:05,117 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
81
+ 2025-08-27 11:29:21,721 | INFO | app_logger | api/routers/ideation.py:28 | Executed the ideation pipeline.
src/genai/ideation_agent/agent.py CHANGED
@@ -1,6 +1,6 @@
1
  from langgraph.graph import StateGraph, START, END , MessagesState
2
  from .utils.state import State
3
- from .utils.nodes import RetrieverNode, IdeatorNode , CriticNode , ValidatorNode , RoutingAfterValidation, JudgeNode1 , JudgeNode2, Aggregrator
4
  from langgraph.checkpoint.memory import MemorySaver
5
 
6
  class IdeationAgent:
@@ -12,6 +12,7 @@ class IdeationAgent:
12
  graph_builder.add_node("retriever", RetrieverNode().run)
13
  graph_builder.add_node("ideator", IdeatorNode().run)
14
  graph_builder.add_node("critic", CriticNode().run)
 
15
  graph_builder.add_node("judge1", JudgeNode1().run)
16
  graph_builder.add_node("judge2", JudgeNode2().run)
17
  graph_builder.add_node("aggregrator", Aggregrator().run)
@@ -20,16 +21,16 @@ class IdeationAgent:
20
  graph_builder.add_edge(START, "retriever")
21
  graph_builder.add_edge("retriever", "ideator")
22
  graph_builder.add_edge("ideator", "critic")
23
- graph_builder.add_edge("critic", "judge1")
24
- graph_builder.add_edge("critic", "judge2")
 
25
  graph_builder.add_edge("judge1", "aggregrator")
26
  graph_builder.add_edge("judge2", "aggregrator")
27
- graph_builder.add_edge("aggregrator", "validator")
28
- graph_builder.add_edge("validator", END)
29
 
30
 
31
- # Use conditional routing from validator
32
- graph_builder.add_conditional_edges("validator", RoutingAfterValidation().route,{False:'critic',True:END})
33
 
34
  return graph_builder.compile(checkpointer=self.memory)
35
 
 
1
  from langgraph.graph import StateGraph, START, END , MessagesState
2
  from .utils.state import State
3
+ from .utils.nodes import RetrieverNode, IdeatorNode , CriticNode ,NormalizerNode, ValidatorNode , RoutingAfterValidation, JudgeNode1 , JudgeNode2, Aggregrator
4
  from langgraph.checkpoint.memory import MemorySaver
5
 
6
  class IdeationAgent:
 
12
  graph_builder.add_node("retriever", RetrieverNode().run)
13
  graph_builder.add_node("ideator", IdeatorNode().run)
14
  graph_builder.add_node("critic", CriticNode().run)
15
+ graph_builder.add_node("normalizer",NormalizerNode().run)
16
  graph_builder.add_node("judge1", JudgeNode1().run)
17
  graph_builder.add_node("judge2", JudgeNode2().run)
18
  graph_builder.add_node("aggregrator", Aggregrator().run)
 
21
  graph_builder.add_edge(START, "retriever")
22
  graph_builder.add_edge("retriever", "ideator")
23
  graph_builder.add_edge("ideator", "critic")
24
+ graph_builder.add_edge("critic", "normalizer")
25
+ graph_builder.add_edge("normalizer", "judge1")
26
+ graph_builder.add_edge("normalizer","judge2")
27
  graph_builder.add_edge("judge1", "aggregrator")
28
  graph_builder.add_edge("judge2", "aggregrator")
29
+ graph_builder.add_edge("aggregrator", END)
30
+
31
 
32
 
33
+ # graph_builder.add_conditional_edges("validator", RoutingAfterValidation().route,{False:'critic',True:END})
 
34
 
35
  return graph_builder.compile(checkpointer=self.memory)
36
 
src/genai/ideation_agent/utils/nodes.py CHANGED
@@ -1,7 +1,7 @@
1
  from .state import State , ValidationFormatter , CriticResponseFormatter
2
  from .tools import Retrieval
3
  from langgraph.prebuilt import create_react_agent
4
- from src.genai.utils.models_loader import ideator_llm, critic_llm , improver_llm , validator_llm , judge1_llm , judge2_llm
5
  from langchain_core.messages import SystemMessage , HumanMessage, FunctionMessage
6
  from .prompts import ideator_prompt_v3 , critic_prompt_v3 , improver_prompt , validator_prompt, judge_prompt
7
  from .schemas import ideation_json_schema , judge_response_json_schema
@@ -24,11 +24,11 @@ class IdeatorNode:
24
  template = ideator_prompt_v3()
25
  messages = [SystemMessage(content=template),
26
  HumanMessage(content=f'''The business_details is\n{state.business_details[-1]}\n
27
- The information of the image is:\n{state.image_caption[-1]}'''),
28
- FunctionMessage(name='inf_data_ideator', content=f'''The data of influencers is:\n {state.influencers_data[-1]}\n''')]
29
- response = self.llm.with_structured_output(ideation_json_schema).invoke(messages)
30
- print('Ideator Response:', response)
31
- state.ideator_response.append(str(response))
32
  print('Ideator Node executed')
33
  return state
34
 
@@ -42,14 +42,26 @@ class CriticNode:
42
  messages = [SystemMessage(content=template),
43
  HumanMessage(content=f'''The ideas generated by ideator are:\n{state.ideator_response[-1]}\n.
44
  The business_details is\n{state.business_details[-1]}\n
45
- The information of the image is:\n{state.image_caption[-1]}'''),
46
- FunctionMessage(name='inf_data_critic', content=f'''The data of influencers is:\n {state.influencers_data[-1]}''')]
47
 
48
- response = self.llm.with_structured_output(ideation_json_schema).invoke(messages)
49
- state.critic_response.append(str(response))
 
50
  print('Critic Node executed')
51
  return state
52
 
 
 
 
 
 
 
 
 
 
 
 
53
  class Judge:
54
  def __init__(self, llm):
55
  self.llm = llm
@@ -57,7 +69,7 @@ class Judge:
57
  def run (self, state:State):
58
  template = judge_prompt(state)
59
  messages = [SystemMessage(content=template),
60
- HumanMessage(content=f'''The generated 10 ideas are:\n{state.critic_response[-1]}\n.
61
  The business_details is\n{state.business_details[-1]}\n
62
  The information of image is:{state.image_caption[-1]}\n''')]
63
  response = self.llm.with_structured_output(judge_response_json_schema).invoke(messages)
@@ -84,28 +96,35 @@ class Aggregrator:
84
  def __init__(self):
85
  self.unique_ideas = {}
86
 
87
- def run(self, state:State):
 
88
  all_selected_ideas = [
89
  *state.judge1_response[-1]['selected_ideas'],
90
  *state.judge2_response[-1]['selected_ideas']
91
  ]
92
 
 
 
 
93
  for idea in all_selected_ideas:
94
  title = idea['title']
95
- if title not in self.unique_ideas or idea['scores']['total_score'] > self.unique_ideas[title]['scores']['total_score']:
 
96
  self.unique_ideas[title] = idea
97
-
 
98
  unique_ideas_list = list(self.unique_ideas.values())
99
- top_4_ideas = sorted(unique_ideas_list, key=lambda x: x['scores']['total_score'], reverse=True)[:4]
100
- print('Type of top 4 ideas:', type(top_4_ideas))
101
- print('Top 4 ideas are:', top_4_ideas)
102
- state.top_4_ideas.append(top_4_ideas)
 
103
  return state
104
 
105
  class ValidatorNode:
106
  def __init__(self):
107
  self.validator_llm1 = validator_llm
108
- self.validator_llm2 = improver_llm
109
 
110
  def get_response(self,state, validator_llm):
111
  template = validator_prompt(state)
 
1
  from .state import State , ValidationFormatter , CriticResponseFormatter
2
  from .tools import Retrieval
3
  from langgraph.prebuilt import create_react_agent
4
+ from src.genai.utils.models_loader import ideator_llm, critic_llm , normalizer_llm , validator_llm , judge1_llm , judge2_llm
5
  from langchain_core.messages import SystemMessage , HumanMessage, FunctionMessage
6
  from .prompts import ideator_prompt_v3 , critic_prompt_v3 , improver_prompt , validator_prompt, judge_prompt
7
  from .schemas import ideation_json_schema , judge_response_json_schema
 
24
  template = ideator_prompt_v3()
25
  messages = [SystemMessage(content=template),
26
  HumanMessage(content=f'''The business_details is\n{state.business_details[-1]}\n
27
+ The information of the image is:\n{state.image_caption[-1]}'''),]
28
+ # FunctionMessage(name='inf_data_ideator', content=f'''The data of influencers is:\n {state.influencers_data[-1]}\n''')]
29
+ response = self.llm.invoke(messages)
30
+ print('Ideator Response:', response.content)
31
+ state.ideator_response.append(str(response.content))
32
  print('Ideator Node executed')
33
  return state
34
 
 
42
  messages = [SystemMessage(content=template),
43
  HumanMessage(content=f'''The ideas generated by ideator are:\n{state.ideator_response[-1]}\n.
44
  The business_details is\n{state.business_details[-1]}\n
45
+ The information of the image is:\n{state.image_caption[-1]}'''),]
46
+ # FunctionMessage(name='inf_data_critic', content=f'''The data of influencers is:\n {state.influencers_data[-1]}''')]
47
 
48
+ response = self.llm.invoke(messages)
49
+ state.critic_response.append(str(response.content))
50
+ print('Critic Response:', response.content)
51
  print('Critic Node executed')
52
  return state
53
 
54
+ class NormalizerNode:
55
+ def __init__(self):
56
+ self.llm = normalizer_llm
57
+
58
+ def run(self, state:State):
59
+ response = self.llm.with_structured_output(ideation_json_schema).invoke(str(state.critic_response[-1]))
60
+ state.normalizer_response.append(response)
61
+ print('Normalizer Executed')
62
+ return state
63
+
64
+
65
  class Judge:
66
  def __init__(self, llm):
67
  self.llm = llm
 
69
  def run (self, state:State):
70
  template = judge_prompt(state)
71
  messages = [SystemMessage(content=template),
72
+ HumanMessage(content=f'''The generated 10 ideas are:\n{state.normalizer_response[-1]}\n.
73
  The business_details is\n{state.business_details[-1]}\n
74
  The information of image is:{state.image_caption[-1]}\n''')]
75
  response = self.llm.with_structured_output(judge_response_json_schema).invoke(messages)
 
96
  def __init__(self):
97
  self.unique_ideas = {}
98
 
99
+ def run(self, state: State):
100
+ # Combine ideas from both judges
101
  all_selected_ideas = [
102
  *state.judge1_response[-1]['selected_ideas'],
103
  *state.judge2_response[-1]['selected_ideas']
104
  ]
105
 
106
+ print('All selected ideas:', all_selected_ideas)
107
+
108
+ # Keep only unique ideas by title
109
  for idea in all_selected_ideas:
110
  title = idea['title']
111
+ # If title not already added, store it
112
+ if title not in self.unique_ideas:
113
  self.unique_ideas[title] = idea
114
+
115
+ # Convert to list
116
  unique_ideas_list = list(self.unique_ideas.values())
117
+
118
+ # Save unique ideas to state
119
+ state.unique_selected_ideas.append(unique_ideas_list)
120
+
121
+
122
  return state
123
 
124
  class ValidatorNode:
125
  def __init__(self):
126
  self.validator_llm1 = validator_llm
127
+ self.validator_llm2 = validator_llm
128
 
129
  def get_response(self,state, validator_llm):
130
  template = validator_prompt(state)
src/genai/ideation_agent/utils/prompts.py CHANGED
@@ -1,63 +1,98 @@
1
  def ideator_prompt_v3():
2
  return f"""
3
  You are Ideasmith Pro, a world-class video ideator trusted by top brands to craft crisp, simple, and high-impact short-form video concepts for TikTok, Instagram, and YouTube Shorts.
4
- Your task is to create exactly 10 unique and highly creative video ideas (conceptual seeds, not full scripts). Each idea should be short, clear, and visually vivid.
5
  I am working on a project where i have to give very unique, creative and feasible video ideas for tiktok and instagram reels to the nepali business houses by understanding their business details.
 
6
 
7
 
8
  You will be given:
9
- - Business details (from the human message): Focus more strongly on device_used_to_create_videos , challenges_faced and additional informations provided.
10
  - Influencer data (from the function message): You can take it as a reference if it helps you.
11
 
12
  Output Rules:
13
  - Respond in valid JSON format only.
14
- - Return an array of exactly 10 objects.
15
  - Each object must include 5 fields:
16
  1. title → Short, catchy and unique title: Not more than 3 words.
17
  2. one_line_description → A simple but very creative and unique one-liner description
18
  3. hook → The surprising or bold moment that makes the entire idea clicked to the business.
19
  4. usp → The unique selling proposition tied to the business
 
 
20
 
21
  Very Important Creative Guidelines:
22
- - Each idea must be completely different in plot, theme, settings, tone, characters, events etc.
23
  - No repeating characters, locations, or flow patterns.
24
  - Use simple, clear, and engaging language.
25
- - Each idea must end with a strong conclusion that ties back to the business details.
26
- - The idea have to start from an unexpected or abstract scene/event before anchoring back to the business details.
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  """
29
 
30
  def critic_prompt_v3():
31
  return f"""
32
  You are a precision-focused, detail-oriented video ideas critic and ideas refiner.
33
- You’ve been assigned to critique and refine 10 video ideas created by another ideator.
34
- Your job is to identify weaknesses and then improve them making more creative, unique and tied to the business details.
 
35
  I am working on a project where i have to give very unique, creative and feasible video ideas for tiktok and instagram reels to the nepali business houses by understanding their business details.
36
 
37
  You are be provided with:
38
- - Business details (from the human message): Focus more strongly on device_used_to_create_videos , challenges_faced and additional informations provided.
39
  - Ideas generated by the ideator (from the human message)
40
  - Influencer data (from the function message): You can take it as a reference if it helps you.
41
 
42
  Your Job:
43
- 1. Identify collective flaws across the 10 original ideas — e.g., uncreative, lacking uniqueness, repetition, weak hooks, confusing flow, poor tie-in to business, lack of diversity, or unclear USP.
44
  2. Improve or rewrite each idea while keeping the structure intact in JSON format.
45
  - title → Short, catchy title
46
  - one_line_description → A simple but very creative and unique one-liner description
47
  - hook → The surprising or bold moment that makes the entire idea clicked to the business.
48
  - usp → The unique selling proposition tied to the business
 
49
 
50
  3. You are also allowed to change some entire ideas too if it lacks everything. But if some are already creative, you can refine them.
51
  4. Give the response in simple and understandable vocabularies.
52
 
53
-
54
  Very Important Creative Guidelines:
55
  - Each idea must be completely different in plot, theme, setting, and tone, characters , events etc.
56
- - Avoid repeating characters, hooks, settings, or storylines across the 10 ideas.
57
  - Use simple, clear, and engaging language.
58
- - Each idea must end with a strong, creative tie-in to the business details provided
59
- - The idea have to start from an unexpected or abstract scene, character, or event, then subtly anchor it to the business in the conclusion.
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  """
62
 
63
  def judge_prompt(state):
@@ -69,20 +104,20 @@ Each idea must be analyzed and scored on specific creativity and business alignm
69
 
70
  ### Scoring Rules:
71
  - You must evaluate all 10 ideas against the metrics below.
72
- - Use a 1–5 score scale for each metric:
73
- - Metrics to score for every idea:
74
- 1. Originality: 1=Very common, 2=Slight twist, 3=Moderately unique, 4=Rare/innovative, 5=Completely new
75
- 2. Fluency: 1=One-off, 2=Few vars, 3=Some, 4=Many contexts, 5=Endless remix
76
- 3. Flexibility: 1=One niche, 2=Few creators, 3=Several niches, 4=Many categories, 5=Universal
77
- 4. Feasibility (phone-only): 1=Impossible, 2=Very hard, 3=Possible w/ effort, 4=Easy on phone, 5=Effortless
78
- 5. Practical Value: 1=None, 2=Low, 3=Some, 4=High, 5=Very high/viral
79
- 6. Surprise_factor: 1=Predictable, 2=Mild, 3=Moderate, 4=Strong, 5=Shocking
80
- 7. Combinatorial Novelty: 1=Copy, 2=Slight remix, 3=Familiar combo, 4=Creative blend, 5=Radical fusion
81
- 8. Simplicity: 1=Very complex, 2=Complicated, 3=Some effort, 4=Simple, 5=Instantly clear
82
- 9. Scalability: 1=One-time, 2=Few times, 3=Limited repeats, 4=Recurring, 5=Endless series
83
- 10. Cultural Freshness: 1=Outdated, 2=Stale, 3=Current common, 4=Fresh twist, 5=Trendsetting
84
- 11. Alignment_with_business_details
85
- 12. Total_score
86
 
87
  ---
88
 
@@ -408,7 +443,7 @@ def validator_prompt(state):
408
  return f'''
409
  You are reviewing 4 short video ideas meant for a social media promotional campaign.
410
 
411
- Each idea creatively tells a short story that connects indirectly to the business details — starting from an unrelated or surprising scenario and ending with a clever link back to the business theme.
412
 
413
  ---
414
 
@@ -417,7 +452,7 @@ Each idea creatively tells a short story that connects indirectly to the busines
417
  {state.business_details[-1]}
418
 
419
  **Final 4 Ideas from Improver**:
420
- {state.top_4_ideas[-1]}
421
 
422
  ---
423
 
 
1
  def ideator_prompt_v3():
2
  return f"""
3
  You are Ideasmith Pro, a world-class video ideator trusted by top brands to craft crisp, simple, and high-impact short-form video concepts for TikTok, Instagram, and YouTube Shorts.
4
+ Your task is to create exactly 8 unique and highly creative video ideas (conceptual seeds, not full scripts). Each idea should be short, clear, and visually vivid.
5
  I am working on a project where i have to give very unique, creative and feasible video ideas for tiktok and instagram reels to the nepali business houses by understanding their business details.
6
+ The idea must have to include very unique events, surprises to make the video catchy.
7
 
8
 
9
  You will be given:
10
+ - Business details (from the human message): Focus more strongly on device_used_to_create_videos and additional informations provided. The video is to be shoot using the provided device in the business details.
11
  - Influencer data (from the function message): You can take it as a reference if it helps you.
12
 
13
  Output Rules:
14
  - Respond in valid JSON format only.
15
+ - Return an array of exactly 8 objects.
16
  - Each object must include 5 fields:
17
  1. title → Short, catchy and unique title: Not more than 3 words.
18
  2. one_line_description → A simple but very creative and unique one-liner description
19
  3. hook → The surprising or bold moment that makes the entire idea clicked to the business.
20
  4. usp → The unique selling proposition tied to the business
21
+ 5. niche → The specific target audience or market segment most likely to resonate with the video.
22
+
23
 
24
  Very Important Creative Guidelines:
25
+ - Each idea must be completely different in plot, theme, settings, tone, characters, events and everything.
26
  - No repeating characters, locations, or flow patterns.
27
  - Use simple, clear, and engaging language.
 
 
28
 
29
+ Here is the example of what kind of ideas i want:
30
+ The business details is:
31
+ Business Type: Women’s bags online store
32
+ Platforms: Instagram, TikTok
33
+ Target Audience: Women aged 18–50
34
+ Content Shooting Device: Mobile phone
35
+
36
+ The ideas for it are:
37
+ idea1:
38
+ title: What fits inside?
39
+ one_line_description: Empty bag → fill it with 5–6 useful items.
40
+ hook: “how much can THIS bag hold?”
41
+ idea_2:
42
+ One-line_description: show how one bag works in 3 daily scenarios (work, casual, night out).
43
+ Hook: “1 bag → 3 lifestyles.”
44
+
45
+ I want this kind of creative ideas. The video have to be very catchy enough and include surprise factors too. Don't make idea generic. The idea have to stand out very creatively.
46
  """
47
 
48
  def critic_prompt_v3():
49
  return f"""
50
  You are a precision-focused, detail-oriented video ideas critic and ideas refiner.
51
+ You’ve been assigned to critique and refine 8 video ideas created by another ideator.
52
+ Your job is to identify weaknesses and then improve them making more creative and unique.
53
+ The idea must have to include very unique events, surprises to make the video catchy.
54
  I am working on a project where i have to give very unique, creative and feasible video ideas for tiktok and instagram reels to the nepali business houses by understanding their business details.
55
 
56
  You are be provided with:
57
+ - Business details (from the human message): Focus more strongly on device_used_to_create_videos and additional informations provided. The video is to be shoot using the provided device in the business details.
58
  - Ideas generated by the ideator (from the human message)
59
  - Influencer data (from the function message): You can take it as a reference if it helps you.
60
 
61
  Your Job:
62
+ 1. Identify collective flaws across the 8 original ideas — e.g., uncreative, lacking uniqueness, repetition, weak hooks, confusing flow, poor tie-in to business, lack of diversity, or unclear USP.
63
  2. Improve or rewrite each idea while keeping the structure intact in JSON format.
64
  - title → Short, catchy title
65
  - one_line_description → A simple but very creative and unique one-liner description
66
  - hook → The surprising or bold moment that makes the entire idea clicked to the business.
67
  - usp → The unique selling proposition tied to the business
68
+ - niche → The specific target audience or market segment most likely to resonate with the video.
69
 
70
  3. You are also allowed to change some entire ideas too if it lacks everything. But if some are already creative, you can refine them.
71
  4. Give the response in simple and understandable vocabularies.
72
 
 
73
  Very Important Creative Guidelines:
74
  - Each idea must be completely different in plot, theme, setting, and tone, characters , events etc.
75
+ - Avoid repeating characters, hooks, settings, or storylines across the 8 ideas.
76
  - Use simple, clear, and engaging language.
 
 
77
 
78
+ Here is the example of what kind of ideas i want:
79
+ The business details is:
80
+ Business Type: Women’s bags online store
81
+ Platforms: Instagram, TikTok
82
+ Target Audience: Women aged 18–50
83
+ Content Shooting Device: Mobile phone
84
+
85
+ The ideas for it are:
86
+ idea1:
87
+ title: What fits inside?
88
+ one_line_description: Empty bag → fill it with 5–6 useful items.
89
+ hook: “how much can THIS bag hold?”
90
+ idea_2:
91
+ One-line_description: show how one bag works in 3 daily scenarios (work, casual, night out).
92
+ Hook: “1 bag → 3 lifestyles.”
93
+
94
+ I want this kind of creative ideas. The video have to be very catchy enough and include surprise factors too. Don't make idea generic. The idea have to stand out very creatively.
95
+
96
  """
97
 
98
  def judge_prompt(state):
 
104
 
105
  ### Scoring Rules:
106
  - You must evaluate all 10 ideas against the metrics below.
107
+ - Use a 1–5 score scale for each metric. You have to score in floating point value. Not integer.
108
+ For each score, output a FLOAT between 1.0 and 5.0 (decimals allowed like 3.5 or 4.0).
109
+ Use the following definitions:
110
+ 1. Originality: 1.0=Very common, 2.0=Slight twist, 3.0=Moderately unique, 4.0=Rare/innovative, 5.0=Completely new
111
+ 2. Fluency: 1.0=One-off, 2.0=Few vars, 3.0=Some, 4.0=Many contexts, 5.0=Endless remix
112
+ 3. Flexibility: 1.0=One niche, 2.0=Few creators, 3.0=Several niches, 4.0=Many categories, 5.0=Universal
113
+ 4. Feasibility (phone-only): 1.0=Impossible, 2.0=Very hard, 3.0=Possible w/ effort, 4.0=Easy on phone, 5.0=Effortless
114
+ 5. Practical Value: 1.0=None, 2.0=Low, 3.0=Some, 4.0=High, 5.0=Very high/viral
115
+ 6. Surprise_factor: 1.0=Predictable, 2.0=Mild, 3.0=Moderate, 4.0=Strong, 5.0=Shocking
116
+ 7. Combinatorial Novelty: 1.0=Copy, 2.0=Slight remix, 3.0=Familiar combo, 4.0=Creative blend, 5.0=Radical fusion
117
+ 8. Simplicity: 1.0=Very complex, 2.0=Complicated, 3.0=Some effort, 4.0=Simple, 5.0=Instantly clear
118
+ 9. Scalability: 1.0=One-time, 2.0=Few times, 3.0=Limited repeats, 4.0=Recurring, 5.0=Endless series
119
+ 10. Cultural Freshness: 1.0=Outdated, 2.0=Stale, 3.0=Current common, 4.0=Fresh twist, 5.0=Trendsetting
120
+ 11. Alignment_with_business_details: 1.0=Very low alignment, 5.0=Perfect alignment
121
 
122
  ---
123
 
 
443
  return f'''
444
  You are reviewing 4 short video ideas meant for a social media promotional campaign.
445
 
446
+ Each idea creatively tells a short story that connects indirectly to the business details.
447
 
448
  ---
449
 
 
452
  {state.business_details[-1]}
453
 
454
  **Final 4 Ideas from Improver**:
455
+ {state.unique_selected_ideas[-1]}
456
 
457
  ---
458
 
src/genai/ideation_agent/utils/schemas.py CHANGED
@@ -23,7 +23,11 @@ ideation_json_schema={
23
  "unique_selling_proposition": {
24
  "type": "string",
25
  "description": "The unique selling point that makes this idea stand out"
26
- }
 
 
 
 
27
  },
28
  "required": [
29
  "title",
@@ -60,30 +64,30 @@ judge_response_json_schema = {
60
  "type": "string",
61
  "description": "The attention-grabbing hook"
62
  },
63
- "storyline_flow": {
64
- "type": "string",
65
- "description": "The structured flow of the storyline"
66
- },
67
  "unique_selling_proposition": {
68
  "type": "string",
69
  "description": "The unique selling proposition (USP) of the idea"
 
 
 
 
70
  },
71
  "scores": {
72
  "title": "Scores",
73
  "type": "object",
 
74
  "properties": {
75
- "originality": { "type": "integer" },
76
- "feasibility": { "type": "integer" },
77
- "practical_value": { "type": "integer" },
78
- "flexibility": { "type": "integer" },
79
- "fluency": { "type": "integer" },
80
- "simplicity": { "type": "integer" },
81
- "combinatorial_novelty": { "type": "integer" },
82
- "culture_freshness": { "type": "integer" },
83
- "surprise_factor": { "type": "integer" },
84
- "scalability": { "type": "integer" },
85
- "alignment_with_business_details": { "type": "integer" },
86
- "total_score": { "type": "integer" }
87
  },
88
  "required": [
89
  "originality",
@@ -97,7 +101,6 @@ judge_response_json_schema = {
97
  "surprise_factor",
98
  "scalability",
99
  "alignment_with_business_details",
100
- "total_score"
101
  ]
102
  }
103
  },
@@ -105,8 +108,8 @@ judge_response_json_schema = {
105
  "title",
106
  "one_line_description",
107
  "hook",
108
- "storyline_flow",
109
  "unique_selling_proposition",
 
110
  "scores"
111
  ]
112
  }
 
23
  "unique_selling_proposition": {
24
  "type": "string",
25
  "description": "The unique selling point that makes this idea stand out"
26
+ },
27
+ "niche":{
28
+ "type": "string",
29
+ "description": "The specific target audience or market segment most likely to resonate with the video."
30
+ },
31
  },
32
  "required": [
33
  "title",
 
64
  "type": "string",
65
  "description": "The attention-grabbing hook"
66
  },
 
 
 
 
67
  "unique_selling_proposition": {
68
  "type": "string",
69
  "description": "The unique selling proposition (USP) of the idea"
70
+ },
71
+ "niche": {
72
+ "type": "string",
73
+ "description": "The specific target audience or market segment most likely to resonate with the video."
74
  },
75
  "scores": {
76
  "title": "Scores",
77
  "type": "object",
78
+ "description": "Float values in the range of 1.0 to 5.0",
79
  "properties": {
80
+ "originality": { "type": "number","description":"originality score for the idea (float between 1.0 and 5.0)"},
81
+ "feasibility": { "type": "number" ,"description":"feasibility score for the idea (float between 1.0 and 5.0)"},
82
+ "practical_value": { "type": "number" ,"description":"practical_value score for the idea (float between 1.0 and 5.0)"},
83
+ "flexibility": { "type": "number" ,"description":"flexibility score for the idea (float between 1.0 and 5.0)"},
84
+ "fluency": { "type": "number","description":"fluency score for the idea (float between 1.0 and 5.0)"},
85
+ "simplicity": { "type": "number" ,"description":"simplicity score for the idea (float between 1.0 and 5.0)"},
86
+ "combinatorial_novelty": { "type": "number" ,"description":"combinatorial_novelty score for the idea (float between 1.0 and 5.0)"},
87
+ "culture_freshness": { "type": "number","description":"culture_freshness score for the idea (float between 1.0 and 5.0)"},
88
+ "surprise_factor": { "type": "number" ,"description":"surprise_factor score for the idea (float between 1.0 and 5.0)"},
89
+ "scalability": { "type": "number","description":"scalability score for the idea (float between 1.0 and 5.0)" },
90
+ "alignment_with_business_details": { "type": "number" ,"description":"alignment score for the idea (float between 1.0 and 5.0)"},
 
91
  },
92
  "required": [
93
  "originality",
 
101
  "surprise_factor",
102
  "scalability",
103
  "alignment_with_business_details",
 
104
  ]
105
  }
106
  },
 
108
  "title",
109
  "one_line_description",
110
  "hook",
 
111
  "unique_selling_proposition",
112
+ "niche",
113
  "scores"
114
  ]
115
  }
src/genai/ideation_agent/utils/state.py CHANGED
@@ -8,9 +8,10 @@ class State(BaseModel):
8
  influencers_data : Annotated[list[str],operator.add] = []
9
  ideator_response: Annotated[list[str],operator.add] = []
10
  critic_response: Annotated[list[str],operator.add] = []
 
11
  judge1_response : Annotated[list[dict],operator.add] = []
12
  judge2_response : Annotated[list[dict],operator.add] = []
13
- top_4_ideas : Annotated[list[list],operator.add] = []
14
  validator_response: Annotated[list[str],operator.add] = []
15
  disagreement_reason: Annotated[list[str],operator.add] = []
16
  image_caption: Annotated[list[str],operator.add] = []
 
8
  influencers_data : Annotated[list[str],operator.add] = []
9
  ideator_response: Annotated[list[str],operator.add] = []
10
  critic_response: Annotated[list[str],operator.add] = []
11
+ normalizer_response : Annotated[list[dict],operator.add] = []
12
  judge1_response : Annotated[list[dict],operator.add] = []
13
  judge2_response : Annotated[list[dict],operator.add] = []
14
+ unique_selected_ideas : Annotated[list[dict],operator.add] = []
15
  validator_response: Annotated[list[str],operator.add] = []
16
  disagreement_reason: Annotated[list[str],operator.add] = []
17
  image_caption: Annotated[list[str],operator.add] = []
src/genai/ideation_agent/utils/tools.py CHANGED
@@ -50,7 +50,7 @@ class Retrieval:
50
  cleaned_response = clean_text(str(outer_list))
51
  encoding = tiktoken.encoding_for_model('gpt-4o-mini')
52
  tokens = encoding.encode(cleaned_response)
53
- trimmed_response = tokens[:1000]
54
  return encoding.decode(trimmed_response)
55
 
56
  def imdb_ideas(self):
 
50
  cleaned_response = clean_text(str(outer_list))
51
  encoding = tiktoken.encoding_for_model('gpt-4o-mini')
52
  tokens = encoding.encode(cleaned_response)
53
+ trimmed_response = tokens[:100]
54
  return encoding.decode(trimmed_response)
55
 
56
  def imdb_ideas(self):
src/genai/utils/__pycache__/models_loader.cpython-313.pyc CHANGED
Binary files a/src/genai/utils/__pycache__/models_loader.cpython-313.pyc and b/src/genai/utils/__pycache__/models_loader.cpython-313.pyc differ
 
src/genai/utils/models_loader.py CHANGED
@@ -14,17 +14,18 @@ login(os.environ['HUGGINGFACEHUB_ACCESS_TOKEN'])
14
 
15
 
16
  embedding_model = OpenAIEmbeddings(model="text-embedding-3-small", dimensions=1536)
17
- llm_anthropic = ChatAnthropic(model='claude-3-5-sonnet-20241022', temperature=0.7, max_tokens=500)
18
  llm_gemini = ChatGoogleGenerativeAI(model="gemini-1.5-flash")
19
  llm_groq = ChatGroq(model="llama-3.1-8b-instant",temperature=0.7)
20
  llm_gpt = ChatOpenAI(model="gpt-4o-mini",temperature=0.3)
 
21
 
22
  captioning_model = "meta-llama/llama-4-scout-17b-16e-instruct"
23
  image_generation_model = "black-forest-labs/FLUX.1-schnell"
24
 
25
- improver_llm = llm_gpt
26
  ideator_llm = llm_gpt
27
  critic_llm = llm_gpt
 
28
  validator_llm = llm_gpt
29
  judge1_llm = llm_gpt
30
  judge2_llm = llm_gpt
 
14
 
15
 
16
  embedding_model = OpenAIEmbeddings(model="text-embedding-3-small", dimensions=1536)
17
+ llm_anthropic = ChatAnthropic(model='claude-3-7-sonnet-latest', temperature=1)
18
  llm_gemini = ChatGoogleGenerativeAI(model="gemini-1.5-flash")
19
  llm_groq = ChatGroq(model="llama-3.1-8b-instant",temperature=0.7)
20
  llm_gpt = ChatOpenAI(model="gpt-4o-mini",temperature=0.3)
21
+ llm_gpt_high = ChatOpenAI(model="gpt-4o",temperature=0.5)
22
 
23
  captioning_model = "meta-llama/llama-4-scout-17b-16e-instruct"
24
  image_generation_model = "black-forest-labs/FLUX.1-schnell"
25
 
 
26
  ideator_llm = llm_gpt
27
  critic_llm = llm_gpt
28
+ normalizer_llm = llm_gpt
29
  validator_llm = llm_gpt
30
  judge1_llm = llm_gpt
31
  judge2_llm = llm_gpt