import { Chatkit, SessionList, type SessionListProps, useChatSessions } from '@volcengine/chatkit';
import { createOpenAiAdapter } from '@volcengine/chatkit/adapters/openai';
import '@volcengine/chatkit/styles.css';
// 请求都发给自己的服务:由它校验登录态、补上模型名和密钥,再转发给模型接口
const send = (method: string, path: string, body?: unknown) =>
fetch(`/api/chat${path}`, {
method,
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
...(body === undefined ? {} : { body: JSON.stringify(body) }),
});
const adapter = createOpenAiAdapter({
// 对话:把轮次编号带给后端,历史里用它标明消息属于哪一轮
run: ({ sessionId, runId, body }) => send('POST', `/sessions/${sessionId}/runs`, { run_id: runId, ...body }),
// 重新生成、编辑后重发:后端作废 replace_from 那一轮和它之后的内容
regenerate: ({ sessionId, runId, targetRunId, body }) =>
send('POST', `/sessions/${sessionId}/runs`, { run_id: runId, replace_from: targetRunId, ...body }),
edit: ({ sessionId, runId, targetRunId, body }) =>
send('POST', `/sessions/${sessionId}/runs`, { run_id: runId, replace_from: targetRunId, ...body }),
// 历史:给了它,刷新后对话才能还原
history: ({ sessionId, cursor }) =>
send('GET', `/sessions/${sessionId}/messages${cursor ? `?cursor=${encodeURIComponent(cursor)}` : ''}`),
// 在浏览器里执行的工具
tools: {
query_tickets: {
description: '查询工单',
parameters: { type: 'object', properties: { status: { type: 'string' } } },
execute: async (args, { signal }) => {
const response = await fetch('/api/tickets/query', { method: 'POST', body: JSON.stringify(args), signal });
return response.json();
},
},
},
});
export function App({
sessions: items,
activeSessionId,
onSelect,
}: Pick<SessionListProps, 'sessions' | 'activeSessionId' | 'onSelect'>) {
const sessions = useChatSessions({ activeSessionId, adapter });
return (
<div style={{ display: 'flex', height: '100vh' }}>
<SessionList sessions={items} activeSessionId={activeSessionId} onSelect={onSelect} style={{ width: 260 }} />
<div style={{ flex: 1, minWidth: 0 }}>
{/* settings、features、slots、renderers、onSend、onEvent 与完整示例相同 */}
<Chatkit sessions={sessions} />
</div>
</div>
);
}