In this article, I have attempted to create windows to talk to Chat GPT using the least amount of code.
Introduction
This application is my attempt to create a smallest client app to talk to Chat GPT. Chat GPT is an AI your application can talk to.
Using the Code
- Get
OPENAI_API_KEY
from https://beta.openai.com/account/api-keys. - Open App.config (or bin\Debug\ChatGPT.exe.config) and add the API Key key to it.
Here is the code. Basically, it uses HttpWebRequest
to post JSON to OpenAI. Endpoint: https://api.openai.com/v1/completions.
VB.NET Version
Imports System.Net
Imports System.IO
Imports System.Configuration
Imports System.Security.Cryptography
Imports System.Speech.Synthesis
Imports System.Speech.Recognition
Imports System.Numerics
Public Class frmGPTChat
Dim OPENAI_API_KEY As String = ""
Dim oSpeechRecognitionEngine As SpeechRecognitionEngine = Nothing
Dim oSpeechSynthesizer As System.Speech.Synthesis.SpeechSynthesizer = Nothing
Private Sub frmGPTChat_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim oAppSettingsReader As New AppSettingsReader()
Dim sApiKey As String = oAppSettingsReader.GetValue("OPENAI_API_KEY", GetType(String)) & ""
If sApiKey = "" Then
MsgBox("Please enter your OpenAI API key in the App.config file.")
End
Else
OPENAI_API_KEY = sApiKey
End If
cbModel.SelectedIndex = 0
cbVoice.Items.Clear()
Dim synth As New SpeechSynthesizer()
For Each voice In synth.GetInstalledVoices()
cbVoice.Items.Add(voice.VoiceInfo.Name)
Next
cbVoice.SelectedIndex = 0
End Sub
Private Sub chkListen_CheckedChanged(sender As Object, e As EventArgs) Handles chkListen.CheckedChanged
If chkListen.Checked Then
lblSpeech.Text = ""
lblSpeech.Visible = True
SpeechToText()
Else
oSpeechRecognitionEngine.RecognizeAsyncStop()
lblSpeech.Visible = False
End If
End Sub
Private Sub chkMute_CheckedChanged(sender As Object, e As EventArgs) Handles chkMute.CheckedChanged
If chkMute.Checked Then
lblVoice.Visible = False
cbVoice.Visible = False
Else
lblVoice.Visible = True
cbVoice.Visible = True
End If
End Sub
Private Sub SpeechToText()
If oSpeechRecognitionEngine IsNot Nothing Then
oSpeechRecognitionEngine.RecognizeAsync(RecognizeMode.Multiple)
Exit Sub
End If
oSpeechRecognitionEngine = New SpeechRecognitionEngine(New System.Globalization.CultureInfo("en-US"))
oSpeechRecognitionEngine.LoadGrammar(New DictationGrammar())
AddHandler oSpeechRecognitionEngine.SpeechRecognized, AddressOf OnSpeechRecognized
AddHandler oSpeechRecognitionEngine.SpeechHypothesized, AddressOf OnSpeechHypothesized
oSpeechRecognitionEngine.SetInputToDefaultAudioDevice()
oSpeechRecognitionEngine.RecognizeAsync(RecognizeMode.Multiple)
End Sub
Private Sub OnSpeechRecognized(sender As Object, e As SpeechRecognizedEventArgs)
lblSpeech.Text = ""
If txtQuestion.Text <> "" Then
txtQuestion.Text += vbCrLf
End If
Dim text As String = e.Result.Text
txtQuestion.Text += text
End Sub
Private Sub OnSpeechHypothesized(sender As Object, e As SpeechHypothesizedEventArgs)
Dim text As String = e.Result.Text
lblSpeech.Text = text
End Sub
Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
Dim sQuestion As String = txtQuestion.Text
If sQuestion = "" Then
MsgBox("Type in your question!")
txtQuestion.Focus()
Exit Sub
End If
If txtAnswer.Text <> "" Then
txtAnswer.AppendText(vbCrLf)
End If
txtAnswer.AppendText("Me: " & sQuestion & vbCrLf)
txtQuestion.Text = ""
Try
Dim sAnswer As String = SendMsg(sQuestion)
txtAnswer.AppendText("Chat GPT: " & Trim(Replace(sAnswer, vbLf, vbCrLf)))
SpeechToText(sAnswer)
Catch ex As Exception
txtAnswer.AppendText("Error: " & ex.Message)
End Try
End Sub
Sub SpeechToText(ByVal s As String)
If chkMute.Checked Then
Exit Sub
End If
If oSpeechSynthesizer Is Nothing Then
oSpeechSynthesizer = New System.Speech.Synthesis.SpeechSynthesizer()
oSpeechSynthesizer.SetOutputToDefaultAudioDevice()
End If
If cbVoice.Text <> "" Then
oSpeechSynthesizer.SelectVoice(cbVoice.Text)
End If
oSpeechSynthesizer.Speak(s)
End Sub
Function SendMsg(ByVal sQuestion As String)
System.Net.ServicePointManager.SecurityProtocol =
System.Net.SecurityProtocolType.Ssl3 Or
System.Net.SecurityProtocolType.Tls12 Or
System.Net.SecurityProtocolType.Tls11 Or
System.Net.SecurityProtocolType.Tls
Dim sModel As String = cbModel.Text
Dim sUrl As String = "https://api.openai.com/v1/completions"
If sModel.IndexOf("gpt-3.5-turbo") <> -1 Then
sUrl = "https://api.openai.com/v1/chat/completions"
End If
Dim request As HttpWebRequest = WebRequest.Create(sUrl)
request.Method = "POST"
request.ContentType = "application/json"
request.Headers.Add("Authorization", "Bearer " & OPENAI_API_KEY)
Dim iMaxTokens As Integer = txtMaxTokens.Text
Dim dTemperature As Double = txtTemperature.Text
If dTemperature < 0 Or dTemperature > 1 Then
MsgBox("Randomness has to be between 0 and 1 with higher values resulting in more random text")
Return ""
End If
Dim sUserId As String = txtUserID.Text
Dim data As String = ""
If sModel.IndexOf("gpt-3.5-turbo") <> -1 Then
data = "{"
data += " ""model"":""" & sModel & ""","
data += " ""messages"": [{""role"":""user"", ""content"": """ & PadQuotes(sQuestion) & """}]"
data += "}"
Else
data = "{"
data += " ""model"":""" & sModel & ""","
data += " ""prompt"": """ & PadQuotes(sQuestion) & ""","
data += " ""max_tokens"": " & iMaxTokens & ","
data += " ""user"": """ & sUserId & """, "
data += " ""temperature"": " & dTemperature & ", "
data += " ""frequency_penalty"": 0.0" & ", "
data += " ""presence_penalty"": 0.0" & ", "
data += " ""stop"": [""#"", "";""]"
data += "}"
End If
Using streamWriter As New StreamWriter(request.GetRequestStream())
streamWriter.Write(data)
streamWriter.Flush()
streamWriter.Close()
End Using
Dim response As HttpWebResponse = request.GetResponse()
Dim streamReader As New StreamReader(response.GetResponseStream())
Dim sJson As String = streamReader.ReadToEnd()
Dim oJavaScriptSerializer As New System.Web.Script.Serialization.JavaScriptSerializer
Dim oJson As Hashtable = oJavaScriptSerializer.Deserialize(Of Hashtable)(sJson)
Dim sResponse As String = ""
If sModel.IndexOf("gpt-3.5-turbo") <> -1 Then
sResponse = oJson("choices")(0)("message")("content")
Else
sResponse = oJson("choices")(0)("text")
End If
Return sResponse
End Function
Private Sub SetModels()
System.Net.ServicePointManager.SecurityProtocol =
System.Net.SecurityProtocolType.Ssl3 Or
System.Net.SecurityProtocolType.Tls12 Or
System.Net.SecurityProtocolType.Tls11 Or
System.Net.SecurityProtocolType.Tls
Dim apiEndpoint As String = "https://api.openai.com/v1/models"
Dim request As HttpWebRequest = WebRequest.Create(apiEndpoint)
request.Method = "GET"
request.ContentType = "application/json"
request.Headers.Add("Authorization", "Bearer " & OPENAI_API_KEY)
Dim response As HttpWebResponse = request.GetResponse()
Dim streamReader As New StreamReader(response.GetResponseStream())
Dim sJson As String = streamReader.ReadToEnd()
cbModel.Items.Clear()
Dim oSortedList As SortedList = New SortedList()
Dim oJavaScriptSerializer As New System.Web.Script.Serialization.JavaScriptSerializer
Dim oJson As Hashtable = oJavaScriptSerializer.Deserialize(Of Hashtable)(sJson)
Dim oList As Object() = oJson("data")
For i As Integer = 0 To oList.Length - 1
Dim sId As String = oList(i)("id")
oSortedList.Add(sId, sId)
Next
For Each oItem As DictionaryEntry In oSortedList
cbModel.Items.Add(oItem.Key)
Next
End Sub
Private Function PadQuotes(ByVal s As String) As String
If s.IndexOf("\") <> -1 Then
s = Replace(s, "\", "\\")
End If
If s.IndexOf(vbCrLf) <> -1 Then
s = Replace(s, vbCrLf, "\n")
End If
If s.IndexOf(vbCr) <> -1 Then
s = Replace(s, vbCr, "\r")
End If
If s.IndexOf(vbLf) <> -1 Then
s = Replace(s, vbLf, "\f")
End If
If s.IndexOf(vbTab) <> -1 Then
s = Replace(s, vbTab, "\t")
End If
If s.IndexOf("""") = -1 Then
Return s
Else
Return Replace(s, """", "\""")
End If
End Function
End Class
C# Version
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Speech.Synthesis;
using System.Speech.Recognition;
using static System.Net.WebRequestMethods;
namespace ChatGPTCS
{
public partial class ChatGPT : Form
{
string OPENAI_API_KEY = "sfdsf";
SpeechRecognitionEngine oSpeechRecognitionEngine = null;
System.Speech.Synthesis.SpeechSynthesizer oSpeechSynthesizer = null;
public ChatGPT()
{
InitializeComponent();
}
private void ChatGPT_Load(object sender, EventArgs e)
{
AppSettingsReader oAppSettingsReader = new AppSettingsReader();
string sApiKey = oAppSettingsReader.GetValue("OPENAI_API_KEY", typeof(string)) + "";
if (sApiKey == "")
{
MessageBox.Show("Please enter your OpenAI API key in the App.config file.");
System.Windows.Forms.Application.Exit();
}
else
{
OPENAI_API_KEY = sApiKey;
}
cbModel.SelectedIndex = 0;
cbVoice.Items.Clear();
SpeechSynthesizer synth = new SpeechSynthesizer();
foreach (var voice in synth.GetInstalledVoices())
cbVoice.Items.Add(voice.VoiceInfo.Name);
cbVoice.SelectedIndex = 0;
}
private void chkListen_CheckedChanged(object sender, EventArgs e)
{
if (chkListen.Checked)
{
lblSpeech.Text = "";
lblSpeech.Visible = true;
SpeechToText();
}
else
{
oSpeechRecognitionEngine.RecognizeAsyncStop();
lblSpeech.Visible = false;
}
}
private void chkMute_CheckedChanged(object sender, EventArgs e)
{
if (chkMute.Checked)
{
lblVoice.Visible = false;
cbVoice.Visible = false;
}
else
{
lblVoice.Visible = true;
cbVoice.Visible = true;
}
}
private void SpeechToText()
{
if (oSpeechRecognitionEngine != null)
{
oSpeechRecognitionEngine.RecognizeAsync(RecognizeMode.Multiple);
return;
}
oSpeechRecognitionEngine = new SpeechRecognitionEngine(new System.Globalization.CultureInfo("en-US"));
oSpeechRecognitionEngine.LoadGrammar(new DictationGrammar());
oSpeechRecognitionEngine.SpeechRecognized += OnSpeechRecognized;
oSpeechRecognitionEngine.SpeechHypothesized += OnSpeechHypothesized;
oSpeechRecognitionEngine.SetInputToDefaultAudioDevice();
oSpeechRecognitionEngine.RecognizeAsync(RecognizeMode.Multiple);
}
private void OnSpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
lblSpeech.Text = "";
if (txtQuestion.Text != "")
txtQuestion.Text += "\n";
string text = e.Result.Text;
txtQuestion.Text += text;
}
private void OnSpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
{
string text = e.Result.Text;
lblSpeech.Text = text;
}
private void btnSend_Click(object sender, EventArgs e)
{
{
string sQuestion = txtQuestion.Text;
if (string.IsNullOrEmpty(sQuestion))
{
MessageBox.Show("Type in your question!");
txtQuestion.Focus();
return;
}
if (txtAnswer.Text != "")
{
txtAnswer.AppendText("\r\n");
}
txtAnswer.AppendText("Me: " + sQuestion + "\r\n");
txtQuestion.Text = "";
try
{
string sAnswer = SendMsg(sQuestion) + "";
txtAnswer.AppendText("Chat GPT: " + sAnswer.Replace( "\n", "\r\n").Trim());
SpeechToText(sAnswer);
}
catch (Exception ex)
{
txtAnswer.AppendText("Error: " + ex.Message);
}
}
}
public void SpeechToText(string s)
{
if (chkMute.Checked)
return;
if (oSpeechSynthesizer == null)
{
oSpeechSynthesizer = new System.Speech.Synthesis.SpeechSynthesizer();
oSpeechSynthesizer.SetOutputToDefaultAudioDevice();
}
if (cbVoice.Text != "")
oSpeechSynthesizer.SelectVoice(cbVoice.Text);
oSpeechSynthesizer.Speak(s);
}
public string SendMsg(string sQuestion)
{
System.Net.ServicePointManager.SecurityProtocol =
System.Net.SecurityProtocolType.Ssl3 |
System.Net.SecurityProtocolType.Tls12 |
System.Net.SecurityProtocolType.Tls11 |
System.Net.SecurityProtocolType.Tls;
string sModel = cbModel.Text;
string sUrl = "https://api.openai.com/v1/completions";
if (sModel.IndexOf("gpt-3.5-turbo") != -1)
{
sUrl = "https://api.openai.com/v1/chat/completions";
}
var request = WebRequest.Create(sUrl);
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("Authorization", "Bearer " + OPENAI_API_KEY);
int iMaxTokens = int.Parse( txtMaxTokens.Text);
double dTemperature = double.Parse(txtTemperature.Text);
if (dTemperature < 0d | dTemperature > 1d)
{
MessageBox.Show("Randomness has to be between 0 and 1 with higher values resulting in more random text");
return "";
}
string sUserId = txtUserID.Text;
string data = "";
if (sModel.IndexOf("gpt-3.5-turbo") != -1)
{
data = "{";
data += " \"model\":\"" + sModel + "\",";
data += " \"messages\": [{\"role\": \"user\", \"content\": \"" + PadQuotes(sQuestion) + "\"}]";
data += "}";
}
else
{
data = "{";
data += " \"model\":\"" + sModel + "\",";
data += " \"prompt\": \"" + PadQuotes(sQuestion) + "\",";
data += " \"max_tokens\": " + iMaxTokens + ",";
data += " \"user\": \"" + sUserId + "\", ";
data += " \"temperature\": " + dTemperature + ", ";
data += " \"frequency_penalty\": 0.0" + ", ";
data += " \"presence_penalty\": 0.0" + ", ";
data += " \"stop\": [\"#\", \";\"]";
data += "}";
}
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(data);
streamWriter.Flush();
streamWriter.Close();
}
var response = request.GetResponse();
var streamReader = new StreamReader(response.GetResponseStream());
string sJson = streamReader.ReadToEnd();
var oJavaScriptSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
Dictionary<string, object> oJson = (Dictionary<string, object>) oJavaScriptSerializer.DeserializeObject(sJson);
Object[] oChoices = (Object[])oJson["choices"];
Dictionary<string, object> oChoice = (Dictionary<string, object>)oChoices[0];
string sResponse = "";
if (sModel.IndexOf("gpt-3.5-turbo") != -1)
{
Dictionary<string, object> oMessage = (Dictionary<string, object>) oChoice["message"];
sResponse = (string) oMessage["content"];
}
else
{
sResponse = (string) oChoice["text"];
}
return sResponse;
}
private string PadQuotes(string s)
{
if (s.IndexOf("\\") != -1)
s = s.Replace("\\", @"\\");
if (s.IndexOf("\n\r") != -1)
s = s.Replace("\n\r", @"\n");
if (s.IndexOf("\r") != -1)
s = s.Replace("\r", @"\r");
if (s.IndexOf("\n") != -1)
s = s.Replace("\n", @"\n");
if (s.IndexOf("\t") != -1)
s = s.Replace("\t", @"\t");
if (s.IndexOf("\"") != -1)
return s.Replace("\"", @"""");
else
return s;
}
private void SetModels()
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3 | System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls;
string apiEndpoint = "https://api.openai.com/v1/models";
var request = WebRequest.Create(apiEndpoint);
request.Method = "GET";
request.ContentType = "application/json";
request.Headers.Add("Authorization", "Bearer " + OPENAI_API_KEY);
var response = request.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
string sJson = streamReader.ReadToEnd();
cbModel.Items.Clear();
SortedList oSortedList = new SortedList();
System.Web.Script.Serialization.JavaScriptSerializer oJavaScriptSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
Dictionary<string, object> oJson = (Dictionary<string, object>)oJavaScriptSerializer.DeserializeObject(sJson);
Object[] oList = (Object[])oJson["data"];
for (int i = 0; i <= oList.Length - 1; i++)
{
Dictionary<string, object> oItem = (Dictionary<string, object>)oList[i];
string sId = (String) oItem["id"];
if (oSortedList.ContainsKey(sId) == false)
{
oSortedList.Add(sId, sId);
}
}
foreach (DictionaryEntry oItem in oSortedList)
cbModel.Items.Add(oItem.Key);
}
}
}
Points of Interest
The next step is to create an application that does something more useful... like read an Outlook email, text me its summary and file it into an appropriate Outlook folder.
History
- 23rd December, 2022: Version 1 created
- 24th December, 2022: Version 2 created (Added C#)
- 27th December, 2022: Version 3 created (Added Model Selector)
- 24th May , 2023: Chat GPT4 support