Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
Updated the response object to cope with changes to the json output. Removed legacy textcompletion endpoint.
  • Loading branch information
zq99 authored Dec 16, 2023
1 parent 9d21bf0 commit 1f706c9
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 331 deletions.
Binary file modified OpenAIFrameworkDemo.xlsm
Binary file not shown.
24 changes: 0 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,30 +52,6 @@ Public Sub TestSimpleOpenAI()
End Sub
```

### Text Completion API

```
Public Sub TestTextCompletionSimpleOpenAI()
Dim oOpenAI As clsOpenAI
Dim oResponse As clsOpenAIResponse
Set oOpenAI = New clsOpenAI
oOpenAI.API_KEY = "<API_KEY>"
Set oResponse = oOpenAI.TextCompletion("Write a Haiku about a dinosaur that loves to code!")
If Not oResponse Is Nothing Then
Debug.Print (oResponse.TextContent)
End If
Set oResponse = Nothing
Set oOpenAI = Nothing
End Sub
```

### DALL-E Image Creation

```
Expand Down
42 changes: 0 additions & 42 deletions clsOpenAI.cls
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,14 @@ Private mlngCallsToAPICount As Long

'OpenAI API Endpoints
Private Const API_ENDPOINT_CHAT As String = "https://api.openai.com/v1/chat/completions"
Private Const API_ENDPOINT_COMPLETIONS As String = "https://api.openai.com/v1/completions"
Private Const API_ENDPOINT_IMAGE_CREATION As String = "https://api.openai.com/v1/images/generations"

Private Const DEFAULT_LOCAL_LOCATION As String = "C:\Users\Public\Downloads\"
Private mstrFolderToSave As String

'More models can be found here: https://platform.openai.com/docs/models/overview
Private Const DEFAULT_CHAT_MODEL As String = "gpt-3.5-turbo"
Private Const DEFAULT_TEXT_COMPLETION_MODEL As String = "text-davinci-003"

Private Const DEFAULT_CHAT_TOKENS_COUNT As Integer = 512
Private Const DEFAULT_TEXT_TOKENS_COUNT As Integer = 1024

'Project constants
Private Const UNASSIGNED_VALUE As Integer = -1
Expand Down Expand Up @@ -236,13 +232,6 @@ On Error GoTo ERR_HANDLER:
oResponse.ParseChatJSON (strResponseJson)
Set GetResponseFromAPI = oResponse

ElseIf strEndPoint = API_ENDPOINT_COMPLETIONS Then

'GPT3 and earlier
Set oResponse = New clsOpenAIResponse
oResponse.ParseTextCompletionJSON (strResponseJson)
Set GetResponseFromAPI = oResponse

ElseIf strEndPoint = API_ENDPOINT_IMAGE_CREATION Then

'DALL-E image generator
Expand Down Expand Up @@ -354,37 +343,6 @@ Public Function ChatCompletion(ByVal oMessages As clsOpenAIMessages) As clsOpenA
End Function


Public Function TextCompletion(ByVal strPrompt As String) As clsOpenAIResponse
'Purpose: This is for OpenAI's Text Completion API

Set TextCompletion = Nothing

If Not IsAPIKeyValid Then
mobjLogger.PrintCriticalMessage MESSAGE_INVALID_API_KEY, True
Exit Function
End If

If strPrompt = Empty Then
Exit Function
End If

mobjRequest.prompt = strPrompt

If mobjRequest.Model = Empty Then
mobjRequest.Model = DEFAULT_TEXT_COMPLETION_MODEL
End If

If mobjRequest.MaxTokens = UNASSIGNED_VALUE Then
mobjRequest.MaxTokens = DEFAULT_TEXT_TOKENS_COUNT
End If

Log mobjRequest.GetTextCompletionSendToAPIJsonString

Set TextCompletion = GetResponseFromAPI(mobjRequest.GetTextCompletionSendToAPIJsonString, API_ENDPOINT_COMPLETIONS)

End Function


Private Sub Class_Initialize()

mstrMSXMLType = MSXML_DEFAULT
Expand Down
4 changes: 2 additions & 2 deletions clsOpenAILogger.cls
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ Private Sub Class_Terminate()
Set mobjClass = Nothing
End Sub

Public Sub SetClass(ByVal Obj As IOpenAINameProvider)
Set mobjClass = Obj
Public Sub SetClass(ByVal obj As IOpenAINameProvider)
Set mobjClass = obj
End Sub


