lemma-sdk 0.2.7 → 0.2.9
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
2
|
import { parseSSEJson, readSSE } from "../streams.js";
|
|
3
3
|
import { parseAssistantStreamEvent, upsertConversationMessage } from "../assistant-events.js";
|
|
4
4
|
function resolveOptionalPodId(client, podId) {
|
|
@@ -22,15 +22,15 @@ function normalizeError(error, fallback) {
|
|
|
22
22
|
return error;
|
|
23
23
|
return new Error(fallback);
|
|
24
24
|
}
|
|
25
|
-
function normalizeScope(client,
|
|
25
|
+
function normalizeScope(client, defaults, override) {
|
|
26
26
|
return {
|
|
27
|
-
podId: override?.podId ??
|
|
28
|
-
assistantId: override?.assistantId ??
|
|
29
|
-
organizationId: override?.organizationId ??
|
|
27
|
+
podId: override?.podId ?? defaults.podId ?? client.podId ?? null,
|
|
28
|
+
assistantId: override?.assistantId ?? defaults.assistantId ?? null,
|
|
29
|
+
organizationId: override?.organizationId ?? defaults.organizationId ?? null,
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
export function useAssistantSession(options) {
|
|
33
|
-
const { client, conversationId: externalConversationId = null, autoLoad = true, onEvent, onStatus, onMessage, onError, } = options;
|
|
33
|
+
const { client, podId: defaultPodId, assistantId: defaultAssistantId, organizationId: defaultOrganizationId, conversationId: externalConversationId = null, autoLoad = true, onEvent, onStatus, onMessage, onError, } = options;
|
|
34
34
|
const [conversationId, setConversationIdState] = useState(externalConversationId);
|
|
35
35
|
const [conversation, setConversation] = useState(null);
|
|
36
36
|
const [status, setStatus] = useState(undefined);
|
|
@@ -53,9 +53,14 @@ export function useAssistantSession(options) {
|
|
|
53
53
|
abortRef.current?.abort();
|
|
54
54
|
abortRef.current = null;
|
|
55
55
|
}, []);
|
|
56
|
+
const defaultScope = useMemo(() => ({
|
|
57
|
+
podId: defaultPodId ?? null,
|
|
58
|
+
assistantId: defaultAssistantId ?? null,
|
|
59
|
+
organizationId: defaultOrganizationId ?? null,
|
|
60
|
+
}), [defaultAssistantId, defaultOrganizationId, defaultPodId]);
|
|
56
61
|
const listConversations = useCallback(async (input = {}) => {
|
|
57
62
|
try {
|
|
58
|
-
const scope = normalizeScope(client,
|
|
63
|
+
const scope = normalizeScope(client, defaultScope, input.scope);
|
|
59
64
|
applyPodScope(client, scope.podId);
|
|
60
65
|
const response = await client.conversations.list({
|
|
61
66
|
pod_id: scope.podId ?? undefined,
|
|
@@ -80,14 +85,14 @@ export function useAssistantSession(options) {
|
|
|
80
85
|
next_page_token: null,
|
|
81
86
|
};
|
|
82
87
|
}
|
|
83
|
-
}, [client,
|
|
88
|
+
}, [client, defaultScope, onError]);
|
|
84
89
|
const createConversation = useCallback(async (input = {}) => {
|
|
85
|
-
applyPodScope(client, input.podId ??
|
|
90
|
+
applyPodScope(client, input.podId ?? defaultPodId ?? null);
|
|
86
91
|
const payload = {
|
|
87
92
|
title: input.title ?? undefined,
|
|
88
|
-
pod_id: input.podId ??
|
|
89
|
-
assistant_id: input.assistantId ??
|
|
90
|
-
organization_id: input.organizationId ??
|
|
93
|
+
pod_id: input.podId ?? defaultPodId ?? client.podId ?? undefined,
|
|
94
|
+
assistant_id: input.assistantId ?? defaultAssistantId ?? undefined,
|
|
95
|
+
organization_id: input.organizationId ?? defaultOrganizationId ?? undefined,
|
|
91
96
|
model: typeof input.model === "undefined"
|
|
92
97
|
? undefined
|
|
93
98
|
: input.model,
|
|
@@ -100,13 +105,13 @@ export function useAssistantSession(options) {
|
|
|
100
105
|
setMessages([]);
|
|
101
106
|
}
|
|
102
107
|
return created;
|
|
103
|
-
}, [client,
|
|
108
|
+
}, [client, defaultAssistantId, defaultOrganizationId, defaultPodId]);
|
|
104
109
|
const refreshConversation = useCallback(async (explicitConversationId) => {
|
|
105
110
|
const id = explicitConversationId ?? conversationId;
|
|
106
111
|
if (!id)
|
|
107
112
|
return null;
|
|
108
113
|
try {
|
|
109
|
-
const scope = normalizeScope(client,
|
|
114
|
+
const scope = normalizeScope(client, defaultScope);
|
|
110
115
|
applyPodScope(client, scope.podId);
|
|
111
116
|
const nextConversation = await client.conversations.get(id, {
|
|
112
117
|
pod_id: scope.podId ?? undefined,
|
|
@@ -127,14 +132,14 @@ export function useAssistantSession(options) {
|
|
|
127
132
|
onError?.(refreshError);
|
|
128
133
|
return null;
|
|
129
134
|
}
|
|
130
|
-
}, [client, conversationId, onError, onStatus
|
|
135
|
+
}, [client, conversationId, defaultScope, onError, onStatus]);
|
|
131
136
|
const loadMessages = useCallback(async (input = {}) => {
|
|
132
137
|
const id = input.conversationId ?? conversationId;
|
|
133
138
|
if (!id) {
|
|
134
139
|
return { items: [], limit: input.limit ?? 20, next_page_token: null };
|
|
135
140
|
}
|
|
136
141
|
try {
|
|
137
|
-
const scope = normalizeScope(client,
|
|
142
|
+
const scope = normalizeScope(client, defaultScope);
|
|
138
143
|
applyPodScope(client, scope.podId);
|
|
139
144
|
const response = await client.conversations.messages.list(id, {
|
|
140
145
|
pod_id: scope.podId ?? undefined,
|
|
@@ -159,7 +164,7 @@ export function useAssistantSession(options) {
|
|
|
159
164
|
next_page_token: null,
|
|
160
165
|
};
|
|
161
166
|
}
|
|
162
|
-
}, [client, conversationId,
|
|
167
|
+
}, [client, conversationId, defaultScope, onError]);
|
|
163
168
|
const consume = useCallback(async (stream, controller) => {
|
|
164
169
|
setIsStreaming(true);
|
|
165
170
|
setError(null);
|
|
@@ -198,6 +203,10 @@ export function useAssistantSession(options) {
|
|
|
198
203
|
const ensureConversation = useCallback(async (overrideConversationId, options) => {
|
|
199
204
|
const existingId = overrideConversationId ?? conversationId;
|
|
200
205
|
if (existingId) {
|
|
206
|
+
// Avoid a network roundtrip on every send when we already have this conversation in state.
|
|
207
|
+
if (conversation?.id === existingId) {
|
|
208
|
+
return conversation;
|
|
209
|
+
}
|
|
201
210
|
const existing = await refreshConversation(existingId);
|
|
202
211
|
if (existing)
|
|
203
212
|
return existing;
|
|
@@ -210,14 +219,14 @@ export function useAssistantSession(options) {
|
|
|
210
219
|
...(options.createConversation ?? {}),
|
|
211
220
|
setActive: true,
|
|
212
221
|
});
|
|
213
|
-
}, [conversationId, createConversation, refreshConversation]);
|
|
222
|
+
}, [conversation, conversationId, createConversation, refreshConversation]);
|
|
214
223
|
const sendMessage = useCallback(async (content, input = {}) => {
|
|
215
224
|
const resolvedConversation = await ensureConversation(input.conversationId, input);
|
|
216
225
|
const resolvedConversationId = requireConversationId(resolvedConversation.id);
|
|
217
226
|
cancel();
|
|
218
227
|
const controller = new AbortController();
|
|
219
228
|
abortRef.current = controller;
|
|
220
|
-
const scope = normalizeScope(client,
|
|
229
|
+
const scope = normalizeScope(client, defaultScope, input.createConversation);
|
|
221
230
|
applyPodScope(client, scope.podId);
|
|
222
231
|
const stream = await client.conversations.sendMessageStream(resolvedConversationId, { content }, {
|
|
223
232
|
pod_id: scope.podId ?? undefined,
|
|
@@ -225,28 +234,28 @@ export function useAssistantSession(options) {
|
|
|
225
234
|
});
|
|
226
235
|
await consume(stream, controller);
|
|
227
236
|
return resolvedConversation;
|
|
228
|
-
}, [cancel, client, consume,
|
|
237
|
+
}, [cancel, client, consume, defaultScope, ensureConversation]);
|
|
229
238
|
const resume = useCallback(async (explicitConversationId) => {
|
|
230
239
|
const id = requireConversationId(explicitConversationId ?? conversationId);
|
|
231
240
|
cancel();
|
|
232
241
|
const controller = new AbortController();
|
|
233
242
|
abortRef.current = controller;
|
|
234
|
-
const scope = normalizeScope(client,
|
|
243
|
+
const scope = normalizeScope(client, defaultScope);
|
|
235
244
|
applyPodScope(client, scope.podId);
|
|
236
245
|
const stream = await client.conversations.resumeStream(id, {
|
|
237
246
|
pod_id: scope.podId ?? undefined,
|
|
238
247
|
signal: controller.signal,
|
|
239
248
|
});
|
|
240
249
|
await consume(stream, controller);
|
|
241
|
-
}, [cancel, client, consume, conversationId,
|
|
250
|
+
}, [cancel, client, consume, conversationId, defaultScope]);
|
|
242
251
|
const stop = useCallback(async (explicitConversationId) => {
|
|
243
252
|
const id = requireConversationId(explicitConversationId ?? conversationId);
|
|
244
|
-
const scope = normalizeScope(client,
|
|
253
|
+
const scope = normalizeScope(client, defaultScope);
|
|
245
254
|
applyPodScope(client, scope.podId);
|
|
246
255
|
await client.conversations.stopRun(id, {
|
|
247
256
|
pod_id: scope.podId ?? undefined,
|
|
248
257
|
});
|
|
249
|
-
}, [client, conversationId,
|
|
258
|
+
}, [client, conversationId, defaultScope]);
|
|
250
259
|
const clearMessages = useCallback(() => {
|
|
251
260
|
setMessages([]);
|
|
252
261
|
}, []);
|