@bytexbyte/nxtlinq-ai-agent-react-native-development 0.2.0
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/context/NxtlinqAgentContext.d.ts +13 -0
- package/dist/context/NxtlinqAgentContext.d.ts.map +1 -0
- package/dist/context/NxtlinqAgentContext.js +42 -0
- package/dist/createNxtlinqAgent.d.ts +9 -0
- package/dist/createNxtlinqAgent.d.ts.map +1 -0
- package/dist/createNxtlinqAgent.js +16 -0
- package/dist/hooks/useNxtlinqAgent.d.ts +20 -0
- package/dist/hooks/useNxtlinqAgent.d.ts.map +1 -0
- package/dist/hooks/useNxtlinqAgent.js +25 -0
- package/dist/hooks/useNxtlinqVoice.d.ts +23 -0
- package/dist/hooks/useNxtlinqVoice.d.ts.map +1 -0
- package/dist/hooks/useNxtlinqVoice.js +79 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/ports/createAsyncStoragePort.d.ts +9 -0
- package/dist/ports/createAsyncStoragePort.d.ts.map +1 -0
- package/dist/ports/createAsyncStoragePort.js +7 -0
- package/dist/ports/createRNHttpPort.d.ts +4 -0
- package/dist/ports/createRNHttpPort.d.ts.map +1 -0
- package/dist/ports/createRNHttpPort.js +9 -0
- package/dist/ports/createRNPlatformPorts.d.ts +14 -0
- package/dist/ports/createRNPlatformPorts.d.ts.map +1 -0
- package/dist/ports/createRNPlatformPorts.js +21 -0
- package/dist/ports/createRNWebRTCPort.d.ts +81 -0
- package/dist/ports/createRNWebRTCPort.d.ts.map +1 -0
- package/dist/ports/createRNWebRTCPort.js +235 -0
- package/dist/utils/ensureRecordAudioPermission.d.ts +7 -0
- package/dist/utils/ensureRecordAudioPermission.d.ts.map +1 -0
- package/dist/utils/ensureRecordAudioPermission.js +24 -0
- package/dist/utils/fetchUriAsDataUri.d.ts +11 -0
- package/dist/utils/fetchUriAsDataUri.d.ts.map +1 -0
- package/dist/utils/fetchUriAsDataUri.js +143 -0
- package/dist/utils/iosAudioSessionReady.d.ts +27 -0
- package/dist/utils/iosAudioSessionReady.d.ts.map +1 -0
- package/dist/utils/iosAudioSessionReady.js +93 -0
- package/dist/utils/iosWebRTCAudioSession.d.ts +5 -0
- package/dist/utils/iosWebRTCAudioSession.d.ts.map +1 -0
- package/dist/utils/iosWebRTCAudioSession.js +35 -0
- package/package.json +56 -0
- package/src/context/NxtlinqAgentContext.tsx +87 -0
- package/src/createNxtlinqAgent.ts +32 -0
- package/src/hooks/useNxtlinqAgent.ts +76 -0
- package/src/hooks/useNxtlinqVoice.ts +148 -0
- package/src/index.ts +74 -0
- package/src/ports/createAsyncStoragePort.ts +16 -0
- package/src/ports/createRNHttpPort.ts +11 -0
- package/src/ports/createRNPlatformPorts.ts +37 -0
- package/src/ports/createRNWebRTCPort.ts +327 -0
- package/src/utils/ensureRecordAudioPermission.ts +28 -0
- package/src/utils/fetchUriAsDataUri.ts +166 -0
- package/src/utils/iosAudioSessionReady.ts +106 -0
- package/src/utils/iosWebRTCAudioSession.ts +39 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NxtlinqAgent,
|
|
3
|
+
type AgentConfig,
|
|
4
|
+
} from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
5
|
+
import React, {
|
|
6
|
+
createContext,
|
|
7
|
+
useContext,
|
|
8
|
+
useEffect,
|
|
9
|
+
useMemo,
|
|
10
|
+
type ReactNode,
|
|
11
|
+
} from 'react';
|
|
12
|
+
import {
|
|
13
|
+
createNxtlinqAgentRN,
|
|
14
|
+
type CreateNxtlinqAgentRNOptions,
|
|
15
|
+
} from '../createNxtlinqAgent';
|
|
16
|
+
|
|
17
|
+
const NxtlinqAgentContext = createContext<NxtlinqAgent | null>(null);
|
|
18
|
+
|
|
19
|
+
export type NxtlinqAgentProviderProps = CreateNxtlinqAgentRNOptions & {
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
/** Replace messages when identity fields change (e.g. new chat session). */
|
|
22
|
+
resetOnIdentityChange?: boolean;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function NxtlinqAgentProvider({
|
|
26
|
+
children,
|
|
27
|
+
resetOnIdentityChange = true,
|
|
28
|
+
storage,
|
|
29
|
+
fetchImpl,
|
|
30
|
+
getTimezone,
|
|
31
|
+
webrtcModule,
|
|
32
|
+
webrtc,
|
|
33
|
+
...config
|
|
34
|
+
}: NxtlinqAgentProviderProps): React.ReactElement {
|
|
35
|
+
const agent = useMemo(
|
|
36
|
+
() =>
|
|
37
|
+
createNxtlinqAgentRN({
|
|
38
|
+
storage,
|
|
39
|
+
fetchImpl,
|
|
40
|
+
getTimezone,
|
|
41
|
+
webrtcModule,
|
|
42
|
+
webrtc,
|
|
43
|
+
...config,
|
|
44
|
+
}),
|
|
45
|
+
[
|
|
46
|
+
config.serviceId,
|
|
47
|
+
config.apiKey,
|
|
48
|
+
config.apiSecret,
|
|
49
|
+
config.environment,
|
|
50
|
+
config.pseudoId,
|
|
51
|
+
config.externalId,
|
|
52
|
+
config.defaultModel,
|
|
53
|
+
config.voiceMode,
|
|
54
|
+
storage,
|
|
55
|
+
fetchImpl,
|
|
56
|
+
getTimezone,
|
|
57
|
+
webrtcModule,
|
|
58
|
+
webrtc,
|
|
59
|
+
],
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!resetOnIdentityChange) return;
|
|
64
|
+
agent.setMessages([]);
|
|
65
|
+
}, [agent, resetOnIdentityChange, config.pseudoId, config.externalId]);
|
|
66
|
+
|
|
67
|
+
useEffect(() => () => agent.destroy(), [agent]);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<NxtlinqAgentContext.Provider value={agent}>
|
|
71
|
+
{children}
|
|
72
|
+
</NxtlinqAgentContext.Provider>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function useNxtlinqAgentContext(): NxtlinqAgent {
|
|
77
|
+
const agent = useContext(NxtlinqAgentContext);
|
|
78
|
+
if (!agent) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
'useNxtlinqAgentContext must be used within <NxtlinqAgentProvider>',
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return agent;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Re-export for apps that build the agent manually. */
|
|
87
|
+
export type { AgentConfig };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NxtlinqAgent,
|
|
3
|
+
type AgentConfig,
|
|
4
|
+
type PlatformPorts,
|
|
5
|
+
} from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
6
|
+
import { createRNPlatformPorts, type CreateRNPlatformPortsOptions } from './ports/createRNPlatformPorts';
|
|
7
|
+
|
|
8
|
+
export type CreateNxtlinqAgentRNOptions = AgentConfig & CreateRNPlatformPortsOptions;
|
|
9
|
+
|
|
10
|
+
export type { RNWebRTCModule } from './ports/createRNWebRTCPort';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create a platform-ready {@link NxtlinqAgent} for React Native custom UIs.
|
|
14
|
+
*/
|
|
15
|
+
export function createNxtlinqAgentRN(options: CreateNxtlinqAgentRNOptions): NxtlinqAgent {
|
|
16
|
+
const {
|
|
17
|
+
storage,
|
|
18
|
+
fetchImpl,
|
|
19
|
+
getTimezone,
|
|
20
|
+
webrtcModule,
|
|
21
|
+
webrtc,
|
|
22
|
+
...config
|
|
23
|
+
} = options;
|
|
24
|
+
const ports: PlatformPorts = createRNPlatformPorts({
|
|
25
|
+
storage,
|
|
26
|
+
fetchImpl,
|
|
27
|
+
getTimezone,
|
|
28
|
+
webrtcModule,
|
|
29
|
+
webrtc,
|
|
30
|
+
});
|
|
31
|
+
return new NxtlinqAgent(config, ports);
|
|
32
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Message,
|
|
3
|
+
NxtlinqAgentSnapshot,
|
|
4
|
+
PostTextTtsResult,
|
|
5
|
+
SendMessageOptions,
|
|
6
|
+
} from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
7
|
+
import { useCallback, useSyncExternalStore } from 'react';
|
|
8
|
+
import { useNxtlinqAgentContext } from '../context/NxtlinqAgentContext';
|
|
9
|
+
|
|
10
|
+
export type UseNxtlinqAgentResult = NxtlinqAgentSnapshot & {
|
|
11
|
+
agent: ReturnType<typeof useNxtlinqAgentContext>;
|
|
12
|
+
sendMessage: (
|
|
13
|
+
text: string,
|
|
14
|
+
options?: Omit<SendMessageOptions, 'text'>,
|
|
15
|
+
) => Promise<void>;
|
|
16
|
+
loadHistory: (options?: { last?: number }) => Promise<void>;
|
|
17
|
+
syncVoiceTurnHistory: (options?: { last?: number }) => Promise<void>;
|
|
18
|
+
setMessages: (messages: Message[]) => void;
|
|
19
|
+
postTextTts: (text: string) => Promise<PostTextTtsResult>;
|
|
20
|
+
buildTextTtsPlaybackUri: (result: PostTextTtsResult) => string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Subscribe to {@link NxtlinqAgent} state for custom RN chat UIs.
|
|
25
|
+
*/
|
|
26
|
+
export function useNxtlinqAgent(): UseNxtlinqAgentResult {
|
|
27
|
+
const agent = useNxtlinqAgentContext();
|
|
28
|
+
|
|
29
|
+
const snapshot = useSyncExternalStore(
|
|
30
|
+
(onStoreChange) => agent.subscribe(onStoreChange),
|
|
31
|
+
() => agent.getSnapshot(),
|
|
32
|
+
() => agent.getSnapshot(),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const sendMessage = useCallback(
|
|
36
|
+
(text: string, options?: Omit<SendMessageOptions, 'text'>) =>
|
|
37
|
+
agent.sendMessage(text, options),
|
|
38
|
+
[agent],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const loadHistory = useCallback(
|
|
42
|
+
(options?: { last?: number }) => agent.loadHistory(options),
|
|
43
|
+
[agent],
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const syncVoiceTurnHistory = useCallback(
|
|
47
|
+
(options?: { last?: number }) => agent.syncVoiceTurnHistory(options),
|
|
48
|
+
[agent],
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const setMessages = useCallback(
|
|
52
|
+
(messages: Message[]) => agent.setMessages(messages),
|
|
53
|
+
[agent],
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const postTextTts = useCallback(
|
|
57
|
+
(text: string) => agent.postTextTts(text),
|
|
58
|
+
[agent],
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const buildTextTtsPlaybackUri = useCallback(
|
|
62
|
+
(result: PostTextTtsResult) => agent.buildTextTtsPlaybackUri(result),
|
|
63
|
+
[agent],
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
agent,
|
|
68
|
+
...snapshot,
|
|
69
|
+
sendMessage,
|
|
70
|
+
loadHistory,
|
|
71
|
+
syncVoiceTurnHistory,
|
|
72
|
+
setMessages,
|
|
73
|
+
postTextTts,
|
|
74
|
+
buildTextTtsPlaybackUri,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
StartVoiceSessionOptions,
|
|
3
|
+
VoiceGreetingOptions,
|
|
4
|
+
VoiceSession,
|
|
5
|
+
VoiceStatus,
|
|
6
|
+
VoiceUserInputOptions,
|
|
7
|
+
} from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
8
|
+
import { VoiceNotSupportedError } from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
9
|
+
import { useCallback, useMemo, useRef, useSyncExternalStore } from 'react';
|
|
10
|
+
import { useNxtlinqAgentContext } from '../context/NxtlinqAgentContext';
|
|
11
|
+
|
|
12
|
+
export type UseNxtlinqVoiceOptions = Partial<
|
|
13
|
+
Omit<
|
|
14
|
+
StartVoiceSessionOptions,
|
|
15
|
+
'apiKey' | 'apiSecret' | 'pseudoId'
|
|
16
|
+
>
|
|
17
|
+
>;
|
|
18
|
+
|
|
19
|
+
export type UseNxtlinqVoiceResult = {
|
|
20
|
+
voiceStatus: VoiceStatus;
|
|
21
|
+
voiceSessionId: string | null;
|
|
22
|
+
isVoiceActive: boolean;
|
|
23
|
+
startVoice: (options?: UseNxtlinqVoiceOptions) => Promise<VoiceSession>;
|
|
24
|
+
stopVoice: (reason?: string) => Promise<void>;
|
|
25
|
+
muteMic: (muted: boolean) => void;
|
|
26
|
+
interrupt: () => void;
|
|
27
|
+
getRemoteAudioStream: () => MediaStream | null;
|
|
28
|
+
getOutputAudioLevel: () => number;
|
|
29
|
+
sendVoiceUserInput: (options: VoiceUserInputOptions) => void;
|
|
30
|
+
triggerVoiceGreeting: (
|
|
31
|
+
options: VoiceGreetingOptions,
|
|
32
|
+
greetOptions?: { waitForChannel?: boolean; timeoutMs?: number },
|
|
33
|
+
) => Promise<void>;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Voice controls for custom RN UIs. Requires `webrtcModule` on {@link NxtlinqAgentProvider}.
|
|
38
|
+
*/
|
|
39
|
+
export function useNxtlinqVoice(): UseNxtlinqVoiceResult {
|
|
40
|
+
const agent = useNxtlinqAgentContext();
|
|
41
|
+
const sessionRef = useRef<VoiceSession | null>(null);
|
|
42
|
+
|
|
43
|
+
const snapshot = useSyncExternalStore(
|
|
44
|
+
(onStoreChange) => agent.subscribe(onStoreChange),
|
|
45
|
+
() => agent.getSnapshot(),
|
|
46
|
+
() => agent.getSnapshot(),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const refreshSessionRef = useCallback(() => {
|
|
50
|
+
sessionRef.current = agent.getVoiceSession();
|
|
51
|
+
}, [agent]);
|
|
52
|
+
|
|
53
|
+
const startVoice = useCallback(
|
|
54
|
+
async (options?: UseNxtlinqVoiceOptions) => {
|
|
55
|
+
try {
|
|
56
|
+
const session = await agent.startVoice(options);
|
|
57
|
+
sessionRef.current = session;
|
|
58
|
+
return session;
|
|
59
|
+
} catch (err) {
|
|
60
|
+
if (err instanceof VoiceNotSupportedError) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
'Voice requires react-native-webrtc — pass webrtcModule to NxtlinqAgentProvider.',
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
[agent],
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const stopVoice = useCallback(
|
|
72
|
+
async (reason?: string) => {
|
|
73
|
+
await agent.stopVoice(reason);
|
|
74
|
+
sessionRef.current = null;
|
|
75
|
+
},
|
|
76
|
+
[agent],
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const muteMic = useCallback(
|
|
80
|
+
(muted: boolean) => {
|
|
81
|
+
refreshSessionRef();
|
|
82
|
+
sessionRef.current?.muteMic(muted);
|
|
83
|
+
},
|
|
84
|
+
[refreshSessionRef],
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const interrupt = useCallback(() => {
|
|
88
|
+
refreshSessionRef();
|
|
89
|
+
sessionRef.current?.interrupt();
|
|
90
|
+
}, [refreshSessionRef]);
|
|
91
|
+
|
|
92
|
+
const getRemoteAudioStream = useCallback(() => {
|
|
93
|
+
return agent.getVoiceSession()?.getRemoteAudioStream() ?? null;
|
|
94
|
+
}, [agent]);
|
|
95
|
+
|
|
96
|
+
const getOutputAudioLevel = useCallback(() => {
|
|
97
|
+
refreshSessionRef();
|
|
98
|
+
return sessionRef.current?.getOutputAudioLevel() ?? agent.getOutputAudioLevel();
|
|
99
|
+
}, [refreshSessionRef, agent]);
|
|
100
|
+
|
|
101
|
+
const sendVoiceUserInput = useCallback(
|
|
102
|
+
(options: VoiceUserInputOptions) => {
|
|
103
|
+
refreshSessionRef();
|
|
104
|
+
if (sessionRef.current) {
|
|
105
|
+
sessionRef.current.sendVoiceUserInput(options);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
agent.sendVoiceUserInput(options);
|
|
109
|
+
},
|
|
110
|
+
[refreshSessionRef, agent],
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const triggerVoiceGreeting = useCallback(
|
|
114
|
+
(
|
|
115
|
+
options: VoiceGreetingOptions,
|
|
116
|
+
greetOptions?: { waitForChannel?: boolean; timeoutMs?: number },
|
|
117
|
+
) => agent.triggerVoiceGreeting(options, greetOptions),
|
|
118
|
+
[agent],
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
return useMemo(
|
|
122
|
+
() => ({
|
|
123
|
+
voiceStatus: snapshot.voiceStatus,
|
|
124
|
+
voiceSessionId: snapshot.voiceSessionId,
|
|
125
|
+
isVoiceActive: snapshot.voiceSessionId != null,
|
|
126
|
+
startVoice,
|
|
127
|
+
stopVoice,
|
|
128
|
+
muteMic,
|
|
129
|
+
interrupt,
|
|
130
|
+
getRemoteAudioStream,
|
|
131
|
+
getOutputAudioLevel,
|
|
132
|
+
sendVoiceUserInput,
|
|
133
|
+
triggerVoiceGreeting,
|
|
134
|
+
}),
|
|
135
|
+
[
|
|
136
|
+
snapshot.voiceStatus,
|
|
137
|
+
snapshot.voiceSessionId,
|
|
138
|
+
startVoice,
|
|
139
|
+
stopVoice,
|
|
140
|
+
muteMic,
|
|
141
|
+
interrupt,
|
|
142
|
+
getRemoteAudioStream,
|
|
143
|
+
getOutputAudioLevel,
|
|
144
|
+
sendVoiceUserInput,
|
|
145
|
+
triggerVoiceGreeting,
|
|
146
|
+
],
|
|
147
|
+
);
|
|
148
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export {
|
|
2
|
+
createNxtlinqAgentRN,
|
|
3
|
+
type CreateNxtlinqAgentRNOptions,
|
|
4
|
+
} from './createNxtlinqAgent';
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
NxtlinqAgentProvider,
|
|
8
|
+
useNxtlinqAgentContext,
|
|
9
|
+
type NxtlinqAgentProviderProps,
|
|
10
|
+
type AgentConfig,
|
|
11
|
+
} from './context/NxtlinqAgentContext';
|
|
12
|
+
|
|
13
|
+
export { useNxtlinqAgent, type UseNxtlinqAgentResult } from './hooks/useNxtlinqAgent';
|
|
14
|
+
export { useNxtlinqVoice, type UseNxtlinqVoiceResult, type UseNxtlinqVoiceOptions } from './hooks/useNxtlinqVoice';
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
createAsyncStoragePort,
|
|
18
|
+
type AsyncStorageLike,
|
|
19
|
+
} from './ports/createAsyncStoragePort';
|
|
20
|
+
export { createRNHttpPort } from './ports/createRNHttpPort';
|
|
21
|
+
export {
|
|
22
|
+
createRNPlatformPorts,
|
|
23
|
+
type CreateRNPlatformPortsOptions,
|
|
24
|
+
} from './ports/createRNPlatformPorts';
|
|
25
|
+
export {
|
|
26
|
+
createRNWebRTCPort,
|
|
27
|
+
type RNWebRTCModule,
|
|
28
|
+
} from './ports/createRNWebRTCPort';
|
|
29
|
+
export {
|
|
30
|
+
fetchUriAsDataUriAttachment,
|
|
31
|
+
uriToVoiceImageAttachment,
|
|
32
|
+
} from './utils/fetchUriAsDataUri';
|
|
33
|
+
export {
|
|
34
|
+
ensureRecordAudioPermission,
|
|
35
|
+
MicrophonePermissionDeniedError,
|
|
36
|
+
} from './utils/ensureRecordAudioPermission';
|
|
37
|
+
export {
|
|
38
|
+
ensureIOSAudioSessionForVoiceCapture,
|
|
39
|
+
markIOSAudioSessionReady,
|
|
40
|
+
markIOSVoiceCaptureCompleted,
|
|
41
|
+
notifyIOSVoiceSessionEnded,
|
|
42
|
+
setIOSAudioSessionPrewarmHandler,
|
|
43
|
+
waitForIOSAudioSessionReady,
|
|
44
|
+
waitForIOSVoiceCaptureRelease,
|
|
45
|
+
} from './utils/iosAudioSessionReady';
|
|
46
|
+
|
|
47
|
+
// Re-export core types consumers need in custom UIs
|
|
48
|
+
export type {
|
|
49
|
+
Message,
|
|
50
|
+
Attachment,
|
|
51
|
+
AgentResponse,
|
|
52
|
+
AgentConfig as CoreAgentConfig,
|
|
53
|
+
SendMessageOptions,
|
|
54
|
+
NxtlinqAgentSnapshot,
|
|
55
|
+
ToolUse,
|
|
56
|
+
StartVoiceSessionOptions,
|
|
57
|
+
VoiceSession,
|
|
58
|
+
VoiceStatus,
|
|
59
|
+
VoiceTranscriptEvent,
|
|
60
|
+
VoiceDoneEvent,
|
|
61
|
+
VoiceUserInputOptions,
|
|
62
|
+
VoiceGreetingOptions,
|
|
63
|
+
} from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
64
|
+
|
|
65
|
+
export {
|
|
66
|
+
NxtlinqAgent,
|
|
67
|
+
setApiHosts,
|
|
68
|
+
startVoiceSessionWithPort,
|
|
69
|
+
createBrowserWebRTCPort,
|
|
70
|
+
VoiceNotSupportedError,
|
|
71
|
+
mapServerHistoryToMessages,
|
|
72
|
+
appendServerHistoryIntoMessages,
|
|
73
|
+
STORAGE_KEYS,
|
|
74
|
+
} from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { StoragePort } from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
2
|
+
|
|
3
|
+
/** Minimal AsyncStorage surface (matches @react-native-async-storage/async-storage). */
|
|
4
|
+
export type AsyncStorageLike = {
|
|
5
|
+
getItem(key: string): Promise<string | null>;
|
|
6
|
+
setItem(key: string, value: string): Promise<void>;
|
|
7
|
+
removeItem(key: string): Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export function createAsyncStoragePort(storage: AsyncStorageLike): StoragePort {
|
|
11
|
+
return {
|
|
12
|
+
getItem: (key) => storage.getItem(key),
|
|
13
|
+
setItem: (key, value) => storage.setItem(key, value),
|
|
14
|
+
removeItem: (key) => storage.removeItem(key),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HttpPort } from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
2
|
+
|
|
3
|
+
/** React Native global `fetch` (same signature as browser). */
|
|
4
|
+
export function createRNHttpPort(fetchImpl: typeof fetch = globalThis.fetch): HttpPort {
|
|
5
|
+
if (!fetchImpl) {
|
|
6
|
+
throw new Error('fetch is not available — pass a fetch implementation to createRNHttpPort');
|
|
7
|
+
}
|
|
8
|
+
return {
|
|
9
|
+
fetch: (input, init) => fetchImpl(input, init),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { PlatformPorts, WebRTCPort } from '@bytexbyte/nxtlinq-ai-agent-core-development';
|
|
2
|
+
import { createAsyncStoragePort, type AsyncStorageLike } from './createAsyncStoragePort';
|
|
3
|
+
import { createRNHttpPort } from './createRNHttpPort';
|
|
4
|
+
import { createRNWebRTCPort, type RNWebRTCModule } from './createRNWebRTCPort';
|
|
5
|
+
|
|
6
|
+
export type CreateRNPlatformPortsOptions = {
|
|
7
|
+
storage: AsyncStorageLike;
|
|
8
|
+
fetchImpl?: typeof fetch;
|
|
9
|
+
getTimezone?: () => string;
|
|
10
|
+
/** Pass `react-native-webrtc` exports to enable voice (M2). */
|
|
11
|
+
webrtcModule?: RNWebRTCModule;
|
|
12
|
+
/** Pre-built port (overrides `webrtcModule`). */
|
|
13
|
+
webrtc?: WebRTCPort;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function createRNPlatformPorts(
|
|
17
|
+
options: CreateRNPlatformPortsOptions,
|
|
18
|
+
): PlatformPorts {
|
|
19
|
+
const webrtc =
|
|
20
|
+
options.webrtc
|
|
21
|
+
?? (options.webrtcModule ? createRNWebRTCPort(options.webrtcModule) : undefined);
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
storage: createAsyncStoragePort(options.storage),
|
|
25
|
+
http: createRNHttpPort(options.fetchImpl),
|
|
26
|
+
webrtc,
|
|
27
|
+
getTimezone:
|
|
28
|
+
options.getTimezone
|
|
29
|
+
?? (() => {
|
|
30
|
+
try {
|
|
31
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
32
|
+
} catch {
|
|
33
|
+
return 'UTC';
|
|
34
|
+
}
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
}
|