Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sendChat is failing because ChatMessage has extra property #100

Open
ktorimaru opened this issue Jul 15, 2023 · 12 comments · May be fixed by #107
Open

sendChat is failing because ChatMessage has extra property #100

ktorimaru opened this issue Jul 15, 2023 · 12 comments · May be fixed by #107

Comments

@ktorimaru
Copy link

Getting the following when submitting a "sendChat"
▿ OpenAIError
▿ chatError : 1 element
▿ error : Payload

  • message : "Additional properties are not allowed ('id' was unexpected) - 'messages.0'"
  • type : "invalid_request_error"
  • param : nil
  • code : nil

It looks like OpenAI is throwing an error because of the extra field.

Removing the Identifiable protocol and the id variable allows everything to run.

`/// A structure that represents a single message in a chat conversation.

public struct ChatMessage: Codable {
/// The role of the sender of the message.
public let role: ChatRole?
/// The content of the message.
public let content: String?
...
`

@rxrw
Copy link

rxrw commented Jul 16, 2023

I got this error, too.
It's may produced by: #94

@rom4in
Copy link
Contributor

rom4in commented Jul 16, 2023

add this extension instead:

import OpenAISwift
import Foundation

extension ChatMessage: Identifiable, Equatable {
public var id: UUID {
return UUID()
}
public func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
public static func == (lhs: ChatMessage, rhs: ChatMessage) -> Bool {
return lhs.id == rhs.id
}
}

@MarkHoath
Copy link

Confirmed this fixes the error... I dont know if it fixes the Swift Identifciable issue as I dont use SwiftUI

@Mmanion
Copy link

Mmanion commented Jul 30, 2023

I'm using SwiftUI, and it doesn't seems to solve the problem.

Created a PR to remove it. #106

Definitely like the idea of ChatMessages being Identifiable. If I have the time, will see how to implement it while preventing this bug.

@MarkHoath
Copy link

All your PR does is rollback to the previous version. Is the extension provided by rom4in not working ? As from the documentation it appears that it should.

In Swift, extension properties do not have to comply with Codable directly. Codable is a protocol used for encoding and decoding Swift types to and from external representations like JSON or Plist.

When you conform a type to Codable, you are essentially telling Swift how to convert an instance of that type to and from a JSON representation. The properties that are encoded and decoded must themselves be Codable.

If you extend a type with additional properties through an extension, those extension properties are not automatically considered when encoding or decoding using Codable. Only the properties declared in the original type or any extensions that directly implement Codable will be considered.

@Mmanion
Copy link

Mmanion commented Jul 31, 2023

No, the extension by rom4in did not work for SwiftUI.
Yes, it is a rollback.

Not sure which part of the documentation you're referring to but definitely give this a try in SwiftUI (with the solutions mentioned above) and you'll see.

marcoboerner added a commit to marcoboerner/OpenAISwift that referenced this issue Jul 31, 2023
Fixes adamrushy#100 `sendChat is failing because ChatMessage has extra property`
@marcoboerner
Copy link

marcoboerner commented Jul 31, 2023

I created a pull request that keeps the id and Identifiable conformance in place, which I think is preferable when using it with SwiftUI, but skips the id when encoding. Hashable and equatable conformance can then be done with a similar extension as above if needed.

extension ChatMessage: Hashable {
    public static func == (lhs: ChatMessage, rhs: ChatMessage) -> Bool {
        lhs.id == rhs.id &&
        lhs.content == rhs.content
    }
    public func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

@Mmanion maybe you'd prefer this over a rollback 🙃

@Mmanion
Copy link

Mmanion commented Jul 31, 2023

@marcoboerner Yup, thats a much better fix then mine. I ran it in SwiftUI and it works, just closed my PR. Great job!

@marcoboerner
Copy link

The only thing that you need to be aware of when streaming is, currently with every updated ChatMessage a new UUID is generated. It's fine if you're just replacing the last ChatMessage of an array with the updated ChatMessage, but if you try to work with a set or try to use the id to find the ChatMessage that is being updated, that won't work. But I think that's rather an implementation detail in the stream logic.

@tingspain
Copy link

It is not working for me. I dont know what i am doing wrong. I keep getting the following error:

chatError(error: OpenAISwift.ChatError.Payload(message: "Additional properties are not allowed (\'id\' was unexpected) - \'messages.0\'", type: "invalid_request_error", param: nil, code: nil))

Could anyone point me on the right way to do it?

This is my code:

extension ChatMessage: Identifiable, Equatable, Hashable {
    
    public var id: UUID {
        return UUID()
    }
    public func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    public static func == (lhs: ChatMessage, rhs: ChatMessage) -> Bool {
        lhs.id == rhs.id &&
        lhs.content == rhs.content
    }

}

    
class OpenAIChat : ObservableObject{
   
    let openAI = OpenAISwift(config: .makeDefaultOpenAI(apiKey: "sk-"))
    
    var message: String = ""
    
    func send(question: String = "Hello, how are you?") async {
        
        print("Before send")
        print("QUESTION: \(question)")
        
        do {

            let chat: [ChatMessage] = [
                ChatMessage(role: .system, content: "You are a helpful assistant."),
                ChatMessage(role: .user, content: "Who won the world series in 2020?")
            ]
                        
            let result = try await openAI.sendChat(
                                                with: chat,
                                                model: .chat(.chatgpt),
                                                choices: 1,
                                                maxTokens: 256
                                                )

            print("RESULT: ")
            print( result )
                  
        } catch {
           print(error)
        }
        
        print("After send")
    }
    
}

@marcoboerner
Copy link

@tingspain are you using the last pre-release version? The PRs to fix this issue have not been released. You may want to switch to an earlier version or use the branch of the PR with the last main commit.

@tingspain
Copy link

@marcoboerner, ah. Let me switch to the PR and test it. Thank you very much!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
7 participants