OpenAI
OpenAI copied to clipboard
feat: Assistants API Beta Implemented
What
Eight new API endpoints are exposed in the APIPath to support the assistants API.
Thanks again to @bwhtmnv for his contribution to my fork assistants API PR. Functions are now supported upon assistant creation and when interacting with thread messages! All the credit goes to him for implementing the new Tool parameters for assistants and RunToolOutputsQuery for making functions useful within assistant threads.
static let assistants = "/v1/assistants"
static let assistantsModify = "/v1/assistants/ASST_ID"
static let threads = "/v1/threads"
static let runs = "/v1/threads/THREAD_ID/runs"
static let runRetrieve = "/v1/threads/THREAD_ID/runs/RUN_ID"
static let runRetrieveSteps = "/v1/threads/THREAD_ID/runs/RUN_ID/steps"
static let threadsMessages = "/v1/threads/THREAD_ID/messages"
static let files = "/v1/files"
The OpenAIProtocol
is modified as follows: added
func assistants(query: AssistantsQuery?, method: String, completion: @escaping (Result<AssistantsResult, Error>) -> Void)
func threads(query: ThreadsQuery, completion: @escaping (Result<ThreadsResult, Error>) -> Void)
func runs(threadId: String, query: RunsQuery, completion: @escaping (Result<RunsResult, Error>) -> Void)
func runRetrieve(threadId: String, runId:String, completion: @escaping (Result<RunRetreiveResult, Error>) -> Void)
func runRetrieveSteps(threadId: String, runId: String, before: String?, completion: @escaping (Result<RunRetreiveStepsResult, Error>) -> Void)
func threadsMessages(threadId: String, before: String?, completion: @escaping (Result<ThreadsMessagesResult, Error>) -> Void)
func threadsAddMessage(threadId: String, query: ThreadAddMessageQuery, completion: @escaping (Result<ThreadAddMessageResult, Error>) -> Void)
func files(query: FilesQuery, completion: @escaping (Result<FilesResult, Error>) -> Void)
Assistants:
-
[X] Create
-
[x] Modify
-
[x] Attach files of all supported OpenAI types to Assistants on creation or modify.
-
[X] List assistants
- [x] Paging through assistants list
Tools can be passed to assistant creation/modify.
- [X] Code Interpreter
- [X] Retrieval
- [x] Functions
Threads/Runs
- [X] Create Thread
- [X] Create Run
- [X] Retrieve Run
- [X] Add Message to Thread
- [X] Retrieve Threads Messages
- [X] Retrieve Run Steps
Files
- [X] Upload
Example App:
A new demonstration of the assistants API and its requirements of the polling has been added to the Demo app.
-
Now you can create a new assistant on the Chats tab by selecting "+" -> New Assistant -> Fill in details -> OK. This should result in a "New Assistant" row being added to the chats, you can chat with your newly created assistant in this conversation.
-
You can now list your OpenAI API Assistants on the "Assistants" tab. Select "+" -> Get Assistants to load the assistants list.
-
For now I've implemented additional chat messages that are shown when run steps include tool calls such as code interpreter or retrieval.
Why
To support the assistant features like threads, runs, tools (such as code_interpreter and retrieval), and files with assistants API.
Affected Areas
OpenAI
Quality Gate passed
The SonarCloud Quality Gate passed, but some issues were introduced.
55 New issues
0 Security Hotspots
No data about Coverage
2.2% Duplication on New Code
Looking forward for this PR to be merged. 👁️
Just what I need!
thanks @cdillard for doing this. Please review it and get it merged guys
Quality Gate passed
Issues
70 New issues
Measures
0 Security Hotspots
No data about Coverage
1.7% Duplication on New Code
Thanks to bwhtmn and his AWESOME contribution here.
Functions are now supported!
Thanks again to @bwhtmn for adding this on my fork. All the credit goes to him for implementing the new Tool parameters for assistants and RunToolOutputsQuery for making functions useful within assistant threads.
@cdillard have you been looking at the new Assistants Streaming functionality? Any plans to add? Thanks for the stellar work on adding this functionality for Assistants!
@cdillard @bwhtmn , how can we fetch arguments from a function call response?
@cdillard @bwhtmn , how can we fetch arguments from a function call response?
@alelordelo here's an example, assuming that you have started a run with threadRun(query:)
:
let run = try await openAI.runRetrieve(threadId: threadId, runId: runId)
switch run.status {
case .requiresAction:
guard let toolCalls = run.requiredAction?.submitToolOutputs.toolCalls else {
break
}
for toolCall in toolCalls where toolCall.type == "function" {
// Arguments can be accessed like this as a string and parsed into JSON as needed.
let arguments = toolCall.function.arguments
}
default:
break
}
thank @cdillard!
I was hoping to access it in ChatBubble like:
case .tool:
let arguments = tool.function.arguments
The issue is that case .tool is actually incorrect, it doesn't represent a tool response (either in Assistant or Completion API)....
switch message.role {
case .assistant:
Text(message.content)
.padding(.horizontal, 16)
.padding(.vertical, 12)
.background(assistantBackgroundColor)
.clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
Spacer(minLength: 24)
case .user:
Spacer(minLength: 24)
Text(message.content)
.padding(.horizontal, 16)
.padding(.vertical, 12)
.foregroundColor(userForegroundColor)
.background(userBackgroundColor)
.clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
case .tool:
//fetch tool arguments here
Text(message.content)
.font(.footnote.monospaced())
.padding(.horizontal, 16)
.padding(.vertical, 12)
.background(.green)
.clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous))
Spacer(minLength: 24)
case .system:
EmptyView()
}
As for your suggestion, the run doesn't seem to be accessible on DetailView, and its not clear how the thread was created and how we could access in DetailView?
Maybe would make sense to create a AssistantDetailView?
let run = try await openAI.runRetrieve(threadId: threadId, runId: runId)
switch run.status {
case .requiresAction:
guard let toolCalls = run.requiredAction?.submitToolOutputs.toolCalls else {
break
}
for toolCall in toolCalls where toolCall.type == "function" {
// Arguments can be accessed like this as a string and parsed into JSON as needed.
let arguments = toolCall.function.arguments
}
default:
break
}