mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
c513ad22d7
- move chat controller, state, protocol, history, and websocket logic into a dedicated chat feature module - improve chat reconnection, session hydration, and send gating based on actual websocket state - preserve gateway status during transient SSE disconnects and update stop state immediately - generate wss websocket URLs behind HTTPS proxies and add backend tests for forwarded proto handling
63 lines
1.3 KiB
TypeScript
63 lines
1.3 KiB
TypeScript
import { atom, getDefaultStore } from "jotai"
|
|
|
|
import {
|
|
getInitialActiveSessionId,
|
|
writeStoredSessionId,
|
|
} from "@/features/chat/state"
|
|
|
|
export interface ChatMessage {
|
|
id: string
|
|
role: "user" | "assistant"
|
|
content: string
|
|
timestamp: number | string
|
|
}
|
|
|
|
export type ConnectionState =
|
|
| "disconnected"
|
|
| "connecting"
|
|
| "connected"
|
|
| "error"
|
|
|
|
export interface ChatStoreState {
|
|
messages: ChatMessage[]
|
|
connectionState: ConnectionState
|
|
isTyping: boolean
|
|
activeSessionId: string
|
|
hasHydratedActiveSession: boolean
|
|
}
|
|
|
|
type ChatStorePatch = Partial<ChatStoreState>
|
|
|
|
const DEFAULT_CHAT_STATE: ChatStoreState = {
|
|
messages: [],
|
|
connectionState: "disconnected",
|
|
isTyping: false,
|
|
activeSessionId: getInitialActiveSessionId(),
|
|
hasHydratedActiveSession: false,
|
|
}
|
|
|
|
export const chatAtom = atom<ChatStoreState>(DEFAULT_CHAT_STATE)
|
|
|
|
const store = getDefaultStore()
|
|
|
|
export function getChatState() {
|
|
return store.get(chatAtom)
|
|
}
|
|
|
|
export function updateChatStore(
|
|
patch:
|
|
| ChatStorePatch
|
|
| ((prev: ChatStoreState) => ChatStorePatch | ChatStoreState),
|
|
) {
|
|
store.set(chatAtom, (prev) => {
|
|
const nextPatch = typeof patch === "function" ? patch(prev) : patch
|
|
const next = { ...prev, ...nextPatch }
|
|
|
|
if (next.activeSessionId !== prev.activeSessionId) {
|
|
writeStoredSessionId(next.activeSessionId)
|
|
}
|
|
|
|
return next
|
|
})
|
|
}
|