Skip to content

Commit 682a19c

Browse files
feat(examples): add Song Meaning Analyzer agent (#568)
* feat(examples): add Song Meaning Analyzer agent Agno + OpenRouter agent that analyzes song meanings with structured SUMMARY / MEANING / EVIDENCE output. Matches Bindu Agents Tracker spec. Verified locally end-to-end with Bohemian Rhapsody test query. * fix: address CodeRabbit feedback (MD040 fences, word count per bullet) * fix: add trailing newline to README.md * fix: ensure all files end with newline
1 parent f09d037 commit 682a19c

4 files changed

Lines changed: 316 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
OPENROUTER_API_KEY=your_openrouter_api_key_here
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# 🎵 Song Meaning Analyzer
2+
3+
A Bindu agent that deeply researches songs, lyrics, artists, and cultural context
4+
to uncover and articulate the true meaning behind any musical work.
5+
6+
## Features
7+
8+
- Accepts any song title, artist name, or pasted lyrics
9+
- Produces structured analyses: SUMMARY, MEANING, and EVIDENCE
10+
- Grounds every claim in lyrics, artist statements, or documented context
11+
- Handles ambiguous songs by surfacing multiple interpretations
12+
- Live A2A microservice via `bindufy()`
13+
14+
## Output Format
15+
16+
```text`r`nSUMMARY
17+
A single sentence (25 words max) capturing the song's core meaning.
18+
19+
MEANING
20+
- 3–5 bullets (~165 words each) covering themes, symbolism, and context
21+
22+
EVIDENCE
23+
- 3–5 bullets (~15 words each) citing lyrics and artist statements
24+
```
25+
26+
## Setup
27+
28+
```bash
29+
cp .env.example .env
30+
# Add your OPENROUTER_API_KEY to .env
31+
32+
uv add bindu agno python-dotenv
33+
python song_meaning_agent.py
34+
```
35+
36+
The agent runs at `http://localhost:3773`.
37+
38+
## Example Queries
39+
40+
```json
41+
{"role": "user", "content": "What does 'Bohemian Rhapsody' by Queen really mean?"}
42+
{"role": "user", "content": "Analyze the deeper meaning behind these lyrics: ..."}
43+
{"role": "user", "content": "Explain the themes and symbolism in this artist's work."}
44+
{"role": "user", "content": "Uncover the meaning of 'The Sound of Silence' based on artist context."}
45+
```
46+
47+
## Project Structure
48+
49+
```text`r`nsong-meaning-agent/
50+
├── song_meaning_agent.py # Main agent + bindufy()
51+
├── .env.example # Environment variables
52+
├── skills/
53+
│ └── song-meaning-skill/
54+
│ └── skill.yaml # Skill definition
55+
└── README.md
56+
```
57+
58+
## Environment Variables
59+
60+
| Variable | Required | Description |
61+
|---|---|---|
62+
| `OPENROUTER_API_KEY` | Yes | OpenRouter API key |
63+
| `BINDU_DEPLOYMENT_URL` | No | Override default `http://localhost:3773` |
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
id: song-meaning-skill
2+
name: Song Meaning Skill
3+
version: 1.0.0
4+
author: your.email@example.com
5+
description: >
6+
Deeply researches songs, lyrics, artists, and cultural context to uncover
7+
and articulate the true meaning behind any musical work. Produces structured
8+
analyses with a summary sentence, thematic bullet points, and evidence-backed
9+
citations. Powered by OpenRouter and exposed as a live A2A-compliant Bindu
10+
microservice.
11+
12+
features:
13+
- Accept any song title, artist name, or pasted lyrics as input
14+
- Research lyrics, artist interviews, liner notes, and cultural context
15+
- Produce a 25-word SUMMARY sentence capturing the song's core meaning
16+
- Write 3-5 MEANING bullets (~65 words each) covering themes, symbolism, and context
17+
- Provide 3-5 EVIDENCE bullets (~15 words each) citing lyrics and artist statements
18+
- Handle ambiguous songs by surfacing multiple interpretations
19+
- Deployed as a live Bindu microservice via bindufy()
20+
- A2A / X402 protocol-compliant out of the box
21+
22+
tags:
23+
- music
24+
- lyrics
25+
- song-analysis
26+
- thematic-extraction
27+
- lyric-interpretation
28+
- artist-context-research
29+
- musical-symbolism
30+
- evidence-based-conclusion
31+
- openrouter
32+
33+
input_modes:
34+
- text/plain # Song title + artist, or pasted lyrics
35+
36+
output_modes:
37+
- text/plain # Structured Markdown analysis
38+
39+
examples:
40+
- input: "What does 'Bohemian Rhapsody' by Queen really mean?"
41+
output: |
42+
SUMMARY
43+
A theatrical journey through guilt, fate, and acceptance told across
44+
multiple operatic personas by Freddie Mercury.
45+
46+
MEANING
47+
- The song opens with a condemned narrator facing execution, establishing
48+
the central tension between agency and fate. Mercury reportedly described
49+
it as a random collection of ideas, but the recurring motif of a young
50+
man unable to escape consequences suggests a deeper autobiographical
51+
thread about identity and self-reckoning.
52+
- The operatic middle section fragments the narrator into multiple voices
53+
arguing over culpability. Bismillah (Arabic for "in the name of God")
54+
and Beelzebub represent the spiritual battle for the narrator's soul,
55+
drawing on Mercury's Zoroastrian upbringing and his complex relationship
56+
with religion and mortality.
57+
58+
EVIDENCE
59+
- "Mama, just killed a man" establishes the irreversible act driving the narrative.
60+
- Mercury told friends the lyrics were deliberately left open to interpretation.
61+
62+
- input: "Analyze the meaning of 'The Sound of Silence' by Simon & Garfunkel"
63+
output: |
64+
SUMMARY
65+
A meditation on modern alienation where people worship mass media and
66+
hollow spectacle instead of genuine human connection.
67+
68+
MEANING
69+
- Written by Paul Simon in 1964 following the JFK assassination, the song
70+
captures a generation's sense of disconnection and disillusionment with
71+
American optimism. The darkness is not literal night but emotional isolation
72+
that persists even in daylight.
73+
- The neon god the people bow and pray to is widely read as television,
74+
the dominant mass medium of the era. Simon observed people passively
75+
consuming broadcast culture rather than speaking honestly to one another,
76+
creating communities bound by spectacle rather than meaning.
77+
78+
EVIDENCE
79+
- "People talking without speaking, hearing without listening" defines
80+
the failure of communication as the song's core theme.
81+
- Simon confirmed the song was written in a darkened bathroom to aid concentration.
82+
83+
capabilities_detail:
84+
lyric_analysis:
85+
description: >
86+
Interprets lyrical content through close reading, identifying metaphors,
87+
narrative structure, and recurring motifs.
88+
approach: Evidence-based; claims tied to specific lines or documented artist statements.
89+
90+
contextual_research:
91+
description: >
92+
Grounds interpretation in artist biography, historical moment, genre conventions,
93+
and cultural reception.
94+
sources: Artist interviews, liner notes, critical essays, documented fan analysis.
95+
96+
output_format:
97+
structure: SUMMARY → MEANING → EVIDENCE
98+
summary_length: 25 words maximum
99+
meaning_bullets: 3-5 bullets, ~65 words each
100+
evidence_bullets: 3-5 bullets, ~15 words each
101+
markdown: plain Markdown, no bold or italics inside bullet points
102+
103+
transport:
104+
protocol: A2A (JSON-RPC over HTTP)
105+
endpoint: POST /
106+
port: 3773
107+
auth: disabled (configurable via config.auth.enabled)
108+
storage: in-memory (configurable)
109+
scheduler: in-memory (configurable)
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
"""
2+
Song Meaning Analyzer — Bindu Example
3+
4+
An expert agent that deeply researches songs, lyrics, artists, and context
5+
to uncover and articulate the true meaning behind any musical work.
6+
7+
Prerequisites
8+
-------------
9+
uv add bindu agno python-dotenv
10+
11+
Usage
12+
-----
13+
export OPENROUTER_API_KEY="your_api_key_here" # pragma: allowlist secret
14+
python song_meaning_agent.py
15+
16+
The agent will be live at http://localhost:3773
17+
Send it a message like:
18+
{"role": "user", "content": "What does 'Bohemian Rhapsody' really mean?"}
19+
or:
20+
{"role": "user", "content": "Analyze the meaning of 'The Sound of Silence' by Simon & Garfunkel"}
21+
"""
22+
23+
import os
24+
25+
from agno.agent import Agent
26+
from agno.models.openrouter import OpenRouter
27+
from bindu.penguin.bindufy import bindufy
28+
from dotenv import load_dotenv
29+
30+
load_dotenv()
31+
32+
# ---------------------------------------------------------------------------
33+
# 1. Agent definition
34+
# ---------------------------------------------------------------------------
35+
36+
INSTRUCTIONS = """
37+
You are an expert songwriter, musicologist, and cultural analyst with deep knowledge
38+
of music history, lyrical symbolism, and artistic context across all genres and eras.
39+
40+
When asked to analyze a song, you MUST follow this exact structure:
41+
42+
**SUMMARY**
43+
A single sentence (25 words max) capturing the song's core meaning.
44+
45+
**MEANING**
46+
3–5 bullet points (each ~65 words) exploring:
47+
- Central themes and emotional narrative
48+
- Symbolic imagery and metaphors used
49+
- Cultural, historical, or biographical context
50+
- The artist's intent or stated interpretation (if known)
51+
- How the musical elements reinforce the lyrical meaning
52+
53+
**EVIDENCE**
54+
3–5 bullet points (each ~15 words) citing:
55+
- Specific lyrics that support your interpretation
56+
- Artist interviews, liner notes, or documented statements
57+
- Fan analysis or cultural reception where relevant
58+
59+
Rules:
60+
- Output in plain Markdown without bold or italics inside bullet points
61+
- Be evidence-based: ground every claim in lyrics, artist statements, or documented context
62+
- If the song or artist is unfamiliar, say so clearly rather than speculating
63+
- Cover multiple interpretations when the song is genuinely ambiguous
64+
""".strip()
65+
66+
agent = Agent(
67+
instructions=INSTRUCTIONS,
68+
model=OpenRouter(
69+
id="openai/gpt-4o-mini",
70+
api_key=os.getenv("OPENROUTER_API_KEY"), # pragma: allowlist secret
71+
),
72+
markdown=True,
73+
)
74+
75+
76+
# ---------------------------------------------------------------------------
77+
# 2. Bindu configuration
78+
# ---------------------------------------------------------------------------
79+
80+
config = {
81+
"author": "your.email@example.com",
82+
"name": "song_meaning_agent",
83+
"description": (
84+
"An expert songwriter and musician that deeply researches songs, lyrics, "
85+
"artists, and context to uncover and articulate the true meaning behind "
86+
"any musical work."
87+
),
88+
"version": "1.0.0",
89+
"capabilities": {
90+
"text_analysis": ["lyric-interpretation", "thematic-extraction", "musical-symbolism"],
91+
"research": ["artist-context-research", "evidence-based-conclusion"],
92+
"streaming": False,
93+
},
94+
"skills": ["skills/song-meaning-skill"],
95+
"auth": {"enabled": False},
96+
"storage": {"type": "memory"},
97+
"scheduler": {"type": "memory"},
98+
"deployment": {
99+
"url": os.getenv("BINDU_DEPLOYMENT_URL", "http://localhost:3773"),
100+
"expose": True,
101+
"cors_origins": ["http://localhost:5173"],
102+
},
103+
}
104+
105+
106+
# ---------------------------------------------------------------------------
107+
# 3. Handler
108+
# ---------------------------------------------------------------------------
109+
110+
def handler(messages: list[dict[str, str]]):
111+
"""Analyze the meaning of a song based on the user's query.
112+
113+
Args:
114+
messages: Standard A2A message list, e.g.
115+
[{"role": "user", "content": "What does Bohemian Rhapsody mean?"}]
116+
117+
Returns:
118+
Structured song meaning analysis with SUMMARY, MEANING, and EVIDENCE sections.
119+
"""
120+
try:
121+
user_messages = [m for m in messages if m.get("role") == "user"]
122+
if not user_messages:
123+
return "No query received. Please ask about a song, e.g. 'What does Bohemian Rhapsody mean?'"
124+
125+
query = user_messages[-1].get("content", "").strip()
126+
if not query:
127+
return "Empty query. Please name a song or paste lyrics you'd like analyzed."
128+
129+
result = agent.run(input=messages)
130+
return result
131+
132+
except Exception as e:
133+
return f"Error analyzing song: {str(e)}"
134+
135+
136+
# ---------------------------------------------------------------------------
137+
# 4. Entry point
138+
# ---------------------------------------------------------------------------
139+
140+
if __name__ == "__main__":
141+
print("🎵 Song Meaning Analyzer running at http://localhost:3773")
142+
print("🎸 Example: {\"role\": \"user\", \"content\": \"What does Bohemian Rhapsody really mean?\"}")
143+
bindufy(config, handler)

0 commit comments

Comments
 (0)