@fencyai/react 0.1.33 → 0.1.35
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.d.ts +1 -4
- package/lib/{hooks → chat-completions}/useChatCompletions.js +15 -22
- 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}/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
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChatCompletion,
|
|
1
|
+
import { ChatCompletion, CreateGeminiChatCompletionParams, CreateOpenAiChatCompletionParams } from '@fencyai/js';
|
|
2
2
|
import z, { ZodTypeAny } from 'zod';
|
|
3
3
|
import { ChatCompletionChunk } from './useEventSource';
|
|
4
4
|
interface Completions {
|
|
@@ -13,12 +13,10 @@ interface HookResponse {
|
|
|
13
13
|
createChatCompletion: (params: {
|
|
14
14
|
openai?: CreateOpenAiChatCompletionParams;
|
|
15
15
|
gemini?: CreateGeminiChatCompletionParams;
|
|
16
|
-
anthropic?: CreateAnthropicChatCompletionParams;
|
|
17
16
|
}) => Promise<ChatCompletion>;
|
|
18
17
|
createStructuredChatCompletion: <T extends ZodTypeAny>(params: {
|
|
19
18
|
openai?: CreateOpenAiChatCompletionParams;
|
|
20
19
|
gemini?: CreateGeminiChatCompletionParams;
|
|
21
|
-
anthropic?: CreateAnthropicChatCompletionParams;
|
|
22
20
|
responseFormat: T;
|
|
23
21
|
}) => Promise<ChatCompletion & {
|
|
24
22
|
structuredResponse: z.infer<T>;
|
|
@@ -26,7 +24,6 @@ interface HookResponse {
|
|
|
26
24
|
createStreamingChatCompletion: (params: {
|
|
27
25
|
openai?: CreateOpenAiChatCompletionParams;
|
|
28
26
|
gemini?: CreateGeminiChatCompletionParams;
|
|
29
|
-
anthropic?: CreateAnthropicChatCompletionParams;
|
|
30
27
|
}) => Promise<{
|
|
31
28
|
chatCompletionStreamId: string;
|
|
32
29
|
chatCompletionId: string;
|
|
@@ -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
|
? {
|
|
@@ -98,12 +97,6 @@ export function useChatCompletions() {
|
|
|
98
97
|
content: params.gemini.content,
|
|
99
98
|
}
|
|
100
99
|
: undefined,
|
|
101
|
-
anthropic: params.anthropic
|
|
102
|
-
? {
|
|
103
|
-
model: params.anthropic.model,
|
|
104
|
-
messages: params.anthropic.messages,
|
|
105
|
-
}
|
|
106
|
-
: undefined,
|
|
107
100
|
},
|
|
108
101
|
});
|
|
109
102
|
setChatCompletions((prev) => [...prev, chatCompletion]);
|
|
@@ -114,7 +107,7 @@ export function useChatCompletions() {
|
|
|
114
107
|
};
|
|
115
108
|
}
|
|
116
109
|
throw new Error('No response from chat completion');
|
|
117
|
-
}, [
|
|
110
|
+
}, [context]);
|
|
118
111
|
const completions = useMemo(() => {
|
|
119
112
|
const completions = [];
|
|
120
113
|
for (const chatCompletion of chatCompletions) {
|
|
@@ -137,9 +130,9 @@ export function useChatCompletions() {
|
|
|
137
130
|
}, [completions]);
|
|
138
131
|
useEffect(() => {
|
|
139
132
|
if (stream) {
|
|
140
|
-
setUrl(`${
|
|
133
|
+
setUrl(`${context.fency.baseUrl}/v1/pub/chat-completion-streams/${stream.id}?pk=${context.fency.publishableKey}`);
|
|
141
134
|
}
|
|
142
|
-
}, [stream,
|
|
135
|
+
}, [stream, context.fency.publishableKey, setUrl]);
|
|
143
136
|
return {
|
|
144
137
|
createChatCompletion: createSynchronousChatCompletion,
|
|
145
138
|
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.35",
|
|
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.35",
|
|
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.35",
|
|
49
49
|
"react": ">=16.8.0"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "682c6da971db5839b435a19661d429a3fae54bbb"
|
|
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
|