mirror of
https://github.com/fumiama/deepinfra.git
synced 2026-06-30 09:40:28 +08:00
feat: add ollama-compatibility
This commit is contained in:
16
README.md
16
README.md
@@ -4,7 +4,7 @@ Call OpenAI compatible APIs, originally designed for DeepInfra.
|
|||||||
## Quick Start
|
## Quick Start
|
||||||
```go
|
```go
|
||||||
api := NewAPI(APIDeepInfra, "PUT YOUR API KEY HERE")
|
api := NewAPI(APIDeepInfra, "PUT YOUR API KEY HERE")
|
||||||
txt, err := api.Request(model.NewDeepSeek(0.7, 0.9, 1024).
|
txt, err := api.Request(model.NewOpenAI(model.ModelDeepDeek, model.SeparatorThink, 0.7, 0.9, 1024).
|
||||||
System("Be a good assistant.").User("Hello"),
|
System("Be a good assistant.").User("Hello"),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -13,17 +13,3 @@ if err != nil {
|
|||||||
fmt.Println(txt)
|
fmt.Println(txt)
|
||||||
// Hello! How can I assist you today?
|
// Hello! How can I assist you today?
|
||||||
```
|
```
|
||||||
|
|
||||||
## Custom Call
|
|
||||||
```go
|
|
||||||
api := NewAPI(APIDeepInfra, "PUT YOUR API KEY HERE")
|
|
||||||
txt, err := api.Request(model.NewCustom("fumiama/ninus", "", 0.7, 0.9, 1024).
|
|
||||||
System("你正在QQ群与用户聊天,用户发送了消息。按自己的心情简短思考后,条理清晰地回应**一句话**,禁止回应多句。").
|
|
||||||
User("总不能什么都查吧").User("后面DOGE就成恶龙了 很常见的场景"),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
fmt.Println(txt)
|
|
||||||
// 要不我给你查一下?
|
|
||||||
```
|
|
||||||
|
|||||||
15
model.go
15
model.go
@@ -1,6 +1,8 @@
|
|||||||
package deepinfra
|
package deepinfra
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/fumiama/deepinfra/model"
|
"github.com/fumiama/deepinfra/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -8,3 +10,16 @@ type Model interface {
|
|||||||
model.Inputer
|
model.Inputer
|
||||||
model.Outputer
|
model.Outputer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
api := NewAPI(APIDeepInfra, "PUT YOUR API KEY HERE")
|
||||||
|
txt, err := api.Request(model.NewOpenAI("fumiama/ninus", "", 0.7, 0.9, 1024).
|
||||||
|
System("你正在QQ群与用户聊天,用户发送了消息。按自己的心情简短思考后,条理清晰地回应**一句话**,禁止回应多句。").
|
||||||
|
User("总不能什么都查吧").User("后面DOGE就成恶龙了 很常见的场景"),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(txt)
|
||||||
|
// 要不我给你查一下?
|
||||||
|
}
|
||||||
|
|||||||
13
model/api.go
13
model/api.go
@@ -21,13 +21,8 @@ type MessageBuilder[T any] interface {
|
|||||||
Assistant(prompt string) T
|
Assistant(prompt string) T
|
||||||
}
|
}
|
||||||
|
|
||||||
type Message struct {
|
type Protocol[T any] interface {
|
||||||
Role string `json:"role"`
|
Inputer
|
||||||
Content string `json:"content"`
|
Outputer
|
||||||
}
|
MessageBuilder[T]
|
||||||
|
|
||||||
type Choice struct {
|
|
||||||
Index int `json:"index"`
|
|
||||||
Message Message `json:"message"`
|
|
||||||
FinishReason string `json:"finish_reason"`
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Custom as an compatible example.
|
|
||||||
type Custom struct {
|
|
||||||
Inputer `json:"-"`
|
|
||||||
Outputer `json:"-"`
|
|
||||||
MessageBuilder[*DeepSeek] `json:"-"`
|
|
||||||
sep string `json:"-"`
|
|
||||||
// callback only
|
|
||||||
ID string `json:"id,omitempty"`
|
|
||||||
Object string `json:"object,omitempty"`
|
|
||||||
Created int `json:"created,omitempty"`
|
|
||||||
Choices []Choice `json:"choices,omitempty"`
|
|
||||||
// callback/request
|
|
||||||
Model string `json:"model"`
|
|
||||||
Messages []Message `json:"messages"`
|
|
||||||
Temperature float32 `json:"temperature"` // Temperature 0.7
|
|
||||||
TopP float32 `json:"top_p"` // TopP 0.9
|
|
||||||
MaxTokens int `json:"max_tokens"` // MaxTokens 16384
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCustom(model, sep string, temp, topp float32, maxn uint) *Custom {
|
|
||||||
c := new(Custom)
|
|
||||||
c.sep = sep
|
|
||||||
c.Model = model
|
|
||||||
c.Temperature = temp
|
|
||||||
c.TopP = topp
|
|
||||||
c.MaxTokens = int(maxn)
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Custom) Parse(body io.Reader) error {
|
|
||||||
return json.NewDecoder(body).Decode(&c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Custom) Output() string {
|
|
||||||
if len(c.Choices) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return CutLast(c.Choices[len(c.Choices)-1].Message.Content, c.sep)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Custom) OutputRaw() string {
|
|
||||||
if len(c.Choices) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return c.Choices[len(c.Choices)-1].Message.Content
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *Custom) System(prompt string) *Custom {
|
|
||||||
ds.Messages = make([]Message, 1, 8)
|
|
||||||
ds.Messages[0] = Message{
|
|
||||||
Role: "system",
|
|
||||||
Content: prompt,
|
|
||||||
}
|
|
||||||
return ds
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *Custom) User(prompt string) *Custom {
|
|
||||||
ds.Messages = append(ds.Messages, Message{
|
|
||||||
Role: "user",
|
|
||||||
Content: prompt,
|
|
||||||
})
|
|
||||||
return ds
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *Custom) Assistant(prompt string) *Custom {
|
|
||||||
ds.Messages = append(ds.Messages, Message{
|
|
||||||
Role: "assistant",
|
|
||||||
Content: prompt,
|
|
||||||
})
|
|
||||||
return ds
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *Custom) Body() *bytes.Buffer {
|
|
||||||
w := bytes.NewBuffer(make([]byte, 0, 16384))
|
|
||||||
err := json.NewEncoder(w).Encode(ds)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
modelDeepDeek = "deepseek-ai/DeepSeek-R1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DeepSeek as an specified example.
|
|
||||||
type DeepSeek struct {
|
|
||||||
Inputer `json:"-"`
|
|
||||||
Outputer `json:"-"`
|
|
||||||
MessageBuilder[*DeepSeek] `json:"-"`
|
|
||||||
// callback only
|
|
||||||
ID string `json:"id,omitempty"`
|
|
||||||
Object string `json:"object,omitempty"`
|
|
||||||
Created int `json:"created,omitempty"`
|
|
||||||
Choices []Choice `json:"choices,omitempty"`
|
|
||||||
// callback/request
|
|
||||||
Model string `json:"model"`
|
|
||||||
Messages []Message `json:"messages"`
|
|
||||||
Temperature float32 `json:"temperature"` // Temperature 0.7
|
|
||||||
TopP float32 `json:"top_p"` // TopP 0.9
|
|
||||||
MaxTokens int `json:"max_tokens"` // MaxTokens 16384
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDeepSeek 0.7, 0.9
|
|
||||||
func NewDeepSeek(temp, topp float32, maxn uint) *DeepSeek {
|
|
||||||
ds := new(DeepSeek)
|
|
||||||
ds.Model = modelDeepDeek
|
|
||||||
ds.Temperature = temp
|
|
||||||
ds.TopP = topp
|
|
||||||
ds.MaxTokens = int(maxn)
|
|
||||||
return ds
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *DeepSeek) Body() *bytes.Buffer {
|
|
||||||
w := bytes.NewBuffer(make([]byte, 0, 16384))
|
|
||||||
err := json.NewEncoder(w).Encode(ds)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *DeepSeek) Parse(body io.Reader) error {
|
|
||||||
return json.NewDecoder(body).Decode(&ds)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *DeepSeek) Output() string {
|
|
||||||
if len(ds.Choices) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return CutLast(ds.Choices[len(ds.Choices)-1].Message.Content, SeparatorThink)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *DeepSeek) OutputRaw() string {
|
|
||||||
if len(ds.Choices) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return ds.Choices[len(ds.Choices)-1].Message.Content
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *DeepSeek) System(prompt string) *DeepSeek {
|
|
||||||
ds.Messages = make([]Message, 1, 8)
|
|
||||||
ds.Messages[0] = Message{
|
|
||||||
Role: "system",
|
|
||||||
Content: prompt,
|
|
||||||
}
|
|
||||||
return ds
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *DeepSeek) User(prompt string) *DeepSeek {
|
|
||||||
ds.Messages = append(ds.Messages, Message{
|
|
||||||
Role: "user",
|
|
||||||
Content: prompt,
|
|
||||||
})
|
|
||||||
return ds
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *DeepSeek) Assistant(prompt string) *DeepSeek {
|
|
||||||
ds.Messages = append(ds.Messages, Message{
|
|
||||||
Role: "assistant",
|
|
||||||
Content: prompt,
|
|
||||||
})
|
|
||||||
return ds
|
|
||||||
}
|
|
||||||
87
model/ollama.go
Normal file
87
model/ollama.go
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OLLaMA as an specified example.
|
||||||
|
type OLLaMA struct {
|
||||||
|
sep string
|
||||||
|
Protocol[*OLLaMA] `json:"-"`
|
||||||
|
// callback only
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Object string `json:"object,omitempty"`
|
||||||
|
Created int `json:"created,omitempty"`
|
||||||
|
Messages []Message `json:"messages"`
|
||||||
|
// callback/request
|
||||||
|
Model string `json:"model"`
|
||||||
|
Message *Message `json:"message,omitempty"`
|
||||||
|
Temperature float32 `json:"temperature"` // Temperature 0.7
|
||||||
|
TopP float32 `json:"top_p"` // TopP 0.9
|
||||||
|
MaxTokens int `json:"max_tokens"` // MaxTokens 4096
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOLLaMA use temp 0.7, topp 0.9, maxn 4096 if you don't know the meaning.
|
||||||
|
func NewOLLaMA(model, sep string, temp, topp float32, maxn uint) *OLLaMA {
|
||||||
|
opai := new(OLLaMA)
|
||||||
|
opai.sep = sep
|
||||||
|
opai.Model = model
|
||||||
|
opai.Temperature = temp
|
||||||
|
opai.TopP = topp
|
||||||
|
opai.MaxTokens = int(maxn)
|
||||||
|
return opai
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ollm *OLLaMA) Body() *bytes.Buffer {
|
||||||
|
w := bytes.NewBuffer(make([]byte, 0, 8192))
|
||||||
|
err := json.NewEncoder(w).Encode(ollm)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ollm *OLLaMA) Parse(body io.Reader) error {
|
||||||
|
return json.NewDecoder(body).Decode(&ollm)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ollm *OLLaMA) Output() string {
|
||||||
|
if ollm.Message == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return CutLast(ollm.Message.Content, ollm.sep)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ollm *OLLaMA) OutputRaw() string {
|
||||||
|
if ollm.Message == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return ollm.Message.Content
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ollm *OLLaMA) System(prompt string) *OLLaMA {
|
||||||
|
ollm.Messages = make([]Message, 1, 8)
|
||||||
|
ollm.Messages[0] = Message{
|
||||||
|
Role: "system",
|
||||||
|
Content: prompt,
|
||||||
|
}
|
||||||
|
return ollm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ollm *OLLaMA) User(prompt string) *OLLaMA {
|
||||||
|
ollm.Messages = append(ollm.Messages, Message{
|
||||||
|
Role: "user",
|
||||||
|
Content: prompt,
|
||||||
|
})
|
||||||
|
return ollm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ollm *OLLaMA) Assistant(prompt string) *OLLaMA {
|
||||||
|
ollm.Messages = append(ollm.Messages, Message{
|
||||||
|
Role: "assistant",
|
||||||
|
Content: prompt,
|
||||||
|
})
|
||||||
|
return ollm
|
||||||
|
}
|
||||||
102
model/openai.go
Normal file
102
model/openai.go
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ModelDeepDeek = "deepseek-ai/DeepSeek-R1"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Role string `json:"role"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Choice struct {
|
||||||
|
Index int `json:"index"`
|
||||||
|
Message Message `json:"message"`
|
||||||
|
FinishReason string `json:"finish_reason"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenAI as an specified example.
|
||||||
|
type OpenAI struct {
|
||||||
|
sep string
|
||||||
|
Protocol[*OpenAI] `json:"-"`
|
||||||
|
// callback only
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Object string `json:"object,omitempty"`
|
||||||
|
Created int `json:"created,omitempty"`
|
||||||
|
Choices []Choice `json:"choices,omitempty"`
|
||||||
|
// callback/request
|
||||||
|
Model string `json:"model"`
|
||||||
|
Messages []Message `json:"messages"`
|
||||||
|
Temperature float32 `json:"temperature"` // Temperature 0.7
|
||||||
|
TopP float32 `json:"top_p"` // TopP 0.9
|
||||||
|
MaxTokens int `json:"max_tokens"` // MaxTokens 4096
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOpenAI use temp 0.7, topp 0.9, maxn 4096 if you don't know the meaning.
|
||||||
|
func NewOpenAI(model, sep string, temp, topp float32, maxn uint) *OpenAI {
|
||||||
|
opai := new(OpenAI)
|
||||||
|
opai.sep = sep
|
||||||
|
opai.Model = model
|
||||||
|
opai.Temperature = temp
|
||||||
|
opai.TopP = topp
|
||||||
|
opai.MaxTokens = int(maxn)
|
||||||
|
return opai
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opai *OpenAI) Body() *bytes.Buffer {
|
||||||
|
w := bytes.NewBuffer(make([]byte, 0, 8192))
|
||||||
|
err := json.NewEncoder(w).Encode(opai)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opai *OpenAI) Parse(body io.Reader) error {
|
||||||
|
return json.NewDecoder(body).Decode(&opai)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opai *OpenAI) Output() string {
|
||||||
|
if len(opai.Choices) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return CutLast(opai.Choices[len(opai.Choices)-1].Message.Content, opai.sep)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opai *OpenAI) OutputRaw() string {
|
||||||
|
if len(opai.Choices) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return opai.Choices[len(opai.Choices)-1].Message.Content
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opai *OpenAI) System(prompt string) *OpenAI {
|
||||||
|
opai.Messages = make([]Message, 1, 8)
|
||||||
|
opai.Messages[0] = Message{
|
||||||
|
Role: "system",
|
||||||
|
Content: prompt,
|
||||||
|
}
|
||||||
|
return opai
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opai *OpenAI) User(prompt string) *OpenAI {
|
||||||
|
opai.Messages = append(opai.Messages, Message{
|
||||||
|
Role: "user",
|
||||||
|
Content: prompt,
|
||||||
|
})
|
||||||
|
return opai
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opai *OpenAI) Assistant(prompt string) *OpenAI {
|
||||||
|
opai.Messages = append(opai.Messages, Message{
|
||||||
|
Role: "assistant",
|
||||||
|
Content: prompt,
|
||||||
|
})
|
||||||
|
return opai
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user