feat: release contextual omnichannel customer platform

Add Telegram, WhatsApp and email account management, realtime messaging, contextual multilingual AI, customer intelligence, knowledge workflows, enterprise controls, a unified design system and complete repository documentation.
This commit is contained in:
wmq
2026-07-30 02:29:53 +08:00
parent 9804341463
commit af49d22ca7
66 changed files with 3181 additions and 554 deletions
+21 -6
View File
@@ -7,7 +7,11 @@ function parseJson(text) {
return JSON.parse(cleaned)
}
export async function deepseek(system, user, json = false) {
export async function deepseek(system, user, jsonOrOptions = false) {
const options = typeof jsonOrOptions === 'boolean'
? { json: jsonOrOptions }
: { ...(jsonOrOptions || {}) }
const json = Boolean(options.json)
const apiKey = process.env.DEEPSEEK_API_KEY
if (!apiKey) throw Object.assign(new Error('DEEPSEEK_API_KEY 尚未配置'), { status: 503 })
const endpoint = `${(process.env.DEEPSEEK_BASE_URL || 'https://api.deepseek.com/anthropic').replace(/\/$/, '')}/v1/messages`
@@ -17,7 +21,10 @@ export async function deepseek(system, user, json = false) {
for (let attempt = 0; attempt < attempts; attempt += 1) {
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), Number(process.env.AI_TIMEOUT_MS || 45000))
const timeout = setTimeout(
() => controller.abort(),
Number(options.timeoutMs || process.env.AI_TIMEOUT_MS || 30000),
)
try {
const response = await fetch(endpoint, {
method: 'POST',
@@ -29,8 +36,11 @@ export async function deepseek(system, user, json = false) {
},
body: JSON.stringify({
model: process.env.DEEPSEEK_MODEL || 'deepseek-v4-flash',
max_tokens: Number(process.env.AI_MAX_TOKENS || 4096),
temperature: json ? 0 : 0.3,
max_tokens: Number(options.maxTokens || process.env.AI_MAX_TOKENS || 4096),
temperature: options.temperature ?? (json ? 0 : 0.3),
thinking: options.thinking === true
? { type: 'enabled' }
: { type: 'disabled' },
system,
messages: [{ role: 'user', content: [{ type: 'text', text: prompt }] }],
}),
@@ -47,6 +57,11 @@ export async function deepseek(system, user, json = false) {
lastError = error
prompt = `${user}\n\n上一次响应不是合法 JSON。请重新生成完整结果:只允许输出一个可被 JSON.parse 直接解析的 JSON 值;不得使用 Markdown;字符串中的双引号、换行和反斜杠必须正确转义。`
}
} catch (error) {
if (error?.name === 'AbortError') {
throw Object.assign(new Error('AI 响应超时,请稍后重试'), { status: 504 })
}
throw error
} finally {
clearTimeout(timeout)
}
@@ -54,8 +69,8 @@ export async function deepseek(system, user, json = false) {
throw Object.assign(new Error('AI 返回格式异常,自动重试后仍无法解析'), { status: 502, cause: lastError })
}
export function conversationContext(messages) {
return messages.slice(-80).map((m) => {
export function conversationContext(messages, limit = 30) {
return messages.slice(-limit).map((m) => {
const role = m.sender === 'agent' ? '坐席' : m.sender === 'system' ? '系统' : '客户'
const content = m.originalText || m.attachmentName || `[${m.type || '消息'}]`
const translation = m.translatedText && m.translatedText !== content ? `(译文:${m.translatedText})` : ''