@agentuity/workbench 1.0.5 → 1.0.6

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.
Files changed (35) hide show
  1. package/dist/components/internal/chat.d.ts.map +1 -1
  2. package/dist/components/internal/chat.js +1 -1
  3. package/dist/components/internal/chat.js.map +1 -1
  4. package/dist/components/internal/input-section.d.ts.map +1 -1
  5. package/dist/components/internal/input-section.js +10 -10
  6. package/dist/components/internal/input-section.js.map +1 -1
  7. package/dist/components/internal/workbench-provider.d.ts +13 -1
  8. package/dist/components/internal/workbench-provider.d.ts.map +1 -1
  9. package/dist/components/internal/workbench-provider.js +96 -44
  10. package/dist/components/internal/workbench-provider.js.map +1 -1
  11. package/dist/components/ui/button.d.ts +1 -1
  12. package/dist/hooks/useAgentSchemas.d.ts +3 -0
  13. package/dist/hooks/useAgentSchemas.d.ts.map +1 -1
  14. package/dist/hooks/useAgentSchemas.js +18 -3
  15. package/dist/hooks/useAgentSchemas.js.map +1 -1
  16. package/dist/hooks/useLogger.d.ts.map +1 -1
  17. package/dist/hooks/useLogger.js +18 -14
  18. package/dist/hooks/useLogger.js.map +1 -1
  19. package/dist/hooks/useWorkbenchWebsocket.d.ts +1 -0
  20. package/dist/hooks/useWorkbenchWebsocket.d.ts.map +1 -1
  21. package/dist/hooks/useWorkbenchWebsocket.js +13 -2
  22. package/dist/hooks/useWorkbenchWebsocket.js.map +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/standalone.css +11 -0
  28. package/package.json +4 -4
  29. package/src/components/internal/chat.tsx +15 -5
  30. package/src/components/internal/input-section.tsx +17 -14
  31. package/src/components/internal/workbench-provider.tsx +133 -55
  32. package/src/hooks/useAgentSchemas.ts +23 -4
  33. package/src/hooks/useLogger.ts +15 -13
  34. package/src/hooks/useWorkbenchWebsocket.ts +16 -2
  35. package/src/index.ts +5 -1
@@ -1,6 +1,6 @@
1
1
  import type { WorkbenchConfig } from '@agentuity/core/workbench';
2
2
  import type React from 'react';
3
- import { createContext, useCallback, useContext, useEffect, useState } from 'react';
3
+ import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';
4
4
  import { useAgentSchemas } from '../../hooks/useAgentSchemas';
5
5
  import { useLogger } from '../../hooks/useLogger';
6
6
  import { useWorkbenchWebsocket } from '../../hooks/useWorkbenchWebsocket';
@@ -19,6 +19,13 @@ export function useWorkbench() {
19
19
  return context;
20
20
  }
21
21
 
22
+ /**
23
+ * Callback to get authentication headers for workbench requests.
24
+ * Called before each API request with the request body.
25
+ * Should return headers like X-Agentuity-Workbench-Signature and X-Agentuity-Workbench-Timestamp.
26
+ */
27
+ export type GetAuthHeaders = (body: string) => Promise<Record<string, string>>;
28
+
22
29
  interface WorkbenchProviderProps {
23
30
  config: Omit<WorkbenchConfig, 'route'> & {
24
31
  baseUrl?: string | null;
@@ -36,6 +43,12 @@ interface WorkbenchProviderProps {
36
43
  post?: React.ReactNode;
37
44
  };
38
45
  };
46
+ /**
47
+ * Optional callback to get authentication headers for requests to deployed agents.
48
+ * Called before each API request with the request body (empty string for GET/DELETE).
49
+ * Useful for signature-based authentication in production deployments.
50
+ */
51
+ getAuthHeaders?: GetAuthHeaders;
39
52
  }
40
53
 
