diff --git a/frameworks/agno/youtube-agent/.agentuity-crash-1756999032.json b/frameworks/agno/youtube-agent/.agentuity-crash-1756999032.json new file mode 100644 index 00000000..ed072cb4 --- /dev/null +++ b/frameworks/agno/youtube-agent/.agentuity-crash-1756999032.json @@ -0,0 +1,18 @@ +{ + "id": "c9aca38c-9807-48bb-988d-edec595c53b9", + "timestamp": "2025-09-04T11:17:12-04:00", + "error": "failed to install dependencies (exit code 2): exit status 2. error: Unable to find lockfile at `uv.lock`. To create a lockfile, run `uv lock` or `uv sync`.\n", + "error_type": { + "code": "CLI-0006", + "message": "Invalid configuration" + }, + "username": "dhilanfye", + "os_name": "darwin", + "os_arch": "arm64", + "cli_version": "0.0.166", + "attributes": { + "message": "Failed to bundle project: failed to install dependencies (exit code 2): exit status 2. error: Unable to find lockfile at `uv.lock`. To create a lockfile, run `uv lock` or `uv sync`.\n", + "user_id": "user_2x3CH4tR8dMwfWSkzUsyLznYKQT" + }, + "stack_trace": "goroutine 125 [running]:\nruntime/debug.Stack()\n\t/home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.0.linux-amd64/src/runtime/debug/stack.go:26 +0x64\ngithub.com/agentuity/cli/internal/errsystem.(*errSystem).ShowErrorAndExit(0x14000156230)\n\t/home/runner/_work/cli/cli/internal/errsystem/console.go:103 +0x7c\ngithub.com/agentuity/cli/cmd.init.func31.2.1()\n\t/home/runner/_work/cli/cli/cmd/dev.go:168 +0x188\ngithub.com/agentuity/go-common/tui.ShowSpinner.func1()\n\t/home/runner/go/pkg/mod/github.com/agentuity/go-common@v1.0.72/tui/spinner.go:31 +0x48\ngithub.com/agentuity/go-common/tui.ShowSpinner.(*Spinner).Action.func2({0x0?, 0x0?})\n\t/home/runner/go/pkg/mod/github.com/charmbracelet/huh/spinner@v0.0.0-20250313000648-36d9de46d64e/spinner.go:74 +0x24\ngithub.com/charmbracelet/huh/spinner.(*Spinner).Init.func1()\n\t/home/runner/go/pkg/mod/github.com/charmbracelet/huh/spinner@v0.0.0-20250313000648-36d9de46d64e/spinner.go:131 +0x34\ngithub.com/charmbracelet/bubbletea.(*Program).handleCommands.func1.1()\n\t/home/runner/go/pkg/mod/github.com/charmbracelet/bubbletea@v1.3.4/tea.go:352 +0x5c\ncreated by github.com/charmbracelet/bubbletea.(*Program).handleCommands.func1 in goroutine 122\n\t/home/runner/go/pkg/mod/github.com/charmbracelet/bubbletea@v1.3.4/tea.go:346 +0xf4\n" + } diff --git a/frameworks/agno/youtube-agent/.agentuity/config.json b/frameworks/agno/youtube-agent/.agentuity/config.json new file mode 100644 index 00000000..2cf2a596 --- /dev/null +++ b/frameworks/agno/youtube-agent/.agentuity/config.json @@ -0,0 +1 @@ +{"agents":[{"id":"agent_5bf6fcde1d06b2dc696ac4eea1ae6902","name":"YouTubeAgent","filename":"agents/YouTubeAgent/agent.py"}],"app":{"name":"youtube-agent","version":"0.1.0"},"cli_version":"0.0.166","environment":"development"} \ No newline at end of file diff --git a/frameworks/agno/youtube-agent/.editorconfig b/frameworks/agno/youtube-agent/.editorconfig new file mode 100644 index 00000000..58291889 --- /dev/null +++ b/frameworks/agno/youtube-agent/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.py] +indent_size = 4 + +[*.md] +trim_trailing_whitespace = false diff --git a/frameworks/agno/youtube-agent/.env.development b/frameworks/agno/youtube-agent/.env.development new file mode 100644 index 00000000..775450c8 --- /dev/null +++ b/frameworks/agno/youtube-agent/.env.development @@ -0,0 +1 @@ +# This file is used to store development environment variables diff --git a/frameworks/agno/youtube-agent/.gitignore b/frameworks/agno/youtube-agent/.gitignore new file mode 100644 index 00000000..2cb33bba --- /dev/null +++ b/frameworks/agno/youtube-agent/.gitignore @@ -0,0 +1,132 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# UV +uv.lock diff --git a/frameworks/agno/youtube-agent/README.md b/frameworks/agno/youtube-agent/README.md new file mode 100644 index 00000000..4f6d416c --- /dev/null +++ b/frameworks/agno/youtube-agent/README.md @@ -0,0 +1,152 @@ +
+ Agentuity
+ Build Agents, Not Infrastructure
+
+ + + +
+
+ +# 🎬 YouTube Content Analyzer Agent + +[![Deploy with Agentuity](https://app.agentuity.com/img/deploy.svg)](https://app.agentuity.com/deploy) + +## 🔗 Agno Framework Integration + +This project demonstrates how to seamlessly integrate [Agno's YouTube Agent](https://docs.agno.com/examples/agents/youtube-agent) with Agentuity. The original Agno YouTube agent provides powerful YouTube content analysis capabilities, and Agentuity makes it incredibly easy to deploy and scale in production. + +**Ported from:** https://docs.agno.com/examples/agents/youtube-agent + +## 🎯 What This Agent Does + +This intelligent YouTube content analyzer provides detailed video breakdowns, timestamps, and summaries. Perfect for content creators, researchers, and viewers who efficiently navigate video content. + +### Key Features + +- **Video Overview**: Analyzes video length, type, and basic metadata +- **Smart Timestamps**: Creates precise, meaningful timestamps for key segments +- **Content Organization**: Groups related segments and identifies main themes +- **Comprehensive Analysis**: Provides detailed summaries and highlight notes + +### Example Prompts to Try + +- "Analyze this tech review: [video_url]" +- "Get timestamps for this coding tutorial: [video_url]" +- "Break down the key points of this lecture: [video_url]" +- "Summarize the main topics in this documentary: [video_url]" +- "Create a study guide from this educational video: [video_url]" + +## 🚀 How It Works + +With just a simple wrapper function, you can take the original Agno YouTube agent and deploy it to Agentuity's cloud platform: + +```python +from agentuity import AgentRequest, AgentResponse, AgentContext +from agents.YouTubeAgent.youtube_agent import youtube_agent + +# Agentuity handler - wraps the original Agno YouTube agent +async def run(request: AgentRequest, response: AgentResponse, context: AgentContext): + # Get user input from Agentuity + prompt = await request.data.text() + + # Run the original Agno YouTube agent + raw = await loop.run_in_executor(None, lambda: youtube_agent.run(prompt)) + + # Return response through Agentuity + return response.text(output) +``` + +This integration gives you the best of both worlds: Agno's powerful YouTube analysis framework combined with Agentuity's enterprise-grade deployment, monitoring, and scaling capabilities. + +## 📋 Prerequisites + +Before you begin, ensure you have the following installed: + +- **Python**: Version 3.10 or higher +- **UV**: Version 0.5.25 or higher ([Documentation](https://docs.astral.sh/uv/)) + +## 🚀 Getting Started + +### Authentication + +Before using Agentuity, you need to authenticate: + +```bash +agentuity login +``` + +This command will open a browser window where you can log in to your Agentuity account. + +### Development Mode + +Run your project in development mode with: + +```bash +agentuity dev +``` + +This will start your project and open a new browser window connecting your Agent to the Agentuity Console in Live Mode, allowing you to test and debug your agent in real-time. + +## 🌐 Deployment + +When you're ready to deploy your agent to the Agentuity Cloud: + +```bash +agentuity deploy +``` + +This command will bundle your agent and deploy it to the cloud, making it accessible via the Agentuity platform. + +## 📚 Project Structure + +``` +├── agents/ +│ └── YouTubeAgent/ +│ ├── agent.py # Agentuity wrapper +│ ├── youtube_agent.py # Original Agno agent (preserved) +│ └── __init__.py +├── .venv/ # Virtual environment (created by UV) +├── pyproject.toml # Project dependencies and metadata +├── server.py # Server entry point +└── agentuity.yaml # Agentuity project configuration +``` + +## 🔧 Configuration + +Your project configuration is stored in `agentuity.yaml`. This file defines your agents, development settings, and deployment configuration. + +## 🛠️ Advanced Usage + +### Environment Variables + +You can set environment variables for your project: + +```bash +agentuity env set KEY VALUE +``` + +### Secrets Management + +For sensitive information, use secrets: + +```bash +agentuity env set --secret KEY VALUE +``` + +## 📖 Documentation + +For comprehensive documentation on the Agentuity Python SDK, visit: +[https://agentuity.dev/SDKs/python](https://agentuity.dev/SDKs/python) + +## 🆘 Troubleshooting + +If you encounter any issues: + +1. Check the [documentation](https://agentuity.dev/SDKs/python) +2. Join our [Discord community](https://discord.gg/agentuity) for support +3. Contact the Agentuity support team + +## 📝 License + +This project is licensed under the terms specified in the LICENSE file. diff --git a/frameworks/agno/youtube-agent/agents/YouTubeAgent/__init__.py b/frameworks/agno/youtube-agent/agents/YouTubeAgent/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/frameworks/agno/youtube-agent/agents/YouTubeAgent/agent.py b/frameworks/agno/youtube-agent/agents/YouTubeAgent/agent.py new file mode 100644 index 00000000..3b240527 --- /dev/null +++ b/frameworks/agno/youtube-agent/agents/YouTubeAgent/agent.py @@ -0,0 +1,36 @@ +from agentuity import AgentRequest, AgentResponse, AgentContext +import asyncio + +from agents.YouTubeAgent.youtube_agent import youtube_agent + +def welcome(): + return { + "welcome": "🎬 I'm a YouTube Content Analyzer. Paste any YouTube link and tell me what you need!", + } + +async def run(request: AgentRequest, response: AgentResponse, context: AgentContext): + prompt = await request.data.text() + context.logger.info(f"[YouTubeAgent] prompt: {prompt!r}") + + try: + loop = asyncio.get_running_loop() + raw = await loop.run_in_executor(None, lambda: youtube_agent.run(prompt)) + + if isinstance(raw, str): + output = raw + elif hasattr(raw, "content"): + output = raw.content + elif hasattr(raw, "reply"): + output = raw.reply + else: + output = str(raw) + + if not output.strip(): + context.logger.error("[YouTubeAgent] empty output") + return response.text("⚠️ Analyzer produced no content.") + + return response.text(output) + + except Exception as exc: + context.logger.error(f"[YouTubeAgent] fatal error: {exc}", exc_info=True) + return response.text("❌ An internal error occurred while analyzing the video.") diff --git a/frameworks/agno/youtube-agent/agents/YouTubeAgent/youtube_agent.py b/frameworks/agno/youtube-agent/agents/YouTubeAgent/youtube_agent.py new file mode 100644 index 00000000..eb3546fd --- /dev/null +++ b/frameworks/agno/youtube-agent/agents/YouTubeAgent/youtube_agent.py @@ -0,0 +1,53 @@ +from textwrap import dedent + +from agno.agent import Agent +from agno.models.openai import OpenAIChat +from agno.tools.youtube import YouTubeTools + +youtube_agent = Agent( + name="YouTube Agent", + model=OpenAIChat(id="gpt-4o"), + tools=[YouTubeTools()], + show_tool_calls=True, + instructions=dedent( + """\ + You are an expert YouTube content analyst with a keen eye for detail! 🎓 + Follow these steps for comprehensive video analysis: + 1. Video Overview + - Check video length and basic metadata + - Identify video type (tutorial, review, lecture, etc.) + - Note the content structure + 2. Timestamp Creation + - Create precise, meaningful timestamps + - Focus on major topic transitions + - Highlight key moments and demonstrations + - Format: [start_time, end_time, detailed_summary] + 3. Content Organization + - Group related segments + - Identify main themes + - Track topic progression + + Your analysis style: + - Begin with a video overview + - Use clear, descriptive segment titles + - Include relevant emojis for content types: + 📚 Educational + 💻 Technical + 🎮 Gaming + 📱 Tech Review + 🎨 Creative + - Highlight key learning points + - Note practical demonstrations + - Mark important references + + Quality Guidelines: + - Verify timestamp accuracy + - Avoid timestamp hallucination + - Ensure comprehensive coverage + - Maintain consistent detail level + - Focus on valuable content markers + """ + ), + add_datetime_to_instructions=True, + markdown=True, +) diff --git a/frameworks/agno/youtube-agent/agents/__init__.py b/frameworks/agno/youtube-agent/agents/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/frameworks/agno/youtube-agent/agentuity.yaml b/frameworks/agno/youtube-agent/agentuity.yaml new file mode 100644 index 00000000..b1d3031d --- /dev/null +++ b/frameworks/agno/youtube-agent/agentuity.yaml @@ -0,0 +1,64 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/agentuity/cli/refs/heads/main/agentuity.schema.json + +# ------------------------------------------------ +# This file is generated by Agentuity +# You should check this file into version control +# ------------------------------------------------ + +# The version semver range required to run this project +version: '>=0.0.142' +# The ID of the project which is automatically generated +project_id: proj_5d575910625b8d532bba90828b203fce +# The name of the project which is editable +name: youtube-agent +# The description of the project which is editable +description: YouTube Content Analyzer using Agno framework wrapped in Agentuity +# The development configuration for the project +development: + # The port to run the development server on which can be overridden by setting the PORT environment variable + port: 3500 + watch: + # Whether to watch for changes and automatically restart the server + enabled: true + # Rules for files to watch for changes + files: + - agents/** + # The command to run the development server + command: uv + # The arguments to pass to the development server + args: + - run + - --env-file + - .env + - --env-file + - .env.development + - server.py +deployment: + command: uv + args: + - run + - server.py + # You should tune the resources for the deployment + resources: + # The memory requirements + memory: 250Mi + # The CPU requirements + cpu: 500M + # The disk size requirements + disk: 300Mi +# You should not need to change these value +bundler: + enabled: true + identifier: python-uv + language: python + runtime: uv + agents: + dir: agents + ignore: + - '**/__pycache__/**' +# The agents that are part of this project +agents: + - # The ID of the Agent which is automatically generated + id: agent_5bf6fcde1d06b2dc696ac4eea1ae6902 + # The name of the Agent which is editable + name: YouTubeAgent diff --git a/frameworks/agno/youtube-agent/main.py b/frameworks/agno/youtube-agent/main.py new file mode 100644 index 00000000..982ad5d7 --- /dev/null +++ b/frameworks/agno/youtube-agent/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from youtube-agent!") + + +if __name__ == "__main__": + main() diff --git a/frameworks/agno/youtube-agent/pyproject.toml b/frameworks/agno/youtube-agent/pyproject.toml new file mode 100644 index 00000000..f9f799a7 --- /dev/null +++ b/frameworks/agno/youtube-agent/pyproject.toml @@ -0,0 +1,10 @@ +[project] +name = "youtube-agent" +version = "0.1.0" +description = "YouTube Content Analyzer using Agno framework wrapped in Agentuity" +requires-python = ">=3.10, <3.13" +dependencies = [ + "agentuity>=0.0.87", + "agno", + "youtube_transcript_api", +] diff --git a/frameworks/agno/youtube-agent/server.py b/frameworks/agno/youtube-agent/server.py new file mode 100644 index 00000000..8a22539d --- /dev/null +++ b/frameworks/agno/youtube-agent/server.py @@ -0,0 +1,33 @@ +from agentuity import autostart +import logging +import os +import sys + +if __name__ == "__main__": + if not os.environ.get("AGENTUITY_API_KEY") and not os.environ.get( + "AGENTUITY_SDK_KEY" + ): + print( + "\033[31m[ERROR] AGENTUITY_API_KEY or AGENTUITY_SDK_KEY is not set. This should have been set automatically by the Agentuity CLI or picked up from the .env file.\033[0m" + ) + if os.environ.get("_", "").endswith("uv") and os.path.exists(".env"): + print( + "\033[31m[ERROR] Re-run the command with `uv run --env-file .env server.py`\033[0m" + ) + sys.exit(1) + + if not os.environ.get("AGENTUITY_URL"): + print( + "\033[31m[WARN] You are running this agent outside of the Agentuity environment. Any automatic Agentuity features will be disabled.\033[0m" + ) + print( + "\033[31m[WARN] Recommend running `agentuity dev` to run your project locally instead of `python script`.\033[0m" + ) + + logging.basicConfig( + stream=sys.stdout, + level=logging.INFO, + format="[%(levelname)-5.5s] %(message)s", + ) + + autostart()