Not able to store the responses and feedback in the Teams bot built through teams tool kit

Raghunatha N S 0 Reputation points
2025-03-08T04:53:11.9733333+00:00

Hi,

We have built a custom AI agent with RAG approach using AI search and Azure Open AI service in Teams toolkit framework. We have also provisioned PostgreSQL in Azure for storing the responses and human feedback.

The toolkit works fine when tested locally using test tool, but when deployed into the teams, bot is not responding.

This issue raised when PostgreSQL integrated with toolkit for capturing responses and feedback.

the bot code is as follows, any suggestion would help.

import asyncio
from dataclasses import dataclass, asdict
import json
import os
import sys
import traceback
from typing import Generic, TypeVar, List, Dict, Any, Optional
import psycopg2
from datetime import datetime
from botbuilder.core import MemoryStorage, TurnContext, Middleware, ActivityHandler
from botbuilder.schema import Activity, ActivityTypes
from teams import Application, ApplicationOptions, TeamsAdapter
from teams.ai import AIOptions
from teams.ai.models import AzureOpenAIModelOptions, OpenAIModel, OpenAIModelOptions
from teams.ai.planners import ActionPlanner, ActionPlannerOptions
from teams.ai.prompts import PromptManager, PromptManagerOptions
from teams.ai.actions import ActionTypes
from teams.state import TurnState
from teams.feedback_loop_data import FeedbackLoopData
from azure_ai_search_data_source import AzureAISearchDataSource, AzureAISearchDataSourceOptions
from config import Config

class ChatbotApplication:
    def __init__(self, config):
        self.config = config
        
        # Azure PostgreSQL connection parameters
        self.db_config = {
            'dbname': 'POSTGREDB_NAME',  # Standard database name in Azure PostgreSQL
            'user': 'USER',
            'password': 'DB_KEY',
            'host': 'DB_HOST',
            'port': '5432',
            'sslmode': 'require'  # Required for secure Azure connections
        }
        
        # Initialize the chat bot components
        self.create_required_tables()
        self.setup_bot_components()
    
    def setup_bot_components(self):
        # Create AI components
        model = OpenAIModel(
            AzureOpenAIModelOptions(
                api_key=self.config.AZURE_OPENAI_API_KEY,
                default_model=self.config.AZURE_OPENAI_MODEL_DEPLOYMENT_NAME,
                endpoint=self.config.AZURE_OPENAI_ENDPOINT,
            )
        )
            
        prompts = PromptManager(PromptManagerOptions(prompts_folder=f"{os.getcwd()}/prompts"))
        prompts.add_data_source(
            AzureAISearchDataSource(
                AzureAISearchDataSourceOptions(
                    name='azure-ai-search',
                    indexName='index-demo',
                    azureAISearchApiKey=self.config.AZURE_SEARCH_KEY,
                    azureAISearchEndpoint=self.config.AZURE_SEARCH_ENDPOINT,
                )
            )
        )
        
        planner = ActionPlanner(
            ActionPlannerOptions(model=model, prompts=prompts, default_prompt="chat")
        )
        
        # Create our custom adapter
        self.custom_adapter = ResponseCaptureAdapter(self.config)
        
        # Define storage and application
        self.storage = MemoryStorage()
        self.bot_app = Application[TurnState](
            ApplicationOptions(
                bot_app_id=self.config.APP_ID,
                storage=self.storage,
                adapter=self.custom_adapter,  # Use our custom adapter
                ai=AIOptions(planner=planner, enable_feedback_loop=True),
            )
        )
    
    def setup_event_handlers(self):
        """Setup all event handlers for the bot application"""
        @self.bot_app.error
        async def on_error(context: TurnContext, error: Exception):
            print(f"\n [on_turn_error] unhandled error: {error}", file=sys.stderr)
            traceback.print_exc()
            await context.send_activity("The bot encountered an error or bug.")
        
        @self.bot_app.activity("message")
        async def on_message(context: TurnContext, state: TurnState):
            try:
                query = context.activity.text
                print(f"Received message: {query[:100] if query else 'None'}")

                # Run the AI which will generate and send responses
                result = await self.bot_app.ai.run(context, state)
                print(f"AI result: {result}")

                # Capture the response from our adapter
                adapter = context.adapter
                if isinstance(adapter, ResponseCaptureAdapter):
                    response_data = adapter.get_response_for_query(context)
                    if query and response_data:
                        conversation_id = response_data['conversation_id']
                        activity_id = response_data['activity_id']
                        
                        print(f"Processing response for conversation_id: {conversation_id}, activity_id: {activity_id}")

                        # Store response along with conversation and activity IDs
                        chat_log_id = await self.log_chat_to_db(
                            query, 
                            response_data['text'],
                            conversation_id,
                            activity_id,
                            None,  # Initially, human_feedback is null
                            None   # Initially, comments are null
                        )

                        if chat_log_id:
                            # Store mapping in our new table
                            await self.store_feedback_mapping(conversation_id, activity_id, chat_log_id)
                            
                            # Store IDs in conversation state for persistence
                            # We'll also store in turn state as a backup
                            key = f"{conversation_id}_last_activity"
                            await self.storage.write({key: activity_id})
                            
                            # Store in turn state as well (may not persist between turns)
                            # Use dictionary style access for TurnState
                            state["conversation_reference"] = {
                                'conversation_id': conversation_id,
                                'activity_id': activity_id,
                                'chat_log_id': chat_log_id
                            }
                            print(f"Stored conversation reference in state: {state['conversation_reference']}")

                        # Clear stored response
                        conversation_activity_id = f"{conversation_id}_{activity_id}"
                        if conversation_activity_id in adapter.query_response_map:
                            del adapter.query_response_map[conversation_activity_id]
                            print(f"Cleared response from map for {conversation_activity_id}")
                else:
                    print("Adapter is not an instance of ResponseCaptureAdapter")

                return result
            except Exception as e:
                print(f"Error in on_message handler: {e}")
                traceback.print_exc()
        
Microsoft Teams Development
Microsoft Teams Development
Microsoft Teams: A Microsoft customizable chat-based workspace.Development: The process of researching, productizing, and refining new or existing technologies.
3,638 questions
0 comments No comments
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.