41
54
  export function WorkbenchProvider({
@@ -47,9 +60,14 @@ export function WorkbenchProvider({
47
60
  },
48
61
  children,
49
62
  portals,
63
+ getAuthHeaders,
50
64
  }: WorkbenchProviderProps) {
51
65
  const logger = useLogger('WorkbenchProvider');
52
66
 
67
+ // Use ref for getAuthHeaders to prevent re-render loops when the callback changes identity
68
+ const getAuthHeadersRef = useRef(getAuthHeaders);
69
+ getAuthHeadersRef.current = getAuthHeaders;
70
+
53
71
  // localStorage utilities scoped by project
54
72
  const getStorageKey = useCallback(
55
73
  (key: string) =>
@@ -77,26 +95,35 @@ export function WorkbenchProvider({
77
95
  }
78
96
  }, [getStorageKey]);
79
97
 
98
+ // Thread IDs are stored per baseUrl to avoid signature mismatch between environments
99
+ // (local signs with 'agentuity', cloud signs with AGENTUITY_SDK_KEY)
100
+ const getThreadStorageKey = useCallback(() => {
101
+ // Use a hash of the baseUrl to create unique storage per endpoint
102
+ const url = config.baseUrl ?? 'local';
103
+ const urlHash = typeof url === 'string' ? btoa(encodeURIComponent(url)).slice(0, 16) : 'local';
104
+ return getStorageKey(`thread-id-${urlHash}`);
105
+ }, [getStorageKey, config.baseUrl]);
106
+
80
107
  const saveThreadId = useCallback(
81
108
  (threadId: string) => {
82
109
  try {
83
- localStorage.setItem(getStorageKey('thread-id'), threadId);
110
+ localStorage.setItem(getThreadStorageKey(), threadId);
84
111
  } catch (error) {
85
112
  logger.warn('Failed to save thread id to localStorage:', error);
86
113
  }
87
114
  },
88
- [getStorageKey]
115
+ [getThreadStorageKey]
89
116
  );
90
117
 
91
118
  const loadThreadId = useCallback((): string | null => {
92
119
  try {
93
- return localStorage.getItem(getStorageKey('thread-id'));
120
+ return localStorage.getItem(getThreadStorageKey());
94
121
  } catch (error) {
95
122
  logger.warn('Failed to load thread id from localStorage:', error);
96
123
 
97
124
  return null;
98
125
  }
99
- }, [getStorageKey]);
126
+ }, [getThreadStorageKey]);
100
127
 
