@informedai/react 0.1.0 → 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/index.d.mts +43 -41
- package/dist/index.d.ts +43 -41
- package/dist/index.js +75 -138
- package/dist/index.mjs +75 -137
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -71,12 +71,10 @@ interface Document {
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
interface InformedAssistantConfig {
|
|
74
|
-
/**
|
|
75
|
-
|
|
74
|
+
/** Document Type ID - identifies which form schema to use */
|
|
75
|
+
documentTypeId: string;
|
|
76
76
|
/** API base URL (defaults to https://api.informedassistant.ai/api/v1) */
|
|
77
77
|
apiUrl?: string;
|
|
78
|
-
/** Document ID to work with */
|
|
79
|
-
documentId: string;
|
|
80
78
|
/** Optional: Existing session ID to resume */
|
|
81
79
|
sessionId?: string;
|
|
82
80
|
/** Callback when a field value is applied */
|
|
@@ -119,14 +117,6 @@ interface UseSessionReturn {
|
|
|
119
117
|
applyPendingValue: () => Promise<void>;
|
|
120
118
|
skipTask: () => Promise<void>;
|
|
121
119
|
}
|
|
122
|
-
interface UseDocumentReturn {
|
|
123
|
-
document: Document | null;
|
|
124
|
-
documentType: DocumentType | null;
|
|
125
|
-
isLoading: boolean;
|
|
126
|
-
error: Error | null;
|
|
127
|
-
updateField: (fieldName: string, value: unknown) => Promise<void>;
|
|
128
|
-
refetch: () => Promise<void>;
|
|
129
|
-
}
|
|
130
120
|
|
|
131
121
|
interface InformedAssistantProps extends InformedAssistantConfig {
|
|
132
122
|
/** Additional CSS class name */
|
|
@@ -173,62 +163,74 @@ declare function InformedAIProvider({ config, children }: InformedAIProviderProp
|
|
|
173
163
|
*/
|
|
174
164
|
|
|
175
165
|
interface UseSessionOptions {
|
|
176
|
-
|
|
166
|
+
/** Document Type ID - identifies which form schema to use */
|
|
167
|
+
documentTypeId: string;
|
|
168
|
+
/** API base URL (defaults to https://api.informedassistant.ai/api/v1) */
|
|
177
169
|
apiUrl?: string;
|
|
178
|
-
|
|
170
|
+
/** Optional: Existing session ID to resume */
|
|
179
171
|
sessionId?: string;
|
|
172
|
+
/** Callback when session state changes */
|
|
180
173
|
onSessionChange?: (session: Session) => void;
|
|
174
|
+
/** Callback when an error occurs */
|
|
181
175
|
onError?: (error: Error) => void;
|
|
182
176
|
}
|
|
183
177
|
declare function useSession(options: UseSessionOptions): UseSessionReturn;
|
|
184
178
|
|
|
185
|
-
/**
|
|
186
|
-
* useDocument Hook
|
|
187
|
-
* For developers who want direct access to document management
|
|
188
|
-
*/
|
|
189
|
-
|
|
190
|
-
interface UseDocumentOptions {
|
|
191
|
-
apiKey: string;
|
|
192
|
-
apiUrl?: string;
|
|
193
|
-
documentId: string;
|
|
194
|
-
onError?: (error: Error) => void;
|
|
195
|
-
}
|
|
196
|
-
declare function useDocument(options: UseDocumentOptions): UseDocumentReturn;
|
|
197
|
-
|
|
198
179
|
/**
|
|
199
180
|
* InformedAI API Client
|
|
200
181
|
* Handles all communication with the InformedAI backend
|
|
182
|
+
*
|
|
183
|
+
* Uses keyless widget endpoints with domain-based authentication.
|
|
201
184
|
*/
|
|
202
185
|
|
|
186
|
+
interface CreateSessionResponse {
|
|
187
|
+
session: Session;
|
|
188
|
+
document: Document;
|
|
189
|
+
documentType: {
|
|
190
|
+
id: string;
|
|
191
|
+
name: string;
|
|
192
|
+
displayName: string;
|
|
193
|
+
schema: unknown;
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
interface ApplyResponse {
|
|
197
|
+
session: Session;
|
|
198
|
+
appliedField: string;
|
|
199
|
+
appliedValue: unknown;
|
|
200
|
+
}
|
|
203
201
|
declare class InformedAIClient {
|
|
204
|
-
private apiKey;
|
|
205
202
|
private apiUrl;
|
|
206
|
-
constructor(
|
|
203
|
+
constructor(apiUrl?: string);
|
|
207
204
|
private getHeaders;
|
|
208
205
|
private request;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
206
|
+
/**
|
|
207
|
+
* Create a new session for a document type.
|
|
208
|
+
* This automatically creates a document with default values.
|
|
209
|
+
*/
|
|
210
|
+
createSession(documentTypeId: string): Promise<CreateSessionResponse>;
|
|
211
|
+
/**
|
|
212
|
+
* Get an existing session.
|
|
213
|
+
*/
|
|
213
214
|
getSession(id: string): Promise<Session>;
|
|
214
|
-
deleteSession(id: string): Promise<void>;
|
|
215
215
|
/**
|
|
216
|
-
* Send a message to the session with SSE streaming
|
|
216
|
+
* Send a message to the session with SSE streaming.
|
|
217
217
|
*/
|
|
218
218
|
sendMessage(sessionId: string, message: string, onEvent: (event: SSEEvent) => void): Promise<void>;
|
|
219
219
|
/**
|
|
220
|
-
* Send a quick action to the session
|
|
220
|
+
* Send a quick action to the session.
|
|
221
|
+
* For actions that trigger AI (task_action:*), returns SSE stream.
|
|
222
|
+
* For other actions (select_task:*, resume_task:*), returns session directly.
|
|
221
223
|
*/
|
|
222
|
-
sendQuickAction(sessionId: string, action: string,
|
|
224
|
+
sendQuickAction(sessionId: string, action: string, onEvent?: (event: SSEEvent) => void): Promise<Session>;
|
|
223
225
|
/**
|
|
224
|
-
* Apply the pending value for the active task
|
|
226
|
+
* Apply the pending value for the active task.
|
|
225
227
|
*/
|
|
226
|
-
applyPendingValue(sessionId: string): Promise<
|
|
228
|
+
applyPendingValue(sessionId: string): Promise<ApplyResponse>;
|
|
227
229
|
/**
|
|
228
|
-
* Skip the active task
|
|
230
|
+
* Skip the active task.
|
|
229
231
|
*/
|
|
230
232
|
skipTask(sessionId: string): Promise<Session>;
|
|
231
233
|
private processSSEStream;
|
|
232
234
|
}
|
|
233
235
|
|
|
234
|
-
export { type ChatMessage, type Document, type DocumentType, type DocumentTypeSchema, type FieldDefinition, InformedAIClient, InformedAIProvider, InformedAssistant, type InformedAssistantConfig, type QuickAction, type SSEEvent, type Session, type TaskConfig, type TaskState, type
|
|
236
|
+
export { type ChatMessage, type Document, type DocumentType, type DocumentTypeSchema, type FieldDefinition, InformedAIClient, InformedAIProvider, InformedAssistant, type InformedAssistantConfig, type QuickAction, type SSEEvent, type Session, type TaskConfig, type TaskState, type UseSessionReturn, type WidgetMessage, type WidgetTheme, useInformedAI, useSession };
|
package/dist/index.d.ts
CHANGED
|
@@ -71,12 +71,10 @@ interface Document {
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
interface InformedAssistantConfig {
|
|
74
|
-
/**
|
|
75
|
-
|
|
74
|
+
/** Document Type ID - identifies which form schema to use */
|
|
75
|
+
documentTypeId: string;
|
|
76
76
|
/** API base URL (defaults to https://api.informedassistant.ai/api/v1) */
|
|
77
77
|
apiUrl?: string;
|
|
78
|
-
/** Document ID to work with */
|
|
79
|
-
documentId: string;
|
|
80
78
|
/** Optional: Existing session ID to resume */
|
|
81
79
|
sessionId?: string;
|
|
82
80
|
/** Callback when a field value is applied */
|
|
@@ -119,14 +117,6 @@ interface UseSessionReturn {
|
|
|
119
117
|
applyPendingValue: () => Promise<void>;
|
|
120
118
|
skipTask: () => Promise<void>;
|
|
121
119
|
}
|
|
122
|
-
interface UseDocumentReturn {
|
|
123
|
-
document: Document | null;
|
|
124
|
-
documentType: DocumentType | null;
|
|
125
|
-
isLoading: boolean;
|
|
126
|
-
error: Error | null;
|
|
127
|
-
updateField: (fieldName: string, value: unknown) => Promise<void>;
|
|
128
|
-
refetch: () => Promise<void>;
|
|
129
|
-
}
|
|
130
120
|
|
|
131
121
|
interface InformedAssistantProps extends InformedAssistantConfig {
|
|
132
122
|
/** Additional CSS class name */
|
|
@@ -173,62 +163,74 @@ declare function InformedAIProvider({ config, children }: InformedAIProviderProp
|
|
|
173
163
|
*/
|
|
174
164
|
|
|
175
165
|
interface UseSessionOptions {
|
|
176
|
-
|
|
166
|
+
/** Document Type ID - identifies which form schema to use */
|
|
167
|
+
documentTypeId: string;
|
|
168
|
+
/** API base URL (defaults to https://api.informedassistant.ai/api/v1) */
|
|
177
169
|
apiUrl?: string;
|
|
178
|
-
|
|
170
|
+
/** Optional: Existing session ID to resume */
|
|
179
171
|
sessionId?: string;
|
|
172
|
+
/** Callback when session state changes */
|
|
180
173
|
onSessionChange?: (session: Session) => void;
|
|
174
|
+
/** Callback when an error occurs */
|
|
181
175
|
onError?: (error: Error) => void;
|
|
182
176
|
}
|
|
183
177
|
declare function useSession(options: UseSessionOptions): UseSessionReturn;
|
|
184
178
|
|
|
185
|
-
/**
|
|
186
|
-
* useDocument Hook
|
|
187
|
-
* For developers who want direct access to document management
|
|
188
|
-
*/
|
|
189
|
-
|
|
190
|
-
interface UseDocumentOptions {
|
|
191
|
-
apiKey: string;
|
|
192
|
-
apiUrl?: string;
|
|
193
|
-
documentId: string;
|
|
194
|
-
onError?: (error: Error) => void;
|
|
195
|
-
}
|
|
196
|
-
declare function useDocument(options: UseDocumentOptions): UseDocumentReturn;
|
|
197
|
-
|
|
198
179
|
/**
|
|
199
180
|
* InformedAI API Client
|
|
200
181
|
* Handles all communication with the InformedAI backend
|
|
182
|
+
*
|
|
183
|
+
* Uses keyless widget endpoints with domain-based authentication.
|
|
201
184
|
*/
|
|
202
185
|
|
|
186
|
+
interface CreateSessionResponse {
|
|
187
|
+
session: Session;
|
|
188
|
+
document: Document;
|
|
189
|
+
documentType: {
|
|
190
|
+
id: string;
|
|
191
|
+
name: string;
|
|
192
|
+
displayName: string;
|
|
193
|
+
schema: unknown;
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
interface ApplyResponse {
|
|
197
|
+
session: Session;
|
|
198
|
+
appliedField: string;
|
|
199
|
+
appliedValue: unknown;
|
|
200
|
+
}
|
|
203
201
|
declare class InformedAIClient {
|
|
204
|
-
private apiKey;
|
|
205
202
|
private apiUrl;
|
|
206
|
-
constructor(
|
|
203
|
+
constructor(apiUrl?: string);
|
|
207
204
|
private getHeaders;
|
|
208
205
|
private request;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
206
|
+
/**
|
|
207
|
+
* Create a new session for a document type.
|
|
208
|
+
* This automatically creates a document with default values.
|
|
209
|
+
*/
|
|
210
|
+
createSession(documentTypeId: string): Promise<CreateSessionResponse>;
|
|
211
|
+
/**
|
|
212
|
+
* Get an existing session.
|
|
213
|
+
*/
|
|
213
214
|
getSession(id: string): Promise<Session>;
|
|
214
|
-
deleteSession(id: string): Promise<void>;
|
|
215
215
|
/**
|
|
216
|
-
* Send a message to the session with SSE streaming
|
|
216
|
+
* Send a message to the session with SSE streaming.
|
|
217
217
|
*/
|
|
218
218
|
sendMessage(sessionId: string, message: string, onEvent: (event: SSEEvent) => void): Promise<void>;
|
|
219
219
|
/**
|
|
220
|
-
* Send a quick action to the session
|
|
220
|
+
* Send a quick action to the session.
|
|
221
|
+
* For actions that trigger AI (task_action:*), returns SSE stream.
|
|
222
|
+
* For other actions (select_task:*, resume_task:*), returns session directly.
|
|
221
223
|
*/
|
|
222
|
-
sendQuickAction(sessionId: string, action: string,
|
|
224
|
+
sendQuickAction(sessionId: string, action: string, onEvent?: (event: SSEEvent) => void): Promise<Session>;
|
|
223
225
|
/**
|
|
224
|
-
* Apply the pending value for the active task
|
|
226
|
+
* Apply the pending value for the active task.
|
|
225
227
|
*/
|
|
226
|
-
applyPendingValue(sessionId: string): Promise<
|
|
228
|
+
applyPendingValue(sessionId: string): Promise<ApplyResponse>;
|
|
227
229
|
/**
|
|
228
|
-
* Skip the active task
|
|
230
|
+
* Skip the active task.
|
|
229
231
|
*/
|
|
230
232
|
skipTask(sessionId: string): Promise<Session>;
|
|
231
233
|
private processSSEStream;
|
|
232
234
|
}
|
|
233
235
|
|
|
234
|
-
export { type ChatMessage, type Document, type DocumentType, type DocumentTypeSchema, type FieldDefinition, InformedAIClient, InformedAIProvider, InformedAssistant, type InformedAssistantConfig, type QuickAction, type SSEEvent, type Session, type TaskConfig, type TaskState, type
|
|
236
|
+
export { type ChatMessage, type Document, type DocumentType, type DocumentTypeSchema, type FieldDefinition, InformedAIClient, InformedAIProvider, InformedAssistant, type InformedAssistantConfig, type QuickAction, type SSEEvent, type Session, type TaskConfig, type TaskState, type UseSessionReturn, type WidgetMessage, type WidgetTheme, useInformedAI, useSession };
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,6 @@ __export(index_exports, {
|
|
|
23
23
|
InformedAIClient: () => InformedAIClient,
|
|
24
24
|
InformedAIProvider: () => InformedAIProvider,
|
|
25
25
|
InformedAssistant: () => InformedAssistant,
|
|
26
|
-
useDocument: () => useDocument,
|
|
27
26
|
useInformedAI: () => useInformedAI,
|
|
28
27
|
useSession: () => useSession
|
|
29
28
|
});
|
|
@@ -38,14 +37,12 @@ var import_react = require("react");
|
|
|
38
37
|
// src/utils/api-client.ts
|
|
39
38
|
var DEFAULT_API_URL = "https://api.informedassistant.ai/api/v1";
|
|
40
39
|
var InformedAIClient = class {
|
|
41
|
-
constructor(
|
|
42
|
-
this.apiKey = apiKey;
|
|
40
|
+
constructor(apiUrl) {
|
|
43
41
|
this.apiUrl = apiUrl || DEFAULT_API_URL;
|
|
44
42
|
}
|
|
45
43
|
getHeaders() {
|
|
46
44
|
return {
|
|
47
|
-
"Content-Type": "application/json"
|
|
48
|
-
"Authorization": `Bearer ${this.apiKey}`
|
|
45
|
+
"Content-Type": "application/json"
|
|
49
46
|
};
|
|
50
47
|
}
|
|
51
48
|
async request(endpoint, options = {}) {
|
|
@@ -66,40 +63,29 @@ var InformedAIClient = class {
|
|
|
66
63
|
return response.json();
|
|
67
64
|
}
|
|
68
65
|
// ========================================================================
|
|
69
|
-
//
|
|
66
|
+
// Widget Session Operations (keyless)
|
|
70
67
|
// ========================================================================
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
async updateDocumentField(documentId, field, value) {
|
|
78
|
-
return this.request(`/documents/${documentId}/field`, {
|
|
79
|
-
method: "PATCH",
|
|
80
|
-
body: JSON.stringify({ field, value })
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
// ========================================================================
|
|
84
|
-
// Session Operations
|
|
85
|
-
// ========================================================================
|
|
86
|
-
async createSession(documentId) {
|
|
87
|
-
return this.request("/sessions", {
|
|
68
|
+
/**
|
|
69
|
+
* Create a new session for a document type.
|
|
70
|
+
* This automatically creates a document with default values.
|
|
71
|
+
*/
|
|
72
|
+
async createSession(documentTypeId) {
|
|
73
|
+
return this.request("/widget/sessions", {
|
|
88
74
|
method: "POST",
|
|
89
|
-
body: JSON.stringify({
|
|
75
|
+
body: JSON.stringify({ documentTypeId })
|
|
90
76
|
});
|
|
91
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Get an existing session.
|
|
80
|
+
*/
|
|
92
81
|
async getSession(id) {
|
|
93
|
-
return this.request(`/sessions/${id}`);
|
|
94
|
-
}
|
|
95
|
-
async deleteSession(id) {
|
|
96
|
-
await this.request(`/sessions/${id}`, { method: "DELETE" });
|
|
82
|
+
return this.request(`/widget/sessions/${id}`);
|
|
97
83
|
}
|
|
98
84
|
/**
|
|
99
|
-
* Send a message to the session with SSE streaming
|
|
85
|
+
* Send a message to the session with SSE streaming.
|
|
100
86
|
*/
|
|
101
87
|
async sendMessage(sessionId, message, onEvent) {
|
|
102
|
-
const response = await fetch(`${this.apiUrl}/sessions/${sessionId}/message`, {
|
|
88
|
+
const response = await fetch(`${this.apiUrl}/widget/sessions/${sessionId}/message`, {
|
|
103
89
|
method: "POST",
|
|
104
90
|
headers: this.getHeaders(),
|
|
105
91
|
body: JSON.stringify({ message })
|
|
@@ -111,43 +97,50 @@ var InformedAIClient = class {
|
|
|
111
97
|
await this.processSSEStream(response, onEvent);
|
|
112
98
|
}
|
|
113
99
|
/**
|
|
114
|
-
* Send a quick action to the session
|
|
100
|
+
* Send a quick action to the session.
|
|
101
|
+
* For actions that trigger AI (task_action:*), returns SSE stream.
|
|
102
|
+
* For other actions (select_task:*, resume_task:*), returns session directly.
|
|
115
103
|
*/
|
|
116
|
-
async sendQuickAction(sessionId, action,
|
|
117
|
-
const response = await fetch(`${this.apiUrl}/sessions/${sessionId}/quick-action`, {
|
|
104
|
+
async sendQuickAction(sessionId, action, onEvent) {
|
|
105
|
+
const response = await fetch(`${this.apiUrl}/widget/sessions/${sessionId}/quick-action`, {
|
|
118
106
|
method: "POST",
|
|
119
107
|
headers: this.getHeaders(),
|
|
120
|
-
body: JSON.stringify({ action
|
|
108
|
+
body: JSON.stringify({ action })
|
|
121
109
|
});
|
|
122
110
|
if (!response.ok) {
|
|
123
111
|
const error = await response.json().catch(() => ({ error: "Request failed" }));
|
|
124
112
|
throw new Error(error.error || `HTTP ${response.status}`);
|
|
125
113
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
114
|
+
const contentType = response.headers.get("content-type") || "";
|
|
115
|
+
if (contentType.includes("text/event-stream")) {
|
|
116
|
+
let finalSession = null;
|
|
117
|
+
await this.processSSEStream(response, (event) => {
|
|
118
|
+
onEvent?.(event);
|
|
119
|
+
if (event.session) {
|
|
120
|
+
finalSession = event.session;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
if (!finalSession) {
|
|
124
|
+
return this.getSession(sessionId);
|
|
131
125
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
126
|
+
return finalSession;
|
|
127
|
+
} else {
|
|
128
|
+
return response.json();
|
|
135
129
|
}
|
|
136
|
-
return finalSession;
|
|
137
130
|
}
|
|
138
131
|
/**
|
|
139
|
-
* Apply the pending value for the active task
|
|
132
|
+
* Apply the pending value for the active task.
|
|
140
133
|
*/
|
|
141
134
|
async applyPendingValue(sessionId) {
|
|
142
|
-
return this.request(`/sessions/${sessionId}/apply`, {
|
|
135
|
+
return this.request(`/widget/sessions/${sessionId}/apply`, {
|
|
143
136
|
method: "POST"
|
|
144
137
|
});
|
|
145
138
|
}
|
|
146
139
|
/**
|
|
147
|
-
* Skip the active task
|
|
140
|
+
* Skip the active task.
|
|
148
141
|
*/
|
|
149
142
|
async skipTask(sessionId) {
|
|
150
|
-
return this.request(`/sessions/${sessionId}/skip`, {
|
|
143
|
+
return this.request(`/widget/sessions/${sessionId}/skip`, {
|
|
151
144
|
method: "POST"
|
|
152
145
|
});
|
|
153
146
|
}
|
|
@@ -211,25 +204,37 @@ function InformedAIProvider({ config, children }) {
|
|
|
211
204
|
const [streamingContent, setStreamingContent] = (0, import_react.useState)("");
|
|
212
205
|
const clientRef = (0, import_react.useRef)(null);
|
|
213
206
|
(0, import_react.useEffect)(() => {
|
|
214
|
-
clientRef.current = new InformedAIClient(config.
|
|
215
|
-
}, [config.
|
|
207
|
+
clientRef.current = new InformedAIClient(config.apiUrl);
|
|
208
|
+
}, [config.apiUrl]);
|
|
216
209
|
(0, import_react.useEffect)(() => {
|
|
217
210
|
async function initialize() {
|
|
218
211
|
if (!clientRef.current) return;
|
|
219
212
|
try {
|
|
220
213
|
setIsLoading(true);
|
|
221
214
|
setError(null);
|
|
222
|
-
const doc = await clientRef.current.getDocument(config.documentId);
|
|
223
|
-
setDocument(doc);
|
|
224
|
-
const dt = await clientRef.current.getDocumentType(doc.documentTypeId);
|
|
225
|
-
setDocumentType(dt);
|
|
226
215
|
let sess;
|
|
216
|
+
let doc = null;
|
|
217
|
+
let dt = null;
|
|
227
218
|
if (config.sessionId) {
|
|
228
219
|
sess = await clientRef.current.getSession(config.sessionId);
|
|
229
220
|
} else {
|
|
230
|
-
|
|
221
|
+
const result = await clientRef.current.createSession(config.documentTypeId);
|
|
222
|
+
sess = result.session;
|
|
223
|
+
doc = result.document;
|
|
224
|
+
dt = {
|
|
225
|
+
id: result.documentType.id,
|
|
226
|
+
name: result.documentType.name,
|
|
227
|
+
displayName: result.documentType.displayName,
|
|
228
|
+
schema: result.documentType.schema,
|
|
229
|
+
workspaceId: "",
|
|
230
|
+
taskConfigs: {},
|
|
231
|
+
createdAt: "",
|
|
232
|
+
updatedAt: ""
|
|
233
|
+
};
|
|
231
234
|
}
|
|
232
235
|
setSession(sess);
|
|
236
|
+
if (doc) setDocument(doc);
|
|
237
|
+
if (dt) setDocumentType(dt);
|
|
233
238
|
config.onSessionChange?.(sess);
|
|
234
239
|
} catch (err) {
|
|
235
240
|
const error2 = err instanceof Error ? err : new Error("Initialization failed");
|
|
@@ -240,7 +245,7 @@ function InformedAIProvider({ config, children }) {
|
|
|
240
245
|
}
|
|
241
246
|
}
|
|
242
247
|
initialize();
|
|
243
|
-
}, [config.
|
|
248
|
+
}, [config.documentTypeId, config.sessionId]);
|
|
244
249
|
const handleSSEEvent = (0, import_react.useCallback)((event) => {
|
|
245
250
|
if (event.type === "content" && event.content) {
|
|
246
251
|
setStreamingContent((prev) => prev + event.content);
|
|
@@ -249,11 +254,6 @@ function InformedAIProvider({ config, children }) {
|
|
|
249
254
|
if (event.session) {
|
|
250
255
|
setSession(event.session);
|
|
251
256
|
config.onSessionChange?.(event.session);
|
|
252
|
-
if (event.session.activeTask) {
|
|
253
|
-
const taskState = event.session.taskStates[event.session.activeTask];
|
|
254
|
-
if (taskState?.pendingValue !== void 0) {
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
257
|
}
|
|
258
258
|
setStreamingContent("");
|
|
259
259
|
setIsStreaming(false);
|
|
@@ -279,7 +279,7 @@ function InformedAIProvider({ config, children }) {
|
|
|
279
279
|
setIsStreaming(false);
|
|
280
280
|
}
|
|
281
281
|
}, [session, handleSSEEvent, config]);
|
|
282
|
-
const sendQuickAction = (0, import_react.useCallback)(async (action
|
|
282
|
+
const sendQuickAction = (0, import_react.useCallback)(async (action) => {
|
|
283
283
|
if (!clientRef.current || !session) return;
|
|
284
284
|
try {
|
|
285
285
|
setIsStreaming(true);
|
|
@@ -288,7 +288,6 @@ function InformedAIProvider({ config, children }) {
|
|
|
288
288
|
const newSession = await clientRef.current.sendQuickAction(
|
|
289
289
|
session.id,
|
|
290
290
|
action,
|
|
291
|
-
payload,
|
|
292
291
|
handleSSEEvent
|
|
293
292
|
);
|
|
294
293
|
setSession(newSession);
|
|
@@ -305,14 +304,10 @@ function InformedAIProvider({ config, children }) {
|
|
|
305
304
|
if (!clientRef.current || !session) return;
|
|
306
305
|
try {
|
|
307
306
|
setError(null);
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
config.onSessionChange?.(newSession);
|
|
313
|
-
if (activeTask && pendingValue !== void 0) {
|
|
314
|
-
config.onFieldApply?.(activeTask, pendingValue);
|
|
315
|
-
}
|
|
307
|
+
const result = await clientRef.current.applyPendingValue(session.id);
|
|
308
|
+
setSession(result.session);
|
|
309
|
+
config.onSessionChange?.(result.session);
|
|
310
|
+
config.onFieldApply?.(result.appliedField, result.appliedValue);
|
|
316
311
|
} catch (err) {
|
|
317
312
|
const error2 = err instanceof Error ? err : new Error("Failed to apply value");
|
|
318
313
|
setError(error2);
|
|
@@ -809,15 +804,15 @@ function LoadingSpinner({ size = 20 }) {
|
|
|
809
804
|
// src/hooks/useSession.ts
|
|
810
805
|
var import_react3 = require("react");
|
|
811
806
|
function useSession(options) {
|
|
812
|
-
const {
|
|
807
|
+
const { apiUrl, documentTypeId, sessionId, onSessionChange, onError } = options;
|
|
813
808
|
const [session, setSession] = (0, import_react3.useState)(null);
|
|
814
809
|
const [isLoading, setIsLoading] = (0, import_react3.useState)(true);
|
|
815
810
|
const [error, setError] = (0, import_react3.useState)(null);
|
|
816
811
|
const clientRef = (0, import_react3.useRef)(null);
|
|
817
812
|
const isStreamingRef = (0, import_react3.useRef)(false);
|
|
818
813
|
(0, import_react3.useEffect)(() => {
|
|
819
|
-
clientRef.current = new InformedAIClient(
|
|
820
|
-
}, [
|
|
814
|
+
clientRef.current = new InformedAIClient(apiUrl);
|
|
815
|
+
}, [apiUrl]);
|
|
821
816
|
(0, import_react3.useEffect)(() => {
|
|
822
817
|
async function initialize() {
|
|
823
818
|
if (!clientRef.current) return;
|
|
@@ -828,7 +823,8 @@ function useSession(options) {
|
|
|
828
823
|
if (sessionId) {
|
|
829
824
|
sess = await clientRef.current.getSession(sessionId);
|
|
830
825
|
} else {
|
|
831
|
-
|
|
826
|
+
const result = await clientRef.current.createSession(documentTypeId);
|
|
827
|
+
sess = result.session;
|
|
832
828
|
}
|
|
833
829
|
setSession(sess);
|
|
834
830
|
onSessionChange?.(sess);
|
|
@@ -841,7 +837,7 @@ function useSession(options) {
|
|
|
841
837
|
}
|
|
842
838
|
}
|
|
843
839
|
initialize();
|
|
844
|
-
}, [
|
|
840
|
+
}, [documentTypeId, sessionId, onSessionChange, onError]);
|
|
845
841
|
const handleSSEEvent = (0, import_react3.useCallback)((event) => {
|
|
846
842
|
if (event.type === "done" || event.type === "session_update") {
|
|
847
843
|
if (event.session) {
|
|
@@ -870,7 +866,7 @@ function useSession(options) {
|
|
|
870
866
|
isStreamingRef.current = false;
|
|
871
867
|
}
|
|
872
868
|
}, [session, handleSSEEvent, onError]);
|
|
873
|
-
const sendQuickAction = (0, import_react3.useCallback)(async (action
|
|
869
|
+
const sendQuickAction = (0, import_react3.useCallback)(async (action) => {
|
|
874
870
|
if (!clientRef.current || !session || isStreamingRef.current) return;
|
|
875
871
|
try {
|
|
876
872
|
isStreamingRef.current = true;
|
|
@@ -878,7 +874,6 @@ function useSession(options) {
|
|
|
878
874
|
const newSession = await clientRef.current.sendQuickAction(
|
|
879
875
|
session.id,
|
|
880
876
|
action,
|
|
881
|
-
payload,
|
|
882
877
|
handleSSEEvent
|
|
883
878
|
);
|
|
884
879
|
setSession(newSession);
|
|
@@ -895,9 +890,9 @@ function useSession(options) {
|
|
|
895
890
|
if (!clientRef.current || !session) return;
|
|
896
891
|
try {
|
|
897
892
|
setError(null);
|
|
898
|
-
const
|
|
899
|
-
setSession(
|
|
900
|
-
onSessionChange?.(
|
|
893
|
+
const result = await clientRef.current.applyPendingValue(session.id);
|
|
894
|
+
setSession(result.session);
|
|
895
|
+
onSessionChange?.(result.session);
|
|
901
896
|
} catch (err) {
|
|
902
897
|
const error2 = err instanceof Error ? err : new Error("Failed to apply value");
|
|
903
898
|
setError(error2);
|
|
@@ -927,69 +922,11 @@ function useSession(options) {
|
|
|
927
922
|
skipTask
|
|
928
923
|
};
|
|
929
924
|
}
|
|
930
|
-
|
|
931
|
-
// src/hooks/useDocument.ts
|
|
932
|
-
var import_react4 = require("react");
|
|
933
|
-
function useDocument(options) {
|
|
934
|
-
const { apiKey, apiUrl, documentId, onError } = options;
|
|
935
|
-
const [document, setDocument] = (0, import_react4.useState)(null);
|
|
936
|
-
const [documentType, setDocumentType] = (0, import_react4.useState)(null);
|
|
937
|
-
const [isLoading, setIsLoading] = (0, import_react4.useState)(true);
|
|
938
|
-
const [error, setError] = (0, import_react4.useState)(null);
|
|
939
|
-
const clientRef = (0, import_react4.useRef)(null);
|
|
940
|
-
(0, import_react4.useEffect)(() => {
|
|
941
|
-
clientRef.current = new InformedAIClient(apiKey, apiUrl);
|
|
942
|
-
}, [apiKey, apiUrl]);
|
|
943
|
-
const fetchDocument = (0, import_react4.useCallback)(async () => {
|
|
944
|
-
if (!clientRef.current) return;
|
|
945
|
-
try {
|
|
946
|
-
setIsLoading(true);
|
|
947
|
-
setError(null);
|
|
948
|
-
const doc = await clientRef.current.getDocument(documentId);
|
|
949
|
-
setDocument(doc);
|
|
950
|
-
const dt = await clientRef.current.getDocumentType(doc.documentTypeId);
|
|
951
|
-
setDocumentType(dt);
|
|
952
|
-
} catch (err) {
|
|
953
|
-
const error2 = err instanceof Error ? err : new Error("Failed to fetch document");
|
|
954
|
-
setError(error2);
|
|
955
|
-
onError?.(error2);
|
|
956
|
-
} finally {
|
|
957
|
-
setIsLoading(false);
|
|
958
|
-
}
|
|
959
|
-
}, [documentId, onError]);
|
|
960
|
-
(0, import_react4.useEffect)(() => {
|
|
961
|
-
fetchDocument();
|
|
962
|
-
}, [fetchDocument]);
|
|
963
|
-
const updateField = (0, import_react4.useCallback)(async (fieldName, value) => {
|
|
964
|
-
if (!clientRef.current || !document) return;
|
|
965
|
-
try {
|
|
966
|
-
setError(null);
|
|
967
|
-
const updatedDoc = await clientRef.current.updateDocumentField(document.id, fieldName, value);
|
|
968
|
-
setDocument(updatedDoc);
|
|
969
|
-
} catch (err) {
|
|
970
|
-
const error2 = err instanceof Error ? err : new Error("Failed to update field");
|
|
971
|
-
setError(error2);
|
|
972
|
-
onError?.(error2);
|
|
973
|
-
}
|
|
974
|
-
}, [document, onError]);
|
|
975
|
-
const refetch = (0, import_react4.useCallback)(async () => {
|
|
976
|
-
await fetchDocument();
|
|
977
|
-
}, [fetchDocument]);
|
|
978
|
-
return {
|
|
979
|
-
document,
|
|
980
|
-
documentType,
|
|
981
|
-
isLoading,
|
|
982
|
-
error,
|
|
983
|
-
updateField,
|
|
984
|
-
refetch
|
|
985
|
-
};
|
|
986
|
-
}
|
|
987
925
|
// Annotate the CommonJS export names for ESM import in node:
|
|
988
926
|
0 && (module.exports = {
|
|
989
927
|
InformedAIClient,
|
|
990
928
|
InformedAIProvider,
|
|
991
929
|
InformedAssistant,
|
|
992
|
-
useDocument,
|
|
993
930
|
useInformedAI,
|
|
994
931
|
useSession
|
|
995
932
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -7,14 +7,12 @@ import { createContext, useContext, useEffect, useState, useCallback, useRef } f
|
|
|
7
7
|
// src/utils/api-client.ts
|
|
8
8
|
var DEFAULT_API_URL = "https://api.informedassistant.ai/api/v1";
|
|
9
9
|
var InformedAIClient = class {
|
|
10
|
-
constructor(
|
|
11
|
-
this.apiKey = apiKey;
|
|
10
|
+
constructor(apiUrl) {
|
|
12
11
|
this.apiUrl = apiUrl || DEFAULT_API_URL;
|
|
13
12
|
}
|
|
14
13
|
getHeaders() {
|
|
15
14
|
return {
|
|
16
|
-
"Content-Type": "application/json"
|
|
17
|
-
"Authorization": `Bearer ${this.apiKey}`
|
|
15
|
+
"Content-Type": "application/json"
|
|
18
16
|
};
|
|
19
17
|
}
|
|
20
18
|
async request(endpoint, options = {}) {
|
|
@@ -35,40 +33,29 @@ var InformedAIClient = class {
|
|
|
35
33
|
return response.json();
|
|
36
34
|
}
|
|
37
35
|
// ========================================================================
|
|
38
|
-
//
|
|
36
|
+
// Widget Session Operations (keyless)
|
|
39
37
|
// ========================================================================
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
async updateDocumentField(documentId, field, value) {
|
|
47
|
-
return this.request(`/documents/${documentId}/field`, {
|
|
48
|
-
method: "PATCH",
|
|
49
|
-
body: JSON.stringify({ field, value })
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
// ========================================================================
|
|
53
|
-
// Session Operations
|
|
54
|
-
// ========================================================================
|
|
55
|
-
async createSession(documentId) {
|
|
56
|
-
return this.request("/sessions", {
|
|
38
|
+
/**
|
|
39
|
+
* Create a new session for a document type.
|
|
40
|
+
* This automatically creates a document with default values.
|
|
41
|
+
*/
|
|
42
|
+
async createSession(documentTypeId) {
|
|
43
|
+
return this.request("/widget/sessions", {
|
|
57
44
|
method: "POST",
|
|
58
|
-
body: JSON.stringify({
|
|
45
|
+
body: JSON.stringify({ documentTypeId })
|
|
59
46
|
});
|
|
60
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Get an existing session.
|
|
50
|
+
*/
|
|
61
51
|
async getSession(id) {
|
|
62
|
-
return this.request(`/sessions/${id}`);
|
|
63
|
-
}
|
|
64
|
-
async deleteSession(id) {
|
|
65
|
-
await this.request(`/sessions/${id}`, { method: "DELETE" });
|
|
52
|
+
return this.request(`/widget/sessions/${id}`);
|
|
66
53
|
}
|
|
67
54
|
/**
|
|
68
|
-
* Send a message to the session with SSE streaming
|
|
55
|
+
* Send a message to the session with SSE streaming.
|
|
69
56
|
*/
|
|
70
57
|
async sendMessage(sessionId, message, onEvent) {
|
|
71
|
-
const response = await fetch(`${this.apiUrl}/sessions/${sessionId}/message`, {
|
|
58
|
+
const response = await fetch(`${this.apiUrl}/widget/sessions/${sessionId}/message`, {
|
|
72
59
|
method: "POST",
|
|
73
60
|
headers: this.getHeaders(),
|
|
74
61
|
body: JSON.stringify({ message })
|
|
@@ -80,43 +67,50 @@ var InformedAIClient = class {
|
|
|
80
67
|
await this.processSSEStream(response, onEvent);
|
|
81
68
|
}
|
|
82
69
|
/**
|
|
83
|
-
* Send a quick action to the session
|
|
70
|
+
* Send a quick action to the session.
|
|
71
|
+
* For actions that trigger AI (task_action:*), returns SSE stream.
|
|
72
|
+
* For other actions (select_task:*, resume_task:*), returns session directly.
|
|
84
73
|
*/
|
|
85
|
-
async sendQuickAction(sessionId, action,
|
|
86
|
-
const response = await fetch(`${this.apiUrl}/sessions/${sessionId}/quick-action`, {
|
|
74
|
+
async sendQuickAction(sessionId, action, onEvent) {
|
|
75
|
+
const response = await fetch(`${this.apiUrl}/widget/sessions/${sessionId}/quick-action`, {
|
|
87
76
|
method: "POST",
|
|
88
77
|
headers: this.getHeaders(),
|
|
89
|
-
body: JSON.stringify({ action
|
|
78
|
+
body: JSON.stringify({ action })
|
|
90
79
|
});
|
|
91
80
|
if (!response.ok) {
|
|
92
81
|
const error = await response.json().catch(() => ({ error: "Request failed" }));
|
|
93
82
|
throw new Error(error.error || `HTTP ${response.status}`);
|
|
94
83
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
84
|
+
const contentType = response.headers.get("content-type") || "";
|
|
85
|
+
if (contentType.includes("text/event-stream")) {
|
|
86
|
+
let finalSession = null;
|
|
87
|
+
await this.processSSEStream(response, (event) => {
|
|
88
|
+
onEvent?.(event);
|
|
89
|
+
if (event.session) {
|
|
90
|
+
finalSession = event.session;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
if (!finalSession) {
|
|
94
|
+
return this.getSession(sessionId);
|
|
100
95
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
return finalSession;
|
|
97
|
+
} else {
|
|
98
|
+
return response.json();
|
|
104
99
|
}
|
|
105
|
-
return finalSession;
|
|
106
100
|
}
|
|
107
101
|
/**
|
|
108
|
-
* Apply the pending value for the active task
|
|
102
|
+
* Apply the pending value for the active task.
|
|
109
103
|
*/
|
|
110
104
|
async applyPendingValue(sessionId) {
|
|
111
|
-
return this.request(`/sessions/${sessionId}/apply`, {
|
|
105
|
+
return this.request(`/widget/sessions/${sessionId}/apply`, {
|
|
112
106
|
method: "POST"
|
|
113
107
|
});
|
|
114
108
|
}
|
|
115
109
|
/**
|
|
116
|
-
* Skip the active task
|
|
110
|
+
* Skip the active task.
|
|
117
111
|
*/
|
|
118
112
|
async skipTask(sessionId) {
|
|
119
|
-
return this.request(`/sessions/${sessionId}/skip`, {
|
|
113
|
+
return this.request(`/widget/sessions/${sessionId}/skip`, {
|
|
120
114
|
method: "POST"
|
|
121
115
|
});
|
|
122
116
|
}
|
|
@@ -180,25 +174,37 @@ function InformedAIProvider({ config, children }) {
|
|
|
180
174
|
const [streamingContent, setStreamingContent] = useState("");
|
|
181
175
|
const clientRef = useRef(null);
|
|
182
176
|
useEffect(() => {
|
|
183
|
-
clientRef.current = new InformedAIClient(config.
|
|
184
|
-
}, [config.
|
|
177
|
+
clientRef.current = new InformedAIClient(config.apiUrl);
|
|
178
|
+
}, [config.apiUrl]);
|
|
185
179
|
useEffect(() => {
|
|
186
180
|
async function initialize() {
|
|
187
181
|
if (!clientRef.current) return;
|
|
188
182
|
try {
|
|
189
183
|
setIsLoading(true);
|
|
190
184
|
setError(null);
|
|
191
|
-
const doc = await clientRef.current.getDocument(config.documentId);
|
|
192
|
-
setDocument(doc);
|
|
193
|
-
const dt = await clientRef.current.getDocumentType(doc.documentTypeId);
|
|
194
|
-
setDocumentType(dt);
|
|
195
185
|
let sess;
|
|
186
|
+
let doc = null;
|
|
187
|
+
let dt = null;
|
|
196
188
|
if (config.sessionId) {
|
|
197
189
|
sess = await clientRef.current.getSession(config.sessionId);
|
|
198
190
|
} else {
|
|
199
|
-
|
|
191
|
+
const result = await clientRef.current.createSession(config.documentTypeId);
|
|
192
|
+
sess = result.session;
|
|
193
|
+
doc = result.document;
|
|
194
|
+
dt = {
|
|
195
|
+
id: result.documentType.id,
|
|
196
|
+
name: result.documentType.name,
|
|
197
|
+
displayName: result.documentType.displayName,
|
|
198
|
+
schema: result.documentType.schema,
|
|
199
|
+
workspaceId: "",
|
|
200
|
+
taskConfigs: {},
|
|
201
|
+
createdAt: "",
|
|
202
|
+
updatedAt: ""
|
|
203
|
+
};
|
|
200
204
|
}
|
|
201
205
|
setSession(sess);
|
|
206
|
+
if (doc) setDocument(doc);
|
|
207
|
+
if (dt) setDocumentType(dt);
|
|
202
208
|
config.onSessionChange?.(sess);
|
|
203
209
|
} catch (err) {
|
|
204
210
|
const error2 = err instanceof Error ? err : new Error("Initialization failed");
|
|
@@ -209,7 +215,7 @@ function InformedAIProvider({ config, children }) {
|
|
|
209
215
|
}
|
|
210
216
|
}
|
|
211
217
|
initialize();
|
|
212
|
-
}, [config.
|
|
218
|
+
}, [config.documentTypeId, config.sessionId]);
|
|
213
219
|
const handleSSEEvent = useCallback((event) => {
|
|
214
220
|
if (event.type === "content" && event.content) {
|
|
215
221
|
setStreamingContent((prev) => prev + event.content);
|
|
@@ -218,11 +224,6 @@ function InformedAIProvider({ config, children }) {
|
|
|
218
224
|
if (event.session) {
|
|
219
225
|
setSession(event.session);
|
|
220
226
|
config.onSessionChange?.(event.session);
|
|
221
|
-
if (event.session.activeTask) {
|
|
222
|
-
const taskState = event.session.taskStates[event.session.activeTask];
|
|
223
|
-
if (taskState?.pendingValue !== void 0) {
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
227
|
}
|
|
227
228
|
setStreamingContent("");
|
|
228
229
|
setIsStreaming(false);
|
|
@@ -248,7 +249,7 @@ function InformedAIProvider({ config, children }) {
|
|
|
248
249
|
setIsStreaming(false);
|
|
249
250
|
}
|
|
250
251
|
}, [session, handleSSEEvent, config]);
|
|
251
|
-
const sendQuickAction = useCallback(async (action
|
|
252
|
+
const sendQuickAction = useCallback(async (action) => {
|
|
252
253
|
if (!clientRef.current || !session) return;
|
|
253
254
|
try {
|
|
254
255
|
setIsStreaming(true);
|
|
@@ -257,7 +258,6 @@ function InformedAIProvider({ config, children }) {
|
|
|
257
258
|
const newSession = await clientRef.current.sendQuickAction(
|
|
258
259
|
session.id,
|
|
259
260
|
action,
|
|
260
|
-
payload,
|
|
261
261
|
handleSSEEvent
|
|
262
262
|
);
|
|
263
263
|
setSession(newSession);
|
|
@@ -274,14 +274,10 @@ function InformedAIProvider({ config, children }) {
|
|
|
274
274
|
if (!clientRef.current || !session) return;
|
|
275
275
|
try {
|
|
276
276
|
setError(null);
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
config.onSessionChange?.(newSession);
|
|
282
|
-
if (activeTask && pendingValue !== void 0) {
|
|
283
|
-
config.onFieldApply?.(activeTask, pendingValue);
|
|
284
|
-
}
|
|
277
|
+
const result = await clientRef.current.applyPendingValue(session.id);
|
|
278
|
+
setSession(result.session);
|
|
279
|
+
config.onSessionChange?.(result.session);
|
|
280
|
+
config.onFieldApply?.(result.appliedField, result.appliedValue);
|
|
285
281
|
} catch (err) {
|
|
286
282
|
const error2 = err instanceof Error ? err : new Error("Failed to apply value");
|
|
287
283
|
setError(error2);
|
|
@@ -778,15 +774,15 @@ function LoadingSpinner({ size = 20 }) {
|
|
|
778
774
|
// src/hooks/useSession.ts
|
|
779
775
|
import { useState as useState3, useEffect as useEffect3, useCallback as useCallback2, useRef as useRef3 } from "react";
|
|
780
776
|
function useSession(options) {
|
|
781
|
-
const {
|
|
777
|
+
const { apiUrl, documentTypeId, sessionId, onSessionChange, onError } = options;
|
|
782
778
|
const [session, setSession] = useState3(null);
|
|
783
779
|
const [isLoading, setIsLoading] = useState3(true);
|
|
784
780
|
const [error, setError] = useState3(null);
|
|
785
781
|
const clientRef = useRef3(null);
|
|
786
782
|
const isStreamingRef = useRef3(false);
|
|
787
783
|
useEffect3(() => {
|
|
788
|
-
clientRef.current = new InformedAIClient(
|
|
789
|
-
}, [
|
|
784
|
+
clientRef.current = new InformedAIClient(apiUrl);
|
|
785
|
+
}, [apiUrl]);
|
|
790
786
|
useEffect3(() => {
|
|
791
787
|
async function initialize() {
|
|
792
788
|
if (!clientRef.current) return;
|
|
@@ -797,7 +793,8 @@ function useSession(options) {
|
|
|
797
793
|
if (sessionId) {
|
|
798
794
|
sess = await clientRef.current.getSession(sessionId);
|
|
799
795
|
} else {
|
|
800
|
-
|
|
796
|
+
const result = await clientRef.current.createSession(documentTypeId);
|
|
797
|
+
sess = result.session;
|
|
801
798
|
}
|
|
802
799
|
setSession(sess);
|
|
803
800
|
onSessionChange?.(sess);
|
|
@@ -810,7 +807,7 @@ function useSession(options) {
|
|
|
810
807
|
}
|
|
811
808
|
}
|
|
812
809
|
initialize();
|
|
813
|
-
}, [
|
|
810
|
+
}, [documentTypeId, sessionId, onSessionChange, onError]);
|
|
814
811
|
const handleSSEEvent = useCallback2((event) => {
|
|
815
812
|
if (event.type === "done" || event.type === "session_update") {
|
|
816
813
|
if (event.session) {
|
|
@@ -839,7 +836,7 @@ function useSession(options) {
|
|
|
839
836
|
isStreamingRef.current = false;
|
|
840
837
|
}
|
|
841
838
|
}, [session, handleSSEEvent, onError]);
|
|
842
|
-
const sendQuickAction = useCallback2(async (action
|
|
839
|
+
const sendQuickAction = useCallback2(async (action) => {
|
|
843
840
|
if (!clientRef.current || !session || isStreamingRef.current) return;
|
|
844
841
|
try {
|
|
845
842
|
isStreamingRef.current = true;
|
|
@@ -847,7 +844,6 @@ function useSession(options) {
|
|
|
847
844
|
const newSession = await clientRef.current.sendQuickAction(
|
|
848
845
|
session.id,
|
|
849
846
|
action,
|
|
850
|
-
payload,
|
|
851
847
|
handleSSEEvent
|
|
852
848
|
);
|
|
853
849
|
setSession(newSession);
|
|
@@ -864,9 +860,9 @@ function useSession(options) {
|
|
|
864
860
|
if (!clientRef.current || !session) return;
|
|
865
861
|
try {
|
|
866
862
|
setError(null);
|
|
867
|
-
const
|
|
868
|
-
setSession(
|
|
869
|
-
onSessionChange?.(
|
|
863
|
+
const result = await clientRef.current.applyPendingValue(session.id);
|
|
864
|
+
setSession(result.session);
|
|
865
|
+
onSessionChange?.(result.session);
|
|
870
866
|
} catch (err) {
|
|
871
867
|
const error2 = err instanceof Error ? err : new Error("Failed to apply value");
|
|
872
868
|
setError(error2);
|
|
@@ -896,68 +892,10 @@ function useSession(options) {
|
|
|
896
892
|
skipTask
|
|
897
893
|
};
|
|
898
894
|
}
|
|
899
|
-
|
|
900
|
-
// src/hooks/useDocument.ts
|
|
901
|
-
import { useState as useState4, useEffect as useEffect4, useCallback as useCallback3, useRef as useRef4 } from "react";
|
|
902
|
-
function useDocument(options) {
|
|
903
|
-
const { apiKey, apiUrl, documentId, onError } = options;
|
|
904
|
-
const [document, setDocument] = useState4(null);
|
|
905
|
-
const [documentType, setDocumentType] = useState4(null);
|
|
906
|
-
const [isLoading, setIsLoading] = useState4(true);
|
|
907
|
-
const [error, setError] = useState4(null);
|
|
908
|
-
const clientRef = useRef4(null);
|
|
909
|
-
useEffect4(() => {
|
|
910
|
-
clientRef.current = new InformedAIClient(apiKey, apiUrl);
|
|
911
|
-
}, [apiKey, apiUrl]);
|
|
912
|
-
const fetchDocument = useCallback3(async () => {
|
|
913
|
-
if (!clientRef.current) return;
|
|
914
|
-
try {
|
|
915
|
-
setIsLoading(true);
|
|
916
|
-
setError(null);
|
|
917
|
-
const doc = await clientRef.current.getDocument(documentId);
|
|
918
|
-
setDocument(doc);
|
|
919
|
-
const dt = await clientRef.current.getDocumentType(doc.documentTypeId);
|
|
920
|
-
setDocumentType(dt);
|
|
921
|
-
} catch (err) {
|
|
922
|
-
const error2 = err instanceof Error ? err : new Error("Failed to fetch document");
|
|
923
|
-
setError(error2);
|
|
924
|
-
onError?.(error2);
|
|
925
|
-
} finally {
|
|
926
|
-
setIsLoading(false);
|
|
927
|
-
}
|
|
928
|
-
}, [documentId, onError]);
|
|
929
|
-
useEffect4(() => {
|
|
930
|
-
fetchDocument();
|
|
931
|
-
}, [fetchDocument]);
|
|
932
|
-
const updateField = useCallback3(async (fieldName, value) => {
|
|
933
|
-
if (!clientRef.current || !document) return;
|
|
934
|
-
try {
|
|
935
|
-
setError(null);
|
|
936
|
-
const updatedDoc = await clientRef.current.updateDocumentField(document.id, fieldName, value);
|
|
937
|
-
setDocument(updatedDoc);
|
|
938
|
-
} catch (err) {
|
|
939
|
-
const error2 = err instanceof Error ? err : new Error("Failed to update field");
|
|
940
|
-
setError(error2);
|
|
941
|
-
onError?.(error2);
|
|
942
|
-
}
|
|
943
|
-
}, [document, onError]);
|
|
944
|
-
const refetch = useCallback3(async () => {
|
|
945
|
-
await fetchDocument();
|
|
946
|
-
}, [fetchDocument]);
|
|
947
|
-
return {
|
|
948
|
-
document,
|
|
949
|
-
documentType,
|
|
950
|
-
isLoading,
|
|
951
|
-
error,
|
|
952
|
-
updateField,
|
|
953
|
-
refetch
|
|
954
|
-
};
|
|
955
|
-
}
|
|
956
895
|
export {
|
|
957
896
|
InformedAIClient,
|
|
958
897
|
InformedAIProvider,
|
|
959
898
|
InformedAssistant,
|
|
960
|
-
useDocument,
|
|
961
899
|
useInformedAI,
|
|
962
900
|
useSession
|
|
963
901
|
};
|