Guide de migration du SDK Azure Bot Framework vers Microsoft 365 Agents SDK pour Node.js

Cet article décrit les modifications requises pour migrer à partir du Kit de développement logiciel (SDK) Bot Framework pour Node.js.

Prerequisites

  • Node.js version 20 ou ultérieure
  • Projet sdk Bot Framework existant
  • Azure Bot Service ressource (reste inchangée pendant la migration)

Modifications du code du SDK NodeJS

Les modifications apportées à cette section sont dues aux différences entre le kit SDK Azure Bot Framework et le Microsoft 365 Agents SDK JavaScript .

Ressources Azure

Vos ressources Azure restent inchangées. Vous devez référencer vos propriétés appsettings pour MicrosoftAppType, MicrosoftAppId, MicrosoftAppPassword, et MicrosoftAppTenantId. Toutefois, ces noms de paramètres ne sont plus utilisés et peuvent être supprimés ultérieurement. En savoir plus sur la configuration de l’environnement

Premières étapes

Appliquez d’abord les modifications suivantes pour résoudre la plupart des différences. Vous devez toujours déboguer et rechercher d’autres différences après avoir appliqué ces modifications.

Mettre à jour les dépendances de package

Cette modification ne règle pas tous les espaces de noms requis, mais elle couvre l'essentiel d'entre eux.

Scénario Kit de développement logiciel (SDK) Bot Framework Kit de développement logiciel (SDK) Agents
Hébergement principal botbuilder @microsoft/agents-hosting
Schéma des activités botframework-schema @microsoft/agents-activity
Dialogs botbuilder-dialogs @microsoft/agents-hosting-dialogs
Azure Cosmos DB, une base de données distribuée globale botbuilder-azure @microsoft/agents-hosting-storage-cosmos
Stockage Blob Azure botbuilder-azure-blobs @microsoft/agents-hosting-storage-blob
Utilitaires de serveur Express Configuration manuelle @microsoft/agents-hosting-express

Bots utilisant Teams

Si votre bot utilise Teams, ajoutez une dépendance de package pour @microsoft/agents-hosting-extensions-teams

Mettre à jour les importations/exiger

Utilisez rechercher et remplacer pour apporter les modifications suivantes :

Bot Framework Kit de développement logiciel (SDK) Agents
require('botframework-schema'); require('@microsoft/agents-activity')
require('botbuilder'); require('@microsoft/agents-hosting')
require('botbuilder-dialogs'); require('@microsoft/agents-hosting-dialogs')

Classe d’activité du Kit de développement logiciel (SDK) Agents

Le @microsoft/agents-activity package inclut la classe Activity pour effectuer l’analyse en fonction de zod. Vous pouvez analyser et valider vos activités personnalisées à partir de JSON avec Activity.fromJson() ou à partir d’objets JavaScript littérals avec Activity.fromObject().

En outre, la Activity classe centralise toutes les opérations liées à la charge utile d’activité, telles que getConversationReference. Les méthodes du tableau suivant ont été déplacées à partir de TurnContext et fonctionnent désormais sur l'instance d'activité actuelle :

Méthode statique Bot Framework Méthode d’instance du Kit de développement logiciel (SDK) Agents
TurnContext.applyConversationReference activity.applyConversationReference
TurnContext.getConversationReference activity.getConversationReference
TurnContext.getReplyConversationReference activity.getReplyConversationReference
TurnContext.removeRecipientMention activity.removeRecipientMention
TurnContext.getMentions activity.getMentions
TurnContext.removeMentionText activity.removeMentionText

Démarrage et configuration

Le système de configuration du Kit de développement logiciel (SDK) Agents remplace la ConfigurationBotFrameworkAuthentication classe par l’interface AuthConfiguration .

Pour charger la configuration à partir du fichier par défaut .env utilise loadAuthConfigFromEnv.

Important

Les variables de configuration sont décrites dans Configurer l’authentification en JavaScript.

Configuration de l’environnement

Créez un .env fichier avec les variables suivantes :

# Required for Azure Bot Service
clientId=your-app-id
clientSecret=your-app-secret  
tenantId=your-tenant-id

# Optional - for local debugging
PORT=3978
DEBUG=true

Remarque de migration : Mettez à jour les noms de vos variables d’environnement, comme indiqué dans le tableau suivant :

Kit de développement logiciel (SDK) Bot Framework Kit de développement logiciel (SDK) Agents
MicrosoftAppId clientId
MicrosoftAppPassword clientSecret
MicrosoftAppTenantId tenantId

Authentification et sécurité

