waveterm/pkg/waveai/waveai.go

97 lines
3.3 KiB
Go
Raw Normal View History

// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package waveai
import (
"context"
"log"
"time"
"github.com/wavetermdev/waveterm/pkg/telemetry"
2024-09-05 23:25:45 +02:00
"github.com/wavetermdev/waveterm/pkg/wshrpc"
)
const OpenAIPacketStr = "openai"
const OpenAICloudReqStr = "openai-cloudreq"
const PacketEOFStr = "EOF"
2024-10-09 22:36:02 +02:00
const DefaultAzureAPIVersion = "2023-05-15"
2024-11-12 02:11:09 +01:00
const ApiType_Anthropic = "anthropic"
const ApiType_Perplexity = "perplexity"
type OpenAICmdInfoPacketOutputType struct {
Model string `json:"model,omitempty"`
Created int64 `json:"created,omitempty"`
FinishReason string `json:"finish_reason,omitempty"`
Message string `json:"message,omitempty"`
Error string `json:"error,omitempty"`
}
func MakeOpenAIPacket() *wshrpc.OpenAIPacketType {
return &wshrpc.OpenAIPacketType{Type: OpenAIPacketStr}
}
type OpenAICmdInfoChatMessage struct {
MessageID int `json:"messageid"`
IsAssistantResponse bool `json:"isassistantresponse,omitempty"`
AssistantResponse *OpenAICmdInfoPacketOutputType `json:"assistantresponse,omitempty"`
UserQuery string `json:"userquery,omitempty"`
UserEngineeredQuery string `json:"userengineeredquery,omitempty"`
}
type AIBackend interface {
StreamCompletion(
ctx context.Context,
request wshrpc.OpenAiStreamRequest,
) chan wshrpc.RespOrErrorUnion[wshrpc.OpenAIPacketType]
}
2024-10-09 22:36:02 +02:00
const DefaultMaxTokens = 2048
2024-08-28 21:05:29 +02:00
const DefaultModel = "gpt-4o-mini"
2024-10-09 22:36:02 +02:00
const WCloudWSEndpoint = "wss://wsapi.waveterm.dev/"
const WCloudWSEndpointVarName = "WCLOUD_WS_ENDPOINT"
const CloudWebsocketConnectTimeout = 1 * time.Minute
2024-10-09 22:36:02 +02:00
func IsCloudAIRequest(opts *wshrpc.OpenAIOptsType) bool {
if opts == nil {
return true
}
return opts.BaseURL == "" && opts.APIToken == ""
}
2024-08-09 03:24:54 +02:00
func makeAIError(err error) wshrpc.RespOrErrorUnion[wshrpc.OpenAIPacketType] {
return wshrpc.RespOrErrorUnion[wshrpc.OpenAIPacketType]{Error: err}
}
2024-10-09 22:36:02 +02:00
func RunAICommand(ctx context.Context, request wshrpc.OpenAiStreamRequest) chan wshrpc.RespOrErrorUnion[wshrpc.OpenAIPacketType] {
telemetry.GoUpdateActivityWrap(wshrpc.ActivityUpdate{NumAIReqs: 1}, "RunAICommand")
2024-11-12 02:11:09 +01:00
if request.Opts.APIType == ApiType_Anthropic {
endpoint := request.Opts.BaseURL
if endpoint == "" {
endpoint = "default"
}
log.Printf("sending ai chat message to anthropic endpoint %q using model %s\n", endpoint, request.Opts.Model)
anthropicBackend := AnthropicBackend{}
return anthropicBackend.StreamCompletion(ctx, request)
}
if request.Opts.APIType == ApiType_Perplexity {
endpoint := request.Opts.BaseURL
if endpoint == "" {
endpoint = "default"
}
log.Printf("sending ai chat message to perplexity endpoint %q using model %s\n", endpoint, request.Opts.Model)
perplexityBackend := PerplexityBackend{}
return perplexityBackend.StreamCompletion(ctx, request)
}
2024-10-09 22:36:02 +02:00
if IsCloudAIRequest(request.Opts) {
log.Print("sending ai chat message to default waveterm cloud endpoint\n")
cloudBackend := WaveAICloudBackend{}
return cloudBackend.StreamCompletion(ctx, request)
2024-10-09 22:36:02 +02:00
} else {
log.Printf("sending ai chat message to user-configured endpoint %s using model %s\n", request.Opts.BaseURL, request.Opts.Model)
openAIBackend := OpenAIBackend{}
return openAIBackend.StreamCompletion(ctx, request)
2024-10-09 22:36:02 +02:00
}
}