{"id":29123102,"url":"https://github.com/sing1ee/a2a-crewai-charts-agent","last_synced_at":"2025-06-29T18:06:05.585Z","repository":{"id":301122611,"uuid":"1008224515","full_name":"sing1ee/a2a-crewai-charts-agent","owner":"sing1ee","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-25T08:11:37.000Z","size":176,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-25T09:25:41.338Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sing1ee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-25T08:08:40.000Z","updated_at":"2025-06-25T08:11:40.000Z","dependencies_parsed_at":"2025-06-25T09:36:08.558Z","dependency_job_id":null,"html_url":"https://github.com/sing1ee/a2a-crewai-charts-agent","commit_stats":null,"previous_names":["sing1ee/a2a-crewai-charts-agent"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sing1ee/a2a-crewai-charts-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sing1ee%2Fa2a-crewai-charts-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sing1ee%2Fa2a-crewai-charts-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sing1ee%2Fa2a-crewai-charts-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sing1ee%2Fa2a-crewai-charts-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sing1ee","download_url":"https://codeload.github.com/sing1ee/a2a-crewai-charts-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sing1ee%2Fa2a-crewai-charts-agent/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262642973,"owners_count":23341819,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-29T18:06:04.826Z","updated_at":"2025-06-29T18:06:05.574Z","avatar_url":"https://github.com/sing1ee.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A2A + CrewAI + OpenRouter Chart Generation Agent Tutorial\n\n## Tutorial Focus\n\nThis tutorial will guide you through practicing the following core skills:\n\n- **Integrating OpenRouter + CrewAI + A2A**: Complete end-to-end Agent development using OpenRouter as LLM provider, CrewAI as Agent framework, and A2A protocol as standardized interface\n- **Practicing A2A Agent Image Data Return**: Learn how to make Agents generate and return image data, not just text responses\n- **Using [A2A Inspector](https://a2aprotocol.ai/blog/a2a-inspector) to Debug A2A Applications**: Master professional debugging tools to test and validate your Agent applications\n\n## Quick Start\n\n### 1. Clone the Code\n\n```bash\ngit clone git@github.com:sing1ee/a2a-crewai-charts-agent.git\ncd a2a-crewai-charts-agent\n```\n\n### 2. Create Environment Configuration\n\nCreate `.env` file:\n\n```bash\nOPENROUTER_API_KEY=sk-or-v1-your-api-key-here\nOPENAI_MODEL_NAME=openrouter/anthropic/claude-3.7-sonnet\n```\n\n### 3. Environment Setup and Run\n\n```bash\n# Create virtual environment\nuv venv\n\n# Activate virtual environment\nsource .venv/bin/activate\n\n# Run application\nuv run .\n```\n\nThe application will start at `http://localhost:10011`.\n\n## Debug with A2A Inspector\n\n[A2A Inspector](https://a2aprotocol.ai/blog/a2a-inspector) is a powerful tool specifically designed for debugging A2A applications.\n\n### Debugging Steps:\n\n1. **Access A2A Inspector**: Open [https://inspector.a2aprotocol.ai](https://inspector.a2aprotocol.ai)\n\n2. **Connect to Your Agent**:\n   - Enter your Agent address in Inspector: `http://localhost:10011`\n   - Click \"Connect\" to establish connection\n\n3. **Test Agent Functionality**:\n   - Send test message: `\"Generate a chart of revenue: Jan,1000 Feb,2000 Mar,1500\"`\n   - Observe the complete A2A protocol interaction process\n   - View returned image data\n\n4. **Debug and Monitor**:\n   - Check Agent's capabilities and skills\n   - Monitor complete request and response flow\n   - Verify correct image data transmission\n\nRefer to [A2A Inspector Documentation](https://a2aprotocol.ai/blog/a2a-inspector) for more detailed debugging guides.\n\n## Main Process and Code Introduction\n\n### System Architecture Sequence Diagram\n\n```mermaid\nsequenceDiagram\n    participant U as User\n    participant A2A as A2A Inspector\n    participant S as A2A Server\n    participant H as DefaultRequestHandler\n    participant E as ChartGenerationAgentExecutor\n    participant CA as ChartGenerationAgent\n    participant Crew as CrewAI Crew\n    participant Tool as ChartGenerationTool\n    participant MP as Matplotlib\n    participant Cache as InMemoryCache\n\n    U-\u003e\u003eA2A: Send prompt \"Generate chart: A,100 B,200\"\n    A2A-\u003e\u003eS: HTTP POST /tasks with A2A message\n    S-\u003e\u003eH: Handle request with RequestContext\n    H-\u003e\u003eE: execute(context, event_queue)\n    E-\u003e\u003eCA: invoke(query, session_id)\n    CA-\u003e\u003eCrew: kickoff with inputs\n    Crew-\u003e\u003eTool: generate_chart_tool(prompt, session_id)\n    Tool-\u003e\u003eTool: Parse CSV data\n    Tool-\u003e\u003eMP: Create bar chart with matplotlib\n    MP--\u003e\u003eTool: Return PNG bytes\n    Tool-\u003e\u003eCache: Store image with ID\n    Cache--\u003e\u003eTool: Confirm storage\n    Tool--\u003e\u003eCrew: Return image ID\n    Crew--\u003e\u003eCA: Return image ID\n    CA--\u003e\u003eE: Return image ID\n    E-\u003e\u003eCA: get_image_data(session_id, image_key)\n    CA-\u003e\u003eCache: Retrieve image data\n    Cache--\u003e\u003eCA: Return Imagedata\n    CA--\u003e\u003eE: Return Imagedata\n    E-\u003e\u003eH: Create FilePart with image bytes\n    H-\u003e\u003eS: enqueue completed_task event\n    S--\u003e\u003eA2A: Return A2A response with image\n    A2A--\u003e\u003eU: Display generated chart\n```\n\n### Core Component Details\n\n#### 1. A2A Server Initialization (`__main__.py`)\n\n```python\n# Define Agent capabilities and skills\ncapabilities = AgentCapabilities(streaming=False)\nskill = AgentSkill(\n    id='chart_generator',\n    name='Chart Generator',\n    description='Generate a chart based on CSV-like data passed in',\n    tags=['generate image', 'edit image'],\n    examples=['Generate a chart of revenue: Jan,$1000 Feb,$2000 Mar,$1500'],\n)\n\n# Create Agent card\nagent_card = AgentCard(\n    name='Chart Generator Agent',\n    description='Generate charts from structured CSV-like data input.',\n    url=f'http://{host}:{port}/',\n    version='1.0.0',\n    defaultInputModes=ChartGenerationAgent.SUPPORTED_CONTENT_TYPES,\n    defaultOutputModes=ChartGenerationAgent.SUPPORTED_CONTENT_TYPES,\n    capabilities=capabilities,\n    skills=[skill],\n)\n```\n\n**Key Points**:\n- `AgentCapabilities` defines supported Agent functions (streaming disabled here)\n- `AgentSkill` describes specific Agent skills and usage examples\n- `AgentCard` is the Agent's identity in A2A protocol\n\n#### 2. CrewAI Agent Implementation (`agent.py`)\n\n```python\nclass ChartGenerationAgent:\n    def __init__(self):\n        # Create specialized chart generation Agent\n        self.chart_creator_agent = Agent(\n            role='Chart Creation Expert',\n            goal='Generate a bar chart image based on structured CSV input.',\n            backstory='You are a data visualization expert who transforms structured data into visual charts.',\n            verbose=False,\n            allow_delegation=False,\n            tools=[generate_chart_tool],\n        )\n\n        # Define task\n        self.chart_creation_task = Task(\n            description=(\n                \"You are given a prompt: '{user_prompt}'.\\n\"\n                \"If the prompt includes comma-separated key:value pairs (e.g. 'a:100, b:200'), \"\n                \"reformat it into CSV with header 'Category,Value'.\\n\"\n                \"Ensure it becomes two-column CSV, then pass that to the 'ChartGenerationTool'.\\n\"\n                \"Use session ID: '{session_id}' when calling the tool.\"\n            ),\n            expected_output='The id of the generated chart image',\n            agent=self.chart_creator_agent,\n        )\n```\n\n**Key Points**:\n- CrewAI's `Agent` class defines AI assistant roles and capabilities\n- `Task` class describes specific task execution logic\n- Custom tools are integrated into Agent through `tools` parameter\n\n#### 3. Chart Generation Tool\n\n```python\n@tool('ChartGenerationTool')\ndef generate_chart_tool(prompt: str, session_id: str) -\u003e str:\n    \"\"\"Generates a bar chart image from CSV-like input using matplotlib.\"\"\"\n    \n    # Parse CSV data\n    df = pd.read_csv(StringIO(prompt))\n    df.columns = ['Category', 'Value']\n    df['Value'] = pd.to_numeric(df['Value'], errors='coerce')\n    \n    # Generate bar chart\n    fig, ax = plt.subplots()\n    ax.bar(df['Category'], df['Value'])\n    ax.set_xlabel('Category')\n    ax.set_ylabel('Value')\n    ax.set_title('Bar Chart')\n    \n    # Save as PNG bytes\n    buf = BytesIO()\n    plt.savefig(buf, format='png')\n    plt.close(fig)\n    buf.seek(0)\n    image_bytes = buf.read()\n    \n    # Encode and cache image\n    data = Imagedata(\n        bytes=base64.b64encode(image_bytes).decode('utf-8'),\n        mime_type='image/png',\n        name='generated_chart.png',\n        id=uuid4().hex,\n    )\n    \n    # Store image in cache\n    session_data = cache.get(session_id) or {}\n    session_data[data.id] = data\n    cache.set(session_id, session_data)\n    \n    return data.id\n```\n\n**Key Points**:\n- Use `@tool` decorator to convert function into CrewAI tool\n- Use pandas to parse CSV data, matplotlib to generate charts\n- Images stored as base64 encoding for network transmission\n- Use session IDs to manage data isolation for multiple users\n\n#### 4. A2A Executor (`agent_executor.py`)\n\n```python\nclass ChartGenerationAgentExecutor(AgentExecutor):\n    async def execute(self, context: RequestContext, event_queue: EventQueue) -\u003e None:\n        # Get user input\n        query = context.get_user_input()\n        \n        # Call CrewAI Agent\n        result = self.agent.invoke(query, context.context_id)\n        \n        # Get generated image data\n        data = self.agent.get_image_data(\n            session_id=context.context_id, \n            image_key=result.raw\n        )\n        \n        if data and not data.error:\n            # Create file part containing image bytes\n            parts = [\n                Part(\n                    root=FilePart(\n                        file=FileWithBytes(\n                            bytes=data.bytes,\n                            mimeType=data.mime_type,\n                            name=data.name,\n                        )\n                    )\n                )\n            ]\n        else:\n            # Return text message in error case\n            parts = [Part(root=TextPart(text=data.error or 'Failed to generate chart image.'))]\n        \n        # Add completed task to event queue\n        event_queue.enqueue_event(\n            completed_task(\n                context.task_id,\n                context.context_id,\n                [new_artifact(parts, f'chart_{context.task_id}')],\n                [context.message],\n            )\n        )\n```\n\n**Key Points**:\n- `AgentExecutor` is A2A protocol execution layer\n- Get user requests through `RequestContext`\n- Convert CrewAI responses to A2A protocol format\n- Support returning file-type data (images)\n\n#### 5. Cache System (`utils.py`)\n\n```python\nclass InMemoryCache:\n    \"\"\"Simple thread-safe in-memory cache with no expiration.\"\"\"\n    \n    def __init__(self):\n        self._lock = threading.Lock()\n        self._store: dict[str, Any] = {}\n    \n    def get(self, key: str) -\u003e Any | None:\n        with self._lock:\n            return self._store.get(key)\n    \n    def set(self, key: str, value: Any) -\u003e None:\n        with self._lock:\n            self._store[key] = value\n```\n\n**Key Points**:\n- Thread-safe in-memory cache implementation\n- Used to store generated image data\n- Supports session isolation to avoid user data confusion\n\n## Technology Stack Summary\n\n- **A2A Protocol**: Standardized Agent communication protocol\n- **CrewAI**: Multi-Agent collaboration framework\n- **OpenRouter**: LLM API aggregation service\n- **Matplotlib**: Python chart generation library\n- **Pandas**: Data processing library\n- **UV**: Modern Python package manager\n\n## Extension Suggestions\n\n1. **Support More Chart Types**: Pie charts, line charts, scatter plots, etc.\n2. **Add Data Validation**: Stronger input data validation and error handling\n3. **Persistent Cache**: Use Redis or file system to store images\n4. **Streaming Support**: Support real-time chart generation progress\n5. **Multimodal Input**: Support uploading CSV files instead of text-only input\n\nThrough this tutorial, you have mastered the core skills of building practical Agents using modern AI technology stack. This chart generation Agent can serve as the foundation for more complex data analysis applications.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsing1ee%2Fa2a-crewai-charts-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsing1ee%2Fa2a-crewai-charts-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsing1ee%2Fa2a-crewai-charts-agent/lists"}