You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
9.2 KiB
215 lines
9.2 KiB
import Flutter
|
|
import UIKit
|
|
|
|
public class OpenAIServicePlugin: NSObject, FlutterPlugin, FlutterStreamHandler {
|
|
// OpenAI服务实例
|
|
private let openAIService = OpenAIService()
|
|
|
|
// 事件接收器
|
|
private var eventSink: FlutterEventSink?
|
|
|
|
// 注册插件
|
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
|
let methodChannel = FlutterMethodChannel(name: "com.yunqiinnovation.open_ai_service/methods", binaryMessenger: registrar.messenger())
|
|
let eventChannel = FlutterEventChannel(name: "com.yunqiinnovation.open_ai_service/events", binaryMessenger: registrar.messenger())
|
|
|
|
let instance = OpenAIServicePlugin()
|
|
registrar.addMethodCallDelegate(instance, channel: methodChannel)
|
|
eventChannel.setStreamHandler(instance)
|
|
}
|
|
|
|
// 处理方法调用
|
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
switch call.method {
|
|
case "initialize":
|
|
if let args = call.arguments as? [String: Any],
|
|
let apiKey = args["apiKey"] as? String {
|
|
let baseUrl = args["baseUrl"] as? String ?? ""
|
|
let model = args["model"] as? String ?? ""
|
|
let initialized = openAIService.initialize(apiKey: apiKey, baseUrl: baseUrl, model: model)
|
|
result(initialized)
|
|
} else {
|
|
result(FlutterError(code: "INVALID_ARGUMENT", message: "初始化参数无效", details: nil))
|
|
}
|
|
|
|
case "registerFunction":
|
|
if let args = call.arguments as? [String: Any],
|
|
let name = args["name"] as? String,
|
|
let description = args["description"] as? String,
|
|
let parameters = args["parameters"] as? [String: Any] {
|
|
|
|
let registered = openAIService.registerFunction(name: name, description: description, parameters: parameters)
|
|
result(registered)
|
|
} else {
|
|
result(FlutterError(code: "INVALID_ARGUMENT", message: "函数注册参数无效", details: nil))
|
|
}
|
|
|
|
case "sendMessage":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let messagesRaw = args["messages"] as? [[String: Any]],
|
|
let systemPrompt = args["systemPrompt"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGUMENT", message: "发送消息参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
// 在后台线程执行
|
|
DispatchQueue.global(qos: .userInitiated).async {
|
|
do {
|
|
let response = try self.openAIService.sendMessage(messages: messagesRaw, systemPrompt: systemPrompt)
|
|
// 在主线程返回结果
|
|
DispatchQueue.main.async {
|
|
result(response)
|
|
}
|
|
} catch {
|
|
// 在主线程返回错误
|
|
DispatchQueue.main.async {
|
|
result(FlutterError(code: "OPENAI_ERROR", message: error.localizedDescription, details: nil))
|
|
}
|
|
}
|
|
}
|
|
|
|
case "sendMessageStream":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let messagesRaw = args["messages"] as? [[String: Any]],
|
|
let systemPrompt = args["systemPrompt"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGUMENT", message: "发送消息参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
// 检查事件接收器
|
|
guard let eventSink = self.eventSink else {
|
|
result(FlutterError(code: "NO_EVENT_SINK", message: "没有可用的事件流接收器", details: nil))
|
|
return
|
|
}
|
|
|
|
// 在后台线程执行
|
|
DispatchQueue.global(qos: .userInitiated).async {
|
|
let callback: OpenAIService.StreamCallback = (
|
|
onToken: { token in
|
|
// 发送token事件
|
|
DispatchQueue.main.async {
|
|
eventSink(["type": "token", "content": token])
|
|
}
|
|
},
|
|
onComplete: {
|
|
// 发送完成事件
|
|
DispatchQueue.main.async {
|
|
eventSink(["type": "complete"])
|
|
}
|
|
},
|
|
onError: { error in
|
|
// 发送错误事件
|
|
DispatchQueue.main.async {
|
|
eventSink(["type": "error", "content": error.localizedDescription])
|
|
}
|
|
},
|
|
onFunctionCall: { functionCall in
|
|
// 发送函数调用事件
|
|
DispatchQueue.main.async {
|
|
eventSink(["type": "functionCall", "content": functionCall])
|
|
}
|
|
}
|
|
)
|
|
|
|
self.openAIService.sendMessageStream(messages: messagesRaw, systemPrompt: systemPrompt, callback: callback)
|
|
|
|
// 请求已开始
|
|
DispatchQueue.main.async {
|
|
result(true)
|
|
}
|
|
}
|
|
|
|
case "sendFunctionCallResult":
|
|
guard let args = call.arguments as? [String: Any],
|
|
let messagesRaw = args["messages"] as? [[String: Any]],
|
|
let systemPrompt = args["systemPrompt"] as? String,
|
|
let functionCallRaw = args["functionCall"] as? [String: Any],
|
|
let functionResult = args["functionResult"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGUMENT", message: "发送函数调用结果参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
// 检查事件接收器
|
|
guard let eventSink = self.eventSink else {
|
|
result(FlutterError(code: "NO_EVENT_SINK", message: "没有可用的事件流接收器", details: nil))
|
|
return
|
|
}
|
|
|
|
// 在后台线程执行
|
|
DispatchQueue.global(qos: .userInitiated).async {
|
|
let callback: OpenAIService.StreamCallback = (
|
|
onToken: { token in
|
|
// 发送token事件
|
|
DispatchQueue.main.async {
|
|
eventSink(["type": "token", "content": token])
|
|
}
|
|
},
|
|
onComplete: {
|
|
// 发送完成事件
|
|
DispatchQueue.main.async {
|
|
eventSink(["type": "complete"])
|
|
}
|
|
},
|
|
onError: { error in
|
|
// 发送错误事件
|
|
DispatchQueue.main.async {
|
|
eventSink(["type": "error", "content": error.localizedDescription])
|
|
}
|
|
},
|
|
onFunctionCall: { functionCall in
|
|
// 发送函数调用事件
|
|
DispatchQueue.main.async {
|
|
eventSink(["type": "functionCall", "content": functionCall])
|
|
}
|
|
}
|
|
)
|
|
|
|
self.openAIService.sendFunctionCallResult(
|
|
messages: messagesRaw,
|
|
systemPrompt: systemPrompt,
|
|
functionCall: functionCallRaw,
|
|
functionResult: functionResult,
|
|
callback: callback
|
|
)
|
|
|
|
// 请求已开始
|
|
DispatchQueue.main.async {
|
|
result(true)
|
|
}
|
|
}
|
|
|
|
case "createUserMessage":
|
|
if let args = call.arguments as? [String: Any],
|
|
let content = args["content"] as? String {
|
|
let message = openAIService.createUserMessage(content: content)
|
|
result(message)
|
|
} else {
|
|
result(FlutterError(code: "INVALID_ARGUMENT", message: "创建用户消息参数无效", details: nil))
|
|
}
|
|
|
|
case "createAssistantMessage":
|
|
if let args = call.arguments as? [String: Any],
|
|
let content = args["content"] as? String {
|
|
let message = openAIService.createAssistantMessage(content: content)
|
|
result(message)
|
|
} else {
|
|
result(FlutterError(code: "INVALID_ARGUMENT", message: "创建助手消息参数无效", details: nil))
|
|
}
|
|
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
|
|
// MARK: - FlutterStreamHandler
|
|
|
|
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
|
self.eventSink = events
|
|
return nil
|
|
}
|
|
|
|
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
|
self.eventSink = nil
|
|
return nil
|
|
}
|
|
}
|