1
0
mirror of https://github.com/fumiama/deepinfra.git synced 2026-06-05 00:32:46 +08:00

init: add codes

This commit is contained in:
源文雨
2025-02-14 15:34:05 +09:00
parent 4d4f1f5cb7
commit 507e407127
6 changed files with 184 additions and 0 deletions

View File

@@ -1,2 +1,15 @@
# 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
View 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
}

3
go.mod Normal file
View File

@@ -0,0 +1,3 @@
module github.com/fumiama/deepinfra
go 1.23.2

12
model.go Normal file
View 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
View 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
View 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:])
}