Skip to content

Commit 4063767

Browse files
Merge branch 'main' into refactor/move-prompts-to-jinja-templates
2 parents e25468c + 3dad881 commit 4063767

File tree

14 files changed

+729
-681
lines changed

14 files changed

+729
-681
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,17 @@ The repo includes sample data so it's ready to try end to end. In this sample ap
7676
**IMPORTANT:** In order to deploy and run this example, you'll need:
7777

7878
- **Azure account**. If you're new to Azure, [get an Azure account for free](https://azure.microsoft.com/free/cognitive-search/) and you'll get some free Azure credits to get started. See [guide to deploying with the free trial](docs/deploy_lowcost.md).
79-
- **Azure subscription with access enabled for the Azure OpenAI service**. You can request access with [this form](https://aka.ms/oaiapply). If your access request to Azure OpenAI service doesn't match the [acceptance criteria](https://learn.microsoft.com/legal/cognitive-services/openai/limited-access?context=%2Fazure%2Fcognitive-services%2Fopenai%2Fcontext%2Fcontext), you can use [OpenAI public API](https://platform.openai.com/docs/api-reference/introduction) instead. Learn [how to switch to an OpenAI instance](docs/deploy_existing.md#openaicom-openai).
8079
- **Azure account permissions**:
8180
- Your Azure account must have `Microsoft.Authorization/roleAssignments/write` permissions, such as [Role Based Access Control Administrator](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#role-based-access-control-administrator-preview), [User Access Administrator](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#user-access-administrator), or [Owner](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#owner). If you don't have subscription-level permissions, you must be granted [RBAC](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#role-based-access-control-administrator-preview) for an existing resource group and [deploy to that existing group](docs/deploy_existing.md#resource-group).
8281
- Your Azure account also needs `Microsoft.Resources/deployments/write` permissions on the subscription level.
8382

8483
### Cost estimation
8584

8685
Pricing varies per region and usage, so it isn't possible to predict exact costs for your usage.
87-
However, you can try the [Azure pricing calculator](https://azure.com/e/a87a169b256e43c089015fda8182ca87) for the resources below.
86+
However, you can try the [Azure pricing calculator](https://azure.com/e/e3490de2372a4f9b909b0d032560e41b) for the resources below.
8887

8988
- Azure Container Apps: Default host for app deployment as of 10/28/2024. See more details in [the ACA deployment guide](docs/azure_container_apps.md). Consumption plan with 1 CPU core, 2.0 GB RAM. Pricing with Pay-as-You-Go. [Pricing](https://azure.microsoft.com/pricing/details/container-apps/)
89+
- Azure Container Registry: Basic tier. [Pricing](https://azure.microsoft.com/pricing/details/container-registry/)
9090
- Azure App Service: Only provisioned if you deploy to Azure App Service following [the App Service deployment guide](docs/azure_app_service.md). Basic Tier with 1 CPU core, 1.75 GB RAM. Pricing per hour. [Pricing](https://azure.microsoft.com/pricing/details/app-service/linux/)
9191
- Azure OpenAI: Standard tier, GPT and Ada models. Pricing per 1K tokens used, and at least 1K tokens are used per question. [Pricing](https://azure.microsoft.com/pricing/details/cognitive-services/openai-service/)
9292
- Azure AI Document Intelligence: SO (Standard) tier using pre-built layout. Pricing per document page, sample documents have 261 pages total. [Pricing](https://azure.microsoft.com/pricing/details/form-recognizer/)

app/backend/requirements.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ aiofiles==24.1.0
88
# via quart
99
aiohappyeyeballs==2.4.0
1010
# via aiohttp
11-
aiohttp==3.10.5
11+
aiohttp==3.10.11
1212
# via
1313
# -r requirements.in
1414
# microsoft-kiota-authentication-azure
@@ -328,6 +328,8 @@ portalocker==2.10.1
328328
# via msal-extensions
329329
priority==2.0.0
330330
# via hypercorn
331+
propcache==0.2.0
332+
# via yarl
331333
psutil==5.9.8
332334
# via azure-monitor-opentelemetry-exporter
333335
pycparser==2.22
@@ -433,7 +435,7 @@ wrapt==1.16.0
433435
# opentelemetry-instrumentation-urllib3
434436
wsproto==1.2.0
435437
# via hypercorn
436-
yarl==1.9.4
438+
yarl==1.17.2
437439
# via aiohttp
438440
zipp==3.20.0
439441
# via importlib-metadata

app/frontend/package-lock.json

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

app/frontend/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
},
1414
"dependencies": {
1515
"@azure/msal-browser": "^3.26.1",
16-
"@azure/msal-react": "^2.0.21",
16+
"@azure/msal-react": "^2.2.0",
1717
"@fluentui/react": "^8.112.5",
18-
"@fluentui/react-components": "^9.55.1",
19-
"@fluentui/react-icons": "^2.0.249",
18+
"@fluentui/react-components": "^9.56.2",
19+
"@fluentui/react-icons": "^2.0.265",
2020
"@react-spring/web": "^9.7.3",
2121
"dompurify": "^3.1.6",
22-
"i18next": "^23.15.2",
22+
"i18next": "^23.16.5",
2323
"i18next-browser-languagedetector": "^8.0.0",
2424
"i18next-http-backend": "^2.5.2",
2525
"idb": "^8.0.0",
@@ -38,13 +38,13 @@
3838
"devDependencies": {
3939
"@types/dom-speech-recognition": "^0.0.4",
4040
"@types/dompurify": "^3.0.5",
41-
"@types/react": "^18.3.11",
41+
"@types/react": "^18.3.12",
4242
"@types/react-dom": "^18.3.1",
4343
"@types/react-syntax-highlighter": "^15.5.13",
4444
"@vitejs/plugin-react": "^4.3.3",
4545
"prettier": "^3.3.3",
4646
"typescript": "^5.6.3",
47-
"vite": "^5.4.10",
47+
"vite": "^5.4.11",
4848
"rollup-plugin-visualizer": "^5.12.0"
4949
}
5050
}

app/frontend/src/components/Answer/Answer.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useMemo } from "react";
1+
import { useMemo, useState } from "react";
22
import { Stack, IconButton } from "@fluentui/react";
33
import { useTranslation } from "react-i18next";
44
import DOMPurify from "dompurify";
@@ -46,13 +46,34 @@ export const Answer = ({
4646
const parsedAnswer = useMemo(() => parseAnswerToHtml(answer, isStreaming, onCitationClicked), [answer]);
4747
const { t } = useTranslation();
4848
const sanitizedAnswerHtml = DOMPurify.sanitize(parsedAnswer.answerHtml);
49+
const [copied, setCopied] = useState(false);
50+
51+
const handleCopy = () => {
52+
// Single replace to remove all HTML tags to remove the citations
53+
const textToCopy = sanitizedAnswerHtml.replace(/<a [^>]*><sup>\d+<\/sup><\/a>|<[^>]+>/g, "");
54+
55+
navigator.clipboard
56+
.writeText(textToCopy)
57+
.then(() => {
58+
setCopied(true);
59+
setTimeout(() => setCopied(false), 2000);
60+
})
61+
.catch(err => console.error("Failed to copy text: ", err));
62+
};
4963

5064
return (
5165
<Stack className={`${styles.answerContainer} ${isSelected && styles.selected}`} verticalAlign="space-between">
5266
<Stack.Item>
5367
<Stack horizontal horizontalAlign="space-between">
5468
<AnswerIcon />
5569
<div>
70+
<IconButton
71+
style={{ color: "black" }}
72+
iconProps={{ iconName: copied ? "CheckMark" : "Copy" }}
73+
title={copied ? t("tooltips.copied") : t("tooltips.copy")}
74+
ariaLabel={copied ? t("tooltips.copied") : t("tooltips.copy")}
75+
onClick={handleCopy}
76+
/>
5677
<IconButton
5778
style={{ color: "black" }}
5879
iconProps={{ iconName: "Lightbulb" }}

app/frontend/src/locales/da/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@
5959
"showSupportingContent": "Vis understøttende indhold",
6060
"speakAnswer": "Afspil svar",
6161
"info": "Info",
62-
"save": "Gem"
62+
"save": "Gem",
63+
"copy": "Kopier",
64+
"copied": "Kopieret!"
6365
},
6466
"headerTexts": {
6567
"thoughtProcess": "Tankeproces",

app/frontend/src/locales/en/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"showSupportingContent": "Show supporting content",
6262
"speakAnswer": "Speak answer",
6363
"info": "Info",
64-
"save": "Save"
64+
"save": "Save",
65+
"copy": "Copy",
66+
"copied": "Copied!"
6567
},
6668

6769
"headerTexts":{

app/frontend/src/locales/es/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"showSupportingContent": "Mostrar contenido de soporte",
6262
"speakAnswer": "Hablar respuesta",
6363
"info": "Información",
64-
"save": "Guardar"
64+
"save": "Guardar",
65+
"copy": "Copiar",
66+
"copied": "¡Copiado!"
6567
},
6668

6769
"headerTexts":{

app/frontend/src/locales/fr/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"showSupportingContent": "Montrer le contenu de soutien",
6262
"speakAnswer": "Parler réponse",
6363
"info": "Info",
64-
"save": "Sauvegarder"
64+
"save": "Sauvegarder",
65+
"copy": "Copier",
66+
"copied": "Copié!"
6567
},
6668

6769
"headerTexts":{

app/frontend/src/locales/ja/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"showSupportingContent": "サポート内容の表示",
6262
"speakAnswer": "音声による回答",
6363
"info": "情報",
64-
"save": "保存"
64+
"save": "保存",
65+
"copy": "コピー",
66+
"copied": "コピーしました!"
6567
},
6668

6769
"headerTexts":{

0 commit comments

Comments
 (0)