@informedai/react 0.2.6 → 0.3.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/index.d.mts +27 -3
- package/dist/index.d.ts +27 -3
- package/dist/index.js +118 -26
- package/dist/index.mjs +118 -26
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -76,7 +76,24 @@ interface InformedAssistantConfig {
|
|
|
76
76
|
documentTypeId: string;
|
|
77
77
|
/** API base URL (defaults to https://api.informedassistant.ai/api/v1) */
|
|
78
78
|
apiUrl?: string;
|
|
79
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* External ID for idempotency - your object's ID in your system.
|
|
81
|
+
* If provided, the widget will find or create a document linked to this ID.
|
|
82
|
+
* This allows resuming work on the same document across sessions.
|
|
83
|
+
*/
|
|
84
|
+
externalId?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Your current field values to sync before starting.
|
|
87
|
+
* Since you're the source of truth, this data will be written to our document.
|
|
88
|
+
* Use this to ensure the assistant sees your latest data.
|
|
89
|
+
*/
|
|
90
|
+
initialData?: Record<string, unknown>;
|
|
91
|
+
/**
|
|
92
|
+
* Whether to persist sessions in localStorage for resumption.
|
|
93
|
+
* Defaults to true when externalId is provided, false otherwise.
|
|
94
|
+
*/
|
|
95
|
+
persistSession?: boolean;
|
|
96
|
+
/** Optional: Existing session ID to resume (overrides localStorage) */
|
|
80
97
|
sessionId?: string;
|
|
81
98
|
/** Callback when widget is ready with document type schema */
|
|
82
99
|
onReady?: (context: WidgetReadyContext) => void;
|
|
@@ -156,6 +173,7 @@ interface InformedAIContextValue {
|
|
|
156
173
|
sendQuickAction: (action: string, payload?: Record<string, unknown>) => Promise<void>;
|
|
157
174
|
applyPendingValue: () => Promise<void>;
|
|
158
175
|
skipTask: () => Promise<void>;
|
|
176
|
+
startNewSession: () => Promise<void>;
|
|
159
177
|
clearError: () => void;
|
|
160
178
|
}
|
|
161
179
|
declare function useInformedAI(): InformedAIContextValue;
|
|
@@ -213,9 +231,15 @@ declare class InformedAIClient {
|
|
|
213
231
|
private request;
|
|
214
232
|
/**
|
|
215
233
|
* Create a new session for a document type.
|
|
216
|
-
*
|
|
234
|
+
*
|
|
235
|
+
* @param documentTypeId - The document type to create a session for
|
|
236
|
+
* @param options.externalId - Your object's ID for idempotency (finds or creates document)
|
|
237
|
+
* @param options.initialData - Your current field values to sync (you're the source of truth)
|
|
217
238
|
*/
|
|
218
|
-
createSession(documentTypeId: string
|
|
239
|
+
createSession(documentTypeId: string, options?: {
|
|
240
|
+
externalId?: string;
|
|
241
|
+
initialData?: Record<string, unknown>;
|
|
242
|
+
}): Promise<CreateSessionResponse>;
|
|
219
243
|
/**
|
|
220
244
|
* Get an existing session.
|
|
221
245
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -76,7 +76,24 @@ interface InformedAssistantConfig {
|
|
|
76
76
|
documentTypeId: string;
|
|
77
77
|
/** API base URL (defaults to https://api.informedassistant.ai/api/v1) */
|
|
78
78
|
apiUrl?: string;
|
|
79
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* External ID for idempotency - your object's ID in your system.
|
|
81
|
+
* If provided, the widget will find or create a document linked to this ID.
|
|
82
|
+
* This allows resuming work on the same document across sessions.
|
|
83
|
+
*/
|
|
84
|
+
externalId?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Your current field values to sync before starting.
|
|
87
|
+
* Since you're the source of truth, this data will be written to our document.
|
|
88
|
+
* Use this to ensure the assistant sees your latest data.
|
|
89
|
+
*/
|
|
90
|
+
initialData?: Record<string, unknown>;
|
|
91
|
+
/**
|
|
92
|
+
* Whether to persist sessions in localStorage for resumption.
|
|
93
|
+
* Defaults to true when externalId is provided, false otherwise.
|
|
94
|
+
*/
|
|
95
|
+
persistSession?: boolean;
|
|
96
|
+
/** Optional: Existing session ID to resume (overrides localStorage) */
|
|
80
97
|
sessionId?: string;
|
|
81
98
|
/** Callback when widget is ready with document type schema */
|
|
82
99
|
onReady?: (context: WidgetReadyContext) => void;
|
|
@@ -156,6 +173,7 @@ interface InformedAIContextValue {
|
|
|
156
173
|
sendQuickAction: (action: string, payload?: Record<string, unknown>) => Promise<void>;
|
|
157
174
|
applyPendingValue: () => Promise<void>;
|
|
158
175
|
skipTask: () => Promise<void>;
|
|
176
|
+
startNewSession: () => Promise<void>;
|
|
159
177
|
clearError: () => void;
|
|
160
178
|
}
|
|
161
179
|
declare function useInformedAI(): InformedAIContextValue;
|
|
@@ -213,9 +231,15 @@ declare class InformedAIClient {
|
|
|
213
231
|
private request;
|
|
214
232
|
/**
|
|
215
233
|
* Create a new session for a document type.
|
|
216
|
-
*
|
|
234
|
+
*
|
|
235
|
+
* @param documentTypeId - The document type to create a session for
|
|
236
|
+
* @param options.externalId - Your object's ID for idempotency (finds or creates document)
|
|
237
|
+
* @param options.initialData - Your current field values to sync (you're the source of truth)
|
|
217
238
|
*/
|
|
218
|
-
createSession(documentTypeId: string
|
|
239
|
+
createSession(documentTypeId: string, options?: {
|
|
240
|
+
externalId?: string;
|
|
241
|
+
initialData?: Record<string, unknown>;
|
|
242
|
+
}): Promise<CreateSessionResponse>;
|
|
219
243
|
/**
|
|
220
244
|
* Get an existing session.
|
|
221
245
|
*/
|
package/dist/index.js
CHANGED
|
@@ -67,12 +67,19 @@ var InformedAIClient = class {
|
|
|
67
67
|
// ========================================================================
|
|
68
68
|
/**
|
|
69
69
|
* Create a new session for a document type.
|
|
70
|
-
*
|
|
70
|
+
*
|
|
71
|
+
* @param documentTypeId - The document type to create a session for
|
|
72
|
+
* @param options.externalId - Your object's ID for idempotency (finds or creates document)
|
|
73
|
+
* @param options.initialData - Your current field values to sync (you're the source of truth)
|
|
71
74
|
*/
|
|
72
|
-
async createSession(documentTypeId) {
|
|
75
|
+
async createSession(documentTypeId, options) {
|
|
73
76
|
return this.request("/widget/sessions", {
|
|
74
77
|
method: "POST",
|
|
75
|
-
body: JSON.stringify({
|
|
78
|
+
body: JSON.stringify({
|
|
79
|
+
documentTypeId,
|
|
80
|
+
externalId: options?.externalId,
|
|
81
|
+
initialData: options?.initialData
|
|
82
|
+
})
|
|
76
83
|
});
|
|
77
84
|
}
|
|
78
85
|
/**
|
|
@@ -186,6 +193,7 @@ var InformedAIClient = class {
|
|
|
186
193
|
|
|
187
194
|
// src/context/InformedAIContext.tsx
|
|
188
195
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
196
|
+
var getStorageKey = (documentTypeId, externalId) => `informedai_session_${documentTypeId}${externalId ? `_${externalId}` : ""}`;
|
|
189
197
|
var InformedAIContext = (0, import_react.createContext)(null);
|
|
190
198
|
function useInformedAI() {
|
|
191
199
|
const context = (0, import_react.useContext)(InformedAIContext);
|
|
@@ -203,41 +211,93 @@ function InformedAIProvider({ config, children }) {
|
|
|
203
211
|
const [error, setError] = (0, import_react.useState)(null);
|
|
204
212
|
const [streamingContent, setStreamingContent] = (0, import_react.useState)("");
|
|
205
213
|
const clientRef = (0, import_react.useRef)(null);
|
|
214
|
+
const initRef = (0, import_react.useRef)(false);
|
|
215
|
+
const shouldPersist = config.persistSession ?? !!config.externalId;
|
|
216
|
+
const storageKey = getStorageKey(config.documentTypeId, config.externalId);
|
|
206
217
|
(0, import_react.useEffect)(() => {
|
|
207
218
|
clientRef.current = new InformedAIClient(config.apiUrl);
|
|
208
219
|
}, [config.apiUrl]);
|
|
220
|
+
const createNewSession = (0, import_react.useCallback)(async () => {
|
|
221
|
+
if (!clientRef.current) return null;
|
|
222
|
+
const result = await clientRef.current.createSession(
|
|
223
|
+
config.documentTypeId,
|
|
224
|
+
{
|
|
225
|
+
externalId: config.externalId,
|
|
226
|
+
initialData: config.initialData
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
const dt = {
|
|
230
|
+
id: result.documentType.id,
|
|
231
|
+
name: result.documentType.name,
|
|
232
|
+
displayName: result.documentType.displayName,
|
|
233
|
+
schema: result.documentType.schema,
|
|
234
|
+
workspaceId: "",
|
|
235
|
+
taskConfigs: {},
|
|
236
|
+
createdAt: "",
|
|
237
|
+
updatedAt: ""
|
|
238
|
+
};
|
|
239
|
+
if (shouldPersist && typeof window !== "undefined") {
|
|
240
|
+
try {
|
|
241
|
+
localStorage.setItem(storageKey, result.session.id);
|
|
242
|
+
} catch (e) {
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return { session: result.session, document: result.document, documentType: dt };
|
|
246
|
+
}, [config.documentTypeId, config.externalId, config.initialData, shouldPersist, storageKey]);
|
|
209
247
|
(0, import_react.useEffect)(() => {
|
|
248
|
+
if (initRef.current) return;
|
|
249
|
+
initRef.current = true;
|
|
210
250
|
async function initialize() {
|
|
211
251
|
if (!clientRef.current) return;
|
|
212
252
|
try {
|
|
213
253
|
setIsLoading(true);
|
|
214
254
|
setError(null);
|
|
215
|
-
let sess;
|
|
255
|
+
let sess = null;
|
|
216
256
|
let doc = null;
|
|
217
257
|
let dt = null;
|
|
218
|
-
|
|
219
|
-
|
|
258
|
+
let sessionIdToResume = config.sessionId;
|
|
259
|
+
if (!sessionIdToResume && shouldPersist && typeof window !== "undefined") {
|
|
260
|
+
try {
|
|
261
|
+
sessionIdToResume = localStorage.getItem(storageKey) || void 0;
|
|
262
|
+
} catch (e) {
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (sessionIdToResume) {
|
|
266
|
+
try {
|
|
267
|
+
sess = await clientRef.current.getSession(sessionIdToResume);
|
|
268
|
+
} catch (e) {
|
|
269
|
+
console.warn("Failed to resume session, creating new one");
|
|
270
|
+
if (shouldPersist && typeof window !== "undefined") {
|
|
271
|
+
try {
|
|
272
|
+
localStorage.removeItem(storageKey);
|
|
273
|
+
} catch (e2) {
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (!sess) {
|
|
279
|
+
const result = await createNewSession();
|
|
280
|
+
if (result) {
|
|
281
|
+
sess = result.session;
|
|
282
|
+
doc = result.document;
|
|
283
|
+
dt = result.documentType;
|
|
284
|
+
}
|
|
220
285
|
} else {
|
|
221
|
-
const result = await
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
displayName: result.documentType.displayName,
|
|
228
|
-
schema: result.documentType.schema,
|
|
229
|
-
workspaceId: "",
|
|
230
|
-
taskConfigs: {},
|
|
231
|
-
createdAt: "",
|
|
232
|
-
updatedAt: ""
|
|
233
|
-
};
|
|
286
|
+
const result = await createNewSession();
|
|
287
|
+
if (result) {
|
|
288
|
+
sess = result.session;
|
|
289
|
+
doc = result.document;
|
|
290
|
+
dt = result.documentType;
|
|
291
|
+
}
|
|
234
292
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
293
|
+
if (sess) {
|
|
294
|
+
setSession(sess);
|
|
295
|
+
if (doc) setDocument(doc);
|
|
296
|
+
if (dt) setDocumentType(dt);
|
|
297
|
+
config.onSessionChange?.(sess);
|
|
298
|
+
if (doc && dt) {
|
|
299
|
+
config.onReady?.({ session: sess, document: doc, documentType: dt });
|
|
300
|
+
}
|
|
241
301
|
}
|
|
242
302
|
} catch (err) {
|
|
243
303
|
const error2 = err instanceof Error ? err : new Error("Initialization failed");
|
|
@@ -248,7 +308,7 @@ function InformedAIProvider({ config, children }) {
|
|
|
248
308
|
}
|
|
249
309
|
}
|
|
250
310
|
initialize();
|
|
251
|
-
}, [config.documentTypeId, config.sessionId]);
|
|
311
|
+
}, [config.documentTypeId, config.sessionId, config.externalId]);
|
|
252
312
|
const handleSSEEvent = (0, import_react.useCallback)((event) => {
|
|
253
313
|
if (event.type === "content" && event.content) {
|
|
254
314
|
setStreamingContent((prev) => prev + event.content);
|
|
@@ -330,6 +390,37 @@ function InformedAIProvider({ config, children }) {
|
|
|
330
390
|
config.onError?.(error2);
|
|
331
391
|
}
|
|
332
392
|
}, [session, config]);
|
|
393
|
+
const startNewSession = (0, import_react.useCallback)(async () => {
|
|
394
|
+
if (!clientRef.current) return;
|
|
395
|
+
try {
|
|
396
|
+
setIsLoading(true);
|
|
397
|
+
setError(null);
|
|
398
|
+
if (shouldPersist && typeof window !== "undefined") {
|
|
399
|
+
try {
|
|
400
|
+
localStorage.removeItem(storageKey);
|
|
401
|
+
} catch (e) {
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
const result = await createNewSession();
|
|
405
|
+
if (result) {
|
|
406
|
+
setSession(result.session);
|
|
407
|
+
setDocument(result.document);
|
|
408
|
+
setDocumentType(result.documentType);
|
|
409
|
+
config.onSessionChange?.(result.session);
|
|
410
|
+
config.onReady?.({
|
|
411
|
+
session: result.session,
|
|
412
|
+
document: result.document,
|
|
413
|
+
documentType: result.documentType
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
} catch (err) {
|
|
417
|
+
const error2 = err instanceof Error ? err : new Error("Failed to start new session");
|
|
418
|
+
setError(error2);
|
|
419
|
+
config.onError?.(error2);
|
|
420
|
+
} finally {
|
|
421
|
+
setIsLoading(false);
|
|
422
|
+
}
|
|
423
|
+
}, [createNewSession, shouldPersist, storageKey, config]);
|
|
333
424
|
const clearError = (0, import_react.useCallback)(() => {
|
|
334
425
|
setError(null);
|
|
335
426
|
}, []);
|
|
@@ -345,6 +436,7 @@ function InformedAIProvider({ config, children }) {
|
|
|
345
436
|
sendQuickAction,
|
|
346
437
|
applyPendingValue,
|
|
347
438
|
skipTask,
|
|
439
|
+
startNewSession,
|
|
348
440
|
clearError
|
|
349
441
|
};
|
|
350
442
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InformedAIContext.Provider, { value, children });
|
package/dist/index.mjs
CHANGED
|
@@ -37,12 +37,19 @@ var InformedAIClient = class {
|
|
|
37
37
|
// ========================================================================
|
|
38
38
|
/**
|
|
39
39
|
* Create a new session for a document type.
|
|
40
|
-
*
|
|
40
|
+
*
|
|
41
|
+
* @param documentTypeId - The document type to create a session for
|
|
42
|
+
* @param options.externalId - Your object's ID for idempotency (finds or creates document)
|
|
43
|
+
* @param options.initialData - Your current field values to sync (you're the source of truth)
|
|
41
44
|
*/
|
|
42
|
-
async createSession(documentTypeId) {
|
|
45
|
+
async createSession(documentTypeId, options) {
|
|
43
46
|
return this.request("/widget/sessions", {
|
|
44
47
|
method: "POST",
|
|
45
|
-
body: JSON.stringify({
|
|
48
|
+
body: JSON.stringify({
|
|
49
|
+
documentTypeId,
|
|
50
|
+
externalId: options?.externalId,
|
|
51
|
+
initialData: options?.initialData
|
|
52
|
+
})
|
|
46
53
|
});
|
|
47
54
|
}
|
|
48
55
|
/**
|
|
@@ -156,6 +163,7 @@ var InformedAIClient = class {
|
|
|
156
163
|
|
|
157
164
|
// src/context/InformedAIContext.tsx
|
|
158
165
|
import { jsx } from "react/jsx-runtime";
|
|
166
|
+
var getStorageKey = (documentTypeId, externalId) => `informedai_session_${documentTypeId}${externalId ? `_${externalId}` : ""}`;
|
|
159
167
|
var InformedAIContext = createContext(null);
|
|
160
168
|
function useInformedAI() {
|
|
161
169
|
const context = useContext(InformedAIContext);
|
|
@@ -173,41 +181,93 @@ function InformedAIProvider({ config, children }) {
|
|
|
173
181
|
const [error, setError] = useState(null);
|
|
174
182
|
const [streamingContent, setStreamingContent] = useState("");
|
|
175
183
|
const clientRef = useRef(null);
|
|
184
|
+
const initRef = useRef(false);
|
|
185
|
+
const shouldPersist = config.persistSession ?? !!config.externalId;
|
|
186
|
+
const storageKey = getStorageKey(config.documentTypeId, config.externalId);
|
|
176
187
|
useEffect(() => {
|
|
177
188
|
clientRef.current = new InformedAIClient(config.apiUrl);
|
|
178
189
|
}, [config.apiUrl]);
|
|
190
|
+
const createNewSession = useCallback(async () => {
|
|
191
|
+
if (!clientRef.current) return null;
|
|
192
|
+
const result = await clientRef.current.createSession(
|
|
193
|
+
config.documentTypeId,
|
|
194
|
+
{
|
|
195
|
+
externalId: config.externalId,
|
|
196
|
+
initialData: config.initialData
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
const dt = {
|
|
200
|
+
id: result.documentType.id,
|
|
201
|
+
name: result.documentType.name,
|
|
202
|
+
displayName: result.documentType.displayName,
|
|
203
|
+
schema: result.documentType.schema,
|
|
204
|
+
workspaceId: "",
|
|
205
|
+
taskConfigs: {},
|
|
206
|
+
createdAt: "",
|
|
207
|
+
updatedAt: ""
|
|
208
|
+
};
|
|
209
|
+
if (shouldPersist && typeof window !== "undefined") {
|
|
210
|
+
try {
|
|
211
|
+
localStorage.setItem(storageKey, result.session.id);
|
|
212
|
+
} catch (e) {
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return { session: result.session, document: result.document, documentType: dt };
|
|
216
|
+
}, [config.documentTypeId, config.externalId, config.initialData, shouldPersist, storageKey]);
|
|
179
217
|
useEffect(() => {
|
|
218
|
+
if (initRef.current) return;
|
|
219
|
+
initRef.current = true;
|
|
180
220
|
async function initialize() {
|
|
181
221
|
if (!clientRef.current) return;
|
|
182
222
|
try {
|
|
183
223
|
setIsLoading(true);
|
|
184
224
|
setError(null);
|
|
185
|
-
let sess;
|
|
225
|
+
let sess = null;
|
|
186
226
|
let doc = null;
|
|
187
227
|
let dt = null;
|
|
188
|
-
|
|
189
|
-
|
|
228
|
+
let sessionIdToResume = config.sessionId;
|
|
229
|
+
if (!sessionIdToResume && shouldPersist && typeof window !== "undefined") {
|
|
230
|
+
try {
|
|
231
|
+
sessionIdToResume = localStorage.getItem(storageKey) || void 0;
|
|
232
|
+
} catch (e) {
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (sessionIdToResume) {
|
|
236
|
+
try {
|
|
237
|
+
sess = await clientRef.current.getSession(sessionIdToResume);
|
|
238
|
+
} catch (e) {
|
|
239
|
+
console.warn("Failed to resume session, creating new one");
|
|
240
|
+
if (shouldPersist && typeof window !== "undefined") {
|
|
241
|
+
try {
|
|
242
|
+
localStorage.removeItem(storageKey);
|
|
243
|
+
} catch (e2) {
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (!sess) {
|
|
249
|
+
const result = await createNewSession();
|
|
250
|
+
if (result) {
|
|
251
|
+
sess = result.session;
|
|
252
|
+
doc = result.document;
|
|
253
|
+
dt = result.documentType;
|
|
254
|
+
}
|
|
190
255
|
} else {
|
|
191
|
-
const result = await
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
displayName: result.documentType.displayName,
|
|
198
|
-
schema: result.documentType.schema,
|
|
199
|
-
workspaceId: "",
|
|
200
|
-
taskConfigs: {},
|
|
201
|
-
createdAt: "",
|
|
202
|
-
updatedAt: ""
|
|
203
|
-
};
|
|
256
|
+
const result = await createNewSession();
|
|
257
|
+
if (result) {
|
|
258
|
+
sess = result.session;
|
|
259
|
+
doc = result.document;
|
|
260
|
+
dt = result.documentType;
|
|
261
|
+
}
|
|
204
262
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
263
|
+
if (sess) {
|
|
264
|
+
setSession(sess);
|
|
265
|
+
if (doc) setDocument(doc);
|
|
266
|
+
if (dt) setDocumentType(dt);
|
|
267
|
+
config.onSessionChange?.(sess);
|
|
268
|
+
if (doc && dt) {
|
|
269
|
+
config.onReady?.({ session: sess, document: doc, documentType: dt });
|
|
270
|
+
}
|
|
211
271
|
}
|
|
212
272
|
} catch (err) {
|
|
213
273
|
const error2 = err instanceof Error ? err : new Error("Initialization failed");
|
|
@@ -218,7 +278,7 @@ function InformedAIProvider({ config, children }) {
|
|
|
218
278
|
}
|
|
219
279
|
}
|
|
220
280
|
initialize();
|
|
221
|
-
}, [config.documentTypeId, config.sessionId]);
|
|
281
|
+
}, [config.documentTypeId, config.sessionId, config.externalId]);
|
|
222
282
|
const handleSSEEvent = useCallback((event) => {
|
|
223
283
|
if (event.type === "content" && event.content) {
|
|
224
284
|
setStreamingContent((prev) => prev + event.content);
|
|
@@ -300,6 +360,37 @@ function InformedAIProvider({ config, children }) {
|
|
|
300
360
|
config.onError?.(error2);
|
|
301
361
|
}
|
|
302
362
|
}, [session, config]);
|
|
363
|
+
const startNewSession = useCallback(async () => {
|
|
364
|
+
if (!clientRef.current) return;
|
|
365
|
+
try {
|
|
366
|
+
setIsLoading(true);
|
|
367
|
+
setError(null);
|
|
368
|
+
if (shouldPersist && typeof window !== "undefined") {
|
|
369
|
+
try {
|
|
370
|
+
localStorage.removeItem(storageKey);
|
|
371
|
+
} catch (e) {
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
const result = await createNewSession();
|
|
375
|
+
if (result) {
|
|
376
|
+
setSession(result.session);
|
|
377
|
+
setDocument(result.document);
|
|
378
|
+
setDocumentType(result.documentType);
|
|
379
|
+
config.onSessionChange?.(result.session);
|
|
380
|
+
config.onReady?.({
|
|
381
|
+
session: result.session,
|
|
382
|
+
document: result.document,
|
|
383
|
+
documentType: result.documentType
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
} catch (err) {
|
|
387
|
+
const error2 = err instanceof Error ? err : new Error("Failed to start new session");
|
|
388
|
+
setError(error2);
|
|
389
|
+
config.onError?.(error2);
|
|
390
|
+
} finally {
|
|
391
|
+
setIsLoading(false);
|
|
392
|
+
}
|
|
393
|
+
}, [createNewSession, shouldPersist, storageKey, config]);
|
|
303
394
|
const clearError = useCallback(() => {
|
|
304
395
|
setError(null);
|
|
305
396
|
}, []);
|
|
@@ -315,6 +406,7 @@ function InformedAIProvider({ config, children }) {
|
|
|
315
406
|
sendQuickAction,
|
|
316
407
|
applyPendingValue,
|
|
317
408
|
skipTask,
|
|
409
|
+
startNewSession,
|
|
318
410
|
clearError
|
|
319
411
|
};
|
|
320
412
|
return /* @__PURE__ */ jsx(InformedAIContext.Provider, { value, children });
|