fd44b15d81
**死锁根因修复** - periodicThinkLoop:1015 orphaned lock → 删除(字段已原子化) - RecordUserMessage 隔离为 recordMu - atomic.Int64 替换 lastUserMessage/lastThinkTime 等 **MD3 / Android 17 主题** - 毛玻璃卡片 (backdrop-filter) - MD3 色彩令牌 (pink primary #f472b6) - icons.js 独立矢量图标库 + 运行时 emoji 替换 - 无边框卡片、圆角按钮、阴影层次 **上下文持久化** - AddMessage → saveToDB 异步写 PostgreSQL - LoadFromDB 恢复 (admin-session-main + 懒加载) - LLMMessage.Timestamp 字段 **群聊与适配器** - group_ambient 模式: 非@消息让 LLM 自己判断是否插话 - 戳一戳动作消息总是回复 - NapCat 打字状态 (set_input_status, 最小3秒显示) - HTTP API 配置 (http_url/http_token) **知识库 & 防编造** - knowledge.CanHandle 对 chat 意图也触发 - 关键词预筛选避免无关 embedding 调用 - persona + synthesizer 三重诚实规则 - 工具结果持久化到会话历史 **平台桥接器** - detached:true Go进程独立存活 - ethend 重启自动接管已运行服务 - stop() 接管模式 taskkill/F/ PID - Windows netstat 替代 fuser 获取 PID - 重复适配器种子逻辑修复 - 失败转发日志 Direction: error **崩溃诊断** - crashlog 包 (Recover + WrapHTTP + LLMCall) - /api/v1/debug/goroutines 端点 - thinker 操作日志 + 30s stats - 日志写入 logs/ 目录持久化 Co-Authored-By: Claude <noreply@anthropic.com>
84 lines
2.8 KiB
Go
84 lines
2.8 KiB
Go
package model
|
|
|
|
import "time"
|
|
|
|
// Role 消息角色
|
|
type Role string
|
|
|
|
const (
|
|
RoleSystem Role = "system"
|
|
RoleUser Role = "user"
|
|
RoleAssistant Role = "assistant"
|
|
RoleTool Role = "tool"
|
|
)
|
|
|
|
// LLMMessage 发送给LLM的消息
|
|
type LLMMessage struct {
|
|
Role Role `json:"role"`
|
|
Content string `json:"content"`
|
|
Images []string `json:"images,omitempty"` // 图片 base64 data URL 列表 (多模态)
|
|
VideoURLs []string `json:"video_urls,omitempty"` // 视频 URL 列表 (多模态)
|
|
Name string `json:"name,omitempty"` // 可选发送者名称
|
|
ToolCallID string `json:"tool_call_id,omitempty"` // 工具调用关联ID (tool role 消息关联调用)
|
|
ToolCalls []ToolCall `json:"tool_calls,omitempty"` // 助手消息中的工具调用列表
|
|
ReasoningContent string `json:"reasoning_content,omitempty"` // DeepSeek 思考链内容(需回传)
|
|
Timestamp time.Time `json:"timestamp,omitempty"` // 消息时间
|
|
}
|
|
|
|
// ImageContent is a multimodal content part for images.
|
|
type ImageContent struct {
|
|
Type string `json:"type"`
|
|
Text string `json:"text,omitempty"`
|
|
ImageURL *ImageURL `json:"image_url,omitempty"`
|
|
}
|
|
|
|
// ImageURL holds an image URL (can be a data: URL or http: URL).
|
|
type ImageURL struct {
|
|
URL string `json:"url"`
|
|
Detail string `json:"detail,omitempty"` // low, high, auto
|
|
}
|
|
|
|
// VideoURLContent holds a video URL for multimodal video understanding.
|
|
type VideoURLContent struct {
|
|
VideoURL *VideoURL `json:"video_url,omitempty"`
|
|
}
|
|
|
|
// VideoURL holds a video URL.
|
|
type VideoURL struct {
|
|
URL string `json:"url"`
|
|
}
|
|
|
|
// ChatMessage 数据库存储的对话消息
|
|
type ChatMessage struct {
|
|
ID string `json:"id" db:"id"`
|
|
SessionID string `json:"session_id" db:"session_id"`
|
|
UserID string `json:"user_id" db:"user_id"`
|
|
Role Role `json:"role" db:"role"`
|
|
Content string `json:"content" db:"content"`
|
|
Mode string `json:"mode" db:"mode"` // text | voice_msg | voice_assistant
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
}
|
|
|
|
// LLMResponse LLM返回的响应
|
|
type LLMResponse struct {
|
|
Content string `json:"content"`
|
|
FinishReason string `json:"finish_reason"` // stop | length | tool_calls
|
|
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
|
|
Usage Usage `json:"usage,omitempty"`
|
|
ReasoningContent string `json:"reasoning_content,omitempty"` // DeepSeek 思考链内容
|
|
}
|
|
|
|
// ToolCall 工具调用
|
|
type ToolCall struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Arguments string `json:"arguments"`
|
|
}
|
|
|
|
// Usage token用量统计
|
|
type Usage struct {
|
|
PromptTokens int `json:"prompt_tokens"`
|
|
CompletionTokens int `json:"completion_tokens"`
|
|
TotalTokens int `json:"total_tokens"`
|
|
}
|