@fencyai/react 0.1.81 → 0.1.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index.css +1 -0
- package/dist/chat/Chat.d.ts +8 -0
- package/dist/chat/ChatResponse.d.ts +5 -0
- package/dist/chat/EditableContent.d.ts +11 -0
- package/dist/chat/GhostWrapper.d.ts +10 -0
- package/dist/chat/MentionCategory.d.ts +5 -0
- package/dist/chat/MentionInput.d.ts +20 -0
- package/dist/chat/MentionOption.d.ts +5 -0
- package/dist/chat/MentionPopover.d.ts +10 -0
- package/dist/chat/hooks/useContentEditable.d.ts +10 -0
- package/dist/chat/hooks/useKeyboardNavigation.d.ts +10 -0
- package/dist/chat/hooks/useMentionParser.d.ts +15 -0
- package/dist/chat/hooks/useMentionRenderer.d.ts +22 -0
- package/dist/chat/hooks/useMentionState.d.ts +14 -0
- package/{lib → dist}/hooks/useFencyEventSource/index.d.ts +1 -1
- package/{lib → dist}/index.d.ts +7 -3
- package/dist/index.js +34947 -0
- package/{lib → dist}/provider/FencyContextValue.d.ts +1 -1
- package/{lib → dist}/provider/useFencyContext.d.ts +1 -1
- package/dist/types/AiModel.d.ts +2 -0
- package/{lib → dist}/types/CreateGeminiChatCompletionParams.d.ts +1 -2
- package/{lib → dist}/types/CreateOpenAiChatCompletionParams.d.ts +1 -2
- package/dist/types/FencyContext.d.ts +12 -0
- package/{lib → dist}/types/UseBasicChatCompletions.d.ts +3 -3
- package/{lib → dist}/types/UseStreamingChatCompletions.d.ts +3 -3
- package/package.json +23 -15
- package/lib/hooks/useBasicChatCompletions/index.js +0 -92
- package/lib/hooks/useCreateFiles/index.js +0 -72
- package/lib/hooks/useFencyEventSource/index.js +0 -39
- package/lib/hooks/useListFiles/index.js +0 -125
- package/lib/hooks/useSearchFiles/index.js +0 -26
- package/lib/hooks/useStream/index.js +0 -73
- package/lib/hooks/useStream/toStreamData.js +0 -116
- package/lib/hooks/useStreamingChatCompletions/index.js +0 -205
- package/lib/hooks/useStructuredChatCompletions/index.js +0 -124
- package/lib/hooks/useWebsites/index.js +0 -55
- package/lib/index.js +0 -14
- package/lib/provider/FencyContextValue.js +0 -3
- package/lib/provider/FencyProvider.js +0 -32
- package/lib/provider/useFencyContext.js +0 -12
- package/lib/types/AiModel.d.ts +0 -4
- package/lib/types/AiModel.js +0 -1
- package/lib/types/BasicChatCompletion.js +0 -1
- package/lib/types/BasicChatCompletionData.js +0 -1
- package/lib/types/BasicChatCompletionResponse.js +0 -1
- package/lib/types/CreateBasicChatCompletionParams.js +0 -1
- package/lib/types/CreateClaudeChatCompletionParams.js +0 -1
- package/lib/types/CreateFileParams.js +0 -1
- package/lib/types/CreateGeminiChatCompletionParams.js +0 -1
- package/lib/types/CreateGenericChatCompletionParams.js +0 -169
- package/lib/types/CreateOpenAiChatCompletionParams.js +0 -1
- package/lib/types/CreateStreamResponse.js +0 -1
- package/lib/types/CreateStreamingChatCompletionParams.js +0 -1
- package/lib/types/CreateStreamingChatCompletionResponse.js +0 -1
- package/lib/types/CreateStructuredChatCompletionParams.js +0 -1
- package/lib/types/CreateWebsiteParams.js +0 -1
- package/lib/types/FencyContext.d.ts +0 -6
- package/lib/types/FencyContext.js +0 -1
- package/lib/types/FencyProviderProps.js +0 -1
- package/lib/types/ListFilesPage.js +0 -1
- package/lib/types/ListFilesParams.js +0 -1
- package/lib/types/ListFilesResult.js +0 -1
- package/lib/types/SearchFilesParams.js +0 -1
- package/lib/types/StreamData.js +0 -1
- package/lib/types/StreamError.js +0 -1
- package/lib/types/StreamingChatCompletion.js +0 -1
- package/lib/types/StreamingChatCompletionData.js +0 -1
- package/lib/types/StructuredChatCompletion.js +0 -1
- package/lib/types/StructuredChatCompletionData.js +0 -1
- package/lib/types/StructuredChatCompletionResponse.js +0 -1
- package/lib/types/UseBasicChatCompletions.js +0 -1
- package/lib/types/UseCreateFiles.js +0 -1
- package/lib/types/UseCreateFilesProps.js +0 -1
- package/lib/types/UseListFiles.js +0 -1
- package/lib/types/UseListFilesProps.js +0 -1
- package/lib/types/UseSearchFiles.js +0 -1
- package/lib/types/UseStream.js +0 -1
- package/lib/types/UseStreamProps.js +0 -1
- package/lib/types/UseStreamingChatCompletions.js +0 -1
- package/lib/types/UseStreamingChatCompletionsProps.js +0 -1
- package/lib/types/UseStructuredChatCompletions.js +0 -1
- package/lib/types/UseWebsites.js +0 -1
- package/lib/types/UseWebsitesProps.js +0 -1
- package/lib/types/index.js +0 -48
- /package/{lib → dist}/hooks/useBasicChatCompletions/index.d.ts +0 -0
- /package/{lib → dist}/hooks/useCreateFiles/index.d.ts +0 -0
- /package/{lib → dist}/hooks/useListFiles/index.d.ts +0 -0
- /package/{lib → dist}/hooks/useSearchFiles/index.d.ts +0 -0
- /package/{lib → dist}/hooks/useStream/index.d.ts +0 -0
- /package/{lib → dist}/hooks/useStream/toStreamData.d.ts +0 -0
- /package/{lib → dist}/hooks/useStreamingChatCompletions/index.d.ts +0 -0
- /package/{lib → dist}/hooks/useStructuredChatCompletions/index.d.ts +0 -0
- /package/{lib → dist}/hooks/useWebsites/index.d.ts +0 -0
- /package/{lib → dist}/provider/FencyProvider.d.ts +0 -0
- /package/{lib → dist}/types/BasicChatCompletion.d.ts +0 -0
- /package/{lib → dist}/types/BasicChatCompletionData.d.ts +0 -0
- /package/{lib → dist}/types/BasicChatCompletionResponse.d.ts +0 -0
- /package/{lib → dist}/types/CreateBasicChatCompletionParams.d.ts +0 -0
- /package/{lib → dist}/types/CreateClaudeChatCompletionParams.d.ts +0 -0
- /package/{lib → dist}/types/CreateFileParams.d.ts +0 -0
- /package/{lib → dist}/types/CreateGenericChatCompletionParams.d.ts +0 -0
- /package/{lib → dist}/types/CreateStreamResponse.d.ts +0 -0
- /package/{lib → dist}/types/CreateStreamingChatCompletionParams.d.ts +0 -0
- /package/{lib → dist}/types/CreateStreamingChatCompletionResponse.d.ts +0 -0
- /package/{lib → dist}/types/CreateStructuredChatCompletionParams.d.ts +0 -0
- /package/{lib → dist}/types/CreateWebsiteParams.d.ts +0 -0
- /package/{lib → dist}/types/FencyProviderProps.d.ts +0 -0
- /package/{lib → dist}/types/ListFilesPage.d.ts +0 -0
- /package/{lib → dist}/types/ListFilesParams.d.ts +0 -0
- /package/{lib → dist}/types/ListFilesResult.d.ts +0 -0
- /package/{lib → dist}/types/SearchFilesParams.d.ts +0 -0
- /package/{lib → dist}/types/StreamData.d.ts +0 -0
- /package/{lib → dist}/types/StreamError.d.ts +0 -0
- /package/{lib → dist}/types/StreamingChatCompletion.d.ts +0 -0
- /package/{lib → dist}/types/StreamingChatCompletionData.d.ts +0 -0
- /package/{lib → dist}/types/StructuredChatCompletion.d.ts +0 -0
- /package/{lib → dist}/types/StructuredChatCompletionData.d.ts +0 -0
- /package/{lib → dist}/types/StructuredChatCompletionResponse.d.ts +0 -0
- /package/{lib → dist}/types/UseCreateFiles.d.ts +0 -0
- /package/{lib → dist}/types/UseCreateFilesProps.d.ts +0 -0
- /package/{lib → dist}/types/UseListFiles.d.ts +0 -0
- /package/{lib → dist}/types/UseListFilesProps.d.ts +0 -0
- /package/{lib → dist}/types/UseSearchFiles.d.ts +0 -0
- /package/{lib → dist}/types/UseStream.d.ts +0 -0
- /package/{lib → dist}/types/UseStreamProps.d.ts +0 -0
- /package/{lib → dist}/types/UseStreamingChatCompletionsProps.d.ts +0 -0
- /package/{lib → dist}/types/UseStructuredChatCompletions.d.ts +0 -0
- /package/{lib → dist}/types/UseWebsites.d.ts +0 -0
- /package/{lib → dist}/types/UseWebsitesProps.d.ts +0 -0
- /package/{lib → dist}/types/index.d.ts +0 -0
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
export const toStreamData = (data) => {
|
|
2
|
-
try {
|
|
3
|
-
const json = JSON.parse(data);
|
|
4
|
-
return toStreamDataRaw(json);
|
|
5
|
-
}
|
|
6
|
-
catch (error) {
|
|
7
|
-
console.error('Error parsing message:', error);
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
const toStreamDataRaw = (data) => {
|
|
12
|
-
const basicTypeExist = typeof data === 'object' &&
|
|
13
|
-
data !== null &&
|
|
14
|
-
'type' in data &&
|
|
15
|
-
'streamId' in data &&
|
|
16
|
-
'timestamp' in data;
|
|
17
|
-
if (!basicTypeExist) {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
switch (data.type) {
|
|
21
|
-
case 'NewChatCompletionStreamChunk':
|
|
22
|
-
return toNewChatCompletionStreamChunk(data);
|
|
23
|
-
case 'ChatCompletionStreamCompleted':
|
|
24
|
-
return toChatCompletionStreamCompleted(data);
|
|
25
|
-
case 'StreamTimeout':
|
|
26
|
-
return toStreamTimeout(data);
|
|
27
|
-
case 'StreamNotFound':
|
|
28
|
-
return toStreamNotFound(data);
|
|
29
|
-
case 'FileUploadCompleted':
|
|
30
|
-
return toFileUploadCompleted(data);
|
|
31
|
-
case 'FileTextContentReady':
|
|
32
|
-
return toFileTextContentReady(data);
|
|
33
|
-
case 'WebsiteHtmlContentReady':
|
|
34
|
-
return toWebsiteHtmlContentReady(data);
|
|
35
|
-
case 'WebsiteTextContentReady':
|
|
36
|
-
return toWebsiteTextContentReady(data);
|
|
37
|
-
case 'FileSearchIndexReady':
|
|
38
|
-
return toFileSearchIndexReady(data);
|
|
39
|
-
}
|
|
40
|
-
return null;
|
|
41
|
-
};
|
|
42
|
-
const toNewChatCompletionStreamChunk = (data) => {
|
|
43
|
-
return {
|
|
44
|
-
type: 'NewChatCompletionStreamChunk',
|
|
45
|
-
streamId: data.streamId,
|
|
46
|
-
chatCompletionId: data.chatCompletionId,
|
|
47
|
-
timestamp: data.timestamp,
|
|
48
|
-
content: data.content,
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
|
-
const toChatCompletionStreamCompleted = (data) => {
|
|
52
|
-
return {
|
|
53
|
-
type: 'ChatCompletionStreamCompleted',
|
|
54
|
-
streamId: data.streamId,
|
|
55
|
-
chatCompletionId: data.chatCompletionId,
|
|
56
|
-
timestamp: data.timestamp,
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
const toStreamTimeout = (data) => {
|
|
60
|
-
return {
|
|
61
|
-
type: 'StreamTimeout',
|
|
62
|
-
streamId: data.streamId,
|
|
63
|
-
timestamp: data.timestamp,
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
const toStreamNotFound = (data) => {
|
|
67
|
-
return {
|
|
68
|
-
type: 'StreamNotFound',
|
|
69
|
-
streamId: data.streamId,
|
|
70
|
-
timestamp: data.timestamp,
|
|
71
|
-
};
|
|
72
|
-
};
|
|
73
|
-
const toFileUploadCompleted = (data) => {
|
|
74
|
-
return {
|
|
75
|
-
type: 'FileUploadCompleted',
|
|
76
|
-
streamId: data.streamId,
|
|
77
|
-
uploadId: data.fileId,
|
|
78
|
-
fileId: data.fileId,
|
|
79
|
-
timestamp: data.timestamp,
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
const toFileTextContentReady = (data) => {
|
|
83
|
-
return {
|
|
84
|
-
type: 'FileTextContentReady',
|
|
85
|
-
streamId: data.streamId,
|
|
86
|
-
fileId: data.fileId,
|
|
87
|
-
textContent: data.textContent,
|
|
88
|
-
timestamp: data.timestamp,
|
|
89
|
-
};
|
|
90
|
-
};
|
|
91
|
-
const toWebsiteHtmlContentReady = (data) => {
|
|
92
|
-
return {
|
|
93
|
-
type: 'WebsiteHtmlContentReady',
|
|
94
|
-
streamId: data.streamId,
|
|
95
|
-
websiteId: data.websiteId,
|
|
96
|
-
htmlContent: data.htmlContent,
|
|
97
|
-
timestamp: data.timestamp,
|
|
98
|
-
};
|
|
99
|
-
};
|
|
100
|
-
const toWebsiteTextContentReady = (data) => {
|
|
101
|
-
return {
|
|
102
|
-
type: 'WebsiteTextContentReady',
|
|
103
|
-
streamId: data.streamId,
|
|
104
|
-
websiteId: data.websiteId,
|
|
105
|
-
textContent: data.textContent,
|
|
106
|
-
timestamp: data.timestamp,
|
|
107
|
-
};
|
|
108
|
-
};
|
|
109
|
-
const toFileSearchIndexReady = (data) => {
|
|
110
|
-
return {
|
|
111
|
-
type: 'FileSearchIndexReady',
|
|
112
|
-
streamId: data.streamId,
|
|
113
|
-
fileId: data.fileId,
|
|
114
|
-
timestamp: data.timestamp,
|
|
115
|
-
};
|
|
116
|
-
};
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { createChatCompletion } from '@fencyai/js';
|
|
2
|
-
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
3
|
-
import { useFencyContext } from '../../provider/useFencyContext';
|
|
4
|
-
import { toSpecificChatCompletionParams } from '../../types/CreateGenericChatCompletionParams';
|
|
5
|
-
import { useStream } from '../useStream';
|
|
6
|
-
export const useStreamingChatCompletions = (props) => {
|
|
7
|
-
const context = useFencyContext();
|
|
8
|
-
const [chatCompletions, setChatCompletions] = useState([]);
|
|
9
|
-
const [completedStreamIds, setCompletedStreamIds] = useState([]);
|
|
10
|
-
const [chunks, setChunks] = useState([]);
|
|
11
|
-
const { createStream } = useStream({
|
|
12
|
-
onNewChatCompletionStreamChunk: (streamData) => {
|
|
13
|
-
props?.onChatCompletionStreamChunk?.(streamData);
|
|
14
|
-
setChunks((prev) => [...prev, streamData]);
|
|
15
|
-
},
|
|
16
|
-
onChatCompletionStreamCompleted: (stream) => {
|
|
17
|
-
props?.onChatCompletionStreamCompleted?.(stream);
|
|
18
|
-
setCompletedStreamIds((prev) => [...prev, stream.streamId]);
|
|
19
|
-
},
|
|
20
|
-
onStreamError: (error) => {
|
|
21
|
-
props?.onStreamError?.(error);
|
|
22
|
-
setChatCompletions((prev) => {
|
|
23
|
-
const existing = prev.find((c) => c.streamId === error.streamId);
|
|
24
|
-
if (!existing)
|
|
25
|
-
return prev;
|
|
26
|
-
return [
|
|
27
|
-
...prev.filter((c) => c.streamId === error.streamId),
|
|
28
|
-
{
|
|
29
|
-
...existing,
|
|
30
|
-
loading: false,
|
|
31
|
-
error: error.error,
|
|
32
|
-
},
|
|
33
|
-
];
|
|
34
|
-
});
|
|
35
|
-
},
|
|
36
|
-
onStreamNotFound: (error) => {
|
|
37
|
-
props?.onStreamNotFound?.(error);
|
|
38
|
-
},
|
|
39
|
-
onStreamTimeout: (error) => {
|
|
40
|
-
props?.onStreamTimeout?.(error);
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
setChatCompletions((prev) => {
|
|
45
|
-
return prev.map((chatCompletion) => {
|
|
46
|
-
if (completedStreamIds.includes(chatCompletion.streamId)) {
|
|
47
|
-
return {
|
|
48
|
-
...chatCompletion,
|
|
49
|
-
doneStreaming: true,
|
|
50
|
-
loading: false,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
return chatCompletion;
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
}, [completedStreamIds]);
|
|
57
|
-
useEffect(() => {
|
|
58
|
-
const newChatCompletions = [];
|
|
59
|
-
for (const chatCompletion of chatCompletions) {
|
|
60
|
-
const relevantChunks = chunks
|
|
61
|
-
.filter((chunk) => {
|
|
62
|
-
return chunk.streamId === chatCompletion.streamId;
|
|
63
|
-
})
|
|
64
|
-
.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
65
|
-
const fullMessage = relevantChunks
|
|
66
|
-
.map((chunk) => chunk.content)
|
|
67
|
-
.join('');
|
|
68
|
-
newChatCompletions.push({
|
|
69
|
-
triggeredAt: chatCompletion.triggeredAt,
|
|
70
|
-
data: chatCompletion.data
|
|
71
|
-
? {
|
|
72
|
-
id: chatCompletion.data.id,
|
|
73
|
-
createdAt: chatCompletion.data.createdAt,
|
|
74
|
-
streamId: chatCompletion.data.streamId,
|
|
75
|
-
}
|
|
76
|
-
: null,
|
|
77
|
-
streamId: chatCompletion.streamId,
|
|
78
|
-
error: chatCompletion.error,
|
|
79
|
-
prompt: chatCompletion.prompt,
|
|
80
|
-
loading: chatCompletion.loading,
|
|
81
|
-
doneStreaming: chatCompletion.doneStreaming,
|
|
82
|
-
response: fullMessage,
|
|
83
|
-
chunks: relevantChunks,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
setChatCompletions(newChatCompletions);
|
|
87
|
-
}, [chunks]);
|
|
88
|
-
const createStreamingChatCompletion = useCallback(async (params) => {
|
|
89
|
-
// Step 1: Create stream if not exists
|
|
90
|
-
const streamResponse = await createStream({
|
|
91
|
-
type: 'ChatCompletionStream',
|
|
92
|
-
});
|
|
93
|
-
if (streamResponse.type === 'success') {
|
|
94
|
-
setChatCompletions([
|
|
95
|
-
...chatCompletions,
|
|
96
|
-
{
|
|
97
|
-
streamId: streamResponse.stream.id,
|
|
98
|
-
triggeredAt: new Date().toISOString(),
|
|
99
|
-
data: null,
|
|
100
|
-
error: null,
|
|
101
|
-
prompt: params,
|
|
102
|
-
response: '',
|
|
103
|
-
chunks: [],
|
|
104
|
-
loading: true,
|
|
105
|
-
doneStreaming: false,
|
|
106
|
-
},
|
|
107
|
-
]);
|
|
108
|
-
const specificParams = toSpecificChatCompletionParams(params.openai, params.gemini, params.claude, params.generic);
|
|
109
|
-
// Step 2: Send chat completion
|
|
110
|
-
const chatCompletion = await createChatCompletion({
|
|
111
|
-
pk: context.fency.publishableKey,
|
|
112
|
-
baseUrl: context.fency.baseUrl,
|
|
113
|
-
request: {
|
|
114
|
-
streamId: streamResponse.stream.id,
|
|
115
|
-
...specificParams,
|
|
116
|
-
},
|
|
117
|
-
});
|
|
118
|
-
if (chatCompletion.type === 'success' &&
|
|
119
|
-
chatCompletion.completion) {
|
|
120
|
-
setChatCompletions((prev) => [
|
|
121
|
-
...prev.filter((c) => c.streamId !== streamResponse.stream.id),
|
|
122
|
-
{
|
|
123
|
-
streamId: streamResponse.stream.id,
|
|
124
|
-
triggeredAt: new Date().toISOString(),
|
|
125
|
-
data: {
|
|
126
|
-
id: chatCompletion.completion.id,
|
|
127
|
-
createdAt: chatCompletion.completion.createdAt,
|
|
128
|
-
streamId: streamResponse.stream.id,
|
|
129
|
-
},
|
|
130
|
-
error: null,
|
|
131
|
-
prompt: params,
|
|
132
|
-
response: '',
|
|
133
|
-
chunks: [],
|
|
134
|
-
doneStreaming: false,
|
|
135
|
-
loading: true,
|
|
136
|
-
},
|
|
137
|
-
]);
|
|
138
|
-
return {
|
|
139
|
-
type: 'success',
|
|
140
|
-
streamId: streamResponse.stream.id,
|
|
141
|
-
chatCompletionId: chatCompletion.completion.id,
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
else if (chatCompletion.type === 'error') {
|
|
145
|
-
setChatCompletions((prev) => [
|
|
146
|
-
...prev.filter((c) => c.streamId !== streamResponse.stream.id),
|
|
147
|
-
{
|
|
148
|
-
triggeredAt: new Date().toISOString(),
|
|
149
|
-
streamId: streamResponse.stream.id,
|
|
150
|
-
prompt: params,
|
|
151
|
-
error: chatCompletion.error,
|
|
152
|
-
response: '',
|
|
153
|
-
chunks: [],
|
|
154
|
-
loading: false,
|
|
155
|
-
doneStreaming: false,
|
|
156
|
-
data: null,
|
|
157
|
-
},
|
|
158
|
-
]);
|
|
159
|
-
return {
|
|
160
|
-
type: 'error',
|
|
161
|
-
error: chatCompletion.error,
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
const error = {
|
|
166
|
-
message: 'No response received',
|
|
167
|
-
code: 'UnknownError',
|
|
168
|
-
};
|
|
169
|
-
setChatCompletions((prev) => [
|
|
170
|
-
...prev.filter((c) => c.streamId !== streamResponse.stream.id),
|
|
171
|
-
{
|
|
172
|
-
triggeredAt: new Date().toISOString(),
|
|
173
|
-
streamId: streamResponse.stream.id,
|
|
174
|
-
error: error,
|
|
175
|
-
prompt: params,
|
|
176
|
-
response: '',
|
|
177
|
-
chunks: [],
|
|
178
|
-
loading: false,
|
|
179
|
-
doneStreaming: false,
|
|
180
|
-
data: null,
|
|
181
|
-
},
|
|
182
|
-
]);
|
|
183
|
-
return {
|
|
184
|
-
type: 'error',
|
|
185
|
-
error: error,
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
else {
|
|
190
|
-
console.error(streamResponse.error);
|
|
191
|
-
return streamResponse;
|
|
192
|
-
}
|
|
193
|
-
}, [context, chatCompletions]);
|
|
194
|
-
const latest = useMemo(() => {
|
|
195
|
-
return chatCompletions.sort((a, b) => {
|
|
196
|
-
return (new Date(b.triggeredAt).getTime() -
|
|
197
|
-
new Date(a.triggeredAt).getTime());
|
|
198
|
-
})[0];
|
|
199
|
-
}, [chatCompletions]);
|
|
200
|
-
return {
|
|
201
|
-
chatCompletions,
|
|
202
|
-
createStreamingChatCompletion,
|
|
203
|
-
latest,
|
|
204
|
-
};
|
|
205
|
-
};
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { createChatCompletion } from '@fencyai/js';
|
|
2
|
-
import { useCallback, useMemo, useState } from 'react';
|
|
3
|
-
import { z } from 'zod';
|
|
4
|
-
import { useFencyContext } from '../../provider/useFencyContext';
|
|
5
|
-
import { toSpecificChatCompletionParams } from '../../types/CreateGenericChatCompletionParams';
|
|
6
|
-
export const useStructuredChatCompletions = () => {
|
|
7
|
-
const context = useFencyContext();
|
|
8
|
-
const [chatCompletions, setChatCompletions] = useState([]);
|
|
9
|
-
const createStructuredChatCompletion = useCallback(async (params) => {
|
|
10
|
-
const triggeredAt = new Date().toISOString();
|
|
11
|
-
setChatCompletions((prev) => [
|
|
12
|
-
...prev,
|
|
13
|
-
{
|
|
14
|
-
triggeredAt,
|
|
15
|
-
data: null,
|
|
16
|
-
error: null,
|
|
17
|
-
loading: true,
|
|
18
|
-
},
|
|
19
|
-
]);
|
|
20
|
-
const jsonSchema = z.toJSONSchema(params.responseFormat);
|
|
21
|
-
const parseResponse = (response, params) => {
|
|
22
|
-
try {
|
|
23
|
-
return params.responseFormat.parse(JSON.parse(response));
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
console.error('could not parse response', response);
|
|
27
|
-
console.error(error);
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
const parsedJsonSchema = JSON.stringify(jsonSchema);
|
|
32
|
-
const specificParams = toSpecificChatCompletionParams(params.openai, params.gemini, params.claude, params.generic);
|
|
33
|
-
const response = await createChatCompletion({
|
|
34
|
-
pk: context.fency.publishableKey,
|
|
35
|
-
baseUrl: context.fency.baseUrl,
|
|
36
|
-
request: {
|
|
37
|
-
openai: specificParams.openai
|
|
38
|
-
? {
|
|
39
|
-
responseJsonSchema: parsedJsonSchema,
|
|
40
|
-
...specificParams.openai,
|
|
41
|
-
}
|
|
42
|
-
: undefined,
|
|
43
|
-
gemini: specificParams.gemini
|
|
44
|
-
? {
|
|
45
|
-
responseJsonSchema: parsedJsonSchema,
|
|
46
|
-
...specificParams.gemini,
|
|
47
|
-
}
|
|
48
|
-
: undefined,
|
|
49
|
-
claude: specificParams.claude
|
|
50
|
-
? {
|
|
51
|
-
...specificParams.claude,
|
|
52
|
-
}
|
|
53
|
-
: undefined,
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
if (response.type === 'success') {
|
|
57
|
-
if (response.completion.response) {
|
|
58
|
-
const structuredResponse = parseResponse(response.completion.response, params);
|
|
59
|
-
const data = {
|
|
60
|
-
id: response.completion.id,
|
|
61
|
-
createdAt: response.completion.createdAt,
|
|
62
|
-
response: structuredResponse,
|
|
63
|
-
structuredResponse: structuredResponse,
|
|
64
|
-
};
|
|
65
|
-
const structuredChatCompletion = {
|
|
66
|
-
triggeredAt,
|
|
67
|
-
data: data,
|
|
68
|
-
error: null,
|
|
69
|
-
loading: false,
|
|
70
|
-
};
|
|
71
|
-
setChatCompletions((prev) => [
|
|
72
|
-
...prev.filter((c) => c.triggeredAt !== triggeredAt),
|
|
73
|
-
structuredChatCompletion,
|
|
74
|
-
]);
|
|
75
|
-
return {
|
|
76
|
-
type: 'success',
|
|
77
|
-
data: data,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
const error = {
|
|
82
|
-
code: 'NoResponse',
|
|
83
|
-
message: 'No response from chat completion',
|
|
84
|
-
};
|
|
85
|
-
setChatCompletions((prev) => [
|
|
86
|
-
...prev.filter((c) => c.triggeredAt !== triggeredAt),
|
|
87
|
-
{
|
|
88
|
-
triggeredAt,
|
|
89
|
-
data: null,
|
|
90
|
-
error: error,
|
|
91
|
-
loading: false,
|
|
92
|
-
},
|
|
93
|
-
]);
|
|
94
|
-
return {
|
|
95
|
-
type: 'error',
|
|
96
|
-
error: error,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
setChatCompletions((prev) => [
|
|
102
|
-
...prev.filter((c) => c.triggeredAt !== triggeredAt),
|
|
103
|
-
{
|
|
104
|
-
triggeredAt,
|
|
105
|
-
data: null,
|
|
106
|
-
error: response.error,
|
|
107
|
-
loading: false,
|
|
108
|
-
},
|
|
109
|
-
]);
|
|
110
|
-
return response;
|
|
111
|
-
}
|
|
112
|
-
}, [context]);
|
|
113
|
-
const latest = useMemo(() => {
|
|
114
|
-
return chatCompletions.sort((a, b) => {
|
|
115
|
-
return (new Date(b.triggeredAt).getTime() -
|
|
116
|
-
new Date(a.triggeredAt).getTime());
|
|
117
|
-
})[0];
|
|
118
|
-
}, [chatCompletions]);
|
|
119
|
-
return {
|
|
120
|
-
chatCompletions,
|
|
121
|
-
createStructuredChatCompletion,
|
|
122
|
-
latest,
|
|
123
|
-
};
|
|
124
|
-
};
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { createWebsite as createWebsiteApi, } from '@fencyai/js';
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import { useFencyContext } from '../../provider/useFencyContext';
|
|
4
|
-
import { useStream } from '../useStream';
|
|
5
|
-
export function useWebsites(props) {
|
|
6
|
-
const context = useFencyContext();
|
|
7
|
-
const [websites, setWebsites] = useState([]);
|
|
8
|
-
const { createStream } = useStream({
|
|
9
|
-
onWebsiteHtmlContentReady: (streamData) => {
|
|
10
|
-
props?.onHtmlContentReady?.(streamData);
|
|
11
|
-
setWebsites((prev) => prev.map((website) => {
|
|
12
|
-
return website.id === streamData.websiteId
|
|
13
|
-
? { ...website, htmlContent: streamData.htmlContent }
|
|
14
|
-
: website;
|
|
15
|
-
}));
|
|
16
|
-
},
|
|
17
|
-
onWebsiteTextContentReady: (streamData) => {
|
|
18
|
-
props?.onTextContentReady?.(streamData);
|
|
19
|
-
setWebsites((prev) => prev.map((website) => website.id === streamData.websiteId
|
|
20
|
-
? { ...website, textContent: streamData.textContent }
|
|
21
|
-
: website));
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
const createWebsite = async (params) => {
|
|
25
|
-
const stream = await createStream({
|
|
26
|
-
type: 'ChatCompletionStream',
|
|
27
|
-
});
|
|
28
|
-
if (stream.type === 'success') {
|
|
29
|
-
const response = await createWebsiteApi({
|
|
30
|
-
pk: context.fency.publishableKey,
|
|
31
|
-
request: {
|
|
32
|
-
url: params.url,
|
|
33
|
-
streamId: stream.stream.id,
|
|
34
|
-
extractHtmlContent: params.extractHtmlContent || true,
|
|
35
|
-
extractTextContent: params.extractTextContent || true,
|
|
36
|
-
},
|
|
37
|
-
baseUrl: context.fency.baseUrl,
|
|
38
|
-
});
|
|
39
|
-
if (response.type === 'success') {
|
|
40
|
-
setWebsites([...websites, response.website]);
|
|
41
|
-
}
|
|
42
|
-
return response;
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
return {
|
|
46
|
-
type: 'error',
|
|
47
|
-
error: stream.error,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
return {
|
|
52
|
-
createWebsite,
|
|
53
|
-
websites,
|
|
54
|
-
};
|
|
55
|
-
}
|
package/lib/index.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// Re-export components and hooks
|
|
2
|
-
export { useBasicChatCompletions } from './hooks/useBasicChatCompletions';
|
|
3
|
-
export { useSearchFiles } from './hooks/useSearchFiles';
|
|
4
|
-
export { useCreateFiles } from './hooks/useCreateFiles';
|
|
5
|
-
export { useListFiles } from './hooks/useListFiles';
|
|
6
|
-
export { useStreamingChatCompletions } from './hooks/useStreamingChatCompletions';
|
|
7
|
-
export { useStructuredChatCompletions } from './hooks/useStructuredChatCompletions';
|
|
8
|
-
export { useWebsites } from './hooks/useWebsites';
|
|
9
|
-
export { useStream } from './hooks/useStream';
|
|
10
|
-
export { useFencyEventSource } from './hooks/useFencyEventSource';
|
|
11
|
-
// Re-export providers
|
|
12
|
-
export { FencyProvider } from './provider/FencyProvider';
|
|
13
|
-
// Re-export all types from centralized location
|
|
14
|
-
export * from './types';
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState } from 'react';
|
|
3
|
-
import { FencyContextValue } from './FencyContextValue';
|
|
4
|
-
export function FencyProvider({ fency, children }) {
|
|
5
|
-
const [fencyInstance, setFencyInstance] = useState(null);
|
|
6
|
-
const [loading, setLoading] = useState(true);
|
|
7
|
-
const [error, setError] = useState(null);
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
fency
|
|
10
|
-
.then((instance) => {
|
|
11
|
-
setFencyInstance(instance);
|
|
12
|
-
setLoading(false);
|
|
13
|
-
})
|
|
14
|
-
.catch((err) => {
|
|
15
|
-
setError(err);
|
|
16
|
-
setLoading(false);
|
|
17
|
-
});
|
|
18
|
-
}, [fency]);
|
|
19
|
-
if (error) {
|
|
20
|
-
return _jsxs("div", { children: ["Fency error: ", error.message] });
|
|
21
|
-
}
|
|
22
|
-
// Only render children and provide context when fency is loaded
|
|
23
|
-
if (!fencyInstance) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
const value = {
|
|
27
|
-
fency: fencyInstance,
|
|
28
|
-
loading,
|
|
29
|
-
error,
|
|
30
|
-
};
|
|
31
|
-
return (_jsx(FencyContextValue.Provider, { value: value, children: children }));
|
|
32
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { useContext } from 'react';
|
|
2
|
-
import { FencyContextValue } from './FencyContextValue';
|
|
3
|
-
/**
|
|
4
|
-
* Hook to access Fency instance and loading state
|
|
5
|
-
*/
|
|
6
|
-
export function useFencyContext() {
|
|
7
|
-
const context = useContext(FencyContextValue);
|
|
8
|
-
if (context === undefined) {
|
|
9
|
-
throw new Error('useFencyContext must be used within a FencyProvider');
|
|
10
|
-
}
|
|
11
|
-
return context;
|
|
12
|
-
}
|
package/lib/types/AiModel.d.ts
DELETED
package/lib/types/AiModel.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|