- {useLogin && }
+ {useLogin && }
diff --git a/app/frontend/src/pages/oneshot/OneShot.tsx b/app/frontend/src/pages/oneshot/OneShot.tsx
index bb048ca5fb..eb73ad5394 100644
--- a/app/frontend/src/pages/oneshot/OneShot.tsx
+++ b/app/frontend/src/pages/oneshot/OneShot.tsx
@@ -3,7 +3,7 @@ import { Checkbox, ChoiceGroup, IChoiceGroupOption, Panel, DefaultButton, Spinne
import styles from "./OneShot.module.css";
-import { askApi, ChatAppResponse, AskRequest, RetrievalMode } from "../../api";
+import { askApi, ChatAppResponse, ChatAppRequest, RetrievalMode } from "../../api";
import { Answer, AnswerError } from "../../components/Answer";
import { QuestionInput } from "../../components/QuestionInput";
import { ExampleList } from "../../components/Example";
@@ -35,7 +35,7 @@ export function Component(): JSX.Element {
const [activeCitation, setActiveCitation] = useState();
const [activeAnalysisPanelTab, setActiveAnalysisPanelTab] = useState(undefined);
- const client = useLogin ? useMsal().instance : undefined
+ const client = useLogin ? useMsal().instance : undefined;
const makeApiRequest = async (question: string) => {
lastQuestionRef.current = question;
@@ -45,26 +45,34 @@ export function Component(): JSX.Element {
setActiveCitation(undefined);
setActiveAnalysisPanelTab(undefined);
- const token = client ? await getToken(client) : undefined
+ const token = client ? await getToken(client) : undefined;
try {
- const request: AskRequest = {
- question,
- overrides: {
- promptTemplate: promptTemplate.length === 0 ? undefined : promptTemplate,
- promptTemplatePrefix: promptTemplatePrefix.length === 0 ? undefined : promptTemplatePrefix,
- promptTemplateSuffix: promptTemplateSuffix.length === 0 ? undefined : promptTemplateSuffix,
- excludeCategory: excludeCategory.length === 0 ? undefined : excludeCategory,
- top: retrieveCount,
- retrievalMode: retrievalMode,
- semanticRanker: useSemanticRanker,
- semanticCaptions: useSemanticCaptions,
- useOidSecurityFilter: useOidSecurityFilter,
- useGroupsSecurityFilter: useGroupsSecurityFilter
+ const request: ChatAppRequest = {
+ messages: [
+ {
+ content: question,
+ role: "user"
+ }
+ ],
+ context: {
+ overrides: {
+ prompt_template: promptTemplate.length === 0 ? undefined : promptTemplate,
+ prompt_template_prefix: promptTemplatePrefix.length === 0 ? undefined : promptTemplatePrefix,
+ prompt_template_suffix: promptTemplateSuffix.length === 0 ? undefined : promptTemplateSuffix,
+ exclude_category: excludeCategory.length === 0 ? undefined : excludeCategory,
+ top: retrieveCount,
+ retrieval_mode: retrievalMode,
+ semantic_ranker: useSemanticRanker,
+ semantic_captions: useSemanticCaptions,
+ use_oid_security_filter: useOidSecurityFilter,
+ use_groups_security_filter: useGroupsSecurityFilter
+ }
},
- idToken: token?.accessToken
+ // ChatAppProtocol: Client must pass on any session state received from the server
+ session_state: answer ? answer.choices[0].session_state : null
};
- const result = await askApi(request);
+ const result = await askApi(request, token?.accessToken);
setAnswer(result);
} catch (e) {
setError(e);
@@ -183,7 +191,6 @@ export function Component(): JSX.Element {
onRenderFooterContent={() => setIsConfigPanelOpen(false)}>Close}
isFooterAtBottom={true}
>
-
)}
- {useLogin && (
+ {useLogin && (
- { useLogin && }
+ {useLogin && }
);
diff --git a/app/frontend/vite.config.ts b/app/frontend/vite.config.ts
index b5ff872f32..1e8c4efa2b 100644
--- a/app/frontend/vite.config.ts
+++ b/app/frontend/vite.config.ts
@@ -25,6 +25,8 @@ export default defineConfig({
},
server: {
proxy: {
+ "/content/": "http://localhost:50505",
+ "/auth_setup": "http://localhost:50505",
"/ask": "http://localhost:50505",
"/chat": "http://localhost:50505"
}
diff --git a/infra/main.bicep b/infra/main.bicep
index 5ddcf80316..6bd548f873 100644
--- a/infra/main.bicep
+++ b/infra/main.bicep
@@ -22,6 +22,8 @@ param searchServiceLocation string = ''
@allowed(['basic', 'standard', 'standard2', 'standard3', 'storage_optimized_l1', 'storage_optimized_l2'])
param searchServiceSkuName string // Set in main.parameters.json
param searchIndexName string // Set in main.parameters.json
+param searchQueryLanguage string // Set in main.parameters.json
+param searchQuerySpeller string // Set in main.parameters.json
param storageAccountName string = ''
param storageResourceGroupName string = ''
@@ -142,7 +144,7 @@ module backend 'core/host/appservice.bicep' = {
tags: union(tags, { 'azd-service-name': 'backend' })
appServicePlanId: appServicePlan.outputs.id
runtimeName: 'python'
- runtimeVersion: '3.10'
+ runtimeVersion: '3.11'
appCommandLine: 'python3 -m gunicorn main:app'
scmDoBuildDuringDeployment: true
managedIdentity: true
@@ -152,6 +154,8 @@ module backend 'core/host/appservice.bicep' = {
AZURE_STORAGE_CONTAINER: storageContainerName
AZURE_SEARCH_INDEX: searchIndexName
AZURE_SEARCH_SERVICE: searchService.outputs.name
+ AZURE_SEARCH_QUERY_LANGUAGE: searchQueryLanguage
+ AZURE_SEARCH_QUERY_SPELLER: searchQuerySpeller
APPLICATIONINSIGHTS_CONNECTION_STRING: useApplicationInsights ? monitoring.outputs.applicationInsightsConnectionString : ''
// Shared by all OpenAI deployments
OPENAI_HOST: openAiHost
diff --git a/infra/main.parameters.json b/infra/main.parameters.json
index 15ddc8289c..3c5719161e 100644
--- a/infra/main.parameters.json
+++ b/infra/main.parameters.json
@@ -47,6 +47,12 @@
"searchServiceSkuName": {
"value": "${AZURE_SEARCH_SERVICE_SKU=standard}"
},
+ "searchQueryLanguage": {
+ "value": "${AZURE_SEARCH_QUERY_LANGUAGE=en-us}"
+ },
+ "searchQuerySpeller": {
+ "value": "${AZURE_SEARCH_QUERY_SPELLER=lexicon}"
+ },
"storageAccountName": {
"value": "${AZURE_STORAGE_ACCOUNT}"
},
diff --git a/locustfile.py b/locustfile.py
index 3bcf62d05a..0bc5f0cbfc 100644
--- a/locustfile.py
+++ b/locustfile.py
@@ -16,15 +16,16 @@ def ask_question(self):
json={
"history": [
{
- "user": random.choice(
+ "content": random.choice(
[
"What is included in my Northwind Health Plus plan that is not in standard?",
"What does a Product Manager do?",
"What happens in a performance review?",
"Whats your whistleblower policy?",
]
- )
- }
+ ),
+ "role": "user",
+ },
],
"overrides": {
"retrieval_mode": "hybrid",
@@ -40,11 +41,12 @@ def ask_question(self):
"/chat",
json={
"history": [
+ {"content": "What happens in a performance review?", "role": "user"},
{
- "user": "What happens in a performance review?",
- "bot": "During the performance review at Contoso Electronics, the supervisor will discuss the employee's performance over the past year and provide feedback on areas for improvement. They will also provide an opportunity for the employee to discuss their goals and objectives for the upcoming year. The review is a two-way dialogue between managers and employees, and employees will receive a written summary of their performance review which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
+ "content": "During a performance review, employees will receive feedback on their performance over the past year, including both successes and areas for improvement. The feedback will be provided by the employee's supervisor and is intended to help the employee develop and grow in their role [employee_handbook-3.pdf]. The review is a two-way dialogue between the employee and their manager, so employees are encouraged to be honest and open during the process [employee_handbook-3.pdf]. The employee will also have the opportunity to discuss their goals and objectives for the upcoming year [employee_handbook-3.pdf]. A written summary of the performance review will be provided to the employee, which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
+ "role": "assistant",
},
- {"user": "Does my plan cover eye exams?"},
+ {"content": "Does my plan cover eye exams?", "role": "user"},
],
"overrides": {
"retrieval_mode": "hybrid",
diff --git a/pyproject.toml b/pyproject.toml
index 26d8bcc1d6..def1afefd7 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -16,3 +16,14 @@ source = ["scripts", "app"]
[tool.coverage.report]
show_missing = true
+
+[tool.mypy]
+check_untyped_defs = true
+python_version = 3.9
+
+[[tool.mypy.overrides]]
+module = [
+ "msal.*",
+ "msal_extensions.*",
+]
+ignore_missing_imports = true
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 4108af173b..f5408b2b29 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -12,3 +12,4 @@ pytest-playwright
pre-commit
locust
pip-tools
+mypy
diff --git a/scripts/adlsgen2setup.py b/scripts/adlsgen2setup.py
index 0c4bd59c14..00de15eb25 100644
--- a/scripts/adlsgen2setup.py
+++ b/scripts/adlsgen2setup.py
@@ -3,6 +3,7 @@
import json
import logging
import os
+from typing import Any, Optional
import aiohttp
from azure.core.credentials_async import AsyncTokenCredential
@@ -24,7 +25,7 @@ def __init__(
storage_account_name: str,
filesystem_name: str,
security_enabled_groups: bool,
- data_access_control_format: dict[str, any],
+ data_access_control_format: dict[str, Any],
credentials: AsyncTokenCredential,
):
"""
@@ -49,7 +50,7 @@ def __init__(
self.credentials = credentials
self.security_enabled_groups = security_enabled_groups
self.data_access_control_format = data_access_control_format
- self.graph_headers = None
+ self.graph_headers: Optional[dict[str, str]] = None
async def run(self):
async with self.create_service_client() as service_client:
@@ -143,7 +144,7 @@ async def create_or_get_group(self, group_name: str):
return group_id
-async def main(args: any):
+async def main(args: Any):
async with AzureDeveloperCliCredential() as credentials:
with open(args.data_access_control) as f:
data_access_control_format = json.load(f)
diff --git a/scripts/manageacl.py b/scripts/manageacl.py
index 6b49ae4b75..fa02bd2a4f 100644
--- a/scripts/manageacl.py
+++ b/scripts/manageacl.py
@@ -2,11 +2,11 @@
import asyncio
import json
import logging
-from typing import Union
+from typing import Any, Union
from azure.core.credentials import AzureKeyCredential
from azure.core.credentials_async import AsyncTokenCredential
-from azure.identity import AzureDeveloperCliCredential
+from azure.identity.aio import AzureDeveloperCliCredential
from azure.search.documents.aio import SearchClient
from azure.search.documents.indexes.aio import SearchIndexClient
from azure.search.documents.indexes.models import (
@@ -143,14 +143,16 @@ async def enable_acls(self, endpoint: str):
await search_index_client.create_or_update_index(index_definition)
-async def main(args: any):
+async def main(args: Any):
# Use the current user identity to connect to Azure services unless a key is explicitly set for any of them
azd_credential = (
AzureDeveloperCliCredential()
if args.tenant_id is None
else AzureDeveloperCliCredential(tenant_id=args.tenant_id, process_timeout=60)
)
- search_credential = azd_credential if args.search_key is None else AzureKeyCredential(args.search_key)
+ search_credential: Union[AsyncTokenCredential, AzureKeyCredential] = azd_credential
+ if args.search_key is not None:
+ search_credential = AzureKeyCredential(args.search_key)
command = ManageAcl(
service_name=args.search_service,
diff --git a/scripts/prepdocs.ps1 b/scripts/prepdocs.ps1
index e01f99b468..8097b3d2c2 100755
--- a/scripts/prepdocs.ps1
+++ b/scripts/prepdocs.ps1
@@ -27,7 +27,11 @@ if ($env:AZURE_ADLS_GEN2_STORAGE_ACCOUNT) {
}
$aclArg = "--useacls"
}
-$argumentList = "./scripts/prepdocs.py `"$cwd/data/*`" $adlsGen2StorageAccountArg $adlsGen2FilesystemArg $adlsGen2FilesystemPathArg " + `
+# Optional Search Analyzer name if using a custom analyzer
+if ($env:AZURE_SEARCH_ANALYZER_NAME) {
+ $searchAnalyzerNameArg = "--searchanalyzername $env:AZURE_SEARCH_ANALYZER_NAME"
+}
+$argumentList = "./scripts/prepdocs.py `"$cwd/data/*`" $adlsGen2StorageAccountArg $adlsGen2FilesystemArg $adlsGen2FilesystemPathArg $searchAnalyzerNameArg " + `
"$aclArg --storageaccount $env:AZURE_STORAGE_ACCOUNT --container $env:AZURE_STORAGE_CONTAINER " + `
"--searchservice $env:AZURE_SEARCH_SERVICE --openaihost `"$env:OPENAI_HOST`" " + `
"--openaiservice `"$env:AZURE_OPENAI_SERVICE`" --openaikey `"$env:OPENAI_API_KEY`" " + `
diff --git a/scripts/prepdocs.py b/scripts/prepdocs.py
index c555928fe3..90c8001551 100644
--- a/scripts/prepdocs.py
+++ b/scripts/prepdocs.py
@@ -7,11 +7,12 @@
import re
import tempfile
import time
+from typing import Any, Optional, Union
import openai
import tiktoken
from azure.ai.formrecognizer import DocumentAnalysisClient
-from azure.core.credentials import AzureKeyCredential
+from azure.core.credentials import AzureKeyCredential, TokenCredential
from azure.identity import AzureDeveloperCliCredential
from azure.search.documents import SearchClient
from azure.search.documents.indexes import SearchIndexClient
@@ -60,7 +61,7 @@
SENTENCE_SEARCH_LIMIT = 100
SECTION_OVERLAP = 100
-open_ai_token_cache = {}
+open_ai_token_cache: dict[str, Any] = {}
CACHE_KEY_TOKEN_CRED = "openai_token_cred"
CACHE_KEY_CREATED_TIME = "created_time"
CACHE_KEY_TOKEN_TYPE = "token_type"
@@ -118,7 +119,7 @@ def remove_blobs(filename):
blob_container = blob_service.get_container_client(args.container)
if blob_container.exists():
if filename is None:
- blobs = blob_container.list_blob_names()
+ blobs = iter(blob_container.list_blob_names())
else:
prefix = os.path.splitext(os.path.basename(filename))[0]
blobs = filter(
@@ -177,8 +178,8 @@ def get_document_text(filename):
for page_num, page in enumerate(form_recognizer_results.pages):
tables_on_page = [
table
- for table in form_recognizer_results.tables
- if table.bounding_regions[0].page_number == page_num + 1
+ for table in (form_recognizer_results.tables or [])
+ if table.bounding_regions and table.bounding_regions[0].page_number == page_num + 1
]
# mark all positions of the table spans in the page
@@ -289,7 +290,9 @@ def filename_to_id(filename):
return f"file-{filename_ascii}-{filename_hash}"
-def create_sections(filename, page_map, use_vectors, embedding_deployment: str = None, embedding_model: str = None):
+def create_sections(
+ filename, page_map, use_vectors, embedding_deployment: Optional[str] = None, embedding_model: Optional[str] = None
+):
file_id = filename_to_id(filename)
for i, (content, pagenum) in enumerate(split_text(page_map, filename)):
section = {
@@ -342,7 +345,7 @@ def create_search_index():
)
fields = [
SimpleField(name="id", type="Edm.String", key=True),
- SearchableField(name="content", type="Edm.String", analyzer_name="en.microsoft"),
+ SearchableField(name="content", type="Edm.String", analyzer_name=args.searchanalyzername),
SearchField(
name="embedding",
type=SearchFieldDataType.Collection(SearchFieldDataType.Single),
@@ -397,7 +400,7 @@ def create_search_index():
def update_embeddings_in_batch(sections):
- batch_queue = []
+ batch_queue: list = []
copy_s = []
batch_response = {}
token_count = 0
@@ -469,9 +472,9 @@ def remove_from_index(filename):
r = search_client.search("", filter=filter, top=1000, include_total_count=True)
if r.get_count() == 0:
break
- r = search_client.delete_documents(documents=[{"id": d["id"]} for d in r])
+ removed_docs = search_client.delete_documents(documents=[{"id": d["id"]} for d in r])
if args.verbose:
- print(f"\tRemoved {len(r)} sections from index")
+ print(f"\tRemoved {len(removed_docs)} sections from index")
# It can take a few seconds for search results to reflect changes, so wait a bit
time.sleep(2)
@@ -494,8 +497,8 @@ def read_files(
path_pattern: str,
use_vectors: bool,
vectors_batch_support: bool,
- embedding_deployment: str = None,
- embedding_model: str = None,
+ embedding_deployment: Optional[str] = None,
+ embedding_model: Optional[str] = None,
):
"""
Recursively read directory structure under `path_pattern`
@@ -530,7 +533,10 @@ def read_files(
def read_adls_gen2_files(
- use_vectors: bool, vectors_batch_support: bool, embedding_deployment: str = None, embedding_model: str = None
+ use_vectors: bool,
+ vectors_batch_support: bool,
+ embedding_deployment: Optional[str] = None,
+ embedding_model: Optional[str] = None,
):
datalake_service = DataLakeServiceClient(
account_url=f"https://{args.datalakestorageaccount}.dfs.core.windows.net", credential=adls_gen2_creds
@@ -549,7 +555,7 @@ def read_adls_gen2_files(
file_client = filesystem_client.get_file_client(path)
file_client.download_file().readinto(temp_file)
- acls = None
+ acls: Optional[dict[str, list]] = None
if args.useacls:
# Parse out user ids and group ids
acls = {"oids": [], "groups": []}
@@ -560,7 +566,7 @@ def read_adls_gen2_files(
# ACL Format: user::rwx,group::r-x,other::r--,user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:r--
acl_list = acl_list.split(",")
for acl in acl_list:
- acl_parts = acl.split(":")
+ acl_parts: list = acl.split(":")
if len(acl_parts) != 3:
continue
if len(acl_parts[1]) == 0:
@@ -648,6 +654,12 @@ def read_adls_gen2_files(
required=False,
help="Optional. Use this Azure Cognitive Search account key instead of the current user identity to login (use az login to set current user for Azure)",
)
+ parser.add_argument(
+ "--searchanalyzername",
+ required=False,
+ default="en.microsoft",
+ help="Optional. Name of the Azure Cognitive Search analyzer to use for the content field in the index",
+ )
parser.add_argument("--openaihost", help="Host of the API used to compute embeddings ('azure' or 'openai')")
parser.add_argument("--openaiservice", help="Name of the Azure OpenAI service used to compute embeddings")
parser.add_argument(
@@ -706,14 +718,15 @@ def read_adls_gen2_files(
if args.tenantid is None
else AzureDeveloperCliCredential(tenant_id=args.tenantid, process_timeout=60)
)
- default_creds = azd_credential if args.searchkey is None or args.storagekey is None else None
adls_gen2_creds = azd_credential if args.datalakekey is None else AzureKeyCredential(args.datalakekey)
- search_creds = default_creds if args.searchkey is None else AzureKeyCredential(args.searchkey)
+ search_creds: Union[TokenCredential, AzureKeyCredential] = azd_credential
+ if args.searchkey is not None:
+ search_creds = AzureKeyCredential(args.searchkey)
use_vectors = not args.novectors
compute_vectors_in_batch = not args.disablebatchvectors and args.openaimodelname in SUPPORTED_BATCH_AOAI_MODEL
if not args.skipblobs:
- storage_creds = default_creds if args.storagekey is None else args.storagekey
+ storage_creds = azd_credential if args.storagekey is None else args.storagekey
if not args.localpdfparser:
# check if Azure Form Recognizer credentials are provided
if args.formrecognizerservice is None:
@@ -721,9 +734,9 @@ def read_adls_gen2_files(
"Error: Azure Form Recognizer service is not provided. Please provide formrecognizerservice or use --localpdfparser for local pypdf parser."
)
exit(1)
- formrecognizer_creds = (
- default_creds if args.formrecognizerkey is None else AzureKeyCredential(args.formrecognizerkey)
- )
+ formrecognizer_creds: Union[TokenCredential, AzureKeyCredential] = azd_credential
+ if args.formrecognizerkey is not None:
+ formrecognizer_creds = AzureKeyCredential(args.formrecognizerkey)
if use_vectors:
if args.openaihost != "openai":
diff --git a/scripts/prepdocs.sh b/scripts/prepdocs.sh
index b58e2b7f55..8411b1c684 100755
--- a/scripts/prepdocs.sh
+++ b/scripts/prepdocs.sh
@@ -17,11 +17,16 @@ if [ -n "$AZURE_ADLS_GEN2_STORAGE_ACCOUNT" ]; then
aclArg="--useacls"
fi
+if [ -n "$AZURE_SEARCH_ANALYZER_NAME" ]; then
+ searchAnalyzerNameArg="--searchanalyzername $AZURE_SEARCH_ANALYZER_NAME"
+fi
+
./scripts/.venv/bin/python ./scripts/prepdocs.py \
-'./data/*' $adlsGen2StorageAccountArg $adlsGen2FilesystemArg $adlsGen2FilesystemPathArg \
+'./data/*' $adlsGen2StorageAccountArg $adlsGen2FilesystemArg $adlsGen2FilesystemPathArg $searchAnalyzerNameArg \
$aclArg --storageaccount "$AZURE_STORAGE_ACCOUNT" \
--container "$AZURE_STORAGE_CONTAINER" --searchservice "$AZURE_SEARCH_SERVICE" \
--openaiservice "$AZURE_OPENAI_SERVICE" --openaideployment "$AZURE_OPENAI_EMB_DEPLOYMENT" \
--openaimodelname "$AZURE_OPENAI_EMB_MODEL_NAME" --index "$AZURE_SEARCH_INDEX" \
--formrecognizerservice "$AZURE_FORMRECOGNIZER_SERVICE" --openaimodelname "$AZURE_OPENAI_EMB_MODEL_NAME" \
---tenantid "$AZURE_TENANT_ID" -v
+--tenantid "$AZURE_TENANT_ID" --openaihost "$OPENAI_HOST" \
+--openaikey "$OPENAI_API_KEY" -v
diff --git a/scripts/requirements.txt b/scripts/requirements.txt
index f84b25693f..cb2f3493d6 100644
--- a/scripts/requirements.txt
+++ b/scripts/requirements.txt
@@ -2,7 +2,7 @@
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
-# pip-compile scripts/requirements.in
+# pip-compile requirements.in
#
aiohttp==3.8.5
# via openai
@@ -140,7 +140,7 @@ typing-extensions==4.8.0
# azure-storage-file-datalake
tzdata==2023.3
# via pandas
-urllib3==2.0.5
+urllib3==2.0.7
# via requests
yarl==1.9.2
# via aiohttp
diff --git a/tests/conftest.py b/tests/conftest.py
index 5f2c262a90..a2309c5953 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -64,7 +64,7 @@ async def mock_acreate(*args, **kwargs):
if messages[-1]["content"] == "Generate search query for: What is the capital of France?":
answer = "capital of France"
else:
- answer = "The capital of France is Paris."
+ answer = "The capital of France is Paris. [Benefit_Options-2.pdf]."
if "stream" in kwargs and kwargs["stream"] is True:
return AsyncChatCompletionIterator(answer)
else:
diff --git a/tests/e2e.py b/tests/e2e.py
index 6abcb2c71a..234676d083 100644
--- a/tests/e2e.py
+++ b/tests/e2e.py
@@ -53,15 +53,18 @@ def test_home(page: Page, live_server_url: str):
def test_chat(page: Page, live_server_url: str):
- # Set up a mock route to the /chat_stream endpoint
+ # Set up a mock route to the /chat endpoint with streaming results
def handle(route: Route):
+ # Assert that session_state is specified in the request (None for now)
+ session_state = route.request.post_data_json["session_state"]
+ assert session_state is None
# Read the JSONL from our snapshot results and return as the response
f = open("tests/snapshots/test_app/test_chat_stream_text/client0/result.jsonlines")
jsonl = f.read()
f.close()
route.fulfill(body=jsonl, status=200, headers={"Transfer-encoding": "Chunked"})
- page.route("*/**/chat_stream", handle)
+ page.route("*/**/chat", handle)
# Check initial page state
page.goto(live_server_url)
@@ -80,3 +83,135 @@ def handle(route: Route):
expect(page.get_by_text("Whats the dental plan?")).to_be_visible()
expect(page.get_by_text("The capital of France is Paris.")).to_be_visible()
expect(page.get_by_role("button", name="Clear chat")).to_be_enabled()
+
+ # Show the citation document
+ page.get_by_text("1. Benefit_Options-2.pdf").click()
+ expect(page.get_by_role("tab", name="Citation")).to_be_visible()
+ expect(page.get_by_title("Citation")).to_be_visible()
+
+ # Show the thought process
+ page.get_by_label("Show thought process").click()
+ expect(page.get_by_title("Thought process")).to_be_visible()
+ expect(page.get_by_text("Searched for:")).to_be_visible()
+
+ # Show the supporting content
+ page.get_by_label("Show supporting content").click()
+ expect(page.get_by_title("Supporting content")).to_be_visible()
+ expect(page.get_by_role("heading", name="Benefit_Options-2.pdf")).to_be_visible()
+
+ # Clear the chat
+ page.get_by_role("button", name="Clear chat").click()
+ expect(page.get_by_text("Whats the dental plan?")).not_to_be_visible()
+ expect(page.get_by_text("The capital of France is Paris.")).not_to_be_visible()
+ expect(page.get_by_role("button", name="Clear chat")).to_be_disabled()
+
+
+def test_chat_customization(page: Page, live_server_url: str):
+ # Set up a mock route to the /chat endpoint
+ def handle(route: Route):
+ overrides = route.request.post_data_json["context"]["overrides"]
+ assert overrides["retrieval_mode"] == "vectors"
+ assert overrides["semantic_ranker"] is False
+ assert overrides["semantic_captions"] is True
+ assert overrides["top"] == 1
+ assert overrides["prompt_template"] == "You are a cat and only talk about tuna."
+ assert overrides["exclude_category"] == "dogs"
+ assert overrides["suggest_followup_questions"] is True
+ assert overrides["use_oid_security_filter"] is False
+ assert overrides["use_groups_security_filter"] is False
+
+ # Read the JSON from our snapshot results and return as the response
+ f = open("tests/snapshots/test_app/test_chat_text/client0/result.json")
+ json = f.read()
+ f.close()
+ route.fulfill(body=json, status=200)
+
+ page.route("*/**/chat", handle)
+
+ # Check initial page state
+ page.goto(live_server_url)
+ expect(page).to_have_title("GPT + Enterprise data | Sample")
+
+ # Customize all the settings
+ page.get_by_role("button", name="Developer settings").click()
+ page.get_by_label("Override prompt template").click()
+ page.get_by_label("Override prompt template").fill("You are a cat and only talk about tuna.")
+ page.get_by_label("Retrieve this many search results:").click()
+ page.get_by_label("Retrieve this many search results:").fill("1")
+ page.get_by_label("Exclude category").click()
+ page.get_by_label("Exclude category").fill("dogs")
+ page.get_by_text("Use query-contextual summaries instead of whole documents").click()
+ page.get_by_text("Suggest follow-up questions").click()
+ page.get_by_text("Use semantic ranker for retrieval").click()
+ page.get_by_text("Vectors + Text (Hybrid)").click()
+ page.get_by_role("option", name="Vectors", exact=True).click()
+ page.get_by_text("Stream chat completion responses").click()
+ page.locator("button").filter(has_text="Close").click()
+
+ # Ask a question and wait for the message to appear
+ page.get_by_placeholder("Type a new question (e.g. does my plan cover annual eye exams?)").click()
+ page.get_by_placeholder("Type a new question (e.g. does my plan cover annual eye exams?)").fill(
+ "Whats the dental plan?"
+ )
+ page.get_by_role("button", name="Ask question button").click()
+
+ expect(page.get_by_text("Whats the dental plan?")).to_be_visible()
+ expect(page.get_by_text("The capital of France is Paris.")).to_be_visible()
+ expect(page.get_by_role("button", name="Clear chat")).to_be_enabled()
+
+
+def test_chat_nonstreaming(page: Page, live_server_url: str):
+ # Set up a mock route to the /chat_stream endpoint
+ def handle(route: Route):
+ # Read the JSON from our snapshot results and return as the response
+ f = open("tests/snapshots/test_app/test_chat_text/client0/result.json")
+ json = f.read()
+ f.close()
+ route.fulfill(body=json, status=200)
+
+ page.route("*/**/chat", handle)
+
+ # Check initial page state
+ page.goto(live_server_url)
+ expect(page).to_have_title("GPT + Enterprise data | Sample")
+ expect(page.get_by_role("button", name="Developer settings")).to_be_enabled()
+ page.get_by_role("button", name="Developer settings").click()
+ page.get_by_text("Stream chat completion responses").click()
+ page.locator("button").filter(has_text="Close").click()
+
+ # Ask a question and wait for the message to appear
+ page.get_by_placeholder("Type a new question (e.g. does my plan cover annual eye exams?)").click()
+ page.get_by_placeholder("Type a new question (e.g. does my plan cover annual eye exams?)").fill(
+ "Whats the dental plan?"
+ )
+ page.get_by_label("Ask question button").click()
+
+ expect(page.get_by_text("Whats the dental plan?")).to_be_visible()
+ expect(page.get_by_text("The capital of France is Paris.")).to_be_visible()
+ expect(page.get_by_role("button", name="Clear chat")).to_be_enabled()
+
+
+def test_ask(page: Page, live_server_url: str):
+ # Set up a mock route to the /ask endpoint
+ def handle(route: Route):
+ # Assert that session_state is specified in the request (None for now)
+ session_state = route.request.post_data_json["session_state"]
+ assert session_state is None
+ # Read the JSON from our snapshot results and return as the response
+ f = open("tests/snapshots/test_app/test_ask_rtr_hybrid/client0/result.json")
+ json = f.read()
+ f.close()
+ route.fulfill(body=json, status=200)
+
+ page.route("*/**/ask", handle)
+ page.goto(live_server_url)
+ expect(page).to_have_title("GPT + Enterprise data | Sample")
+
+ page.get_by_role("link", name="Ask a question").click()
+ page.get_by_placeholder("Example: Does my plan cover annual eye exams?").click()
+ page.get_by_placeholder("Example: Does my plan cover annual eye exams?").fill("Whats the dental plan?")
+ page.get_by_placeholder("Example: Does my plan cover annual eye exams?").click()
+ page.get_by_label("Ask question button").click()
+
+ expect(page.get_by_text("Whats the dental plan?")).to_be_visible()
+ expect(page.get_by_text("The capital of France is Paris.")).to_be_visible()
diff --git a/tests/snapshots/test_app/test_ask_rtr_hybrid/client0/result.json b/tests/snapshots/test_app/test_ask_rtr_hybrid/client0/result.json
index fba6d28157..809a74e7a8 100644
--- a/tests/snapshots/test_app/test_ask_rtr_hybrid/client0/result.json
+++ b/tests/snapshots/test_app/test_ask_rtr_hybrid/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n Benefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_ask_rtr_hybrid/client1/result.json b/tests/snapshots/test_app/test_ask_rtr_hybrid/client1/result.json
index fba6d28157..809a74e7a8 100644
--- a/tests/snapshots/test_app/test_ask_rtr_hybrid/client1/result.json
+++ b/tests/snapshots/test_app/test_ask_rtr_hybrid/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n Benefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_ask_rtr_text/client0/result.json b/tests/snapshots/test_app/test_ask_rtr_text/client0/result.json
index fba6d28157..809a74e7a8 100644
--- a/tests/snapshots/test_app/test_ask_rtr_text/client0/result.json
+++ b/tests/snapshots/test_app/test_ask_rtr_text/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n Benefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_ask_rtr_text/client1/result.json b/tests/snapshots/test_app/test_ask_rtr_text/client1/result.json
index fba6d28157..809a74e7a8 100644
--- a/tests/snapshots/test_app/test_ask_rtr_text/client1/result.json
+++ b/tests/snapshots/test_app/test_ask_rtr_text/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n Benefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_ask_rtr_text_filter/auth_client0/result.json b/tests/snapshots/test_app/test_ask_rtr_text_filter/auth_client0/result.json
index 87ebda374c..635be8acc9 100644
--- a/tests/snapshots/test_app/test_ask_rtr_text_filter/auth_client0/result.json
+++ b/tests/snapshots/test_app/test_ask_rtr_text_filter/auth_client0/result.json
@@ -1,14 +1,15 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [],
"thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n '}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_ask_rtr_text_semanticcaptions/client0/result.json b/tests/snapshots/test_app/test_ask_rtr_text_semanticcaptions/client0/result.json
index c400f9f5e9..0b2118eb52 100644
--- a/tests/snapshots/test_app/test_ask_rtr_text_semanticcaptions/client0/result.json
+++ b/tests/snapshots/test_app/test_ask_rtr_text_semanticcaptions/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: Caption: A whistleblower policy."
],
"thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n Benefit_Options-2.pdf: Caption: A whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_ask_rtr_text_semanticcaptions/client1/result.json b/tests/snapshots/test_app/test_ask_rtr_text_semanticcaptions/client1/result.json
index c400f9f5e9..0b2118eb52 100644
--- a/tests/snapshots/test_app/test_ask_rtr_text_semanticcaptions/client1/result.json
+++ b/tests/snapshots/test_app/test_ask_rtr_text_semanticcaptions/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: Caption: A whistleblower policy."
],
"thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n Benefit_Options-2.pdf: Caption: A whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_ask_rtr_text_semanticranker/client0/result.json b/tests/snapshots/test_app/test_ask_rtr_text_semanticranker/client0/result.json
index fba6d28157..809a74e7a8 100644
--- a/tests/snapshots/test_app/test_ask_rtr_text_semanticranker/client0/result.json
+++ b/tests/snapshots/test_app/test_ask_rtr_text_semanticranker/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n Benefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_ask_rtr_text_semanticranker/client1/result.json b/tests/snapshots/test_app/test_ask_rtr_text_semanticranker/client1/result.json
index fba6d28157..809a74e7a8 100644
--- a/tests/snapshots/test_app/test_ask_rtr_text_semanticranker/client1/result.json
+++ b/tests/snapshots/test_app/test_ask_rtr_text_semanticranker/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n Benefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_ask_session_state_persists/client0/result.json b/tests/snapshots/test_app/test_ask_session_state_persists/client0/result.json
new file mode 100644
index 0000000000..f194c956e5
--- /dev/null
+++ b/tests/snapshots/test_app/test_ask_session_state_persists/client0/result.json
@@ -0,0 +1,20 @@
+{
+ "choices": [
+ {
+ "context": {
+ "data_points": [
+ "Benefit_Options-2.pdf: There is a whistleblower policy."
+ ],
+ "thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n Benefit_Options-2.pdf: There is a whistleblower policy.'}"
+ },
+ "message": {
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
+ "role": "assistant"
+ },
+ "session_state": {
+ "conversation_id": 1234
+ }
+ }
+ ],
+ "object": "chat.completion"
+}
\ No newline at end of file
diff --git a/tests/snapshots/test_app/test_ask_session_state_persists/client1/result.json b/tests/snapshots/test_app/test_ask_session_state_persists/client1/result.json
new file mode 100644
index 0000000000..f194c956e5
--- /dev/null
+++ b/tests/snapshots/test_app/test_ask_session_state_persists/client1/result.json
@@ -0,0 +1,20 @@
+{
+ "choices": [
+ {
+ "context": {
+ "data_points": [
+ "Benefit_Options-2.pdf: There is a whistleblower policy."
+ ],
+ "thoughts": "Question: What is the capital of France?
Prompt: {'role': 'system', 'content': \"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. Use 'you' to refer to the individual asking the questions even if they ask with 'I'. Answer the following question using only the data provided in the sources below. For tabular information return it as an html table. Do not return markdown format. Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. If you cannot answer using the sources below, say you don't know. Use below example to answer\"}\n\n{'role': 'user', 'content': \"\\n'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'\\n\\nSources:\\ninfo1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.\\ninfo2.pdf: Overlake is in-network for the employee plan.\\ninfo3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.\\ninfo4.pdf: In-network institutions include Overlake, Swedish and others in the region\\n\"}\n\n{'role': 'assistant', 'content': 'In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].'}\n\n{'role': 'user', 'content': 'What is the capital of France?\\nSources:\\n Benefit_Options-2.pdf: There is a whistleblower policy.'}"
+ },
+ "message": {
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
+ "role": "assistant"
+ },
+ "session_state": {
+ "conversation_id": 1234
+ }
+ }
+ ],
+ "object": "chat.completion"
+}
\ No newline at end of file
diff --git a/tests/snapshots/test_app/test_chat_hybrid/client0/result.json b/tests/snapshots/test_app/test_chat_hybrid/client0/result.json
index 8ab51eb41c..1bb8a6fc64 100644
--- a/tests/snapshots/test_app/test_chat_hybrid/client0/result.json
+++ b/tests/snapshots/test_app/test_chat_hybrid/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_hybrid/client1/result.json b/tests/snapshots/test_app/test_chat_hybrid/client1/result.json
index 8ab51eb41c..1bb8a6fc64 100644
--- a/tests/snapshots/test_app/test_chat_hybrid/client1/result.json
+++ b/tests/snapshots/test_app/test_chat_hybrid/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_prompt_template/client0/result.json b/tests/snapshots/test_app/test_chat_prompt_template/client0/result.json
index 2a92fc548e..5e1b1726a1 100644
--- a/tests/snapshots/test_app/test_chat_prompt_template/client0/result.json
+++ b/tests/snapshots/test_app/test_chat_prompt_template/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': 'You are a cat.'}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_prompt_template/client1/result.json b/tests/snapshots/test_app/test_chat_prompt_template/client1/result.json
index 2a92fc548e..5e1b1726a1 100644
--- a/tests/snapshots/test_app/test_chat_prompt_template/client1/result.json
+++ b/tests/snapshots/test_app/test_chat_prompt_template/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': 'You are a cat.'}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_prompt_template_concat/client0/result.json b/tests/snapshots/test_app/test_chat_prompt_template_concat/client0/result.json
index 2d64cd3486..c000a96511 100644
--- a/tests/snapshots/test_app/test_chat_prompt_template_concat/client0/result.json
+++ b/tests/snapshots/test_app/test_chat_prompt_template_concat/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n Meow like a cat.\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_prompt_template_concat/client1/result.json b/tests/snapshots/test_app/test_chat_prompt_template_concat/client1/result.json
index 2d64cd3486..c000a96511 100644
--- a/tests/snapshots/test_app/test_chat_prompt_template_concat/client1/result.json
+++ b/tests/snapshots/test_app/test_chat_prompt_template_concat/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n Meow like a cat.\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_session_state_persists/client0/result.json b/tests/snapshots/test_app/test_chat_session_state_persists/client0/result.json
new file mode 100644
index 0000000000..a9325a1f9d
--- /dev/null
+++ b/tests/snapshots/test_app/test_chat_session_state_persists/client0/result.json
@@ -0,0 +1,20 @@
+{
+ "choices": [
+ {
+ "context": {
+ "data_points": [
+ "Benefit_Options-2.pdf: There is a whistleblower policy."
+ ],
+ "thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
+ },
+ "message": {
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
+ "role": "assistant"
+ },
+ "session_state": {
+ "conversation_id": 1234
+ }
+ }
+ ],
+ "object": "chat.completion"
+}
\ No newline at end of file
diff --git a/tests/snapshots/test_app/test_chat_session_state_persists/client1/result.json b/tests/snapshots/test_app/test_chat_session_state_persists/client1/result.json
new file mode 100644
index 0000000000..a9325a1f9d
--- /dev/null
+++ b/tests/snapshots/test_app/test_chat_session_state_persists/client1/result.json
@@ -0,0 +1,20 @@
+{
+ "choices": [
+ {
+ "context": {
+ "data_points": [
+ "Benefit_Options-2.pdf: There is a whistleblower policy."
+ ],
+ "thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
+ },
+ "message": {
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
+ "role": "assistant"
+ },
+ "session_state": {
+ "conversation_id": 1234
+ }
+ }
+ ],
+ "object": "chat.completion"
+}
\ No newline at end of file
diff --git a/tests/snapshots/test_app/test_chat_stream_session_state_persists/client0/result.jsonlines b/tests/snapshots/test_app/test_chat_stream_session_state_persists/client0/result.jsonlines
new file mode 100644
index 0000000000..904ca7edf9
--- /dev/null
+++ b/tests/snapshots/test_app/test_chat_stream_session_state_persists/client0/result.jsonlines
@@ -0,0 +1,3 @@
+{"choices": [{"delta": {"role": "assistant"}, "context": {"data_points": ["Benefit_Options-2.pdf: There is a whistleblower policy."], "thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"}, "session_state": {"conversation_id": 1234}, "finish_reason": null, "index": 0}], "object": "chat.completion.chunk"}
+{"object": "chat.completion.chunk", "choices": [{"delta": {"role": "assistant"}}]}
+{"object": "chat.completion.chunk", "choices": [{"delta": {"content": "The capital of France is Paris. [Benefit_Options-2.pdf]."}}]}
diff --git a/tests/snapshots/test_app/test_chat_stream_session_state_persists/client1/result.jsonlines b/tests/snapshots/test_app/test_chat_stream_session_state_persists/client1/result.jsonlines
new file mode 100644
index 0000000000..904ca7edf9
--- /dev/null
+++ b/tests/snapshots/test_app/test_chat_stream_session_state_persists/client1/result.jsonlines
@@ -0,0 +1,3 @@
+{"choices": [{"delta": {"role": "assistant"}, "context": {"data_points": ["Benefit_Options-2.pdf: There is a whistleblower policy."], "thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"}, "session_state": {"conversation_id": 1234}, "finish_reason": null, "index": 0}], "object": "chat.completion.chunk"}
+{"object": "chat.completion.chunk", "choices": [{"delta": {"role": "assistant"}}]}
+{"object": "chat.completion.chunk", "choices": [{"delta": {"content": "The capital of France is Paris. [Benefit_Options-2.pdf]."}}]}
diff --git a/tests/snapshots/test_app/test_chat_stream_text/client0/result.jsonlines b/tests/snapshots/test_app/test_chat_stream_text/client0/result.jsonlines
index 4ad2e5c111..a702fe72d5 100644
--- a/tests/snapshots/test_app/test_chat_stream_text/client0/result.jsonlines
+++ b/tests/snapshots/test_app/test_chat_stream_text/client0/result.jsonlines
@@ -1,3 +1,3 @@
-{"choices": [{"delta": {"role": "assistant"}, "extra_args": {"data_points": ["Benefit_Options-2.pdf: There is a whistleblower policy."], "thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"}, "finish_reason": null, "index": 0}], "object": "chat.completion.chunk"}
+{"choices": [{"delta": {"role": "assistant"}, "context": {"data_points": ["Benefit_Options-2.pdf: There is a whistleblower policy."], "thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"}, "session_state": null, "finish_reason": null, "index": 0}], "object": "chat.completion.chunk"}
{"object": "chat.completion.chunk", "choices": [{"delta": {"role": "assistant"}}]}
-{"object": "chat.completion.chunk", "choices": [{"delta": {"content": "The capital of France is Paris."}}]}
+{"object": "chat.completion.chunk", "choices": [{"delta": {"content": "The capital of France is Paris. [Benefit_Options-2.pdf]."}}]}
diff --git a/tests/snapshots/test_app/test_chat_stream_text/client1/result.jsonlines b/tests/snapshots/test_app/test_chat_stream_text/client1/result.jsonlines
index 4ad2e5c111..a702fe72d5 100644
--- a/tests/snapshots/test_app/test_chat_stream_text/client1/result.jsonlines
+++ b/tests/snapshots/test_app/test_chat_stream_text/client1/result.jsonlines
@@ -1,3 +1,3 @@
-{"choices": [{"delta": {"role": "assistant"}, "extra_args": {"data_points": ["Benefit_Options-2.pdf: There is a whistleblower policy."], "thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"}, "finish_reason": null, "index": 0}], "object": "chat.completion.chunk"}
+{"choices": [{"delta": {"role": "assistant"}, "context": {"data_points": ["Benefit_Options-2.pdf: There is a whistleblower policy."], "thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"}, "session_state": null, "finish_reason": null, "index": 0}], "object": "chat.completion.chunk"}
{"object": "chat.completion.chunk", "choices": [{"delta": {"role": "assistant"}}]}
-{"object": "chat.completion.chunk", "choices": [{"delta": {"content": "The capital of France is Paris."}}]}
+{"object": "chat.completion.chunk", "choices": [{"delta": {"content": "The capital of France is Paris. [Benefit_Options-2.pdf]."}}]}
diff --git a/tests/snapshots/test_app/test_chat_stream_text_filter/auth_client0/result.jsonlines b/tests/snapshots/test_app/test_chat_stream_text_filter/auth_client0/result.jsonlines
index cc6d520bcd..9f0c584b47 100644
--- a/tests/snapshots/test_app/test_chat_stream_text_filter/auth_client0/result.jsonlines
+++ b/tests/snapshots/test_app/test_chat_stream_text_filter/auth_client0/result.jsonlines
@@ -1,3 +1,3 @@
-{"choices": [{"delta": {"role": "assistant"}, "extra_args": {"data_points": [], "thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\n'}"}, "finish_reason": null, "index": 0}], "object": "chat.completion.chunk"}
+{"choices": [{"delta": {"role": "assistant"}, "context": {"data_points": [], "thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\n'}"}, "session_state": null, "finish_reason": null, "index": 0}], "object": "chat.completion.chunk"}
{"object": "chat.completion.chunk", "choices": [{"delta": {"role": "assistant"}}]}
-{"object": "chat.completion.chunk", "choices": [{"delta": {"content": "The capital of France is Paris."}}]}
+{"object": "chat.completion.chunk", "choices": [{"delta": {"content": "The capital of France is Paris. [Benefit_Options-2.pdf]."}}]}
diff --git a/tests/snapshots/test_app/test_chat_text/client0/result.json b/tests/snapshots/test_app/test_chat_text/client0/result.json
index 8ab51eb41c..1bb8a6fc64 100644
--- a/tests/snapshots/test_app/test_chat_text/client0/result.json
+++ b/tests/snapshots/test_app/test_chat_text/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_text/client1/result.json b/tests/snapshots/test_app/test_chat_text/client1/result.json
index 8ab51eb41c..1bb8a6fc64 100644
--- a/tests/snapshots/test_app/test_chat_text/client1/result.json
+++ b/tests/snapshots/test_app/test_chat_text/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_text_filter/auth_client0/result.json b/tests/snapshots/test_app/test_chat_text_filter/auth_client0/result.json
index ddcb422b12..6dfbd05bc1 100644
--- a/tests/snapshots/test_app/test_chat_text_filter/auth_client0/result.json
+++ b/tests/snapshots/test_app/test_chat_text_filter/auth_client0/result.json
@@ -1,14 +1,15 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\n'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_text_semanticcaptions/client0/result.json b/tests/snapshots/test_app/test_chat_text_semanticcaptions/client0/result.json
index 2ce4879228..47b36ea79d 100644
--- a/tests/snapshots/test_app/test_chat_text_semanticcaptions/client0/result.json
+++ b/tests/snapshots/test_app/test_chat_text_semanticcaptions/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: Caption: A whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: Caption: A whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_text_semanticcaptions/client1/result.json b/tests/snapshots/test_app/test_chat_text_semanticcaptions/client1/result.json
index 2ce4879228..47b36ea79d 100644
--- a/tests/snapshots/test_app/test_chat_text_semanticcaptions/client1/result.json
+++ b/tests/snapshots/test_app/test_chat_text_semanticcaptions/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: Caption: A whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: Caption: A whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_text_semanticranker/client0/result.json b/tests/snapshots/test_app/test_chat_text_semanticranker/client0/result.json
index 8ab51eb41c..1bb8a6fc64 100644
--- a/tests/snapshots/test_app/test_chat_text_semanticranker/client0/result.json
+++ b/tests/snapshots/test_app/test_chat_text_semanticranker/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_text_semanticranker/client1/result.json b/tests/snapshots/test_app/test_chat_text_semanticranker/client1/result.json
index 8ab51eb41c..1bb8a6fc64 100644
--- a/tests/snapshots/test_app/test_chat_text_semanticranker/client1/result.json
+++ b/tests/snapshots/test_app/test_chat_text_semanticranker/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: capital of France
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_vector/client0/result.json b/tests/snapshots/test_app/test_chat_vector/client0/result.json
index 4117f95583..60234c9f81 100644
--- a/tests/snapshots/test_app/test_chat_vector/client0/result.json
+++ b/tests/snapshots/test_app/test_chat_vector/client0/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: None
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_vector/client1/result.json b/tests/snapshots/test_app/test_chat_vector/client1/result.json
index 4117f95583..60234c9f81 100644
--- a/tests/snapshots/test_app/test_chat_vector/client1/result.json
+++ b/tests/snapshots/test_app/test_chat_vector/client1/result.json
@@ -1,16 +1,17 @@
{
"choices": [
{
- "extra_args": {
+ "context": {
"data_points": [
"Benefit_Options-2.pdf: There is a whistleblower policy."
],
"thoughts": "Searched for: None
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What is the capital of France?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
},
"message": {
- "content": "The capital of France is Paris.",
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
"role": "assistant"
- }
+ },
+ "session_state": null
}
],
"object": "chat.completion"
diff --git a/tests/snapshots/test_app/test_chat_with_history/client0/result.json b/tests/snapshots/test_app/test_chat_with_history/client0/result.json
new file mode 100644
index 0000000000..089c1e8f9d
--- /dev/null
+++ b/tests/snapshots/test_app/test_chat_with_history/client0/result.json
@@ -0,0 +1,18 @@
+{
+ "choices": [
+ {
+ "context": {
+ "data_points": [
+ "Benefit_Options-2.pdf: There is a whistleblower policy."
+ ],
+ "thoughts": "Searched for: The capital of France is Paris. [Benefit_Options-2.pdf].
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What happens in a performance review?'}
{'role': 'assistant', 'content': \"During a performance review, employees will receive feedback on their performance over the past year, including both successes and areas for improvement. The feedback will be provided by the employee's supervisor and is intended to help the employee develop and grow in their role [employee_handbook-3.pdf]. The review is a two-way dialogue between the employee and their manager, so employees are encouraged to be honest and open during the process [employee_handbook-3.pdf]. The employee will also have the opportunity to discuss their goals and objectives for the upcoming year [employee_handbook-3.pdf]. A written summary of the performance review will be provided to the employee, which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].\"}
{'role': 'user', 'content': 'Is dental covered?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
+ },
+ "message": {
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
+ "role": "assistant"
+ },
+ "session_state": null
+ }
+ ],
+ "object": "chat.completion"
+}
\ No newline at end of file
diff --git a/tests/snapshots/test_app/test_chat_with_history/client1/result.json b/tests/snapshots/test_app/test_chat_with_history/client1/result.json
new file mode 100644
index 0000000000..089c1e8f9d
--- /dev/null
+++ b/tests/snapshots/test_app/test_chat_with_history/client1/result.json
@@ -0,0 +1,18 @@
+{
+ "choices": [
+ {
+ "context": {
+ "data_points": [
+ "Benefit_Options-2.pdf: There is a whistleblower policy."
+ ],
+ "thoughts": "Searched for: The capital of France is Paris. [Benefit_Options-2.pdf].
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What happens in a performance review?'}
{'role': 'assistant', 'content': \"During a performance review, employees will receive feedback on their performance over the past year, including both successes and areas for improvement. The feedback will be provided by the employee's supervisor and is intended to help the employee develop and grow in their role [employee_handbook-3.pdf]. The review is a two-way dialogue between the employee and their manager, so employees are encouraged to be honest and open during the process [employee_handbook-3.pdf]. The employee will also have the opportunity to discuss their goals and objectives for the upcoming year [employee_handbook-3.pdf]. A written summary of the performance review will be provided to the employee, which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].\"}
{'role': 'user', 'content': 'Is dental covered?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
+ },
+ "message": {
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
+ "role": "assistant"
+ },
+ "session_state": null
+ }
+ ],
+ "object": "chat.completion"
+}
\ No newline at end of file
diff --git a/tests/snapshots/test_app/test_chat_with_long_history/client0/result.json b/tests/snapshots/test_app/test_chat_with_long_history/client0/result.json
new file mode 100644
index 0000000000..ec5a666c11
--- /dev/null
+++ b/tests/snapshots/test_app/test_chat_with_long_history/client0/result.json
@@ -0,0 +1,18 @@
+{
+ "choices": [
+ {
+ "context": {
+ "data_points": [
+ "Benefit_Options-2.pdf: There is a whistleblower policy."
+ ],
+ "thoughts": "Searched for: The capital of France is Paris. [Benefit_Options-2.pdf].
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What does a product manager do?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
+ },
+ "message": {
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
+ "role": "assistant"
+ },
+ "session_state": null
+ }
+ ],
+ "object": "chat.completion"
+}
\ No newline at end of file
diff --git a/tests/snapshots/test_app/test_chat_with_long_history/client1/result.json b/tests/snapshots/test_app/test_chat_with_long_history/client1/result.json
new file mode 100644
index 0000000000..ec5a666c11
--- /dev/null
+++ b/tests/snapshots/test_app/test_chat_with_long_history/client1/result.json
@@ -0,0 +1,18 @@
+{
+ "choices": [
+ {
+ "context": {
+ "data_points": [
+ "Benefit_Options-2.pdf: There is a whistleblower policy."
+ ],
+ "thoughts": "Searched for: The capital of France is Paris. [Benefit_Options-2.pdf].
Conversations: {'role': 'system', 'content': \"Assistant helps the company employees with their healthcare plan questions, and questions about the employee handbook. Be brief in your answers.\\nAnswer ONLY with the facts listed in the list of sources below. If there isn't enough information below, say you don't know. Do not generate answers that don't use the sources below. If asking a clarifying question to the user would help, ask the question.\\nFor tabular information return it as an html table. Do not return markdown format. If the question is not in English, answer in the language used in the question.\\nEach source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. Use square brackets to reference the source, e.g. [info1.txt]. Don't combine sources, list each source separately, e.g. [info1.txt][info2.pdf].\\n\\n\\n\"}
{'role': 'user', 'content': 'What does a product manager do?\\n\\nSources:\\nBenefit_Options-2.pdf: There is a whistleblower policy.'}"
+ },
+ "message": {
+ "content": "The capital of France is Paris. [Benefit_Options-2.pdf].",
+ "role": "assistant"
+ },
+ "session_state": null
+ }
+ ],
+ "object": "chat.completion"
+}
\ No newline at end of file
diff --git a/tests/test_app.py b/tests/test_app.py
index 843dbcbb2e..d14c53bcb1 100644
--- a/tests/test_app.py
+++ b/tests/test_app.py
@@ -1,4 +1,5 @@
import json
+import logging
import os
from unittest import mock
@@ -50,8 +51,10 @@ async def test_ask_rtr_text(client, snapshot):
response = await client.post(
"/ask",
json={
- "question": "What is the capital of France?",
- "overrides": {"retrieval_mode": "text"},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text"},
+ },
},
)
assert response.status_code == 200
@@ -65,12 +68,14 @@ async def test_ask_rtr_text_filter(auth_client, snapshot):
"/ask",
headers={"Authorization": "Bearer MockToken"},
json={
- "question": "What is the capital of France?",
- "overrides": {
- "retrieval_mode": "text",
- "use_oid_security_filter": True,
- "use_groups_security_filter": True,
- "exclude_category": "excluded",
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {
+ "retrieval_mode": "text",
+ "use_oid_security_filter": True,
+ "use_groups_security_filter": True,
+ "exclude_category": "excluded",
+ },
},
},
)
@@ -88,8 +93,10 @@ async def test_ask_rtr_text_semanticranker(client, snapshot):
response = await client.post(
"/ask",
json={
- "question": "What is the capital of France?",
- "overrides": {"retrieval_mode": "text", "semantic_ranker": True},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text", "semantic_ranker": True},
+ },
},
)
assert response.status_code == 200
@@ -102,8 +109,10 @@ async def test_ask_rtr_text_semanticcaptions(client, snapshot):
response = await client.post(
"/ask",
json={
- "question": "What is the capital of France?",
- "overrides": {"retrieval_mode": "text", "semantic_captions": True},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text", "semantic_captions": True},
+ },
},
)
assert response.status_code == 200
@@ -116,8 +125,10 @@ async def test_ask_rtr_hybrid(client, snapshot):
response = await client.post(
"/ask",
json={
- "question": "What is the capital of France?",
- "overrides": {"retrieval_mode": "hybrid"},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "hybrid"},
+ },
},
)
assert response.status_code == 200
@@ -138,8 +149,10 @@ async def test_chat_text(client, snapshot):
response = await client.post(
"/chat",
json={
- "history": [{"user": "What is the capital of France?"}],
- "overrides": {"retrieval_mode": "text"},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text"},
+ },
},
)
assert response.status_code == 200
@@ -153,12 +166,14 @@ async def test_chat_text_filter(auth_client, snapshot):
"/chat",
headers={"Authorization": "Bearer MockToken"},
json={
- "history": [{"user": "What is the capital of France?"}],
- "overrides": {
- "retrieval_mode": "text",
- "use_oid_security_filter": True,
- "use_groups_security_filter": True,
- "exclude_category": "excluded",
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {
+ "retrieval_mode": "text",
+ "use_oid_security_filter": True,
+ "use_groups_security_filter": True,
+ "exclude_category": "excluded",
+ },
},
},
)
@@ -176,8 +191,10 @@ async def test_chat_text_semanticranker(client, snapshot):
response = await client.post(
"/chat",
json={
- "history": [{"user": "What is the capital of France?"}],
- "overrides": {"retrieval_mode": "text", "semantic_ranker": True},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text", "semantic_ranker": True},
+ },
},
)
assert response.status_code == 200
@@ -190,8 +207,10 @@ async def test_chat_text_semanticcaptions(client, snapshot):
response = await client.post(
"/chat",
json={
- "history": [{"user": "What is the capital of France?"}],
- "overrides": {"retrieval_mode": "text", "semantic_captions": True},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text", "semantic_captions": True},
+ },
},
)
assert response.status_code == 200
@@ -204,8 +223,10 @@ async def test_chat_prompt_template(client, snapshot):
response = await client.post(
"/chat",
json={
- "history": [{"user": "What is the capital of France?"}],
- "overrides": {"retrieval_mode": "text", "prompt_template": "You are a cat."},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text", "prompt_template": "You are a cat."},
+ },
},
)
assert response.status_code == 200
@@ -218,8 +239,10 @@ async def test_chat_prompt_template_concat(client, snapshot):
response = await client.post(
"/chat",
json={
- "history": [{"user": "What is the capital of France?"}],
- "overrides": {"retrieval_mode": "text", "prompt_template": ">>> Meow like a cat."},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text", "prompt_template": ">>> Meow like a cat."},
+ },
},
)
assert response.status_code == 200
@@ -232,8 +255,10 @@ async def test_chat_hybrid(client, snapshot):
response = await client.post(
"/chat",
json={
- "history": [{"user": "What is the capital of France?"}],
- "overrides": {"retrieval_mode": "hybrid"},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "hybrid"},
+ },
},
)
assert response.status_code == 200
@@ -246,8 +271,10 @@ async def test_chat_vector(client, snapshot):
response = await client.post(
"/chat",
json={
- "history": [{"user": "What is the capital of France?"}],
- "overrides": {"retrieval_mode": "vector"},
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "vector"},
+ },
},
)
assert response.status_code == 200
@@ -255,21 +282,16 @@ async def test_chat_vector(client, snapshot):
snapshot.assert_match(json.dumps(result, indent=4), "result.json")
-@pytest.mark.asyncio
-async def test_chat_stream_request_must_be_json(client):
- response = await client.post("/chat_stream")
- assert response.status_code == 415
- result = await response.get_json()
- assert result["error"] == "request must be json"
-
-
@pytest.mark.asyncio
async def test_chat_stream_text(client, snapshot):
response = await client.post(
- "/chat_stream",
+ "/chat",
json={
- "history": [{"user": "What is the capital of France?"}],
- "overrides": {"retrieval_mode": "text"},
+ "stream": True,
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text"},
+ },
},
)
assert response.status_code == 200
@@ -280,15 +302,18 @@ async def test_chat_stream_text(client, snapshot):
@pytest.mark.asyncio
async def test_chat_stream_text_filter(auth_client, snapshot):
response = await auth_client.post(
- "/chat_stream",
+ "/chat",
headers={"Authorization": "Bearer MockToken"},
json={
- "history": [{"user": "What is the capital of France?"}],
- "overrides": {
- "retrieval_mode": "text",
- "use_oid_security_filter": True,
- "use_groups_security_filter": True,
- "exclude_category": "excluded",
+ "stream": True,
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {
+ "retrieval_mode": "text",
+ "use_oid_security_filter": True,
+ "use_groups_security_filter": True,
+ "exclude_category": "excluded",
+ }
},
},
)
@@ -301,6 +326,94 @@ async def test_chat_stream_text_filter(auth_client, snapshot):
snapshot.assert_match(result, "result.jsonlines")
+@pytest.mark.asyncio
+async def test_chat_with_history(client, snapshot):
+ response = await client.post(
+ "/chat",
+ json={
+ "messages": [
+ {"content": "What happens in a performance review?", "role": "user"},
+ {
+ "content": "During a performance review, employees will receive feedback on their performance over the past year, including both successes and areas for improvement. The feedback will be provided by the employee's supervisor and is intended to help the employee develop and grow in their role [employee_handbook-3.pdf]. The review is a two-way dialogue between the employee and their manager, so employees are encouraged to be honest and open during the process [employee_handbook-3.pdf]. The employee will also have the opportunity to discuss their goals and objectives for the upcoming year [employee_handbook-3.pdf]. A written summary of the performance review will be provided to the employee, which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
+ "role": "assistant",
+ },
+ {"content": "Is dental covered?", "role": "user"},
+ ],
+ "context": {
+ "overrides": {"retrieval_mode": "text"},
+ },
+ },
+ )
+ assert response.status_code == 200
+ result = await response.get_json()
+ assert result["choices"][0]["context"]["thoughts"].find("performance review") != -1
+ snapshot.assert_match(json.dumps(result, indent=4), "result.json")
+
+
+@pytest.mark.asyncio
+async def test_chat_with_long_history(client, snapshot, caplog):
+ """This test makes sure that the history is truncated to max tokens minus 1024."""
+ caplog.set_level(logging.DEBUG)
+ response = await client.post(
+ "/chat",
+ json={
+ "messages": [
+ {"role": "user", "content": "Is there a dress code?"}, # 9 tokens
+ {
+ "role": "assistant",
+ "content": "Yes, there is a dress code at Contoso Electronics. Look sharp! [employee_handbook-1.pdf]"
+ * 150,
+ }, # 3900 tokens
+ {"role": "user", "content": "What does a product manager do?"}, # 10 tokens
+ ],
+ "context": {
+ "overrides": {"retrieval_mode": "text"},
+ },
+ },
+ )
+ assert response.status_code == 200
+ result = await response.get_json()
+ # Assert that it doesn't find the first message, since it wouldn't fit in the max tokens.
+ assert result["choices"][0]["context"]["thoughts"].find("Is there a dress code?") == -1
+ assert "Reached max tokens" in caplog.text
+ snapshot.assert_match(json.dumps(result, indent=4), "result.json")
+
+
+@pytest.mark.asyncio
+async def test_chat_session_state_persists(client, snapshot):
+ response = await client.post(
+ "/chat",
+ json={
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text"},
+ },
+ "session_state": {"conversation_id": 1234},
+ },
+ )
+ assert response.status_code == 200
+ result = await response.get_json()
+ snapshot.assert_match(json.dumps(result, indent=4), "result.json")
+
+
+@pytest.mark.asyncio
+async def test_chat_stream_session_state_persists(client, snapshot):
+ response = await client.post(
+ "/chat",
+ json={
+ "messages": [{"content": "What is the capital of France?", "role": "user"}],
+ "context": {
+ "overrides": {"retrieval_mode": "text"},
+ },
+ "stream": True,
+ "session_state": {"conversation_id": 1234},
+ },
+ )
+ assert response.status_code == 200
+ result = await response.get_data()
+ snapshot.assert_match(result, "result.jsonlines")
+
+
@pytest.mark.asyncio
async def test_format_as_ndjson():
async def gen():
diff --git a/tests/test_chatapproach.py b/tests/test_chatapproach.py
index 4dc40d2fce..fa81ebffe7 100644
--- a/tests/test_chatapproach.py
+++ b/tests/test_chatapproach.py
@@ -4,7 +4,9 @@
def test_get_search_query():
- chat_approach = ChatReadRetrieveReadApproach(None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "")
+ chat_approach = ChatReadRetrieveReadApproach(
+ None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "", "en-us", "lexicon"
+ )
payload = '{"id":"chatcmpl-81JkxYqYppUkPtOAia40gki2vJ9QM","object":"chat.completion","created":1695324963,"model":"gpt-35-turbo","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"choices":[{"index":0,"finish_reason":"function_call","message":{"role":"assistant","function_call":{"name":"search_sources","arguments":"{\\n\\"search_query\\":\\"accesstelemedicineservices\\"\\n}"}},"content_filter_results":{}}],"usage":{"completion_tokens":19,"prompt_tokens":425,"total_tokens":444}}'
default_query = "hello"
@@ -14,7 +16,9 @@ def test_get_search_query():
def test_get_search_query_returns_default():
- chat_approach = ChatReadRetrieveReadApproach(None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "")
+ chat_approach = ChatReadRetrieveReadApproach(
+ None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "", "en-us", "lexicon"
+ )
payload = '{"id":"chatcmpl-81JkxYqYppUkPtOAia40gki2vJ9QM","object":"chat.completion","created":1695324963,"model":"gpt-35-turbo","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"choices":[{"index":0,"finish_reason":"function_call","message":{"role":"assistant"},"content_filter_results":{}}],"usage":{"completion_tokens":19,"prompt_tokens":425,"total_tokens":444}}'
default_query = "hello"
@@ -24,19 +28,23 @@ def test_get_search_query_returns_default():
def test_get_messages_from_history():
- chat_approach = ChatReadRetrieveReadApproach(None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "")
+ chat_approach = ChatReadRetrieveReadApproach(
+ None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "", "en-us", "lexicon"
+ )
messages = chat_approach.get_messages_from_history(
system_prompt="You are a bot.",
model_id="gpt-35-turbo",
history=[
+ {"role": "user", "content": "What happens in a performance review?"},
{
- "user": "What happens in a performance review?",
- "bot": "During the performance review at Contoso Electronics, the supervisor will discuss the employee's performance over the past year and provide feedback on areas for improvement. They will also provide an opportunity for the employee to discuss their goals and objectives for the upcoming year. The review is a two-way dialogue between managers and employees, and employees will receive a written summary of their performance review which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
+ "role": "assistant",
+ "content": "During the performance review at Contoso Electronics, the supervisor will discuss the employee's performance over the past year and provide feedback on areas for improvement. They will also provide an opportunity for the employee to discuss their goals and objectives for the upcoming year. The review is a two-way dialogue between managers and employees, and employees will receive a written summary of their performance review which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
},
- {"user": "What does a Product Manager do?"},
+ {"role": "user", "content": "What does a Product Manager do?"},
],
user_content="What does a Product Manager do?",
+ max_tokens=3000,
)
assert messages == [
{"role": "system", "content": "You are a bot."},
@@ -50,17 +58,20 @@ def test_get_messages_from_history():
def test_get_messages_from_history_truncated():
- chat_approach = ChatReadRetrieveReadApproach(None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "")
+ chat_approach = ChatReadRetrieveReadApproach(
+ None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "", "en-us", "lexicon"
+ )
messages = chat_approach.get_messages_from_history(
system_prompt="You are a bot.",
model_id="gpt-35-turbo",
history=[
+ {"role": "user", "content": "What happens in a performance review?"},
{
- "user": "What happens in a performance review?",
- "bot": "During the performance review at Contoso Electronics, the supervisor will discuss the employee's performance over the past year and provide feedback on areas for improvement. They will also provide an opportunity for the employee to discuss their goals and objectives for the upcoming year. The review is a two-way dialogue between managers and employees, and employees will receive a written summary of their performance review which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
+ "role": "assistant",
+ "content": "During the performance review at Contoso Electronics, the supervisor will discuss the employee's performance over the past year and provide feedback on areas for improvement. They will also provide an opportunity for the employee to discuss their goals and objectives for the upcoming year. The review is a two-way dialogue between managers and employees, and employees will receive a written summary of their performance review which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
},
- {"user": "What does a Product Manager do?"},
+ {"role": "user", "content": "What does a Product Manager do?"},
],
user_content="What does a Product Manager do?",
max_tokens=10,
@@ -72,24 +83,28 @@ def test_get_messages_from_history_truncated():
def test_get_messages_from_history_truncated_longer():
- chat_approach = ChatReadRetrieveReadApproach(None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "")
+ chat_approach = ChatReadRetrieveReadApproach(
+ None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "", "en-us", "lexicon"
+ )
messages = chat_approach.get_messages_from_history(
- system_prompt="You are a bot.",
+ system_prompt="You are a bot.", # 8 tokens
model_id="gpt-35-turbo",
history=[
+ {"role": "user", "content": "What happens in a performance review?"}, # 10 tokens
{
- "user": "What happens in a performance review?",
- "bot": "During the performance review at Contoso Electronics, the supervisor will discuss the employee's performance over the past year and provide feedback on areas for improvement. They will also provide an opportunity for the employee to discuss their goals and objectives for the upcoming year. The review is a two-way dialogue between managers and employees, and employees will receive a written summary of their performance review which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
- },
+ "role": "assistant",
+ "content": "During the performance review at Contoso Electronics, the supervisor will discuss the employee's performance over the past year and provide feedback on areas for improvement. They will also provide an opportunity for the employee to discuss their goals and objectives for the upcoming year. The review is a two-way dialogue between managers and employees, and employees will receive a written summary of their performance review which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
+ }, # 102 tokens
+ {"role": "user", "content": "Is there a dress code?"}, # 9 tokens
{
- "user": "Is there a dress code?",
- "bot": "Yes, there is a dress code at Contoso Electronics. Look sharp! [employee_handbook-1.pdf]",
- },
- {"user": "What does a Product Manager do?"},
+ "role": "assistant",
+ "content": "Yes, there is a dress code at Contoso Electronics. Look sharp! [employee_handbook-1.pdf]",
+ }, # 26 tokens
+ {"role": "user", "content": "What does a Product Manager do?"}, # 10 tokens
],
user_content="What does a Product Manager do?",
- max_tokens=30,
+ max_tokens=55,
)
assert messages == [
{"role": "system", "content": "You are a bot."},
@@ -100,3 +115,43 @@ def test_get_messages_from_history_truncated_longer():
},
{"role": "user", "content": "What does a Product Manager do?"},
]
+
+
+def test_get_messages_from_history_truncated_break_pair():
+ """Tests that the truncation breaks the pair of messages."""
+ chat_approach = ChatReadRetrieveReadApproach(
+ None, "", "gpt-35-turbo", "gpt-35-turbo", "", "", "", "", "en-us", "lexicon"
+ )
+
+ messages = chat_approach.get_messages_from_history(
+ system_prompt="You are a bot.", # 8 tokens
+ model_id="gpt-35-turbo",
+ history=[
+ {"role": "user", "content": "What happens in a performance review?"}, # 10 tokens
+ {
+ "role": "assistant",
+ "content": "During the performance review at Contoso Electronics, the supervisor will discuss the employee's performance over the past year and provide feedback on areas for improvement. They will also provide an opportunity for the employee to discuss their goals and objectives for the upcoming year. The review is a two-way dialogue between managers and employees, and employees will receive a written summary of their performance review which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
+ }, # 102 tokens
+ {"role": "user", "content": "Is there a dress code?"}, # 9 tokens
+ {
+ "role": "assistant",
+ "content": "Yes, there is a dress code at Contoso Electronics. Look sharp! [employee_handbook-1.pdf]",
+ }, # 26 tokens
+ {"role": "user", "content": "What does a Product Manager do?"}, # 10 tokens
+ ],
+ user_content="What does a Product Manager do?",
+ max_tokens=147,
+ )
+ assert messages == [
+ {"role": "system", "content": "You are a bot."},
+ {
+ "role": "assistant",
+ "content": "During the performance review at Contoso Electronics, the supervisor will discuss the employee's performance over the past year and provide feedback on areas for improvement. They will also provide an opportunity for the employee to discuss their goals and objectives for the upcoming year. The review is a two-way dialogue between managers and employees, and employees will receive a written summary of their performance review which will include a rating of their performance, feedback, and goals and objectives for the upcoming year [employee_handbook-3.pdf].",
+ },
+ {"role": "user", "content": "Is there a dress code?"},
+ {
+ "role": "assistant",
+ "content": "Yes, there is a dress code at Contoso Electronics. Look sharp! [employee_handbook-1.pdf]",
+ },
+ {"role": "user", "content": "What does a Product Manager do?"},
+ ]
diff --git a/tests/test_messagebuilder.py b/tests/test_messagebuilder.py
index 85a5497904..3b6cb687fa 100644
--- a/tests/test_messagebuilder.py
+++ b/tests/test_messagebuilder.py
@@ -8,7 +8,7 @@ def test_messagebuilder():
{"role": "system", "content": "You are a bot."}
]
assert builder.model == "gpt-35-turbo"
- assert builder.token_length == 8
+ assert builder.count_tokens_for_message(builder.messages[0]) == 8
def test_messagebuilder_append():
@@ -21,7 +21,8 @@ def test_messagebuilder_append():
{"role": "user", "content": "Hello, how are you?"},
]
assert builder.model == "gpt-35-turbo"
- assert builder.token_length == 17
+ assert builder.count_tokens_for_message(builder.messages[0]) == 8
+ assert builder.count_tokens_for_message(builder.messages[1]) == 9
def test_messagebuilder_unicode():
@@ -31,7 +32,7 @@ def test_messagebuilder_unicode():
{"role": "system", "content": "á"}
]
assert builder.model == "gpt-35-turbo"
- assert builder.token_length == 4
+ assert builder.count_tokens_for_message(builder.messages[0]) == 4
def test_messagebuilder_unicode_append():
@@ -44,4 +45,5 @@ def test_messagebuilder_unicode_append():
{"role": "user", "content": "á"},
]
assert builder.model == "gpt-35-turbo"
- assert builder.token_length == 8
+ assert builder.count_tokens_for_message(builder.messages[0]) == 4
+ assert builder.count_tokens_for_message(builder.messages[1]) == 4