Skip to content

Commit

Permalink
Copilot chat cleanup - removing Vite and updating README (#284)
Browse files Browse the repository at this point in the history
### Motivation and Context
Removing Vite dependency to simplify toolchain + updating README

### Description
We are authenticating with the /common endpoint, and in order to use
/common/ endpoint, the application must not be configured with
'Consumer' as the user audience. The userAudience should be configured
with 'All' to use /common/ endpoint.
  • Loading branch information
adrianwyatt authored Apr 3, 2023
2 parents 532ba43 + 010f66d commit 0c917a7
Show file tree
Hide file tree
Showing 15 changed files with 6,570 additions and 2,454 deletions.
27 changes: 20 additions & 7 deletions samples/apps/copilot-chat-app/WebApp/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# Copilot Chat Web App
> **!IMPORTANT**
> This learning sample is for educational purposes only and should not be used in any
> production use case. It is intended to highlight concepts of Semantic Kernel and not
> any architectural / security design practices to be used.
The Copilot Chat sample showcases how you can create an enriched experience with multiple dynamic components, including command messages, user intent, and memories, etc. The chat prompt will evolve as the conversation between the user and the application proceeds. This chat experience is a chat skill containing multiple functions that work together to construct the final prompt for each exchange.

### Watch the Copilot Chat Sample Quick Start Video [here](https://aka.ms/SK-Copilotchat-video).

## Running the sample

Expand All @@ -7,15 +15,20 @@
[register your application](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app)
in the Azure Portal. Follow the steps to register your app
[here](https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app).
- Select **`Single-page application (SPA)`** as platform type, and the Redirect URI will be **`https://localhost:3000`**
- Select **`Personal Microsoft accounts only`** as supported account types for this sample
- Select **`Single-page application (SPA)`** as platform type, and the Redirect URI will be **`http://localhost:3000`**
- Select **`Accounts in any organizational directory and personal Microsoft accounts`** as supported account types for this sample.
4. Create an **[.env](.env)** file to this folder root with the following variables and fill in with your information, where
`REACT_APP_GRAPH_CLIENT_ID=` is the GUID copied from the **Application (client) ID** from the Azure Portal and
`VITE_REACT_APP_BACKEND_URI=` is the URI where your backend is running:
`APP_CHAT_CLIENT_ID=` is the GUID copied from the **Application (client) ID** from the Azure Portal and
`APP_BACKEND_URI=` is the URI where your backend is running:

VITE_REACT_APP_CHAT_CLIENT_ID=
VITE_REACT_APP_BACKEND_URI=https://localhost:40443
APP_CHAT_CLIENT_ID=
APP_BACKEND_URI=https://localhost:40443

5. **Run** the following command `yarn install` (if you have never run the app before)
and/or `yarn start` from the command line.
6. A browser will automatically open, otherwise you can navigate to `https://localhost:3000/` to use the ChatBot.
6. A browser will automatically open, otherwise you can navigate to `http://localhost:3000/` to use the ChatBot.

## About the Copilot Chat Sample

### Authentication in this sample
This sample uses the Microsoft Authentication Library (MSAL) for React to sign in users. Learn more about it here: https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-react.
48 changes: 27 additions & 21 deletions samples/apps/copilot-chat-app/WebApp/package.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
{
"name": "chatbot",
"name": "copilot-chat",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"auth": "vsts-npm-auth -config .npmrc",
"auth:mac": "better-vsts-npm-auth -config .npmrc",
"dev": "vite",
"build": "tsc && vite build",
"depcheck": "depcheck --ignores=\"@types/*,typescript,vite\" --ignore-dirs=\".vscode,.vs,.git,node_modules\" --skip-missing",
"depcheck": "depcheck --ignores=\"@types/*,typescript\" --ignore-dirs=\".vscode,.vs,.git,node_modules\" --skip-missing",
"lint": "eslint src",
"prettify": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,scss,css,html,svg}\"",
"preview": "vite preview",
"serve": "http-server dist -p 4000 -S -C certs/cert.pem -K certs/key.pem",
"start": "vite"
},
"eslintConfig": {
"extends": [
"react-app"
]
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"dependencies": {
"@azure/ms-rest-js": "^2.6.4",
Expand All @@ -27,29 +22,24 @@
"@fluentui/react-components": "^9.13.0",
"@fluentui/react-icons": "^2.0.193",
"@reduxjs/toolkit": "^1.9.1",
"abcjs": "^6.1.9",
"cron": "^2.2.0",
"debug": "^4.3.4",
"fluid-framework": "^1.3.4",
"mermaid": "^9.3.0",
"microsoft-cognitiveservices-speech-sdk": "^1.24.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-scripts": "^5.0.1",
"strict-event-emitter-types": "^2.0.0"
},
"devDependencies": {
"@types/cron": "^2.0.0",
"@types/debug": "^4.1.7",
"@types/node": "^18.11.9",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.45.0",
"@vitejs/plugin-react": "^3.0.1",
"better-vsts-npm-auth": "^7.0.0",
"depcheck": "^1.4.3",
"eslint": "^8.0.1",
"eslint-config-react-app": "^7.0.1",
"eslint-config-standard-with-typescript": "^23.0.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-n": "^15.0.0",
Expand All @@ -60,10 +50,26 @@
"http-server": "^14.1.1",
"prettier": "^2.8.1",
"typescript": "*",
"vite": "^4.0.4",
"vite-plugin-mkcert": "^1.11.0",
"vite-plugin-pwa": "^0.14.1",
"vsts-npm-auth": "^0.42.1",
"workbox-window": "^6.5.4"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 edge version",
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Copilot Chat</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
8 changes: 4 additions & 4 deletions samples/apps/copilot-chat-app/WebApp/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Copyright (c) Microsoft. All rights reserved.

import { AuthenticatedTemplate, UnauthenticatedTemplate } from '@azure/msal-react';
import { Avatar, makeStyles, Subtitle1 } from '@fluentui/react-components';
import { Avatar, Subtitle1, makeStyles } from '@fluentui/react-components';
import * as React from 'react';
import { FC, useEffect } from 'react';
import { msalInstance } from '.';
import { Login } from './components/Login';
import { ChatView } from './components/views/ChatView';
import BackendProbe from './components/views/BackendProbe';
import { msalInstance } from './main';
import { ChatView } from './components/views/ChatView';
import { useAppDispatch, useAppSelector } from './redux/app/hooks';
import { RootState } from './redux/app/store';
import { setSelectedConversation } from './redux/features/conversations/conversationsSlice';
Expand Down Expand Up @@ -63,7 +63,7 @@ const App: FC = () => {
<AuthenticatedTemplate>
{appState === AppState.ProbeForBackend &&
<BackendProbe
uri={import.meta.env.VITE_REACT_APP_BACKEND_URI as string}
uri={process.env.APP_BACKEND_URI as string}
onBackendFound={() => setAppState(AppState.Chat)}
/>
}
Expand Down
2 changes: 1 addition & 1 deletion samples/apps/copilot-chat-app/WebApp/src/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const Constants = {
msal: {
method: 'redirect', // 'redirect' | 'popup'
auth: {
clientId: import.meta.env.VITE_REACT_APP_CHAT_CLIENT_ID as string,
clientId: process.env.APP_CHAT_CLIENT_ID as string,
authority: 'https://login.microsoftonline.com/common',
},
cache: {
Expand Down
83 changes: 0 additions & 83 deletions samples/apps/copilot-chat-app/WebApp/src/components/PageViewer.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ export const ChatHistoryItem: React.FC<ChatHistoryItemProps> = (props) => {
const chat = useChat();
const account = useAccount();
const classes = useClasses();
const [isHovered, setIsHovered] = React.useState(false);
const { conversations, selectedId } = useAppSelector((state: RootState) => state.conversations);

const content = message.content
Expand Down Expand Up @@ -111,8 +110,6 @@ export const ChatHistoryItem: React.FC<ChatHistoryItemProps> = (props) => {
{!isMe && <Persona className={classes.persona} avatar={avatar} />}
<div
className={isMe ? mergeClasses(classes.item, classes.me) : classes.item}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
<div className={classes.header}>
{!isMe && <Label weight="semibold">{fullName}</Label>}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.

import { Body1, Spinner, Title3 } from '@fluentui/react-components';
import * as React from 'react';
import { FC, useEffect } from 'react';

interface IData {
Expand Down Expand Up @@ -29,7 +28,7 @@ const BackendProbe: FC<IData> = ({ uri, onBackendFound }) => {
<Title3>Looking for your backend</Title3>
<Spinner />
<Body1>
This sample expects to find a Semantic Kernel service from <strong>samples/packaged/SKWebAPI</strong>{' '}
This sample expects to find a Semantic Kernel service from <strong>samples/apps/copilot-chat-app/SKWebApi</strong>{' '}
running at <strong>{uri}</strong>
</Body1>
<Body1>
Expand Down
13 changes: 0 additions & 13 deletions samples/apps/copilot-chat-app/WebApp/src/libs/AuthHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
RedirectRequest
} from '@azure/msal-browser';
import debug from 'debug';
import { Dispatch } from 'react';
import { Constants } from '../Constants';

const log = debug(Constants.debug.root).extend('authHelper');
Expand Down Expand Up @@ -75,23 +74,11 @@ const logoutAsync = async (instance: IPublicClientApplication) => {
}
};

// TODO: error handling
const aquireToken = async(instance: IPublicClientApplication, setAccessToken: Dispatch<React.SetStateAction<string>>) => {
instance.acquireTokenSilent(loginRequest).then((response) => {
setAccessToken(response.accessToken);
}).catch((_error: any) => {
instance.acquireTokenPopup(loginRequest).then((response) => {
setAccessToken(response.accessToken);
});
});
};

export const AuthHelper = {
msalConfig,
loginRequest,
logoutRequest,
ssoSilentRequest,
loginAsync,
logoutAsync,
aquireToken
};
7 changes: 2 additions & 5 deletions samples/apps/copilot-chat-app/WebApp/src/libs/useChat.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useAccount } from "@azure/msal-react";
import debug from "debug";
import { Constants } from "../Constants";
import { useAppDispatch, useAppSelector } from "../redux/app/hooks";
import { RootState } from "../redux/app/store";
Expand All @@ -8,14 +7,12 @@ import { addConversation, setSelectedConversation, updateConversation } from "..
import { ChatUser } from "./models/ChatUser";
import { useSemanticKernel } from "./semantic-kernel/useSemanticKernel";

const log = debug(Constants.debug.root).extend('use-chat');

export const useChat = () => {
const { audience } = useAppSelector((state: RootState) => state.chat);
const dispatch = useAppDispatch();
const account = useAccount();
const sk = useSemanticKernel(import.meta.env.VITE_REACT_APP_BACKEND_URI as string);
const { conversations, selectedId } = useAppSelector((state: RootState) => state.conversations);
const sk = useSemanticKernel(process.env.APP_BACKEND_URI as string);
const { conversations } = useAppSelector((state: RootState) => state.conversations);

const botProfilePictures : string[] = [
'/assets/bot-icon-1.png',
Expand Down
1 change: 0 additions & 1 deletion samples/apps/copilot-chat-app/WebApp/src/vite-env.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion samples/apps/copilot-chat-app/WebApp/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
"types": [],
"composite": true
},
"include": ["src", "vite.config.ts"]
"include": ["src"]
}
Loading

0 comments on commit 0c917a7

Please sign in to comment.