SDK · Go
平行映射自 TypeScript 权威实现。基于
net/http+bufio.Scanner解析 SSE 流。
实现状态
[TODO: github.com/volo-ai/volo-go 仓库未公开。接口规格如下,可作 RFC 起点]
安装
bash
go get github.com/volo-ai/volo-go环境要求:Go ≥ 1.21(依赖 slog、泛型)
初始化
go
package main
import (
"context"
"os"
"github.com/volo-ai/volo-go"
)
func main() {
client := volo.NewClient(&volo.Config{
APIKey: os.Getenv("VOLO_API_KEY"),
BaseURL: "https://api.volo.ai",
})
}1 · Chat · 流式对话
go
import (
"context"
"fmt"
"github.com/google/uuid"
)
ctx := context.Background()
sessionID := uuid.New()
stream, err := client.Chat.Stream(ctx, &volo.ChatRequest{
SessionID: sessionID,
UserMessage: "你好",
ExecutionMode: volo.ModeAuto,
})
if err != nil {
panic(err)
}
defer stream.Close()
for event := range stream.Events() {
switch event.Type {
case volo.EventAssistantDelta:
fmt.Print(event.Content)
case volo.EventToolStart:
fmt.Printf("\n[工具] %s\n", event.ToolName)
case volo.EventComplete:
fmt.Println("\n[完成]")
case volo.EventError:
return fmt.Errorf("agent error: %s", event.Message)
}
}
if err := stream.Err(); err != nil {
panic(err)
}停止 / 追加 / 恢复
go
err := client.Chat.Stop(ctx, sessionID)
err := client.Chat.Append(ctx, sessionID, "顺便加夜间模式")
resumeStream, err := client.Chat.Resume(ctx, &volo.ResumeRequest{
TurnID: pendingTurnID,
Response: "选择 B 方案",
})工具审批
go
err := client.Chat.ApproveToolCall(ctx, &volo.ToolApprovalRequest{
ToolCallID: toolCallID,
TurnID: turnID,
Approved: true,
Reason: "用户已确认",
})2 · Memory · 记忆相册
go
// 上传
file, _ := os.Open("/path/to/photo.jpg")
defer file.Close()
memory, err := client.Memory.Upload(ctx, &volo.UploadRequest{
File: file,
Filename: "photo.jpg",
UserTitle: "春节家宴",
UserDescription: "2026 春节...",
})
// 列出
page, err := client.Memory.List(ctx, &volo.PageOpts{Page: 0, PageSize: 20})
// 搜索
results, err := client.Memory.Search(ctx, &volo.SearchRequest{
Query: "春节",
TopK: 10,
MinScore: 0.6,
})
// 删除
err := client.Memory.Delete(ctx, memoryID)3 · Skill · 技能市场
go
// 列出
page, err := client.Skill.List(ctx, &volo.SkillListOpts{
Page: 0,
PageSize: 20,
Category: "design",
Keyword: "critique",
})
// 安装 / 卸载
err := client.Skill.Install(ctx, skillID)
err := client.Skill.Uninstall(ctx, skillID)
// 我的
mine, err := client.Skill.ListMine(ctx, &volo.PageOpts{Page: 0, PageSize: 50})
// Package 子技能
children, err := client.Skill.GetChildren(ctx, packageID)
err := client.Skill.ToggleChild(ctx, packageID, childSkillID, false)4 · Auth · 鉴权
go
result, err := client.Auth.LoginByEmail(ctx, &volo.EmailLoginRequest{
Email: "user@example.com",
Code: "123456",
})
// SDK 自动 refresh
token := client.Tokens().AccessToken()
err := client.Auth.Logout(ctx)Context 取消
所有方法接受 context.Context,取消 ctx 会立即终止请求(含 SSE 流):
go
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
stream, err := client.Chat.Stream(ctx, request)
// 30 秒后自动取消错误处理
go
import "errors"
stream, err := client.Chat.Stream(ctx, request)
if err != nil {
var authErr *volo.AuthError
var rateErr *volo.RateLimitError
var quotaErr *volo.QuotaError
switch {
case errors.As(err, &authErr):
log.Fatal("API Key 无效")
case errors.As(err, &rateErr):
log.Printf("被限流,retry after %v", rateErr.RetryAfter)
case errors.As(err, "aErr):
log.Fatal("配额耗尽")
default:
log.Fatalf("未知错误: %v", err)
}
}类型
go
type EventType string
const (
EventProgress EventType = "PROGRESS"
EventAssistantDelta EventType = "ASSISTANT_DELTA"
EventToolStart EventType = "TOOL_START"
EventToolEnd EventType = "TOOL_END"
EventRenderUI EventType = "RENDER_UI"
EventInteraction EventType = "INTERACTION"
EventComplete EventType = "COMPLETE"
EventError EventType = "ERROR"
// ... 完整 34+ 枚举与后端镜像
)
type ExecutionMode string
const (
ModeFast ExecutionMode = "FAST"
ModeMax ExecutionMode = "MAX"
ModeAuto ExecutionMode = "AUTO"
)与 HTTP Server 集成
把 VOLO AI 流式响应转发为 SSE:
go
http.HandleFunc("/chat", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
var req volo.ChatRequest
json.NewDecoder(r.Body).Decode(&req)
stream, err := client.Chat.Stream(r.Context(), &req)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
defer stream.Close()
flusher := w.(http.Flusher)
for event := range stream.Events() {
data, _ := json.Marshal(event)
fmt.Fprintf(w, "event: %s\ndata: %s\n\n", event.Type, data)
flusher.Flush()
}
})相关
- SDK · TypeScript — 权威实现参考
- API · Chat