101
128
  const applyThreadIdHeader = useCallback(
102
129
  (headers: Record<string, string>) => {
@@ -128,8 +155,51 @@ export function WorkbenchProvider({
128
155
  // Config values
129
156
  const baseUrl = config.baseUrl === undefined ? defaultBaseUrl : config.baseUrl;
130
157
  const apiKey = config.apiKey;
158
+ const configHeaders = config.headers;
131
159
  const isBaseUrlNull = config.baseUrl === null;
132
160
 
161
+ // Helper to build request headers with config headers, auth, and thread ID
162
+ const buildRequestHeaders = useCallback(
163
+ (additionalHeaders?: Record<string, string>): Record<string, string> => {
164
+ const headers: Record<string, string> = {
165
+ ...(configHeaders || {}),
166
+ ...(additionalHeaders || {}),
167
+ };
168
+
169
+ if (apiKey) {
170
+ headers.Authorization = `Bearer ${apiKey}`;
171
+ }
172
+
173
+ applyThreadIdHeader(headers);
174
+
175
+ return headers;
176
+ },
177
+ [configHeaders, apiKey, applyThreadIdHeader]
178
+ );
179
+
180
+ // Async helper to get request headers including auth headers from callback
181
+ const getRequestHeaders = useCallback(
182
+ async (
183
+ body: string,
184
+ additionalHeaders?: Record<string, string>
185
+ ): Promise<Record<string, string>> => {
186
+ const headers = buildRequestHeaders(additionalHeaders);
187
+
188
+ // Call getAuthHeaders callback if provided (use ref to avoid re-render loops)
189
+ if (getAuthHeadersRef.current) {
190
+ try {
191
+ const authHeaders = await getAuthHeadersRef.current(body);
192
+ Object.assign(headers, authHeaders);
193
+ } catch (error) {
194
+ logger.warn('Failed to get auth headers:', error);
195
+ }
196
+ }
197
+
198
+ return headers;
199
+ },
200
+ [buildRequestHeaders, logger]
201
+ );
202
+
133
203
  // Log baseUrl state
134
204
  useEffect(() => {
135
205
  if (isBaseUrlNull) {
@@ -139,14 +209,19 @@ export function WorkbenchProvider({
139
209
  }
140
210
  }, [isBaseUrlNull, baseUrl, logger]);
141
211
 
142
- // Set disconnected status if baseUrl is null
212
+ // Set connection status based on baseUrl availability
213
+ // In cloud mode, we don't have websocket so we set connected when baseUrl is available
143
214
  useEffect(() => {
144
215
  if (isBaseUrlNull) {
145
216
  logger.debug('🔌 Setting connection status to disconnected (baseUrl is null)');
146
-
147
217
  setConnectionStatus('disconnected');
218
+ } else if (env.cloud) {
219
+ // In cloud mode, we're "connected" as soon as we have a baseUrl
220
+ // (no websocket to wait for)
221
+ logger.debug('🔌 Setting connection status to connected (cloud mode with baseUrl)');
222
+ setConnectionStatus('connected');
148
223
  }
149
- }, [isBaseUrlNull, logger]);
224
+ }, [isBaseUrlNull, env.cloud, logger]);
150
225
 
151
226
  useEffect(() => {
152
227
  if (isBaseUrlNull) {
@@ -160,24 +235,31 @@ export function WorkbenchProvider({
160
235
  error: schemasError,
161
236
  refetch: refetchSchemas,
162
237
  } = useAgentSchemas({
163
- baseUrl,
238
+ baseUrl: baseUrl ?? undefined,
164
239
  apiKey,
240
+ headers: configHeaders,
165
241
  enabled: !isBaseUrlNull,
242
+ getAuthHeaders,
166
243
  });
167
244
 
168
245
  // WebSocket connection for dev server restart detection
169
- const wsBaseUrl = isBaseUrlNull ? undefined : baseUrl;
246
+ // Only enable for local dev - deployed agents don't have websocket endpoints
247
+ const wsEnabled = !isBaseUrlNull && !env.cloud;
248
+ const wsBaseUrl = wsEnabled && baseUrl ? baseUrl : undefined;
170
249
 
171
250
  useEffect(() => {
172
251
  if (isBaseUrlNull) {
173
252
  logger.debug('🔌 WebSocket connection disabled (baseUrl is null)');
253
+ } else if (env.cloud) {
254
+ logger.debug('🔌 WebSocket connection disabled (cloud mode)');
174
255
  }
175
- }, [isBaseUrlNull, logger]);
256
+ }, [isBaseUrlNull, env.cloud, logger]);
176
257
 
177
258
  const { connected } = useWorkbenchWebsocket({
178
- enabled: !isBaseUrlNull,
259
+ enabled: wsEnabled,
179
260
  baseUrl: wsBaseUrl,
180
261
  apiKey,
262
+ headers: configHeaders,
181
263
  onConnect: () => {
182
264
  setConnectionStatus('connected');
183
265
  refetchSchemas();
@@ -196,10 +278,12 @@ export function WorkbenchProvider({
196
278
  });
197
279
 
198
280
  useEffect(() => {
199
- if (!isBaseUrlNull && !connected && connectionStatus !== 'restarting') {
281
+ // In cloud mode, websocket is disabled so we stay 'connected' (no live connection tracking)
282
+ // In local mode, track the websocket connection status
283
+ if (!isBaseUrlNull && !env.cloud && !connected && connectionStatus !== 'restarting') {
200
284
  setConnectionStatus('disconnected');
201
285
  }
202
- }, [connected, connectionStatus, isBaseUrlNull]);
286
+ }, [connected, connectionStatus, isBaseUrlNull, env.cloud]);
203
287
 
204
288
  // Convert schema data to Agent format, no fallback
205
289
  const agents = schemaData?.agents;
@@ -228,18 +312,11 @@ export function WorkbenchProvider({
228
312
  }
229
313
 
230
314
  try {
231
- const headers: Record<string, string> = {};
232
-
233
- if (apiKey) {
234
- headers.Authorization = `Bearer ${apiKey}`;
235
- }
236
-
237
- applyThreadIdHeader(headers);
238
-
239
315
  const url = `${baseUrl}/_agentuity/workbench/state?agentId=${encodeURIComponent(agentId)}`;
240
316
 
241
317
  logger.debug('📡 Fetching state for agent:', agentId);
242
318
 
319
+ const headers = await getRequestHeaders('');
243
320
  const response = await fetch(url, {
244
321
  method: 'GET',
245
322
  headers,
@@ -295,7 +372,7 @@ export function WorkbenchProvider({
295
372
  setMessages([]);
296
373
  }
297
374
  },
298
- [baseUrl, apiKey, logger, applyThreadIdHeader, persistThreadIdFromResponse]
375
+ [baseUrl, logger, getRequestHeaders, persistThreadIdFromResponse]
299
376
  );
300
377
 
301
378
  // Set initial agent selection
@@ -369,6 +446,31 @@ export function WorkbenchProvider({
369
446
  }
370
447
  }, [agents, selectedAgent, loadSelectedAgent, saveSelectedAgent, logger, fetchAgentState]);
371
448
 
449
+ // Validate selected agent still exists when agents list changes (e.g., switching local ↔ cloud)
450
+ useEffect(() => {
451
+ if (!agents || Object.keys(agents).length === 0 || !selectedAgent) return;
452
+
453
+ const agentExists = Object.values(agents).some(
454
+ (agent) => agent.metadata.agentId === selectedAgent
455
+ );
456
+
457
+ if (!agentExists) {
458
+ logger.debug('⚠️ Selected agent no longer exists, falling back to first agent');
459
+
460
+ const sortedAgents = Object.values(agents).sort((a, b) =>
461
+ a.metadata.name.localeCompare(b.metadata.name)
462
+ );
463
+
464
+ const firstAgent = sortedAgents[0];
465
+
466
+ if (firstAgent) {
467
+ setSelectedAgent(firstAgent.metadata.agentId);
468
+ saveSelectedAgent(firstAgent.metadata.agentId);
469
+ fetchAgentState(firstAgent.metadata.agentId);
470
+ }
471
+ }
472
+ }, [agents, selectedAgent, logger, saveSelectedAgent, fetchAgentState]);
473
+
372
474
  const submitMessage = async (value: string, _mode: 'text' | 'form' = 'text') => {
373
475
  if (!selectedAgent) return;
374
476
 
@@ -456,16 +558,6 @@ export function WorkbenchProvider({
456
558
 
457
559
  logger.debug('🌐 About to make API call...');
458
560
 
459
- const headers: Record<string, string> = {
460
- 'Content-Type': 'application/json',
461
- };
462
-
463
- if (apiKey) {
464
- headers.Authorization = `Bearer ${apiKey}`;
465
- }
466
-
467
- applyThreadIdHeader(headers);
468
-
469
561
  const startTime = performance.now();
470
562
 
471
563
  try {
@@ -473,13 +565,17 @@ export function WorkbenchProvider({
473
565
  agentId: selectedAgent,
474
566
  input: parsedInput,
475
567
  };
568
+ const requestBody = JSON.stringify(requestPayload);
476
569
 
477
570
  logger.debug('📤 API Request payload:', requestPayload);
478
571
 
572
+ const headers = await getRequestHeaders(requestBody, {
573
+ 'Content-Type': 'application/json',
574
+ });
479
575
  const response = await fetch(`${baseUrl}/_agentuity/workbench/execute`, {
480
576
  method: 'POST',
481
577
  headers,
482
- body: JSON.stringify(requestPayload),
578
+ body: requestBody,
483
579
  credentials: 'include',
484
580
  });
485
581
 
@@ -641,19 +737,8 @@ export function WorkbenchProvider({
641
737
 
642
738
  try {
643
739
  const url = `${baseUrl}/_agentuity/workbench/sample?agentId=${encodeURIComponent(agentId)}`;
644
- const headers: HeadersInit = {
645
- 'Content-Type': 'application/json',
646
- };
647
-
648
- if (apiKey) {
649
- headers.Authorization = `Bearer ${apiKey}`;
650
- }
651
-
652
- // Keep thread id stable across workbench endpoints.
653
- if (typeof headers === 'object' && headers && !Array.isArray(headers)) {
654
- applyThreadIdHeader(headers as Record<string, string>);
655
- }
656
740
 
741
+ const headers = await getRequestHeaders('', { 'Content-Type': 'application/json' });
657
742
  const response = await fetch(url, {
658
743
  method: 'GET',
659
744
  headers,
@@ -713,15 +798,8 @@ export function WorkbenchProvider({
713
798
  }
714
799
 
715
800
  try {
716
- const headers: Record<string, string> = {};
717
-
718
- if (apiKey) {
719
- headers.Authorization = `Bearer ${apiKey}`;
720
- }
721
-
722
- applyThreadIdHeader(headers);
723
-
724
801
  const url = `${baseUrl}/_agentuity/workbench/state?agentId=${encodeURIComponent(agentId)}`;
802
+ const headers = await getRequestHeaders('');
725
803
  const response = await fetch(url, {
726
804
  method: 'DELETE',
727
805
  headers,
@@ -741,7 +819,7 @@ export function WorkbenchProvider({
741
819
  logger.debug('⚠️ Error clearing state:', error);
742
820
  }
743
821
  },
744
- [baseUrl, apiKey, logger, applyThreadIdHeader, persistThreadIdFromResponse]
822
+ [baseUrl, logger, getRequestHeaders, persistThreadIdFromResponse]
745
823
  );
746
824
 
747
825
  const contextValue: WorkbenchContextType = {
@@ -1,5 +1,6 @@
1
1
  import type { JSONSchema7 } from 'ai';
2
- import { useCallback, useEffect, useState } from 'react';
2
+ import { useCallback, useEffect, useRef, useState } from 'react';
3
+ import type { GetAuthHeaders } from '../components/internal/workbench-provider';
3
4
  import { useLogger } from './useLogger';
4
5
 
5
6
  export interface AgentSchema {
@@ -36,6 +37,8 @@ export interface UseAgentSchemasOptions {
36
37
  apiKey?: string;
37
38
  baseUrl?: string;
38
39
  enabled?: boolean;
40
+ headers?: Record<string, string>;
41
+ getAuthHeaders?: GetAuthHeaders;
39
42
  }
40
43
 
41
44
  export interface UseAgentSchemasResult {
@@ -66,13 +69,17 @@ export interface UseAgentSchemasResult {
66
69
  * ```
67
70
  */
68
71
  export function useAgentSchemas(options: UseAgentSchemasOptions = {}): UseAgentSchemasResult {
69
- const { baseUrl = '', apiKey, enabled = true } = options;
72
+ const { baseUrl = '', apiKey, enabled = true, headers: configHeaders, getAuthHeaders } = options;
70
73
 
71
74
  const logger = useLogger('useAgentSchemas');
72
75
  const [data, setData] = useState<AgentSchemasResponse | null>(null);
73
76
  const [isLoading, setIsLoading] = useState(false);
74
77
  const [error, setError] = useState<Error | null>(null);
75
78
 
79
+ // Use ref to avoid re-render loops when getAuthHeaders changes
80
+ const getAuthHeadersRef = useRef(getAuthHeaders);
81
+ getAuthHeadersRef.current = getAuthHeaders;
82
+
76
83
  const fetchSchemas = useCallback(async () => {
77
84
  if (!enabled) return;
78
85
 
@@ -81,7 +88,8 @@ export function useAgentSchemas(options: UseAgentSchemasOptions = {}): UseAgentS
81
88
 
82
89
  try {
83
90
  const url = `${baseUrl}/_agentuity/workbench/metadata.json`;
84
- const headers: HeadersInit = {
91
+ const headers: Record<string, string> = {
92
+ ...(configHeaders || {}),
85
93
  'Content-Type': 'application/json',
86
94
  };
87
95
 
@@ -89,6 +97,16 @@ export function useAgentSchemas(options: UseAgentSchemasOptions = {}): UseAgentS
89
97
  headers.Authorization = `Bearer ${apiKey}`;
90
98
  }
91
99
 
100
+ // Get auth headers if callback is provided
101
+ if (getAuthHeadersRef.current) {
102
+ try {
103
+ const authHeaders = await getAuthHeadersRef.current('');
104
+ Object.assign(headers, authHeaders);
105
+ } catch (err) {
106
+ logger.warn('Failed to get auth headers:', err);
107
+ }
108
+ }
109
+
92
110
  const response = await fetch(url, {
93
111
  method: 'GET',
94
112
  headers,
@@ -131,7 +149,8 @@ export function useAgentSchemas(options: UseAgentSchemasOptions = {}): UseAgentS
131
149
  } finally {
132
150
  setIsLoading(false);
133
151
  }
134
- }, [baseUrl, apiKey, enabled]);
152
+ // eslint-disable-next-line -- getAuthHeadersRef is a ref
153
+ }, [baseUrl, apiKey, enabled, configHeaders, logger]);
135
154
 
136
155
  const refetch = useCallback(() => {
137
156
  void fetchSchemas();
@@ -1,4 +1,4 @@
1
- import { useCallback } from 'react';
1
+ import { useMemo } from 'react';
2
2
 
3
3
  type LogLevel = 'debug' | 'info' | 'warn' | 'error';
4
4
 
@@ -39,8 +39,11 @@ const shouldLog = (messageLevel: LogLevel): boolean => {
39
39
  };
40
40
 
41
41
  export function useLogger(component?: string): Logger {
42
- const createLogFunction = useCallback(
43
- (level: LogLevel) =>
42
+ // Memoize the entire logger object to prevent re-render loops
43
+ // when logger is used as a dependency in useCallback/useEffect
44
+ return useMemo(() => {
45
+ const createLogFunction =
46
+ (level: LogLevel) =>
44
47
  (...args: unknown[]) => {
45
48
  if (!shouldLog(level)) {
46
49
  return;
@@ -50,14 +53,13 @@ export function useLogger(component?: string): Logger {
50
53
  const consoleFn = console[level] || console.log;
51
54
 
52
55
  consoleFn(prefix, ...args);
53
- },
54
- [component]
55
- );
56
-
57
- return {
58
- debug: createLogFunction('debug'),
59
- info: createLogFunction('info'),
60
- warn: createLogFunction('warn'),
61
- error: createLogFunction('error'),
62
- };
56
+ };
57
+
58
+ return {
59
+ debug: createLogFunction('debug'),
60
+ info: createLogFunction('info'),
61
+ warn: createLogFunction('warn'),
62
+ error: createLogFunction('error'),
63
+ };
64
+ }, [component]);
63
65
  }
@@ -1,5 +1,6 @@
1
1
  import { useCallback, useEffect, useRef, useState } from 'react';
2
2
 
3
+
3
4
  interface ReconnectOptions {
4
5
  baseDelay?: number;
5
6
  enabled?: () => boolean;
@@ -88,6 +89,7 @@ export interface UseWorkbenchWebsocketOptions {
88
89
  apiKey?: string;
89
90
  baseUrl?: string;
90
91
  enabled?: boolean;
92
+ headers?: Record<string, string>;
91
93
  onAlive?: () => void;
92
94
  onConnect?: () => void;
93
95
  onReconnect?: () => void;
@@ -102,7 +104,7 @@ export interface UseWorkbenchWebsocketResult {
102
104
  export function useWorkbenchWebsocket(
103
105
  options: UseWorkbenchWebsocketOptions = {}
104
106
  ): UseWorkbenchWebsocketResult {
105
- const { baseUrl, apiKey, onConnect, onReconnect, onAlive, onRestarting } = options;
107
+ const { baseUrl, apiKey, headers, onConnect, onReconnect, onAlive, onRestarting } = options;
106
108
 
107
109
  const [connected, setConnected] = useState(false);
108
110
  const [error, setError] = useState<Error | null>(null);
@@ -138,8 +140,20 @@ export function useWorkbenchWebsocket(
138
140
  url.searchParams.set('apiKey', apiKey);
139
141
  }
140
142
 
143
+ // Pass any manual headers as query params (WebSocket can't use custom headers in browser)
144
+ if (headers) {
145
+ const signature = headers['X-Agentuity-Workbench-Signature'];
146
+ const timestamp = headers['X-Agentuity-Workbench-Timestamp'];
147
+ if (signature) {
148
+ url.searchParams.set('signature', signature);
149
+ }
150
+ if (timestamp) {
151
+ url.searchParams.set('timestamp', timestamp);
152
+ }
153
+ }
154
+
141
155
  return url.toString();
142
- }, [baseUrl, apiKey]);
156
+ }, [baseUrl, apiKey, headers]);
143
157
 
144
158
  const connect = useCallback(() => {
145
159
  if (manualClose.current || !options.enabled) {
package/src/index.ts CHANGED
@@ -2,7 +2,11 @@ export { default as App } from './components/App';
2
2
  export { Chat } from './components/internal/chat';
3
3
  export { StatusIndicator } from './components/internal/header';
4
4
  export { Schema } from './components/internal/schema';
5
- export { useWorkbench, WorkbenchProvider } from './components/internal/workbench-provider';
5
+ export {
6
+ useWorkbench,
7
+ WorkbenchProvider,
8
+ type GetAuthHeaders,
9
+ } from './components/internal/workbench-provider';
6
10
  export type { WorkbenchInstance } from './types';
7
11
  export type { ConnectionStatus, WorkbenchMessage } from './types/config';
8
12
  export { createWorkbench } from './workbench';