Skip to content

Commit

Permalink
set azure credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
lzzze987 committed Mar 18, 2024
1 parent bfbf443 commit dc63b25
Show file tree
Hide file tree
Showing 27 changed files with 6,627 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
40 changes: 40 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local
.env
.env.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

certificates
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}
87 changes: 87 additions & 0 deletions actions/transcript.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"use server";

import {
AzureKeyCredential,
ChatRequestMessage,
OpenAIClient,
} from "@azure/openai";

async function transcript(prevState: any, formData: FormData) {
"use server";

const id = Math.random().toString(36);

console.log("PREVIOUS STATE:", prevState);
if (
process.env.AZURE_API_KEY === undefined ||
process.env.AZURE_ENDPOINT === undefined ||
process.env.AZURE_DEPLOYMENT_NAME === undefined ||
process.env.AZURE_DEPLOYMENT_COMPLETIONS_NAME === undefined
) {
console.error("Azure credentials not set");
return {
sender: "",
response: "Azure credentials not set",
};
}

const file = formData.get("audio") as File;
if (file.size === 0) {
return {
sender: "",
response: "No audio file provided",
};
}

console.log(">>", file);

const arrayBuffer = await file.arrayBuffer();
const audio = new Uint8Array(arrayBuffer);

// --- get audio transcription from Azure OpenAI Whisper ----

console.log("== Transcribe Audio Sample ==");

const client = new OpenAIClient(
process.env.AZURE_ENDPOINT,
new AzureKeyCredential(process.env.AZURE_API_KEY)
);

const result = await client.getAudioTranscription(
process.env.AZURE_DEPLOYMENT_NAME,
audio
);
console.log(`Transcription: ${result.text}`);

// --- get chat completion from Azure OpenAI ----

const messages: ChatRequestMessage[] = [
{
role: "system",
content:
"You are a helpful assistant created by Deepak Kushwaha. You will answer questions and reply I cannot answer that if you dont know the answer.",
},
{ role: "user", content: result.text },
];

console.log(`Messages: ${messages.map((m) => m.content).join("\n")}`);

const completions = await client.getChatCompletions(
process.env.AZURE_DEPLOYMENT_COMPLETIONS_NAME,
messages,
{ maxTokens: 128 }
);

console.log("chatbot: ", completions.choices[0].message?.content);

const response = completions.choices[0].message?.content;

console.log(prevState.sender, "+++", result.text);
return {
sender: result.text,
response: response,
id: id,
};
}

export default transcript;
Binary file added app/favicon.ico
Binary file not shown.
86 changes: 86 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
.message {
@apply bg-purple-500 relative text-white p-4 rounded-lg w-fit;
}

.assistant {
@apply h-40 w-40 object-contain;
}
}

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;

--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;

--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;

--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;

--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;

--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;

--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;

--radius: 0.5rem;
}

.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;

--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;

--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;

--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;

--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;

--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;

--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;

--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;

--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
22 changes: 22 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className="h-screen overflow-hidden">{children}</body>
</html>
);
}
109 changes: 109 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"use client";

import transcript from "@/actions/transcript";
import { useFormState } from "react-dom";
import { useEffect, useRef, useState } from "react";
import Recorder from "@/components/Recorder";
import VoiceSynthesizer from "@/components/VoiceSynthesizer";
import Messages from "@/components/Messages";
import { SettingsIcon } from "lucide-react";
import Image from "next/image";
import mee from "@/img/mee.jpg"

const initialState = {
sender: "",
response: "",
id: "",
};

export type Message = {
sender: string;
response: string;
id: string;
};

export default function Home() {
const [state, formAction] = useFormState(transcript, initialState);
const fileRef = useRef<HTMLInputElement | null>(null);
const submitButtonRef = useRef<HTMLButtonElement | null>(null);
const [messages, setMessages] = useState<Message[]>([]);
const [displaySettings, setDisplaySettings] = useState(false);

// Responsible for updating the messages when the Server Action completes
useEffect(() => {
if (state.response && state.sender) {
setMessages((messages) => [
{
sender: state.sender || "",
response: state.response || "",
id: state.id || "",
},
...messages,
]);
}
}, [state]);

const uploadAudio = (blob: Blob) => {
if (typeof window !== 'undefined') {
const url = URL.createObjectURL(blob);
const audio = document.createElement("audio");
audio.src = url;
audio.controls = true;

// Create a File object from the Blob
const file = new File([blob], "audio.webm", { type: blob.type });

// Set the file as the value of the file input element
if (fileRef.current) {
// Create a DataTransfer object to simulate a file input event
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file);
fileRef.current.files = dataTransfer.files;

// Submit the form
if (submitButtonRef.current) {
submitButtonRef.current.click();
}
}
}
};


console.log(messages);

return (
<main className="bg-black h-screen overflow-y-scroll">
<header className="flex fixed top-0 justify-between text-white w-full p-5">
<Image
src={mee.src}
alt="Logo"
width={50}
height={50}
className="rounded-3xl"
/>

<SettingsIcon
className="p-2 m-2 rounded-full cursor-pointer bg-purple-600 text-black transition-all ease-in-out duration-150 hover:bg-purple-700 hover:text-white"
onClick={() => setDisplaySettings(!displaySettings)}
size={40}
/>
</header>

<form action={formAction} className="flex flex-col bg-black">
<div className="flex-1 bg-gradient-to-b from-purple-500 to-black">
<Messages messages={messages} />
</div>

<input type="file" name="audio" ref={fileRef} hidden />
<button type="submit" hidden ref={submitButtonRef} />

<div className="fixed bottom-0 w-full overflow-hidden bg-black rounded-t-3xl">
<Recorder uploadAudio={uploadAudio} />
<div className="">
<VoiceSynthesizer state={state} displaySettings={displaySettings} />
</div>
</div>
</form>
</main>
);
}
17 changes: 17 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
Loading

0 comments on commit dc63b25

Please sign in to comment.