Chat GPT in VB.NET and C#






4.98/5 (29 votes)
Windows app to talk to Chat GPT
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 = "" 'https://beta.openai.com/account/api-keys
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
'SetModels()
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 = "" 'Reset Hypothesized 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 'text-davinci-002, text-davinci-003
Dim sUrl As String = "https://api.openai.com/v1/completions"
If sModel.IndexOf("gpt-3.5-turbo") <> -1 Then
'Chat GTP 4 https://openai.com/research/gpt-4
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 '2048
Dim dTemperature As Double = txtTemperature.Text '0.5
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 '1
'https://beta.openai.com/docs/api-reference/completions/create
Dim data As String = ""
If sModel.IndexOf("gpt-3.5-turbo") <> -1 Then
'Chat GTP 4
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" & ", " 'Number between -2.0 and 2.0 Positive value decrease the model's likelihood to repeat the same line verbatim.
data += " ""presence_penalty"": 0.0" & ", " ' Number between -2.0 and 2.0. Positive values increase the model's likelihood to talk about new topics.
data += " ""stop"": [""#"", "";""]" 'Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence.
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()
'Return sJson
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
'Chat GTP 4
sResponse = oJson("choices")(0)("message")("content")
Else
sResponse = oJson("choices")(0)("text")
End If
Return sResponse
End Function
Private Sub SetModels()
'https://beta.openai.com/docs/models/gpt-3
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()
'Return sJson
cbModel.Items.Clear()
'Dim sIds As String = ""
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")
'Dim sCreated As String = oList(i)("created")
'Dim sObject As String = oList(i)("object")
'Dim sOwned_by As String = oList(i)("owned_by")
'Dim oPermission As Hashtable = oList(i)("permission")(0)
'If sIds <> "" Then sIds += vbCrLf
'sIds += sCreated & vbTab & sId
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"; // https://beta.openai.com/account/api-keys
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;
}
//SetModels();
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 = ""; // Reset Hypothesized 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; // text-davinci-002, text-davinci-003
string sUrl = "https://api.openai.com/v1/completions";
if (sModel.IndexOf("gpt-3.5-turbo") != -1)
{
//Chat GTP 4 https://openai.com/research/gpt-4
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); // 2048
double dTemperature = double.Parse(txtTemperature.Text); // 0.5
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; // 1
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" + ", "; // Number between -2.0 and 2.0 Positive value decrease the model's likelihood to repeat the same line verbatim.
data += " \"presence_penalty\": 0.0" + ", "; // Number between -2.0 and 2.0. Positive values increase the model's likelihood to talk about new topics.
data += " \"stop\": [\"#\", \";\"]"; // Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence.
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();
// Return sJson
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()
{
// https://beta.openai.com/docs/models/gpt-3
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