@agentuity/workbench 1.0.5 → 1.0.7

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 +17 -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 +10 -0
  30. package/src/components/internal/input-section.tsx +62 -59
  31. package/src/components/internal/workbench-provider.tsx +134 -55
  32. package/src/hooks/useAgentSchemas.ts +22 -4
  33. package/src/hooks/useLogger.ts +15 -13
  34. package/src/hooks/useWorkbenchWebsocket.ts +15 -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,36 @@ 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 =
104
+ typeof url === 'string' ? btoa(encodeURIComponent(url)).slice(0, 16) : 'local';
105
+ return getStorageKey(`thread-id-${urlHash}`);
106
+ }, [getStorageKey, config.baseUrl]);
107
+
80
108
  const saveThreadId = useCallback(
81
109
  (threadId: string) => {
82
110
  try {
83
- localStorage.setItem(getStorageKey('thread-id'), threadId);
111
+ localStorage.setItem(getThreadStorageKey(), threadId);
84
112
  } catch (error) {
85
113
  logger.warn('Failed to save thread id to localStorage:', error);
86
114
  }
87
115
  },
88
- [getStorageKey]
116
+ [getThreadStorageKey]
89
117
  );
90
118
 
91
119
  const loadThreadId = useCallback((): string | null => {
92
120
  try {
93
- return localStorage.getItem(getStorageKey('thread-id'));
121
+ return localStorage.getItem(getThreadStorageKey());
94
122
  } catch (error) {
95
123
  logger.warn('Failed to load thread id from localStorage:', error);
96
124
 
97
125
  return null;
98
126
  }
99
- }, [getStorageKey]);
127
+ }, [getThreadStorageKey]);
100
128
 
101
129
  const applyThreadIdHeader = useCallback(
102
130
  (headers: Record<string, string>) => {
@@ -128,8 +156,51 @@ export function WorkbenchProvider({
128
156
  // Config values
129
157
  const baseUrl = config.baseUrl === undefined ? defaultBaseUrl : config.baseUrl;
130
158
  const apiKey = config.apiKey;
159
+ const configHeaders = config.headers;
131
160
  const isBaseUrlNull = config.baseUrl === null;
132
161
 
162
+ // Helper to build request headers with config headers, auth, and thread ID
163
+ const buildRequestHeaders = useCallback(
164
+ (additionalHeaders?: Record<string, string>): Record<string, string> => {
165
+ const headers: Record<string, string> = {
166
+ ...(configHeaders || {}),
167
+ ...(additionalHeaders || {}),
168
+ };
169
+
170
+ if (apiKey) {
171
+ headers.Authorization = `Bearer ${apiKey}`;
172
+ }
173
+
174
+ applyThreadIdHeader(headers);
175
+
176
+ return headers;
177
+ },
178
+ [configHeaders, apiKey, applyThreadIdHeader]
179
+ );
180
+
181
+ // Async helper to get request headers including auth headers from callback
182
+ const getRequestHeaders = useCallback(
183
+ async (
184
+ body: string,
185
+ additionalHeaders?: Record<string, string>
186
+ ): Promise<Record<string, string>> => {
187
+ const headers = buildRequestHeaders(additionalHeaders);
188
+
189
+ // Call getAuthHeaders callback if provided (use ref to avoid re-render loops)
190
+ if (getAuthHeadersRef.current) {
191
+ try {
192
+ const authHeaders = await getAuthHeadersRef.current(body);
193
+ Object.assign(headers, authHeaders);
194
+ } catch (error) {
195
+ logger.warn('Failed to get auth headers:', error);
196
+ }
197
+ }
198
+
199
+ return headers;
200
+ },
201
+ [buildRequestHeaders, logger]
202
+ );
203
+
133
204
  // Log baseUrl state
134
205
  useEffect(() => {
135
206
  if (isBaseUrlNull) {
@@ -139,14 +210,19 @@ export function WorkbenchProvider({
139
210
  }
140
211
  }, [isBaseUrlNull, baseUrl, logger]);
141
212
 
142
- // Set disconnected status if baseUrl is null
213
+ // Set connection status based on baseUrl availability
214
+ // In cloud mode, we don't have websocket so we set connected when baseUrl is available
143
215
  useEffect(() => {
144
216
  if (isBaseUrlNull) {
145
217
  logger.debug('🔌 Setting connection status to disconnected (baseUrl is null)');
146
-
147
218
  setConnectionStatus('disconnected');
219
+ } else if (env.cloud) {
220
+ // In cloud mode, we're "connected" as soon as we have a baseUrl
221
+ // (no websocket to wait for)
222
+ logger.debug('🔌 Setting connection status to connected (cloud mode with baseUrl)');
223
+ setConnectionStatus('connected');
148
224
  }
149
- }, [isBaseUrlNull, logger]);
225
+ }, [isBaseUrlNull, env.cloud, logger]);
150
226
 
151
227
  useEffect(() => {
152
228
  if (isBaseUrlNull) {
@@ -160,24 +236,31 @@ export function WorkbenchProvider({
160
236
  error: schemasError,
161
237
  refetch: refetchSchemas,
162
238
  } = useAgentSchemas({
163
- baseUrl,
239
+ baseUrl: baseUrl ?? undefined,
164
240
  apiKey,
241
+ headers: configHeaders,
165
242
  enabled: !isBaseUrlNull,
243
+ getAuthHeaders,
166
244
  });
167
245
 
168
246
  // WebSocket connection for dev server restart detection
169
- const wsBaseUrl = isBaseUrlNull ? undefined : baseUrl;
247
+ // Only enable for local dev - deployed agents don't have websocket endpoints
248
+ const wsEnabled = !isBaseUrlNull && !env.cloud;
249
+ const wsBaseUrl = wsEnabled && baseUrl ? baseUrl : undefined;
170
250
 
171
251
  useEffect(() => {
172
252
  if (isBaseUrlNull) {
173
253
  logger.debug('🔌 WebSocket connection disabled (baseUrl is null)');
254
+ } else if (env.cloud) {
255
+ logger.debug('🔌 WebSocket connection disabled (cloud mode)');
174
256
  }
175
- }, [isBaseUrlNull, logger]);
257
+ }, [isBaseUrlNull, env.cloud, logger]);
176
258
 
177
259
  const { connected } = useWorkbenchWebsocket({
178
- enabled: !isBaseUrlNull,
260
+ enabled: wsEnabled,
179
261
  baseUrl: wsBaseUrl,
180
262
  apiKey,
263
+ headers: configHeaders,
181
264
  onConnect: () => {
182
265
  setConnectionStatus('connected');
183
266
  refetchSchemas();
@@ -196,10 +279,12 @@ export function WorkbenchProvider({
196
279
  });
197
280
 
198
281
  useEffect(() => {
199
- if (!isBaseUrlNull && !connected && connectionStatus !== 'restarting') {
282
+ // In cloud mode, websocket is disabled so we stay 'connected' (no live connection tracking)
283
+ // In local mode, track the websocket connection status
284
+ if (!isBaseUrlNull && !env.cloud && !connected && connectionStatus !== 'restarting') {
200
285
  setConnectionStatus('disconnected');
201
286
  }
202
- }, [connected, connectionStatus, isBaseUrlNull]);
287
+ }, [connected, connectionStatus, isBaseUrlNull, env.cloud]);
203
288
 
204
289
  // Convert schema data to Agent format, no fallback
205
290
  const agents = schemaData?.agents;
@@ -228,18 +313,11 @@ export function WorkbenchProvider({
228
313
  }
229
314
 
230
315
  try {
231
- const headers: Record<string, string> = {};
232
-
233
- if (apiKey) {
234
- headers.Authorization = `Bearer ${apiKey}`;
235
- }
236
-
237
- applyThreadIdHeader(headers);
238
-
239
316
  const url = `${baseUrl}/_agentuity/workbench/state?agentId=${encodeURIComponent(agentId)}`;
240
317
 
241
318
  logger.debug('📡 Fetching state for agent:', agentId);
242
319
 
320
+ const headers = await getRequestHeaders('');
243
321
  const response = await fetch(url, {
244
322
  method: 'GET',
245
323
  headers,
@@ -295,7 +373,7 @@ export function WorkbenchProvider({
295
373
  setMessages([]);
296
374
  }
297
375
  },
298
- [baseUrl, apiKey, logger, applyThreadIdHeader, persistThreadIdFromResponse]
376
+ [baseUrl, logger, getRequestHeaders, persistThreadIdFromResponse]
299
377
  );
300
378
 
301
379
  // Set initial agent selection
@@ -369,6 +447,31 @@ export function WorkbenchProvider({
369
447
  }
370
448
  }, [agents, selectedAgent, loadSelectedAgent, saveSelectedAgent, logger, fetchAgentState]);
371
449
 
450
+ // Validate selected agent still exists when agents list changes (e.g., switching local ↔ cloud)
451
+ useEffect(() => {
452
+ if (!agents || Object.keys(agents).length === 0 || !selectedAgent) return;
453
+
454
+ const agentExists = Object.values(agents).some(
455
+ (agent) => agent.metadata.agentId === selectedAgent
456
+ );
457
+
458
+ if (!agentExists) {
459
+ logger.debug('⚠️ Selected agent no longer exists, falling back to first agent');
460
+
461
+ const sortedAgents = Object.values(agents).sort((a, b) =>
462
+ a.metadata.name.localeCompare(b.metadata.name)
463
+ );
464
+
465
+ const firstAgent = sortedAgents[0];
466
+
467
+ if (firstAgent) {
468
+ setSelectedAgent(firstAgent.metadata.agentId);
469
+ saveSelectedAgent(firstAgent.metadata.agentId);
470
+ fetchAgentState(firstAgent.metadata.agentId);
471
+ }
472
+ }
473
+ }, [agents, selectedAgent, logger, saveSelectedAgent, fetchAgentState]);
474
+
372
475
  const submitMessage = async (value: string, _mode: 'text' | 'form' = 'text') => {
373
476
  if (!selectedAgent) return;
374
477
 
@@ -456,16 +559,6 @@ export function WorkbenchProvider({
456
559
 
457
560
  logger.debug('🌐 About to make API call...');
458
561
 
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
562
  const startTime = performance.now();
470
563
 
471
564
  try {
@@ -473,13 +566,17 @@ export function WorkbenchProvider({
473
566
  agentId: selectedAgent,
474
567
  input: parsedInput,
475
568
  };
569
+ const requestBody = JSON.stringify(requestPayload);
476
570
 
477
571
  logger.debug('📤 API Request payload:', requestPayload);
478
572
 
573
+ const headers = await getRequestHeaders(requestBody, {
574
+ 'Content-Type': 'application/json',
575
+ });
479
576
  const response = await fetch(`${baseUrl}/_agentuity/workbench/execute`, {
480
577
  method: 'POST',
481
578
  headers,
482
- body: JSON.stringify(requestPayload),
579
+ body: requestBody,
483
580
  credentials: 'include',
484
581
  });
485
582
 
@@ -641,19 +738,8 @@ export function WorkbenchProvider({
641
738
 
642
739
  try {
643
740
  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
741
 
742
+ const headers = await getRequestHeaders('', { 'Content-Type': 'application/json' });
657
743
  const response = await fetch(url, {
658
744
  method: 'GET',
659
745
  headers,
@@ -713,15 +799,8 @@ export function WorkbenchProvider({
713
799
  }
714
800
 
715
801
  try {
716
- const headers: Record<string, string> = {};
717
-
718
- if (apiKey) {
719
- headers.Authorization = `Bearer ${apiKey}`;
720
- }
721
-
722
- applyThreadIdHeader(headers);
723
-
724
802
  const url = `${baseUrl}/_agentuity/workbench/state?agentId=${encodeURIComponent(agentId)}`;
803
+ const headers = await getRequestHeaders('');
725
804
  const response = await fetch(url, {
726
805
  method: 'DELETE',
727
806
  headers,
@@ -741,7 +820,7 @@ export function WorkbenchProvider({
741
820
  logger.debug('⚠️ Error clearing state:', error);
742
821
  }
743
822
  },
744
- [baseUrl, apiKey, logger, applyThreadIdHeader, persistThreadIdFromResponse]
823
+ [baseUrl, logger, getRequestHeaders, persistThreadIdFromResponse]
745
824
  );
746
825
 
747
826
  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,7 @@ export function useAgentSchemas(options: UseAgentSchemasOptions = {}): UseAgentS
131
149
  } finally {
132
150
  setIsLoading(false);
133
151
  }
134
- }, [baseUrl, apiKey, enabled]);
152
+ }, [baseUrl, apiKey, enabled, configHeaders, logger]);
135
153
 
136
154
  const refetch = useCallback(() => {
137
155
  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
  }
@@ -88,6 +88,7 @@ export interface UseWorkbenchWebsocketOptions {
88
88
  apiKey?: string;
89
89
  baseUrl?: string;
90
90
  enabled?: boolean;
91
+ headers?: Record<string, string>;
91
92
  onAlive?: () => void;
92
93
  onConnect?: () => void;
93
94
  onReconnect?: () => void;
@@ -102,7 +103,7 @@ export interface UseWorkbenchWebsocketResult {
102
103
  export function useWorkbenchWebsocket(
103
104
  options: UseWorkbenchWebsocketOptions = {}
104
105
  ): UseWorkbenchWebsocketResult {
105
- const { baseUrl, apiKey, onConnect, onReconnect, onAlive, onRestarting } = options;
106
+ const { baseUrl, apiKey, headers, onConnect, onReconnect, onAlive, onRestarting } = options;
106
107
 
107
108
  const [connected, setConnected] = useState(false);
108
109
  const [error, setError] = useState<Error | null>(null);
@@ -138,8 +139,20 @@ export function useWorkbenchWebsocket(
138
139
  url.searchParams.set('apiKey', apiKey);
139
140
  }
140
141
 
142
+ // Pass any manual headers as query params (WebSocket can't use custom headers in browser)
143
+ if (headers) {
144
+ const signature = headers['X-Agentuity-Workbench-Signature'];
145
+ const timestamp = headers['X-Agentuity-Workbench-Timestamp'];
146
+ if (signature) {
147
+ url.searchParams.set('signature', signature);
148
+ }
149
+ if (timestamp) {
150
+ url.searchParams.set('timestamp', timestamp);
151
+ }
152
+ }
153
+
141
154
  return url.toString();
142
- }, [baseUrl, apiKey]);
155
+ }, [baseUrl, apiKey, headers]);
143
156
 
144
157
  const connect = useCallback(() => {
145
158
  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';