Skip to content

Commit be26d31

Browse files
fujita-hpamelafoxmanekinekko
authored
Add chat history feature (#1988)
* Add chat history feature 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. * Add translations for chat history in Spanish and French * Update e2e test * Refactor chat history configuration variables Changed variable names to make their functions clearer. * Refactor session state handling Changed to generate session state on the server side. * Add support for chat history feature to bicep * Update workflows, docs, typing * Apply suggestions from code review Co-authored-by: Wassim Chegham <[email protected]> * Revert e2e test change --------- Co-authored-by: Pamela Fox <[email protected]> Co-authored-by: Wassim Chegham <[email protected]> Co-authored-by: Pamela Fox <[email protected]>
1 parent f4f6896 commit be26d31

33 files changed

+708
-9
lines changed

.azdo/pipelines/azure-dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ steps:
111111
AZURE_ADLS_GEN2_FILESYSTEM: $(AZURE_ADLS_GEN2_FILESYSTEM)
112112
DEPLOYMENT_TARGET: $(DEPLOYMENT_TARGET)
113113
AZURE_CONTAINER_APPS_WORKLOAD_PROFILE: $(AZURE_CONTAINER_APPS_WORKLOAD_PROFILE)
114-
114+
USE_CHAT_HISTORY_BROWSER: $(USE_CHAT_HISTORY_BROWSER)
115115
- task: AzureCLI@2
116116
displayName: Deploy Application
117117
inputs:

.github/workflows/azure-dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ jobs:
9595
AZURE_ADLS_GEN2_FILESYSTEM: ${{ vars.AZURE_ADLS_GEN2_FILESYSTEM }}
9696
DEPLOYMENT_TARGET: ${{ vars.DEPLOYMENT_TARGET }}
9797
AZURE_CONTAINER_APPS_WORKLOAD_PROFILE: ${{ vars.AZURE_CONTAINER_APPS_WORKLOAD_PROFILE }}
98-
98+
USE_CHAT_HISTORY_BROWSER: ${{ vars.USE_CHAT_HISTORY_BROWSER }}
9999
steps:
100100
- name: Checkout
101101
uses: actions/checkout@v4

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ If you followed the steps above to install the pre-commit hooks, then you can ju
165165
## Adding new azd environment variables
166166

167167
When adding new azd environment variables, please remember to update:
168+
168169
1. App Service's [azure.yaml](./azure.yaml)
169170
1. [ADO pipeline](.azdo/pipelines/azure-dev.yml).
170171
1. [Github workflows](.github/workflows/azure-dev.yml)

app/backend/app.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
CONFIG_AUTH_CLIENT,
6060
CONFIG_BLOB_CONTAINER_CLIENT,
6161
CONFIG_CHAT_APPROACH,
62+
CONFIG_CHAT_HISTORY_BROWSER_ENABLED,
6263
CONFIG_CHAT_VISION_APPROACH,
6364
CONFIG_CREDENTIAL,
6465
CONFIG_GPT4V_DEPLOYED,
@@ -79,6 +80,7 @@
7980
CONFIG_VECTOR_SEARCH_ENABLED,
8081
)
8182
from core.authentication import AuthenticationHelper
83+
from core.sessionhelper import create_session_id
8284
from decorators import authenticated, authenticated_path
8385
from error import error_dict, error_response
8486
from prepdocs import (
@@ -218,10 +220,15 @@ async def chat(auth_claims: Dict[str, Any]):
218220
else:
219221
approach = cast(Approach, current_app.config[CONFIG_CHAT_APPROACH])
220222

223+
# If session state is provided, persists the session state,
224+
# else creates a new session_id depending on the chat history options enabled.
225+
session_state = request_json.get("session_state")
226+
if session_state is None:
227+
session_state = create_session_id(current_app.config[CONFIG_CHAT_HISTORY_BROWSER_ENABLED])
221228
result = await approach.run(
222229
request_json["messages"],
223230
context=context,
224-
session_state=request_json.get("session_state"),
231+
session_state=session_state,
225232
)
226233
return jsonify(result)
227234
except Exception as error:
@@ -244,10 +251,15 @@ async def chat_stream(auth_claims: Dict[str, Any]):
244251
else:
245252
approach = cast(Approach, current_app.config[CONFIG_CHAT_APPROACH])
246253

254+
# If session state is provided, persists the session state,
255+
# else creates a new session_id depending on the chat history options enabled.
256+
session_state = request_json.get("session_state")
257+
if session_state is None:
258+
session_state = create_session_id(current_app.config[CONFIG_CHAT_HISTORY_BROWSER_ENABLED])
247259
result = await approach.run_stream(
248260
request_json["messages"],
249261
context=context,
250-
session_state=request_json.get("session_state"),
262+
session_state=session_state,
251263
)
252264
response = await make_response(format_as_ndjson(result))
253265
response.timeout = None # type: ignore
@@ -276,6 +288,7 @@ def config():
276288
"showSpeechInput": current_app.config[CONFIG_SPEECH_INPUT_ENABLED],
277289
"showSpeechOutputBrowser": current_app.config[CONFIG_SPEECH_OUTPUT_BROWSER_ENABLED],
278290
"showSpeechOutputAzure": current_app.config[CONFIG_SPEECH_OUTPUT_AZURE_ENABLED],
291+
"showChatHistoryBrowser": current_app.config[CONFIG_CHAT_HISTORY_BROWSER_ENABLED],
279292
}
280293
)
281294

