Spaces:
Sleeping
Sleeping
Commit
·
3a3fe92
1
Parent(s):
215ec10
Created Ideation agent
Browse files- ideation_agent/__init__.py +0 -0
- ideation_agent/__pycache__/__init__.cpython-312.pyc +0 -0
- ideation_agent/__pycache__/agent.cpython-312.pyc +0 -0
- ideation_agent/agent.py +32 -0
- ideation_agent/utils/__pycache__/nodes.cpython-312.pyc +0 -0
- ideation_agent/utils/__pycache__/prompts.cpython-312.pyc +0 -0
- ideation_agent/utils/__pycache__/state.cpython-312.pyc +0 -0
- ideation_agent/utils/__pycache__/tools.cpython-312.pyc +0 -0
- ideation_agent/utils/nodes.py +143 -0
- ideation_agent/utils/prompts.py +159 -0
- ideation_agent/utils/state.py +24 -0
- ideation_agent/utils/tools.py +57 -0
- ideation_agent/utils/utils.py +0 -0
ideation_agent/__init__.py
ADDED
|
File without changes
|
ideation_agent/__pycache__/__init__.cpython-312.pyc
ADDED
|
Binary file (182 Bytes). View file
|
|
|
ideation_agent/__pycache__/agent.cpython-312.pyc
ADDED
|
Binary file (2.15 kB). View file
|
|
|
ideation_agent/agent.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from langgraph.graph import StateGraph, START, END
|
| 2 |
+
from .utils.state import State
|
| 3 |
+
from .utils.nodes import ideator , critic , improver , validator1 , validator2 , validator3 , validator4 , route1_after_validation , route2_after_validation , route3_after_validation , route4_after_validation
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def ideation_graph():
|
| 7 |
+
graph_builder= StateGraph(State)
|
| 8 |
+
graph_builder.add_node(ideator)
|
| 9 |
+
graph_builder.add_node(critic)
|
| 10 |
+
graph_builder.add_node(improver)
|
| 11 |
+
graph_builder.add_node(validator1)
|
| 12 |
+
graph_builder.add_node(validator2)
|
| 13 |
+
graph_builder.add_node(validator3)
|
| 14 |
+
graph_builder.add_node(validator4)
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
graph_builder.add_edge(START, "ideator") # Start the graph with node_1
|
| 18 |
+
graph_builder.add_edge("ideator", "critic")
|
| 19 |
+
graph_builder.add_edge("critic", "improver")
|
| 20 |
+
graph_builder.add_edge("improver", "validator1")
|
| 21 |
+
graph_builder.add_edge("validator1", "validator2")
|
| 22 |
+
graph_builder.add_edge("validator2", "validator3")
|
| 23 |
+
graph_builder.add_edge("validator3", "validator4")
|
| 24 |
+
graph_builder.add_edge("validator4", END)
|
| 25 |
+
|
| 26 |
+
# Use conditional routing from validator
|
| 27 |
+
graph_builder.add_conditional_edges("validator1", route1_after_validation,{False:'improver',True:'validator2'})
|
| 28 |
+
graph_builder.add_conditional_edges("validator2", route2_after_validation,{False:'improver',True:'validator3'})
|
| 29 |
+
graph_builder.add_conditional_edges("validator3", route3_after_validation,{False:'improver',True:'validator4'})
|
| 30 |
+
graph_builder.add_conditional_edges("validator4", route4_after_validation,{False:'improver',True:END})
|
| 31 |
+
|
| 32 |
+
return graph_builder.compile()
|
ideation_agent/utils/__pycache__/nodes.cpython-312.pyc
ADDED
|
Binary file (7.09 kB). View file
|
|
|
ideation_agent/utils/__pycache__/prompts.cpython-312.pyc
ADDED
|
Binary file (7.44 kB). View file
|
|
|
ideation_agent/utils/__pycache__/state.cpython-312.pyc
ADDED
|
Binary file (1.88 kB). View file
|
|
|
ideation_agent/utils/__pycache__/tools.cpython-312.pyc
ADDED
|
Binary file (3.13 kB). View file
|
|
|
ideation_agent/utils/nodes.py
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .state import State , ValidationFormatter
|
| 2 |
+
from .tools import retrieve_tool
|
| 3 |
+
from langgraph.prebuilt import create_react_agent
|
| 4 |
+
from utils.models_loader import ideator_llm, critic_llm , improver_llm , validator_llm
|
| 5 |
+
from langchain_core.messages import SystemMessage , HumanMessage
|
| 6 |
+
from .prompts import ideator_prompt , critic_prompt , improver_prompt , validator_prompt
|
| 7 |
+
|
| 8 |
+
def ideator(state:State):
|
| 9 |
+
tools=[retrieve_tool]
|
| 10 |
+
react_agent=create_react_agent(
|
| 11 |
+
model=ideator_llm,
|
| 12 |
+
tools=tools
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
template = ideator_prompt(state)
|
| 16 |
+
|
| 17 |
+
messages = [SystemMessage(content=template),
|
| 18 |
+
HumanMessage(content=f'''The topic of the video is:\n{state.topic}\n''')]
|
| 19 |
+
|
| 20 |
+
response = react_agent.invoke({'messages':messages})
|
| 21 |
+
response = response['messages'][-1].content
|
| 22 |
+
print('Ideator Response:',response)
|
| 23 |
+
state.ideator_response = response
|
| 24 |
+
print('Ideator Generated the story')
|
| 25 |
+
return state
|
| 26 |
+
|
| 27 |
+
def critic(state:State):
|
| 28 |
+
tools=[retrieve_tool]
|
| 29 |
+
react_agent=create_react_agent(
|
| 30 |
+
model=critic_llm,
|
| 31 |
+
tools=tools
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
template = critic_prompt(state)
|
| 35 |
+
messages = [SystemMessage(content=template),
|
| 36 |
+
HumanMessage(content=f'''The topic of the video is:\n{state.topic}\n. The business_details is\n{state.business_details}\n''')]
|
| 37 |
+
|
| 38 |
+
response = react_agent.invoke({'messages':messages})
|
| 39 |
+
response = response['messages'][-1].content
|
| 40 |
+
print('Critic Response:',response)
|
| 41 |
+
|
| 42 |
+
state.critic_response = response
|
| 43 |
+
print('Critic Evaluated the story')
|
| 44 |
+
|
| 45 |
+
return state
|
| 46 |
+
|
| 47 |
+
def improver(state:State):
|
| 48 |
+
react_agent=create_react_agent(
|
| 49 |
+
model=improver_llm,
|
| 50 |
+
tools=[]
|
| 51 |
+
)
|
| 52 |
+
|
| 53 |
+
template = improver_prompt(state)
|
| 54 |
+
messages = [SystemMessage(content=template),
|
| 55 |
+
HumanMessage(content=f'''The topic of the video is:\n{state.topic}\n The business_details is:\n{state.business_details}''')]
|
| 56 |
+
|
| 57 |
+
response = react_agent.invoke({'messages':messages})
|
| 58 |
+
response = response['messages'][-1].content
|
| 59 |
+
print('Improver Response:',response)
|
| 60 |
+
state.improver_response = response
|
| 61 |
+
print('Improver Improved the story')
|
| 62 |
+
return state
|
| 63 |
+
|
| 64 |
+
def validator1(state:State):
|
| 65 |
+
template = validator_prompt(state)
|
| 66 |
+
messages = [SystemMessage(content=template),
|
| 67 |
+
HumanMessage(content=f'''The topic of the video is:\n{state.topic}\n The business_details is:\n{state.business_details}''')]
|
| 68 |
+
|
| 69 |
+
response = validator_llm.with_structured_output(ValidationFormatter).invoke(messages)
|
| 70 |
+
print(f'Validator 1 response: {response}')
|
| 71 |
+
state.validator1_response = response.result
|
| 72 |
+
print('The state check:',state.validator1_response)
|
| 73 |
+
if 'not validated' in response.result:
|
| 74 |
+
state.disagreement_reason = response.reason
|
| 75 |
+
return state
|
| 76 |
+
|
| 77 |
+
def validator2(state:State):
|
| 78 |
+
template = validator_prompt(state)
|
| 79 |
+
messages = [SystemMessage(content=template),
|
| 80 |
+
HumanMessage(content=f'''The topic of the video is:\n{state.topic}\n The business_details is:\n{state.business_details}''')]
|
| 81 |
+
|
| 82 |
+
response = ideator_llm.with_structured_output(ValidationFormatter).invoke(messages)
|
| 83 |
+
print(f'Validator 2 response: {response}')
|
| 84 |
+
state.validator2_response = response.result
|
| 85 |
+
print('The state check:',state.validator1_response)
|
| 86 |
+
if 'not validated' in response.result:
|
| 87 |
+
state.disagreement_reason = response.reason
|
| 88 |
+
return state
|
| 89 |
+
|
| 90 |
+
def validator3(state:State):
|
| 91 |
+
template = validator_prompt(state)
|
| 92 |
+
messages = [SystemMessage(content=template),
|
| 93 |
+
HumanMessage(content=f'''The topic of the video is:\n{state.topic}\n The business_details is:\n{state.business_details}''')]
|
| 94 |
+
|
| 95 |
+
response = critic_llm.with_structured_output(ValidationFormatter).invoke(messages)
|
| 96 |
+
print(f'Validator 3 response: {response}')
|
| 97 |
+
state.validator3_response = response.result
|
| 98 |
+
print('The state check:',state.validator1_response)
|
| 99 |
+
if 'not validated' in response.result:
|
| 100 |
+
state.disagreement_reason = response.reason
|
| 101 |
+
return state
|
| 102 |
+
|
| 103 |
+
def validator4(state:State):
|
| 104 |
+
template = validator_prompt(state)
|
| 105 |
+
messages = [SystemMessage(content=template),
|
| 106 |
+
HumanMessage(content=f'''The topic of the video is:\n{state.topic}\n The business_details is:\n{state.business_details}''')]
|
| 107 |
+
|
| 108 |
+
response = improver_llm.with_structured_output(ValidationFormatter).invoke(messages)
|
| 109 |
+
print(f'Validator 4 response: {response}')
|
| 110 |
+
state.validator4_response = response.result
|
| 111 |
+
print('The state check:',state.validator1_response)
|
| 112 |
+
if 'not validated' in response.result:
|
| 113 |
+
state.topic=None
|
| 114 |
+
state.disagreement_reason = response.reason
|
| 115 |
+
return state
|
| 116 |
+
|
| 117 |
+
def route1_after_validation(state:State):
|
| 118 |
+
if 'not validated' in state.validator1_response:
|
| 119 |
+
return False
|
| 120 |
+
else:
|
| 121 |
+
return True
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def route2_after_validation(state:State):
|
| 125 |
+
if 'not validated' in state.validator2_response:
|
| 126 |
+
return False
|
| 127 |
+
else:
|
| 128 |
+
return True
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
def route3_after_validation(state:State):
|
| 132 |
+
if 'not validated' in state.validator3_response:
|
| 133 |
+
return False
|
| 134 |
+
else:
|
| 135 |
+
return True
|
| 136 |
+
|
| 137 |
+
|
| 138 |
+
def route4_after_validation(state:State):
|
| 139 |
+
if 'not validated' in state.validator4_response:
|
| 140 |
+
return False
|
| 141 |
+
else:
|
| 142 |
+
return True
|
| 143 |
+
|
ideation_agent/utils/prompts.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
def ideator_prompt_old(state):
|
| 3 |
+
return f'''
|
| 4 |
+
|
| 5 |
+
You are a highly creative video content strategist who specializes in generating original, compelling video ideas in exactly 100 words.
|
| 6 |
+
|
| 7 |
+
Your task is to develop a **unique, creative and imaginative root idea** for a promotional video based on the following **video topic** and **business details**. The idea should be highly creative, catchy, and distinct—something that instantly grabs attention.
|
| 8 |
+
|
| 9 |
+
Another important thing is that you have to give the response focusing on the response of the tool provided to you. The tool contains the video stories and contents created by the influencers.
|
| 10 |
+
Use those responses for your reference. You can use your creativity but stay within the boundaries of the tool's response.
|
| 11 |
+
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
**Video Topic**:
|
| 15 |
+
{state.topic}
|
| 16 |
+
|
| 17 |
+
**Business Details**:
|
| 18 |
+
{state.business_details}
|
| 19 |
+
|
| 20 |
+
---
|
| 21 |
+
|
| 22 |
+
**Important Instructions**:
|
| 23 |
+
Do **not** generate a complete storyline. Focus only on the **main root idea** that is clear, unique, bold, and creatively promising. Keep it exactly 100 words.
|
| 24 |
+
Now, generate the final idea for the video topic.
|
| 25 |
+
'''
|
| 26 |
+
|
| 27 |
+
def ideator_prompt(state):
|
| 28 |
+
return f'''
|
| 29 |
+
You are a highly imaginative and strategic **video ideator** who specializes in crafting powerful promotional video **core ideas** in **exactly 100 words**.
|
| 30 |
+
|
| 31 |
+
Your task is to develop a **single, bold, unique, and creative paragraph** that represents the **root idea** of a promotional video. This is **not** a full concept or storyline — just the **main idea**, presented creatively and concisely.
|
| 32 |
+
|
| 33 |
+
Use the response of the provided tool (which includes video stories from influencers) as inspiration. Stay within the creative boundaries of that tool's content, but feel free to push the edges with originality.
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
**Video Topic**:
|
| 38 |
+
{state.topic}
|
| 39 |
+
|
| 40 |
+
**Business Details**:
|
| 41 |
+
{state.business_details}
|
| 42 |
+
|
| 43 |
+
---
|
| 44 |
+
|
| 45 |
+
**Important Instructions**:
|
| 46 |
+
- Write only **one paragraph**, not a list.
|
| 47 |
+
- Do **not** include titles, headers, sections, or formatting like bullet points.
|
| 48 |
+
- The output must be exactly **100 words** — no more, no less.
|
| 49 |
+
- Focus on uniqueness, imagination, and viral potential.
|
| 50 |
+
|
| 51 |
+
Now, generate the **core idea paragraph**.
|
| 52 |
+
'''
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def critic_prompt(state):
|
| 56 |
+
return f'''
|
| 57 |
+
You are an expert **video content strategist and creative critic**.
|
| 58 |
+
|
| 59 |
+
Your job is to **analyze and critique** the following promotional video idea. Your critique should be insightful, constructive, and based on storytelling quality, creativity, uniqueness, and alignment with the provided video topic and business context.
|
| 60 |
+
|
| 61 |
+
Also, you have to check whether the given idea is relevant to the tool's response or not. The tool's response includes the video stories of the influencers. If it's not relevant to the tool's response, you have to specify it.
|
| 62 |
+
|
| 63 |
+
After identifying the weaknesses or faults in the idea, you must **rewrite a new, improved version** of the core idea that fixes those flaws or faults while keeping the concept bold, creative, and engaging. The improved idea should also be exactly 100 words.
|
| 64 |
+
|
| 65 |
+
---
|
| 66 |
+
|
| 67 |
+
**Video Topic**:
|
| 68 |
+
{state.topic}
|
| 69 |
+
|
| 70 |
+
**Business Details**:
|
| 71 |
+
{state.business_details}
|
| 72 |
+
|
| 73 |
+
**Original Video Idea** (100 words):
|
| 74 |
+
{state.ideator_response}
|
| 75 |
+
|
| 76 |
+
---
|
| 77 |
+
|
| 78 |
+
**Your Task as the Critic**:
|
| 79 |
+
1. List the **key faults** or weak areas in the original idea.
|
| 80 |
+
2. Provide a **revised version** of the idea that improves upon the original, maintains high creativity, and stays within 100 words.
|
| 81 |
+
'''
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def improver_prompt(state):
|
| 85 |
+
disagreement_note = (
|
| 86 |
+
f"**Your idea was not validated before because of this reason:\n{state.disagreement_reason}\n**"
|
| 87 |
+
if state.disagreement_reason else ""
|
| 88 |
+
)
|
| 89 |
+
return f'''
|
| 90 |
+
You are a master-level **video concept developer** known for turning creative ideas into standout, refined gems.
|
| 91 |
+
|
| 92 |
+
Your task is to carefully evaluate the **critic's response** to a promotional video idea. The critic has already listed faults in the original idea and provided a revised version. You must now go a step further and generate an **even more creative, emotionally engaging, and original 100-word idea** that corrects any lingering weaknesses or missed potential in the critic’s revision.
|
| 93 |
+
|
| 94 |
+
Focus on making the idea sharper, bolder, and more impactful — while staying aligned with the video topic, business details, and the style of influencer content referenced in the tool’s response.
|
| 95 |
+
|
| 96 |
+
---
|
| 97 |
+
|
| 98 |
+
**Video Topic**:
|
| 99 |
+
{state.topic}
|
| 100 |
+
|
| 101 |
+
**Business Details**:
|
| 102 |
+
{state.business_details}
|
| 103 |
+
|
| 104 |
+
**Critic's Response**:
|
| 105 |
+
{state.critic_response}
|
| 106 |
+
|
| 107 |
+
{disagreement_note}
|
| 108 |
+
|
| 109 |
+
---
|
| 110 |
+
|
| 111 |
+
**Your Task**:
|
| 112 |
+
Generate a **new, final improved idea** based on the critic’s analysis and revision. Your idea must be exactly **100 words**, stand out with high creativity, and reflect a strong understanding of narrative appeal and brand relevance.
|
| 113 |
+
If the critic's revision doesn't have any problem, give the same critic's idea.
|
| 114 |
+
'''
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def validator_prompt(state):
|
| 118 |
+
return f'''
|
| 119 |
+
You are a strict and unbiased judge responsible for evaluating whether a promotional video idea is ready for publishing.
|
| 120 |
+
|
| 121 |
+
You will be given the video topic, business details, and the final version of the video idea (after improvement). Your task is to assess if this idea meets all necessary standards in terms of:
|
| 122 |
+
|
| 123 |
+
- Relevance to the video topic
|
| 124 |
+
- Alignment with the business context
|
| 125 |
+
- Tone matching the business type
|
| 126 |
+
- Creativity and clarity
|
| 127 |
+
|
| 128 |
+
You can also use the tool's response as your reference to make the validation. The tool's response includes existing influencer-style stories or content for reference.
|
| 129 |
+
|
| 130 |
+
---
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
**Video Topic**:
|
| 134 |
+
{state.topic}
|
| 135 |
+
|
| 136 |
+
**Business Details**:
|
| 137 |
+
{state.business_details}
|
| 138 |
+
|
| 139 |
+
**Final idea from Improver**:
|
| 140 |
+
{state.improver_response}
|
| 141 |
+
|
| 142 |
+
---
|
| 143 |
+
|
| 144 |
+
**Validation Criteria**:
|
| 145 |
+
|
| 146 |
+
- Is the idea **fully aligned** with the topic, business details and the tool's response?
|
| 147 |
+
- Does the structure flow logically and effectively?
|
| 148 |
+
- Does it feel complete and professional to use this idea to create a video?
|
| 149 |
+
|
| 150 |
+
---
|
| 151 |
+
|
| 152 |
+
**Output Instruction**: There are two outputs you have to give.
|
| 153 |
+
|
| 154 |
+
1.Respond strictly just with one of the following values:
|
| 155 |
+
- `validated` – if the idea meets all the criteria and is validated.
|
| 156 |
+
- `not validated` – if it fails to meet any key criteria and needs further improvement.
|
| 157 |
+
|
| 158 |
+
2. Give a short reason of 30 words why the idea is validated or not validated.
|
| 159 |
+
'''
|
ideation_agent/utils/state.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pydantic import BaseModel, Field
|
| 2 |
+
from typing import Optional
|
| 3 |
+
import operator
|
| 4 |
+
from typing import Annotated
|
| 5 |
+
|
| 6 |
+
class State(BaseModel):
|
| 7 |
+
topic: list
|
| 8 |
+
business_details: Optional[dict]
|
| 9 |
+
ideator_response: Optional[str] = None
|
| 10 |
+
critic_response: Optional[str]=None
|
| 11 |
+
improver_response: Optional[str]=None
|
| 12 |
+
validator1_response: Optional[str]=None
|
| 13 |
+
validator2_response: Optional[str]=None
|
| 14 |
+
validator3_response: Optional[str]=None
|
| 15 |
+
validator4_response: Optional[str]=None
|
| 16 |
+
disagreement_reason: Optional[str]=None
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class QueryFormatter(BaseModel):
|
| 20 |
+
video_topic: str = Field(description="The video topic that user passes to the agent")
|
| 21 |
+
|
| 22 |
+
class ValidationFormatter(BaseModel):
|
| 23 |
+
result: str = Field(description="Returns **validated** if the story is validated. Returns **not validated** if story is not validated.")
|
| 24 |
+
reason: str = Field(description="Returns the reason why the story is validated or not validated.")
|
ideation_agent/utils/tools.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
from langchain_core.tools import tool
|
| 3 |
+
from .state import QueryFormatter
|
| 4 |
+
import pandas as pd
|
| 5 |
+
import numpy as np
|
| 6 |
+
import ast
|
| 7 |
+
import faiss
|
| 8 |
+
from utils.models_loader import ST
|
| 9 |
+
|
| 10 |
+
@tool("influencer's data-retrieval-tool", args_schema=QueryFormatter, return_direct=False,description="Retrieve influencer-related data for a given query.")
|
| 11 |
+
def retrieve_tool(video_topic):
|
| 12 |
+
'''
|
| 13 |
+
Always invoke this tool.
|
| 14 |
+
Retrieve influencer's data by semantic search of **video topic**.
|
| 15 |
+
'''
|
| 16 |
+
# === Load CSV ===
|
| 17 |
+
csv_path = 'extracted_data.csv'
|
| 18 |
+
df = pd.read_csv(csv_path)
|
| 19 |
+
|
| 20 |
+
# === Parse stored embeddings ===
|
| 21 |
+
df['embeddings'] = df['embeddings'].apply(lambda x: ast.literal_eval(x) if isinstance(x, str) else x)
|
| 22 |
+
embeddings = np.vstack(df['embeddings'].values).astype('float32')
|
| 23 |
+
|
| 24 |
+
# === Build FAISS index ===
|
| 25 |
+
dimension = embeddings.shape[1]
|
| 26 |
+
index = faiss.IndexFlatL2(dimension)
|
| 27 |
+
index.add(embeddings)
|
| 28 |
+
|
| 29 |
+
# === Load SentenceTransformer model ===
|
| 30 |
+
|
| 31 |
+
# === Encode the query and search ===
|
| 32 |
+
query_embedding = ST.encode(str(video_topic)).reshape(1, -1).astype('float32')
|
| 33 |
+
top_k=7
|
| 34 |
+
distances, indices = index.search(query_embedding, top_k)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
# === Format results ===
|
| 39 |
+
outer_list = []
|
| 40 |
+
for i, idx in enumerate(indices[0]):
|
| 41 |
+
res = {
|
| 42 |
+
'rank': i + 1,
|
| 43 |
+
'username': df.iloc[idx]['username'],
|
| 44 |
+
'story': df.iloc[idx]['story'],
|
| 45 |
+
'visible_text_or_brandings': df.iloc[idx]['story'],
|
| 46 |
+
'likesCount': df.iloc[idx]['likesCount'],
|
| 47 |
+
'commentCount': df.iloc[idx]['commentCount'],
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
inner_list = []
|
| 51 |
+
inner_list.append(f"[{res['rank']}]. The influencer name is: **{res['username']}** — Likes: **{res['likesCount']}**, Comments: **{res['commentCount']}**")
|
| 52 |
+
inner_list.append(f"The story of that particular video is:\n{res['story']}")
|
| 53 |
+
inner_list.append(f"The branding or promotion done is:\n{res['visible_text_or_brandings']}")
|
| 54 |
+
|
| 55 |
+
outer_list.append(inner_list)
|
| 56 |
+
|
| 57 |
+
return str(outer_list)
|
ideation_agent/utils/utils.py
ADDED
|
File without changes
|