Skip to content

Conversation

fujita-h
Copy link
Contributor

@fujita-h fujita-h commented Sep 25, 2024

This commit adds the following new files:

  • HistoryItem: A new component for displaying chat history items.
  • HistoryPanel: A new component for displaying the chat history panel.
  • HistoryButton: A new component for opening the chat history.
  • HistoryProviders: A new module containing history provider classes.

These changes include functionality to support future enhancements to the chat history feature.

The chat history feature is only enabled when you explicitly set the environment variable USE_CHAT_HISTORY.

The history function uses the browser's IndexedDB. I understand that there is also an approach to use CosmosDB, but this requires enabling authentication to identify users, so I decided to start with IndexedDB, which does not depend on authentication.

To make it easier to implement other data stores, I made it easier to implement additional data stores with HistoryProviders.

Related: #977 #1863 #259

Purpose

Does this introduce a breaking change?

When developers merge from main and run the server, azd up, or azd deploy, will this produce an error?
If you're not sure, try it out on an old environment.

[ ] Yes
[x] No

Does this require changes to learn.microsoft.com docs?

This repository is referenced by this tutorial
which includes deployment, settings and usage instructions. If text or screenshot need to change in the tutorial,
check the box below and notify the tutorial author. A Microsoft employee can do this for you if you're an external contributor.

[ ] Yes
[x] No

Type of change

[ ] Bugfix
[x] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Documentation content changes
[ ] Other... Please describe:

Code quality checklist

See CONTRIBUTING.md for more details.

  • The current tests all pass (python -m pytest).
  • I added tests that prove my fix is effective or that my feature works
  • I ran python -m pytest --cov to verify 100% coverage of added lines
  • I ran python -m mypy to check for type errors
  • I either used the pre-commit hooks or ran ruff and black manually on my code.

This commit adds the following new files:
- HistoryItem: A new component for displaying chat history items.
- HistoryPanel: A new component for displaying the chat history panel.
- HistoryButton: A new component for opening the chat history.
- HistoryProviders: A new module containing history provider classes.

These changes include functionality to support future enhancements to the chat history feature.
@fujita-h
Copy link
Contributor Author

@microsoft-github-policy-service agree

@pamelafox
Copy link
Collaborator

Ooo, very interesting approach with the IndexedDB! It sounds like you've designed it very thoughtfully, I'll take a look soon.

// AI Chat Protocol: Client must pass on any session state received from the server
session_state: answers.length ? answers[answers.length - 1][1].session_state : null
// Set new UUID as session state for the first request
session_state: answers.length ? answers[answers.length - 1][1].session_state : crypto.randomUUID()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we'd also use this randomUUID for apps with logged in users, or would we use Entra OIDs for them? Am wondering if it'd be better to have a helper function to generate this ID.
And if the history storage was in CosmosDB, would we still generate the UUID on the client? Want to make sure this is forward-compatible if possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for pointing that out.
You're right, it seems we should think about this carefully.

We need to assign an ID to each "series of chats" to identify them, regardless of whether the user is logged in or not. We'll call this sessionId.

In the case of IndexedDB

  • On the client side (React), sessionId does not necessarily have to be a UUID, as long as it is a unique key within the client side.
  • There is also no need to exchange sessionId with the server side using session_state (the current implementation of storing sessionId in session_state is in anticipation of expansion to CosmosDB).

In the case of CosmosDB

  • It is expected that the design will set the user's Entra OID as the partition key and sessionId as the unique key.
  • In CosmosDB, conversationId does not need to be a UUID, as long as it is unique within the partition.
  • As mentioned above, sessionId does not need to be a UUID on the client side (React).
  • sessionId is a key in CosmosDB. Therefore, it is preferable to generate it on the server side rather than on the client side.
  • As the name session_state suggests, it is natural that the sessionId stored here is generated on the server side.
  • When chat messages are sent and received, the sessionId needs to be exchanged between the server side and the client side. session_state can be used for this.

Fix Plan

