(props: ThreadGPT)
| 78 | } |
| 79 | |
| 80 | function ThreadGPT(props: ThreadGPT) { |
| 81 | const query = useQuery({ |
| 82 | queryKey: ['threadgpt', props.nodeId], |
| 83 | queryFn: async (): Promise<ThreadNode> => { |
| 84 | const key = storageKey(props.nodeId) |
| 85 | const node = await ikv.get(key) |
| 86 | if (!node) { |
| 87 | const defaultNode = { depth: 0, children: [] } |
| 88 | await ikv.set(key, defaultNode) |
| 89 | return defaultNode |
| 90 | } |
| 91 | return node |
| 92 | }, |
| 93 | }) |
| 94 | const nextMessages = useMemo(() => { |
| 95 | return [ |
| 96 | ...props.previousMessages, |
| 97 | ...(query.data?.message ? [query.data?.message] : []), |
| 98 | ] |
| 99 | }, [query.data?.message, props.previousMessages]) |
| 100 | const mutation = useMutation({ |
| 101 | mutationFn: async (data: { text: string; role: Role } | null) => { |
| 102 | const text = data?.text ?? null |
| 103 | const role = data?.role ?? 'user' |
| 104 | |
| 105 | const parentKey = storageKey(props.nodeId) |
| 106 | const parent = await ikv.get(parentKey) |
| 107 | if (!parent) { |
| 108 | throw new Error('Parent node not found') |
| 109 | } |
| 110 | |
| 111 | async function addNode(message: ThreadNode['message'], response?: any) { |
| 112 | const id = String(ObjectID()) |
| 113 | const node: ThreadNode = { |
| 114 | depth: parent.depth + 1, |
| 115 | children: [], |
| 116 | message: message, |
| 117 | response, |
| 118 | timestamp: new Date().toJSON(), |
| 119 | } |
| 120 | await ikv.set(storageKey(id), node) |
| 121 | parent.children.unshift(id) |
| 122 | } |
| 123 | |
| 124 | if (text === null) { |
| 125 | let secretKey = await ikv.get('openaiSecretKey') |
| 126 | if (!secretKey) { |
| 127 | secretKey = prompt('Enter OpenAI secret key') |
| 128 | if (!secretKey) { |
| 129 | throw new Error('OpenAI secret key is required') |
| 130 | } |
| 131 | await ikv.set('openaiSecretKey', secretKey) |
| 132 | queryClient.invalidateQueries(['models']) |
| 133 | } |
| 134 | |
| 135 | const response = await createChatCompletion(nextMessages, secretKey) |
| 136 | for (const [index, choice] of response.data.choices.entries()) { |
| 137 | await addNode(choice.message, { |
nothing calls this directly
no test coverage detected