En robot måste ibland starta om en konversation från början. Om en användare till exempel inte svarar efter en viss tidsperiod. I den här artikeln beskrivs två metoder för att förfalla en konversation:
Exempelkoden i den här artikeln börjar med strukturen för en robot med flera svängar och utökar robotens funktioner genom att lägga till ytterligare kod (som finns i följande avsnitt). Den här utökade koden visar hur du rensar konversationstillståndet efter att en viss tidsperiod har passerat.
Den här typen av konversation som upphör att gälla uppnås genom att lägga till en senast använda tidsegenskap i robotens konversationstillstånd. Det här egenskapsvärdet jämförs sedan med den aktuella tiden i aktivitetshanteraren innan aktiviteter bearbetas.
appsettings.json
Lägg först till en ExpireAfterSeconds
inställning i appsettings.json:
{
"MicrosoftAppId": "",
"MicrosoftAppPassword": "",
"ExpireAfterSeconds": 30
}
Robotar\DialogBot.cs
Lägg sedan till ExpireAfterSeconds
fälten , LastAccessedTimeProperty
och DialogStateProperty
i robotklassen och initiera dem i robotens konstruktor. Lägg också till en IConfiguration
parameter i konstruktorn som värdet ska hämtas ExpireAfterSeconds
med.
I stället för att skapa dialogtillståndets egenskapsåtkomst infogad i OnMessageActivityAsync
metoden skapar och registrerar du den vid initieringstillfället. Roboten behöver åtkomst till tillståndsegenskapen, inte bara för att köra dialogrutan, utan även för att rensa dialogtillståndet.
protected readonly int ExpireAfterSeconds;
protected readonly IStatePropertyAccessor<DateTime> LastAccessedTimeProperty;
protected readonly IStatePropertyAccessor<DialogState> DialogStateProperty;
// Existing fields omitted...
public DialogBot(IConfiguration configuration, ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger)
{
ConversationState = conversationState;
UserState = userState;
Dialog = dialog;
Logger = logger;
ExpireAfterSeconds = configuration.GetValue<int>("ExpireAfterSeconds");
DialogStateProperty = ConversationState.CreateProperty<DialogState>(nameof(DialogState));
LastAccessedTimeProperty = ConversationState.CreateProperty<DateTime>(nameof(LastAccessedTimeProperty));
}
Lägg slutligen till kod i robotens OnTurnAsync
metod för att rensa dialogtillståndet om konversationen är för gammal.
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default)
{
// Retrieve the property value, and compare it to the current time.
var lastAccess = await LastAccessedTimeProperty.GetAsync(turnContext, () => DateTime.UtcNow, cancellationToken).ConfigureAwait(false);
if ((DateTime.UtcNow - lastAccess) >= TimeSpan.FromSeconds(ExpireAfterSeconds))
{
// Notify the user that the conversation is being restarted.
await turnContext.SendActivityAsync("Welcome back! Let's start over from the beginning.").ConfigureAwait(false);
// Clear state.
await ConversationState.ClearStateAsync(turnContext, cancellationToken).ConfigureAwait(false);
}
await base.OnTurnAsync(turnContext, cancellationToken).ConfigureAwait(false);
// Set LastAccessedTime to the current time.
await LastAccessedTimeProperty.SetAsync(turnContext, DateTime.UtcNow, cancellationToken).ConfigureAwait(false);
// Save any state changes that might have occurred during the turn.
await ConversationState.SaveChangesAsync(turnContext, false, cancellationToken).ConfigureAwait(false);
await UserState.SaveChangesAsync(turnContext, false, cancellationToken).ConfigureAwait(false);
}
.Env
Lägg först till en ExpireAfterSeconds
inställning i .env:
MicrosoftAppId=
MicrosoftAppPassword=
ExpireAfterSeconds=30
bots\dialogBot.js
Lägg sedan till fält DialogBot
i och uppdatera konstruktorn. Lägg till lokala fält för expireAfterSeconds
och lastAccessedTimeProperty
.
Lägg till expireAfterSeconds
som en parameter i konstruktorn och skapa nödvändiga StatePropertyAccessor
:
constructor(expireAfterSeconds, conversationState, userState, dialog) {
// Existing code omitted...
this.lastAccessedTimeProperty = this.conversationState.createProperty('LastAccessedTime');
this.expireAfterSeconds = expireAfterSeconds;
// Existing code omitted...
}
Lägg till kod i robotens run
metod:
async run(context) {
// Retrieve the property value, and compare it to the current time.
const now = new Date();
const lastAccess = new Date(await this.lastAccessedTimeProperty.get(context, now.toISOString()));
if (now !== lastAccess && ((now.getTime() - lastAccess.getTime()) / 1000) >= this.expireAfterSeconds) {
// Notify the user that the conversation is being restarted.
await context.sendActivity("Welcome back! Let's start over from the beginning.");
// Clear state.
await this.conversationState.clear(context);
}
await super.run(context);
// Set LastAccessedTime to the current time.
await this.lastAccessedTimeProperty.set(context, now.toISOString());
// Save any state changes. The load happened during the execution of the Dialog.
await this.conversationState.saveChanges(context, false);
await this.userState.saveChanges(context, false);
}
index.js
Slutligen uppdaterar du index.js
för att skicka parametern ExpireAfterSeconds
till DialogBot
:
const bot = new DialogBot(process.env.ExpireAfterSeconds, conversationState, userState, dialog);
application.properties
Lägg först till en ExpireAfterSeconds
inställning i application.properties:
MicrosoftAppId=
MicrosoftAppPassword=
server.port=3978
ExpireAfterSeconds=30
DialogBot.java
Lägg sedan till expireAfterSeconds
fälten , lastAccessedTimeProperty
och dialogStateProperty
i robotklassen och initiera dem i robotens konstruktor. Lägg också till en Configuration
parameter i konstruktorn för att hämta ExpireAfterSeconds
värdet.
I stället för att skapa dialogtillståndets egenskapsåtkomst infogad i onMessageActivity
metoden skapar och registrerar du den vid initieringstillfället. Roboten behöver åtkomst till tillståndsegenskapen, inte bara för att köra dialogrutan, utan även för att rensa dialogtillståndet.
protected final int expireAfterSeconds;
protected final StatePropertyAccessor<LocalTime> lastAccessedTimeProperty;
protected final StatePropertyAccessor<DialogState> dialogStateProperty;
// Existing fields omitted...
public DialogBot(
Configuration configuration,
ConversationState withConversationState,
UserState withUserState,
Dialog withDialog
) {
dialog = withDialog;
conversationState = withConversationState;
userState = withUserState;
expireAfterSeconds = configuration.getProperty("ExpireAfterSeconds") != null ?
Integer.parseInt(configuration.getProperty("ExpireAfterSeconds")) :
30;
lastAccessedTimeProperty = conversationState.createProperty("LastAccessedTimeProperty");
dialogStateProperty = conversationState.createProperty("DialogStateProperty");
}
Lägg slutligen till kod i robotens onTurn
metod för att rensa dialogtillståndet om konversationen är för gammal.
@Override
public CompletableFuture<Void> onTurn(
TurnContext turnContext
) {
LocalTime lastAccess = lastAccessedTimeProperty.get(turnContext).join();
if (lastAccess != null
&& (java.time.temporal.ChronoUnit.SECONDS.between(lastAccess, LocalTime.now()) >= expireAfterSeconds)) {
turnContext.sendActivity("Welcome back! Let's start over from the beginning.").join();
conversationState.clearState(turnContext).join();
}
return lastAccessedTimeProperty.set(turnContext, LocalTime.now()).thenCompose(setResult -> {
return super.onTurn(turnContext)
.thenCompose(result -> conversationState.saveChanges(turnContext))
// Save any state changes that might have occurred during the turn.
.thenCompose(result -> userState.saveChanges(turnContext));
});
}
config.py
Lägg först till en ExpireAfterSeconds
inställning i config.py:
PORT = 3978
APP_ID = os.environ.get("MicrosoftAppId", "")
APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "")
EXPIRE_AFTER_SECONDS = os.environ.get("ExpireAfterSeconds", 30)
bots\dialog_bot.py
Lägg sedan till fält DialogBot
i och uppdatera konstruktorn. Lägg till lokala fält för expire_after_seconds
och last_accessed_time_property
.
Lägg till expire_after_seconds
som en parameter i konstruktorn och skapa nödvändiga StatePropertyAccessor
:
def __init__(
self,
expire_after_seconds: int,
conversation_state: ConversationState,
user_state: UserState,
dialog: Dialog,
):
# Existing code omitted...
self.expire_after_seconds = expire_after_seconds
self.dialog_state_property = conversation_state.create_property("DialogState")
self.last_accessed_time_property = conversation_state.create_property("LastAccessedTime")
self.conversation_state = conversation_state
self.user_state = user_state
self.dialog = dialog
Ändra on_message_activity
så att den dialog_state_property
använder :
async def on_message_activity(self, turn_context: TurnContext):
await DialogHelper.run_dialog(
self.dialog,
turn_context,
self.dialog_state_property,
)
Lägg till kod i robotens on_turn
metod:
async def on_turn(self, turn_context: TurnContext):
# Retrieve the property value, and compare it to the current time.
now_seconds = int(time.time())
last_access = int(
await self.last_accessed_time_property.get(turn_context, now_seconds)
)
if now_seconds != last_access and (
now_seconds - last_access >= self.expire_after_seconds
):
# Notify the user that the conversation is being restarted.
await turn_context.send_activity(
"Welcome back! Let's start over from the beginning."
)
# Clear state.
await self.conversation_state.clear_state(turn_context)
await self.conversation_state.save_changes(turn_context, True)
await super().on_turn(turn_context)
# Set LastAccessedTime to the current time.
await self.last_accessed_time_property.set(turn_context, now_seconds)
# Save any state changes that might have occurred during the turn.
await self.conversation_state.save_changes(turn_context)
await self.user_state.save_changes(turn_context)
app.py
Slutligen uppdaterar du app.py
för att skicka parametern EXPIRE_AFTER_SECONDS
till DialogBot
:
BOT = DialogBot(CONFIG.EXPIRE_AFTER_SECONDS, CONVERSATION_STATE, USER_STATE, DIALOG)
Cosmos DB innehåller en TTL-funktion (Time To Live) som gör att du kan ta bort objekt automatiskt från en container efter en viss tidsperiod. Detta kan konfigureras inifrån Azure-portalen eller när containern skapas (med hjälp av språkspecifika Cosmos DB-SDK:er).
Bot Framework SDK exponerar inte en TTL-konfigurationsinställning. Initiering av containrar kan dock åsidosättas och Cosmos DB SDK kan användas för att konfigurera TTL innan Bot Framework-lagringen initieras.
Börja med en ny kopia av exemplet med fråga med flera svar och lägg till Microsoft.Bot.Builder.Azure
NuGet-paketet i projektet.
appsettings.json
Uppdatera appsettings.json för att inkludera Lagringsalternativ för Cosmos DB:
{
"MicrosoftAppId": "",
"MicrosoftAppPassword": "",
"CosmosDbTimeToLive": 30,
"CosmosDbEndpoint": "<endpoint-for-your-cosmosdb-instance>",
"CosmosDbAuthKey": "<your-cosmosdb-auth-key>",
"CosmosDbDatabaseId": "<your-database-id>",
"CosmosDbUserStateContainerId": "<no-ttl-container-id>",
"CosmosDbConversationStateContainerId": "<ttl-container-id>"
}
Observera de två ContainerId:erna, ett för UserState
och ett för ConversationState
. Standard-TTL är inställt på containern ConversationState
, men inte på UserState
.
CosmosDbStorageInitializerHostedService.cs
Skapa sedan en CosmosDbStorageInitializerHostedService
klass som skapar containern med den konfigurerade Time To Live.
// Add required using statements...
public class CosmosDbStorageInitializerHostedService : IHostedService
{
readonly CosmosDbPartitionedStorageOptions _storageOptions;
readonly int _cosmosDbTimeToLive;
public CosmosDbStorageInitializerHostedService(IConfiguration config)
{
_storageOptions = new CosmosDbPartitionedStorageOptions()
{
CosmosDbEndpoint = config["CosmosDbEndpoint"],
AuthKey = config["CosmosDbAuthKey"],
DatabaseId = config["CosmosDbDatabaseId"],
ContainerId = config["CosmosDbConversationStateContainerId"]
};
_cosmosDbTimeToLive = config.GetValue<int>("CosmosDbTimeToLive");
}
public async Task StartAsync(CancellationToken cancellationToken)
{
using (var client = new CosmosClient(
_storageOptions.CosmosDbEndpoint,
_storageOptions.AuthKey,
_storageOptions.CosmosClientOptions ?? new CosmosClientOptions()))
{
// Create the contaier with the provided TTL
var containerResponse = await client
.GetDatabase(_storageOptions.DatabaseId)
.DefineContainer(_storageOptions.ContainerId, "/id")
.WithDefaultTimeToLive(_cosmosDbTimeToLive)
.WithIndexingPolicy().WithAutomaticIndexing(false).Attach()
.CreateIfNotExistsAsync(_storageOptions.ContainerThroughput)
.ConfigureAwait(false);
}
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
Startup.cs
Slutligen uppdaterar du Startup.cs
för att använda lagringsinitieraren och Cosmos DB för tillstånd:
// Existing code omitted...
// commented out MemoryStorage, since we are using CosmosDbPartitionedStorage instead
// services.AddSingleton<IStorage, MemoryStorage>();
// Add the Initializer as a HostedService (so it's called during the app service startup)
services.AddHostedService<CosmosDbStorageInitializerHostedService>();
// Create the storage options for User state
var userStorageOptions = new CosmosDbPartitionedStorageOptions()
{
CosmosDbEndpoint = Configuration["CosmosDbEndpoint"],
AuthKey = Configuration["CosmosDbAuthKey"],
DatabaseId = Configuration["CosmosDbDatabaseId"],
ContainerId = Configuration["CosmosDbUserStateContainerId"]
};
// Create the User state. (Used in this bot's Dialog implementation.)
services.AddSingleton(new UserState(new CosmosDbPartitionedStorage(userStorageOptions)));
// Create the storage options for Conversation state
var conversationStorageOptions = new CosmosDbPartitionedStorageOptions()
{
CosmosDbEndpoint = Configuration["CosmosDbEndpoint"],
AuthKey = Configuration["CosmosDbAuthKey"],
DatabaseId = Configuration["CosmosDbDatabaseId"],
ContainerId = Configuration["CosmosDbConversationStateContainerId"]
};
// Create the Conversation state. (Used by the Dialog system itself.)
services.AddSingleton(new ConversationState(new CosmosDbPartitionedStorage(conversationStorageOptions)));
// Existing code omitted...
Börja med en ny kopia av exemplet med fråga med flera svängar.
.Env
Uppdatera .env för att inkludera Cosmos DB-lagringsalternativ:
MicrosoftAppId=
MicrosoftAppPassword=
CosmosDbTimeToLive=30
CosmosDbEndpoint=<endpoint-for-your-cosmosdb-instance>
CosmosDbAuthKey=<your-cosmosdb-auth-key>
CosmosDbDatabaseId=<your-database-id>
CosmosDbUserStateContainerId=<no-ttl-container-id>
CosmosDbConversationStateContainerId=<ttl-container-id>
Observera de två ContainerId:erna, ett för UserState
och ett för ConversationState
. Standard-TTL är inställt på containern ConversationState
, men inte UserState
.
project.json
Lägg sedan till botbuilder-azure
npm-paketet i project.json.
"dependencies": {
"botbuilder": "~4.9.2",
"botbuilder-dialogs": "~4.9.2",
"botbuilder-azure": "~4.9.2",
"dotenv": "^8.2.0",
"path": "^0.12.7",
"restify": "~8.5.1"
},
index.js
Lägg till nödvändiga kräv-instruktioner i index.js:
const { CosmosDbPartitionedStorage } = require('botbuilder-azure');
const { CosmosClient } = require('@azure/cosmos');
Ersätt MemoryStorage
och ConversationState
UserState
skapa med:
// const memoryStorage = new MemoryStorage();
// Storage options for Conversation State
const conversationStorageOptions = {
cosmosDbEndpoint: process.env.CosmosDbEndpoint,
authKey: process.env.CosmosDbAuthKey,
databaseId: process.env.CosmosDbDatabaseId,
containerId: process.env.CosmosDbConversationStateContainerId
};
// Create a cosmosClient, and set defaultTtl (with other properties)
var cosmosClient = new CosmosClient({
endpoint: conversationStorageOptions.cosmosDbEndpoint,
key: conversationStorageOptions.authKey,
...conversationStorageOptions.cosmosClientOptions,
});
// Create the container with the provided TTL.
Promise.resolve(cosmosClient
.database(conversationStorageOptions.databaseId)
.containers.createIfNotExists({
id: conversationStorageOptions.containerId,
partitionKey: {
paths: ['/id']
},
defaultTtl: parseInt(process.env.CosmosDbTimeToLive, 10)
}));
// Storage options for User State
const userStorageOptions = {
cosmosDbEndpoint: process.env.CosmosDbEndpoint,
authKey: process.env.CosmosDbAuthKey,
databaseId: process.env.CosmosDbDatabaseId,
containerId: process.env.CosmosDbUserStateContainerId
};
// Create state instances.
const conversationState = new ConversationState(new CosmosDbPartitionedStorage(conversationStorageOptions));
const userState = new UserState(new CosmosDbPartitionedStorage(userStorageOptions));
Kör slutligen npm-installationen innan du startar roboten.
npm install
Börja med en ny kopia av exemplet med fråga med flera svar och lägg till följande beroenden i filen pom.xml:
<dependency>
<groupId>com.microsoft.bot</groupId>
<artifactId>bot-azure</artifactId>
<version>4.13.0</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-cosmos</artifactId>
</dependency>
application.properties
Uppdatera application.properties så att de innehåller Lagringsalternativ för Cosmos DB:
MicrosoftAppId=
MicrosoftAppPassword=
server.port=3978
CosmosDbTimeToLive = 30
CosmosDbEndpoint = <endpoint-for-your-cosmosdb-instance>
CosmosDbAuthKey = <your-cosmosdb-auth-key>
CosmosDbDatabaseId = <your-database-id>
CosmosDbUserStateContainerId = <no-ttl-container-id>
CosmosDbConversationStateContainerId = <ttl-container-id>
Observera de två ContainerId:erna, ett för UserState
och ett för ConversationState
. Standard-TTL är inställt på containern ConversationState
, men inte på UserState
.
CosmosDbStorageInitializer.java
Skapa sedan en CosmosDbStorageInitializer
klass som skapar containern med den konfigurerade Time To Live.
package com.microsoft.bot.sample.multiturnprompt;
import com.azure.cosmos.CosmosAsyncClient;
import com.azure.cosmos.CosmosClientBuilder;
import com.azure.cosmos.models.CosmosContainerProperties;
import com.microsoft.bot.azure.CosmosDbPartitionedStorageOptions;
import com.microsoft.bot.integration.Configuration;
public class CosmosDbStorageInitializer {
final CosmosDbPartitionedStorageOptions storageOptions;
final int cosmosDbTimeToLive;
public CosmosDbStorageInitializer(Configuration configuration) {
storageOptions = new CosmosDbPartitionedStorageOptions();
storageOptions.setCosmosDbEndpoint(configuration.getProperty("CosmosDbEndpoint"));
storageOptions.setAuthKey(configuration.getProperty("CosmosDbAuthKey"));
storageOptions.setDatabaseId(configuration.getProperty("CosmosDbDatabaseId"));
storageOptions.setContainerId(configuration.getProperty("CosmosDbConversationStateContainerId"));
cosmosDbTimeToLive = configuration.getProperty("CosmosDbTimeToLive") != null
? Integer.parseInt(configuration.getProperty("CosmosDbTimeToLive"))
: 30;
}
public void initialize() {
CosmosAsyncClient client = new CosmosClientBuilder().endpoint(storageOptions.getCosmosDbEndpoint())
.key(storageOptions.getAuthKey()).buildAsyncClient();
client.createDatabaseIfNotExists(storageOptions.getDatabaseId()).block();
CosmosContainerProperties cosmosContainerProperties = new CosmosContainerProperties(
storageOptions.getContainerId(), "/id");
cosmosContainerProperties.setDefaultTimeToLiveInSeconds(cosmosDbTimeToLive);
client.getDatabase(storageOptions.getDatabaseId()).createContainerIfNotExists(cosmosContainerProperties)
.block();
client.close();
}
}
Application.java
Slutligen uppdaterar du Application.java
för att använda lagringsinitieraren och Cosmos DB för tillstånd:
// Existing code omitted...
@Override
public ConversationState getConversationState(Storage storage) {
Configuration configuration = getConfiguration();
CosmosDbStorageInitializer initializer = new CosmosDbStorageInitializer(configuration);
initializer.initialize();
CosmosDbPartitionedStorageOptions storageOptions = new CosmosDbPartitionedStorageOptions();
storageOptions.setCosmosDbEndpoint(configuration.getProperty("CosmosDbEndpoint"));
storageOptions.setAuthKey(configuration.getProperty("CosmosDbAuthKey"));
storageOptions.setDatabaseId(configuration.getProperty("CosmosDbDatabaseId"));
storageOptions.setContainerId(configuration.getProperty("CosmosDbConversationStateContainerId"));
return new ConversationState(new CosmosDbPartitionedStorage(storageOptions));
}
/**
* Returns a UserState object. Default scope of Singleton.
*
* @param storage The Storage object to use.
* @return A UserState object.
*/
@Override
public UserState getUserState(Storage storage) {
Configuration configuration = getConfiguration();
CosmosDbPartitionedStorageOptions storageOptions = new CosmosDbPartitionedStorageOptions();
storageOptions.setCosmosDbEndpoint(configuration.getProperty("CosmosDbEndpoint"));
storageOptions.setAuthKey(configuration.getProperty("CosmosDbAuthKey"));
storageOptions.setDatabaseId(configuration.getProperty("CosmosDbDatabaseId"));
storageOptions.setContainerId(configuration.getProperty("CosmosDbUserStateContainerId"));
return new UserState(new CosmosDbPartitionedStorage(storageOptions));
}
Börja med en ny kopia av exemplet med fråga med flera svängar.
config.py
Uppdatera config.py
för att inkludera Cosmos DB-lagringsalternativ:
PORT = 3978
APP_ID = os.environ.get("MicrosoftAppId", "")
APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "")
COSMOSDB_TTL = os.environ.get("CosmosDbTimeToLive", 30)
COSMOSDB_ENDPOINT = os.environ.get("CosmosDbEndpoint", "<endpoint-for-your-cosmosdb-instance>")
COSMOSDB_AUTH_KEY = os.environ.get("CosmosDbAuthKey", "<your-cosmosdb-auth-key>")
COSMOSDB_DATABASE_ID = os.environ.get("CosmosDbDatabaseId", "<your-database-id>")
COSMOSDB_USER_STATE_CONTAINER_ID = os.environ.get("CosmosDbUserStateContainerId", "<no-ttl-container-id>")
COSMOSDB_CONVERSATION_STATE_CONTAINER_ID = os.environ.get("CosmosDbConversationStateContainerId", "<ttl-container-id>")
Observera de två ContainerId:erna, ett för UserState
och ett för ConversationState
. Standard-TTL är inställt på containern ConversationState
, men inte UserState
.
requirements.txt
Lägg sedan till paketet i botbuilder-azure
requirements.txt.
botbuilder-integration-aiohttp>=4.10.0
botbuilder-dialogs>=4.10.0
botbuilder-ai>=4.10.0
botbuilder-azure>=4.10.0
Kör sedan pip install:
pip install -r requirements.txt
app.py
client = cosmos_client.CosmosClient(
CONFIG.COSMOSDB_ENDPOINT, {"masterKey": CONFIG.COSMOSDB_AUTH_KEY},
)
containers = list(client.QueryContainers("dbs/" + CONFIG.COSMOSDB_DATABASE_ID, {
"query": "SELECT * FROM r WHERE r.id=@id",
"parameters": [
{"name": "@id", "value": CONFIG.COSMOSDB_CONVERSATION_STATE_CONTAINER_ID}
],
}))
if len(containers) < 1:
new_container = client.CreateContainer(
"dbs/" + CONFIG.COSMOSDB_DATABASE_ID,
{
"defaultTtl": CONFIG.COSMOSDB_TTL,
"id": CONFIG.COSMOSDB_CONVERSATION_STATE_CONTAINER_ID,
"partitionKey": {"paths": ["/id"], "kind": "Hash",},
},
)
Cosmos DB tar nu automatiskt bort konversationstillståndsposter efter 30 sekunders inaktivitet.