feat: 语音流式输入管线 + VAD前端集成 + 插件-工具合并清理

- 前端: VAD语音检测(@ricky0123/vad-web) + useVoiceInput双模式(流式WS/REST)
- Gateway: VoiceStreamManager代理WS流式STT到voice-service
- Voice-service: DashScope REST → Realtime WS → Whisper三级引擎 + ffmpeg转码
- 共享模块: pkg/audio(音频转换) + pkg/dashscope(ASR REST客户端)
- 清理: 移除旧plugin-manager和pkg/plugins,完成插件→工具合并
- 文档: 完善gateway-api.md和voice-service.md语音API文档
- 工具: scripts/voice/ 语音转换脚本集

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 11:50:40 +08:00
parent 258cf81b25
commit 6ef9e082a6
91 changed files with 4091 additions and 3929 deletions
@@ -1,128 +0,0 @@
package tools
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"time"
)
// PluginManagerClient calls the plugin-manager service.
type PluginManagerClient struct {
baseURL string
httpClient *http.Client
}
// PMToolDefinition matches the plugin-manager tool definition format.
type PMToolDefinition struct {
ID string `json:"id"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
Description string `json:"description"`
Category string `json:"category"`
Complexity string `json:"complexity"`
Parameters map[string]interface{} `json:"parameters"`
DangerLevel string `json:"danger_level,omitempty"`
}
// PMToolResult matches the plugin-manager execution result.
type PMToolResult struct {
ToolName string `json:"tool_name"`
Success bool `json:"success"`
Output string `json:"output,omitempty"`
Error string `json:"error,omitempty"`
}
// PMPluginInfo matches plugin-manager plugin info.
type PMPluginInfo struct {
Name string `json:"name"`
Version string `json:"version"`
Status string `json:"status"`
Enabled bool `json:"enabled"`
Tools []string `json:"tools"`
}
func NewPluginManagerClient(baseURL string) *PluginManagerClient {
return &PluginManagerClient{
baseURL: baseURL,
httpClient: &http.Client{Timeout: 10 * time.Second},
}
}
// GetToolDefinitions fetches all tool definitions from plugin-manager.
func (c *PluginManagerClient) GetToolDefinitions(ctx context.Context) ([]PMToolDefinition, error) {
req, _ := http.NewRequestWithContext(ctx, "GET", c.baseURL+"/api/v1/tools", nil)
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("plugin-manager GetToolDefinitions: %w", err)
}
defer resp.Body.Close()
var body struct {
Tools []PMToolDefinition `json:"tools"`
}
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
return nil, fmt.Errorf("plugin-manager decode tools: %w", err)
}
return body.Tools, nil
}
// ExecuteTool calls a tool on plugin-manager by ID.
func (c *PluginManagerClient) ExecuteTool(ctx context.Context, toolID string, args map[string]interface{}) (*PMToolResult, error) {
body, _ := json.Marshal(map[string]interface{}{"arguments": args})
url := fmt.Sprintf("%s/api/v1/tools/%s/execute", c.baseURL, toolID)
req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(body))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("plugin-manager ExecuteTool: %w", err)
}
defer resp.Body.Close()
var result PMToolResult
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("plugin-manager decode result: %w", err)
}
return &result, nil
}
// ListPlugins fetches all installed plugins from plugin-manager.
func (c *PluginManagerClient) ListPlugins(ctx context.Context) ([]PMPluginInfo, error) {
req, _ := http.NewRequestWithContext(ctx, "GET", c.baseURL+"/api/v1/plugins", nil)
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var body struct {
Plugins []PMPluginInfo `json:"plugins"`
}
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
return nil, err
}
return body.Plugins, nil
}
// AdaptDefinitions converts PM tool definitions to ai-core ToolDefinition format.
func (c *PluginManagerClient) AdaptDefinitions(ctx context.Context) ([]ToolDefinition, error) {
pmDefs, err := c.GetToolDefinitions(ctx)
if err != nil {
return nil, err
}
defs := make([]ToolDefinition, 0, len(pmDefs))
for _, d := range pmDefs {
defs = append(defs, ToolDefinition{
Name: d.Name,
Description: d.Description,
Parameters: d.Parameters,
})
}
return defs, nil
}