Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/PreternaturalAI/AI into ENG…
Browse files Browse the repository at this point in the history
…-1490
  • Loading branch information
pmanot committed Dec 5, 2024
2 parents a050529 + baaee74 commit 7603d7c
Show file tree
Hide file tree
Showing 25 changed files with 404 additions and 331 deletions.
14 changes: 7 additions & 7 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"originHash" : "864ef9201dffd6ebf57da3ab4413cc1001edb70cd0c6d264b91e19b3967fb7ba",
"originHash" : "83853ba40d0163bfd6b0d04a734383c75479cd9c8a0fc3cc071250b3e5259dc4",
"pins" : [
{
"identity" : "corepersistence",
"kind" : "remoteSourceControl",
"location" : "https://github.com/vmanot/CorePersistence.git",
"state" : {
"branch" : "main",
"revision" : "38fd5271fa906a2d8395e4b42724142886a3c763"
"revision" : "302f6123b17047b5ea8f91b06b7440370ff13d9f"
}
},
{
Expand All @@ -16,7 +16,7 @@
"location" : "https://github.com/vmanot/Merge.git",
"state" : {
"branch" : "master",
"revision" : "e8bc37c8dc203cab481efedd71237c151882c007"
"revision" : "e06fe31d67b5b2addb49d896437aade25323ef69"
}
},
{
Expand All @@ -34,7 +34,7 @@
"location" : "https://github.com/vmanot/Swallow.git",
"state" : {
"branch" : "master",
"revision" : "6227a1114e341daf54e90df61e173599b187a9b1"
"revision" : "e1831bd9e9f9392be901c6fffee8e236a91ba044"
}
},
{
Expand All @@ -51,8 +51,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
"revision" : "2bc86522d115234d1f588efe2bcb4ce4be8f8b82",
"version" : "510.0.3"
"revision" : "0687f71944021d616d34d922343dcef086855920",
"version" : "600.0.1"
}
},
{
Expand All @@ -70,7 +70,7 @@
"location" : "https://github.com/SwiftUIX/SwiftUIX.git",
"state" : {
"branch" : "master",
"revision" : "836fc284a9bb07fc9ab6d2dce6ebd0e32aabde26"
"revision" : "a68663989c8aaae013c4104c6a4aa2f35afe1000"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ extension AbstractLLM.ChatFunctionCall: AbstractLLM.ChatCompletionDecodable {
}
}

extension AbstractLLM.ChatMessage: AbstractLLM.ChatCompletionDecodable {
public static func decode(
_ type: Self.Type,
from completion: AbstractLLM.ChatCompletion
) async throws -> Self {
completion.message
}

public static func decode(
_ type: Array<Self>.Type,
from completion: AbstractLLM.ChatCompletion
) async throws -> Array<Self> {
[completion.message]
}
}

extension AbstractLLM.ResultOfFunctionCall: AbstractLLM.ChatCompletionDecodable {
public static func decode(
_ type: Self.Type,
Expand Down Expand Up @@ -111,6 +127,30 @@ extension SwiftUIX._AnyImage: AbstractLLM.ChatCompletionDecodable {
}
}

extension Either: AbstractLLM.ChatCompletionDecodable where LeftValue: AbstractLLM.ChatCompletionDecodable, RightValue: AbstractLLM.ChatCompletionDecodable {
public static func decode(
_ type: Self.Type,
from completion: AbstractLLM.ChatCompletion
) async throws -> Self {
do {
return try await .left(LeftValue.decode(LeftValue.self, from: completion))
} catch {
return try await .right(RightValue.decode(RightValue.self, from: completion))
}
}

public static func decode(
_ type: Array<Self>.Type,
from completion: AbstractLLM.ChatCompletion
) async throws -> Array<Self> {
do {
return try await LeftValue.decode([LeftValue].self, from: completion).map({ Self.left($0) })
} catch {
return try await RightValue.decode([RightValue].self, from: completion).map({ Self.right($0) })
}
}
}

extension Array: AbstractLLM.ChatCompletionDecodable where Element: AbstractLLM.ChatCompletionDecodable {
@MainActor
public static func decode(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// Copyright (c) Vatsal Manot
//

import Swallow
import SwiftUIX

extension AbstractLLM {
// Specify the expected result type for strongly-typed results. For example, if you're executing a chat completion, the expected result will be a `.string` type.
public struct ChatCompletionDecodableResultType<T: AbstractLLM.ChatCompletionDecodable> {
fileprivate init() {

}
}
}

extension AbstractLLM.ChatCompletionDecodableResultType where T == String {
public static var string: Self {
.init()
}
}

extension AbstractLLM.ChatCompletionDecodableResultType where T == SwiftUIX._AnyImage {
public static var image: Self {
.init()
}
}

extension AbstractLLM.ChatCompletionDecodableResultType where T == AbstractLLM.ChatMessage {
public static var chatMessage: Self {
.init()
}
}

extension AbstractLLM.ChatCompletionDecodableResultType where T == AbstractLLM.ChatFunctionCall {
public static var functionCall: Self {
.init()
}
}

extension AbstractLLM.ChatCompletionDecodableResultType where T == Array<AbstractLLM.ChatFunctionCall> {
public static var functionCalls: Self {
.init()
}
}

extension AbstractLLM.ChatCompletionDecodableResultType where T == AbstractLLM.ResultOfFunctionCall {
public static var functionInvocation: Self {
.init()
}
}

extension AbstractLLM.ChatCompletionDecodableResultType where T == Array<AbstractLLM.ResultOfFunctionCall> {
public static var functionInvocations: Self {
.init()
}
}

extension AbstractLLM.ChatCompletionDecodableResultType {
public static func either<LHS: AbstractLLM.ChatCompletionDecodable, RHS: AbstractLLM.ChatCompletionDecodable>(
_ lhs: AbstractLLM.ChatCompletionDecodableResultType<LHS>,
or rhs: AbstractLLM.ChatCompletionDecodableResultType<RHS>
) -> Self where Self == AbstractLLM.ChatCompletionDecodableResultType<Either<LHS, RHS>> {
.init()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
//
// Copyright (c) Vatsal Manot
//

import CorePersistence
import Swallow
import SwiftUIX

extension AbstractLLM.ChatMessage {
public init(
id: AnyPersistentIdentifier? = nil,
role: AbstractLLM.ChatRole,
content: String
) {
self.init(
id: id,
role: role,
content: PromptLiteral(stringLiteral: content)
)
}

public init(
id: UUID,
role: AbstractLLM.ChatRole,
content: String
) {
self.init(
id: AnyPersistentIdentifier(erasing: id),
role: role,
content: content
)
}
}

extension AbstractLLM.ChatMessage {
public static func system(
_ content: PromptLiteral
) -> Self {
Self(role: .system, content: content)
}

public static func system(
_ content: () throws -> PromptLiteral
) rethrows -> Self {
Self(role: .system, content: try content())
}

public static func system(
_ content: String
) -> Self {
Self(role: .system, content: content)
}

public static func system(
_ content: () throws -> String
) rethrows -> Self {
Self(role: .system, content: try content())
}
}

extension AbstractLLM.ChatMessage {
public static func assistant(
_ content: PromptLiteral
) -> Self {
Self(role: .assistant, content: content)
}

public static func assistant(
_ content: () throws -> PromptLiteral
) rethrows -> Self {
Self(role: .assistant, content: try content())
}

public static func assistant(
_ content: String
) -> Self {
Self(role: .assistant, content: content)
}

public static func assistant(
_ content: () throws -> String
) rethrows -> Self {
Self(role: .assistant, content: try content())
}

/// A function call.
public static func functionCall(
_ functionCall: AbstractLLM.ChatFunctionCall
) -> Self {
Self(role: .assistant, content: try! PromptLiteral(functionCall: functionCall))
}

/// The function call of a given function, with its arguments expressed as JSON.
public static func functionCall(
of function: AbstractLLM.ChatFunctionDefinition,
arguments: JSON
) -> Self {
Self(
role: .assistant,
content: try! PromptLiteral(
functionCall: AbstractLLM.ChatFunctionCall(
functionID: nil, // FIXME: !!!
name: function.name,
arguments: .init(unencoded: arguments.prettyPrintedDescription),
context: .init()
)
)
)
}

/// A function invocation is a function call + the result.
///
/// Conceptually, this represents the function call as the LLM would invoke it _including_ the function's result.
///
/// You can construct it manually as part of few-shot prompting to guide the LLM on how to call your function.
///
/// This is **not** the same thing as just a 'function call'. A function call is **only** the function name + the parameters that the LLM generates to invoke it, _without_ the actual result of the function.
public static func functionInvocation(
_ functionInvocation: AbstractLLM.ResultOfFunctionCall
) -> Self {
Self(
role: .other(.function),
content: try! PromptLiteral(
functionInvocation: functionInvocation,
role: .chat(.other(.function))
)
)
}
}

extension AbstractLLM.ChatMessage {
public static func user(
_ content: PromptLiteral
) -> Self {
Self(role: .user, content: content)
}

public static func user(
_ content: AppKitOrUIKitImage
) -> Self {
Self(role: .user, content: try! PromptLiteral(image: content))
}

public static func user(
_ content: () throws -> PromptLiteral
) rethrows -> Self {
Self(role: .user, content: try content())
}

public static func user(
_ content: String
) -> Self {
Self(role: .user, content: content)
}

public static func user(
_ content: () throws -> String
) rethrows -> Self {
Self(role: .user, content: try content())
}
}
Loading

0 comments on commit 7603d7c

Please sign in to comment.