You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using AppStae class, which inherits from TurnState class. Everything works just fine, however, lately I was expanding the app to support document upload and search functionality and therefore I've refactored it to be more flexible using DI container. This way I can access various services easily from anywhere in the app.
However, same cannot be said about the AppState. As soon as I register it with builder.Services.AddScoped<AppState>();, whenever I try to populate property values in TempState, I get TurnState hasn't been loaded. Call LoadStateAsync() first... ---> Microsoft.Teams.AI.Exceptions.TeamsAIException: One or more errors occurred. (temp TurnState hasn't been loaded. Call LoadStateAsync() first.) --- End of inner exception stack trace --- at Microsoft.Teams.AI.AI.Planners.ActionPlanner1.ContinueTaskAsync(ITurnContext context, TState state, AI1 ai, CancellationToken cancellationToken) at Microsoft.Teams.AI.AI.Planners.ActionPlanner1.BeginTaskAsync(ITurnContext context, TState state, AI1 ai, CancellationToken cancellationToken) at Microsoft.Teams.AI.AI.AI1.RunAsync(ITurnContext turnContext, TState turnState, Nullable1 startTime, Int32 stepCount, CancellationToken cancellationToken) at Microsoft.Teams.AI.Application1._OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken) at Microsoft.Teams.AI.Application1.OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken) at Microsoft.Bot.Builder.MiddlewareSet.ReceiveActivityWithStatusAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken) at Microsoft.Bot.Builder.BotAdapter.RunPipelineAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken) error.
Code snippets
publicclassAppState:TurnState{publicAppState():base(){ScopeDefaults[CONVERSATION_SCOPE]=newAppConversationState();ScopeDefaults[USER_SCOPE]=newAppUserState();ScopeDefaults[TEMP_SCOPE]=newAppTempState();}/// <summary>/// Stores all the conversation-related state./// </summary>publicnewAppConversationStateConversation{get{TurnStateEntryscope=GetScope(CONVERSATION_SCOPE);if(scope==null){thrownewArgumentException($"{CONVERSATION_SCOPE} TurnState hasn't been loaded. Call LoadStateAsync() first.");}return(AppConversationState)scope.Value!;}set{TurnStateEntryscope=GetScope(CONVERSATION_SCOPE);if(scope==null){thrownewArgumentException($"{CONVERSATION_SCOPE} TurnState hasn't been loaded. Call LoadStateAsync() first.");}scope.Replace(value!);}}publicnewAppUserStateUser{get{TurnStateEntryscope=GetScope(USER_SCOPE);if(scope==null){thrownewArgumentException($"{USER_SCOPE} TurnState hasn't been loaded. Call LoadStateAsync() first.");}return(AppUserState)scope.Value!;}set{TurnStateEntryscope=GetScope(USER_SCOPE);if(scope==null){thrownewArgumentException($"{USER_SCOPE} TurnState hasn't been loaded. Call LoadStateAsync() first.");}scope.Replace(value!);}}publicnewAppTempStateTemp{get{TurnStateEntryscope=GetScope(TEMP_SCOPE);if(scope==null){thrownewArgumentException($"{TEMP_SCOPE} TurnState hasn't been loaded. Call LoadStateAsync() first.");}return(AppTempState)scope.Value!;}set{TurnStateEntryscope=GetScope(TEMP_SCOPE);if(scope==null){thrownewArgumentException($"{TEMP_SCOPE} TurnState hasn't been loaded. Call LoadStateAsync() first.");}scope.Replace(value!);}}}// This class adds custom properties to the turn state which will be accessible in the activity handler methods.publicclassAppConversationState:Record{privateconststring_greetedKey="greeted";publicboolGreeted{get=>Get<bool>(_greetedKey);set=>Set(_greetedKey,value);}}publicclassAppUserState:Record{}publicclassAppTempState:TempState{privateconststring_documentTextKey="documentText";publicstring?DocumentText{get=>Get<string?>(_documentTextKey);set=>Set(_documentTextKey,value);}privateconststring_propertyAddressKey="propertyAddress";publicstring?PropertyAddress{get=>Get<string?>(_propertyAddressKey);set=>Set(_propertyAddressKey,value);}}
It looks like authentication logic is not able to write into _turnState.Temp.AuthTokens["graph"]; and my AuthService cannot then pick it up:
publicclassAuthService:IAuthService{privatereadonlyIServiceScopeFactory_serviceScopeFactory;publicAuthService(IServiceScopeFactoryserviceScopeFactory){_serviceScopeFactory=serviceScopeFactory;}publicstringGetGraphToken(){using(varscope=_serviceScopeFactory.CreateScope()){var_turnState=scope.ServiceProvider.GetRequiredService<AppState>();ArgumentNullException.ThrowIfNull(_turnState);stringgraphToken=string.Empty;if(LocalConfig.LocalSettings.Environment!="DEBUG"){graphToken=_turnState.Temp.AuthTokens["graph"];if(string.IsNullOrEmpty(graphToken)){thrownewException("No auth token found in state. Authentication failed.");}}else{// FOR DEBUGGING ONLYgraphToken="";}returngraphToken;}}}
However, if I pass to action handlers - at that point I can save values into TempState just fine. What is the correct way of passing AppState object around? Unfortunately, due to firewall restrictions, authentication is one area which I cannot properly debug locally.
Apologies for being impatient, but I've tried dozens of ideas and spent days on this issue, and I still can't make AppState to be ready for the authentication logic of the app. Everything else works, if I simply hard-code the Graph token (i.e. from then on AppState properties can be written to and read from as usual), but authentication logic doesn't seem to be able to write into appState.Temp.AuthTokens["graph"] after it retrieves the token, because the AppState is not yet loaded. Just to remind you - it only happens if I register AppState as a service via builder.Services.AddScoped<AppState>(); or builder.Services.AddScoped<IAppState, AppState>();.
And I have no idea how would I get it loaded via LoadStateAsync() this early.
@SubbaReddi thank you. At first , I tried using it as a singleton as well, but that made no difference in its behaviour. I can try it again, if you believe that's where the issue is.
Question
I'm using
AppStae
class, which inherits fromTurnState
class. Everything works just fine, however, lately I was expanding the app to support document upload and search functionality and therefore I've refactored it to be more flexible using DI container. This way I can access various services easily from anywhere in the app.However, same cannot be said about the
AppState
. As soon as I register it withbuilder.Services.AddScoped<AppState>();
, whenever I try to populate property values in TempState, I getTurnState hasn't been loaded. Call LoadStateAsync() first... ---> Microsoft.Teams.AI.Exceptions.TeamsAIException: One or more errors occurred. (temp TurnState hasn't been loaded. Call LoadStateAsync() first.) --- End of inner exception stack trace --- at Microsoft.Teams.AI.AI.Planners.ActionPlanner1.ContinueTaskAsync(ITurnContext context, TState state, AI1 ai, CancellationToken cancellationToken) at Microsoft.Teams.AI.AI.Planners.ActionPlanner1.BeginTaskAsync(ITurnContext context, TState state, AI1 ai, CancellationToken cancellationToken) at Microsoft.Teams.AI.AI.AI1.RunAsync(ITurnContext turnContext, TState turnState, Nullable1 startTime, Int32 stepCount, CancellationToken cancellationToken) at Microsoft.Teams.AI.Application1._OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken) at Microsoft.Teams.AI.Application1.OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken) at Microsoft.Bot.Builder.MiddlewareSet.ReceiveActivityWithStatusAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken) at Microsoft.Bot.Builder.BotAdapter.RunPipelineAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken)
error.Code snippets
It looks like authentication logic is not able to write into
_turnState.Temp.AuthTokens["graph"];
and myAuthService
cannot then pick it up:However, if I pass to action handlers - at that point I can save values into TempState just fine. What is the correct way of passing
AppState
object around? Unfortunately, due to firewall restrictions, authentication is one area which I cannot properly debug locally.Auth logic I am using:
The text was updated successfully, but these errors were encountered: