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

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
}
}