mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-05 02:56:39 +00:00
5a3dfdd2b4
* plans: 20260207-support-bot.md * Update 20260207-support-bot.md * plans: 20260207-support-bot-implementation.md * plans: Update 20260207-support-bot-implementation.md * Relocate plans * apps: support bot code & tests * apps: support bot relocate * support-bot: Fix basic functionality * apps: support-bot /add command & fixes * apps: simplex-support-bot: Change Grok logo * Further usability improvements * simplex-support-bot: Update support plan to reflect current flow * simplex-support-bot: update product design plan * support-bot: update plan * support-bot: review and refine product spec * support-bot: update product spec — complete state, /join team-only, card debouncing - Group preferences applied once at creation, not on every startup - /join restricted to team group only - Team/Grok reply or reaction auto-completes conversation (✅) - Customer message reverts to incomplete - Card updates debounced globally with 15-minute batch flush * support-bot: update implementation plan * support-bot: implement stateless bot with cards, Grok, team flow, hardening Complete rewrite of the support bot to stateless architecture: - State derived from group composition + chat history (survives restarts) - Card dashboard in team group with live status, preview, /join commands - Two-profile architecture (main + Grok) with profileMutex serialization - Grok join race condition fix via bufferedGrokInvitations - Card preview: newest-first truncation, newline sanitization, sender prefixes - Best-effort startup (invite link, group profile update) - Team group preferences: directMessages, fullDelete, commands - 122 tests across 27 suites * support-bot: use apiCreateMemberContact and apiSendMemberContactInvitation instead of raw commands Replace sendChatCmd("/_create member contact ...") and sendChatCmd("/_invite member contact ...") with the typed API methods added in simplex-chat-nodejs. Update plans and build script accordingly. * plans: 20260207-support-bot.md * Update 20260207-support-bot.md * plans: 20260207-support-bot-implementation.md * plans: Update 20260207-support-bot-implementation.md * Relocate plans * apps: support bot code & tests * apps: support bot relocate * support-bot: Fix basic functionality * apps: support-bot /add command & fixes * apps: simplex-support-bot: Change Grok logo * Further usability improvements * simplex-support-bot: Update support plan to reflect current flow * simplex-support-bot: update product design plan * support-bot: update plan * support-bot: review and refine product spec * support-bot: update product spec — complete state, /join team-only, card debouncing - Group preferences applied once at creation, not on every startup - /join restricted to team group only - Team/Grok reply or reaction auto-completes conversation (✅) - Customer message reverts to incomplete - Card updates debounced globally with 15-minute batch flush * support-bot: update implementation plan * support-bot: implement stateless bot with cards, Grok, team flow, hardening Complete rewrite of the support bot to stateless architecture: - State derived from group composition + chat history (survives restarts) - Card dashboard in team group with live status, preview, /join commands - Two-profile architecture (main + Grok) with profileMutex serialization - Grok join race condition fix via bufferedGrokInvitations - Card preview: newest-first truncation, newline sanitization, sender prefixes - Best-effort startup (invite link, group profile update) - Team group preferences: directMessages, fullDelete, commands - 122 tests across 27 suites * support-bot: use apiCreateMemberContact and apiSendMemberContactInvitation instead of raw commands Replace sendChatCmd("/_create member contact ...") and sendChatCmd("/_invite member contact ...") with the typed API methods added in simplex-chat-nodejs. Update plans and build script accordingly. * support-bot: more improvemets * support-bot: add tests for Grok batch dedup and initial response gating 7 new tests covering the duplicate Grok reply fix: - batch dedup: only last customer message per group triggers API call - batch dedup: multi-group batches handled independently - batch dedup: non-customer messages filtered from batch - initial response gating: per-message responses suppressed during activateGrok - gating clears: per-message responses resume after activation completes Update implementation plan test catalog (122 → 129 tests). * support-bot: load context from context file * Rename Grok AI -> Grok * Remove unused strings.ts * support-bot: change messages * cardFlushMinutes 15 -> cardFlushSeconds 300 * support-bot: /team message when grok present * support-bot: correct messages * support-bot: update plans to reflect latest changes * Update plan for state derivation * support-bot: Update state machine plans * support-bot: implement customData state * Fix Grok revertStateOnFail race condition * support-bot: plans adversarial review * support-bot: /join ID part of card in plan * support-bot: implement /join ID inside card * support-bot: plans use params instead of regex in /join * support-bot: Implement adversarial review changes * support-bot: no re-invite if already invited * support-bot: /team should give owner to invited member * Don't change username for existing database * support-bot: update bot commands before sending commands * support-bot: adversarial review fixes * support-bot: implement postgresql (#6876) * support-bot: sqlite/postgres backend via typed DbConfig and parseArgs flags * support-bot: add README with setup and flags reference * support-bot: use published simplex-chat, drop build.sh/start.sh * support-bot: switch CLI to commander, add --help * support-bot: update README --------- Co-authored-by: shum <github.shum@liber.li> Co-authored-by: sh <37271604+shumvgolove@users.noreply.github.com>
56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
import {log, logError} from "./util.js"
|
|
|
|
export interface GrokMessage {
|
|
role: "system" | "user" | "assistant"
|
|
content: string
|
|
}
|
|
|
|
export class GrokApiClient {
|
|
private readonly apiKey: string
|
|
private readonly systemPrompt: string
|
|
|
|
constructor(apiKey: string, systemPrompt: string) {
|
|
this.apiKey = apiKey
|
|
this.systemPrompt = systemPrompt
|
|
}
|
|
|
|
async chatRaw(messages: GrokMessage[]): Promise<string> {
|
|
const response = await fetch("https://api.x.ai/v1/chat/completions", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
"Authorization": `Bearer ${this.apiKey}`,
|
|
},
|
|
body: JSON.stringify({
|
|
model: "grok-3-mini",
|
|
messages,
|
|
temperature: 0.3,
|
|
max_tokens: 1024,
|
|
}),
|
|
signal: AbortSignal.timeout(60_000),
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const body = await response.text()
|
|
logError(`Grok API HTTP ${response.status}`, body)
|
|
throw new Error(`Grok API error: HTTP ${response.status}`)
|
|
}
|
|
|
|
const data = await response.json() as {choices: {message: {content: string}}[]}
|
|
const content = data.choices?.[0]?.message?.content
|
|
if (!content) throw new Error("Grok API returned empty response")
|
|
|
|
log(`Grok API response: ${content.length} chars`)
|
|
return content
|
|
}
|
|
|
|
async chat(history: GrokMessage[], userMessage: string): Promise<string> {
|
|
log(`Grok API call: ${history.length} history msgs, user msg ${userMessage.length} chars`)
|
|
return this.chatRaw([
|
|
{role: "system", content: this.systemPrompt},
|
|
...history,
|
|
{role: "user", content: userMessage},
|
|
])
|
|
}
|
|
}
|