Skip to content

Commit dc63b25

Browse files
committed
set azure credentials
1 parent bfbf443 commit dc63b25

27 files changed

+6627
-0
lines changed

.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "next/core-web-vitals"
3+
}

.gitignore

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
.yarn/install-state.gz
8+
9+
# testing
10+
/coverage
11+
12+
# next.js
13+
/.next/
14+
/out/
15+
16+
# production
17+
/build
18+
19+
# misc
20+
.DS_Store
21+
*.pem
22+
23+
# debug
24+
npm-debug.log*
25+
yarn-debug.log*
26+
yarn-error.log*
27+
28+
# local env files
29+
.env*.local
30+
.env
31+
.env.local
32+
33+
# vercel
34+
.vercel
35+
36+
# typescript
37+
*.tsbuildinfo
38+
next-env.d.ts
39+
40+
certificates

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"typescript.tsdk": "node_modules/typescript/lib"
3+
}

actions/transcript.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"use server";
2+
3+
import {
4+
AzureKeyCredential,
5+
ChatRequestMessage,
6+
OpenAIClient,
7+
} from "@azure/openai";
8+
9+
async function transcript(prevState: any, formData: FormData) {
10+
"use server";
11+
12+
const id = Math.random().toString(36);
13+
14+
console.log("PREVIOUS STATE:", prevState);
15+
if (
16+
process.env.AZURE_API_KEY === undefined ||
17+
process.env.AZURE_ENDPOINT === undefined ||
18+
process.env.AZURE_DEPLOYMENT_NAME === undefined ||
19+
process.env.AZURE_DEPLOYMENT_COMPLETIONS_NAME === undefined
20+
) {
21+
console.error("Azure credentials not set");
22+
return {
23+
sender: "",
24+
response: "Azure credentials not set",
25+
};
26+
}
27+
28+
const file = formData.get("audio") as File;
29+
if (file.size === 0) {
30+
return {
31+
sender: "",
32+
response: "No audio file provided",
33+
};
34+
}
35+
36+
console.log(">>", file);
37+
38+
const arrayBuffer = await file.arrayBuffer();
39+
const audio = new Uint8Array(arrayBuffer);
40+
41+
// --- get audio transcription from Azure OpenAI Whisper ----
42+
43+
console.log("== Transcribe Audio Sample ==");
44+
45+
const client = new OpenAIClient(
46+
process.env.AZURE_ENDPOINT,
47+
new AzureKeyCredential(process.env.AZURE_API_KEY)
48+
);
49+
50+
const result = await client.getAudioTranscription(
51+
process.env.AZURE_DEPLOYMENT_NAME,
52+
audio
53+
);
54+
console.log(`Transcription: ${result.text}`);
55+
56+
// --- get chat completion from Azure OpenAI ----
57+
58+
const messages: ChatRequestMessage[] = [
59+
{
60+
role: "system",
61+
content:
62+
"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.",
63+
},
64+
{ role: "user", content: result.text },
65+
];
66+
67+
console.log(`Messages: ${messages.map((m) => m.content).join("\n")}`);
68+
69+
const completions = await client.getChatCompletions(
70+
process.env.AZURE_DEPLOYMENT_COMPLETIONS_NAME,
71+
messages,
72+
{ maxTokens: 128 }
73+
);
74+
75+
console.log("chatbot: ", completions.choices[0].message?.content);
76+
77+
const response = completions.choices[0].message?.content;
78+
79+
console.log(prevState.sender, "+++", result.text);
80+
return {
81+
sender: result.text,
82+
response: response,
83+
id: id,
84+
};
85+
}
86+
87+
export default transcript;

app/favicon.ico

25.3 KB
Binary file not shown.

app/globals.css

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
@layer components {
6+
.message {
7+
@apply bg-purple-500 relative text-white p-4 rounded-lg w-fit;
8+
}
9+
10+
.assistant {
11+
@apply h-40 w-40 object-contain;
12+
}
13+
}
14+
15+
@layer base {
16+
:root {
17+
--background: 0 0% 100%;
18+
--foreground: 222.2 84% 4.9%;
19+
20+
--card: 0 0% 100%;
21+
--card-foreground: 222.2 84% 4.9%;
22+
23+
--popover: 0 0% 100%;
24+
--popover-foreground: 222.2 84% 4.9%;
25+
26+
--primary: 222.2 47.4% 11.2%;
27+
--primary-foreground: 210 40% 98%;
28+
29+
--secondary: 210 40% 96.1%;
30+
--secondary-foreground: 222.2 47.4% 11.2%;
31+
32+
--muted: 210 40% 96.1%;
33+
--muted-foreground: 215.4 16.3% 46.9%;
34+
35+
--accent: 210 40% 96.1%;
36+
--accent-foreground: 222.2 47.4% 11.2%;
37+
38+
--destructive: 0 84.2% 60.2%;
39+
--destructive-foreground: 210 40% 98%;
40+
41+
--border: 214.3 31.8% 91.4%;
42+
--input: 214.3 31.8% 91.4%;
43+
--ring: 222.2 84% 4.9%;
44+
45+
--radius: 0.5rem;
46+
}
47+
48+
.dark {
49+
--background: 222.2 84% 4.9%;
50+
--foreground: 210 40% 98%;
51+
52+
--card: 222.2 84% 4.9%;
53+
--card-foreground: 210 40% 98%;
54+
55+
--popover: 222.2 84% 4.9%;
56+
--popover-foreground: 210 40% 98%;
57+
58+
--primary: 210 40% 98%;
59+
--primary-foreground: 222.2 47.4% 11.2%;
60+
61+
--secondary: 217.2 32.6% 17.5%;
62+
--secondary-foreground: 210 40% 98%;
63+
64+
--muted: 217.2 32.6% 17.5%;
65+
--muted-foreground: 215 20.2% 65.1%;
66+
67+
--accent: 217.2 32.6% 17.5%;
68+
--accent-foreground: 210 40% 98%;
69+
70+
--destructive: 0 62.8% 30.6%;
71+
--destructive-foreground: 210 40% 98%;
72+
73+
--border: 217.2 32.6% 17.5%;
74+
--input: 217.2 32.6% 17.5%;
75+
--ring: 212.7 26.8% 83.9%;
76+
}
77+
}
78+
79+
@layer base {
80+
* {
81+
@apply border-border;
82+
}
83+
body {
84+
@apply bg-background text-foreground;
85+
}
86+
}