The plan is to summarize these points and fix them in the following plan.

  • If the request from the client contains session_state, it will be used as sessionId. If not, a new one will be generated on the server and added to session_state.
  • sessionId does not necessarily need to be UUID, but unless there is a specific reason, there is no major problem with UUID, so we will basically generate it with uuid.uuid4().
  • Considering the possibility that UUID may be inconvenient when other storage methods are added in the future, we will create a helper function that generates sessionId according to the storage method used.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for that thorough design discussion, that sounds good!

"i18next": "^23.12.2",
"i18next-browser-languagedetector": "^8.0.0",
"i18next-http-backend": "^2.5.2",
"idb": "^8.0.0",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a reasonable addition according to packagephobia and snyk:

https://packagephobia.com/result?p=idb
https://snyk.io/advisor/npm-package/idb

CONFIG_SPEECH_SERVICE_LOCATION = "speech_service_location"
CONFIG_SPEECH_SERVICE_TOKEN = "speech_service_token"
CONFIG_SPEECH_SERVICE_VOICE = "speech_service_voice"
CONFIG_CHAT_HISTORY_ENABLED = "chat_history_enabled"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that a "chat history" feature means different things to different people, I think it might help for the config and env variable to be more specific.

For example, for the env var:

USE_CHAT_HISTORY_BROWSER

In future, we might have:
USE_CHAT_HISTORY_COSMOS

That'd be similar to how we did speech output.

showSpeechInput: boolean;
showSpeechOutputBrowser: boolean;
showSpeechOutputAzure: boolean;
showChatHistory: boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
showChatHistory: boolean;
showChatHistoryBrowser: boolean;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per my other comment, I think we should be clear about what's enabled.

Changed variable names to make their functions clearer.
Changed to generate session state on the server side.
@fujita-h
Copy link
Contributor Author

fujita-h commented Oct 1, 2024

I have corrected the points you pointed out, so please review again.
The environment variable to enable this feature has been changed to USE_CHAT_HISTORY_BROWSER.

@zedhaque
Copy link
Contributor

zedhaque commented Oct 1, 2024

Thank you for the PR! 😊 I’m testing it, and it works locally (auth), but I had to make two minor Bicep changes to deploy it to Azure. These changes are:

  1. adding app variables in main.bicep
  ENABLE_LANGUAGE_PICKER: enableLanguagePicker
  USE_CHAT_HISTORY_BROWSER: useChatHistoryBrowser
  USE_SPEECH_INPUT_BROWSER: useSpeechInputBrowser
  1. adding chat history in main.parameters.json
    "enableLanguagePicker": {
      "value": "${ENABLE_LANGUAGE_PICKER=false}"
    },
    "useChatHistoryBrowser": {
      "value": "${USE_CHAT_HISTORY_BROWSER =false}"
    },

@fujita-h
Copy link
Contributor Author

fujita-h commented Oct 2, 2024

Thank you for pointing that out. I had forgotten about bicep.
ENABLE_LANGUAGE_PICKER and USE_SPEECH_INPUT_BROWSER are outside the scope of this PR, so I have omitted them.

Copy link
Collaborator

@pamelafox pamelafox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm approving the change, but will await a review of the es translations and will check with @mattgotteiner before merging.

Copy link
Collaborator

@mattgotteiner mattgotteiner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approved pending translation review

@pamelafox pamelafox merged commit be26d31 into Azure-Samples:main Oct 4, 2024
17 checks passed
@ibrahimnasir0
Copy link

@fujita-h Where we will be able to see this chat history ?
Can you guide on that

@fujita-h
Copy link
Contributor Author

fujita-h commented Oct 4, 2024

@ibrahimnasir0 Just set the environment variables as follows:
azd env set USE_CHAT_HISTORY_BROWSER true

@ibrahimnasir0
Copy link

Hi @fujita-h
I'm working on integrating Cosmos DB with this updated project to save chat history along with the user OID (since login and Entra ID are enabled). Could you provide some guidance on how to proceed with this?

@fujita-h fujita-h deleted the feat-chat-history branch October 19, 2024 02:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants