Skip to content

Commit

Permalink
Experimental Claude3 support
Browse files Browse the repository at this point in the history
  • Loading branch information
kznrluk committed Mar 15, 2024
1 parent 8d2315a commit 413fe41
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 6 deletions.
5 changes: 5 additions & 0 deletions README-JA.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Go言語によるマルチプラットフォーム対応 & シングルバイナリ
- PowerShellやTerminalでの利用が可能
- GPT-4対応
- Claude3対応 (EXPERIMENTAL)
- 会話履歴の保存と復元
- 任意時点の会話へ移動
- GLOBによるファイル添付機能
Expand Down Expand Up @@ -45,6 +46,9 @@ $ aski
- `-f, --file` : 会話とともに送信するファイルを指定します。
- `-c, --content` : 対話モードを利用せず、引数のコンテンツの回答を出力してプログラムを終了します。他アプリケーションとの連携に便利です。
- `-r, --restore` : 会話履歴をヒストリファイルから復元します。このオプションを使用すると、以前の会話を続けることができます。前方一致。
- `-m, --model` : 使用するモデルを指定します。OpenAIのAPIで利用できる値である必要があります。
[Models - OpenAI API](https://platform.openai.com/docs/models/chatgpt)
Claude3を使用する場合は `claude-3-opus-20240229` を指定します。
- `--rest` : REST APIで通信します。ストリーミングが不安定な場合や、適切な応答が受信できない場合に便利です。
```

Expand Down Expand Up @@ -140,6 +144,7 @@ askiが利用するファイルは基本的にホームディレクトリ直下

```yaml
OpenAIAPIKey: sk-Bs.....................
AnthropicAPIKey: sk-.....................
CurrentProfile: gpt4.yaml
```
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
## Features
- It is written in Go, which allows for cross-platform compatibility on systems that support Go.
- Works in the shell, compatible with PowerShell and Terminal.
- Support for GPT-4 Turbo (Preview)
- Support for OpenAI GPT-4 Turbo
- Support for Anthropic Claude3Opus (EXPERIMENTAL)
- Save and restore conversation history
- Move to any point in the conversation
- File attachment with GLOB support
Expand Down Expand Up @@ -46,6 +47,9 @@ By default, it uses a generic profile, unless otherwise specified.
- `-f, --file` : Specifies a file to send with the conversation.
- `-c, --content` : Outputs the answer for the content of the argument without using the interactive mode and ends the program. Useful for integration with other applications.
- `-r, --restore` : Restores the conversation history from a history file. With this option, you can continue a previous conversation. Forward match.
- `-m, --model` : Specifies the model to use. It must be a valid value that can be used with the OpenAI API.
[Models - OpenAI API](https://platform.openai.com/docs/models/chatgpt)
If you want to use Claude3, specify `claude-3-opus-20240229`.
- `--rest` : Communicate with the REST API. Useful when streaming is unstable or appropriate responses cannot be received.
```

Expand Down Expand Up @@ -143,6 +147,7 @@ The configuration file includes the current profile and OpenAI API key. Profiles

```yaml
OpenAIAPIKey: sk-Bs.....................
AnthropicAPIKey: sk-.....................
CurrentProfile: gpt4.yaml
```
Expand Down
40 changes: 40 additions & 0 deletions chat/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/fatih/color"
"github.com/kznrluk/aski/config"
"github.com/kznrluk/aski/conv"
"github.com/kznrluk/go-anthropic"
"github.com/sashabaranov/go-openai"
"io"
"os"
Expand All @@ -18,13 +19,22 @@ func RetrieveResponse(isRestMode bool, cfg config.Config, conv conv.Conversation
cancelCtx, cancelFunc := createCancellableContext()
defer cancelFunc()

if isClaude(conv.GetProfile().Model) {
ac := anthropic.NewClient(cfg.AnthropicAPIKey)
return StreamClaudeExperimental(cancelCtx, ac, conv)
}

oc := openai.NewClient(cfg.OpenAIAPIKey)
if isRestMode {
return Rest(cancelCtx, oc, conv)
}
return Stream(cancelCtx, oc, conv)
}

func isClaude(model string) bool {
return model == string(anthropic.Claude3Opus20240229)
}

func GetSummary(cfg config.Config, conv conv.Conversation) string {
oc := openai.NewClient(cfg.OpenAIAPIKey)

Expand Down Expand Up @@ -176,3 +186,33 @@ func createCancellableContext() (context.Context, context.CancelFunc) {

return ctx, cancel
}

// this will be refactored in the future
func StreamClaudeExperimental(ctx context.Context, ac *anthropic.Client, conv conv.Conversation) (string, error) {
stream, err := ac.CreateMessageStream(anthropic.MessageRequest{
MaxTokens: 4096,
Model: anthropic.Claude3Opus20240229,
System: conv.GetProfile().SystemContext,
Messages: conv.ToAnthropicMessage(),
})

if err != nil {
return "", err
}

data := ""
for {
resp, err := stream.Recv()
if err != nil {
if err == io.EOF {
break
} else {
return "", err
}
}

fmt.Printf("%s", resp.Delta.Text)
data += resp.Delta.Text
}
return data, nil
}
10 changes: 6 additions & 4 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import (
)

type Config struct {
OpenAIAPIKey string `yaml:"OpenAIAPIKey"`
CurrentProfile string `yaml:"CurrentProfile"`
OpenAIAPIKey string `yaml:"OpenAIAPIKey"`
AnthropicAPIKey string `yaml:"AnthropicAPIKey"`
CurrentProfile string `yaml:"CurrentProfile"`

// Profiles is no longer being used.
// It will remain for a while so that the user's settings are not lost.
Expand All @@ -27,8 +28,9 @@ func InitialConfig() Config {
currentUser.Username = "aski"
}
return Config{
OpenAIAPIKey: "",
CurrentProfile: GetDefaultProfileFileName(),
OpenAIAPIKey: "",
AnthropicAPIKey: "",
CurrentProfile: GetDefaultProfileFileName(),
}
}

Expand Down
32 changes: 32 additions & 0 deletions conv/conversation.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/kznrluk/aski/config"
"github.com/kznrluk/aski/session"
"github.com/kznrluk/aski/util"
"github.com/kznrluk/go-anthropic"
"github.com/sashabaranov/go-openai"
"strings"
)
Expand All @@ -24,6 +25,7 @@ type (
SetProfile(profile config.Profile) error
Modify(m Message) error
ToChatCompletionMessage() []openai.ChatCompletionMessage
ToAnthropicMessage() []anthropic.Message
ChangeHead(sha string) (Message, error)
GetProfile() config.Profile
ToYAML() ([]byte, error)
Expand Down Expand Up @@ -199,6 +201,36 @@ func (c conv) ToChatCompletionMessage() []openai.ChatCompletionMessage {
return chatMessages
}

func (c conv) ToAnthropicMessage() []anthropic.Message {
var chatMessages []anthropic.Message

for _, message := range c.MessagesFromHead() {
var role anthropic.RoleType

if message.Role == openai.ChatMessageRoleSystem {
continue // anthropic doesn't have a system role
}

if message.Role == openai.ChatMessageRoleUser {
role = anthropic.ChatMessageRoleUser
} else {
role = anthropic.ChatMessageRoleAssistant
}
chatMessages = append(chatMessages, anthropic.Message{
Role: role,
Content: message.Content,
})
}

if session.Verbose() {
for _, message := range chatMessages {
fmt.Printf("[%s]: %.32s\n", message.Role, message.Content)
}
}

return chatMessages
}

func (c conv) ToYAML() ([]byte, error) {
yamlBytes, err := yaml.Marshal(c)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
module github.com/kznrluk/aski

go 1.20
go 1.21.6

require (
github.com/AlecAivazis/survey/v2 v2.3.7
github.com/charmbracelet/glamour v0.6.0
github.com/fatih/color v1.16.0
github.com/goccy/go-yaml v1.11.2
github.com/kznrluk/go-anthropic v0.0.0-20240315093738-f37049eee303
github.com/mattn/go-colorable v0.1.13
github.com/nyaosorg/go-readline-ny v1.0.1
github.com/sashabaranov/go-openai v1.17.2
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cn
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ=
github.com/goccy/go-yaml v1.11.2/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
Expand All @@ -39,7 +43,10 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kznrluk/go-anthropic v0.0.0-20240315093738-f37049eee303 h1:Gx7NOw3aUWYCLb+Ys+z/sBfBcddaMVFb/qAzjlyQOg4=
github.com/kznrluk/go-anthropic v0.0.0-20240315093738-f37049eee303/go.mod h1:uQw260BrkJJ1maPoZ3WA/NXvRD29tkMKBZpfVZvBDhk=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
Expand Down Expand Up @@ -103,6 +110,7 @@ github.com/yuin/goldmark-emoji v1.0.2/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nD
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
Expand Down

0 comments on commit 413fe41

Please sign in to comment.