Skip to content

create : Added Sunbird AI Assistant integration with Sunbird Ed APIs #686

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions sunbird-ai-assistant/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
SUNBIRD_BASE_URL=https://dev.sunbird.org/api
SUNBIRD_AUTH_TOKEN=your_bearer_token_here
DEFAULT_USER_ID=your_test_user_id
LOG_LEVEL=DEBUG
DEFAULT_COURSE_LIMIT=10
68 changes: 68 additions & 0 deletions sunbird-ai-assistant/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# 🤖 Sunbird AI Assistant

An intelligent, context-aware AI assistant powered by the Model Context Protocol (MCP), designed to integrate with the Sunbird Ed platform and enhance learning experiences through natural language interaction.

Built by COSS • Category: AI & Conversational Agents, Education

---

## 🚀 Project Overview

Sunbird AI Assistant enables conversational access to Sunbird Ed’s powerful learning APIs through a modular AI agent. It allows users to:

- Query course metadata
- Retrieve enrollment information
- View their profile details
- Leverage deployment-specific context
- Extend toward personalized learning journeys

---

## 🧠 Features

- **Context-Aware**: The AI assistant is capable of responding based on both installation-level context and user-specific data.
- **Customizable Tools**: Integrates with the Sunbird Ed APIs for fetching course metadata, user enrollments, and profile information.
- **Extensible**: Designed to allow easy integration of additional tools and features.
- **Lightweight UI**: Initially built with a simple CLI interface for easy interaction and testing.

---

## ⚙️ Setup & Installation

1. **Clone the Repository**

```bash
git clone https://github.com/Code4GovTech/C4GT.git
cd C4GT/sunbird-ai-assistant
```

2. **Install Dependencies**

Make sure you have Python 3.8 or higher installed.

```bash
pip install -r requirements.txt
```

3. **Set Up Environment Variables**

Create a `.env` file in the root of the project and add the following:

```dotenv
SUNBIRD_BASE_URL=https://dev.sunbird.org/api
SUNBIRD_AUTH_TOKEN=your_bearer_token_here
DEFAULT_USER_ID=your_test_user_id
LOG_LEVEL=DEBUG
DEFAULT_COURSE_LIMIT=10
```

> **Note**: Make sure to keep your Bearer Token (`SUNBIRD_AUTH_TOKEN`) secure and do not expose it in your public repository.

---

## 🧪 Running Tests

Run the integration tests to verify that the AI assistant is correctly interacting with the Sunbird Ed APIs.