Expand Down
7 changes: 1 addition & 6 deletions clsOpenAIRequest.cls
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ End Function


Private Function IOpenAINameProvider_ToString() As String
IOpenAINameProvider_ToString = "chat json=" & Me.GetChatSendToAPIJsonString & " | " & "text json=" & Me.GetTextCompletionSendToAPIJsonString
IOpenAINameProvider_ToString = "chat json=" & Me.GetChatSendToAPIJsonString
End Function


Expand Down Expand Up @@ -172,11 +172,6 @@ Public Function GetChatSendToAPIJsonString() As String
End Function


Public Function GetTextCompletionSendToAPIJsonString() As String
GetTextCompletionSendToAPIJsonString = "{""model"": """ & mstrModel & """, ""prompt"": """ & mstrPrompt & """, ""max_tokens"": " & mlngMaxTokens & ", ""temperature"": " & mdblTemperature & "}"
End Function


Public Function GetDalleImageSendToAPIJsonString() As String
Dim strImageSize As String
strImageSize = Me.GetImageDimensionLabel()
Expand Down
218 changes: 44 additions & 174 deletions clsOpenAIResponse.cls
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Private mintIndex As Integer
Private mstrText As String
Private mstrLogprobs As String
Private mstrSavedFile As String

Private mstrJson As String

Private Function IOpenAINameProvider_GetClassName() As String
IOpenAINameProvider_GetClassName = "clsOpenAIResponse"
Expand All @@ -68,6 +68,10 @@ Private Function IOpenAINameProvider_ToString() As String
End Function


Public Property Get Json() As String
Json = mstrJson
End Property

Public Property Get Id() As String
Id = mstrId
End Property
Expand Down Expand Up @@ -132,8 +136,10 @@ Public Function IsExistSavedLocalFile() As Boolean
IsExistSavedLocalFile = IIf(Len(Dir(mstrSavedFile)) > 0, True, False)
End Function


Private Sub Class_Initialize()
' Initialize the variables
mstrJson = Empty
mstrId = Empty
mstrObject = Empty
mstrCreated = 0
Expand All @@ -152,183 +158,49 @@ End Sub


Public Sub ParseChatJSON(ByVal strJson As String)
'Purpose: This method is for parsing OpenAI's strJson response from it's Chat End point
' Purpose: This method is for parsing OpenAI's strJson response from its Chat Endpoint

'Allow for the full response to be accessed by downstream clients using the class
mstrJson = strJson

' Extract each property from the JSON string
mstrId = ExtractJsonValue(strJson, """id"": """, """")
mstrObject = ExtractJsonValue(strJson, """object"": """, """")
mstrCreated = CLng(ExtractJsonValue(strJson, """created"": ", ","))
mstrModel = ExtractJsonValue(strJson, """model"": """, """")
mintPromptTokens = CInt(ExtractJsonValue(strJson, """prompt_tokens"": ", ","))
mintCompletionTokens = CInt(ExtractJsonValue(strJson, """completion_tokens"": ", ","))
mintTotalTokens = CInt(ExtractJsonValue(strJson, """total_tokens"": ", "}"))

' Extract the nested message information
Dim messageJson As String
messageJson = ExtractJsonValue(strJson, """message"": {", "}")
mstrMessageRole = ExtractJsonValue(messageJson, """role"": """, """")
mstrMessageContent = ExtractJsonValue(messageJson, """content"": """, """")
mstrMessageContent = Replace(mstrMessageContent, "\""", """") ' Replace escaped quotes with actual quotes
mstrFinishReason = ExtractJsonValue(strJson, """finish_reason"": """, """")
mintIndex = CInt(ExtractJsonValue(strJson, """index"": ", ","))

Dim intStartPos As Integer
Dim intEndPos As Integer
Dim strTemp As String

' Extract "id"
If InStr(1, strJson, """id"":""") > 0 Then
intStartPos = InStr(1, strJson, """id"":""") + Len("""id"":""")
intEndPos = InStr(intStartPos, strJson, """")
mstrId = Trim(Mid(strJson, intStartPos, intEndPos - intStartPos))
End If

' Extract "object"
If InStr(1, strJson, """object"":""") > 0 Then
intStartPos = InStr(1, strJson, """object"":""") + Len("""object"":""")
intEndPos = InStr(intStartPos, strJson, """")
mstrObject = Trim(Mid(strJson, intStartPos, intEndPos - intStartPos))
End If

' Extract "created"
If InStr(1, strJson, """created"":") > 0 Then
intStartPos = InStr(1, strJson, """created"":") + Len("""created"":")
intEndPos = InStr(intStartPos, strJson, ",")
mstrCreated = CLng(Trim(Mid(strJson, intStartPos, intEndPos - intStartPos)))
End If

' Extract "model"
If InStr(1, strJson, """model"":""") > 0 Then
intStartPos = InStr(1, strJson, """model"":""") + Len("""model"":""")
intEndPos = InStr(intStartPos, strJson, """")
mstrModel = Trim(Mid(strJson, intStartPos, intEndPos - intStartPos))
End If

' Extract "prompt_tokens"
If InStr(1, strJson, """prompt_tokens"":") > 0 Then
intStartPos = InStr(1, strJson, """prompt_tokens"":") + Len("""prompt_tokens"":")
intEndPos = InStr(intStartPos, strJson, ",")
mintPromptTokens = CInt(Trim(Mid(strJson, intStartPos, intEndPos - intStartPos)))
End If

' Extract "completion_tokens"
If InStr(1, strJson, """completion_tokens"":") > 0 Then
intStartPos = InStr(1, strJson, """completion_tokens"":") + Len("""completion_tokens"":")
intEndPos = InStr(intStartPos, strJson, ",")
mintCompletionTokens = CInt(Trim(Mid(strJson, intStartPos, intEndPos - intStartPos)))
End If

' Extract "total_tokens"
If InStr(1, strJson, """total_tokens"":") > 0 Then
intStartPos = InStr(1, strJson, """total_tokens"":") + Len("""total_tokens"":")
intEndPos = InStr(intStartPos, strJson, "}")
mintTotalTokens = CInt(Trim(Mid(strJson, intStartPos, intEndPos - intStartPos)))
End If

' Extract "message_role"
If InStr(1, strJson, """role"":""") > 0 Then
intStartPos = InStr(1, strJson, """role"":""") + Len("""role"":""")
intEndPos = InStr(intStartPos, strJson, """")
mstrMessageRole = Trim(Mid(strJson, intStartPos, intEndPos - intStartPos))
End If

' Extract "message_content"
If InStr(1, strJson, """content"":""") > 0 Then
intStartPos = InStr(1, strJson, """content"":""") + Len("""content"":""")
intEndPos = InStr(intStartPos, strJson, """},") ' end position is now before "}," sequence
strTemp = Mid(strJson, intStartPos, intEndPos - intStartPos)
strTemp = Replace(strTemp, "\""", """") ' Replace escaped quotes with actual quotes
mstrMessageContent = Trim(strTemp)
End If


' Extract "finish_reason"
If InStr(1, strJson, """finish_reason"":""") > 0 Then
intStartPos = InStr(1, strJson, """finish_reason"":""") + Len("""finish_reason"":""")
intEndPos = InStr(intStartPos, strJson, """")
mstrFinishReason = Trim(Mid(strJson, intStartPos, intEndPos - intStartPos))
End If

' Extract "index"
If InStr(1, strJson, """index"":") > 0 Then
intStartPos = InStr(1, strJson, """index"":") + Len("""index"":")
intEndPos = InStr(intStartPos, strJson, "}")
mintIndex = CInt(Trim(Mid(strJson, intStartPos, intEndPos - intStartPos)))
End If
End Sub


Public Sub ParseTextCompletionJSON(ByVal strJson As String)
'Purpose: This method is for parsing OpenAI's strJson from it's text completion end point
Private Function ExtractJsonValue(ByVal Json As String, ByVal key As String, ByVal delimiter As String) As String
' Find the start position of the key
Dim startPos As Integer
startPos = InStr(Json, key)
If startPos = 0 Then Exit Function

Dim intStartPos As Integer
Dim intEndPos As Integer
Dim strTemp As String

' Extract "id"
If InStr(1, strJson, """id"":""") > 0 Then
intStartPos = InStr(1, strJson, """id"":""") + Len("""id"":""")
intEndPos = InStr(intStartPos, strJson, """")
mstrId = Trim(Mid(strJson, intStartPos, intEndPos - intStartPos))
End If

' Extract "object"
If InStr(1, strJson, """object"":""") > 0 Then
intStartPos = InStr(1, strJson, """object"":""") + Len("""object"":""")
intEndPos = InStr(intStartPos, strJson, """")
mstrObject = Trim(Mid(strJson, intStartPos, intEndPos - intStartPos))
End If

' Extract "created"
If InStr(1, strJson, """created"":") > 0 Then
intStartPos = InStr(1, strJson, """created"":") + Len("""created"":")
intEndPos = InStr(intStartPos, strJson, ",")
mstrCreated = CLng(Trim(Mid(strJson, intStartPos, intEndPos - intStartPos)))
End If

' Extract "model"
If InStr(1, strJson, """model"":""") > 0 Then
intStartPos = InStr(1, strJson, """model"":""") + Len("""model"":""")
intEndPos = InStr(intStartPos, strJson, """")
mstrModel = Trim(Mid(strJson, intStartPos, intEndPos - intStartPos))
End If

' Extract "prompt_tokens"
If InStr(1, strJson, """prompt_tokens"":") > 0 Then
intStartPos = InStr(1, strJson, """prompt_tokens"":") + Len("""prompt_tokens"":")
intEndPos = InStr(intStartPos, strJson, ",")
mintPromptTokens = CInt(Trim(Mid(strJson, intStartPos, intEndPos - intStartPos)))
End If

' Extract "completion_tokens"
If InStr(1, strJson, """completion_tokens"":") > 0 Then
intStartPos = InStr(1, strJson, """completion_tokens"":") + Len("""completion_tokens"":")
intEndPos = InStr(intStartPos, strJson, ",")
mintCompletionTokens = CInt(Trim(Mid(strJson, intStartPos, intEndPos - intStartPos)))
End If

' Extract "total_tokens"
If InStr(1, strJson, """total_tokens"":") > 0 Then
intStartPos = InStr(1, strJson, """total_tokens"":") + Len("""total_tokens"":")
intEndPos = InStr(intStartPos, strJson, "}")
mintTotalTokens = CInt(Trim(Mid(strJson, intStartPos, intEndPos - intStartPos)))
End If

' Extract "text"
If InStr(1, strJson, """text"":""") > 0 Then
intStartPos = InStr(1, strJson, """text"":""") + Len("""text"":""")
intEndPos = InStr(intStartPos, strJson, """,""") ' end position is now before the sequence ","
strTemp = Mid(strJson, intStartPos, intEndPos - intStartPos)
strTemp = Replace(strTemp, "\""", """") ' Replace escaped quotes with actual quotes
mstrText = Trim(strTemp)
End If

' Extract "logprobs"
If InStr(1, strJson, """logprobs"":") > 0 Then
intStartPos = InStr(1, strJson, """logprobs"":") + Len("""logprobs"":")
intEndPos = InStr(intStartPos, strJson, ",") ' end position is now before the sequence ","
strTemp = Mid(strJson, intStartPos, intEndPos - intStartPos)
strTemp = Replace(strTemp, "\""", """") ' Replace escaped quotes with actual quotes
mstrLogprobs = Trim(strTemp)
End If
' Adjust start position to start of the value
startPos = startPos + Len(key)


' Extract "finish_reason"
If InStr(1, strJson, """finish_reason"":""") > 0 Then
intStartPos = InStr(1, strJson, """finish_reason"":""") + Len("""finish_reason"":""")
intEndPos = InStr(intStartPos, strJson, """")
mstrFinishReason = Trim(Mid(strJson, intStartPos, intEndPos - intStartPos))
End If

' Extract "index"
If InStr(1, strJson, """index"":") > 0 Then
intStartPos = InStr(1, strJson, """index"":") + Len("""index"":")
intEndPos = InStr(intStartPos, strJson, ",")
mintIndex = CInt(Trim(Mid(strJson, intStartPos, intEndPos - intStartPos)))
End If
End Sub
' Find the end position of the value
Dim endPos As Integer
endPos = InStr(startPos, Json, delimiter)
If endPos = 0 Then Exit Function

' Extract the value
ExtractJsonValue = Mid(Json, startPos, endPos - startPos)
End Function


Public Function GetFileNameFromImageURL(ByVal strImageUrl As String)
Expand Down Expand Up @@ -381,5 +253,3 @@ Public Function GetImageURLFromImageCreationJSON(ByVal strResponseJson As String

End Function



Loading

0 comments on commit 1f706c9

Please sign in to comment.