mirror of
https://github.com/fumiama/deepinfra.git
synced 2026-06-12 14:06:35 +08:00
init: add codes
This commit is contained in:
13
README.md
13
README.md
@@ -1,2 +1,15 @@
|
|||||||
# deepinfra
|
# deepinfra
|
||||||
Call OpenAI compatible APIs, originally designed for DeepInfra.
|
Call OpenAI compatible APIs, originally designed for DeepInfra.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
```go
|
||||||
|
api := NewAPI(APIDeepInfra, "PUT YOUR API KEY HERE")
|
||||||
|
txt, err := api.Request(model.NewDeepSeek(0.7, 0.9, 1024).
|
||||||
|
System("Be a good assistant.").User("Hello"),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(txt)
|
||||||
|
// Hello! How can I assist you today?
|
||||||
|
```
|
||||||
|
|||||||
37
api.go
Normal file
37
api.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package deepinfra
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
APIDeepInfra = "https://api.deepinfra.com/v1/openai/chat/completions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type API struct {
|
||||||
|
api string // api to call
|
||||||
|
key string // key in Authorization: Bearer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAPI(api, key string) API {
|
||||||
|
return API{api: api, key: key}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *API) Request(model Model) (string, error) {
|
||||||
|
req, err := http.NewRequest("POST", api.api, model.Body())
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
req.Header.Add("Authorization", "Bearer "+api.key)
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
err = model.Parse(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return model.Output(), nil
|
||||||
|
}
|
||||||
12
model.go
Normal file
12
model.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package deepinfra
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Model interface {
|
||||||
|
Body() *bytes.Buffer
|
||||||
|
Parse(io.Reader) error
|
||||||
|
Output() string
|
||||||
|
}
|
||||||
100
model/deepseek.go
Normal file
100
model/deepseek.go
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
modelDeepDeek = "deepseek-ai/DeepSeek-R1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeepSeek as an example.
|
||||||
|
type DeepSeek struct {
|
||||||
|
// 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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
19
model/utils.go
Normal file
19
model/utils.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
const (
|
||||||
|
SeparatorThink = "</think>"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CutLast(txt, sep string) string {
|
||||||
|
a := strings.LastIndex(txt, sep)
|
||||||
|
if a < 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
a += len(sep)
|
||||||
|
if a >= len(txt) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(txt[a:])
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user