Lorsque le Kit de développement logiciel (SDK) Bot Framework autorise les demandes entrantes, il inclut des jetons d’autorisation JSON Web Token (JWT) dans la pile. Le Kit de développement logiciel (SDK) Agents ne le fait pas. Lorsque vous utilisez un runtime de serveur web tel qu’express, vous devez configurer un intergiciel JWT pour autoriser les requêtes entrantes en fonction du jeton du porteur JWT, le Kit de développement logiciel (SDK) Agents fournit la authorizeJWT(AuthConfiguration) méthode.

Middleware JWT (requis pour la production) :

import { authorizeJWT, loadAuthConfigFromEnv } from '@microsoft/agents-hosting'

const authConfig = loadAuthConfigFromEnv()
server.use(authorizeJWT(authConfig))

Développement local :

Pour le débogage local, la validation JWT peut être désactivée :

// Only for local development - NEVER in production
if (process.env.NODE_ENV === 'development') {
    // JWT validation disabled for local testing
} else {
    server.use(authorizeJWT(authConfig))
}

Options d’installation du serveur

Le Kit de développement logiciel (SDK) Agents fournit deux approches pour configurer votre serveur :

Utiliser la méthode startServer

Utilisez cette approche simplifiée pour les nouveaux projets lorsque vous souhaitez une configuration minimale et n’avez pas besoin d’intergiciels personnalisés.

Mettez à jour votre code d’initialisation à partir de botbuilder:

const { EchoBot } = require('./bot');
const {
    CloudAdapter,
    ConfigurationBotFrameworkAuthentication
} = require('botbuilder');
const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env);
const adapter = new CloudAdapter(botFrameworkAuthentication);
const myBot = new EchoBot();
const server = express();
server.use(express.json());
server.post('/api/messages', async (req, res) => 
    await adapter.process(req, res, (context) => 
      myBot.run(context));
);

Pour héberger des assistants avec startServer() :

const { EchoBot } = require('./bot');
const { startServer } = require('@microsoft/agents-hosting-express')
startServer(new EchoBot());

Configuration manuelle d’Express

Utilisez cette approche lors de la migration de bots existants, besoin d’un intergiciel personnalisé, voulez un contrôle total sur la configuration Express

const { EchoBot } = require('./bot');
const {
    CloudAdapter,
    loadAuthConfigFromEnv, // Update
    authorizeJWT // Update
} = require('@microsoft/agents-hosting'); // Update
const authConfig = loadAuthConfigFromEnv(); // Update
const adapter = new CloudAdapter(authConfig); // Update
const myBot = new EchoBot();
const server = express();
server.use(express.json());
server.use(authorizeJWT(authConfig)); // Update
server.post('/api/messages', async (req, res) => 
    await adapter.process(req, res, (context) => 
      myBot.run(context));
);

const port = process.env.PORT || 3978;
server.listen(port, () => {
    console.log(`Server listening on port ${port}`);
}).on('error', (err) => {
    console.error('Server failed to start:', err);
    process.exit(1);
});

Prise en charge de ActivityHandler

La plupart des bots créés avec le Kit de développement logiciel (SDK) Bot Framework sont basés sur la classe de botbuilder-core.ActivityHandler base.

Le Kit de développement logiciel (SDK) Agents fournit une agents-hosting.ActivityHandler compatible qui conserve la même surface d’API pour faciliter la migration.

Principales différences

Voici quelques différences clés entre le Kit de développement logiciel (SDK) Bot Framework et le SDK Agents :

Paramètres du gestionnaire :

SDK Type de gestionnaire
Kit de développement logiciel (SDK) Bot Framework BotHandler
Kit de développement logiciel (SDK) Agents AgentHandler

Méthodes supplémentaires dans le Kit de développement logiciel (SDK) Agents :

Méthode Description
onMessageDelete Gère les activités de suppression de messages
onMessageUpdate Gère les activités de mise à jour des messages
onSignInInvoke Gère les activités d’invocation pour la connexion

Méthodes manquantes dans le Kit de développement logiciel (SDK) Agents :

