package echomeet import ( "context" "fmt" "yunyan/pb" "yunyan/sys/iflytek/openaichat" "yunyan/sys/iflytek/ost" ) // 科大讯飞 SparkChain 的两条服务端能力: // 转写用 SDK 里 RegionMSFT 的录音文件引擎(音频地址仍是客户端 OSS 公网 URL); // 总结用同一套凭据的海外文本模型,domain=openai(gpt-5.3-chat),不走星火。 type iflytekTranscriber struct { sys *ost.Client } func newIflytekTranscriber(f map[string]string) (Transcriber, error) { appID, err := need(f, "iflytek", "app_id") if err != nil { return nil, err } key, err := need(f, "iflytek", "api_key") if err != nil { return nil, err } secret, err := need(f, "iflytek", "api_secret") if err != nil { return nil, err } sys, err := ost.New(appID, key, secret, f["host"], f["task_type"]) if err != nil { return nil, err } return &iflytekTranscriber{sys: sys}, nil } func (this *iflytekTranscriber) Submit(_ context.Context, req SubmitRequest) (*SubmitResult, error) { taskID, err := this.sys.Create(req.AudioURL, req.EnableSpeaker, req.Language) if err != nil { return nil, err } return &SubmitResult{TaskID: taskID}, nil } func (this *iflytekTranscriber) Query(_ context.Context, taskID, _ string) (*QueryResult, error) { status, segs, err := this.sys.Query(taskID) switch status { case ost.StatusSuccess: out := make([]*pb.ContextStruct, 0, len(segs)) for _, s := range segs { out = append(out, &pb.ContextStruct{ Content: s.Text, Starttime: s.StartMs, Endtime: s.EndMs, Speaker: s.Speaker, }) } return &QueryResult{Status: StatusSuccess, Contexts: out}, nil case ost.StatusRunning: return &QueryResult{Status: StatusRunning}, nil default: if err == nil { err = fmt.Errorf("iflytek ost query failed") } return &QueryResult{Status: StatusFailed}, err } } type iflytekSummarizer struct { sys *openaichat.Client } func newIflytekSummarizer(f map[string]string) (Summarizer, error) { appID, err := need(f, "iflytek", "app_id") if err != nil { return nil, err } key, err := need(f, "iflytek", "api_key") if err != nil { return nil, err } secret, err := need(f, "iflytek", "api_secret") if err != nil { return nil, err } // 库里若还留着星火的 host/domain,New 会丢掉,改走 SDK 预置的 openai 地址和 gpt-5.3-chat。 sys, err := openaichat.New(appID, key, secret, f["host"], f["model"]) if err != nil { return nil, err } return &iflytekSummarizer{sys: sys}, nil } // iflytekSummaryDisplayName 生成弹窗里显示的模型名,跟真正发出去的模型一致。 func iflytekSummaryDisplayName(fields map[string]string) string { model := "" if fields != nil { model = fields["model"] } return openaichat.EffectiveModel(model) } func (this *iflytekSummarizer) Chat(_ context.Context, messages []ChatMessage) (string, error) { in := make([]openaichat.Message, 0, len(messages)) for _, m := range messages { in = append(in, openaichat.Message{Role: m.Role, Content: m.Content}) } return this.sys.Chat(in) }