```bash
python -m unittest tests/test_agent.py
12 changes: 12 additions & 0 deletions sunbird-ai-assistant/app/agents/sunbird_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from openai_mcp_sdk.agent import Agent
from app.tools.course_tool import CourseMetadataTool
from app.tools.enrollment_tool import EnrollmentTool
from app.tools.profile_tool import UserProfileTool

def build_agent(context: dict) -> Agent:
tools = [
CourseMetadataTool(),
EnrollmentTool(),
UserProfileTool()
]
return Agent(tools=tools, initial_context=context)
7 changes: 7 additions & 0 deletions sunbird-ai-assistant/app/context/installation_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
def get_installation_context():
return {
"deployment": "sunbird-dev",
"base_url": "https://dev.sunbird.org/api",
"token": "your-auth-token", # Secure this in production
"features_enabled": ["courses", "progress", "enrollments"]
}
9 changes: 9 additions & 0 deletions sunbird-ai-assistant/app/interface/cli_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
def chat_loop(agent):
print("Sunbird AI Assistant (type 'exit' to quit)\n")
while True:
user_input = input("> ")
if user_input.lower() in ("exit", "quit"):
print("Goodbye!")
break
response = agent.chat(user_input)
print(response)
15 changes: 15 additions & 0 deletions sunbird-ai-assistant/app/tools/course_tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
def call(self, input_data: dict) -> dict:
url = f"{input_data['base_url']}/course/v1/search"
headers = {
"Authorization": f"Bearer {input_data['token']}",
"Content-Type": "application/json"
}
body = {
"request": {
"filters": input_data.get("filters", {}),
"limit": input_data.get("limit", 10)
}
}

response = requests.post(url, json=body, headers=headers)
return response.json()
10 changes: 10 additions & 0 deletions sunbird-ai-assistant/app/tools/enrollment_tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def call(self, input_data: dict) -> dict:
user_id = input_data["user_id"]
url = f"{input_data['base_url']}/user/enrollment/list/{user_id}"
headers = {
"Authorization": f"Bearer {input_data['token']}",
"Content-Type": "application/json"
}

response = requests.get(url, headers=headers)
return response.json()
10 changes: 10 additions & 0 deletions sunbird-ai-assistant/app/tools/profile_tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def call(self, input_data: dict) -> dict:
user_id = input_data["user_id"]
url = f"{input_data['base_url']}/user/v1/profile/{user_id}"
headers = {
"Authorization": f"Bearer {input_data['token']}",
"Content-Type": "application/json"
}

response = requests.get(url, headers=headers)
return response.json()
20 changes: 20 additions & 0 deletions sunbird-ai-assistant/config/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import os
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

# Base URL of the Sunbird Ed API deployment
SUNBIRD_BASE_URL = os.getenv("SUNBIRD_BASE_URL", "https://dev.sunbird.org/api")

# Bearer token or API key for authentication (keep this secure!)
SUNBIRD_AUTH_TOKEN = os.getenv("SUNBIRD_AUTH_TOKEN")

# Default user ID (for testing or fallback)
DEFAULT_USER_ID = os.getenv("DEFAULT_USER_ID", "replace_with_a_test_user_id")

# Logging level
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")

# Tool config: default course fetch limit
DEFAULT_COURSE_LIMIT = int(os.getenv("DEFAULT_COURSE_LIMIT", 10))
22 changes: 22 additions & 0 deletions sunbird-ai-assistant/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from app.agents.sunbird_agent import build_agent
from app.interface.cli_interface import chat_loop
from config.settings import SUNBIRD_BASE_URL, SUNBIRD_AUTH_TOKEN, DEFAULT_USER_ID

def main():
print("Initializing Sunbird AI Assistant...")

# Shared context passed to tools and agent
context = {
"base_url": SUNBIRD_BASE_URL,
"token": SUNBIRD_AUTH_TOKEN,
"user_id": DEFAULT_USER_ID
}

# Build the agent with context-aware tools
agent = build_agent(context)

# Start CLI loop
chat_loop(agent)

if __name__ == "__main__":
main()
12 changes: 12 additions & 0 deletions sunbird-ai-assistant/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Python core
python-dotenv>=1.0.0
requests>=2.31.0

# MCP SDK (assuming from OpenAI or similar package)
openai-mcp-sdk>=0.1.0 # Replace with the actual package name if different

# Optional for development and testing
unittest2>=1.1.0

# Linting (optional)
flake8>=6.0.0
34 changes: 34 additions & 0 deletions sunbird-ai-assistant/tests/test_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import unittest
from app.agents.sunbird_agent import build_agent
from config.settings import SUNBIRD_BASE_URL, SUNBIRD_AUTH_TOKEN, DEFAULT_USER_ID

class TestSunbirdAgent(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.context = {
"base_url": SUNBIRD_BASE_URL,
"token": SUNBIRD_AUTH_TOKEN,
"user_id": DEFAULT_USER_ID
}
cls.agent = build_agent(cls.context)

def test_course_metadata_tool(self):
prompt = "List some available courses"
response = self.agent.chat(prompt)
self.assertIn("result", response)
print("Course Metadata Tool Output:", response)

def test_enrollment_tool(self):
prompt = "Show my enrolled courses"
response = self.agent.chat(prompt)
self.assertIn("result", response)
print("Enrollment Tool Output:", response)

def test_profile_tool(self):
prompt = "What is my profile info?"
response = self.agent.chat(prompt)
self.assertIn("result", response)
print("User Profile Tool Output:", response)

if __name__ == "__main__":
unittest.main()