Méthode Motif
onCommand Les activités de commande ne sont pas prises en charge
onCommandResult Les activités de résultat de commande ne sont pas prises en charge
onEvent Gestion des événements génériques (les types d'événements spécifiques comme onTokenResponseEvent sont toujours pris en charge)
onTokenResponseEvent Événements de réponse de jeton OAuth

Modifications de signature de méthode :

Toutes les méthodes de gestionnaire renvoient ActivityHandler au lieu de this pour le chaînage de méthodes. Les fonctions de gestionnaire utilisent le AgentHandler type, qui a la même signature que BotHandler

Exemple de migration :

Kit de développement logiciel (SDK) Bot Framework :

const { ActivityHandler } = require('botbuilder');

class MyBot extends ActivityHandler {
    constructor() {
        super();
        this.onMessage(async (context, next) => {
            await context.sendActivity('Hello!');
            await next();
        });
    }
}

La migration est principalement simple, avec la modification principale étant l’instruction import et le type de gestionnaire. La plupart des bots basés sur l’existant ActivityHandlerdoivent fonctionner avec des modifications minimales.

Important

ActivityHandler est déconseillé au profit de la classe AgentApplication

Migration de ActivityHandler vers vers AgentApplication

Bien que ActivityHandler soit pris en charge pour assurer la compatibilité descendante, il est recommandé d'utiliser AgentApplication.

Utilisation de ActivityHandler:

import { ActivityHandler } from '@microsoft/agents-hosting'

class MyBot extends ActivityHandler {
    constructor() {
        super()
        this.onMessage(async (context, next) => {
            await context.sendActivity('Hello!')
            await next()
        })
        
        this.onMembersAdded(async (context, next) => {
            await context.sendActivity('Welcome!')
            await next()
        })
    }
}

Principales différences

Le tableau suivant décrit les principales différences de fonctionnalités entre ActivityHandler et AgentApplication:

Caractéristique ActivityHandler AgentApplication
Gestion de l’état Gestion manuelle de l’état requise Gestion de l’état intégrée fournie
Gestion des événements Gestionnaires d’événements génériques (par exemple, onMembersAdded) Gestionnaires d’événements plus spécifiques (par exemple, membersAdded)
Fonction suivante Les gestionnaires nécessitent l’appel next() Les gestionnaires n'ont pas besoin d'appeler next()
Stockage Configuration manuelle du stockage Prise en charge du stockage intégré avec persistance automatique de l’état

Modèles de migration courants

Voici quelques modèles de migration courants :

Bot d'Écho Simple

Bot Framework

const { ActivityHandler } = require('botbuilder')

class EchoBot extends ActivityHandler {
    constructor() {
        super()
        this.onMessage(async (context, next) => {
            await context.sendActivity(`You said: ${context.activity.text}`)
            await next()
        })
    }
}

Gestion de l’état

Utilisation de AgentApplication:

import { AgentApplication, MemoryStorage } from '@microsoft/agents-hosting'

const agent = new AgentApplication({
    storage: new MemoryStorage()
})

agent.onMessage('/count', async (context, state) => {
    const count = state.conversation.count ?? 0
    state.conversation.count = count + 1
    await context.sendActivity(`Count: ${state.conversation.count}`)
})

Hériter de AgentApplication

Pour les scénarios plus complexes, vous pouvez créer une classe qui hérite de AgentApplication:

import { AgentApplication, MemoryStorage, MessageFactory } from '@microsoft/agents-hosting'

class MyAgent extends AgentApplication {
    constructor() {
        super({
            storage: new MemoryStorage()
        })
        this.setupRoutes()
    }
    
    setupRoutes() {
        this.onMessage('/help', this.handleHelp)
        this.onMessage('/status', this.handleStatus)
        this.onMessage('/reset', this.handleReset)
        
        this.onActivity('message', this.handleDefault)
        this.onConversationUpdate('membersAdded', this.handleWelcome)
    }
    
    handleHelp = async (context, state) => {
        const helpText = `
                Available commands:
                - /help - Show this help message
                - /status - Show current status
                - /reset - Reset conversation state
        `
        await context.sendActivity(MessageFactory.text(helpText))
    }
    
    handleStatus = async (context, state) => {
        const messageCount = state.conversation.messageCount ?? 0
        await context.sendActivity(`Messages processed: ${messageCount}`)
    }
    
    handleReset = async (context, state) => {
        state.deleteConversationState()
        await context.sendActivity('Conversation state has been reset.')
    }
    
    handleWelcome = async (context, state) => {
        const welcomeText = 'Welcome! Type /help to see available commands.'
        await context.sendActivity(MessageFactory.text(welcomeText))
    }
    
    handleDefault = async (context, state) => {
        // Increment message counter
        const messageCount = (state.conversation.messageCount ?? 0) + 1
        state.conversation.messageCount = messageCount
        
        const replyText = `Echo: ${context.activity.text} (Message #${messageCount})`
        await context.sendActivity(MessageFactory.text(replyText))
    }
}

export default new MyAgent()

Avantages de ce modèle

Avantage Description
Meilleure organisation Méthodes distinctes pour différents gestionnaires
Réutilisabilité Peut être facilement étendu ou hérité
Testabilité Les méthodes individuelles peuvent être testées unitairement
Maintainability Structure de code plus propre pour les bots complexes
Fonctions de flèche Lier automatiquement le this contexte sans avoir besoin de .bind()