Spaces:
Sleeping
Sleeping
Commit ·
55dd1f8
0
Parent(s):
first commit
Browse files- .gitignore +12 -0
- config.py +69 -0
- example.json +7 -0
- journal.txt +18 -0
- metadata.ipynb +0 -0
- overall_problemdesc.json +0 -0
- overall_specific_problempair.json +0 -0
- requirements.txt +148 -0
- structured_output_updated.json +0 -0
- test.ipynb +0 -0
- test.json +0 -0
- tp_final.ipynb +0 -0
- tp_final.py +447 -0
- utils.py +68 -0
.gitignore
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Python cache
|
| 2 |
+
__pycache__/
|
| 3 |
+
|
| 4 |
+
# Virtual Environment
|
| 5 |
+
calibre-env/
|
| 6 |
+
|
| 7 |
+
# Chroma DB databases
|
| 8 |
+
chroma_db_*/
|
| 9 |
+
|
| 10 |
+
# Other common Python files to ignore
|
| 11 |
+
.env
|
| 12 |
+
*.pyc
|
config.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from utils import get_file_data
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
# user_journal = get_file_data("journal.txt")
|
| 6 |
+
# example = get_file_data("example.json")
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
# direcindirecprompt = f'''
|
| 11 |
+
# I'll be giving you a journal entry written by a user. Your task is to extract out problems being faced by the user in the following format:
|
| 12 |
+
# {{
|
| 13 |
+
# "Overall Problem 1": ["Specific reason1 - reason why it was created", "Specific reason2 - reason why it was created"],
|
| 14 |
+
# "Overall Problem 2": ["Specific reason1 - reason why it was created"],
|
| 15 |
+
# }}
|
| 16 |
+
# I'll give you an example how this overall - specific problem pair looks like. Here you'll see that the heading (single word is the overall problem), then we have the reasons why it was created
|
| 17 |
+
# here is the overall - specific problem pair: {example}
|
| 18 |
+
# Obviusly a single overall problem can have multiple specific reasons why it was created. Put it in the exact format as shown above.
|
| 19 |
+
# Also, multiple overall problems can share a common specific reason why it was created. In that case, just repeat the specific reason under all of them.
|
| 20 |
+
# Here is the user text you have to analyse: {user_journal}
|
| 21 |
+
# Output strictly in the format given to you no extra symbols or words or anything
|
| 22 |
+
|
| 23 |
+
'''
|
| 24 |
+
|
| 25 |
+
# if os.path.getsize("overall_specific_problempair.json") != 0:
|
| 26 |
+
# user_problem = get_file_data("overall_specific_problempair.json")
|
| 27 |
+
# # print("File is empty")
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
# directdesc = f'''
|
| 31 |
+
# So i am giving you the iverall problems that are being faced by the user. Here it is: {user_problem.keys()}
|
| 32 |
+
# Now I want you to generate a 2-3 line summary/description for each of the problems. It shuold indicate what effect it has on the user's body and mind.
|
| 33 |
+
# So basically I want to perform a cosine similarity between this description that you give and a task dataset that has multiple tasks and they have their own descriptions of what they are able to cure
|
| 34 |
+
# So, If you write a good description for each overall problem, then I can match it with the task dataset descriptions to find the best matching tasks for the user.
|
| 35 |
+
# Here are examples of what is present int the task dataset descriptions:
|
| 36 |
+
# "Nadi Shodhana (Alternate Nostril Breathing)": {{
|
| 37 |
+
# "Stress": [
|
| 38 |
+
# "Balances left/right brain hemispheres for nervous system equilibrium",
|
| 39 |
+
# "Reduces cortisol by 27% through symmetrical breathing patterns",
|
| 40 |
+
# "Creates instant mental clarity during decision fatigue"
|
| 41 |
+
# ],
|
| 42 |
+
# "Emotions": [
|
| 43 |
+
# "Harmonizes emotional extremes by balancing solar/moon energies",
|
| 44 |
+
# "Resets emotional reactivity through prefrontal cortex activation",
|
| 45 |
+
# "Integrates logical and intuitive aspects of awareness"
|
| 46 |
+
# ],
|
| 47 |
+
# }}
|
| 48 |
+
# "Bakasana (Crow Pose)": {{
|
| 49 |
+
# "Focus": [
|
| 50 |
+
# "Develops laser-like concentration to prevent falling",
|
| 51 |
+
# "Trains mind-body coordination in challenging position",
|
| 52 |
+
# "Builds mental discipline through fear management"
|
| 53 |
+
# ],
|
| 54 |
+
# "Strength": [
|
| 55 |
+
# "Develops core and wrist strength simultaneously",
|
| 56 |
+
# "Tones abdominal muscles through active engagement",
|
| 57 |
+
# "Builds functional arm strength for daily activities"
|
| 58 |
+
# ],
|
| 59 |
+
# }}
|
| 60 |
+
# So, you see there is a certain way the descriptions are written for the task and hence you need to generate the descriptions for the overall problems in a similar way so that cosine similarity precisely extracts onyl those tasks which are highly relevant to the overall problems being faced by the user.
|
| 61 |
+
# Also, follow the following format strictly:
|
| 62 |
+
# {{
|
| 63 |
+
# "Overall Problem 1": ["Description"]
|
| 64 |
+
# "Overall Problem 2": ["Description"]
|
| 65 |
+
# }}
|
| 66 |
+
|
| 67 |
+
# Remember to output not anything else what is said, also don't use veyr veyr complicated words. You can use some technical words but keep it simple and precise otherwise if those words are present in the task dataset then cosine similaity will be very less.
|
| 68 |
+
# also, replace "Overall Problem 1" with the problem name for which description is being written
|
| 69 |
+
# '''
|
example.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"Axienty":["User is feeling that their might be no one to understand or console him","user recieved a mail from a boss or professor saying “We need to talk"],
|
| 3 |
+
"Sleepness":["User is having trouble falling asleep at night","User said that couldn't sleep till 4 am and then had an interview in the early morning"],
|
| 4 |
+
"Procrastination":["User mentioned that they keep scrolling social media instead of completing deadline tasks"],
|
| 5 |
+
"Depression":["User mentioned stopped feeling excited about hobbies, sports, games, or hanging out."]
|
| 6 |
+
|
| 7 |
+
}
|
journal.txt
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
So i joined an American company. It was a beautiful experience when i was finally able to work exact office hours and where we were treated like adults and not kids.
|
| 2 |
+
No shouting, no yelling during meeting. Politely giving us our tasks, and taking an update only after deadline. Even if deadline is missed, instead of arguing, they tried to find out why did it happen and what they can do to help reach it the next time. All the help was provided without ever having any issue with each other. Colleagues are great and helpful.
|
| 3 |
+
Every morning i was eager to work and woke up with enthusiasm
|
| 4 |
+
But this lasted only until they decided to introduce a mediatory between us.
|
| 5 |
+
AN INDIAN MANAGER
|
| 6 |
+
We all knew how indian tendency is regarrding work culture, and our fears came true.
|
| 7 |
+
The manager now wanted to control all the things we did. On top of that he started doubting us whether we are slacking off work. So he asked us to timetrack all our activities while at home. Started delegating his own work to us which wasnt even in the job profile. Soon the politics started when he decided to involve top management even in low level discussion so that his views are enforced. On top of that all his mistakes that delay work are quitely not recorded on anything.
|
| 8 |
+
Messaging us at odd times after office hours and expecting us to work late at night is very 'casual' and signs of dedicated employee. The attitude of 'toh kya hua' is affecting very negatively.
|
| 9 |
+
I did not for a second ever imagined that such a wonderful experience of working in a great company could be destroyed by 1 person. The work culture that i left with previous company has now caught up to me again.
|
| 10 |
+
This is one of the biggest reason i am trying to leave India and find a job elsewhere , where even if pay is low i'll be able to live peacefully.
|
| 11 |
+
Four years. Three unicorn startups. Multiple cities. And yet, here I am, sitting at my desk, wondering why this part of corporate life feels like navigating a maze blindfolded. Let me vent—because maybe I’m not alone?
|
| 12 |
+
“Hindi hai, bro? Cool, let’s switch.” Imagine walking into a meeting that starts with a polite “How’s your day?” in English, only for the next 30 minutes to dissolve into rapid-fire Hindi. Jokes fly, ideas bounce, and you’re just…nodding. Not because you agree, but because you’re lost. You’re South Indian, Northeast, or from a region where Hindi isn’t your mother tongue. You’ve tried learning it—really!—but fluency? The slang? The casual wit that makes everyone laugh? It’s like trying to catch smoke with your hands.
|
| 13 |
+
The worst part? The bonding. Chai breaks, lunch tables, even Slack threads—suddenly, you’re the outsider in your own office. Colleagues bond over shared references, memes, and inside jokes you can’t decode. You smile awkwardly, laugh a beat too late. It’s not malice; it’s just…habit. But when promotions hinge on “culture fit,” how do you fit into a culture that feels linguistically gated?
|
| 14 |
+
2. “No Smoke? No Drink? No Seat at the Table.” Here’s the other “unofficial rulebook”: smoke breaks = networking gold. Every hour, the balcony fills with folks puffing away, discussing projects, venting about managers, or just…chatting. You don’t smoke? Congrats on the healthy lungs! Now enjoy staring at your screen while career-critical conversations happen without you.
|
| 15 |
+
And office parties? If you’re not clinking glasses, you’re a ghost. “Why aren’t you drinking?!” becomes the anthem of the night. Decline politely, and suddenly, you’re the “boring one.” The FOMO isn’t about the alcohol—it’s about the camaraderie that evaporates when you’re not “one of them.”
|
| 16 |
+
So…Is It Just Me? I’m not judging anyone’s choices. Smoke if you want. Drink if you like. Speak whatever language feels like home. But when exclusion becomes the collateral damage of these habits, it’s exhausting. You start questioning: Is my career growth tied to my ability to chain-smoke or crack jokes in Hindi?
|
| 17 |
+
To anyone else sitting silently in meetings, faking laughs, or skipping parties to avoid the peer pressure—I see you. This isn’t about “snowflake syndrome.” It’s about workplaces feeling like high school cliques, where your worth hinges on things that have nothing to do with your skills.
|
| 18 |
+
I feel sick knowing how these cronies abuse the shit out of us, rob us from our money. CEO Narayan Murthy wants us to work for 70 hours per week but the dude himself can't see anything fucking straight, cross-eyed loser. We should just work for 10 hours per week max and call it a day. This 9-5 is making us depressed. We also need to stop breeding like cockroaches because at least, unlike humans, cockroaches can walk over themselves, but humans can't. I blame the system and schools such as City International School which looks like a fucking warehouse which you have to pay 89k rupees for annually, where's the infrastructure man? Nigerian schools have better infrastructure and better toilets which don't stink of piss. Also, school boards such as ICSE are to blame for this slave mentality. Also, when are we going to employ a 1 child policy? We should be having a king culture rather than a fucking slave culture which is glorified in this shit country. No wonder people are crippled nowadays. They are perpetually stressed. The average Indian man goes bald by 30 and grow a tummy like the laughing Buddha. Tax the rich CEOs and not the common man, why don't we Indians unionize and fight for our goddamn rights huh?
|
metadata.ipynb
ADDED
|
File without changes
|
overall_problemdesc.json
ADDED
|
File without changes
|
overall_specific_problempair.json
ADDED
|
File without changes
|
requirements.txt
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
aiohappyeyeballs==2.6.1
|
| 2 |
+
aiohttp==3.13.2
|
| 3 |
+
aiosignal==1.4.0
|
| 4 |
+
annotated-doc==0.0.4
|
| 5 |
+
annotated-types==0.7.0
|
| 6 |
+
annoy==1.17.3
|
| 7 |
+
anyio==4.12.0
|
| 8 |
+
asttokens==3.0.1
|
| 9 |
+
attrs==25.4.0
|
| 10 |
+
certifi==2025.11.12
|
| 11 |
+
charset-normalizer==3.4.4
|
| 12 |
+
click==8.3.1
|
| 13 |
+
coloredlogs==15.0.1
|
| 14 |
+
comm==0.2.3
|
| 15 |
+
dataclasses-json==0.6.7
|
| 16 |
+
debugpy==1.8.17
|
| 17 |
+
decorator==5.2.1
|
| 18 |
+
distlib==0.4.0
|
| 19 |
+
distro==1.9.0
|
| 20 |
+
dnspython==2.8.0
|
| 21 |
+
dotenv==0.9.9
|
| 22 |
+
executing==2.2.1
|
| 23 |
+
faiss-cpu==1.13.1
|
| 24 |
+
fastapi==0.124.2
|
| 25 |
+
fastembed==0.6.0
|
| 26 |
+
filelock==3.20.0
|
| 27 |
+
filetype==1.2.0
|
| 28 |
+
flatbuffers==25.9.23
|
| 29 |
+
frozenlist==1.8.0
|
| 30 |
+
fsspec==2025.12.0
|
| 31 |
+
greenlet==3.3.0
|
| 32 |
+
groq==0.37.1
|
| 33 |
+
h11==0.16.0
|
| 34 |
+
hf-xet==1.2.0
|
| 35 |
+
httpcore==1.0.9
|
| 36 |
+
httpx==0.28.1
|
| 37 |
+
httpx-sse==0.4.3
|
| 38 |
+
huggingface-hub==0.36.0
|
| 39 |
+
humanfriendly==10.0
|
| 40 |
+
idna==3.11
|
| 41 |
+
ipykernel==7.1.0
|
| 42 |
+
ipython==9.8.0
|
| 43 |
+
ipython_pygments_lexers==1.1.1
|
| 44 |
+
jedi==0.19.2
|
| 45 |
+
Jinja2==3.1.6
|
| 46 |
+
joblib==1.5.2
|
| 47 |
+
jsonlines==4.0.0
|
| 48 |
+
jsonpatch==1.33
|
| 49 |
+
jsonpointer==3.0.0
|
| 50 |
+
jsonschema==4.25.1
|
| 51 |
+
jsonschema-specifications==2025.9.1
|
| 52 |
+
jupyter_client==8.6.3
|
| 53 |
+
jupyter_core==5.9.1
|
| 54 |
+
langchain==1.1.2
|
| 55 |
+
langchain-classic==1.0.0
|
| 56 |
+
langchain-community==0.4.1
|
| 57 |
+
langchain-core==1.1.1
|
| 58 |
+
langchain-groq==1.1.0
|
| 59 |
+
langchain-nomic==1.0.1
|
| 60 |
+
langchain-nvidia-ai-endpoints==1.0.0
|
| 61 |
+
langchain-text-splitters==1.0.0
|
| 62 |
+
langgraph==1.0.4
|
| 63 |
+
langgraph-checkpoint==3.0.1
|
| 64 |
+
langgraph-prebuilt==1.0.5
|
| 65 |
+
langgraph-sdk==0.2.14
|
| 66 |
+
langsmith==0.4.56
|
| 67 |
+
lark==1.3.1
|
| 68 |
+
loguru==0.7.3
|
| 69 |
+
markdown-it-py==4.0.0
|
| 70 |
+
MarkupSafe==3.0.3
|
| 71 |
+
marshmallow==3.26.1
|
| 72 |
+
matplotlib-inline==0.2.1
|
| 73 |
+
mdurl==0.1.2
|
| 74 |
+
mmh3==5.2.0
|
| 75 |
+
mpmath==1.3.0
|
| 76 |
+
multidict==6.7.0
|
| 77 |
+
mypy_extensions==1.1.0
|
| 78 |
+
nest-asyncio==1.6.0
|
| 79 |
+
nomic==3.9.0
|
| 80 |
+
numpy==2.3.5
|
| 81 |
+
onnxruntime==1.23.2
|
| 82 |
+
orjson==3.11.5
|
| 83 |
+
ormsgpack==1.12.0
|
| 84 |
+
packaging==25.0
|
| 85 |
+
pandas==2.3.3
|
| 86 |
+
parso==0.8.5
|
| 87 |
+
perplexityai==0.22.0
|
| 88 |
+
pexpect==4.9.0
|
| 89 |
+
pillow==11.3.0
|
| 90 |
+
platformdirs==4.5.1
|
| 91 |
+
prompt_toolkit==3.0.52
|
| 92 |
+
propcache==0.4.1
|
| 93 |
+
protobuf==6.33.2
|
| 94 |
+
psutil==7.1.3
|
| 95 |
+
ptyprocess==0.7.0
|
| 96 |
+
pure_eval==0.2.3
|
| 97 |
+
py_rust_stemmers==0.1.5
|
| 98 |
+
pyarrow==22.0.0
|
| 99 |
+
pydantic==2.12.5
|
| 100 |
+
pydantic-settings==2.12.0
|
| 101 |
+
pydantic_core==2.41.5
|
| 102 |
+
Pygments==2.19.2
|
| 103 |
+
PyJWT==2.10.1
|
| 104 |
+
pymongo==4.15.5
|
| 105 |
+
python-dateutil==2.9.0.post0
|
| 106 |
+
python-dotenv==1.2.1
|
| 107 |
+
pytz==2025.2
|
| 108 |
+
PyYAML==6.0.3
|
| 109 |
+
pyzmq==27.1.0
|
| 110 |
+
referencing==0.37.0
|
| 111 |
+
regex==2025.11.3
|
| 112 |
+
requests==2.32.5
|
| 113 |
+
requests-toolbelt==1.0.0
|
| 114 |
+
rich==14.2.0
|
| 115 |
+
rpds-py==0.30.0
|
| 116 |
+
scikit-learn==1.8.0
|
| 117 |
+
scipy==1.16.3
|
| 118 |
+
shellingham==1.5.4
|
| 119 |
+
simpleeval==1.0.3
|
| 120 |
+
six==1.17.0
|
| 121 |
+
sniffio==1.3.1
|
| 122 |
+
SQLAlchemy==2.0.44
|
| 123 |
+
stack-data==0.6.3
|
| 124 |
+
starlette==0.50.0
|
| 125 |
+
sympy==1.14.0
|
| 126 |
+
tenacity==9.1.2
|
| 127 |
+
threadpoolctl==3.6.0
|
| 128 |
+
tiktoken==0.12.0
|
| 129 |
+
tokenizers==0.22.1
|
| 130 |
+
tornado==6.5.2
|
| 131 |
+
tqdm==4.67.1
|
| 132 |
+
traitlets==5.14.3
|
| 133 |
+
typer==0.20.0
|
| 134 |
+
typing-inspect==0.9.0
|
| 135 |
+
typing-inspection==0.4.2
|
| 136 |
+
typing_extensions==4.15.0
|
| 137 |
+
tzdata==2025.2
|
| 138 |
+
u==1.0.4
|
| 139 |
+
urllib3==2.6.0
|
| 140 |
+
uuid_utils==0.12.0
|
| 141 |
+
uvicorn==0.38.0
|
| 142 |
+
virtualenv==20.35.4
|
| 143 |
+
virtualenvwrapper-win==1.2.7
|
| 144 |
+
watchdog==6.0.0
|
| 145 |
+
wcwidth==0.2.14
|
| 146 |
+
xxhash==3.6.0
|
| 147 |
+
yarl==1.22.0
|
| 148 |
+
zstandard==0.25.0
|
structured_output_updated.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
test.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
test.json
ADDED
|
File without changes
|
tp_final.ipynb
ADDED
|
File without changes
|
tp_final.py
ADDED
|
@@ -0,0 +1,447 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# from itertools import islice
|
| 2 |
+
# import itertools
|
| 3 |
+
# import json
|
| 4 |
+
# import re
|
| 5 |
+
# from groq import Groq
|
| 6 |
+
# from config import direcindirecprompt
|
| 7 |
+
# from utils import groq_calls,write_to_file, get_file_data, get_mongo_collection
|
| 8 |
+
# from sklearn.feature_extraction.text import TfidfVectorizer
|
| 9 |
+
# from sklearn.metrics.pairwise import cosine_similarity
|
| 10 |
+
# import numpy as np
|
| 11 |
+
# from datetime import datetime
|
| 12 |
+
|
| 13 |
+
# '''
|
| 14 |
+
# The architecture is like this
|
| 15 |
+
|
| 16 |
+
# '''
|
| 17 |
+
# collection = get_mongo_collection()
|
| 18 |
+
|
| 19 |
+
# def main():
|
| 20 |
+
# # user_journal = get_file_data("journal.txt")
|
| 21 |
+
# # example = get_file_data("example.json")
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
# # prompt= direcindirecprompt
|
| 25 |
+
# direcindirecgroq_response = groq_calls(direcindirecprompt)
|
| 26 |
+
# # parsed_json = json.loads(direcindirecgroq_response)
|
| 27 |
+
# # print(parsed_json)
|
| 28 |
+
# # write_to_file("overall_specific_problempair.json",direcindirecgroq_response)
|
| 29 |
+
|
| 30 |
+
# guideprompt = f'''
|
| 31 |
+
# So, I am giving a set of direct-indirect problem pair, here it is: {direcindirecgroq_response}
|
| 32 |
+
# Now, these are some of the issues the user is facing in his daily life. Assume that you're a very skilled psychologist and help solve the problems faced
|
| 33 |
+
# by the users in their daily life by recommending them a set of guidelines of what they could follow or practice in their daily life to keep themselves calm
|
| 34 |
+
# These guidelines should not be very long, some short recommendations which can be followed even when the person is seated on his chair in office
|
| 35 |
+
# or any where else. Basically the guidelines should be accessible/doable any time.
|
| 36 |
+
# Give 1-2 guidelines for each of the problem that the user is facing as in the problem pair procided to you
|
| 37 |
+
|
| 38 |
+
# Here are some examples of how guidelines could look like
|
| 39 |
+
# -Take short breaks for deep breathing, walk in the present, and journal three things you're grateful for daily to shift perspective.
|
| 40 |
+
# -Dedicate even 10 minutes to a hobby or enjoyable activity to recharge.
|
| 41 |
+
# -Reduce news consumption and screen time, especially before bed, to avoid overwhelm.
|
| 42 |
+
|
| 43 |
+
# Above are some examples only, but remember whatever you suggest should be relevant to the problems the user is facing
|
| 44 |
+
# Final output should be in JSON format only
|
| 45 |
+
# final output should start and end like this
|
| 46 |
+
# {{
|
| 47 |
+
# problem1:["Set dedicated focus blocks (e.g., 90‑min) and log only the block end to satisfy reporting.","Use a private tracker to note progress, then share a concise daily summary with the manager."]
|
| 48 |
+
# }}
|
| 49 |
+
# '''
|
| 50 |
+
|
| 51 |
+
# guidegroq_response = groq_calls(guideprompt)
|
| 52 |
+
# # with open("test.json", "w") as f:
|
| 53 |
+
# # f.write(guidegroq_response)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
# with open("structured_output_updated.json","r") as f:
|
| 59 |
+
# task_dataset = json.load(f)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
# result = {}
|
| 64 |
+
# # task_dataset = test
|
| 65 |
+
# yogabranches = list(task_dataset["Yoga"]["branches"].keys())
|
| 66 |
+
# for branch in yogabranches:
|
| 67 |
+
# if branch == "Asana":
|
| 68 |
+
# postures = list(task_dataset["Yoga"]["branches"][branch].keys())
|
| 69 |
+
# # print(postures)
|
| 70 |
+
# result[f"{branch}s"] = {}
|
| 71 |
+
# for posture in postures:
|
| 72 |
+
# lst = list(task_dataset["Yoga"]["branches"][branch][posture].keys())
|
| 73 |
+
# for pose in lst:
|
| 74 |
+
# # # poses.append(task_dataset["Yoga"]["branches"][branch][posture][pose])
|
| 75 |
+
# # print(task_dataset["Yoga"]["branches"][branch][posture][pose])
|
| 76 |
+
# sliced_items = list(task_dataset["Yoga"]["branches"][branch][posture][pose].values())[:2]
|
| 77 |
+
# result[f"{branch}s"][pose] = list(itertools.chain.from_iterable(sliced_items))
|
| 78 |
+
# else:
|
| 79 |
+
# postures = list(task_dataset["Yoga"]["branches"][branch].keys())
|
| 80 |
+
# # print(postures)
|
| 81 |
+
# result[f"{branch}s"] = {}
|
| 82 |
+
# for posture in postures:
|
| 83 |
+
# lst = list(task_dataset["Yoga"]["branches"][branch][posture].values())[:2]
|
| 84 |
+
# result[f"{branch}s"][posture] = list(itertools.chain.from_iterable(lst))
|
| 85 |
+
|
| 86 |
+
# # with open("overall_specific_problempair.json","r",encoding = "utf-8") as f:
|
| 87 |
+
# # user_problem = json.load(f)
|
| 88 |
+
|
| 89 |
+
# user_problem = json.loads(direcindirecgroq_response)
|
| 90 |
+
|
| 91 |
+
# cosineprompt = f'''
|
| 92 |
+
# So i am giving you the iverall problems that are being faced by the user. Here it is: {user_problem.keys()}
|
| 93 |
+
# Now I want you to generate a 2-3 line summary/description for each of the problems. It shuold indicate what effect it has on the user's body and mind.
|
| 94 |
+
# So basically I want to perform a cosine similarity between this description that you give and a task dataset that has multiple tasks and they have their own descriptions of what they are able to cure
|
| 95 |
+
# So, If you write a good description for each overall problem, then I can match it with the task dataset descriptions to find the best matching tasks for the user.
|
| 96 |
+
# Here are examples of what is present in the task dataset descriptions:
|
| 97 |
+
# "Nadi Shodhana (Alternate Nostril Breathing)": {{
|
| 98 |
+
# "Stress": [
|
| 99 |
+
# "Balances left/right brain hemispheres for nervous system equilibrium",
|
| 100 |
+
# "Reduces cortisol by 27% through symmetrical breathing patterns",
|
| 101 |
+
# "Creates instant mental clarity during decision fatigue"
|
| 102 |
+
# ],
|
| 103 |
+
# "Emotions": [
|
| 104 |
+
# "Harmonizes emotional extremes by balancing solar/moon energies",
|
| 105 |
+
# "Resets emotional reactivity through prefrontal cortex activation",
|
| 106 |
+
# "Integrates logical and intuitive aspects of awareness"
|
| 107 |
+
# ],
|
| 108 |
+
# }}
|
| 109 |
+
# "Bakasana (Crow Pose)": {{
|
| 110 |
+
# "Focus": [
|
| 111 |
+
# "Develops laser-like concentration to prevent falling",
|
| 112 |
+
# "Trains mind-body coordination in challenging position",
|
| 113 |
+
# "Builds mental discipline through fear management"
|
| 114 |
+
# ],
|
| 115 |
+
# "Strength": [
|
| 116 |
+
# "Develops core and wrist strength simultaneously",
|
| 117 |
+
# "Tones abdominal muscles through active engagement",
|
| 118 |
+
# "Builds functional arm strength for daily activities"
|
| 119 |
+
# ],
|
| 120 |
+
# }}
|
| 121 |
+
# So, you see there is a certain way the descriptions are written for the task and hence you need to generate the descriptions for the overall problems in a similar way so that cosine similarity precisely extracts onyl those tasks which are highly relevant to the overall problems being faced by the user.
|
| 122 |
+
# Also, follow the following format strictly:
|
| 123 |
+
# {{
|
| 124 |
+
# "Overall Problem 1": ["Description"]
|
| 125 |
+
# "Overall Problem 2": ["Description"]
|
| 126 |
+
# }}
|
| 127 |
+
|
| 128 |
+
# Remember to output not anything else what is said, also don't use very complicated words. You can use some technical words but keep it simple and precise otherwise if those words are present in the task dataset then cosine similaity will be very less.
|
| 129 |
+
# also, replace "Overall Problem 1" with the problem name for which description is being written
|
| 130 |
+
# '''
|
| 131 |
+
|
| 132 |
+
# cosinegroq_response = groq_calls(cosineprompt)
|
| 133 |
+
# # with open("test.json","w") as f:
|
| 134 |
+
# # f.write(cosinegroq_response)
|
| 135 |
+
# parsed_json = json.loads(cosinegroq_response)
|
| 136 |
+
# # write_to_file("overall_problemdesc.json",cosinegroq_response)
|
| 137 |
+
|
| 138 |
+
# user_problem = parsed_json
|
| 139 |
+
# user_problem_text = " ".join(sum(user_problem.values(), []))
|
| 140 |
+
# tasks = {}
|
| 141 |
+
# for branch in result.keys():
|
| 142 |
+
# for pose in result[branch].keys():
|
| 143 |
+
# documents = []
|
| 144 |
+
# # print(result[branch][pose])
|
| 145 |
+
# desc = ", ".join(result[branch][pose])
|
| 146 |
+
# # print(desc)
|
| 147 |
+
# documents.append(desc)
|
| 148 |
+
# documents.append(user_problem_text)
|
| 149 |
+
|
| 150 |
+
# # documents[0] ='Micromanagement scrutiny, raising heart rate and restlessness. leading to tight muscles and frequent headaches. Language barriers and frustration, making communication difficult. Shallow breathing and lowering confidence and increasing social anxiety. Social exclusion triggers. It reduces heart rate variability and raises cortisol, leaving the body stressed. Burnout produces persistent fatigue, headaches, and muscle aches. Focus and decision‑making suffer, while sleep quality drops and inflammation markers rise. Discrimination induces emotional distress and self‑doubt, making the mind hypervigilant and anxious. stressing the body.'
|
| 151 |
+
# vectorizer = TfidfVectorizer(stop_words='english')
|
| 152 |
+
# tfidf_matrix = vectorizer.fit_transform(documents)
|
| 153 |
+
# similarities = cosine_similarity(tfidf_matrix[-1], tfidf_matrix[:-1]).flatten()
|
| 154 |
+
# tasks[f"{branch}({pose})"]= similarities
|
| 155 |
+
# # print(f"{branch} --> ", f"{pose} --> ", similarities)
|
| 156 |
+
|
| 157 |
+
# print(documents)
|
| 158 |
+
# sorted_tasks = dict(sorted(tasks.items(), key=lambda item: item[1], reverse=True))
|
| 159 |
+
# print(list(sorted_tasks.items())[:5])
|
| 160 |
+
|
| 161 |
+
# username = "sameer" #in production extract the username
|
| 162 |
+
|
| 163 |
+
# if collection is not None:
|
| 164 |
+
# chat_document = {
|
| 165 |
+
# "user_id": username,
|
| 166 |
+
# "timestamp": datetime.now(),
|
| 167 |
+
# "problemdesc": direcindirecgroq_response,
|
| 168 |
+
# "guidelines":guidegroq_response,
|
| 169 |
+
# "tasks": list(sorted_tasks.keys())[:5]
|
| 170 |
+
|
| 171 |
+
# }
|
| 172 |
+
|
| 173 |
+
# try:
|
| 174 |
+
# collection.insert_one(chat_document)
|
| 175 |
+
# print("Saved to DB")
|
| 176 |
+
# except Exception as e:
|
| 177 |
+
# print(f"Failed to save to DB: {e}")
|
| 178 |
+
|
| 179 |
+
# if __name__ == "__main__":
|
| 180 |
+
# main()
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
from fastapi import FastAPI, HTTPException
|
| 188 |
+
from pydantic import BaseModel
|
| 189 |
+
from typing import Optional, List, Dict, Any
|
| 190 |
+
from itertools import islice
|
| 191 |
+
import itertools
|
| 192 |
+
import json
|
| 193 |
+
import re
|
| 194 |
+
from datetime import datetime
|
| 195 |
+
|
| 196 |
+
# ML and Math imports
|
| 197 |
+
from sklearn.feature_extraction.text import TfidfVectorizer
|
| 198 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
| 199 |
+
import numpy as np
|
| 200 |
+
|
| 201 |
+
# Custom modules (assuming these exist in your project structure)
|
| 202 |
+
from groq import Groq
|
| 203 |
+
# from config import direcindirecprompt
|
| 204 |
+
from utils import groq_calls, write_to_file, get_file_data, get_mongo_collection
|
| 205 |
+
import uvicorn
|
| 206 |
+
|
| 207 |
+
# Initialize FastAPI app
|
| 208 |
+
app = FastAPI(title="Vidur Yoga Recommendation API")
|
| 209 |
+
|
| 210 |
+
# Initialize DB connection globally (or within dependency)
|
| 211 |
+
try:
|
| 212 |
+
collection = get_mongo_collection()
|
| 213 |
+
except Exception as e:
|
| 214 |
+
print(f"Warning: Database connection failed on startup: {e}")
|
| 215 |
+
collection = None
|
| 216 |
+
|
| 217 |
+
# --- Pydantic Models for Request/Response ---
|
| 218 |
+
class AnalysisRequest(BaseModel):
|
| 219 |
+
username: str = "sameer" # Default as per your code
|
| 220 |
+
user_journal: str
|
| 221 |
+
# Add other fields here if you need to pass user_journal dynamically later
|
| 222 |
+
|
| 223 |
+
class AnalysisResponse(BaseModel):
|
| 224 |
+
status: str
|
| 225 |
+
username: str
|
| 226 |
+
guidelines: Dict[str, Any]
|
| 227 |
+
recommended_tasks: List[str]
|
| 228 |
+
timestamp: datetime
|
| 229 |
+
|
| 230 |
+
@app.post("/analyze-tasks", response_model=AnalysisResponse)
|
| 231 |
+
def generate_analysis(request: AnalysisRequest):
|
| 232 |
+
"""
|
| 233 |
+
Executes the analysis pipeline:
|
| 234 |
+
1. Identifies direct/indirect problems via Groq.
|
| 235 |
+
2. Generates guidelines via Groq.
|
| 236 |
+
3. Matches problems to Yoga tasks using TF-IDF/Cosine Similarity.
|
| 237 |
+
4. Saves to MongoDB.
|
| 238 |
+
"""
|
| 239 |
+
|
| 240 |
+
example = get_file_data("example.json")
|
| 241 |
+
direcindirecprompt = f'''
|
| 242 |
+
I'll be giving you a journal entry written by a user. Your task is to extract out problems being faced by the user in the following format:
|
| 243 |
+
{{
|
| 244 |
+
"Overall Problem 1": ["Specific reason1 - reason why it was created", "Specific reason2 - reason why it was created"],
|
| 245 |
+
"Overall Problem 2": ["Specific reason1 - reason why it was created"],
|
| 246 |
+
}}
|
| 247 |
+
I'll give you an example how this overall - specific problem pair looks like. Here you'll see that the heading (single word is the overall problem), then we have the reasons why it was created
|
| 248 |
+
here is the overall - specific problem pair: {example}
|
| 249 |
+
Obviusly a single overall problem can have multiple specific reasons why it was created. Put it in the exact format as shown above.
|
| 250 |
+
Also, multiple overall problems can share a common specific reason why it was created. In that case, just repeat the specific reason under all of them.
|
| 251 |
+
Here is the user text you have to analyse: {request.user_journal}
|
| 252 |
+
Output strictly in the format given to you no extra symbols or words or anything
|
| 253 |
+
'''
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
# 1. Direct/Indirect Problem Identification
|
| 257 |
+
try:
|
| 258 |
+
# Assuming direcindirecprompt is imported from config
|
| 259 |
+
|
| 260 |
+
direcindirecgroq_response = groq_calls(direcindirecprompt)
|
| 261 |
+
# If the response acts as a JSON source, we try to parse it to ensure validity
|
| 262 |
+
# parsed_check = json.loads(direcindirecgroq_response)
|
| 263 |
+
except Exception as e:
|
| 264 |
+
raise HTTPException(status_code=502, detail=f"Groq API Error (Problem Identification): {str(e)}")
|
| 265 |
+
|
| 266 |
+
# 2. Guidelines Generation
|
| 267 |
+
try:
|
| 268 |
+
guideprompt = f'''
|
| 269 |
+
So, I am giving a set of direct-indirect problem pair, here it is: {direcindirecgroq_response}
|
| 270 |
+
Now, these are some of the issues the user is facing in his daily life. Assume that you're a very skilled psychologist and help solve the problems faced
|
| 271 |
+
by the users in their daily life by recommending them a set of guidelines of what they could follow or practice in their daily life to keep themselves calm
|
| 272 |
+
These guidelines should not be very long, some short recommendations which can be followed even when the person is seated on his chair in office
|
| 273 |
+
or any where else. Basically the guidelines should be accessible/doable any time.
|
| 274 |
+
Give 1-2 guidelines for each of the problem that the user is facing as in the problem pair procided to you
|
| 275 |
+
|
| 276 |
+
Here are some examples of how guidelines could look like
|
| 277 |
+
-Take short breaks for deep breathing, walk in the present, and journal three things you're grateful for daily to shift perspective.
|
| 278 |
+
-Dedicate even 10 minutes to a hobby or enjoyable activity to recharge.
|
| 279 |
+
-Reduce news consumption and screen time, especially before bed, to avoid overwhelm.
|
| 280 |
+
|
| 281 |
+
Above are some examples only, but remember whatever you suggest should be relevant to the problems the user is facing
|
| 282 |
+
Final output should be in JSON format only
|
| 283 |
+
final output should start and end like this
|
| 284 |
+
{{
|
| 285 |
+
"problem1": ["Set dedicated focus blocks...", "Use a private tracker..."]
|
| 286 |
+
}}
|
| 287 |
+
'''
|
| 288 |
+
guidegroq_response = groq_calls(guideprompt)
|
| 289 |
+
except Exception as e:
|
| 290 |
+
raise HTTPException(status_code=502, detail=f"Groq API Error (Guideline Generation): {str(e)}")
|
| 291 |
+
|
| 292 |
+
# 3. Load Task Dataset
|
| 293 |
+
try:
|
| 294 |
+
with open("structured_output_updated.json", "r") as f:
|
| 295 |
+
task_dataset = json.load(f)
|
| 296 |
+
except FileNotFoundError:
|
| 297 |
+
raise HTTPException(status_code=500, detail="Server Error: 'structured_output_updated.json' file not found.")
|
| 298 |
+
except json.JSONDecodeError:
|
| 299 |
+
raise HTTPException(status_code=500, detail="Server Error: Failed to decode task dataset JSON.")
|
| 300 |
+
|
| 301 |
+
# 4. Process Yoga Branches (Business Logic)
|
| 302 |
+
try:
|
| 303 |
+
result = {}
|
| 304 |
+
yogabranches = list(task_dataset["Yoga"]["branches"].keys())
|
| 305 |
+
|
| 306 |
+
for branch in yogabranches:
|
| 307 |
+
if branch == "Asana":
|
| 308 |
+
postures = list(task_dataset["Yoga"]["branches"][branch].keys())
|
| 309 |
+
result[f"{branch}s"] = {}
|
| 310 |
+
for posture in postures:
|
| 311 |
+
# Depending on structure, sometimes keys are poses
|
| 312 |
+
lst = list(task_dataset["Yoga"]["branches"][branch][posture].keys())
|
| 313 |
+
for pose in lst:
|
| 314 |
+
sliced_items = list(task_dataset["Yoga"]["branches"][branch][posture][pose].values())[:2]
|
| 315 |
+
result[f"{branch}s"][pose] = list(itertools.chain.from_iterable(sliced_items))
|
| 316 |
+
else:
|
| 317 |
+
postures = list(task_dataset["Yoga"]["branches"][branch].keys())
|
| 318 |
+
result[f"{branch}s"] = {}
|
| 319 |
+
for posture in postures:
|
| 320 |
+
lst = list(task_dataset["Yoga"]["branches"][branch][posture].values())[:2]
|
| 321 |
+
result[f"{branch}s"][posture] = list(itertools.chain.from_iterable(lst))
|
| 322 |
+
except KeyError as e:
|
| 323 |
+
raise HTTPException(status_code=500, detail=f"Data Processing Error: Key {str(e)} missing in dataset.")
|
| 324 |
+
except Exception as e:
|
| 325 |
+
raise HTTPException(status_code=500, detail=f"Data Processing Error: {str(e)}")
|
| 326 |
+
|
| 327 |
+
# 5. Cosine Similarity Preparation
|
| 328 |
+
try:
|
| 329 |
+
# We parse the response from Step 1 to get keys for the next prompt
|
| 330 |
+
user_problem_raw = json.loads(direcindirecgroq_response)
|
| 331 |
+
|
| 332 |
+
cosineprompt = f'''
|
| 333 |
+
So i am giving you the iverall problems that are being faced by the user. Here it is: {user_problem_raw.keys()}
|
| 334 |
+
Now I want you to generate a 2-3 line summary/description for each of the problems. It shuold indicate what effect it has on the user's body and mind.
|
| 335 |
+
So basically I want to perform a cosine similarity between this description that you give and a task dataset that has multiple tasks and they have their own descriptions of what they are able to cure
|
| 336 |
+
So, If you write a good description for each overall problem, then I can match it with the task dataset descriptions to find the best matching tasks for the user.
|
| 337 |
+
Here are examples of what is present in the task dataset descriptions:
|
| 338 |
+
"Nadi Shodhana (Alternate Nostril Breathing)": {{
|
| 339 |
+
"Stress": [
|
| 340 |
+
"Balances left/right brain hemispheres for nervous system equilibrium",
|
| 341 |
+
"Reduces cortisol by 27% through symmetrical breathing patterns",
|
| 342 |
+
"Creates instant mental clarity during decision fatigue"
|
| 343 |
+
],
|
| 344 |
+
"Emotions": [
|
| 345 |
+
"Harmonizes emotional extremes by balancing solar/moon energies",
|
| 346 |
+
"Resets emotional reactivity through prefrontal cortex activation",
|
| 347 |
+
"Integrates logical and intuitive aspects of awareness"
|
| 348 |
+
],
|
| 349 |
+
}}
|
| 350 |
+
"Bakasana (Crow Pose)": {{
|
| 351 |
+
"Focus": [
|
| 352 |
+
"Develops laser-like concentration to prevent falling",
|
| 353 |
+
"Trains mind-body coordination in challenging position",
|
| 354 |
+
"Builds mental discipline through fear management"
|
| 355 |
+
],
|
| 356 |
+
"Strength": [
|
| 357 |
+
"Develops core and wrist strength simultaneously",
|
| 358 |
+
"Tones abdominal muscles through active engagement",
|
| 359 |
+
"Builds functional arm strength for daily activities"
|
| 360 |
+
],
|
| 361 |
+
}}
|
| 362 |
+
So, you see there is a certain way the descriptions are written for the task and hence you need to generate the descriptions for the overall problems in a similar way so that cosine similarity precisely extracts onyl those tasks which are highly relevant to the overall problems being faced by the user.
|
| 363 |
+
Also, follow the following format strictly:
|
| 364 |
+
{{
|
| 365 |
+
"Overall Problem 1": ["Description"]
|
| 366 |
+
"Overall Problem 2": ["Description"]
|
| 367 |
+
}}
|
| 368 |
+
|
| 369 |
+
Remember to output not anything else what is said, also don't use very complicated words. You can use some technical words but keep it simple and precise otherwise if those words are present in the task dataset then cosine similaity will be very less.
|
| 370 |
+
also, replace "Overall Problem 1" with the problem name for which description is being written
|
| 371 |
+
'''
|
| 372 |
+
|
| 373 |
+
cosinegroq_response = groq_calls(cosineprompt)
|
| 374 |
+
parsed_cosine_json = json.loads(cosinegroq_response)
|
| 375 |
+
|
| 376 |
+
user_problem = parsed_cosine_json
|
| 377 |
+
user_problem_text = " ".join(sum(user_problem.values(), []))
|
| 378 |
+
|
| 379 |
+
except json.JSONDecodeError:
|
| 380 |
+
raise HTTPException(status_code=500, detail="Failed to parse JSON from Groq response (Cosine Prompt).")
|
| 381 |
+
except Exception as e:
|
| 382 |
+
raise HTTPException(status_code=500, detail=f"Error preparing Cosine Similarity data: {str(e)}")
|
| 383 |
+
|
| 384 |
+
# 6. Calculate Cosine Similarity
|
| 385 |
+
try:
|
| 386 |
+
tasks = {}
|
| 387 |
+
for branch in result.keys():
|
| 388 |
+
for pose in result[branch].keys():
|
| 389 |
+
documents = []
|
| 390 |
+
desc = ", ".join(result[branch][pose])
|
| 391 |
+
documents.append(desc)
|
| 392 |
+
documents.append(user_problem_text)
|
| 393 |
+
|
| 394 |
+
vectorizer = TfidfVectorizer(stop_words='english')
|
| 395 |
+
tfidf_matrix = vectorizer.fit_transform(documents)
|
| 396 |
+
|
| 397 |
+
# Compare the last doc (user problem) with the first doc (task desc)
|
| 398 |
+
similarities = cosine_similarity(tfidf_matrix[-1], tfidf_matrix[:-1]).flatten()
|
| 399 |
+
tasks[f"{branch}({pose})"] = similarities[0] # Take the float value
|
| 400 |
+
|
| 401 |
+
# Sort and take top 5
|
| 402 |
+
sorted_tasks = dict(sorted(tasks.items(), key=lambda item: item[1], reverse=True))
|
| 403 |
+
top_tasks = list(sorted_tasks.keys())[:5]
|
| 404 |
+
|
| 405 |
+
except Exception as e:
|
| 406 |
+
raise HTTPException(status_code=500, detail=f"Math/Vectorization Error: {str(e)}")
|
| 407 |
+
|
| 408 |
+
# 7. Database Insertion
|
| 409 |
+
chat_document = None
|
| 410 |
+
try:
|
| 411 |
+
# Try to parse guidelines string to JSON object for cleaner DB storage/Response
|
| 412 |
+
try:
|
| 413 |
+
guidelines_obj = json.loads(guidegroq_response)
|
| 414 |
+
except:
|
| 415 |
+
guidelines_obj = {"raw_text": guidegroq_response}
|
| 416 |
+
|
| 417 |
+
chat_document = {
|
| 418 |
+
"user_id": request.username,
|
| 419 |
+
"timestamp": datetime.now(),
|
| 420 |
+
"problemdesc": direcindirecgroq_response, # Storing raw response string as per original code
|
| 421 |
+
"guidelines": guidegroq_response, # Storing raw response string as per original code
|
| 422 |
+
"tasks": top_tasks
|
| 423 |
+
}
|
| 424 |
+
|
| 425 |
+
if collection is not None:
|
| 426 |
+
collection.insert_one(chat_document)
|
| 427 |
+
print("Saved to DB")
|
| 428 |
+
else:
|
| 429 |
+
print("Skipped DB save (Collection not available)")
|
| 430 |
+
|
| 431 |
+
except Exception as e:
|
| 432 |
+
# We log the DB error but might not want to fail the whole request if the calculation succeeded
|
| 433 |
+
print(f"Failed to save to DB: {e}")
|
| 434 |
+
# Note: Depending on requirements, you might want to raise HTTPException here or just proceed.
|
| 435 |
+
|
| 436 |
+
# 8. Return Response
|
| 437 |
+
return AnalysisResponse(
|
| 438 |
+
status="success",
|
| 439 |
+
username=request.username,
|
| 440 |
+
guidelines=guidelines_obj,
|
| 441 |
+
recommended_tasks=top_tasks,
|
| 442 |
+
timestamp=chat_document["timestamp"] if chat_document else datetime.now()
|
| 443 |
+
)
|
| 444 |
+
|
| 445 |
+
if __name__ == "__main__":
|
| 446 |
+
# Run the app with uvicorn
|
| 447 |
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|
utils.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import json
|
| 3 |
+
import itertools
|
| 4 |
+
from groq import Groq
|
| 5 |
+
from dotenv import load_dotenv
|
| 6 |
+
from pymongo import MongoClient
|
| 7 |
+
import certifi
|
| 8 |
+
load_dotenv()
|
| 9 |
+
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def get_mongo_collection():
|
| 13 |
+
CONNECTION_STRING = os.getenv("CONNECTION_STRING")
|
| 14 |
+
DB_NAME = os.getenv("DB_NAME")
|
| 15 |
+
COLLECTION_NAME = os.getenv("COLLECTION_NAME")
|
| 16 |
+
try:
|
| 17 |
+
# Connect with certifi to avoid SSL errors
|
| 18 |
+
client = MongoClient(CONNECTION_STRING, tlsCAFile=certifi.where())
|
| 19 |
+
db = client[DB_NAME]
|
| 20 |
+
return db[COLLECTION_NAME]
|
| 21 |
+
except Exception as e:
|
| 22 |
+
print(f"Error connecting to Mongo: {e}")
|
| 23 |
+
return None
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def get_file_data(filepath):
|
| 29 |
+
if(filepath.endswith(".json")):
|
| 30 |
+
with open(filepath,"r") as f:
|
| 31 |
+
data = json.load(f)
|
| 32 |
+
return data
|
| 33 |
+
else:
|
| 34 |
+
with open(filepath,"r") as f:
|
| 35 |
+
data = f.read()
|
| 36 |
+
return data
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def groq_calls(prompt):
|
| 40 |
+
client = Groq(api_key=GROQ_API_KEY)
|
| 41 |
+
|
| 42 |
+
groq_card = client.chat.completions.create(
|
| 43 |
+
# 401629
|
| 44 |
+
messages=[
|
| 45 |
+
{
|
| 46 |
+
"role": "user",
|
| 47 |
+
"content": f"{prompt}",
|
| 48 |
+
},
|
| 49 |
+
{
|
| 50 |
+
"role":"system",
|
| 51 |
+
"content":"You are a psychologist. Output JSON"
|
| 52 |
+
}
|
| 53 |
+
],
|
| 54 |
+
model="openai/gpt-oss-20b",
|
| 55 |
+
response_format={"type": "json_object"}
|
| 56 |
+
)
|
| 57 |
+
|
| 58 |
+
# print(groq_card.choices[0].message.content)
|
| 59 |
+
return groq_card.choices[0].message.content
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def write_to_file(output_filename,groq_response):
|
| 63 |
+
# output_filename = "overall_specific_problempair.json"
|
| 64 |
+
parsed_json = json.loads(groq_response)
|
| 65 |
+
with open(output_filename, 'a', encoding='utf-8') as f:
|
| 66 |
+
json.dump(parsed_json, f)
|
| 67 |
+
|
| 68 |
+
|