app/layout.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { Metadata } from "next";
2+
import { Inter } from "next/font/google";
3+
import "./globals.css";
4+
5+
const inter = Inter({ subsets: ["latin"] });
6+
7+
export const metadata: Metadata = {
8+
title: "Create Next App",
9+
description: "Generated by create next app",
10+
};
11+
12+
export default function RootLayout({
13+
children,
14+
}: Readonly<{
15+
children: React.ReactNode;
16+
}>) {
17+
return (
18+
<html lang="en">
19+
<body className="h-screen overflow-hidden">{children}</body>
20+
</html>
21+
);
22+
}

app/page.tsx

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"use client";
2+
3+
import transcript from "@/actions/transcript";
4+
import { useFormState } from "react-dom";
5+
import { useEffect, useRef, useState } from "react";
6+
import Recorder from "@/components/Recorder";
7+
import VoiceSynthesizer from "@/components/VoiceSynthesizer";
8+
import Messages from "@/components/Messages";
9+
import { SettingsIcon } from "lucide-react";
10+
import Image from "next/image";
11+
import mee from "@/img/mee.jpg"
12+
13+
const initialState = {
14+
sender: "",
15+
response: "",
16+
id: "",
17+
};
18+
19+
export type Message = {
20+
sender: string;
21+
response: string;
22+
id: string;
23+
};
24+
25+
export default function Home() {
26+
const [state, formAction] = useFormState(transcript, initialState);
27+
const fileRef = useRef<HTMLInputElement | null>(null);
28+
const submitButtonRef = useRef<HTMLButtonElement | null>(null);
29+
const [messages, setMessages] = useState<Message[]>([]);
30+
const [displaySettings, setDisplaySettings] = useState(false);
31+
32+
// Responsible for updating the messages when the Server Action completes
33+
useEffect(() => {
34+
if (state.response && state.sender) {
35+
setMessages((messages) => [
36+
{
37+
sender: state.sender || "",
38+
response: state.response || "",
39+
id: state.id || "",
40+
},
41+
...messages,
42+
]);
43+
}
44+
}, [state]);
45+
46+
const uploadAudio = (blob: Blob) => {
47+
if (typeof window !== 'undefined') {
48+
const url = URL.createObjectURL(blob);
49+
const audio = document.createElement("audio");
50+
audio.src = url;
51+
audio.controls = true;
52+
53+
// Create a File object from the Blob
54+
const file = new File([blob], "audio.webm", { type: blob.type });
55+
56+
// Set the file as the value of the file input element
57+
if (fileRef.current) {
58+
// Create a DataTransfer object to simulate a file input event
59+
const dataTransfer = new DataTransfer();
60+
dataTransfer.items.add(file);
61+
fileRef.current.files = dataTransfer.files;
62+
63+
// Submit the form
64+
if (submitButtonRef.current) {
65+
submitButtonRef.current.click();
66+
}
67+
}
68+
}
69+
};
70+
71+
72+
console.log(messages);
73+
74+
return (
75+
<main className="bg-black h-screen overflow-y-scroll">
76+
<header className="flex fixed top-0 justify-between text-white w-full p-5">
77+
<Image
78+
src={mee.src}
79+
alt="Logo"
80+
width={50}
81+
height={50}
82+
className="rounded-3xl"
83+
/>
84+
85+
<SettingsIcon
86+
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"
87+
onClick={() => setDisplaySettings(!displaySettings)}
88+
size={40}
89+
/>
90+
</header>
91+
92+
<form action={formAction} className="flex flex-col bg-black">
93+
<div className="flex-1 bg-gradient-to-b from-purple-500 to-black">
94+
<Messages messages={messages} />
95+
</div>
96+
97+
<input type="file" name="audio" ref={fileRef} hidden />
98+
<button type="submit" hidden ref={submitButtonRef} />
99+
100+
<div className="fixed bottom-0 w-full overflow-hidden bg-black rounded-t-3xl">
101+
<Recorder uploadAudio={uploadAudio} />
102+
<div className="">
103+
<VoiceSynthesizer state={state} displaySettings={displaySettings} />
104+
</div>
105+
</div>
106+
</form>
107+
</main>
108+
);
109+
}

components.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "default",
4+
"rsc": true,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "tailwind.config.ts",
8+
"css": "app/globals.css",
9+
"baseColor": "slate",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils"
16+
}
17+
}

0 commit comments

Comments
 (0)