@fencyai/react 0.1.33 → 0.1.34
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/lib/chat-completions/ChatCompletionProvider.d.ts +22 -0
- package/lib/{FencyProvider.js → chat-completions/ChatCompletionProvider.js} +3 -3
- package/lib/chat-completions/useChatCompletionContext.d.ts +5 -0
- package/lib/chat-completions/useChatCompletionContext.js +12 -0
- package/lib/{hooks → chat-completions}/useChatCompletions.js +15 -16
- package/lib/{hooks → chat-completions}/useEventSource.js +10 -3
- package/lib/index.d.ts +4 -4
- package/lib/index.js +3 -3
- package/package.json +4 -4
- package/lib/FencyProvider.d.ts +0 -19
- package/lib/hooks/useFency.d.ts +0 -5
- package/lib/hooks/useFency.js +0 -12
- /package/lib/{hooks → chat-completions}/useChatCompletions.d.ts +0 -0
- /package/lib/{hooks → chat-completions}/useEventSource.d.ts +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FencyInstance } from '@fencyai/js';
|
|
2
|
+
export declare const ChatCompletionContextValue: import("react").Context<ChatCompletionContext | undefined>;
|
|
3
|
+
/**
|
|
4
|
+
* Provider component that provides Fency instance to child components
|
|
5
|
+
* Expects a promise that resolves to a Fency instance
|
|
6
|
+
*/
|
|
7
|
+
export declare function ChatCompletionProvider({ fency, children, }: ChatCompletionProviderProps): import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export interface ChatCompletionContext {
|
|
9
|
+
fency: FencyInstance;
|
|
10
|
+
loading: boolean;
|
|
11
|
+
error: Error | null;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Props for ChatCompletionProvider
|
|
15
|
+
*/
|
|
16
|
+
export interface ChatCompletionProviderProps {
|
|
17
|
+
fency: Promise<FencyInstance>;
|
|
18
|
+
children: React.ReactNode;
|
|
19
|
+
options?: {
|
|
20
|
+
fetchClientSecret: () => Promise<string>;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, useEffect, useState } from 'react';
|
|
3
3
|
// Create the context
|
|
4
|
-
export const
|
|
4
|
+
export const ChatCompletionContextValue = createContext(undefined);
|
|
5
5
|
/**
|
|
6
6
|
* Provider component that provides Fency instance to child components
|
|
7
7
|
* Expects a promise that resolves to a Fency instance
|
|
8
8
|
*/
|
|
9
|
-
export function
|
|
9
|
+
export function ChatCompletionProvider({ fency, children, }) {
|
|
10
10
|
const [fencyInstance, setFencyInstance] = useState(null);
|
|
11
11
|
const [loading, setLoading] = useState(true);
|
|
12
12
|
const [error, setError] = useState(null);
|
|
@@ -33,5 +33,5 @@ export function FencyProvider({ fency, children }) {
|
|
|
33
33
|
loading,
|
|
34
34
|
error,
|
|
35
35
|
};
|
|
36
|
-
return (_jsx(
|
|
36
|
+
return (_jsx(ChatCompletionContextValue.Provider, { value: value, children: children }));
|
|
37
37
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
import { ChatCompletionContextValue } from './ChatCompletionProvider';
|
|
3
|
+
/**
|
|
4
|
+
* Hook to access Fency instance and loading state
|
|
5
|
+
*/
|
|
6
|
+
export function useChatCompletionContext() {
|
|
7
|
+
const context = useContext(ChatCompletionContextValue);
|
|
8
|
+
if (context === undefined) {
|
|
9
|
+
throw new Error('useChatCompletionContext must be used within a ChatCompletionProvider');
|
|
10
|
+
}
|
|
11
|
+
return context;
|
|
12
|
+
}
|
|
@@ -2,25 +2,24 @@
|
|
|
2
2
|
import { createChatCompletion, createChatCompletionStream, } from '@fencyai/js';
|
|
3
3
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
4
4
|
import z from 'zod';
|
|
5
|
+
import { useChatCompletionContext } from './useChatCompletionContext';
|
|
5
6
|
import { useEventSource } from './useEventSource';
|
|
6
|
-
import { useFency } from './useFency';
|
|
7
7
|
export function useChatCompletions() {
|
|
8
|
-
const
|
|
8
|
+
const context = useChatCompletionContext();
|
|
9
9
|
const { chunks, setUrl } = useEventSource();
|
|
10
10
|
const [chatCompletions, setChatCompletions] = useState([]);
|
|
11
11
|
const [stream, setStream] = useState(null);
|
|
12
|
-
console.log('v2');
|
|
13
12
|
const createStreamingChatCompletion = useCallback(async (params) => {
|
|
14
13
|
// Step 1: Create stream if not exists
|
|
15
14
|
const s = await createChatCompletionStream({
|
|
16
|
-
pk:
|
|
17
|
-
baseUrl:
|
|
15
|
+
pk: context.fency.publishableKey,
|
|
16
|
+
baseUrl: context.fency.baseUrl,
|
|
18
17
|
});
|
|
19
18
|
setStream(s);
|
|
20
19
|
// Step 2: Send chat completion
|
|
21
20
|
const chatCompletion = await createChatCompletion({
|
|
22
|
-
pk:
|
|
23
|
-
baseUrl:
|
|
21
|
+
pk: context.fency.publishableKey,
|
|
22
|
+
baseUrl: context.fency.baseUrl,
|
|
24
23
|
request: {
|
|
25
24
|
streamId: s.id,
|
|
26
25
|
openai: params.openai
|
|
@@ -48,11 +47,11 @@ export function useChatCompletions() {
|
|
|
48
47
|
chatCompletionStreamId: s.id,
|
|
49
48
|
chatCompletionId: chatCompletion.id,
|
|
50
49
|
};
|
|
51
|
-
}, [
|
|
50
|
+
}, [context]);
|
|
52
51
|
const createSynchronousChatCompletion = useCallback(async (params) => {
|
|
53
52
|
const chatCompletion = await createChatCompletion({
|
|
54
|
-
pk:
|
|
55
|
-
baseUrl:
|
|
53
|
+
pk: context.fency.publishableKey,
|
|
54
|
+
baseUrl: context.fency.baseUrl,
|
|
56
55
|
request: {
|
|
57
56
|
openai: params.openai
|
|
58
57
|
? {
|
|
@@ -76,13 +75,13 @@ export function useChatCompletions() {
|
|
|
76
75
|
});
|
|
77
76
|
setChatCompletions((prev) => [...prev, chatCompletion]);
|
|
78
77
|
return chatCompletion;
|
|
79
|
-
}, [
|
|
78
|
+
}, [context]);
|
|
80
79
|
const createStructuredChatCompletion = useCallback(async (params) => {
|
|
81
80
|
const jsonSchema = z.toJSONSchema(params.responseFormat);
|
|
82
81
|
const parsedJsonSchema = JSON.stringify(jsonSchema);
|
|
83
82
|
const chatCompletion = await createChatCompletion({
|
|
84
|
-
pk:
|
|
85
|
-
baseUrl:
|
|
83
|
+
pk: context.fency.publishableKey,
|
|
84
|
+
baseUrl: context.fency.baseUrl,
|
|
86
85
|
request: {
|
|
87
86
|
openai: params.openai
|
|
88
87
|
? {
|
|
@@ -114,7 +113,7 @@ export function useChatCompletions() {
|
|
|
114
113
|
};
|
|
115
114
|
}
|
|
116
115
|
throw new Error('No response from chat completion');
|
|
117
|
-
}, [
|
|
116
|
+
}, [context]);
|
|
118
117
|
const completions = useMemo(() => {
|
|
119
118
|
const completions = [];
|
|
120
119
|
for (const chatCompletion of chatCompletions) {
|
|
@@ -137,9 +136,9 @@ export function useChatCompletions() {
|
|
|
137
136
|
}, [completions]);
|
|
138
137
|
useEffect(() => {
|
|
139
138
|
if (stream) {
|
|
140
|
-
setUrl(`${
|
|
139
|
+
setUrl(`${context.fency.baseUrl}/v1/pub/chat-completion-streams/${stream.id}?pk=${context.fency.publishableKey}`);
|
|
141
140
|
}
|
|
142
|
-
}, [stream,
|
|
141
|
+
}, [stream, context.fency.publishableKey, setUrl]);
|
|
143
142
|
return {
|
|
144
143
|
createChatCompletion: createSynchronousChatCompletion,
|
|
145
144
|
createStructuredChatCompletion: createStructuredChatCompletion,
|
|
@@ -6,17 +6,24 @@ export function useEventSource() {
|
|
|
6
6
|
if (!url)
|
|
7
7
|
return;
|
|
8
8
|
const eventSource = new EventSource(url);
|
|
9
|
-
eventSource.onmessage = (
|
|
10
|
-
|
|
9
|
+
eventSource.onmessage = (message) => {
|
|
10
|
+
if (message.data === '__END_OF_STREAM__') {
|
|
11
|
+
eventSource.close();
|
|
12
|
+
setUrl(null); // Clear URL to prevent reconnection
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const chunk = getChatCompletionChunk(message);
|
|
11
16
|
if (chunk) {
|
|
12
17
|
setChunks((prev) => [...prev, chunk]);
|
|
13
18
|
}
|
|
14
19
|
else {
|
|
15
|
-
console.warn('Unknown message:',
|
|
20
|
+
console.warn('Unknown message:', message);
|
|
16
21
|
}
|
|
17
22
|
};
|
|
18
23
|
eventSource.onerror = (error) => {
|
|
19
24
|
console.error('EventSource error:', error);
|
|
25
|
+
eventSource.close();
|
|
26
|
+
setUrl(null); // Clear URL on error
|
|
20
27
|
};
|
|
21
28
|
return () => {
|
|
22
29
|
eventSource.close();
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export type {
|
|
1
|
+
export { ChatCompletionProvider } from './chat-completions/ChatCompletionProvider';
|
|
2
|
+
export { useChatCompletionContext } from './chat-completions/useChatCompletionContext';
|
|
3
|
+
export { useChatCompletions } from './chat-completions/useChatCompletions';
|
|
4
|
+
export type { ChatCompletionContext, ChatCompletionProviderProps, } from './chat-completions/ChatCompletionProvider';
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Re-export components and hooks
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
2
|
+
export { ChatCompletionProvider } from './chat-completions/ChatCompletionProvider';
|
|
3
|
+
export { useChatCompletionContext } from './chat-completions/useChatCompletionContext';
|
|
4
|
+
export { useChatCompletions } from './chat-completions/useChatCompletions';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fencyai/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"description": "> TODO: description",
|
|
5
5
|
"author": "staklau <steinaageklaussen@gmail.com>",
|
|
6
6
|
"homepage": "",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"zod": "^4.0.5"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@fencyai/js": "^0.1.
|
|
39
|
+
"@fencyai/js": "^0.1.34",
|
|
40
40
|
"@types/jest": "^29.5.11",
|
|
41
41
|
"@types/node": "^20.10.5",
|
|
42
42
|
"@types/react": "^18.2.45",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"typescript": "^5.3.3"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@fencyai/js": "^0.1.
|
|
48
|
+
"@fencyai/js": "^0.1.34",
|
|
49
49
|
"react": ">=16.8.0"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "a4dcf1572fcf4587355ffe38e6971b18025e4568"
|
|
52
52
|
}
|
package/lib/FencyProvider.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { FencyInstance } from '@fencyai/js';
|
|
2
|
-
export declare const FencyContextValue: import("react").Context<FencyContext | undefined>;
|
|
3
|
-
/**
|
|
4
|
-
* Provider component that provides Fency instance to child components
|
|
5
|
-
* Expects a promise that resolves to a Fency instance
|
|
6
|
-
*/
|
|
7
|
-
export declare function FencyProvider({ fency, children }: FencyProviderProps): import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
-
export interface FencyContext {
|
|
9
|
-
fency: FencyInstance;
|
|
10
|
-
loading: boolean;
|
|
11
|
-
error: Error | null;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Props for FencyProvider
|
|
15
|
-
*/
|
|
16
|
-
export interface FencyProviderProps {
|
|
17
|
-
fency: Promise<FencyInstance>;
|
|
18
|
-
children: React.ReactNode;
|
|
19
|
-
}
|
package/lib/hooks/useFency.d.ts
DELETED
package/lib/hooks/useFency.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { useContext } from 'react';
|
|
2
|
-
import { FencyContextValue } from '../FencyProvider';
|
|
3
|
-
/**
|
|
4
|
-
* Hook to access Fency instance and loading state
|
|
5
|
-
*/
|
|
6
|
-
export function useFency() {
|
|
7
|
-
const context = useContext(FencyContextValue);
|
|
8
|
-
if (context === undefined) {
|
|
9
|
-
throw new Error('useFency must be used within a FencyProvider');
|
|
10
|
-
}
|
|
11
|
-
return context;
|
|
12
|
-
}
|
|
File without changes
|
|
File without changes
|