-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathApp.jsx
More file actions
39 lines (32 loc) · 1.57 KB
/
Copy pathApp.jsx
File metadata and controls
39 lines (32 loc) · 1.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { useReducer, useCallback, useMemo } from 'react';
import { UIStateContext, reducer, initialState } from './contexts/UIStateContext.jsx';
import { StreamingContext } from './contexts/StreamingContext.jsx';
import { useWebSocketStream } from './hooks/useWebSocketStream.js';
import { DefaultAppLayout } from './components/DefaultAppLayout.jsx';
import { StreamingState } from './types.js';
export function App({ config }) {
const [state, dispatch] = useReducer(reducer, initialState);
const { send } = useWebSocketStream({
url: config.gatewayUrl,
model: config.model,
workspace: config.workspace,
dispatch,
});
const submit = useCallback((text) => {
dispatch({ type: 'append', item: { kind: 'user', content: text, timestamp: nowTs() } });
dispatch({ type: 'streaming', value: StreamingState.Responding });
send({ type: 'chat', content: text, model: config.model, plan_mode: config.planMode ?? false });
}, [send, config.model, config.planMode]);
const stop = useCallback(() => {
if (state.streamingState === StreamingState.Responding) send({ type: 'stop' });
}, [send, state.streamingState]);
const ctxValue = useMemo(() => ({ state, dispatch, submit, stop }), [state, submit, stop]);
return (
<UIStateContext.Provider value={ctxValue}>
<StreamingContext.Provider value={state.streamingState}>
<DefaultAppLayout model={config.model} />
</StreamingContext.Provider>
</UIStateContext.Provider>
);
}
const nowTs = () => new Date().toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit' });