@@ -439,6 +452,7 @@ async def setup_clients():
439452
USE_SPEECH_INPUT_BROWSER = os.getenv("USE_SPEECH_INPUT_BROWSER", "").lower() == "true"
440453
USE_SPEECH_OUTPUT_BROWSER = os.getenv("USE_SPEECH_OUTPUT_BROWSER", "").lower() == "true"
441454
USE_SPEECH_OUTPUT_AZURE = os.getenv("USE_SPEECH_OUTPUT_AZURE", "").lower() == "true"
455+
USE_CHAT_HISTORY_BROWSER = os.getenv("USE_CHAT_HISTORY_BROWSER", "").lower() == "true"
442456

443457
# WEBSITE_HOSTNAME is always set by App Service, RUNNING_IN_PRODUCTION is set in main.bicep
444458
RUNNING_ON_AZURE = os.getenv("WEBSITE_HOSTNAME") is not None or os.getenv("RUNNING_IN_PRODUCTION") is not None
@@ -609,6 +623,7 @@ async def setup_clients():
609623
current_app.config[CONFIG_SPEECH_INPUT_ENABLED] = USE_SPEECH_INPUT_BROWSER
610624
current_app.config[CONFIG_SPEECH_OUTPUT_BROWSER_ENABLED] = USE_SPEECH_OUTPUT_BROWSER
611625
current_app.config[CONFIG_SPEECH_OUTPUT_AZURE_ENABLED] = USE_SPEECH_OUTPUT_AZURE
626+
current_app.config[CONFIG_CHAT_HISTORY_BROWSER_ENABLED] = USE_CHAT_HISTORY_BROWSER
612627

613628
# Various approaches to integrate GPT and external knowledge, most applications will use a single one of these patterns
614629
# or some derivative, here we include several for exploration purposes

app/backend/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@
2222
CONFIG_SPEECH_SERVICE_LOCATION = "speech_service_location"
2323
CONFIG_SPEECH_SERVICE_TOKEN = "speech_service_token"
2424
CONFIG_SPEECH_SERVICE_VOICE = "speech_service_voice"
25+
CONFIG_CHAT_HISTORY_BROWSER_ENABLED = "chat_history_browser_enabled"

app/backend/core/sessionhelper.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import uuid
2+
from typing import Union
3+
4+
5+
def create_session_id(config_chat_history_browser_enabled: bool) -> Union[str, None]:
6+
if config_chat_history_browser_enabled:
7+
return str(uuid.uuid4())
8+
return None

app/frontend/package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"i18next": "^23.12.2",
2323
"i18next-browser-languagedetector": "^8.0.0",
2424
"i18next-http-backend": "^2.5.2",
25+
"idb": "^8.0.0",
2526
"ndjson-readablestream": "^1.2.0",
2627
"react": "^18.3.1",
2728
"react-dom": "^18.3.1",

app/frontend/src/api/models.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export type Config = {
8989
showSpeechInput: boolean;
9090
showSpeechOutputBrowser: boolean;
9191
showSpeechOutputAzure: boolean;
92+
showChatHistoryBrowser: boolean;
9293
};
9394

9495
export type SimpleAPIResponse = {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.container {
2+
display: flex;
3+
align-items: center;
4+
gap: 0.375em;
5+
cursor: pointer;
6+
padding: 0.5rem;
7+
}

0 commit comments

Comments
 (0)