@mcpstack/agent-sdk 1.0.0-pr.16.7572c080abaa.13.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react-app/index.tsx","../../src/framework/useAppAgentBinding.tsx","../../src/core/sse-client.ts","../../src/core/auth/registration.ts","../../src/core/auth-storage.ts","../../src/core/EmcyAgent.ts","../../src/app/types.ts","../../src/app/presentation.ts","../../src/app/oauth.ts","../../src/app/platform.ts","../../src/app/controller.ts","../../src/react/usePopupOAuthController.ts"],"sourcesContent":["import React, { createContext, useContext, useEffect, useMemo, useRef } from 'react';\nimport type { AppAgentConfig } from '../app/types';\nimport type { McpServerAuthConfig, OAuthTokenResponse } from '../core/types';\nimport {\n useAppAgentBinding,\n type OAuthPopupState,\n type UseAppAgentOptions,\n type UseAppAgentReturn,\n} from '../framework/useAppAgentBinding';\nimport { usePopupOAuthController } from '../react/usePopupOAuthController';\n\nconst AppAgentContext = createContext<UseAppAgentReturn | null>(null);\n\nexport interface AppAgentProviderProps extends AppAgentConfig {\n children: React.ReactNode;\n}\n\nexport function useAppAgent(\n config: AppAgentConfig,\n options?: UseAppAgentOptions,\n): UseAppAgentReturn {\n const shouldUseBuiltInPopupAuth = !config.onAuthRequired && !config.auth;\n const popupRequestAuthRef = useRef<(\n serverUrl: string,\n authConfig: McpServerAuthConfig,\n ) => Promise<OAuthTokenResponse | undefined> | null>(null);\n const builtInPopupAuthHandler = useMemo(() => {\n const handler = (\n serverUrl: string,\n authConfig: McpServerAuthConfig,\n ) => popupRequestAuthRef.current?.(serverUrl, authConfig) ?? Promise.resolve(undefined);\n\n (handler as { __mcpStackBuiltinPopupAuth?: boolean }).__mcpStackBuiltinPopupAuth = true;\n return handler;\n }, []);\n\n const base = useAppAgentBinding(\n config,\n options,\n shouldUseBuiltInPopupAuth\n ? { onAuthRequired: builtInPopupAuthHandler }\n : undefined,\n );\n\n const popup = usePopupOAuthController({\n resolveServerName: (serverUrl: string) =>\n base.runtime.agentConfig?.mcpServers.find((server) => server.url === serverUrl)?.name\n ?? 'MCP Server',\n oauthCallbackUrl: base.runtime.agent.getOAuthCallbackUrl(),\n oauthClientMetadataUrl: base.runtime.agent.getOAuthClientMetadataUrl(),\n userIdentity: config.userIdentity,\n appSessionKey: config.appSessionKey,\n });\n\n popupRequestAuthRef.current = popup.requestAuth;\n\n useEffect(() => {\n if (!shouldUseBuiltInPopupAuth) {\n return;\n }\n\n base.controller.setAuthRequiredHandler(builtInPopupAuthHandler);\n }, [base.controller, builtInPopupAuthHandler, shouldUseBuiltInPopupAuth]);\n\n useEffect(() => {\n base.connections.items.forEach((server) => {\n popup.handleServerAuthStatus(server.url, server.authStatus);\n });\n }, [base.connections.items, popup.handleServerAuthStatus]);\n\n const visiblePopupState: OAuthPopupState | null = shouldUseBuiltInPopupAuth && popup.popupState\n ? (\n base.connections.items.find((server) => server.url === popup.popupState?.serverUrl)?.authStatus === 'connected'\n ? null\n : popup.popupState\n )\n : null;\n\n return {\n ...base,\n popupAuthState: visiblePopupState,\n startOrRetryPopupAuth: popup.startOrRetryPopupAuth,\n cancelPopupAuth: popup.cancelPopupAuth,\n };\n}\n\nexport function AppAgentProvider({\n children,\n ...config\n}: AppAgentProviderProps) {\n const value = useAppAgent(config);\n return (\n <AppAgentContext.Provider value={value}>\n {children}\n </AppAgentContext.Provider>\n );\n}\n\nexport function useAppAgentContext(): UseAppAgentReturn {\n const context = useContext(AppAgentContext);\n if (!context) {\n throw new Error('useAppAgentContext must be used within an AppAgentProvider.');\n }\n\n return context;\n}\n\nexport type {\n OAuthPopupState,\n UseAppAgentOptions,\n UseAppAgentReturn,\n};\n","import {\n useEffect,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from 'react';\nimport type { McpServerAuthConfig, OAuthTokenResponse, SubmitConversationFeedbackRequest } from '../core/types';\nimport { AppAgentController, type AppAgentSnapshot } from '../app/controller';\nimport type { AppAgentConfig } from '../app/types';\n\nexport interface OAuthPopupState {\n serverName: string;\n serverUrl: string;\n phase: 'prompt' | 'preparing' | 'waiting' | 'exchanging' | 'blocked' | 'canceled' | 'error';\n statusMessage?: string | null;\n errorMessage?: string | null;\n hostIdentityLabel?: string | null;\n}\n\nexport interface UseAppAgentOptions {\n enabled?: boolean;\n}\n\nexport interface UseAppAgentReturn {\n controller: AppAgentController;\n runtime: AppAgentSnapshot['runtime'];\n conversation: AppAgentSnapshot['conversation'] & {\n loadMore: () => Promise<void>;\n reset: () => Promise<void>;\n };\n composer: {\n send: (prompt: string, options?: { displayText?: string }) => Promise<void>;\n cancel: () => void;\n };\n connections: AppAgentSnapshot['connections'] & {\n connect: (serverUrl: string) => Promise<boolean>;\n disconnect: (serverUrl: string) => Promise<void>;\n };\n approvals: AppAgentSnapshot['approvals'] & {\n resolve: (id: string, approved: boolean) => void;\n };\n requests: AppAgentSnapshot['requests'] & {\n submit: (id: string, values?: Record<string, unknown>) => void;\n cancel: (id: string) => void;\n };\n feedback: AppAgentSnapshot['feedback'] & {\n submit: (input: Omit<SubmitConversationFeedbackRequest, 'source'>) => Promise<unknown>;\n };\n budget: AppAgentSnapshot['budget'];\n voice: AppAgentSnapshot['voice'] & {\n start: () => Promise<void>;\n stop: () => Promise<void>;\n cancel: () => void;\n };\n popupAuthState: OAuthPopupState | null;\n startOrRetryPopupAuth: () => void;\n cancelPopupAuth: () => void;\n}\n\nexport function useAppAgentBinding(\n config: AppAgentConfig,\n options: UseAppAgentOptions | undefined,\n auth: {\n onAuthRequired?: (mcpServerUrl: string, authConfig: McpServerAuthConfig) => Promise<OAuthTokenResponse | undefined>;\n popupAuthState?: OAuthPopupState | null;\n startOrRetryPopupAuth?: () => void;\n cancelPopupAuth?: () => void;\n } = {},\n): UseAppAgentReturn {\n const enabled = options?.enabled ?? true;\n const disposeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const controller = useMemo(() => new AppAgentController({\n ...config,\n onAuthRequired: auth.onAuthRequired ?? config.onAuthRequired,\n }), [\n auth.onAuthRequired,\n config.agentId,\n config.apiKey,\n config.appSessionKey,\n config.auth?.appId,\n config.auth?.getToken,\n config.auth?.mode,\n config.conversation?.historyPageSize,\n config.conversation?.namespace,\n config.externalUserId,\n config.getAuthToken,\n config.oauthCallbackUrl,\n config.oauthClientMetadataUrl,\n config.onAuthRequired,\n config.platform,\n config.serviceUrl,\n config.storage,\n config.useCookies,\n config.userIdentity?.subject,\n enabled,\n ]);\n\n useEffect(() => {\n if (disposeTimerRef.current) {\n clearTimeout(disposeTimerRef.current);\n disposeTimerRef.current = null;\n }\n\n return () => {\n disposeTimerRef.current = setTimeout(() => {\n controller.dispose();\n disposeTimerRef.current = null;\n }, 0);\n };\n }, [controller]);\n\n useEffect(() => {\n controller.updateDynamicConfig({\n appContext: config.appContext,\n clientTools: config.clientTools,\n feedbackSource: config.feedbackSource,\n });\n }, [config.appContext, config.clientTools, config.feedbackSource, controller]);\n\n useEffect(() => {\n controller.setAuthRequiredHandler(auth.onAuthRequired ?? config.onAuthRequired);\n }, [auth.onAuthRequired, config.onAuthRequired, controller]);\n\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n controller.start();\n }, [controller, enabled]);\n\n const snapshot = useSyncExternalStore(\n controller.subscribe.bind(controller),\n controller.getSnapshot,\n controller.getSnapshot,\n );\n\n return {\n controller,\n runtime: snapshot.runtime,\n conversation: {\n ...snapshot.conversation,\n loadMore: () => controller.loadMore(),\n reset: () => controller.resetConversation(),\n },\n composer: {\n send: (prompt, sendOptions) => controller.send(prompt, sendOptions),\n cancel: () => controller.cancel(),\n },\n connections: {\n ...snapshot.connections,\n connect: (serverUrl) => controller.connect(serverUrl),\n disconnect: (serverUrl) => controller.disconnect(serverUrl),\n },\n approvals: {\n ...snapshot.approvals,\n resolve: (id, approved) => controller.resolveApproval(id, approved),\n },\n requests: {\n ...snapshot.requests,\n submit: (id, values) => controller.submitRequest(id, values),\n cancel: (id) => controller.cancelRequest(id),\n },\n feedback: {\n ...snapshot.feedback,\n submit: (input) => controller.submitFeedback(input),\n },\n budget: snapshot.budget,\n voice: {\n ...snapshot.voice,\n start: () => controller.startVoiceInput(),\n stop: () => controller.stopVoiceInput(),\n cancel: () => controller.cancelVoiceInput(),\n },\n popupAuthState: auth.popupAuthState ?? null,\n startOrRetryPopupAuth: auth.startOrRetryPopupAuth ?? (() => undefined),\n cancelPopupAuth: auth.cancelPopupAuth ?? (() => undefined),\n };\n}\n","/**\n * Parses an SSE stream from the MCP Stack chat API.\n * Yields parsed events as they arrive.\n */\nexport interface ParsedSseEvent {\n type: string;\n data: unknown;\n}\n\nfunction* parseEventBlocks(input: string): Generator<ParsedSseEvent> {\n const normalized = input.replace(/\\r\\n/g, '\\n');\n const eventBlocks = normalized.split('\\n\\n');\n\n for (const eventBlock of eventBlocks) {\n if (!eventBlock.trim()) continue;\n\n let eventType = '';\n const dataLines: string[] = [];\n\n for (const line of eventBlock.split('\\n')) {\n if (line.startsWith('event: ')) {\n eventType = line.slice('event: '.length);\n } else if (line.startsWith('data: ')) {\n dataLines.push(line.slice('data: '.length));\n } else if (line === 'data:') {\n dataLines.push('');\n }\n }\n\n if (!eventType || dataLines.length === 0) {\n continue;\n }\n\n try {\n const parsed = JSON.parse(dataLines.join('\\n'));\n yield { type: eventType, data: parsed };\n } catch {\n // Skip malformed JSON payloads.\n }\n }\n}\n\nexport async function* parseSseStream(\n response: Response,\n signal?: AbortSignal,\n): AsyncGenerator<ParsedSseEvent> {\n const reader = response.body?.getReader();\n if (!reader) {\n const text = await response.text().catch(() => '');\n yield* parseEventBlocks(text);\n return;\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n if (signal?.aborted) break;\n\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const normalized = buffer.replace(/\\r\\n/g, '\\n');\n\n // Split on double newlines (SSE event boundary)\n const events = normalized.split('\\n\\n');\n buffer = events.pop() ?? '';\n\n for (const eventBlock of events) {\n yield* parseEventBlocks(eventBlock);\n }\n }\n\n if (buffer.trim()) {\n yield* parseEventBlocks(buffer);\n }\n } finally {\n reader.releaseLock();\n }\n}\n","import type {\n McpStackStorageLike,\n McpClientRegistrationPreference,\n McpResolvedClientMode,\n McpServerAuthConfig,\n OAuthDynamicClientRegistrationRequest,\n OAuthDynamicClientRegistrationResponse,\n ResolvedOAuthRegistration,\n StoredOAuthRegistration,\n} from '../types';\n\nconst REGISTRATION_STORAGE_PREFIX = 'mcpstack_oauth_registration_';\n\nfunction getStorage(storage?: McpStackStorageLike | null): McpStackStorageLike | null {\n if (storage) {\n return storage;\n }\n\n try {\n return typeof localStorage === 'undefined' ? null : localStorage;\n } catch {\n return null;\n }\n}\n\nfunction encodeCacheKey(raw: string): string {\n return btoa(raw).replace(/[^a-zA-Z0-9]/g, '');\n}\n\nexport function getPreferredRegistrationPreference(\n authConfig: McpServerAuthConfig | null | undefined,\n): McpClientRegistrationPreference {\n return authConfig?.registrationPreference ?? 'auto';\n}\n\nexport function getEffectiveCallbackUrl(\n authConfig: McpServerAuthConfig | null | undefined,\n fallbackCallbackUrl: string,\n): string {\n const configuredCallbackUrl = authConfig?.callbackUrl?.trim();\n if (!configuredCallbackUrl) {\n return fallbackCallbackUrl;\n }\n\n if (isNativeCallbackUrl(fallbackCallbackUrl) && !isNativeCallbackUrl(configuredCallbackUrl)) {\n return fallbackCallbackUrl;\n }\n\n return configuredCallbackUrl;\n}\n\nexport function buildRegistrationCacheKey(\n authConfig: McpServerAuthConfig,\n callbackUrl: string,\n requestedMode: McpResolvedClientMode,\n): string {\n const raw = [\n authConfig.authorizationServerUrl ?? '',\n authConfig.authorizationServerMetadataUrl ?? '',\n authConfig.resource ?? '',\n callbackUrl,\n requestedMode,\n ].join('|');\n return encodeCacheKey(raw);\n}\n\nexport function buildTokenCacheKey(\n authConfig: McpServerAuthConfig | null | undefined,\n mcpServerUrl: string,\n): string {\n if (!authConfig) {\n return encodeCacheKey(`legacy|${mcpServerUrl}`);\n }\n\n const callbackUrl = authConfig.callbackUrl ?? '';\n const clientMode = authConfig.clientMode ?? 'manual';\n const raw = [\n authConfig.authorizationServerUrl ?? mcpServerUrl,\n authConfig.resource ?? '',\n callbackUrl,\n clientMode,\n ].join('|');\n return encodeCacheKey(raw);\n}\n\nexport function loadStoredRegistration(\n cacheKey: string,\n storage?: McpStackStorageLike | null,\n): StoredOAuthRegistration | null {\n const targetStorage = getStorage(storage);\n if (!targetStorage) return null;\n\n try {\n const raw = targetStorage.getItem(`${REGISTRATION_STORAGE_PREFIX}${cacheKey}`);\n if (!raw) return null;\n return JSON.parse(raw) as StoredOAuthRegistration;\n } catch {\n return null;\n }\n}\n\nexport function saveStoredRegistration(\n registration: StoredOAuthRegistration,\n storage?: McpStackStorageLike | null,\n): void {\n const targetStorage = getStorage(storage);\n if (!targetStorage) return;\n\n try {\n targetStorage.setItem(\n `${REGISTRATION_STORAGE_PREFIX}${registration.key}`,\n JSON.stringify(registration),\n );\n } catch {\n // Ignore storage failures in private browsing or sandboxed contexts.\n }\n}\n\nexport function clearStoredRegistration(\n cacheKey: string,\n storage?: McpStackStorageLike | null,\n): void {\n const targetStorage = getStorage(storage);\n if (!targetStorage) return;\n\n try {\n targetStorage.removeItem(`${REGISTRATION_STORAGE_PREFIX}${cacheKey}`);\n } catch {\n // Ignore storage failures.\n }\n}\n\nexport function applyResolvedRegistration(\n authConfig: McpServerAuthConfig,\n registration: ResolvedOAuthRegistration,\n): McpServerAuthConfig {\n return {\n ...authConfig,\n callbackUrl: registration.callbackUrl,\n clientId: registration.clientId ?? authConfig.clientId,\n clientMode: registration.mode,\n resource: registration.resource ?? authConfig.resource,\n authorizationServerUrl:\n registration.authorizationServerUrl ?? authConfig.authorizationServerUrl,\n authorizationServerMetadataUrl:\n registration.authorizationServerMetadataUrl\n ?? authConfig.authorizationServerMetadataUrl,\n registrationEndpoint:\n registration.registrationEndpoint ?? authConfig.registrationEndpoint,\n };\n}\n\nexport interface ResolveOAuthRegistrationOptions {\n callbackUrl: string;\n oauthClientMetadataUrl?: string;\n clientName?: string;\n clientUri?: string;\n fetchImpl?: typeof fetch;\n storage?: McpStackStorageLike | null;\n}\n\nfunction createResolvedRegistration(\n authConfig: McpServerAuthConfig,\n mode: McpResolvedClientMode,\n callbackUrl: string,\n clientId?: string,\n clientMetadataUrl?: string,\n): ResolvedOAuthRegistration {\n return {\n cacheKey: buildRegistrationCacheKey(authConfig, callbackUrl, mode),\n mode,\n clientId,\n callbackUrl,\n resource: authConfig.resource,\n authorizationServerUrl: authConfig.authorizationServerUrl,\n authorizationServerMetadataUrl: authConfig.authorizationServerMetadataUrl,\n registrationEndpoint: authConfig.registrationEndpoint,\n clientMetadataUrl,\n };\n}\n\nfunction shouldAttemptMode(\n preferred: McpClientRegistrationPreference,\n candidate: McpResolvedClientMode,\n): boolean {\n return preferred === 'auto' || preferred === candidate;\n}\n\nfunction isLoopbackHost(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]' || hostname === '::1';\n}\n\nfunction isNativeCallbackUrl(callbackUrl: string): boolean {\n try {\n const url = new URL(callbackUrl);\n return url.protocol !== 'http:' && url.protocol !== 'https:';\n } catch {\n return !callbackUrl.startsWith('http://') && !callbackUrl.startsWith('https://');\n }\n}\n\nfunction inferApplicationType(callbackUrl: string): 'web' | 'native' {\n try {\n const url = new URL(callbackUrl);\n if (url.protocol === 'http:' || url.protocol === 'https:') {\n return isLoopbackHost(url.hostname) ? 'native' : 'web';\n }\n\n return 'native';\n } catch {\n return 'native';\n }\n}\n\nexport async function registerPublicClient(\n authConfig: McpServerAuthConfig,\n options: ResolveOAuthRegistrationOptions,\n): Promise<ResolvedOAuthRegistration> {\n const fetchImpl = options.fetchImpl ?? fetch;\n const callbackUrl = options.callbackUrl;\n const registration = createResolvedRegistration(authConfig, 'dcr', callbackUrl);\n\n if (!authConfig.registrationEndpoint) {\n throw new Error('Dynamic client registration is not available for this server.');\n }\n\n const existing = loadStoredRegistration(registration.cacheKey, options.storage);\n if (existing?.clientId) {\n return {\n ...registration,\n clientId: existing.clientId,\n };\n }\n\n const requestBody: OAuthDynamicClientRegistrationRequest = {\n client_name: options.clientName ?? 'MCP Stack MCP Client',\n application_type: inferApplicationType(callbackUrl),\n redirect_uris: [callbackUrl],\n grant_types: ['authorization_code', 'refresh_token'],\n response_types: ['code'],\n token_endpoint_auth_method: 'none',\n scope: authConfig.scopes?.join(' '),\n client_uri: options.clientUri,\n };\n\n const response = await fetchImpl(authConfig.registrationEndpoint, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Dynamic client registration failed.');\n throw new Error(`Dynamic client registration failed (${response.status}): ${errorText}`);\n }\n\n const payload = await response.json() as OAuthDynamicClientRegistrationResponse;\n if (!payload.client_id) {\n throw new Error('Dynamic client registration response did not include a client_id.');\n }\n\n saveStoredRegistration({\n key: registration.cacheKey,\n mode: 'dcr',\n authorizationServerUrl: authConfig.authorizationServerUrl ?? '',\n authorizationServerMetadataUrl: authConfig.authorizationServerMetadataUrl,\n registrationEndpoint: authConfig.registrationEndpoint,\n clientId: payload.client_id,\n callbackUrl,\n resource: authConfig.resource,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n }, options.storage);\n\n return {\n ...registration,\n clientId: payload.client_id,\n };\n}\n\nexport async function resolveOAuthRegistration(\n authConfig: McpServerAuthConfig,\n options: ResolveOAuthRegistrationOptions,\n): Promise<ResolvedOAuthRegistration> {\n const callbackUrl = getEffectiveCallbackUrl(authConfig, options.callbackUrl);\n const preferred = getPreferredRegistrationPreference(authConfig);\n const preregClientId = authConfig.clientId?.trim();\n\n if (preregClientId && shouldAttemptMode(preferred, 'preregistered')) {\n return createResolvedRegistration(\n authConfig,\n 'preregistered',\n callbackUrl,\n preregClientId,\n );\n }\n\n if (\n authConfig.clientIdMetadataDocumentSupported\n && options.oauthClientMetadataUrl\n && shouldAttemptMode(preferred, 'cimd')\n ) {\n return createResolvedRegistration(\n authConfig,\n 'cimd',\n callbackUrl,\n options.oauthClientMetadataUrl,\n options.oauthClientMetadataUrl,\n );\n }\n\n if (authConfig.registrationEndpoint && shouldAttemptMode(preferred, 'dcr')) {\n return registerPublicClient(authConfig, {\n ...options,\n callbackUrl,\n });\n }\n\n return createResolvedRegistration(\n authConfig,\n preregClientId ? 'preregistered' : 'manual',\n callbackUrl,\n preregClientId,\n );\n}\n","import type { McpStackAgentConfig, McpStackStorageLike } from './types';\n\nexport type PersistedStateStorage = McpStackStorageLike & Pick<Storage, 'key' | 'length'>;\n\nconst LEGACY_OAUTH_TOKEN_STORAGE_PREFIX = 'mcpstack_oauth_';\nconst REGISTRATION_STORAGE_PREFIX = 'mcpstack_oauth_registration_';\nconst SCOPED_OAUTH_TOKEN_STORAGE_PREFIX = 'mcpstack_oauth_session_';\nconst OAUTH_CALLBACK_STORAGE_PREFIX = 'mcpstack-oauth-callback:';\n\nexport interface ClearPersistedMcpAuthStateOptions {\n /** Session scope to clear. Ignored when `clearAll` is true. */\n authSessionKey?: string | null;\n /** Clear all persisted MCP auth state, regardless of scope. */\n clearAll?: boolean;\n /** Test hook for injecting a storage implementation. */\n storage?: PersistedStateStorage | null;\n}\n\nfunction hashAuthSessionKey(value: string): string {\n let hash = 2166136261;\n\n for (let index = 0; index < value.length; index += 1) {\n hash ^= value.charCodeAt(index);\n hash = Math.imul(hash, 16777619);\n }\n\n return (hash >>> 0).toString(36);\n}\n\nexport function normalizeAuthSessionKey(value?: string | null): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n\n const normalized = value.trim();\n return normalized || null;\n}\n\nexport function resolveExplicitAuthSessionKey(\n config: Pick<McpStackAgentConfig, 'authSessionKey'>,\n): string | null {\n return normalizeAuthSessionKey(config.authSessionKey);\n}\n\nexport function buildScopedOAuthTokenStoragePrefix(authSessionKey?: string | null): string {\n const normalizedSessionKey = normalizeAuthSessionKey(authSessionKey);\n if (!normalizedSessionKey) {\n return LEGACY_OAUTH_TOKEN_STORAGE_PREFIX;\n }\n\n return `${SCOPED_OAUTH_TOKEN_STORAGE_PREFIX}${hashAuthSessionKey(normalizedSessionKey)}_`;\n}\n\nexport function buildScopedOAuthTokenStorageKey(\n cacheKey: string,\n authSessionKey?: string | null,\n): string {\n return `${buildScopedOAuthTokenStoragePrefix(authSessionKey)}${cacheKey}`;\n}\n\nfunction getStorage(storage?: PersistedStateStorage | null): PersistedStateStorage | null {\n if (storage) {\n return storage;\n }\n\n try {\n return typeof localStorage === 'undefined' ? null : localStorage;\n } catch {\n return null;\n }\n}\n\nexport function clearPersistedMcpAuthState(\n options: ClearPersistedMcpAuthStateOptions = {},\n): void {\n const storage = getStorage(options.storage);\n if (!storage) {\n return;\n }\n\n const scopedPrefix = buildScopedOAuthTokenStoragePrefix(\n options.authSessionKey,\n );\n const tokenPrefixes = options.clearAll\n ? [LEGACY_OAUTH_TOKEN_STORAGE_PREFIX, SCOPED_OAUTH_TOKEN_STORAGE_PREFIX]\n : [scopedPrefix];\n\n try {\n for (let index = storage.length - 1; index >= 0; index -= 1) {\n const key = storage.key(index);\n if (!key) {\n continue;\n }\n\n if (key.startsWith(OAUTH_CALLBACK_STORAGE_PREFIX)) {\n storage.removeItem(key);\n continue;\n }\n\n if (key.startsWith(REGISTRATION_STORAGE_PREFIX)) {\n continue;\n }\n\n if (tokenPrefixes.some((prefix) => key.startsWith(prefix))) {\n storage.removeItem(key);\n }\n }\n } catch {\n // Ignore storage failures during logout.\n }\n}\n\nexport function clearPersistedMcpAuth(): void {\n clearPersistedMcpAuthState({ clearAll: true });\n}\n","import { parseSseStream } from './sse-client';\nimport type {\n AgentConfigResponse,\n AgentBudgetSnapshot,\n AudioInputState,\n AudioTurnDetectionConfig,\n AuthorizationServerMetadata,\n ChatMessage,\n ConversationFeedback,\n ConversationMessagesPage,\n ClientToolsMap,\n ClientToolParameter,\n McpStackAgentEvent,\n McpStackAgentEventMap,\n McpStackAgentConfig,\n SseContentDelta,\n McpServerAuthConfig,\n McpStackAppTokenAuthConfig,\n OAuthTokenResponse,\n ProtectedResourceMetadata,\n SseError,\n SseMessageEnd,\n SseMessageStart,\n SseToolCall,\n SubmitConversationFeedbackRequest,\n} from './types';\nimport {\n applyResolvedRegistration,\n buildRegistrationCacheKey,\n buildTokenCacheKey,\n getEffectiveCallbackUrl,\n loadStoredRegistration,\n resolveOAuthRegistration,\n} from './auth/registration';\nimport {\n buildScopedOAuthTokenStorageKey,\n resolveExplicitAuthSessionKey,\n} from './auth-storage';\n\ntype EventHandler<T> = (data: T) => void;\ntype BuiltInPopupAuthHandler = {\n __mcpStackBuiltinPopupAuth?: boolean;\n};\n\ntype RealtimeTranscriptionSessionResponse = {\n sessionId: string;\n conversationId: string;\n webSocketUrl: string;\n expiresInSeconds: number;\n maxSessionSeconds: number;\n};\n\ntype ResolvedAudioTurnDetectionConfig = Required<AudioTurnDetectionConfig>;\n\ntype AudioFrameActivity = {\n rms: number;\n peak: number;\n inputLevel: number;\n durationMs: number;\n};\n\ntype AudioTurnState = {\n startedAtMs: number;\n lastFrameAtMs: number;\n speechStartedAtMs: number | null;\n lastSpeechAtMs: number | null;\n speechMs: number;\n silenceMs: number;\n noiseFloor: number;\n isSpeaking: boolean;\n autoCommitted: boolean;\n lastActivityEmitMs: number;\n};\n\nconst DEFAULT_MCP_PROTOCOL_VERSION = '2025-11-25';\nconst DEFAULT_LOCAL_PUBLIC_APP_PORT = '3100';\nconst DEFAULT_OAUTH_CALLBACK_URL = 'https://mcpstack.com/oauth/callback';\nconst DEFAULT_OAUTH_CLIENT_METADATA_URL = 'https://mcpstack.com/.well-known/oauth-client-metadata.json';\nconst DEFAULT_AUDIO_TURN_DETECTION: ResolvedAudioTurnDetectionConfig = {\n enabled: true,\n autoSubmit: true,\n silenceDurationMs: 850,\n minSpeechDurationMs: 180,\n noSpeechTimeoutMs: 12000,\n speechThreshold: 0.012,\n noiseMultiplier: 2.4,\n};\nconst AUDIO_ACTIVITY_EMIT_INTERVAL_MS = 120;\nconst MIN_AUDIO_LEVEL_DELTA_FOR_STATE = 0.03;\n\nfunction isLocalhostHost(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]';\n}\n\nfunction getDefaultOAuthHelperOrigin(agentServiceUrl?: string): string {\n if (!agentServiceUrl) {\n return DEFAULT_OAUTH_CALLBACK_URL.replace(/\\/oauth\\/callback$/, '');\n }\n\n try {\n const url = new URL(agentServiceUrl);\n if (isLocalhostHost(url.hostname)) {\n return `${url.protocol}//${url.hostname}:${DEFAULT_LOCAL_PUBLIC_APP_PORT}`;\n }\n } catch {\n // Fall back to the hosted public app origin.\n }\n\n return DEFAULT_OAUTH_CALLBACK_URL.replace(/\\/oauth\\/callback$/, '');\n}\n\nfunction getDefaultOAuthCallbackUrl(agentServiceUrl?: string): string {\n return `${getDefaultOAuthHelperOrigin(agentServiceUrl)}/oauth/callback`;\n}\n\nfunction getDefaultOAuthClientMetadataUrl(agentServiceUrl?: string): string {\n return `${getDefaultOAuthHelperOrigin(agentServiceUrl)}/.well-known/oauth-client-metadata.json`;\n}\n\nfunction buildEmbeddedExchangeUrl(mcpServerUrl: string): string {\n const url = new URL(mcpServerUrl);\n if (/\\/mcp\\/?$/i.test(url.pathname)) {\n url.pathname = url.pathname.replace(/\\/mcp\\/?$/i, '/embedded/exchange');\n } else {\n url.pathname = `${url.pathname.replace(/\\/$/, '')}/embedded/exchange`;\n }\n return url.toString();\n}\n\nfunction normalizeOAuthTokenResponse(\n payload: Record<string, unknown>,\n authConfig: McpServerAuthConfig,\n): OAuthTokenResponse | undefined {\n const accessToken = typeof payload.accessToken === 'string'\n ? payload.accessToken\n : typeof payload.access_token === 'string'\n ? payload.access_token\n : '';\n if (!accessToken) {\n return undefined;\n }\n\n return {\n accessToken,\n refreshToken: typeof payload.refreshToken === 'string'\n ? payload.refreshToken\n : typeof payload.refresh_token === 'string'\n ? payload.refresh_token\n : undefined,\n expiresIn: typeof payload.expiresIn === 'number'\n ? payload.expiresIn\n : typeof payload.expires_in === 'number'\n ? payload.expires_in\n : undefined,\n tokenType: typeof payload.tokenType === 'string'\n ? payload.tokenType\n : typeof payload.token_type === 'string'\n ? payload.token_type\n : 'Bearer',\n resolvedAuthConfig: authConfig,\n };\n}\n\nfunction createAppTokenAuthHandler(\n agentId: string,\n auth: McpStackAppTokenAuthConfig,\n): McpStackAgentConfig['onAuthRequired'] {\n return async (mcpServerUrl: string, authConfig: McpServerAuthConfig): Promise<OAuthTokenResponse | undefined> => {\n const appToken = await auth.getToken();\n const trimmedToken = appToken?.trim();\n if (!trimmedToken) {\n return undefined;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${trimmedToken}`,\n };\n if (auth.appId?.trim()) {\n headers['x-mcpstack-embedded-app-id'] = auth.appId.trim();\n }\n\n const body: Record<string, unknown> = {\n agentId,\n resource: authConfig.resource ?? mcpServerUrl,\n scopes: authConfig.scopes,\n };\n if (auth.appId?.trim()) {\n body.appId = auth.appId.trim();\n }\n\n const response = await fetch(buildEmbeddedExchangeUrl(mcpServerUrl), {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n const payload = await response.json().catch(() => null) as Record<string, unknown> | null;\n if (!response.ok) {\n const description = typeof payload?.error_description === 'string'\n ? payload.error_description\n : typeof payload?.error === 'string'\n ? payload.error\n : `App token exchange failed (${response.status}).`;\n throw new Error(description);\n }\n\n return normalizeOAuthTokenResponse(payload ?? {}, authConfig);\n };\n}\n\nfunction extractErrorMessage(payload: unknown): string | null {\n if (typeof payload === 'string') {\n const message = payload.trim();\n return message || null;\n }\n\n if (!payload || typeof payload !== 'object') {\n return null;\n }\n\n const record = payload as Record<string, unknown>;\n for (const key of ['error', 'message', 'detail']) {\n const value = record[key];\n if (typeof value === 'string' && value.trim()) {\n return value.trim();\n }\n }\n\n return null;\n}\n\nasync function getResponseErrorMessage(response: Response): Promise<string> {\n const fallback = `HTTP ${response.status}`;\n\n try {\n const payload = await response.clone().json();\n const message = extractErrorMessage(payload);\n if (message) {\n return message;\n }\n } catch {\n // Fall through to plain text below.\n }\n\n const text = await response.text().catch(() => '');\n return text.trim() || fallback;\n}\n\nfunction parameterToJsonSchema(parameter: ClientToolParameter): Record<string, unknown> {\n const schema: Record<string, unknown> = {\n type: parameter.type,\n };\n\n if (parameter.description) {\n schema.description = parameter.description;\n }\n\n if (parameter.enum) {\n schema.enum = parameter.enum;\n }\n\n if (parameter.type === 'array') {\n schema.items = parameter.items\n ? parameterToJsonSchema(parameter.items)\n : { type: 'string' };\n }\n\n if (parameter.type === 'object' && parameter.properties) {\n const properties: Record<string, object> = {};\n const required: string[] = [];\n\n for (const [key, child] of Object.entries(parameter.properties)) {\n properties[key] = parameterToJsonSchema(child);\n if (child.required) required.push(key);\n }\n\n schema.properties = properties;\n schema.required = required;\n }\n\n if (parameter.additionalProperties !== undefined) {\n schema.additionalProperties =\n typeof parameter.additionalProperties === 'boolean'\n ? parameter.additionalProperties\n : parameterToJsonSchema(parameter.additionalProperties);\n }\n\n return schema;\n}\n\n/** Convert client tool parameters to JSON Schema for the API */\nfunction parametersToJsonSchema(params: Record<string, ClientToolParameter>): object {\n const properties: Record<string, object> = {};\n const required: string[] = [];\n for (const [key, p] of Object.entries(params)) {\n properties[key] = parameterToJsonSchema(p);\n if (p.required) required.push(key);\n }\n return { type: 'object', properties, required };\n}\n\n/**\n * Core orchestration class for the MCP Stack Agent SDK.\n * Framework-agnostic — works in any JavaScript environment.\n *\n * Handles:\n * - Communication with the MCP Stack chat API (SSE streaming)\n * - Tool execution via MCP server (browser-side, with user's auth token)\n * - Conversation state management\n * - Event emission for UI updates\n */\nexport class McpStackAgent {\n private config: Required<\n Pick<McpStackAgentConfig, 'apiKey' | 'agentId' | 'agentServiceUrl'>\n > &\n McpStackAgentConfig;\n private agentConfig: AgentConfigResponse | null = null;\n private budgetSnapshot: AgentBudgetSnapshot | null = null;\n private conversationId: string | null = null;\n private messages: ChatMessage[] = [];\n private historyCursor: string | null = null;\n private hasOlderMessages = false;\n private isLoadingHistory = false;\n private abortController: AbortController | null = null;\n private isLoading = false;\n private listeners: Map<string, Set<EventHandler<unknown>>> = new Map();\n /** Per-server MCP session tracking */\n private mcpSessions: Map<string, {\n sessionId: string | null;\n authStatus: 'connected' | 'needs_auth';\n }> = new Map();\n /** OAuth tokens per MCP server URL (standalone mode only) */\n private oauthTokens: Map<string, {\n accessToken: string;\n refreshToken?: string;\n expiresAt: number;\n }> = new Map();\n /** Servers explicitly disconnected by the user and awaiting manual re-auth */\n private manuallySignedOutServers: Set<string> = new Set();\n private audioState: AudioInputState = {\n status: 'idle',\n isSupported: false,\n isEnabled: false,\n transcript: '',\n partialTranscript: '',\n error: null,\n };\n private audioStream: MediaStream | null = null;\n private audioContext: AudioContext | null = null;\n private audioSource: MediaStreamAudioSourceNode | null = null;\n private audioProcessor: ScriptProcessorNode | null = null;\n private audioSilentGain: GainNode | null = null;\n private audioSocket: WebSocket | null = null;\n private audioSessionTimer: ReturnType<typeof setTimeout> | null = null;\n private audioSessionStopRequested = false;\n private audioFinalTranscript = '';\n private audioTurnState: AudioTurnState | null = null;\n\n constructor(config: McpStackAgentConfig) {\n const appTokenAuthHandler = config.auth?.mode === 'app-token'\n ? createAppTokenAuthHandler(config.agentId, config.auth)\n : undefined;\n this.config = {\n ...config,\n agentServiceUrl: config.agentServiceUrl ?? 'https://api.mcpstack.com',\n oauthCallbackUrl: config.oauthCallbackUrl ?? getDefaultOAuthCallbackUrl(config.agentServiceUrl),\n oauthClientMetadataUrl:\n config.oauthClientMetadataUrl ?? getDefaultOAuthClientMetadataUrl(config.agentServiceUrl),\n onAuthRequired: config.onAuthRequired ?? appTokenAuthHandler,\n };\n this.audioState = this.buildAudioState({ status: 'idle' });\n }\n\n private async resolveAuthToken(): Promise<string> {\n if (this.config.getAuthToken) {\n const token = await this.config.getAuthToken();\n if (token) return token;\n }\n return this.config.apiKey;\n }\n\n /** Initialize: fetch agent config (tools, widget settings, MCP servers) */\n async init(): Promise<AgentConfigResponse> {\n const token = await this.resolveAuthToken();\n const response = await fetch(\n `${this.config.agentServiceUrl}/api/v1/agents/${this.config.agentId}/config`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n );\n\n if (!response.ok) {\n throw new Error(await getResponseErrorMessage(response));\n }\n\n this.agentConfig = await response.json();\n this.audioState = this.buildAudioState({ status: 'idle' });\n this.emit('audio_state', this.audioState);\n await this.refreshBudgetSnapshot().catch(() => undefined);\n\n if (this.agentConfig?.mcpServers?.length) {\n await Promise.all(\n this.agentConfig.mcpServers.map(async (server) => {\n server.authConfig = await this.resolveServerAuthConfig(server.url, server.authConfig ?? null);\n }),\n );\n }\n\n // Pre-initialize session tracking for each MCP server\n if (this.agentConfig?.mcpServers) {\n for (const server of this.agentConfig.mcpServers) {\n if (!this.mcpSessions.has(server.url)) {\n let authStatus: 'connected' | 'needs_auth';\n\n if (server.authConfig?.authType === 'oauth2') {\n authStatus = server.authStatus === 'connected' || this.hasValidOAuthToken(server.url)\n ? 'connected'\n : 'needs_auth';\n } else {\n authStatus = server.authStatus || 'connected';\n }\n\n this.mcpSessions.set(server.url, { sessionId: null, authStatus });\n }\n }\n }\n\n if (this.config.initialConversationId) {\n await this.loadConversation(this.config.initialConversationId);\n }\n\n return this.agentConfig!;\n }\n\n /** Get current MCP server auth statuses */\n getMcpServers(): Array<{\n url: string;\n name: string;\n authStatus: 'connected' | 'needs_auth';\n canSignOut: boolean;\n }> {\n if (!this.agentConfig?.mcpServers) return [];\n return this.agentConfig.mcpServers.map(server => ({\n url: server.url,\n name: server.name,\n authStatus: this.mcpSessions.get(server.url)?.authStatus ?? server.authStatus ?? 'connected',\n canSignOut: (server.authConfig?.authType ?? 'none') !== 'none',\n }));\n }\n\n /** Send a message and process the full orchestration loop (including tool calls) */\n async sendMessage(message: string): Promise<void> {\n if (!this.agentConfig) {\n await this.init();\n }\n\n this.isLoading = true;\n this.emit('loading', true);\n\n const userMsg: ChatMessage = {\n id: crypto.randomUUID(),\n role: 'user',\n content: message,\n timestamp: new Date(),\n };\n this.messages.push(userMsg);\n this.emit('message', userMsg);\n\n try {\n await this.runChatLoop(message);\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : 'Unknown error';\n this.emit('error', { code: 'sdk_error', message: errorMsg });\n } finally {\n this.isLoading = false;\n this.emit('loading', false);\n this.emit('thinking', false);\n }\n }\n\n /** Start a new conversation */\n newConversation(): void {\n this.conversationId = null;\n this.messages = [];\n this.historyCursor = null;\n this.hasOlderMessages = false;\n this.isLoadingHistory = false;\n }\n\n /** Cancel the current in-flight request */\n cancel(): void {\n this.abortController?.abort();\n this.abortController = null;\n }\n\n /** Get all messages in the current conversation */\n getMessages(): ChatMessage[] {\n return [...this.messages];\n }\n\n /** Get the current conversation ID */\n getConversationId(): string | null {\n return this.conversationId;\n }\n\n getHasOlderMessages(): boolean {\n return this.hasOlderMessages;\n }\n\n getIsLoadingHistory(): boolean {\n return this.isLoadingHistory;\n }\n\n /** Get the loaded agent config */\n getAgentConfig(): AgentConfigResponse | null {\n return this.agentConfig;\n }\n\n getAudioInputState(): AudioInputState {\n return { ...this.audioState };\n }\n\n async startVoiceInput(): Promise<void> {\n if (!this.agentConfig) {\n await this.init();\n }\n\n if (!this.isAudioInputSupported()) {\n this.setAudioState({\n status: 'error',\n error: {\n code: 'unsupported_browser',\n message: 'Microphone input is not supported in this browser.',\n },\n });\n return;\n }\n\n if (!this.isAudioInputEnabled()) {\n this.setAudioState({\n status: 'error',\n error: {\n code: 'audio_not_enabled',\n message: 'Microphone input is not enabled for this agent.',\n },\n });\n return;\n }\n\n if (\n this.audioState.status === 'requesting_permission'\n || this.audioState.status === 'connecting'\n || this.audioState.status === 'listening'\n || this.audioState.status === 'transcribing'\n ) {\n return;\n }\n\n this.audioSessionStopRequested = false;\n this.audioFinalTranscript = '';\n this.audioTurnState = null;\n this.setAudioState({\n status: 'requesting_permission',\n transcript: '',\n partialTranscript: '',\n error: null,\n sessionId: null,\n conversationId: this.conversationId,\n inputLevel: 0,\n isSpeaking: false,\n speechMs: 0,\n silenceMs: 0,\n autoSubmitEnabled: this.getAudioTurnDetectionConfig().enabled\n && this.getAudioTurnDetectionConfig().autoSubmit,\n });\n\n let stream: MediaStream | null = null;\n try {\n stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n channelCount: 1,\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n },\n });\n } catch (error) {\n this.setAudioState({\n status: 'error',\n error: {\n code: 'microphone_permission_denied',\n message: error instanceof Error ? error.message : 'Microphone permission was denied.',\n },\n });\n return;\n }\n\n try {\n this.audioStream = stream;\n this.setAudioState({ status: 'connecting' });\n\n const session = await this.createRealtimeTranscriptionSession();\n this.conversationId = session.conversationId;\n this.setAudioState({\n sessionId: session.sessionId,\n conversationId: session.conversationId,\n maxSessionSeconds: session.maxSessionSeconds,\n });\n\n const socket = await this.openAudioSocket(session.webSocketUrl);\n this.audioSocket = socket;\n this.bindAudioSocket(socket);\n await this.startAudioCapture(stream, socket);\n\n const maxSessionMs = Math.max(1, session.maxSessionSeconds) * 1000;\n this.audioSessionTimer = setTimeout(() => {\n void this.commitVoiceInput();\n }, maxSessionMs);\n\n this.setAudioState({ status: 'listening' });\n } catch (error) {\n this.cleanupAudioCapture();\n this.setAudioState({\n status: 'error',\n error: {\n code: this.extractErrorCode(error) ?? 'audio_start_failed',\n message: error instanceof Error ? error.message : 'Could not start microphone input.',\n },\n });\n }\n }\n\n async stopVoiceInput(): Promise<void> {\n await this.commitVoiceInput();\n }\n\n cancelVoiceInput(): void {\n this.audioSessionStopRequested = true;\n this.cleanupAudioCapture();\n this.audioTurnState = null;\n this.setAudioState({\n status: 'idle',\n transcript: '',\n partialTranscript: '',\n error: null,\n sessionId: null,\n inputLevel: 0,\n isSpeaking: false,\n speechMs: 0,\n silenceMs: 0,\n });\n }\n\n async loadConversation(\n conversationId: string,\n pageSize = this.config.conversationHistoryPageSize ?? 50,\n ): Promise<ConversationMessagesPage> {\n this.isLoadingHistory = true;\n try {\n const page = await this.fetchConversationMessages(conversationId, undefined, pageSize);\n this.applyConversationPage(page, false);\n return page;\n } finally {\n this.isLoadingHistory = false;\n }\n }\n\n async loadOlderMessages(\n pageSize = this.config.conversationHistoryPageSize ?? 50,\n ): Promise<ConversationMessagesPage | null> {\n if (!this.conversationId || !this.historyCursor || !this.hasOlderMessages) {\n return null;\n }\n\n this.isLoadingHistory = true;\n try {\n const page = await this.fetchConversationMessages(this.conversationId, this.historyCursor, pageSize);\n this.applyConversationPage(page, true);\n return page;\n } finally {\n this.isLoadingHistory = false;\n }\n }\n\n async submitFeedback(input: SubmitConversationFeedbackRequest): Promise<ConversationFeedback> {\n if (!this.conversationId) {\n throw new Error('No active conversation to rate.');\n }\n\n const token = await this.resolveAuthToken();\n const response = await fetch(\n `${this.config.agentServiceUrl}/api/v1/chat/conversations/${encodeURIComponent(this.conversationId)}/feedback`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(input),\n },\n );\n\n if (!response.ok) {\n throw new Error(await getResponseErrorMessage(response));\n }\n\n return (await response.json()) as ConversationFeedback;\n }\n\n /** Convert client tools to the API schema format. */\n private clientToolsToSchemas(): Array<{ name: string; description: string; inputSchema: object; selection?: unknown }> {\n if (!this.config.clientTools) return [];\n return Object.entries(this.config.clientTools).map(([name, def]) => ({\n name,\n description: def.description,\n inputSchema: parametersToJsonSchema(def.parameters) as object,\n selection: def.selection,\n }));\n }\n\n private resolveExternalUserId(): string | undefined {\n const hostIdentity = this.config.embeddedAuth?.hostIdentity;\n return this.config.externalUserId\n ?? hostIdentity?.subject\n ?? hostIdentity?.email\n ?? undefined;\n }\n\n private buildExternalUserContext(): Record<string, unknown> | undefined {\n const hostIdentity = this.config.embeddedAuth?.hostIdentity;\n const id = this.resolveExternalUserId();\n\n const externalUser: Record<string, unknown> = {};\n\n if (id) externalUser.id = id;\n if (hostIdentity?.email) externalUser.email = hostIdentity.email;\n if (hostIdentity?.displayName) externalUser.displayName = hostIdentity.displayName;\n if (hostIdentity?.avatarUrl) externalUser.avatarUrl = hostIdentity.avatarUrl;\n if (hostIdentity?.organizationId) externalUser.organizationId = hostIdentity.organizationId;\n\n return Object.keys(externalUser).length > 0 ? externalUser : undefined;\n }\n\n /** Latest runtime budget snapshot for the current SDK identity. */\n getBudgetSnapshot(): AgentBudgetSnapshot | null {\n return this.budgetSnapshot;\n }\n\n /** Refresh the current SDK identity's budget snapshot from the API. */\n async refreshBudgetSnapshot(): Promise<AgentBudgetSnapshot | null> {\n const token = await this.resolveAuthToken();\n const params = new URLSearchParams();\n const externalUserId = this.resolveExternalUserId();\n if (externalUserId) {\n params.set('externalUserId', externalUserId);\n }\n const query = params.toString();\n const response = await fetch(\n `${this.config.agentServiceUrl}/api/v1/agents/${this.config.agentId}/budget${query ? `?${query}` : ''}`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n );\n\n if (!response.ok) {\n throw new Error(await getResponseErrorMessage(response));\n }\n\n this.budgetSnapshot = await response.json() as AgentBudgetSnapshot;\n this.emit('budget_snapshot', this.budgetSnapshot);\n return this.budgetSnapshot;\n }\n\n /** Whether a request is currently in flight */\n getIsLoading(): boolean {\n return this.isLoading;\n }\n\n /** Update the per-turn app context sent with each chat request. */\n setAppContext(context: Record<string, unknown> | undefined): void {\n this.config = {\n ...this.config,\n context,\n };\n }\n\n /** Update the client tools exposed to the agent without recreating the session. */\n setClientTools(clientTools: ClientToolsMap | undefined): void {\n this.config = {\n ...this.config,\n clientTools,\n };\n }\n\n /**\n * Proactively authenticate with an MCP server before sending a message.\n * If a token response is provided directly, it is stored immediately.\n * Otherwise, this uses the configured OAuth flow and verifies via MCP init.\n *\n * @param mcpServerUrl - The MCP server URL to authenticate with\n * @param tokenResponse - Optional: provide token response directly (from OAuth popup)\n */\n async authenticate(\n mcpServerUrl: string,\n tokenResponse?: OAuthTokenResponse\n ): Promise<boolean> {\n const wasManuallySignedOut = this.manuallySignedOutServers.delete(mcpServerUrl);\n try {\n if (tokenResponse?.accessToken) {\n if (tokenResponse.resolvedAuthConfig) {\n this.updateServerAuthConfig(mcpServerUrl, tokenResponse.resolvedAuthConfig);\n }\n this.storeOAuthToken(mcpServerUrl, tokenResponse);\n this.updateMcpAuthStatus(mcpServerUrl, 'connected');\n return true;\n }\n\n const token = await this.resolveToken(mcpServerUrl);\n if (!token) {\n if (wasManuallySignedOut) {\n this.manuallySignedOutServers.add(mcpServerUrl);\n }\n return false;\n }\n\n // Reflect OAuth success in the UI immediately; MCP session init can follow asynchronously.\n this.updateMcpAuthStatus(mcpServerUrl, 'connected');\n\n try {\n await this.initMcpSession(mcpServerUrl);\n return true;\n } catch {\n // Keep the connected badge when we already have a valid OAuth token.\n return true;\n }\n } catch {\n if (wasManuallySignedOut) {\n this.manuallySignedOutServers.add(mcpServerUrl);\n }\n this.updateMcpAuthStatus(mcpServerUrl, 'needs_auth');\n return false;\n }\n }\n\n /** Disconnect from an MCP server and require explicit re-authentication before reuse. */\n async signOutMcpServer(mcpServerUrl: string): Promise<void> {\n this.manuallySignedOutServers.add(mcpServerUrl);\n await this.closeMcpSession(mcpServerUrl);\n this.clearOAuthToken(mcpServerUrl);\n this.updateMcpAuthStatus(mcpServerUrl, 'needs_auth');\n }\n\n /** Get the auth config for an MCP server (from agent config) */\n getServerAuthConfig(mcpServerUrl: string): McpServerAuthConfig | null {\n const server = this.agentConfig?.mcpServers?.find(s => s.url === mcpServerUrl);\n return server?.authConfig ?? null;\n }\n\n getOAuthCallbackUrl(): string {\n return this.config.oauthCallbackUrl ?? DEFAULT_OAUTH_CALLBACK_URL;\n }\n\n getOAuthClientMetadataUrl(): string {\n return this.config.oauthClientMetadataUrl ?? DEFAULT_OAUTH_CLIENT_METADATA_URL;\n }\n\n private getDefaultAuthRequiredHandler(): McpStackAgentConfig['onAuthRequired'] {\n return this.config.auth?.mode === 'app-token'\n ? createAppTokenAuthHandler(this.config.agentId, this.config.auth)\n : undefined;\n }\n\n setOnAuthRequired(\n onAuthRequired: McpStackAgentConfig['onAuthRequired'],\n ): void {\n this.config = {\n ...this.config,\n onAuthRequired: onAuthRequired ?? this.getDefaultAuthRequiredHandler(),\n };\n }\n\n private isAudioInputSupported(): boolean {\n const audioContextCtor = this.getAudioContextConstructor();\n return (\n typeof navigator !== 'undefined'\n && Boolean(navigator.mediaDevices?.getUserMedia)\n && typeof WebSocket !== 'undefined'\n && Boolean(audioContextCtor)\n && typeof crypto !== 'undefined'\n );\n }\n\n private isAudioInputEnabled(): boolean {\n const capabilities = this.agentConfig?.modelConfig?.capabilities;\n return Boolean(\n this.agentConfig?.audio?.inputEnabled\n && (capabilities?.audioInput ?? capabilities?.realtimeAudioInput),\n );\n }\n\n private isAudioAutoSubmitEnabled(): boolean {\n const turnDetection = this.getAudioTurnDetectionConfig();\n return turnDetection.enabled && turnDetection.autoSubmit;\n }\n\n private getAudioTurnDetectionConfig(): ResolvedAudioTurnDetectionConfig {\n const override = this.config.audioInput?.turnDetection ?? {};\n return {\n enabled: override.enabled ?? DEFAULT_AUDIO_TURN_DETECTION.enabled,\n autoSubmit: override.autoSubmit ?? DEFAULT_AUDIO_TURN_DETECTION.autoSubmit,\n silenceDurationMs: this.clampNumber(\n override.silenceDurationMs,\n 250,\n 3000,\n DEFAULT_AUDIO_TURN_DETECTION.silenceDurationMs,\n ),\n minSpeechDurationMs: this.clampNumber(\n override.minSpeechDurationMs,\n 80,\n 1000,\n DEFAULT_AUDIO_TURN_DETECTION.minSpeechDurationMs,\n ),\n noSpeechTimeoutMs: this.clampNumber(\n override.noSpeechTimeoutMs,\n 0,\n 60000,\n DEFAULT_AUDIO_TURN_DETECTION.noSpeechTimeoutMs,\n ),\n speechThreshold: this.clampNumber(\n override.speechThreshold,\n 0.002,\n 0.2,\n DEFAULT_AUDIO_TURN_DETECTION.speechThreshold,\n ),\n noiseMultiplier: this.clampNumber(\n override.noiseMultiplier,\n 1.2,\n 8,\n DEFAULT_AUDIO_TURN_DETECTION.noiseMultiplier,\n ),\n };\n }\n\n private clampNumber(\n value: number | undefined,\n min: number,\n max: number,\n fallback: number,\n ): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return fallback;\n }\n return Math.min(max, Math.max(min, value));\n }\n\n private buildAudioState(patch: Partial<AudioInputState>): AudioInputState {\n const hasPatch = (key: keyof AudioInputState) => Object.prototype.hasOwnProperty.call(patch, key);\n return {\n status: patch.status ?? this.audioState.status,\n isSupported: this.isAudioInputSupported(),\n isEnabled: this.isAudioInputEnabled(),\n transcript: patch.transcript ?? this.audioState.transcript,\n partialTranscript: patch.partialTranscript ?? this.audioState.partialTranscript,\n error: hasPatch('error') ? patch.error ?? null : this.audioState.error,\n sessionId: hasPatch('sessionId') ? patch.sessionId ?? null : this.audioState.sessionId ?? null,\n conversationId: hasPatch('conversationId')\n ? patch.conversationId ?? null\n : this.audioState.conversationId ?? this.conversationId,\n maxSessionSeconds:\n hasPatch('maxSessionSeconds')\n ? patch.maxSessionSeconds ?? null\n : this.audioState.maxSessionSeconds\n ?? this.agentConfig?.audio?.maxSessionSeconds\n ?? null,\n inputLevel: hasPatch('inputLevel') ? patch.inputLevel ?? 0 : this.audioState.inputLevel ?? 0,\n isSpeaking: hasPatch('isSpeaking') ? patch.isSpeaking ?? false : this.audioState.isSpeaking ?? false,\n speechMs: hasPatch('speechMs') ? patch.speechMs ?? 0 : this.audioState.speechMs ?? 0,\n silenceMs: hasPatch('silenceMs') ? patch.silenceMs ?? 0 : this.audioState.silenceMs ?? 0,\n autoSubmitEnabled: hasPatch('autoSubmitEnabled')\n ? patch.autoSubmitEnabled ?? false\n : this.audioState.autoSubmitEnabled ?? this.isAudioAutoSubmitEnabled(),\n };\n }\n\n private setAudioState(patch: Partial<AudioInputState>): void {\n this.audioState = this.buildAudioState(patch);\n this.emit('audio_state', this.audioState);\n }\n\n private getAudioContextConstructor(): typeof AudioContext | null {\n if (typeof window === 'undefined') {\n return null;\n }\n\n return window.AudioContext\n ?? (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext\n ?? null;\n }\n\n private async createRealtimeTranscriptionSession(): Promise<RealtimeTranscriptionSessionResponse> {\n const token = await this.resolveAuthToken();\n const externalUser = this.buildExternalUserContext();\n const response = await fetch(\n `${this.config.agentServiceUrl}/api/v1/agents/${encodeURIComponent(this.config.agentId)}/realtime/transcription-sessions`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({\n conversationId: this.conversationId,\n externalUserId: this.resolveExternalUserId(),\n externalUser,\n }),\n },\n );\n\n if (!response.ok) {\n throw await this.buildApiError(response);\n }\n\n return (await response.json()) as RealtimeTranscriptionSessionResponse;\n }\n\n private async buildApiError(response: Response): Promise<Error> {\n let code: string | null = null;\n let message: string | null = null;\n\n try {\n const payload = await response.clone().json();\n if (payload && typeof payload === 'object') {\n const record = payload as Record<string, unknown>;\n code = typeof record.code === 'string' ? record.code : null;\n message = extractErrorMessage(payload);\n }\n } catch {\n // Fall back below.\n }\n\n const error = new Error(message ?? await getResponseErrorMessage(response));\n if (code) {\n (error as Error & { code?: string }).code = code;\n }\n return error;\n }\n\n private async openAudioSocket(url: string): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const socket = new WebSocket(this.normalizeAudioSocketUrl(url));\n const cleanup = () => {\n socket.removeEventListener('open', handleOpen);\n socket.removeEventListener('error', handleError);\n };\n const handleOpen = () => {\n cleanup();\n resolve(socket);\n };\n const handleError = () => {\n cleanup();\n reject(new Error('Could not connect to the realtime microphone service.'));\n };\n\n socket.addEventListener('open', handleOpen);\n socket.addEventListener('error', handleError);\n });\n }\n\n private normalizeAudioSocketUrl(url: string): string {\n if (typeof window === 'undefined') {\n return url;\n }\n\n try {\n const parsed = new URL(url, window.location.href);\n if (window.location.protocol === 'https:' && parsed.protocol === 'ws:') {\n parsed.protocol = 'wss:';\n }\n\n return parsed.toString();\n } catch {\n return url;\n }\n }\n\n private bindAudioSocket(socket: WebSocket): void {\n socket.addEventListener('message', (event) => {\n void this.handleAudioSocketMessage(event);\n });\n\n socket.addEventListener('close', () => {\n if (this.audioSocket !== socket) {\n return;\n }\n\n this.audioSocket = null;\n this.clearAudioSessionTimer();\n if (\n this.audioState.status === 'listening'\n || this.audioState.status === 'transcribing'\n || this.audioState.status === 'connecting'\n ) {\n this.cleanupAudioCapture(false);\n this.audioTurnState = null;\n this.setAudioState({\n status: 'idle',\n inputLevel: 0,\n isSpeaking: false,\n speechMs: 0,\n silenceMs: 0,\n });\n }\n });\n\n socket.addEventListener('error', () => {\n if (this.audioSocket !== socket) {\n return;\n }\n\n this.cleanupAudioCapture();\n this.audioTurnState = null;\n this.setAudioState({\n status: 'error',\n error: {\n code: 'audio_socket_error',\n message: 'The realtime microphone connection failed.',\n },\n inputLevel: 0,\n isSpeaking: false,\n speechMs: 0,\n silenceMs: 0,\n });\n });\n }\n\n private async handleAudioSocketMessage(event: MessageEvent): Promise<void> {\n const raw = typeof event.data === 'string'\n ? event.data\n : event.data instanceof Blob\n ? await event.data.text()\n : '';\n if (!raw) {\n return;\n }\n\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return;\n }\n\n const type = typeof payload.type === 'string' ? payload.type : '';\n if (type === 'transcript_delta') {\n const text = typeof payload.text === 'string' ? payload.text : '';\n if (!text) {\n return;\n }\n\n this.audioFinalTranscript += text;\n this.setAudioState({\n partialTranscript: this.audioFinalTranscript,\n transcript: this.audioFinalTranscript,\n });\n this.emit('audio_transcript_delta', {\n text,\n transcript: this.audioFinalTranscript,\n isFinal: false,\n });\n return;\n }\n\n if (type === 'transcript_final') {\n const finalText = (\n typeof payload.text === 'string' && payload.text.trim()\n ? payload.text\n : this.audioFinalTranscript\n ).trim();\n\n this.cleanupAudioCapture();\n this.audioTurnState = null;\n if (!finalText) {\n this.setAudioState({\n status: 'idle',\n transcript: '',\n partialTranscript: '',\n inputLevel: 0,\n isSpeaking: false,\n speechMs: 0,\n silenceMs: 0,\n });\n return;\n }\n\n this.setAudioState({\n status: 'sending',\n transcript: finalText,\n partialTranscript: '',\n error: null,\n inputLevel: 0,\n isSpeaking: false,\n });\n this.emit('audio_transcript_final', {\n text: finalText,\n transcript: finalText,\n conversationId: this.conversationId ?? '',\n });\n await this.sendMessage(finalText);\n this.setAudioState({\n status: 'idle',\n transcript: finalText,\n partialTranscript: '',\n sessionId: null,\n inputLevel: 0,\n isSpeaking: false,\n speechMs: 0,\n silenceMs: 0,\n });\n return;\n }\n\n if (type === 'error') {\n const code = typeof payload.code === 'string' ? payload.code : 'audio_error';\n const message = typeof payload.message === 'string' ? payload.message : 'Microphone input failed.';\n this.cleanupAudioCapture();\n this.audioTurnState = null;\n this.setAudioState({\n status: 'error',\n error: { code, message },\n inputLevel: 0,\n isSpeaking: false,\n speechMs: 0,\n silenceMs: 0,\n });\n }\n }\n\n private async commitVoiceInput(): Promise<void> {\n if (\n this.audioSessionStopRequested\n || (\n this.audioState.status !== 'listening'\n && this.audioState.status !== 'connecting'\n )\n ) {\n return;\n }\n\n this.audioSessionStopRequested = true;\n this.cleanupAudioCapture(false);\n\n if (this.audioSocket?.readyState === WebSocket.OPEN) {\n this.audioSocket.send(JSON.stringify({ type: 'audio.commit' }));\n this.setAudioState({\n status: 'transcribing',\n inputLevel: 0,\n isSpeaking: false,\n silenceMs: this.audioTurnState?.silenceMs ?? this.audioState.silenceMs ?? 0,\n speechMs: this.audioTurnState?.speechMs ?? this.audioState.speechMs ?? 0,\n });\n return;\n }\n\n this.audioTurnState = null;\n this.setAudioState({\n status: 'idle',\n inputLevel: 0,\n isSpeaking: false,\n speechMs: 0,\n silenceMs: 0,\n });\n }\n\n private stopVoiceInputWithoutTranscript(message: string): void {\n this.audioSessionStopRequested = true;\n this.cleanupAudioCapture();\n this.audioTurnState = null;\n this.setAudioState({\n status: 'idle',\n transcript: '',\n partialTranscript: '',\n sessionId: null,\n inputLevel: 0,\n isSpeaking: false,\n speechMs: 0,\n silenceMs: 0,\n error: {\n code: 'no_speech_detected',\n message,\n },\n });\n }\n\n private createAudioTurnState(nowMs: number): AudioTurnState {\n return {\n startedAtMs: nowMs,\n lastFrameAtMs: nowMs,\n speechStartedAtMs: null,\n lastSpeechAtMs: null,\n speechMs: 0,\n silenceMs: 0,\n noiseFloor: DEFAULT_AUDIO_TURN_DETECTION.speechThreshold / 2,\n isSpeaking: false,\n autoCommitted: false,\n lastActivityEmitMs: 0,\n };\n }\n\n private analyzeAudioFrame(input: Float32Array, durationMs: number): AudioFrameActivity {\n if (input.length === 0) {\n return { rms: 0, peak: 0, inputLevel: 0, durationMs };\n }\n\n let sumSquares = 0;\n let peak = 0;\n for (let index = 0; index < input.length; index += 1) {\n const sample = input[index];\n const abs = Math.abs(sample);\n sumSquares += sample * sample;\n if (abs > peak) {\n peak = abs;\n }\n }\n\n const rms = Math.sqrt(sumSquares / input.length);\n return {\n rms,\n peak,\n inputLevel: Math.min(1, rms * 14),\n durationMs,\n };\n }\n\n private processAudioTurnActivity(activity: AudioFrameActivity, nowMs: number): void {\n const config = this.getAudioTurnDetectionConfig();\n if (!config.enabled) {\n this.emitAudioActivity(activity, nowMs, false, 0, 0, DEFAULT_AUDIO_TURN_DETECTION.speechThreshold / 2);\n return;\n }\n\n const state = this.audioTurnState ?? this.createAudioTurnState(nowMs);\n this.audioTurnState = state;\n\n const frameGapMs = Math.max(1, nowMs - state.lastFrameAtMs);\n const frameDurationMs = Math.max(activity.durationMs, frameGapMs);\n state.lastFrameAtMs = nowMs;\n\n const adaptiveThreshold = Math.max(\n config.speechThreshold,\n Math.min(0.08, state.noiseFloor * config.noiseMultiplier),\n );\n const peakThreshold = Math.max(adaptiveThreshold * 2.2, config.speechThreshold * 2.5);\n const speechCandidate = activity.rms >= adaptiveThreshold\n || (activity.rms >= adaptiveThreshold * 0.72 && activity.peak >= peakThreshold);\n\n if (speechCandidate) {\n if (state.speechStartedAtMs === null) {\n state.speechStartedAtMs = nowMs;\n state.speechMs = 0;\n }\n state.lastSpeechAtMs = nowMs;\n state.speechMs += frameDurationMs;\n state.silenceMs = 0;\n state.isSpeaking = true;\n } else {\n state.noiseFloor = this.updateNoiseFloor(state.noiseFloor, activity.rms);\n state.isSpeaking = false;\n if (state.lastSpeechAtMs !== null) {\n state.silenceMs = nowMs - state.lastSpeechAtMs;\n }\n }\n\n if (\n state.speechStartedAtMs !== null\n && state.speechMs < config.minSpeechDurationMs\n && state.silenceMs >= config.silenceDurationMs\n ) {\n state.speechStartedAtMs = null;\n state.lastSpeechAtMs = null;\n state.speechMs = 0;\n state.silenceMs = 0;\n }\n\n this.emitAudioActivity(\n activity,\n nowMs,\n state.isSpeaking,\n state.speechMs,\n state.silenceMs,\n state.noiseFloor,\n );\n\n const noSpeechElapsedMs = nowMs - state.startedAtMs;\n if (\n config.noSpeechTimeoutMs > 0\n && state.speechStartedAtMs === null\n && noSpeechElapsedMs >= config.noSpeechTimeoutMs\n && !state.autoCommitted\n ) {\n state.autoCommitted = true;\n this.stopVoiceInputWithoutTranscript('No speech was detected. Try again when you are ready to speak.');\n return;\n }\n\n if (\n config.autoSubmit\n && state.speechStartedAtMs !== null\n && state.speechMs >= config.minSpeechDurationMs\n && state.silenceMs >= config.silenceDurationMs\n && !state.autoCommitted\n ) {\n state.autoCommitted = true;\n void this.commitVoiceInput();\n }\n }\n\n private updateNoiseFloor(currentNoiseFloor: number, rms: number): number {\n const sample = Math.max(0.0015, Math.min(0.08, rms));\n const smoothing = sample > currentNoiseFloor ? 0.02 : 0.12;\n return currentNoiseFloor * (1 - smoothing) + sample * smoothing;\n }\n\n private emitAudioActivity(\n activity: AudioFrameActivity,\n nowMs: number,\n isSpeaking: boolean,\n speechMs: number,\n silenceMs: number,\n noiseFloor: number,\n ): void {\n const state = this.audioTurnState;\n const shouldEmitState = !state\n || nowMs - state.lastActivityEmitMs >= AUDIO_ACTIVITY_EMIT_INTERVAL_MS\n || isSpeaking !== this.audioState.isSpeaking\n || Math.abs(activity.inputLevel - (this.audioState.inputLevel ?? 0)) >= MIN_AUDIO_LEVEL_DELTA_FOR_STATE;\n\n if (!shouldEmitState) {\n return;\n }\n\n if (state) {\n state.lastActivityEmitMs = nowMs;\n }\n\n const roundedLevel = Number(activity.inputLevel.toFixed(3));\n const roundedNoiseFloor = Number(noiseFloor.toFixed(5));\n this.setAudioState({\n inputLevel: roundedLevel,\n isSpeaking,\n speechMs: Math.round(speechMs),\n silenceMs: Math.round(silenceMs),\n autoSubmitEnabled: this.isAudioAutoSubmitEnabled(),\n });\n this.emit('audio_activity', {\n inputLevel: roundedLevel,\n noiseFloor: roundedNoiseFloor,\n isSpeaking,\n speechMs: Math.round(speechMs),\n silenceMs: Math.round(silenceMs),\n });\n }\n\n private async startAudioCapture(stream: MediaStream, socket: WebSocket): Promise<void> {\n const AudioContextCtor = this.getAudioContextConstructor();\n if (!AudioContextCtor) {\n throw new Error('Audio capture is not available in this browser.');\n }\n\n const context = new AudioContextCtor();\n if (context.state === 'suspended') {\n await context.resume();\n }\n\n const source = context.createMediaStreamSource(stream);\n const processor = context.createScriptProcessor(4096, 1, 1);\n const silentGain = context.createGain();\n silentGain.gain.value = 0;\n this.audioTurnState = this.createAudioTurnState(performance.now());\n\n processor.onaudioprocess = (event) => {\n if (\n this.audioSessionStopRequested\n || socket.readyState !== WebSocket.OPEN\n || this.audioState.status !== 'listening'\n ) {\n return;\n }\n\n const input = event.inputBuffer.getChannelData(0);\n const durationMs = (input.length / context.sampleRate) * 1000;\n this.processAudioTurnActivity(\n this.analyzeAudioFrame(input, durationMs),\n performance.now(),\n );\n\n if (this.audioSessionStopRequested) {\n return;\n }\n\n const resampled = this.resampleToPcm16(input, context.sampleRate, 24000);\n if (resampled.length === 0) {\n return;\n }\n\n socket.send(JSON.stringify({\n type: 'audio.append',\n audio: this.pcm16ToBase64(resampled),\n }));\n };\n\n source.connect(processor);\n processor.connect(silentGain);\n silentGain.connect(context.destination);\n\n this.audioContext = context;\n this.audioSource = source;\n this.audioProcessor = processor;\n this.audioSilentGain = silentGain;\n }\n\n private resampleToPcm16(input: Float32Array, inputSampleRate: number, outputSampleRate: number): Int16Array {\n if (inputSampleRate === outputSampleRate) {\n return this.floatToPcm16(input);\n }\n\n const ratio = inputSampleRate / outputSampleRate;\n const outputLength = Math.floor(input.length / ratio);\n const output = new Float32Array(outputLength);\n\n for (let index = 0; index < outputLength; index += 1) {\n const inputIndex = index * ratio;\n const lower = Math.floor(inputIndex);\n const upper = Math.min(lower + 1, input.length - 1);\n const weight = inputIndex - lower;\n output[index] = input[lower] * (1 - weight) + input[upper] * weight;\n }\n\n return this.floatToPcm16(output);\n }\n\n private floatToPcm16(input: Float32Array): Int16Array {\n const output = new Int16Array(input.length);\n for (let index = 0; index < input.length; index += 1) {\n const sample = Math.max(-1, Math.min(1, input[index]));\n output[index] = sample < 0 ? sample * 0x8000 : sample * 0x7fff;\n }\n return output;\n }\n\n private pcm16ToBase64(input: Int16Array): string {\n const bytes = new Uint8Array(input.buffer, input.byteOffset, input.byteLength);\n let binary = '';\n const chunkSize = 0x8000;\n for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n const chunk = bytes.subarray(offset, offset + chunkSize);\n binary += String.fromCharCode(...chunk);\n }\n return btoa(binary);\n }\n\n private cleanupAudioCapture(closeSocket = true): void {\n this.clearAudioSessionTimer();\n this.audioProcessor?.disconnect();\n this.audioSource?.disconnect();\n this.audioSilentGain?.disconnect();\n this.audioProcessor = null;\n this.audioSource = null;\n this.audioSilentGain = null;\n\n if (this.audioContext) {\n void this.audioContext.close().catch(() => undefined);\n this.audioContext = null;\n }\n\n this.audioStream?.getTracks().forEach((track) => track.stop());\n this.audioStream = null;\n\n if (closeSocket && this.audioSocket) {\n const socket = this.audioSocket;\n this.audioSocket = null;\n if (socket.readyState === WebSocket.OPEN) {\n socket.send(JSON.stringify({ type: 'audio.close' }));\n socket.close();\n } else if (socket.readyState === WebSocket.CONNECTING) {\n socket.close();\n }\n }\n }\n\n private clearAudioSessionTimer(): void {\n if (!this.audioSessionTimer) {\n return;\n }\n\n clearTimeout(this.audioSessionTimer);\n this.audioSessionTimer = null;\n }\n\n private extractErrorCode(error: unknown): string | null {\n if (error && typeof error === 'object' && 'code' in error) {\n const code = (error as { code?: unknown }).code;\n return typeof code === 'string' ? code : null;\n }\n return null;\n }\n\n private getPersistentStorage() {\n return this.config.storage ?? null;\n }\n\n private async resolveOAuthClientRegistration(\n authConfig: McpServerAuthConfig | null | undefined,\n ): Promise<McpServerAuthConfig | null> {\n if (!authConfig || authConfig.authType !== 'oauth2') {\n return authConfig ?? null;\n }\n\n const registration = await resolveOAuthRegistration(authConfig, {\n callbackUrl: this.getOAuthCallbackUrl(),\n oauthClientMetadataUrl: this.config.oauthClientMetadataUrl,\n clientName: 'MCP Stack MCP Client',\n clientUri: 'https://mcpstack.com',\n storage: this.getPersistentStorage(),\n });\n\n return applyResolvedRegistration(authConfig, registration);\n }\n\n /** Subscribe to events */\n on<K extends McpStackAgentEvent>(event: K, handler: EventHandler<McpStackAgentEventMap[K]>): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(handler as EventHandler<unknown>);\n }\n\n /** Unsubscribe from events */\n off<K extends McpStackAgentEvent>(event: K, handler: EventHandler<McpStackAgentEventMap[K]>): void {\n this.listeners.get(event)?.delete(handler as EventHandler<unknown>);\n }\n\n // ================================================================\n // Private methods\n // ================================================================\n\n private buildProtectedResourceMetadataCandidates(mcpServerUrl: string): string[] {\n const url = new URL(mcpServerUrl);\n const candidates = new Set<string>();\n const normalizedPath = url.pathname.endsWith('/') ? url.pathname.slice(0, -1) : url.pathname;\n\n if (!normalizedPath || normalizedPath === '/') {\n candidates.add(`${url.origin}/.well-known/oauth-protected-resource`);\n return [...candidates];\n }\n\n candidates.add(`${url.origin}/.well-known/oauth-protected-resource${normalizedPath}`);\n candidates.add(`${url.origin}${normalizedPath}/.well-known/oauth-protected-resource`);\n candidates.add(`${url.origin}/.well-known/oauth-protected-resource`);\n return [...candidates];\n }\n\n private hasSameOrigin(left: string, right: string): boolean {\n try {\n const leftUrl = new URL(left);\n const rightUrl = new URL(right);\n return leftUrl.origin === rightUrl.origin;\n } catch {\n return false;\n }\n }\n\n private extractQuotedHeaderValue(header: string, key: string): string | null {\n const match = header.match(new RegExp(`${key}=\"([^\"]+)\"`, 'i'));\n return match?.[1] ?? null;\n }\n\n private buildAuthorizationServerMetadataCandidates(issuerOrMetadataUrl: string): string[] {\n const candidates = new Set<string>();\n\n if (\n issuerOrMetadataUrl.includes('/.well-known/oauth-authorization-server')\n || issuerOrMetadataUrl.includes('/.well-known/openid-configuration')\n ) {\n candidates.add(issuerOrMetadataUrl);\n return [...candidates];\n }\n\n const url = new URL(issuerOrMetadataUrl);\n const normalizedPath = url.pathname.endsWith('/') ? url.pathname.slice(0, -1) : url.pathname;\n if (!normalizedPath || normalizedPath === '/') {\n candidates.add(`${url.origin}/.well-known/oauth-authorization-server`);\n candidates.add(`${url.origin}/.well-known/openid-configuration`);\n return [...candidates];\n }\n\n candidates.add(`${url.origin}/.well-known/oauth-authorization-server${normalizedPath}`);\n candidates.add(`${url.origin}/.well-known/openid-configuration${normalizedPath}`);\n candidates.add(`${url.origin}${normalizedPath}/.well-known/openid-configuration`);\n return [...candidates];\n }\n\n private hasExplicitManualOverride(\n manualConfig: McpServerAuthConfig | null | undefined,\n field: string,\n ): boolean {\n return manualConfig?.manualOverrides?.includes(field) ?? false;\n }\n\n private pickAuthConfigValue<T>(\n field: string,\n manualConfig: McpServerAuthConfig | null | undefined,\n manualValue: T | undefined,\n discoveredValue: T | undefined,\n ): T | undefined {\n if (this.hasExplicitManualOverride(manualConfig, field) && manualValue != null) {\n return manualValue;\n }\n\n return discoveredValue ?? manualValue;\n }\n\n private pickAuthConfigArrayValue<T>(\n field: string,\n manualConfig: McpServerAuthConfig | null | undefined,\n manualValue: T[] | undefined,\n discoveredValue: T[] | undefined,\n ): T[] | undefined {\n if (this.hasExplicitManualOverride(manualConfig, field) && manualValue?.length) {\n return manualValue;\n }\n\n if (discoveredValue?.length) {\n return discoveredValue;\n }\n\n return manualValue?.length ? manualValue : undefined;\n }\n\n private mergeAuthConfigs(\n manualConfig: McpServerAuthConfig | null | undefined,\n discoveredConfig: McpServerAuthConfig | null | undefined,\n ): McpServerAuthConfig | null {\n if (!manualConfig && !discoveredConfig) return null;\n\n const manualOverrides = new Set<string>(manualConfig?.manualOverrides ?? []);\n const authorizationEndpoint = this.pickAuthConfigValue(\n 'authorizationEndpoint',\n manualConfig,\n manualConfig?.authorizationEndpoint ?? manualConfig?.loginUrl,\n discoveredConfig?.authorizationEndpoint ?? discoveredConfig?.loginUrl,\n );\n const tokenEndpoint = this.pickAuthConfigValue(\n 'tokenEndpoint',\n manualConfig,\n manualConfig?.tokenEndpoint ?? manualConfig?.tokenUrl,\n discoveredConfig?.tokenEndpoint ?? discoveredConfig?.tokenUrl,\n );\n const callbackUrl = this.pickAuthConfigValue(\n 'callbackUrl',\n manualConfig,\n manualConfig?.callbackUrl,\n discoveredConfig?.callbackUrl,\n ) ?? this.getOAuthCallbackUrl();\n\n const merged: McpServerAuthConfig = {\n authType: manualConfig?.authType ?? discoveredConfig?.authType ?? 'oauth2',\n issuer: discoveredConfig?.issuer ?? manualConfig?.issuer,\n authorizationServerUrl: this.pickAuthConfigValue(\n 'authorizationServerUrl',\n manualConfig,\n manualConfig?.authorizationServerUrl,\n discoveredConfig?.authorizationServerUrl,\n ),\n authorizationServerMetadataUrl:\n this.pickAuthConfigValue(\n 'authorizationServerMetadataUrl',\n manualConfig,\n manualConfig?.authorizationServerMetadataUrl,\n discoveredConfig?.authorizationServerMetadataUrl,\n ),\n authorizationEndpoint,\n loginUrl: authorizationEndpoint,\n tokenEndpoint,\n tokenUrl: tokenEndpoint,\n registrationEndpoint: this.pickAuthConfigValue(\n 'registrationEndpoint',\n manualConfig,\n manualConfig?.registrationEndpoint,\n discoveredConfig?.registrationEndpoint,\n ),\n clientId: this.pickAuthConfigValue(\n 'clientId',\n manualConfig,\n manualConfig?.clientId,\n discoveredConfig?.clientId,\n ),\n scopes: this.pickAuthConfigArrayValue(\n 'scopes',\n manualConfig,\n manualConfig?.scopes,\n discoveredConfig?.scopes,\n ),\n resource: this.pickAuthConfigValue(\n 'resource',\n manualConfig,\n manualConfig?.resource,\n discoveredConfig?.resource,\n ),\n callbackUrl,\n protectedResourceMetadataUrl:\n discoveredConfig?.protectedResourceMetadataUrl ?? manualConfig?.protectedResourceMetadataUrl,\n clientIdMetadataDocumentSupported:\n discoveredConfig?.clientIdMetadataDocumentSupported\n ?? manualConfig?.clientIdMetadataDocumentSupported,\n resourceParameterSupported:\n discoveredConfig?.resourceParameterSupported\n ?? manualConfig?.resourceParameterSupported,\n registrationPreference:\n manualConfig?.registrationPreference\n ?? discoveredConfig?.registrationPreference\n ?? 'auto',\n clientMode: discoveredConfig?.clientMode ?? manualConfig?.clientMode,\n authRecipe: manualConfig?.authRecipe ?? discoveredConfig?.authRecipe,\n manualOverrides: manualOverrides.size ? [...manualOverrides] : undefined,\n discovered: discoveredConfig?.discovered ?? false,\n };\n\n return merged;\n }\n\n private async discoverAuthConfig(\n mcpServerUrl: string,\n manualConfig: McpServerAuthConfig | null | undefined,\n ): Promise<McpServerAuthConfig | null> {\n let protectedResourceUrl: string | null = null;\n let protectedResource: ProtectedResourceMetadata | null = null;\n const protectedResourceCandidates = new Set<string>();\n\n if (manualConfig?.protectedResourceMetadataUrl) {\n protectedResourceCandidates.add(manualConfig.protectedResourceMetadataUrl);\n }\n\n for (const candidate of this.buildProtectedResourceMetadataCandidates(mcpServerUrl)) {\n protectedResourceCandidates.add(candidate);\n }\n\n for (const candidate of protectedResourceCandidates) {\n try {\n const response = await fetch(candidate, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n });\n\n if (response.ok) {\n protectedResource = await response.json();\n protectedResourceUrl = candidate;\n break;\n }\n\n const authenticateHeader = response.headers.get('www-authenticate');\n if (authenticateHeader) {\n const resourceMetadataUrl = this.extractQuotedHeaderValue(authenticateHeader, 'resource_metadata');\n if (resourceMetadataUrl && this.hasSameOrigin(candidate, resourceMetadataUrl)) {\n const metadataResponse = await fetch(resourceMetadataUrl, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n });\n if (metadataResponse.ok) {\n protectedResource = await metadataResponse.json();\n protectedResourceUrl = resourceMetadataUrl;\n break;\n }\n }\n }\n } catch {\n // Try the next candidate.\n }\n }\n\n const authServerUrl =\n protectedResource?.authorization_servers?.[0] ??\n protectedResource?.authorization_server ??\n manualConfig?.authorizationServerUrl;\n\n try {\n let metadata: AuthorizationServerMetadata | null = null;\n let metadataUrl: string | null = manualConfig?.authorizationServerMetadataUrl ?? null;\n\n const metadataCandidates = new Set<string>();\n if (manualConfig?.authorizationServerMetadataUrl) {\n metadataCandidates.add(manualConfig.authorizationServerMetadataUrl);\n }\n if (authServerUrl) {\n for (const candidate of this.buildAuthorizationServerMetadataCandidates(authServerUrl)) {\n metadataCandidates.add(candidate);\n }\n }\n\n for (const candidate of metadataCandidates) {\n try {\n const response = await fetch(candidate, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n });\n if (response.ok) {\n metadata = (await response.json()) as AuthorizationServerMetadata;\n metadataUrl = candidate;\n break;\n }\n } catch {\n // Try the next metadata candidate.\n }\n }\n\n if (!metadata && !protectedResource && !manualConfig) {\n return null;\n }\n return {\n authType: 'oauth2',\n issuer: metadata?.issuer ?? authServerUrl ?? manualConfig?.issuer,\n authorizationServerUrl: authServerUrl ?? manualConfig?.authorizationServerUrl,\n authorizationServerMetadataUrl: metadataUrl ?? undefined,\n authorizationEndpoint:\n metadata?.authorization_endpoint\n ?? manualConfig?.authorizationEndpoint\n ?? manualConfig?.loginUrl,\n loginUrl:\n metadata?.authorization_endpoint\n ?? manualConfig?.loginUrl\n ?? manualConfig?.authorizationEndpoint,\n tokenEndpoint:\n metadata?.token_endpoint\n ?? manualConfig?.tokenEndpoint\n ?? manualConfig?.tokenUrl,\n tokenUrl:\n metadata?.token_endpoint\n ?? manualConfig?.tokenUrl\n ?? manualConfig?.tokenEndpoint,\n registrationEndpoint:\n metadata?.registration_endpoint ?? manualConfig?.registrationEndpoint,\n clientId: manualConfig?.clientId,\n scopes: protectedResource?.scopes_supported?.length\n ? protectedResource.scopes_supported\n : metadata?.scopes_supported ?? manualConfig?.scopes,\n resource: protectedResource?.resource ?? manualConfig?.resource,\n callbackUrl: getEffectiveCallbackUrl(manualConfig, this.getOAuthCallbackUrl()),\n protectedResourceMetadataUrl:\n protectedResourceUrl ?? manualConfig?.protectedResourceMetadataUrl,\n clientIdMetadataDocumentSupported:\n metadata?.client_id_metadata_document_supported\n ?? manualConfig?.clientIdMetadataDocumentSupported,\n resourceParameterSupported:\n metadata?.resource_parameter_supported\n ?? manualConfig?.resourceParameterSupported,\n registrationPreference: manualConfig?.registrationPreference ?? 'auto',\n authRecipe: manualConfig?.authRecipe,\n discovered: Boolean(protectedResource || metadata),\n };\n } catch {\n return manualConfig\n ? {\n ...manualConfig,\n callbackUrl: getEffectiveCallbackUrl(manualConfig, this.getOAuthCallbackUrl()),\n protectedResourceMetadataUrl:\n protectedResourceUrl ?? manualConfig.protectedResourceMetadataUrl,\n resource: protectedResource?.resource ?? manualConfig.resource,\n scopes: protectedResource?.scopes_supported?.length\n ? protectedResource.scopes_supported\n : manualConfig.scopes,\n discovered: Boolean(protectedResource),\n }\n : null;\n }\n }\n\n private async resolveServerAuthConfig(\n mcpServerUrl: string,\n manualConfig: McpServerAuthConfig | null | undefined,\n ): Promise<McpServerAuthConfig | null> {\n const discoveredConfig = await this.discoverAuthConfig(mcpServerUrl, manualConfig);\n return this.mergeAuthConfigs(manualConfig, discoveredConfig);\n }\n\n private async ensureServerAuthConfig(mcpServerUrl: string): Promise<McpServerAuthConfig | null> {\n const server = this.agentConfig?.mcpServers?.find((item) => item.url === mcpServerUrl);\n if (!server) {\n return null;\n }\n\n if (\n server.authConfig\n && (\n server.authConfig.authType !== 'oauth2'\n || server.authConfig.discovered\n || !!server.authConfig.authorizationEndpoint\n || !!server.authConfig.tokenEndpoint\n || !!server.authConfig.tokenUrl\n || !!server.authConfig.registrationEndpoint\n || !!server.authConfig.resource\n )\n ) {\n return server.authConfig;\n }\n\n server.authConfig = await this.resolveServerAuthConfig(mcpServerUrl, server.authConfig ?? null);\n return server.authConfig;\n }\n\n private updateServerAuthConfig(mcpServerUrl: string, authConfig: McpServerAuthConfig): void {\n const server = this.agentConfig?.mcpServers?.find((item) => item.url === mcpServerUrl);\n if (server) {\n server.authConfig = authConfig;\n }\n }\n\n private emit<K extends McpStackAgentEvent>(event: K, data: McpStackAgentEventMap[K]): void {\n this.listeners.get(event)?.forEach((handler) => handler(data));\n }\n\n // ================================================================\n // OAuth Token Storage (standalone mode only)\n // ================================================================\n\n /** Generate the legacy token cache suffix used before auth-aware keying. */\n private hashUrl(url: string): string {\n return btoa(url).replace(/[^a-zA-Z0-9]/g, '').slice(0, 32);\n }\n\n private getLegacyTokenStorageKey(mcpServerUrl: string): string {\n return buildScopedOAuthTokenStorageKey(this.hashUrl(mcpServerUrl));\n }\n\n private getAuthSessionKey(): string | null {\n return resolveExplicitAuthSessionKey(this.config);\n }\n\n private getTokenStorageKey(\n mcpServerUrl: string,\n authConfig: McpServerAuthConfig | null | undefined,\n ): string {\n return buildScopedOAuthTokenStorageKey(\n buildTokenCacheKey(authConfig, mcpServerUrl),\n this.getAuthSessionKey(),\n );\n }\n\n private getTokenStorageCandidates(\n mcpServerUrl: string,\n ): Array<{ storageKey: string; authConfig: McpServerAuthConfig | null }> {\n const currentAuthConfig = this.getServerAuthConfig(mcpServerUrl);\n const hasExplicitAuthSessionKey = this.getAuthSessionKey() !== null;\n if (!currentAuthConfig) {\n return hasExplicitAuthSessionKey\n ? [{\n storageKey: this.getTokenStorageKey(mcpServerUrl, null),\n authConfig: null,\n }]\n : [{\n storageKey: this.getLegacyTokenStorageKey(mcpServerUrl),\n authConfig: null,\n }];\n }\n\n const callbackUrl = getEffectiveCallbackUrl(currentAuthConfig, this.getOAuthCallbackUrl());\n const candidates: McpServerAuthConfig[] = [currentAuthConfig];\n\n if (currentAuthConfig.authType === 'oauth2') {\n candidates.push({\n ...currentAuthConfig,\n clientMode: 'manual',\n callbackUrl,\n });\n\n if (currentAuthConfig.clientId) {\n candidates.push({\n ...currentAuthConfig,\n clientMode: 'preregistered',\n callbackUrl,\n });\n }\n\n if (\n currentAuthConfig.clientIdMetadataDocumentSupported\n && this.config.oauthClientMetadataUrl\n ) {\n candidates.push({\n ...currentAuthConfig,\n clientId: this.config.oauthClientMetadataUrl,\n clientMode: 'cimd',\n callbackUrl,\n });\n }\n\n if (currentAuthConfig.registrationEndpoint) {\n const cacheKey = buildRegistrationCacheKey(currentAuthConfig, callbackUrl, 'dcr');\n const storedRegistration = loadStoredRegistration(cacheKey, this.getPersistentStorage());\n if (storedRegistration?.clientId) {\n candidates.push(applyResolvedRegistration(currentAuthConfig, {\n cacheKey,\n mode: 'dcr',\n clientId: storedRegistration.clientId,\n callbackUrl,\n resource: currentAuthConfig.resource,\n authorizationServerUrl: currentAuthConfig.authorizationServerUrl,\n authorizationServerMetadataUrl: currentAuthConfig.authorizationServerMetadataUrl,\n registrationEndpoint: currentAuthConfig.registrationEndpoint,\n }));\n }\n }\n }\n\n const seen = new Set<string>();\n const resolved = candidates.map((candidate) => ({\n storageKey: this.getTokenStorageKey(mcpServerUrl, candidate),\n authConfig: candidate,\n })).filter((candidate) => {\n if (seen.has(candidate.storageKey)) return false;\n seen.add(candidate.storageKey);\n return true;\n });\n\n if (!hasExplicitAuthSessionKey) {\n resolved.push({\n storageKey: this.getLegacyTokenStorageKey(mcpServerUrl),\n authConfig: currentAuthConfig,\n });\n }\n\n return resolved;\n }\n\n /** Load OAuth token from memory/persistent storage using auth-aware cache keying. */\n private loadOAuthToken(mcpServerUrl: string): {\n accessToken: string;\n refreshToken?: string;\n expiresAt: number;\n } | null {\n for (const candidate of this.getTokenStorageCandidates(mcpServerUrl)) {\n const cached = this.oauthTokens.get(candidate.storageKey);\n if (cached) {\n if (candidate.authConfig) {\n this.updateServerAuthConfig(mcpServerUrl, candidate.authConfig);\n }\n return cached;\n }\n }\n\n try {\n const storage = this.getPersistentStorage() ?? (typeof localStorage !== 'undefined' ? localStorage : null);\n if (storage) {\n for (const candidate of this.getTokenStorageCandidates(mcpServerUrl)) {\n const stored = storage.getItem(candidate.storageKey);\n if (stored) {\n const data = JSON.parse(stored);\n if (data.accessToken && data.expiresAt) {\n this.oauthTokens.set(candidate.storageKey, data);\n if (candidate.authConfig) {\n this.updateServerAuthConfig(mcpServerUrl, candidate.authConfig);\n }\n return data;\n }\n }\n }\n }\n } catch { /* ignore */ }\n\n return null;\n }\n\n /** Check if we have a valid (non-expired) OAuth token */\n private hasValidOAuthToken(mcpServerUrl: string): boolean {\n const token = this.loadOAuthToken(mcpServerUrl);\n if (!token) return false;\n // Valid if not expired OR we have a refresh token\n return token.expiresAt > Date.now() || !!token.refreshToken;\n }\n\n /** Store OAuth token to memory and persistent storage */\n private storeOAuthToken(mcpServerUrl: string, tokenResponse: OAuthTokenResponse): void {\n const resolvedAuthConfig =\n tokenResponse.resolvedAuthConfig ?? this.getServerAuthConfig(mcpServerUrl);\n const storageKey = this.getTokenStorageKey(mcpServerUrl, resolvedAuthConfig);\n const expiresIn = tokenResponse.expiresIn ?? 3600;\n const expiresAt = Date.now() + (expiresIn * 1000) - (60 * 1000); // 1 min buffer\n const data = {\n accessToken: tokenResponse.accessToken,\n refreshToken: tokenResponse.refreshToken,\n expiresAt,\n };\n this.oauthTokens.set(storageKey, data);\n\n try {\n const storage = this.getPersistentStorage() ?? (typeof localStorage !== 'undefined' ? localStorage : null);\n if (storage) {\n storage.setItem(storageKey, JSON.stringify(data));\n }\n } catch { /* ignore */ }\n }\n\n /** Clear OAuth token from memory and persistent storage */\n private clearOAuthToken(mcpServerUrl: string): void {\n for (const candidate of this.getTokenStorageCandidates(mcpServerUrl)) {\n this.oauthTokens.delete(candidate.storageKey);\n }\n\n try {\n const storage = this.getPersistentStorage() ?? (typeof localStorage !== 'undefined' ? localStorage : null);\n if (storage) {\n for (const candidate of this.getTokenStorageCandidates(mcpServerUrl)) {\n storage.removeItem(candidate.storageKey);\n }\n }\n } catch { /* ignore */ }\n }\n\n /** Refresh OAuth token using refresh token */\n private async refreshOAuthToken(mcpServerUrl: string, refreshToken: string): Promise<string | undefined> {\n const authConfig = await this.ensureServerAuthConfig(mcpServerUrl);\n const tokenUrl = authConfig?.tokenEndpoint ?? authConfig?.tokenUrl;\n if (!tokenUrl) return undefined;\n\n try {\n const body = new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n });\n if (authConfig?.clientId) body.set('client_id', authConfig.clientId);\n if (authConfig?.resource) body.set('resource', authConfig.resource);\n\n const response = await fetch(tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body,\n });\n\n if (response.ok) {\n const data = await response.json();\n if (data.access_token) {\n const tokenResponse: OAuthTokenResponse = {\n accessToken: data.access_token,\n refreshToken: data.refresh_token ?? refreshToken,\n expiresIn: data.expires_in,\n resolvedAuthConfig: authConfig ?? undefined,\n };\n this.storeOAuthToken(mcpServerUrl, tokenResponse);\n return data.access_token;\n }\n }\n } catch { /* ignore */ }\n\n return undefined;\n }\n\n // ================================================================\n // Token Resolution\n // ================================================================\n\n /**\n * Resolve the auth token for an MCP server.\n * - OAuth mode: Checks stored token, refreshes if expired, triggers auth if needed\n */\n private async resolveToken(mcpServerUrl: string): Promise<string | undefined> {\n if (this.manuallySignedOutServers.has(mcpServerUrl)) {\n return undefined;\n }\n\n const authConfig = await this.ensureServerAuthConfig(mcpServerUrl);\n\n // OAuth mode: check stored token with expiry\n const stored = this.loadOAuthToken(mcpServerUrl);\n if (stored) {\n // Token not expired - use it\n if (stored.expiresAt > Date.now()) {\n return stored.accessToken;\n }\n\n // Token expired - try refresh if we have refresh token\n if (stored.refreshToken) {\n const refreshed = await this.refreshOAuthToken(mcpServerUrl, stored.refreshToken);\n if (refreshed) return refreshed;\n }\n\n // Refresh failed or no refresh token - clear and re-auth\n this.clearOAuthToken(mcpServerUrl);\n }\n\n // No valid token - trigger auth flow\n if (this.config.onAuthRequired) {\n if (authConfig) {\n const isBuiltInPopupAuth =\n (this.config.onAuthRequired as BuiltInPopupAuthHandler).__mcpStackBuiltinPopupAuth === true;\n const isAppTokenAuth = this.config.auth?.mode === 'app-token';\n const authConfigForHandler =\n authConfig.authType === 'oauth2' && !isBuiltInPopupAuth && !isAppTokenAuth\n ? await this.resolveOAuthClientRegistration(authConfig)\n : authConfig;\n if (authConfigForHandler) {\n this.updateServerAuthConfig(mcpServerUrl, authConfigForHandler);\n }\n const tokenResponse = await this.config.onAuthRequired(\n mcpServerUrl,\n authConfigForHandler ?? authConfig,\n );\n if (tokenResponse?.accessToken) {\n if (tokenResponse.resolvedAuthConfig) {\n this.updateServerAuthConfig(mcpServerUrl, tokenResponse.resolvedAuthConfig);\n }\n this.storeOAuthToken(mcpServerUrl, tokenResponse);\n return tokenResponse.accessToken;\n }\n }\n }\n\n return undefined;\n }\n\n // ================================================================\n // Chat Loop\n // ================================================================\n\n /**\n * The core orchestration loop:\n * 1. Send message to chat API\n * 2. Stream response\n * 3. If tool_call → execute tool via MCP → send result → continue\n * 4. If message_end → done\n */\n private async runChatLoop(message: string): Promise<void> {\n this.abortController = new AbortController();\n this.emit('thinking', true);\n\n const chatBody: Record<string, unknown> = {\n agentId: this.config.agentId,\n conversationId: this.conversationId,\n message,\n externalUserId: this.resolveExternalUserId(),\n context: this.config.context,\n };\n const externalUser = this.buildExternalUserContext();\n if (externalUser) {\n chatBody.externalUser = externalUser;\n }\n const clientToolSchemas = this.clientToolsToSchemas();\n if (clientToolSchemas.length > 0) {\n chatBody.clientTools = clientToolSchemas;\n }\n let response = await this.callChatApi(chatBody, 'chat');\n\n while (true) {\n const result = await this.processSseStream(response);\n\n if (result.type === 'message_end') {\n break;\n }\n\n if (result.type === 'tool_call') {\n const toolCall = result.data as SseToolCall;\n const startTime = Date.now();\n\n try {\n const toolResult = await this.executeTool(toolCall);\n const duration = Date.now() - startTime;\n\n const toolCallMsg = this.messages.find(\n m => m.role === 'tool_call' && m.toolCallId === toolCall.toolCallId\n );\n if (toolCallMsg) {\n toolCallMsg.toolCallStatus = 'completed';\n toolCallMsg.toolCallDuration = duration;\n toolCallMsg.toolResult = typeof toolResult === 'string' ? toolResult : JSON.stringify(toolResult);\n }\n\n this.emit('tool_result', { toolCallId: toolCall.toolCallId, result: toolResult, duration });\n\n const toolResultMsg: ChatMessage = {\n id: crypto.randomUUID(),\n role: 'tool_result',\n content: typeof toolResult === 'string' ? toolResult : JSON.stringify(toolResult),\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n timestamp: new Date(),\n };\n this.messages.push(toolResultMsg);\n\n this.emit('thinking', true);\n\n const toolResultBody: Record<string, unknown> = {\n conversationId: this.conversationId!,\n toolCallId: toolCall.toolCallId,\n result: toolResult,\n durationMs: duration,\n context: this.config.context,\n };\n const clientToolSchemas = this.clientToolsToSchemas();\n if (clientToolSchemas.length > 0) {\n toolResultBody.clientTools = clientToolSchemas;\n }\n response = await this.callChatApi(toolResultBody, 'chat/tool-result');\n } catch (err) {\n const duration = Date.now() - startTime;\n const errorMsg = err instanceof Error ? err.message : 'Tool execution failed';\n\n const toolCallMsg = this.messages.find(\n m => m.role === 'tool_call' && m.toolCallId === toolCall.toolCallId\n );\n if (toolCallMsg) {\n toolCallMsg.toolCallStatus = 'error';\n toolCallMsg.toolCallDuration = duration;\n toolCallMsg.toolError = errorMsg;\n }\n\n this.emit('tool_error', { toolCallId: toolCall.toolCallId, error: errorMsg, duration });\n\n const errorResult = `Error: ${errorMsg}`;\n const toolResultMsg: ChatMessage = {\n id: crypto.randomUUID(),\n role: 'tool_result',\n content: errorResult,\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n timestamp: new Date(),\n };\n this.messages.push(toolResultMsg);\n\n this.emit('thinking', true);\n\n try {\n const toolResultBody: Record<string, unknown> = {\n conversationId: this.conversationId!,\n toolCallId: toolCall.toolCallId,\n result: errorResult,\n isError: true,\n durationMs: duration,\n context: this.config.context,\n };\n const clientToolSchemas = this.clientToolsToSchemas();\n if (clientToolSchemas.length > 0) {\n toolResultBody.clientTools = clientToolSchemas;\n }\n response = await this.callChatApi(toolResultBody, 'chat/tool-result');\n } catch {\n this.emit('error', { code: 'tool_error', message: errorMsg });\n break;\n }\n }\n }\n\n if (result.type === 'error') {\n break;\n }\n }\n }\n\n private async callChatApi(body: unknown, endpoint: string): Promise<Response> {\n const token = await this.resolveAuthToken();\n const response = await fetch(\n `${this.config.agentServiceUrl}/api/v1/${endpoint}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(body),\n signal: this.abortController?.signal,\n },\n );\n\n if (!response.ok) {\n throw new Error(await getResponseErrorMessage(response));\n }\n\n return response;\n }\n\n private async fetchConversationMessages(\n conversationId: string,\n cursor?: string,\n pageSize = 50,\n ): Promise<ConversationMessagesPage> {\n const token = await this.resolveAuthToken();\n const params = new URLSearchParams();\n params.set('pageSize', String(pageSize));\n if (cursor) {\n params.set('cursor', cursor);\n }\n\n const response = await fetch(\n `${this.config.agentServiceUrl}/api/v1/chat/conversations/${encodeURIComponent(conversationId)}/messages?${params.toString()}`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n },\n );\n\n if (!response.ok) {\n throw new Error(await getResponseErrorMessage(response));\n }\n\n return (await response.json()) as ConversationMessagesPage;\n }\n\n private applyConversationPage(\n page: ConversationMessagesPage,\n prepend: boolean,\n ): void {\n const mappedMessages = page.messages.map((message) => this.mapReplayMessage(message));\n this.conversationId = page.conversationId;\n this.historyCursor = page.nextCursor ?? null;\n this.hasOlderMessages = page.hasNextPage;\n this.messages = prepend\n ? [...mappedMessages, ...this.messages]\n : mappedMessages;\n }\n\n private mapReplayMessage(message: ConversationMessagesPage['messages'][number]): ChatMessage {\n const timestamp = new Date(message.createdAt);\n return {\n id: message.id,\n role: message.role,\n content: message.content ?? '',\n toolName: message.toolName ?? undefined,\n toolLabel: message.toolLabel ?? undefined,\n toolCallId: message.toolCallId ?? undefined,\n timestamp,\n toolCallStatus: message.toolCallStatus ?? undefined,\n toolCallStartTime:\n message.toolCallDurationMs != null\n ? timestamp.getTime() - message.toolCallDurationMs\n : undefined,\n toolCallDuration: message.toolCallDurationMs ?? undefined,\n toolResult: message.toolResultJson ?? undefined,\n toolError: message.toolError ?? undefined,\n errorCode: message.errorCode ?? undefined,\n metadataJson: message.metadataJson ?? null,\n };\n }\n\n /**\n * Process an SSE stream from the chat API.\n * Returns when the stream ends (either message_end or tool_call).\n */\n private async processSseStream(\n response: Response,\n ): Promise<{ type: 'message_end' | 'tool_call' | 'error'; data?: unknown }> {\n let assistantContent = '';\n let lastToolCall: SseToolCall | null = null;\n let emittedThinkingFalse = false;\n\n for await (const event of parseSseStream(response, this.abortController?.signal)) {\n switch (event.type) {\n case 'message_start': {\n const data = event.data as SseMessageStart;\n this.conversationId = data.conversationId;\n break;\n }\n\n case 'content_delta': {\n const data = event.data as SseContentDelta;\n if (!emittedThinkingFalse) {\n this.emit('thinking', false);\n emittedThinkingFalse = true;\n }\n assistantContent += data.text;\n this.emit('content_delta', data);\n break;\n }\n\n case 'tool_call': {\n const data = event.data as SseToolCall;\n if (!emittedThinkingFalse) {\n this.emit('thinking', false);\n emittedThinkingFalse = true;\n }\n lastToolCall = data;\n\n const toolCallMsg: ChatMessage = {\n id: crypto.randomUUID(),\n role: 'tool_call',\n content: `Calling ${data.toolLabel ?? data.toolName}...`,\n toolName: data.toolName,\n toolLabel: data.toolLabel,\n toolCallId: data.toolCallId,\n timestamp: new Date(),\n toolCallStatus: 'calling',\n toolCallStartTime: Date.now(),\n };\n this.messages.push(toolCallMsg);\n this.emit('tool_call', data);\n break;\n }\n\n case 'message_end': {\n const data = event.data as SseMessageEnd;\n\n if (assistantContent) {\n const assistantMsg: ChatMessage = {\n id: crypto.randomUUID(),\n role: 'assistant',\n content: assistantContent,\n timestamp: new Date(),\n };\n this.messages.push(assistantMsg);\n this.emit('message', assistantMsg);\n }\n\n this.emit('message_end', data);\n return { type: 'message_end', data };\n }\n\n case 'budget_snapshot': {\n const data = event.data as AgentBudgetSnapshot;\n this.budgetSnapshot = data;\n this.emit('budget_snapshot', data);\n break;\n }\n\n case 'error': {\n const data = event.data as SseError;\n if (data.budget) {\n this.budgetSnapshot = data.budget;\n this.emit('budget_snapshot', data.budget);\n }\n const errorMsg: ChatMessage = {\n id: crypto.randomUUID(),\n role: 'error',\n content: data.message,\n timestamp: new Date(),\n errorCode: data.code,\n };\n this.messages.push(errorMsg);\n this.emit('message', errorMsg);\n this.emit('error', data);\n return { type: 'error', data };\n }\n }\n }\n\n if (lastToolCall) {\n if (assistantContent) {\n const assistantMsg: ChatMessage = {\n id: crypto.randomUUID(),\n role: 'assistant',\n content: assistantContent,\n timestamp: new Date(),\n };\n this.messages.push(assistantMsg);\n this.emit('message', assistantMsg);\n }\n\n return { type: 'tool_call', data: lastToolCall };\n }\n\n if (assistantContent) {\n const assistantMsg: ChatMessage = {\n id: crypto.randomUUID(),\n role: 'assistant',\n content: assistantContent,\n timestamp: new Date(),\n };\n this.messages.push(assistantMsg);\n this.emit('message', assistantMsg);\n }\n\n return { type: 'message_end' };\n }\n\n // ================================================================\n // MCP Session Management\n // ================================================================\n\n /** Build headers for MCP server requests */\n private getMcpHeaders(mcpServerUrl: string): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json, text/event-stream',\n };\n const session = this.mcpSessions.get(mcpServerUrl);\n if (session?.sessionId) {\n headers['Mcp-Session-Id'] = session.sessionId;\n }\n return headers;\n }\n\n /** Best-effort MCP session teardown so reconnect starts cleanly after sign-out. */\n private async closeMcpSession(mcpServerUrl: string): Promise<void> {\n const session = this.mcpSessions.get(mcpServerUrl);\n if (!session?.sessionId) return;\n\n const headers: Record<string, string> = {\n 'Accept': 'application/json, text/event-stream',\n 'Mcp-Session-Id': session.sessionId,\n };\n\n const storedToken = this.loadOAuthToken(mcpServerUrl);\n if (storedToken?.accessToken) {\n headers['Authorization'] = `Bearer ${storedToken.accessToken}`;\n }\n\n try {\n await fetch(mcpServerUrl, {\n method: 'DELETE',\n headers,\n credentials: this.config.useCookies ? 'include' : 'omit',\n });\n } catch {\n // Local state still gets reset below even if the server is unavailable.\n }\n\n this.mcpSessions.set(mcpServerUrl, {\n sessionId: null,\n authStatus: session.authStatus,\n });\n }\n\n /** Initialize the MCP session for a specific server (required before tools/call) */\n private async initMcpSession(mcpServerUrl: string): Promise<void> {\n const session = this.mcpSessions.get(mcpServerUrl);\n if (session?.sessionId) return;\n\n const headers = this.getMcpHeaders(mcpServerUrl);\n await this.ensureServerAuthConfig(mcpServerUrl);\n const token = await this.resolveToken(mcpServerUrl);\n if (token) headers['Authorization'] = `Bearer ${token}`;\n\n const initPayload = JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'initialize',\n params: {\n protocolVersion: DEFAULT_MCP_PROTOCOL_VERSION,\n capabilities: {},\n clientInfo: { name: 'mcpstack-agent-sdk', version: '0.1.0' },\n },\n });\n\n const initResponse = await fetch(mcpServerUrl, {\n method: 'POST',\n headers,\n credentials: this.config.useCookies ? 'include' : 'omit',\n body: initPayload,\n });\n\n if (initResponse.status === 401) {\n this.clearOAuthToken(mcpServerUrl);\n this.updateMcpAuthStatus(mcpServerUrl, 'needs_auth');\n\n const freshToken = await this.resolveToken(mcpServerUrl);\n if (freshToken) {\n headers['Authorization'] = `Bearer ${freshToken}`;\n const retryResponse = await fetch(mcpServerUrl, {\n method: 'POST',\n headers,\n credentials: this.config.useCookies ? 'include' : 'omit',\n body: initPayload,\n });\n if (retryResponse.ok) {\n const sessionId = retryResponse.headers.get('mcp-session-id');\n this.mcpSessions.set(mcpServerUrl, { sessionId, authStatus: 'connected' });\n this.updateMcpAuthStatus(mcpServerUrl, 'connected');\n await retryResponse.text().catch(() => {});\n const notifyHeaders = this.getMcpHeaders(mcpServerUrl);\n notifyHeaders['Authorization'] = `Bearer ${freshToken}`;\n await fetch(mcpServerUrl, {\n method: 'POST',\n headers: notifyHeaders,\n credentials: this.config.useCookies ? 'include' : 'omit',\n body: JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' }),\n });\n return;\n }\n }\n throw new Error('MCP initialization failed (401): Authentication required');\n }\n\n if (!initResponse.ok) {\n const errorText = await initResponse.text().catch(() => 'MCP init error');\n throw new Error(`MCP initialization failed (${initResponse.status}): ${errorText}`);\n }\n\n const sessionId = initResponse.headers.get('mcp-session-id');\n this.mcpSessions.set(mcpServerUrl, { sessionId, authStatus: 'connected' });\n this.updateMcpAuthStatus(mcpServerUrl, 'connected');\n await initResponse.text().catch(() => {});\n\n const notifyHeaders = this.getMcpHeaders(mcpServerUrl);\n if (token) notifyHeaders['Authorization'] = `Bearer ${token}`;\n await fetch(mcpServerUrl, {\n method: 'POST',\n headers: notifyHeaders,\n credentials: this.config.useCookies ? 'include' : 'omit',\n body: JSON.stringify({ jsonrpc: '2.0', method: 'notifications/initialized' }),\n });\n }\n\n /** Update auth status for an MCP server and emit event */\n private updateMcpAuthStatus(mcpServerUrl: string, authStatus: 'connected' | 'needs_auth'): void {\n const session = this.mcpSessions.get(mcpServerUrl);\n if (session) {\n session.authStatus = authStatus;\n } else {\n this.mcpSessions.set(mcpServerUrl, { sessionId: null, authStatus });\n }\n\n const serverInfo = this.agentConfig?.mcpServers?.find(s => s.url === mcpServerUrl);\n this.emit('mcp_auth_status', {\n mcpServerUrl,\n mcpServerName: serverInfo?.name ?? mcpServerUrl,\n authStatus,\n });\n }\n\n /** Parse a JSON-RPC response from either JSON or SSE format */\n private async parseMcpResponse(response: Response): Promise<Record<string, unknown>> {\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\n\n if (contentType.includes('text/event-stream')) {\n const text = await response.text();\n const lines = text.split('\\n');\n let jsonData = '';\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n jsonData += line.slice(6);\n }\n }\n if (!jsonData) {\n throw new Error('No data received from MCP server SSE response');\n }\n return JSON.parse(jsonData);\n }\n\n return response.json();\n }\n\n // ================================================================\n // Tool Execution\n // ================================================================\n\n private async executeTool(toolCall: SseToolCall): Promise<unknown> {\n const isClientTool =\n toolCall.source === 'client' || !toolCall.mcpServerUrl;\n\n if (isClientTool && this.config.clientTools) {\n const def = this.config.clientTools[toolCall.toolName];\n if (def) {\n const result = await def.execute(toolCall.arguments ?? {});\n return result;\n }\n throw new Error(`Unknown client tool: ${toolCall.toolName}`);\n }\n\n const mcpServerUrl = toolCall.mcpServerUrl || this.agentConfig?.mcpServerUrl;\n if (!mcpServerUrl) {\n throw new Error('No MCP server URL for tool call');\n }\n\n await this.initMcpSession(mcpServerUrl);\n\n const token = await this.resolveToken(mcpServerUrl);\n const headers = this.getMcpHeaders(mcpServerUrl);\n if (token) headers['Authorization'] = `Bearer ${token}`;\n\n const toolCallBody = JSON.stringify({\n jsonrpc: '2.0',\n id: 2,\n method: 'tools/call',\n params: { name: toolCall.toolName, arguments: toolCall.arguments },\n });\n\n let response = await fetch(mcpServerUrl, {\n method: 'POST',\n headers,\n credentials: this.config.useCookies ? 'include' : 'omit',\n body: toolCallBody,\n signal: this.abortController?.signal,\n });\n\n // Session expired (404) → reinitialize and retry\n const session = this.mcpSessions.get(mcpServerUrl);\n if (response.status === 404 && session?.sessionId) {\n this.mcpSessions.set(mcpServerUrl, { ...session, sessionId: null });\n await this.initMcpSession(mcpServerUrl);\n const retryHeaders = this.getMcpHeaders(mcpServerUrl);\n if (token) retryHeaders['Authorization'] = `Bearer ${token}`;\n response = await fetch(mcpServerUrl, {\n method: 'POST',\n headers: retryHeaders,\n credentials: this.config.useCookies ? 'include' : 'omit',\n body: toolCallBody,\n signal: this.abortController?.signal,\n });\n }\n\n // 401 → clear token and try fresh auth\n if (response.status === 401) {\n this.clearOAuthToken(mcpServerUrl);\n this.updateMcpAuthStatus(mcpServerUrl, 'needs_auth');\n\n const freshToken = await this.resolveToken(mcpServerUrl);\n if (freshToken) {\n const authHeaders = this.getMcpHeaders(mcpServerUrl);\n authHeaders['Authorization'] = `Bearer ${freshToken}`;\n response = await fetch(mcpServerUrl, {\n method: 'POST',\n headers: authHeaders,\n credentials: this.config.useCookies ? 'include' : 'omit',\n body: toolCallBody,\n signal: this.abortController?.signal,\n });\n if (response.ok) {\n this.updateMcpAuthStatus(mcpServerUrl, 'connected');\n }\n }\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Authentication required');\n throw new Error(`Tool execution failed (401): ${errorText}`);\n }\n }\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'MCP server error');\n throw new Error(`Tool execution failed (${response.status}): ${errorText}`);\n }\n\n const currentSession = this.mcpSessions.get(mcpServerUrl);\n if (currentSession?.authStatus === 'needs_auth') {\n this.updateMcpAuthStatus(mcpServerUrl, 'connected');\n }\n\n const result = await this.parseMcpResponse(response) as {\n result?: { content?: Array<{ type: string; text: string }> };\n error?: { code: number; message: string };\n };\n\n if (result.error) {\n throw new Error(`MCP error (${result.error.code}): ${result.error.message}`);\n }\n\n if (result.result?.content) {\n const textContent = result.result.content\n .filter((c: { type: string }) => c.type === 'text')\n .map((c: { text: string }) => c.text)\n .join('\\n');\n return textContent || result.result;\n }\n\n return result.result ?? result;\n }\n}\n","import type {\n AgentBudgetSnapshot,\n AgentConfigResponse,\n AudioInputState,\n ChatMessage,\n ClientToolsMap as RuntimeClientToolsMap,\n ConversationFeedback,\n ConversationFeedbackSentiment,\n McpStackAppTokenAuthConfig,\n McpStackEmbeddedAuthIdentity,\n McpStackStorageLike,\n McpServerAuthConfig,\n OAuthTokenResponse,\n SseError,\n} from '../core/types';\n\nexport type ClientToolsMap = RuntimeClientToolsMap;\nexport type AppAgentUserIdentity = McpStackEmbeddedAuthIdentity;\n\nexport interface KeyValueStore {\n getItem(key: string): Promise<string | null> | string | null;\n setItem(key: string, value: string): Promise<void> | void;\n removeItem(key: string): Promise<void> | void;\n}\n\nexport interface OAuthSessionRequest {\n authorizeUrl: string;\n redirectUri: string;\n preferEphemeralSession?: boolean;\n}\n\nexport type OAuthSessionResult =\n | { type: 'success'; url: string }\n | { type: 'cancel' | 'dismiss' }\n | { type: 'error'; message?: string };\n\nexport interface AppAgentPlatform {\n storage?: {\n durable: KeyValueStore;\n secure?: KeyValueStore;\n };\n auth?: {\n openOAuthSession(request: OAuthSessionRequest): Promise<OAuthSessionResult>;\n dismissOAuthSession?(): Promise<void> | void;\n };\n lifecycle?: {\n onForegroundChange?(listener: (isForeground: boolean) => void): () => void;\n onConnectivityChange?(listener: (isOnline: boolean) => void): () => void;\n };\n}\n\nexport interface AppAgentApproval {\n id: string;\n title: string;\n rationale?: string;\n steps: string[];\n toolCallId?: string | null;\n confirmLabel?: string;\n cancelLabel?: string;\n}\n\nexport interface AppAgentInputOption {\n label: string;\n value: string;\n}\n\nexport interface AppAgentInputField {\n key: string;\n label: string;\n kind: 'text' | 'textarea' | 'number' | 'select' | 'boolean';\n required?: boolean;\n placeholder?: string;\n options?: AppAgentInputOption[];\n}\n\nexport interface AppAgentInputRequest {\n id: string;\n title: string;\n prompt?: string;\n fields: AppAgentInputField[];\n toolCallId?: string | null;\n submitLabel?: string;\n cancelLabel?: string;\n}\n\nexport interface AppAgentIssue {\n code: 'stale_conversation' | 'runtime_error' | 'config_error';\n message: string;\n recoverable: boolean;\n}\n\nexport interface AppAgentFeedbackState {\n isSubmitting: boolean;\n error: string | null;\n lastSubmittedAt: string | null;\n lastFeedback: ConversationFeedback | null;\n}\n\nexport interface AppAgentConnection {\n url: string;\n name: string;\n authStatus: 'connected' | 'needs_auth';\n canSignOut: boolean;\n}\n\nexport interface AppAgentConversationResumeRecord {\n conversationId: string;\n agentId: string;\n appSessionKey: string | null;\n conversationResumeVersion: string;\n updatedAt: string;\n}\n\nexport interface AppAgentConfig {\n apiKey: string;\n agentId: string;\n serviceUrl?: string;\n initialConnections?: AppAgentConnection[];\n oauthCallbackUrl?: string;\n oauthClientMetadataUrl?: string;\n getAuthToken?: () => Promise<string | undefined>;\n appSessionKey?: string | null;\n userIdentity?: AppAgentUserIdentity;\n auth?: McpStackAppTokenAuthConfig;\n useCookies?: boolean;\n externalUserId?: string;\n appContext?: Record<string, unknown>;\n clientTools?: ClientToolsMap;\n platform?: AppAgentPlatform;\n onAuthRequired?: (mcpServerUrl: string, authConfig: McpServerAuthConfig) => Promise<OAuthTokenResponse | undefined>;\n conversation?: {\n namespace?: string;\n historyPageSize?: number;\n };\n feedbackSource?: string;\n storage?: McpStackStorageLike | null;\n}\n\nexport interface AppAgentLifecycleState {\n isReady: boolean;\n isLoading: boolean;\n isLoadingHistory: boolean;\n isThinking: boolean;\n hasOlderMessages: boolean;\n error: SseError | null;\n issue: AppAgentIssue | null;\n}\n\nexport interface AppAgentSnapshotBase {\n runtime: {\n agent: unknown;\n agentConfig: AgentConfigResponse | null;\n };\n conversation: AppAgentLifecycleState & {\n id: string | null;\n messages: ChatMessage[];\n streamingContent: string;\n statusLabel: string;\n resumeKey: string | null;\n };\n connections: {\n items: AppAgentConnection[];\n needsAttention: boolean;\n };\n approvals: {\n pending: AppAgentApproval[];\n };\n requests: {\n pending: AppAgentInputRequest[];\n };\n feedback: AppAgentFeedbackState;\n budget: AgentBudgetSnapshot | null;\n voice: AudioInputState;\n}\n\nexport const APP_AGENT_APPROVAL_ACTION = 'requestApproval';\nexport const APP_AGENT_INPUT_ACTION = 'requestInput';\n","import type { ChatMessage } from '../core/types';\n\nexport type AppAgentToolCallMessage = ChatMessage & { role: 'tool_call' };\nexport type AppAgentAssistantMessage = ChatMessage & { role: 'assistant' };\nexport type AppAgentUserMessage = ChatMessage & { role: 'user' };\nexport type AppAgentErrorMessage = ChatMessage & { role: 'error' };\nexport type AppAgentConversationMessage =\n | AppAgentAssistantMessage\n | AppAgentUserMessage\n | AppAgentErrorMessage;\nexport type AppAgentVisibleMessage = AppAgentConversationMessage | AppAgentToolCallMessage;\nexport type AppAgentLastTurnSummary = {\n prompt: string;\n toolsUsed: number;\n durationMs: number | null;\n};\n\nexport type AppAgentRenderedNode =\n | { kind: 'user'; id: string; content: string }\n | { kind: 'assistant'; id: string; content: string }\n | { kind: 'tools'; id: string; tools: AppAgentToolCallMessage[] };\n\nexport type AppAgentInlinePendingTurnState = {\n prompt: string;\n baselineAssistantId: string | null;\n baselineToolCount: number;\n};\n\nexport type AppAgentToolStatusPresentation = {\n glyph: '✓' | '✕' | '…';\n tone: 'success' | 'error' | 'active';\n badgeLabel: 'Completed' | 'Failed' | 'Running';\n};\n\nexport type AppAgentInlineFeedState = {\n isActive: boolean;\n pendingPrompt: string | null;\n recentTools: AppAgentToolCallMessage[];\n previewText: string | null;\n waitingForActivity: boolean;\n};\n\nfunction isAssistantMessage(message: ChatMessage): message is AppAgentAssistantMessage {\n return message.role === 'assistant';\n}\n\nfunction isUserMessage(message: ChatMessage): message is AppAgentUserMessage {\n return message.role === 'user';\n}\n\nfunction isErrorMessage(message: ChatMessage): message is AppAgentErrorMessage {\n return message.role === 'error';\n}\n\nfunction isToolCallMessage(message: ChatMessage): message is AppAgentToolCallMessage {\n return message.role === 'tool_call';\n}\n\nexport function deriveVisibleMessages(messages: ChatMessage[]): AppAgentVisibleMessage[] {\n return messages.filter(\n (message): message is AppAgentVisibleMessage =>\n isAssistantMessage(message)\n || isUserMessage(message)\n || isErrorMessage(message)\n || isToolCallMessage(message),\n );\n}\n\nexport function deriveConversationMessages(messages: ChatMessage[]): AppAgentConversationMessage[] {\n return messages.filter(\n (message): message is AppAgentConversationMessage =>\n isUserMessage(message) || isAssistantMessage(message) || isErrorMessage(message),\n );\n}\n\nexport function deriveToolMessages(messages: ChatMessage[]): AppAgentToolCallMessage[] {\n return messages.filter(isToolCallMessage);\n}\n\nexport function getLatestAssistantMessage(messages: ChatMessage[]): AppAgentAssistantMessage | null {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message && isAssistantMessage(message)) {\n return message;\n }\n }\n\n return null;\n}\n\nexport function getLatestUserMessage(messages: ChatMessage[]): AppAgentUserMessage | null {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message && isUserMessage(message)) {\n return message;\n }\n }\n\n return null;\n}\n\nexport function getLatestToolMessage(messages: ChatMessage[]): AppAgentToolCallMessage | null {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message && isToolCallMessage(message)) {\n return message;\n }\n }\n\n return null;\n}\n\nexport function createInlinePendingTurnState(\n prompt: string,\n messages: ChatMessage[],\n): AppAgentInlinePendingTurnState {\n return {\n prompt,\n baselineAssistantId: getLatestAssistantMessage(messages)?.id ?? null,\n baselineToolCount: deriveToolMessages(messages).length,\n };\n}\n\nexport function applyUserMessageOverrides(\n messages: ChatMessage[],\n overrides: Record<string, string>,\n): ChatMessage[] {\n return messages.map((message) =>\n message.role === 'user' && overrides[message.id]\n ? { ...message, content: overrides[message.id] }\n : message,\n );\n}\n\nexport function buildRenderedNodes(messages: ChatMessage[]): AppAgentRenderedNode[] {\n const nodes: AppAgentRenderedNode[] = [];\n let toolBuffer: AppAgentToolCallMessage[] = [];\n\n const flushTools = (id: string) => {\n if (toolBuffer.length > 0) {\n nodes.push({ kind: 'tools', id: `tools-${id}`, tools: toolBuffer });\n toolBuffer = [];\n }\n };\n\n messages.forEach((message) => {\n if (isToolCallMessage(message)) {\n toolBuffer.push(message);\n return;\n }\n\n if (message.role === 'tool_result') {\n return;\n }\n\n flushTools(message.id);\n\n if (message.role === 'user') {\n nodes.push({ kind: 'user', id: message.id, content: message.content });\n return;\n }\n\n if (message.role === 'assistant') {\n nodes.push({ kind: 'assistant', id: message.id, content: message.content });\n }\n });\n\n if (toolBuffer.length > 0) {\n nodes.push({ kind: 'tools', id: 'tools-tail', tools: toolBuffer });\n }\n\n return nodes;\n}\n\nexport function deriveToolStatusPresentation(\n status?: ChatMessage['toolCallStatus'],\n): AppAgentToolStatusPresentation {\n if (status === 'completed') {\n return { glyph: '✓', tone: 'success', badgeLabel: 'Completed' };\n }\n\n if (status === 'error') {\n return { glyph: '✕', tone: 'error', badgeLabel: 'Failed' };\n }\n\n return { glyph: '…', tone: 'active', badgeLabel: 'Running' };\n}\n\nexport function summarizeConversationId(value: string | null): string {\n if (!value) {\n return 'Waiting';\n }\n\n return `${value.slice(0, 6)}…${value.slice(-4)}`;\n}\n\nexport function formatStructuredText(value?: string): string {\n if (!value) {\n return 'No payload captured.';\n }\n\n try {\n return JSON.stringify(JSON.parse(value), null, 2);\n } catch {\n return value;\n }\n}\n\nexport function deriveConversationStatusLabel(options: {\n isReady: boolean;\n isLoading: boolean;\n isThinking: boolean;\n streamingContent?: string;\n hasError?: boolean;\n hasIssue?: boolean;\n hasAttention?: boolean;\n readyLabel?: string;\n loadingLabel?: string;\n thinkingLabel?: string;\n streamingLabel?: string;\n attentionLabel?: string;\n issueLabel?: string;\n reconnectingLabel?: string;\n connectingLabel?: string;\n}): string {\n const {\n isReady,\n isLoading,\n isThinking,\n streamingContent,\n hasError = false,\n hasIssue = false,\n hasAttention = false,\n readyLabel = 'Ready',\n loadingLabel = 'Working…',\n thinkingLabel = 'Thinking…',\n streamingLabel = 'Responding…',\n attentionLabel = 'Needs auth',\n issueLabel = 'Needs attention',\n reconnectingLabel = 'Reconnecting…',\n connectingLabel = 'Connecting…',\n } = options;\n\n if (isReady) {\n if (isLoading) {\n return loadingLabel;\n }\n\n if (isThinking) {\n return thinkingLabel;\n }\n\n if (streamingContent && streamingContent.length > 0) {\n return streamingLabel;\n }\n\n if (hasAttention) {\n return attentionLabel;\n }\n\n if (hasIssue || hasError) {\n return issueLabel;\n }\n\n return readyLabel;\n }\n\n return hasIssue || hasError ? reconnectingLabel : connectingLabel;\n}\n\nexport function deriveLastTurnSummary(messages: ChatMessage[]): AppAgentLastTurnSummary | null {\n const lastUser = getLatestUserMessage(messages);\n if (!lastUser) {\n return null;\n }\n\n const lastUserIndex = messages.findIndex((message) => message.id === lastUser.id);\n if (lastUserIndex < 0) {\n return null;\n }\n\n const after = messages.slice(lastUserIndex + 1);\n const tools = deriveToolMessages(after);\n const lastToolEndedAt = tools\n .map((tool) => (tool.toolCallDuration ?? 0) + (tool.timestamp ? tool.timestamp.getTime() : 0))\n .reduce<number | null>((max, value) => (max === null || value > max ? value : max), null);\n const userStartedAt = lastUser.timestamp ? lastUser.timestamp.getTime() : null;\n\n return {\n prompt: lastUser.content.trim(),\n toolsUsed: tools.length,\n durationMs:\n lastToolEndedAt && userStartedAt\n ? Math.max(0, lastToolEndedAt - userStartedAt)\n : null,\n };\n}\n\nexport function deriveInlineFeedState(options: {\n pendingTurn: AppAgentInlinePendingTurnState | null;\n toolMessages: AppAgentToolCallMessage[];\n latestAssistantMessage?: { id: string; content: string } | null;\n streamingContent?: string;\n isLoading: boolean;\n isThinking: boolean;\n maxRecentTools?: number;\n}): AppAgentInlineFeedState {\n const {\n pendingTurn,\n toolMessages,\n latestAssistantMessage,\n streamingContent = '',\n isLoading,\n isThinking,\n maxRecentTools = 4,\n } = options;\n\n const startIndex = pendingTurn\n ? Math.max(\n pendingTurn.baselineToolCount,\n toolMessages.length - maxRecentTools,\n )\n : Math.max(toolMessages.length - maxRecentTools, 0);\n\n const recentTools = toolMessages.slice(startIndex);\n // While a new turn is in flight, only surface an assistant message if it is\n // genuinely new — i.e. its id is different from the one captured when the\n // turn started. Otherwise we'd flash the stale previous reply under a\n // \"Latest reply\" label until streaming begins.\n const hasFreshAssistantReply = Boolean(\n latestAssistantMessage\n && (!pendingTurn || latestAssistantMessage.id !== pendingTurn.baselineAssistantId),\n );\n const previewText =\n streamingContent\n || (hasFreshAssistantReply ? latestAssistantMessage!.content : null);\n const waitingForActivity =\n Boolean(pendingTurn) &&\n recentTools.length === 0 &&\n !streamingContent &&\n (isLoading || isThinking);\n const isActive = Boolean(isLoading || isThinking || streamingContent.length > 0);\n\n return {\n isActive,\n pendingPrompt: pendingTurn?.prompt ?? null,\n recentTools,\n previewText,\n waitingForActivity,\n };\n}\n","import type {\n McpStackAgentConfig,\n McpServerAuthConfig,\n OAuthTokenResponse,\n} from '../core/types';\nimport type {\n AppAgentPlatform,\n AppAgentUserIdentity,\n} from './types';\n\nfunction normalizeOptionalValue(value?: string): string | undefined {\n if (!value) {\n return undefined;\n }\n\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction isGatewayAuthorizeUrl(authorizationEndpoint: string): boolean {\n try {\n const url = new URL(authorizationEndpoint);\n return /\\/api\\/v1\\/gateway\\/[^/]+\\/authorize$/i.test(url.pathname);\n } catch {\n return false;\n }\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n return btoa(String.fromCharCode(...bytes))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n}\n\nasync function randomToken(length: number): Promise<string> {\n const bytes = new Uint8Array(length);\n crypto.getRandomValues(bytes);\n return base64UrlEncode(bytes);\n}\n\nasync function createCodeChallenge(verifier: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const hash = await crypto.subtle.digest('SHA-256', data);\n return base64UrlEncode(new Uint8Array(hash));\n}\n\nexport function createPlatformAuthHandler(options: {\n platform: AppAgentPlatform;\n userIdentity?: AppAgentUserIdentity;\n oauthCallbackUrl: string;\n}): McpStackAgentConfig['onAuthRequired'] {\n return async (_mcpServerUrl: string, authConfig: McpServerAuthConfig): Promise<OAuthTokenResponse | undefined> => {\n if (!options.platform.auth) {\n return undefined;\n }\n\n const authorizationEndpoint = authConfig.authorizationEndpoint ?? authConfig.loginUrl;\n const tokenEndpoint = authConfig.tokenEndpoint ?? authConfig.tokenUrl;\n const clientId = authConfig.clientId;\n const redirectUri = authConfig.callbackUrl ?? options.oauthCallbackUrl;\n\n if (!authorizationEndpoint || !tokenEndpoint || !clientId || !redirectUri) {\n return undefined;\n }\n\n const verifier = await randomToken(48);\n const state = await randomToken(24);\n const challenge = await createCodeChallenge(verifier);\n const authorizeUrl = new URL(authorizationEndpoint);\n authorizeUrl.searchParams.set('response_type', 'code');\n authorizeUrl.searchParams.set('client_id', clientId);\n authorizeUrl.searchParams.set('redirect_uri', redirectUri);\n authorizeUrl.searchParams.set('state', state);\n authorizeUrl.searchParams.set('code_challenge', challenge);\n authorizeUrl.searchParams.set('code_challenge_method', 'S256');\n\n if (authConfig.scopes?.length) {\n authorizeUrl.searchParams.set('scope', authConfig.scopes.join(' '));\n }\n\n if (authConfig.resource) {\n authorizeUrl.searchParams.set('resource', authConfig.resource);\n }\n\n if (options.userIdentity && isGatewayAuthorizeUrl(authorizationEndpoint)) {\n const subject = normalizeOptionalValue(options.userIdentity.subject);\n const email = normalizeOptionalValue(options.userIdentity.email);\n const organizationId = normalizeOptionalValue(options.userIdentity.organizationId);\n const displayName = normalizeOptionalValue(options.userIdentity.displayName);\n\n if (subject) {\n authorizeUrl.searchParams.set('mcpstack_host_subject', subject);\n }\n if (email) {\n authorizeUrl.searchParams.set('mcpstack_host_email', email);\n }\n if (organizationId) {\n authorizeUrl.searchParams.set('mcpstack_host_organization_id', organizationId);\n }\n if (displayName) {\n authorizeUrl.searchParams.set('mcpstack_host_display_name', displayName);\n }\n authorizeUrl.searchParams.set('mcpstack_mismatch_policy', 'block_with_switch');\n }\n\n const result = await options.platform.auth.openOAuthSession({\n authorizeUrl: authorizeUrl.toString(),\n redirectUri,\n preferEphemeralSession: true,\n });\n\n if (result.type !== 'success' || !result.url) {\n return undefined;\n }\n\n const callback = new URL(result.url);\n const returnedState = callback.searchParams.get('state');\n const code = callback.searchParams.get('code');\n if (returnedState !== state || !code) {\n const errorDescription = callback.searchParams.get('error_description');\n const errorCode = callback.searchParams.get('error');\n throw new Error(errorDescription ?? (errorCode ? `OAuth error: ${errorCode}` : 'Could not complete OAuth login.'));\n }\n\n const tokenResponse = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: clientId,\n redirect_uri: redirectUri,\n code,\n code_verifier: verifier,\n ...(authConfig.resource ? { resource: authConfig.resource } : {}),\n }).toString(),\n });\n\n const payload = await tokenResponse.json().catch(() => null);\n if (!tokenResponse.ok) {\n throw new Error(\n (payload as { error_description?: string; error?: string } | null)?.error_description\n ?? (payload as { error?: string } | null)?.error\n ?? `OAuth sign in failed (${tokenResponse.status}).`,\n );\n }\n\n return {\n accessToken: payload?.access_token ?? payload?.accessToken,\n refreshToken: payload?.refresh_token ?? payload?.refreshToken,\n expiresIn: payload?.expires_in ?? payload?.expiresIn,\n tokenType: payload?.token_type ?? payload?.tokenType,\n resolvedAuthConfig: { ...authConfig, callbackUrl: redirectUri },\n };\n };\n}\n","import type { AppAgentPlatform, KeyValueStore } from './types';\n\ntype LocalStorageLike = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;\n\nexport function createBrowserKeyValueStore(\n storage?: LocalStorageLike | null,\n): KeyValueStore {\n const resolvedStorage = storage ?? (() => {\n try {\n return typeof localStorage === 'undefined' ? null : localStorage;\n } catch {\n return null;\n }\n })();\n\n return {\n getItem(key) {\n return resolvedStorage?.getItem(key) ?? null;\n },\n setItem(key, value) {\n resolvedStorage?.setItem(key, value);\n },\n removeItem(key) {\n resolvedStorage?.removeItem(key);\n },\n };\n}\n\nexport function createBrowserAppAgentPlatform(\n storage?: LocalStorageLike | null,\n): AppAgentPlatform {\n return {\n storage: {\n durable: createBrowserKeyValueStore(storage),\n },\n };\n}\n\nexport function createMemoryKeyValueStore(\n seed: Record<string, string> = {},\n): KeyValueStore {\n const map = new Map(Object.entries(seed));\n\n return {\n getItem(key) {\n return map.has(key) ? map.get(key)! : null;\n },\n setItem(key, value) {\n map.set(key, value);\n },\n removeItem(key) {\n map.delete(key);\n },\n };\n}\n\nexport async function resolveStoreValue<T>(\n value: Promise<T> | T,\n): Promise<T> {\n return await Promise.resolve(value);\n}\n","import { McpStackAgent } from '../core/EmcyAgent';\nimport type {\n AgentBudgetSnapshot,\n AgentConfigResponse,\n AudioInputState,\n ChatMessage,\n ConversationFeedback,\n McpServerAuthConfig,\n OAuthTokenResponse,\n SseContentDelta,\n SseError,\n SseToolCall,\n SubmitConversationFeedbackRequest,\n} from '../core/types';\nimport {\n APP_AGENT_APPROVAL_ACTION,\n APP_AGENT_INPUT_ACTION,\n type AppAgentApproval,\n type AppAgentConfig,\n type AppAgentConnection,\n type AppAgentConversationResumeRecord,\n type AppAgentFeedbackState,\n type AppAgentInputField,\n type AppAgentInputRequest,\n type AppAgentIssue,\n type AppAgentSnapshotBase,\n} from './types';\nimport {\n applyUserMessageOverrides,\n buildRenderedNodes,\n createInlinePendingTurnState,\n deriveConversationMessages,\n deriveLastTurnSummary,\n deriveConversationStatusLabel,\n deriveInlineFeedState,\n deriveToolMessages,\n deriveVisibleMessages,\n getLatestAssistantMessage,\n getLatestToolMessage,\n getLatestUserMessage,\n} from './presentation';\nimport { createPlatformAuthHandler } from './oauth';\nimport { createBrowserAppAgentPlatform, resolveStoreValue } from './platform';\n\ntype Listener = () => void;\n\ntype ApprovalResolver = {\n resolve: (value: { approved: boolean }) => void;\n};\n\ntype InputResolver = {\n resolve: (value: { submitted: boolean; values?: Record<string, unknown> }) => void;\n};\n\ntype AppAgentInternalState = {\n runtime: {\n agentConfig: AgentConfigResponse | null;\n };\n conversation: {\n id: string | null;\n messages: ChatMessage[];\n streamingContent: string;\n pendingTurn: ReturnType<typeof createInlinePendingTurnState> | null;\n pendingTurnSawActivity: boolean;\n statusLabel: string;\n resumeKey: string | null;\n isReady: boolean;\n isLoading: boolean;\n isLoadingHistory: boolean;\n isThinking: boolean;\n hasOlderMessages: boolean;\n error: SseError | null;\n issue: AppAgentIssue | null;\n };\n connections: {\n items: AppAgentConnection[];\n };\n approvals: {\n pending: AppAgentApproval[];\n };\n requests: {\n pending: AppAgentInputRequest[];\n };\n feedback: AppAgentFeedbackState;\n voice: AudioInputState;\n budget: AgentBudgetSnapshot | null;\n};\n\nexport type AppAgentSnapshot = AppAgentSnapshotBase & {\n runtime: AppAgentSnapshotBase['runtime'] & {\n agent: McpStackAgent;\n };\n conversation: AppAgentSnapshotBase['conversation'] & {\n visibleMessages: ReturnType<typeof deriveVisibleMessages>;\n conversationMessages: ReturnType<typeof deriveConversationMessages>;\n toolMessages: ReturnType<typeof deriveToolMessages>;\n renderedNodes: ReturnType<typeof buildRenderedNodes>;\n latestAssistantMessage: ReturnType<typeof getLatestAssistantMessage>;\n latestToolMessage: ReturnType<typeof getLatestToolMessage>;\n latestUserMessage: ReturnType<typeof getLatestUserMessage>;\n lastTurn: ReturnType<typeof deriveLastTurnSummary>;\n pendingTurn: ReturnType<typeof createInlinePendingTurnState> | null;\n inlineFeed: ReturnType<typeof deriveInlineFeedState>;\n };\n};\n\nfunction createId(prefix: string): string {\n return `${prefix}_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`;\n}\n\nfunction normalizeSteps(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((entry): entry is string => typeof entry === 'string' && entry.trim().length > 0)\n : [];\n}\n\nfunction normalizeInputFields(value: unknown): AppAgentInputField[] {\n if (!Array.isArray(value)) {\n return [];\n }\n\n return value.flatMap((entry): AppAgentInputField[] => {\n if (!entry || typeof entry !== 'object') {\n return [];\n }\n\n const record = entry as Record<string, unknown>;\n const key = typeof record.key === 'string' ? record.key.trim() : '';\n const label = typeof record.label === 'string' ? record.label.trim() : '';\n const kind = typeof record.kind === 'string' ? record.kind : 'text';\n if (!key || !label) {\n return [];\n }\n\n return [{\n key,\n label,\n kind:\n kind === 'textarea'\n || kind === 'number'\n || kind === 'select'\n || kind === 'boolean'\n ? kind\n : 'text',\n required: Boolean(record.required),\n placeholder: typeof record.placeholder === 'string' ? record.placeholder : undefined,\n options: Array.isArray(record.options)\n ? record.options.flatMap((option) => {\n if (!option || typeof option !== 'object') {\n return [];\n }\n\n const optionRecord = option as Record<string, unknown>;\n const optionLabel = typeof optionRecord.label === 'string' ? optionRecord.label.trim() : '';\n const optionValue = typeof optionRecord.value === 'string' ? optionRecord.value : '';\n return optionLabel && optionValue\n ? [{ label: optionLabel, value: optionValue }]\n : [];\n })\n : undefined,\n }];\n });\n}\n\nfunction isToolRoutingResetError(error: SseError): boolean {\n return error.code === 'tool_routing_error'\n && /tool not found/i.test(error.message);\n}\n\nfunction mapConnections(agent: McpStackAgent): AppAgentConnection[] {\n return agent.getMcpServers().map((server) => ({\n url: server.url,\n name: server.name,\n authStatus: server.authStatus,\n canSignOut: server.canSignOut,\n }));\n}\n\nfunction normalizeConnections(connections: AppAgentConnection[] | undefined): AppAgentConnection[] {\n if (!connections?.length) {\n return [];\n }\n\n const byUrl = new Map<string, AppAgentConnection>();\n for (const connection of connections) {\n const url = connection.url?.trim();\n if (!url) {\n continue;\n }\n\n byUrl.set(url, {\n ...connection,\n url,\n name: connection.name?.trim() || url,\n });\n }\n\n return Array.from(byUrl.values());\n}\n\nfunction mergeConnections(\n runtimeConnections: AppAgentConnection[],\n existingConnections: AppAgentConnection[],\n): AppAgentConnection[] {\n const byUrl = new Map<string, AppAgentConnection>();\n for (const connection of existingConnections) {\n byUrl.set(connection.url, connection);\n }\n\n for (const connection of runtimeConnections) {\n byUrl.set(connection.url, connection);\n }\n\n return Array.from(byUrl.values());\n}\n\nexport class AppAgentController {\n private readonly listeners = new Set<Listener>();\n private readonly agent: McpStackAgent;\n private readonly platform: NonNullable<AppAgentConfig['platform']>;\n private readonly recoveredConversationIds = new Set<string>();\n private readonly approvalResolvers = new Map<string, ApprovalResolver>();\n private readonly inputResolvers = new Map<string, InputResolver>();\n private readonly pendingToolCallsByAction = new Map<string, string[]>();\n private readonly lifecycleUnsubscribers: Array<() => void> = [];\n private readonly userMessageDisplayOverrides = new Map<string, string>();\n private state: AppAgentInternalState;\n private snapshot: AppAgentSnapshot;\n private started = false;\n private disposed = false;\n private initializationPromise: Promise<void> | null = null;\n private pendingDisplayText: string | null = null;\n\n constructor(private config: AppAgentConfig) {\n this.platform = config.platform ?? createBrowserAppAgentPlatform();\n\n const onAuthRequired =\n config.onAuthRequired\n ?? (\n !config.auth && this.platform.auth\n ? createPlatformAuthHandler({\n platform: this.platform,\n userIdentity: config.userIdentity,\n oauthCallbackUrl: config.oauthCallbackUrl ?? '',\n })\n : undefined\n );\n\n this.agent = new McpStackAgent({\n apiKey: config.apiKey,\n agentId: config.agentId,\n agentServiceUrl: config.serviceUrl,\n oauthCallbackUrl: config.oauthCallbackUrl,\n oauthClientMetadataUrl: config.oauthClientMetadataUrl,\n getAuthToken: config.getAuthToken,\n authSessionKey: config.appSessionKey,\n auth: config.auth,\n embeddedAuth: config.userIdentity\n ? {\n hostIdentity: config.userIdentity,\n mismatchPolicy: 'block_with_switch',\n }\n : undefined,\n useCookies: config.useCookies,\n onAuthRequired,\n externalUserId: config.externalUserId ?? config.userIdentity?.subject ?? config.userIdentity?.email,\n context: config.appContext,\n clientTools: this.buildClientTools(config.clientTools),\n conversationHistoryPageSize: config.conversation?.historyPageSize ?? 50,\n storage: config.storage,\n });\n\n this.state = {\n runtime: {\n agentConfig: null,\n },\n conversation: {\n id: null,\n messages: [],\n streamingContent: '',\n pendingTurn: null,\n pendingTurnSawActivity: false,\n statusLabel: 'Connecting…',\n resumeKey: this.getResumeStorageKey(),\n isReady: false,\n isLoading: false,\n isLoadingHistory: false,\n isThinking: false,\n hasOlderMessages: false,\n error: null,\n issue: null,\n },\n connections: {\n items: normalizeConnections(config.initialConnections),\n },\n approvals: {\n pending: [],\n },\n requests: {\n pending: [],\n },\n feedback: {\n isSubmitting: false,\n error: null,\n lastSubmittedAt: null,\n lastFeedback: null,\n },\n voice: this.agent.getAudioInputState(),\n budget: this.agent.getBudgetSnapshot(),\n };\n\n this.recomputeDerivedState();\n this.snapshot = this.buildSnapshot();\n }\n\n getAgent(): McpStackAgent {\n return this.agent;\n }\n\n getSnapshot = (): AppAgentSnapshot => this.snapshot;\n\n private buildSnapshot(): AppAgentSnapshot {\n const messages = applyUserMessageOverrides(\n this.state.conversation.messages,\n Object.fromEntries(this.userMessageDisplayOverrides),\n );\n const visibleMessages = deriveVisibleMessages(messages);\n const conversationMessages = deriveConversationMessages(messages);\n const toolMessages = deriveToolMessages(visibleMessages);\n const latestAssistantMessage = getLatestAssistantMessage(visibleMessages);\n const latestToolMessage = getLatestToolMessage(toolMessages);\n const latestUserMessage = getLatestUserMessage(visibleMessages);\n const lastTurn = deriveLastTurnSummary(messages);\n const renderedNodes = buildRenderedNodes(messages);\n const inlineFeed = deriveInlineFeedState({\n pendingTurn: this.state.conversation.pendingTurn,\n toolMessages,\n latestAssistantMessage: latestAssistantMessage\n ? { id: latestAssistantMessage.id, content: latestAssistantMessage.content }\n : null,\n streamingContent: this.state.conversation.streamingContent,\n isLoading: this.state.conversation.isLoading,\n isThinking: this.state.conversation.isThinking,\n });\n\n return {\n runtime: {\n agent: this.agent,\n agentConfig: this.state.runtime.agentConfig,\n },\n conversation: {\n ...this.state.conversation,\n messages,\n visibleMessages,\n conversationMessages,\n toolMessages,\n renderedNodes,\n latestAssistantMessage,\n latestToolMessage,\n latestUserMessage,\n lastTurn,\n pendingTurn: this.state.conversation.pendingTurn,\n inlineFeed,\n },\n connections: {\n ...this.state.connections,\n needsAttention: this.state.connections.items.some((item) => item.authStatus === 'needs_auth'),\n },\n approvals: {\n pending: this.state.approvals.pending,\n },\n requests: {\n pending: this.state.requests.pending,\n },\n feedback: this.state.feedback,\n budget: this.state.budget,\n voice: this.state.voice,\n };\n }\n\n subscribe(listener: Listener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n start(): void {\n if (this.started || this.disposed) {\n return;\n }\n\n this.started = true;\n this.bindLifecycleSignals();\n this.bindRuntimeEvents();\n this.initializationPromise = this.initialize();\n }\n\n dispose(): void {\n if (this.disposed) {\n return;\n }\n\n this.disposed = true;\n this.started = false;\n this.agent.off('message', this.handleMessage);\n this.agent.off('content_delta', this.handleContentDelta);\n this.agent.off('tool_call', this.handleToolCall);\n this.agent.off('tool_result', this.handleToolResult);\n this.agent.off('tool_error', this.handleToolError);\n this.agent.off('thinking', this.handleThinking);\n this.agent.off('loading', this.handleLoading);\n this.agent.off('error', this.handleError);\n this.agent.off('mcp_auth_status', this.handleMcpAuthStatus);\n this.agent.off('audio_state', this.handleAudioState);\n this.lifecycleUnsubscribers.splice(0).forEach((unsubscribe) => unsubscribe());\n this.agent.cancelVoiceInput();\n this.agent.cancel();\n this.approvalResolvers.clear();\n this.inputResolvers.clear();\n this.listeners.clear();\n }\n\n updateDynamicConfig(config: Pick<AppAgentConfig, 'appContext' | 'clientTools' | 'feedbackSource'>): void {\n this.config = {\n ...this.config,\n ...config,\n };\n this.agent.setAppContext(this.config.appContext);\n this.agent.setClientTools(this.buildClientTools(this.config.clientTools));\n }\n\n setAuthRequiredHandler(\n onAuthRequired: ((mcpServerUrl: string, authConfig: McpServerAuthConfig) => Promise<OAuthTokenResponse | undefined>) | undefined,\n ): void {\n this.config = {\n ...this.config,\n onAuthRequired,\n };\n this.agent.setOnAuthRequired(onAuthRequired);\n }\n\n async send(prompt: string, options?: { displayText?: string }): Promise<void> {\n const trimmed = prompt.trim();\n if (!trimmed) {\n return;\n }\n\n const displayText = (options?.displayText ?? trimmed).trim() || trimmed;\n this.pendingDisplayText = displayText;\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n pendingTurn: createInlinePendingTurnState(displayText, current.conversation.messages),\n pendingTurnSawActivity: false,\n issue: null,\n },\n }));\n\n try {\n await this.agent.sendMessage(trimmed);\n } catch (error) {\n this.pendingDisplayText = null;\n const message = error instanceof Error ? error.message : 'Could not send message.';\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n pendingTurn: null,\n pendingTurnSawActivity: false,\n error: {\n code: 'send_message_error',\n message,\n },\n issue: {\n code: 'runtime_error',\n message,\n recoverable: false,\n },\n },\n }));\n throw error;\n }\n }\n\n cancel(): void {\n this.agent.cancel();\n }\n\n async startVoiceInput(): Promise<void> {\n await this.agent.startVoiceInput();\n }\n\n async stopVoiceInput(): Promise<void> {\n await this.agent.stopVoiceInput();\n }\n\n cancelVoiceInput(): void {\n this.agent.cancelVoiceInput();\n }\n\n async loadMore(): Promise<void> {\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n isLoadingHistory: true,\n },\n }));\n\n try {\n const page = await this.agent.loadOlderMessages();\n if (!page) {\n return;\n }\n\n this.syncFromRuntime();\n } finally {\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n isLoadingHistory: false,\n },\n }));\n }\n }\n\n async resetConversation(): Promise<void> {\n this.agent.newConversation();\n await this.clearResumeRecord();\n this.recoveredConversationIds.clear();\n this.pendingToolCallsByAction.clear();\n this.approvalResolvers.clear();\n this.inputResolvers.clear();\n this.userMessageDisplayOverrides.clear();\n this.pendingDisplayText = null;\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n id: null,\n messages: [],\n streamingContent: '',\n pendingTurn: null,\n pendingTurnSawActivity: false,\n hasOlderMessages: false,\n error: null,\n issue: null,\n },\n approvals: {\n pending: [],\n },\n requests: {\n pending: [],\n },\n }));\n }\n\n async connect(serverUrl: string): Promise<boolean> {\n await this.ensureInitialized();\n const result = await this.agent.authenticate(serverUrl);\n this.setState((current) => ({\n ...current,\n connections: {\n items: mergeConnections(mapConnections(this.agent), current.connections.items),\n },\n budget: this.agent.getBudgetSnapshot(),\n }));\n return result;\n }\n\n async disconnect(serverUrl: string): Promise<void> {\n await this.agent.signOutMcpServer(serverUrl);\n this.setState((current) => ({\n ...current,\n connections: {\n items: mergeConnections(mapConnections(this.agent), current.connections.items),\n },\n }));\n }\n\n async submitFeedback(\n input: Omit<SubmitConversationFeedbackRequest, 'source'>,\n ): Promise<ConversationFeedback> {\n this.setState((current) => ({\n ...current,\n feedback: {\n ...current.feedback,\n isSubmitting: true,\n error: null,\n },\n }));\n\n try {\n const feedback = await this.agent.submitFeedback({\n ...input,\n source: this.config.feedbackSource ?? 'app-agent',\n });\n\n this.setState((current) => ({\n ...current,\n feedback: {\n isSubmitting: false,\n error: null,\n lastSubmittedAt: feedback.createdAt,\n lastFeedback: feedback,\n },\n }));\n return feedback;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Could not save feedback.';\n this.setState((current) => ({\n ...current,\n feedback: {\n ...current.feedback,\n isSubmitting: false,\n error: message,\n },\n }));\n throw error;\n }\n }\n\n resolveApproval(id: string, approved: boolean): void {\n const resolver = this.approvalResolvers.get(id);\n if (!resolver) {\n return;\n }\n\n this.approvalResolvers.delete(id);\n this.setState((current) => ({\n ...current,\n approvals: {\n pending: current.approvals.pending.filter((approval) => approval.id !== id),\n },\n }));\n resolver.resolve({ approved });\n }\n\n submitRequest(id: string, values?: Record<string, unknown>): void {\n const resolver = this.inputResolvers.get(id);\n if (!resolver) {\n return;\n }\n\n this.inputResolvers.delete(id);\n this.setState((current) => ({\n ...current,\n requests: {\n pending: current.requests.pending.filter((request) => request.id !== id),\n },\n }));\n resolver.resolve({ submitted: true, values });\n }\n\n cancelRequest(id: string): void {\n const resolver = this.inputResolvers.get(id);\n if (!resolver) {\n return;\n }\n\n this.inputResolvers.delete(id);\n this.setState((current) => ({\n ...current,\n requests: {\n pending: current.requests.pending.filter((request) => request.id !== id),\n },\n }));\n resolver.resolve({ submitted: false });\n }\n\n private async initialize(): Promise<void> {\n try {\n const agentConfig = await this.agent.init();\n if (this.disposed) {\n return;\n }\n\n this.setState((current) => ({\n ...current,\n runtime: {\n agentConfig,\n },\n conversation: {\n ...current.conversation,\n isReady: true,\n },\n connections: {\n items: mergeConnections(mapConnections(this.agent), current.connections.items),\n },\n budget: this.agent.getBudgetSnapshot(),\n }));\n\n const resumeRecord = await this.readResumeRecord();\n if (\n resumeRecord\n && resumeRecord.agentId === this.config.agentId\n && resumeRecord.appSessionKey === (this.config.appSessionKey ?? null)\n && resumeRecord.conversationResumeVersion === agentConfig.conversationResumeVersion\n ) {\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n isLoadingHistory: true,\n },\n }));\n\n try {\n await this.agent.loadConversation(\n resumeRecord.conversationId,\n this.config.conversation?.historyPageSize ?? 50,\n );\n } catch (error) {\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n error: {\n code: 'conversation_history_error',\n message: error instanceof Error ? error.message : 'Failed to load conversation history.',\n },\n },\n }));\n await this.clearResumeRecord();\n } finally {\n this.syncFromRuntime();\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n isLoadingHistory: false,\n },\n }));\n }\n } else {\n this.syncFromRuntime();\n }\n } catch (error) {\n const message = error instanceof Error && error.message.trim()\n ? error.message.trim()\n : 'Failed to load agent configuration.';\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n error: {\n code: /api key|unauthorized|401/i.test(message)\n ? 'agent_config_auth_error'\n : 'agent_config_error',\n message,\n },\n issue: {\n code: 'config_error',\n message,\n recoverable: false,\n },\n },\n }));\n }\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.state.runtime.agentConfig) {\n return;\n }\n\n this.initializationPromise ??= this.initialize();\n await this.initializationPromise;\n }\n\n private bindRuntimeEvents(): void {\n this.agent.on('message', this.handleMessage);\n this.agent.on('content_delta', this.handleContentDelta);\n this.agent.on('tool_call', this.handleToolCall);\n this.agent.on('tool_result', this.handleToolResult);\n this.agent.on('tool_error', this.handleToolError);\n this.agent.on('thinking', this.handleThinking);\n this.agent.on('loading', this.handleLoading);\n this.agent.on('error', this.handleError);\n this.agent.on('mcp_auth_status', this.handleMcpAuthStatus);\n this.agent.on('audio_state', this.handleAudioState);\n this.agent.on('budget_snapshot', this.handleBudgetSnapshot);\n }\n\n private readonly handleMessage = (message: ChatMessage): void => {\n if (message.role === 'user' && this.pendingDisplayText) {\n this.userMessageDisplayOverrides.set(message.id, this.pendingDisplayText);\n this.pendingDisplayText = null;\n }\n\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n messages: [...current.conversation.messages, message],\n id: this.agent.getConversationId(),\n streamingContent: '',\n hasOlderMessages: this.agent.getHasOlderMessages(),\n pendingTurnSawActivity: current.conversation.pendingTurn ? true : current.conversation.pendingTurnSawActivity,\n },\n }));\n void this.persistResumeRecord();\n this.finalizePendingTurnIfSettled();\n };\n\n private readonly handleContentDelta = (delta: SseContentDelta): void => {\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n streamingContent: current.conversation.streamingContent + delta.text,\n pendingTurnSawActivity: current.conversation.pendingTurn ? true : current.conversation.pendingTurnSawActivity,\n },\n }));\n };\n\n private readonly handleToolCall = (toolCall: SseToolCall): void => {\n if (\n toolCall.toolName === APP_AGENT_APPROVAL_ACTION\n || toolCall.toolName === APP_AGENT_INPUT_ACTION\n ) {\n const queue = this.pendingToolCallsByAction.get(toolCall.toolName) ?? [];\n queue.push(toolCall.toolCallId);\n this.pendingToolCallsByAction.set(toolCall.toolName, queue);\n }\n\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n id: this.agent.getConversationId(),\n messages: [\n ...current.conversation.messages,\n {\n id: crypto.randomUUID(),\n role: 'tool_call',\n content: `Calling ${toolCall.toolLabel ?? toolCall.toolName}...`,\n toolName: toolCall.toolName,\n toolLabel: toolCall.toolLabel,\n toolCallId: toolCall.toolCallId,\n timestamp: new Date(),\n toolCallStatus: 'calling',\n toolCallStartTime: Date.now(),\n },\n ],\n pendingTurnSawActivity: current.conversation.pendingTurn ? true : current.conversation.pendingTurnSawActivity,\n },\n }));\n };\n\n private readonly handleToolResult = (data: { toolCallId: string; result: unknown; duration: number }): void => {\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n messages: current.conversation.messages.map((message) =>\n message.role === 'tool_call' && message.toolCallId === data.toolCallId\n ? {\n ...message,\n toolCallStatus: 'completed',\n toolCallDuration: data.duration,\n toolResult:\n typeof data.result === 'string'\n ? data.result\n : JSON.stringify(data.result),\n }\n : message,\n ),\n },\n }));\n this.finalizePendingTurnIfSettled();\n };\n\n private readonly handleToolError = (data: { toolCallId: string; error: string; duration: number }): void => {\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n messages: current.conversation.messages.map((message) =>\n message.role === 'tool_call' && message.toolCallId === data.toolCallId\n ? {\n ...message,\n toolCallStatus: 'error',\n toolCallDuration: data.duration,\n toolError: data.error,\n }\n : message,\n ),\n },\n }));\n this.finalizePendingTurnIfSettled();\n };\n\n private readonly handleThinking = (thinking: boolean): void => {\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n isThinking: thinking,\n },\n }));\n this.finalizePendingTurnIfSettled();\n };\n\n private readonly handleLoading = (loading: boolean): void => {\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n isLoading: loading,\n error: loading ? null : current.conversation.error,\n streamingContent: loading ? '' : current.conversation.streamingContent,\n },\n }));\n this.finalizePendingTurnIfSettled();\n };\n\n private readonly handleError = (error: SseError): void => {\n this.setState((current) => ({\n ...current,\n budget: error.budget ?? current.budget,\n conversation: {\n ...current.conversation,\n error,\n pendingTurn: null,\n pendingTurnSawActivity: false,\n },\n }));\n\n if (isToolRoutingResetError(error)) {\n const conversationId = this.agent.getConversationId();\n if (conversationId && !this.recoveredConversationIds.has(conversationId)) {\n this.recoveredConversationIds.add(conversationId);\n void this.handleStaleConversation(error);\n return;\n }\n }\n\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n issue: {\n code: 'runtime_error',\n message: error.message,\n recoverable: false,\n },\n },\n }));\n };\n\n private readonly handleBudgetSnapshot = (budget: AgentBudgetSnapshot): void => {\n this.setState((current) => ({\n ...current,\n budget,\n }));\n };\n\n private readonly handleMcpAuthStatus = (): void => {\n this.setState((current) => ({\n ...current,\n connections: {\n items: mergeConnections(mapConnections(this.agent), current.connections.items),\n },\n }));\n };\n\n private readonly handleAudioState = (voice: AudioInputState): void => {\n this.setState((current) => ({\n ...current,\n voice,\n }));\n };\n\n private async handleStaleConversation(error: SseError): Promise<void> {\n await this.clearResumeRecord();\n this.agent.newConversation();\n this.pendingToolCallsByAction.clear();\n this.approvalResolvers.clear();\n this.inputResolvers.clear();\n this.userMessageDisplayOverrides.clear();\n this.pendingDisplayText = null;\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n id: null,\n messages: [],\n streamingContent: '',\n pendingTurn: null,\n pendingTurnSawActivity: false,\n hasOlderMessages: false,\n issue: {\n code: 'stale_conversation',\n message: error.message,\n recoverable: true,\n },\n },\n approvals: {\n pending: [],\n },\n requests: {\n pending: [],\n },\n }));\n }\n\n private bindLifecycleSignals(): void {\n const lifecycle = this.platform.lifecycle;\n if (!lifecycle) {\n return;\n }\n\n const foregroundUnsubscribe = lifecycle.onForegroundChange?.(() => {\n this.emit();\n });\n if (foregroundUnsubscribe) {\n this.lifecycleUnsubscribers.push(foregroundUnsubscribe);\n }\n\n const connectivityUnsubscribe = lifecycle.onConnectivityChange?.(() => {\n this.emit();\n });\n if (connectivityUnsubscribe) {\n this.lifecycleUnsubscribers.push(connectivityUnsubscribe);\n }\n }\n\n private buildClientTools(clientTools: AppAgentConfig['clientTools']) {\n const approvalAction = {\n description: 'Ask the host app to approve a multi-step plan before you continue.',\n selection: {\n categories: ['approval'],\n alwaysInclude: true,\n risk: 'medium',\n },\n parameters: {\n title: { type: 'string', description: 'Short title for the approval request.', required: true },\n rationale: { type: 'string', description: 'Optional reason for the plan.' },\n steps: { type: 'array', description: 'Ordered steps that need approval.', required: true },\n confirmLabel: { type: 'string', description: 'Optional label for the approve action.' },\n cancelLabel: { type: 'string', description: 'Optional label for the reject action.' },\n },\n execute: async (params: Record<string, unknown>) => {\n const approvalId = createId('approval');\n const toolCallId = this.shiftPendingToolCallId(APP_AGENT_APPROVAL_ACTION);\n const approval: AppAgentApproval = {\n id: approvalId,\n title: typeof params.title === 'string' ? params.title : 'Approval required',\n rationale: typeof params.rationale === 'string' ? params.rationale : undefined,\n steps: normalizeSteps(params.steps),\n toolCallId,\n confirmLabel: typeof params.confirmLabel === 'string' ? params.confirmLabel : undefined,\n cancelLabel: typeof params.cancelLabel === 'string' ? params.cancelLabel : undefined,\n };\n\n this.setState((current) => ({\n ...current,\n approvals: {\n pending: [...current.approvals.pending, approval],\n },\n }));\n\n return await new Promise<{ approved: boolean }>((resolve) => {\n this.approvalResolvers.set(approvalId, { resolve });\n });\n },\n } satisfies NonNullable<AppAgentConfig['clientTools']>[string];\n\n return {\n ...(clientTools ?? {}),\n [APP_AGENT_APPROVAL_ACTION]: {\n ...approvalAction,\n },\n [APP_AGENT_INPUT_ACTION]: {\n description: 'Ask the host app for structured user input before you continue.',\n selection: {\n categories: ['approval'],\n alwaysInclude: true,\n risk: 'medium',\n },\n parameters: {\n title: { type: 'string', description: 'Short title for the input request.', required: true },\n prompt: { type: 'string', description: 'Optional explainer shown above the fields.' },\n fields: { type: 'array', description: 'Structured fields to collect.', required: true },\n submitLabel: { type: 'string', description: 'Optional submit button label.' },\n cancelLabel: { type: 'string', description: 'Optional cancel button label.' },\n },\n execute: async (params: Record<string, unknown>) => {\n const requestId = createId('input');\n const toolCallId = this.shiftPendingToolCallId(APP_AGENT_INPUT_ACTION);\n const request: AppAgentInputRequest = {\n id: requestId,\n title: typeof params.title === 'string' ? params.title : 'Input required',\n prompt: typeof params.prompt === 'string' ? params.prompt : undefined,\n fields: normalizeInputFields(params.fields),\n toolCallId,\n submitLabel: typeof params.submitLabel === 'string' ? params.submitLabel : undefined,\n cancelLabel: typeof params.cancelLabel === 'string' ? params.cancelLabel : undefined,\n };\n\n this.setState((current) => ({\n ...current,\n requests: {\n pending: [...current.requests.pending, request],\n },\n }));\n\n return await new Promise<{ submitted: boolean; values?: Record<string, unknown> }>((resolve) => {\n this.inputResolvers.set(requestId, { resolve });\n });\n },\n },\n };\n }\n\n private shiftPendingToolCallId(actionName: string): string | null {\n const queue = this.pendingToolCallsByAction.get(actionName) ?? [];\n const next = queue.shift() ?? null;\n if (queue.length === 0) {\n this.pendingToolCallsByAction.delete(actionName);\n } else {\n this.pendingToolCallsByAction.set(actionName, queue);\n }\n return next;\n }\n\n private syncFromRuntime(): void {\n this.setState((current) => ({\n ...current,\n conversation: {\n ...current.conversation,\n id: this.agent.getConversationId(),\n messages: this.agent.getMessages(),\n hasOlderMessages: this.agent.getHasOlderMessages(),\n },\n connections: {\n items: mergeConnections(mapConnections(this.agent), current.connections.items),\n },\n }));\n void this.persistResumeRecord();\n }\n\n private finalizePendingTurnIfSettled(): void {\n const current = this.state.conversation;\n if (\n current.pendingTurn\n && current.pendingTurnSawActivity\n && !current.isLoading\n && !current.isThinking\n && !current.streamingContent\n ) {\n this.setState((state) => ({\n ...state,\n conversation: {\n ...state.conversation,\n pendingTurn: null,\n pendingTurnSawActivity: false,\n },\n }));\n }\n }\n\n private getResumeStorageKey(): string | null {\n const durable = this.platform.storage?.durable;\n if (!durable) {\n return null;\n }\n\n const namespace = this.config.conversation?.namespace ?? 'mcpstack.app-agent.resume';\n const sessionKey = this.config.appSessionKey?.trim() || 'anonymous';\n return `${namespace}:${this.config.agentId}:${sessionKey}`;\n }\n\n private async readResumeRecord(): Promise<AppAgentConversationResumeRecord | null> {\n const durable = this.platform.storage?.durable;\n const resumeKey = this.getResumeStorageKey();\n if (!durable || !resumeKey) {\n return null;\n }\n\n try {\n const raw = await resolveStoreValue(durable.getItem(resumeKey));\n if (!raw) {\n return null;\n }\n\n return JSON.parse(raw) as AppAgentConversationResumeRecord;\n } catch {\n return null;\n }\n }\n\n private async persistResumeRecord(): Promise<void> {\n const durable = this.platform.storage?.durable;\n const resumeKey = this.getResumeStorageKey();\n const conversationId = this.agent.getConversationId();\n const agentConfig = this.state.runtime.agentConfig;\n if (!durable || !resumeKey || !conversationId || !agentConfig) {\n return;\n }\n\n const record: AppAgentConversationResumeRecord = {\n conversationId,\n agentId: this.config.agentId,\n appSessionKey: this.config.appSessionKey ?? null,\n conversationResumeVersion: agentConfig.conversationResumeVersion,\n updatedAt: new Date().toISOString(),\n };\n\n try {\n await resolveStoreValue(durable.setItem(resumeKey, JSON.stringify(record)));\n } catch {\n // Ignore persistence failures. Runtime state still works.\n }\n }\n\n private async clearResumeRecord(): Promise<void> {\n const durable = this.platform.storage?.durable;\n const resumeKey = this.getResumeStorageKey();\n if (!durable || !resumeKey) {\n return;\n }\n\n try {\n await resolveStoreValue(durable.removeItem(resumeKey));\n } catch {\n // Ignore persistence failures.\n }\n }\n\n private setState(update: (current: AppAgentInternalState) => AppAgentInternalState): void {\n if (this.disposed) {\n return;\n }\n\n this.state = update(this.state);\n this.recomputeDerivedState();\n this.snapshot = this.buildSnapshot();\n this.emit();\n }\n\n private recomputeDerivedState(): void {\n const hasAttention = this.state.connections.items.some((item) => item.authStatus === 'needs_auth');\n this.state.conversation.statusLabel = deriveConversationStatusLabel({\n isReady: this.state.conversation.isReady,\n isLoading: this.state.conversation.isLoading,\n isThinking: this.state.conversation.isThinking,\n streamingContent: this.state.conversation.streamingContent,\n hasError: this.state.conversation.error != null,\n hasIssue: this.state.conversation.issue != null,\n hasAttention,\n });\n this.state.conversation.resumeKey = this.getResumeStorageKey();\n }\n\n private emit(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n\nexport function createAppAgent(config: AppAgentConfig): AppAgentController {\n return new AppAgentController(config);\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type {\n McpServerAuthConfig,\n OAuthTokenResponse,\n} from '../core/types';\nimport type { AppAgentUserIdentity } from '../app/types';\nimport {\n applyResolvedRegistration,\n buildRegistrationCacheKey,\n clearStoredRegistration,\n resolveOAuthRegistration,\n} from '../core/auth/registration';\nimport { normalizeAuthSessionKey } from '../core/auth-storage';\nimport type { OAuthPopupPhase, OAuthPopupViewState } from './components/OAuthPopup';\n\nconst OAUTH_CALLBACK_CHANNEL_NAME = 'mcpstack-oauth';\nconst OAUTH_CALLBACK_STORAGE_PREFIX = 'mcpstack-oauth-callback:';\n\ninterface UsePopupOAuthControllerOptions {\n resolveServerName: (serverUrl: string) => string;\n oauthCallbackUrl: string;\n oauthClientMetadataUrl: string;\n userIdentity?: AppAgentUserIdentity;\n appSessionKey?: string | null;\n}\n\ninterface ActivePopupAuthRequest {\n serverName: string;\n serverUrl: string;\n authConfig: McpServerAuthConfig;\n resolvedAuthConfig: McpServerAuthConfig;\n promise: Promise<OAuthTokenResponse | undefined>;\n resolve: (tokenResponse: OAuthTokenResponse | undefined) => void;\n state: string;\n codeVerifier: string;\n handledCallback: boolean;\n popupWindow: Window | null;\n pollTimer?: ReturnType<typeof setInterval>;\n userIdentity?: AppAgentUserIdentity;\n hostIdentityLabel?: string | null;\n}\n\nfunction generateCodeVerifier(): string {\n const array = new Uint8Array(32);\n crypto.getRandomValues(array);\n return btoa(String.fromCharCode(...array))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n}\n\nasync function generateCodeChallenge(verifier: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const hash = await crypto.subtle.digest('SHA-256', data);\n return btoa(String.fromCharCode(...new Uint8Array(hash)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n}\n\nfunction createPopupState(\n request: ActivePopupAuthRequest,\n phase: OAuthPopupPhase,\n statusMessage?: string | null,\n errorMessage?: string | null,\n): OAuthPopupViewState {\n return {\n serverName: request.serverName,\n serverUrl: request.serverUrl,\n phase,\n statusMessage: statusMessage ?? null,\n errorMessage: errorMessage ?? null,\n hostIdentityLabel: request.hostIdentityLabel ?? null,\n };\n}\n\nfunction normalizeOptionalValue(value?: string): string | undefined {\n if (!value) {\n return undefined;\n }\n\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction formatUserIdentityLabel(identity?: AppAgentUserIdentity): string | null {\n if (!identity) {\n return null;\n }\n\n return (\n normalizeOptionalValue(identity.displayName) ??\n normalizeOptionalValue(identity.email) ??\n normalizeOptionalValue(identity.subject) ??\n null\n );\n}\n\nfunction isGatewayAuthorizeUrl(authConfig: McpServerAuthConfig): boolean {\n const loginUrl = authConfig.authorizationEndpoint ?? authConfig.loginUrl;\n if (!loginUrl) {\n return false;\n }\n\n try {\n const url = new URL(loginUrl);\n return /\\/api\\/v1\\/gateway\\/[^/]+\\/authorize$/i.test(url.pathname);\n } catch {\n return false;\n }\n}\n\nexport interface PopupOAuthControllerState {\n popupState: OAuthPopupViewState | null;\n requestAuth: (\n serverUrl: string,\n authConfig: McpServerAuthConfig,\n ) => Promise<OAuthTokenResponse | undefined>;\n startOrRetryPopupAuth: () => void;\n cancelPopupAuth: () => void;\n handleServerAuthStatus: (\n serverUrl: string,\n authStatus: 'connected' | 'needs_auth',\n ) => void;\n}\n\nexport function usePopupOAuthController(\n options: UsePopupOAuthControllerOptions,\n): PopupOAuthControllerState {\n const [popupState, setPopupState] = useState<OAuthPopupViewState | null>(null);\n const popupStateRef = useRef<OAuthPopupViewState | null>(null);\n const activeRequestRef = useRef<ActivePopupAuthRequest | null>(null);\n const mountedRef = useRef(true);\n const optionsRef = useRef(options);\n const authSessionKeyRef = useRef(normalizeAuthSessionKey(options.appSessionKey));\n\n useEffect(() => {\n popupStateRef.current = popupState;\n }, [popupState]);\n\n useEffect(() => {\n optionsRef.current = options;\n }, [options]);\n\n const getCallbackUrl = useCallback((config: McpServerAuthConfig) => (\n config.callbackUrl ?? optionsRef.current.oauthCallbackUrl\n ), []);\n\n const clearStoredCallbackPayload = useCallback((state: string) => {\n if (!state) {\n return;\n }\n\n try {\n localStorage.removeItem(`${OAUTH_CALLBACK_STORAGE_PREFIX}${state}`);\n } catch {\n // Ignore storage failures in restricted environments.\n }\n }, []);\n\n const clearPollTimer = useCallback((request: ActivePopupAuthRequest | null) => {\n if (request?.pollTimer) {\n clearInterval(request.pollTimer);\n request.pollTimer = undefined;\n }\n }, []);\n\n const dismissPopupState = useCallback((serverUrl?: string) => {\n if (!mountedRef.current) {\n return;\n }\n\n if (!popupStateRef.current && !activeRequestRef.current) {\n return;\n }\n\n setPopupState((currentState) => {\n if (!currentState) {\n popupStateRef.current = null;\n return null;\n }\n\n if (!serverUrl || currentState.serverUrl === serverUrl) {\n popupStateRef.current = null;\n return null;\n }\n\n return currentState;\n });\n }, []);\n\n const closePopupWindow = useCallback((request: ActivePopupAuthRequest | null) => {\n if (request?.popupWindow && !request.popupWindow.closed) {\n request.popupWindow.close();\n }\n\n if (request) {\n request.popupWindow = null;\n }\n }, []);\n\n useEffect(() => {\n const previousAuthSessionKey = authSessionKeyRef.current;\n const nextAuthSessionKey = normalizeAuthSessionKey(options.appSessionKey);\n\n authSessionKeyRef.current = nextAuthSessionKey;\n if (previousAuthSessionKey === nextAuthSessionKey) {\n return;\n }\n\n const request = activeRequestRef.current;\n if (!request) {\n if (mountedRef.current) {\n setPopupState(null);\n }\n return;\n }\n\n clearPollTimer(request);\n closePopupWindow(request);\n clearStoredCallbackPayload(request.state);\n activeRequestRef.current = null;\n request.resolve(undefined);\n\n if (mountedRef.current) {\n setPopupState(null);\n }\n }, [\n clearPollTimer,\n clearStoredCallbackPayload,\n closePopupWindow,\n options.appSessionKey,\n ]);\n\n const resolveAndClearActiveRequest = useCallback((tokenResponse?: OAuthTokenResponse) => {\n const request = activeRequestRef.current;\n if (!request) {\n dismissPopupState();\n return;\n }\n\n clearPollTimer(request);\n closePopupWindow(request);\n clearStoredCallbackPayload(request.state);\n activeRequestRef.current = null;\n\n request.resolve(tokenResponse);\n dismissPopupState(request.serverUrl);\n }, [clearPollTimer, clearStoredCallbackPayload, closePopupWindow, dismissPopupState]);\n\n const transitionActiveRequest = useCallback((\n phase: OAuthPopupPhase,\n errorMessage?: string | null,\n statusMessage?: string | null,\n ) => {\n const request = activeRequestRef.current;\n if (!request) {\n return;\n }\n\n clearPollTimer(request);\n closePopupWindow(request);\n request.handledCallback = false;\n\n if (mountedRef.current) {\n setPopupState(createPopupState(request, phase, statusMessage, errorMessage));\n }\n }, [clearPollTimer, closePopupWindow]);\n\n const setActivePopupPhase = useCallback((\n phase: OAuthPopupPhase,\n errorMessage?: string | null,\n statusMessage?: string | null,\n ) => {\n const request = activeRequestRef.current;\n if (!request) {\n return;\n }\n\n clearPollTimer(request);\n closePopupWindow(request);\n\n if (mountedRef.current) {\n setPopupState(createPopupState(request, phase, statusMessage, errorMessage));\n }\n }, [clearPollTimer, closePopupWindow]);\n\n const exchangeCodeForToken = useCallback(async (code: string) => {\n const request = activeRequestRef.current;\n if (!request) {\n return;\n }\n\n const effectiveAuthConfig = request.resolvedAuthConfig;\n const callbackUrl = getCallbackUrl(effectiveAuthConfig);\n const tokenUrl = effectiveAuthConfig.tokenEndpoint ?? effectiveAuthConfig.tokenUrl;\n\n if (!tokenUrl) {\n request.handledCallback = false;\n transitionActiveRequest('error', 'This MCP server is missing a token endpoint.');\n return;\n }\n\n if (mountedRef.current) {\n setPopupState(\n createPopupState(\n request,\n 'exchanging',\n 'Exchanging authorization code...',\n ),\n );\n }\n\n try {\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n code_verifier: request.codeVerifier,\n redirect_uri: callbackUrl,\n });\n\n if (effectiveAuthConfig.clientId) {\n body.set('client_id', effectiveAuthConfig.clientId);\n }\n\n if (effectiveAuthConfig.resource) {\n body.set('resource', effectiveAuthConfig.resource);\n }\n\n const response = await fetch(tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body,\n });\n\n if (response.ok) {\n const data = await response.json();\n if (data.access_token) {\n resolveAndClearActiveRequest({\n accessToken: data.access_token,\n refreshToken: data.refresh_token,\n expiresIn: data.expires_in,\n tokenType: data.token_type,\n resolvedAuthConfig: effectiveAuthConfig,\n });\n return;\n }\n }\n\n const errorMessage = await response.text().catch(() => 'Token exchange failed.');\n if (effectiveAuthConfig.clientMode === 'dcr') {\n clearStoredRegistration(\n buildRegistrationCacheKey(effectiveAuthConfig, callbackUrl, 'dcr'),\n );\n }\n request.handledCallback = false;\n transitionActiveRequest('error', errorMessage || 'Token exchange failed.');\n } catch {\n request.handledCallback = false;\n transitionActiveRequest('error', 'Token exchange failed. Please try again.');\n }\n }, [getCallbackUrl, resolveAndClearActiveRequest, transitionActiveRequest]);\n\n const handleAuthPayload = useCallback((payload: unknown) => {\n const request = activeRequestRef.current;\n if (!request || !payload || typeof payload !== 'object') {\n return;\n }\n\n const data = payload as Record<string, unknown>;\n const responseState = typeof data.state === 'string' ? data.state : '';\n if (!request.state || responseState !== request.state || request.handledCallback) {\n return;\n }\n\n request.handledCallback = true;\n clearPollTimer(request);\n clearStoredCallbackPayload(responseState);\n\n if (data.type === 'mcpstack-oauth-callback' && typeof data.token === 'string') {\n resolveAndClearActiveRequest({\n accessToken: data.token,\n resolvedAuthConfig: request.resolvedAuthConfig,\n });\n return;\n }\n\n if (data.type === 'mcpstack-oauth-callback' && typeof data.accessToken === 'string') {\n resolveAndClearActiveRequest({\n accessToken: data.accessToken,\n refreshToken: typeof data.refreshToken === 'string' ? data.refreshToken : undefined,\n expiresIn: typeof data.expiresIn === 'number' ? data.expiresIn : undefined,\n tokenType: typeof data.tokenType === 'string' ? data.tokenType : undefined,\n resolvedAuthConfig: request.resolvedAuthConfig,\n });\n return;\n }\n\n if (data.type === 'mcpstack-oauth-code' && typeof data.code === 'string') {\n void exchangeCodeForToken(data.code);\n return;\n }\n\n if (data.type === 'mcpstack-oauth-error' && typeof data.error === 'string') {\n const description =\n typeof data.errorDescription === 'string'\n ? data.errorDescription\n : typeof data.error_description === 'string'\n ? data.error_description\n : 'Sign in could not be completed.';\n setActivePopupPhase(\n data.error === 'access_denied' ? 'canceled' : 'error',\n description,\n );\n return;\n }\n\n request.handledCallback = false;\n }, [\n clearStoredCallbackPayload,\n exchangeCodeForToken,\n resolveAndClearActiveRequest,\n setActivePopupPhase,\n ]);\n\n const startOrRetryPopupAuth = useCallback(async () => {\n const request = activeRequestRef.current;\n if (!request) {\n return;\n }\n\n const width = 500;\n const height = 600;\n const left = window.screenX + (window.outerWidth - width) / 2;\n const top = window.screenY + (window.outerHeight - height) / 2;\n const popupWindow = window.open(\n 'about:blank',\n 'mcpstack-auth-popup',\n `popup=yes,width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`,\n );\n\n if (!popupWindow) {\n transitionActiveRequest(\n 'blocked',\n 'Your browser blocked the sign-in popup. Allow popups and try again.',\n );\n return;\n }\n\n request.popupWindow = popupWindow;\n request.popupWindow.focus?.();\n\n clearStoredCallbackPayload(request.state);\n clearPollTimer(request);\n\n request.codeVerifier = generateCodeVerifier();\n request.state = crypto.randomUUID();\n request.handledCallback = false;\n\n const popupContext = encodeURIComponent(JSON.stringify({\n openerOrigin: window.location.origin,\n expectedState: request.state,\n }));\n\n try {\n request.popupWindow.name = `mcpstack-auth:${popupContext}`;\n } catch {\n closePopupWindow(request);\n transitionActiveRequest(\n 'error',\n 'The sign-in popup could not be opened. Try again.',\n );\n return;\n }\n\n if (mountedRef.current) {\n setPopupState(\n createPopupState(request, 'preparing', 'Preparing secure sign in...'),\n );\n }\n\n let effectiveAuthConfig = request.authConfig;\n\n try {\n if (effectiveAuthConfig.authType === 'oauth2' && !effectiveAuthConfig.clientMode) {\n const registration = await resolveOAuthRegistration(effectiveAuthConfig, {\n callbackUrl: getCallbackUrl(effectiveAuthConfig),\n oauthClientMetadataUrl: optionsRef.current.oauthClientMetadataUrl,\n clientName: 'MCP Stack MCP Client',\n clientUri: window.location.origin,\n });\n effectiveAuthConfig = applyResolvedRegistration(effectiveAuthConfig, registration);\n }\n\n request.resolvedAuthConfig = effectiveAuthConfig;\n } catch (error) {\n closePopupWindow(request);\n transitionActiveRequest(\n 'error',\n error instanceof Error\n ? error.message\n : 'Failed to prepare OAuth sign in for this MCP server.',\n );\n return;\n }\n\n const callbackUrl = getCallbackUrl(effectiveAuthConfig);\n const loginUrl = effectiveAuthConfig.authorizationEndpoint ?? effectiveAuthConfig.loginUrl;\n if (!loginUrl) {\n closePopupWindow(request);\n transitionActiveRequest('error', 'This MCP server is missing an authorization endpoint.');\n return;\n }\n\n const codeVerifier = request.codeVerifier;\n\n let authUrl = '';\n\n if (effectiveAuthConfig.tokenEndpoint ?? effectiveAuthConfig.tokenUrl) {\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n const params = new URLSearchParams({\n response_type: 'code',\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n state: request.state,\n redirect_uri: callbackUrl,\n });\n if (effectiveAuthConfig.clientId) {\n params.set('client_id', effectiveAuthConfig.clientId);\n }\n if (effectiveAuthConfig.scopes?.length) {\n params.set('scope', effectiveAuthConfig.scopes.join(' '));\n }\n if (effectiveAuthConfig.resource) {\n params.set('resource', effectiveAuthConfig.resource);\n }\n if (request.userIdentity && isGatewayAuthorizeUrl(effectiveAuthConfig)) {\n const subject = normalizeOptionalValue(request.userIdentity.subject);\n const email = normalizeOptionalValue(request.userIdentity.email);\n const organizationId = normalizeOptionalValue(request.userIdentity.organizationId);\n const displayName = normalizeOptionalValue(request.userIdentity.displayName);\n\n if (subject) {\n params.set('mcpstack_host_subject', subject);\n }\n if (email) {\n params.set('mcpstack_host_email', email);\n }\n if (organizationId) {\n params.set('mcpstack_host_organization_id', organizationId);\n }\n if (displayName) {\n params.set('mcpstack_host_display_name', displayName);\n }\n params.set(\n 'mcpstack_mismatch_policy',\n 'block_with_switch',\n );\n }\n authUrl = `${loginUrl}${loginUrl.includes('?') ? '&' : '?'}${params.toString()}`;\n } else {\n const params = new URLSearchParams({\n state: request.state,\n redirect_uri: callbackUrl,\n mode: 'popup',\n });\n if (effectiveAuthConfig.clientId) {\n params.set('client_id', effectiveAuthConfig.clientId);\n }\n if (effectiveAuthConfig.resource) {\n params.set('resource', effectiveAuthConfig.resource);\n }\n authUrl = `${loginUrl}${loginUrl.includes('?') ? '&' : '?'}${params.toString()}`;\n }\n\n if (request.popupWindow.closed) {\n transitionActiveRequest(\n 'canceled',\n 'The sign-in window was closed before authentication completed.',\n );\n return;\n }\n\n try {\n request.popupWindow.location.replace(authUrl);\n } catch {\n closePopupWindow(request);\n transitionActiveRequest(\n 'error',\n 'The sign-in popup could not be opened. Try again.',\n );\n return;\n }\n request.popupWindow.focus?.();\n\n request.pollTimer = setInterval(() => {\n const activeRequest = activeRequestRef.current;\n if (!activeRequest || activeRequest !== request) {\n clearPollTimer(request);\n return;\n }\n\n if (request.popupWindow?.closed) {\n clearPollTimer(request);\n if (mountedRef.current) {\n setPopupState(\n createPopupState(\n request,\n 'canceled',\n null,\n 'The sign-in window was closed before authentication completed.',\n ),\n );\n }\n }\n }, 500);\n\n if (mountedRef.current) {\n setPopupState(\n createPopupState(\n request,\n 'waiting',\n 'Finish sign in in the popup window to connect your account.',\n ),\n );\n }\n }, [\n clearPollTimer,\n clearStoredCallbackPayload,\n closePopupWindow,\n getCallbackUrl,\n transitionActiveRequest,\n ]);\n\n const cancelPopupAuth = useCallback(() => {\n if (!activeRequestRef.current) {\n dismissPopupState();\n return;\n }\n\n resolveAndClearActiveRequest(undefined);\n }, [dismissPopupState, resolveAndClearActiveRequest]);\n\n const handleServerAuthStatus = useCallback((\n serverUrl: string,\n authStatus: 'connected' | 'needs_auth',\n ) => {\n if (authStatus !== 'connected') {\n return;\n }\n\n const request = activeRequestRef.current;\n if (request && request.serverUrl === serverUrl) {\n clearPollTimer(request);\n closePopupWindow(request);\n clearStoredCallbackPayload(request.state);\n activeRequestRef.current = null;\n }\n\n dismissPopupState(serverUrl);\n }, [clearPollTimer, clearStoredCallbackPayload, closePopupWindow, dismissPopupState]);\n\n const requestAuth = useCallback((\n serverUrl: string,\n authConfig: McpServerAuthConfig,\n ) => {\n const activeRequest = activeRequestRef.current;\n if (activeRequest) {\n if (activeRequest.serverUrl === serverUrl) {\n return activeRequest.promise;\n }\n\n if (mountedRef.current) {\n setPopupState((currentState) => (\n currentState\n ? {\n ...currentState,\n errorMessage: 'Another MCP server sign-in is already in progress. Finish or cancel it first.',\n }\n : createPopupState(\n activeRequest,\n 'error',\n null,\n 'Another MCP server sign-in is already in progress. Finish or cancel it first.',\n )\n ));\n }\n\n return Promise.reject(\n new Error('Another MCP server sign-in is already in progress. Finish or cancel it first.'),\n );\n }\n\n const serverName = optionsRef.current.resolveServerName(serverUrl);\n\n let resolvePromise: (tokenResponse: OAuthTokenResponse | undefined) => void = () => {};\n const promise = new Promise<OAuthTokenResponse | undefined>((resolve) => {\n resolvePromise = resolve;\n });\n\n const request: ActivePopupAuthRequest = {\n serverName,\n serverUrl,\n authConfig,\n resolvedAuthConfig: authConfig,\n promise,\n resolve: resolvePromise,\n state: '',\n codeVerifier: '',\n handledCallback: false,\n popupWindow: null,\n userIdentity: optionsRef.current.userIdentity,\n hostIdentityLabel: formatUserIdentityLabel(optionsRef.current.userIdentity),\n };\n\n activeRequestRef.current = request;\n setPopupState(createPopupState(request, 'prompt'));\n\n return promise;\n }, []);\n\n useEffect(() => {\n const handleMessage = (event: MessageEvent) => {\n const request = activeRequestRef.current;\n if (!request) {\n return;\n }\n\n try {\n const callbackOrigin = new URL(getCallbackUrl(request.resolvedAuthConfig)).origin;\n if (event.origin !== callbackOrigin) {\n return;\n }\n } catch {\n return;\n }\n\n handleAuthPayload(event.data);\n };\n\n const handleStorage = (event: StorageEvent) => {\n if (!event.key?.startsWith(OAUTH_CALLBACK_STORAGE_PREFIX) || !event.newValue) {\n return;\n }\n\n try {\n const parsed = JSON.parse(event.newValue) as Record<string, unknown>;\n handleAuthPayload(parsed);\n } catch {\n // Ignore malformed callback payloads.\n }\n };\n\n const channel =\n typeof BroadcastChannel !== 'undefined'\n ? new BroadcastChannel(OAUTH_CALLBACK_CHANNEL_NAME)\n : null;\n\n if (channel) {\n channel.onmessage = (event) => {\n handleAuthPayload(event.data);\n };\n }\n\n window.addEventListener('message', handleMessage);\n window.addEventListener('storage', handleStorage);\n\n return () => {\n window.removeEventListener('message', handleMessage);\n window.removeEventListener('storage', handleStorage);\n channel?.close();\n };\n }, [getCallbackUrl, handleAuthPayload]);\n\n useEffect(() => () => {\n mountedRef.current = false;\n const request = activeRequestRef.current;\n if (!request) {\n return;\n }\n\n clearPollTimer(request);\n closePopupWindow(request);\n clearStoredCallbackPayload(request.state);\n activeRequestRef.current = null;\n request.resolve(undefined);\n }, [clearPollTimer, clearStoredCallbackPayload, closePopupWindow]);\n\n return useMemo(() => ({\n popupState,\n requestAuth,\n startOrRetryPopupAuth,\n cancelPopupAuth,\n handleServerAuthStatus,\n }), [\n cancelPopupAuth,\n handleServerAuthStatus,\n popupState,\n requestAuth,\n startOrRetryPopupAuth,\n ]);\n}\n"],"mappings":"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","names":["import_react","clientToolSchemas","sessionId","notifyHeaders","result","import_react","normalizeOptionalValue","isGatewayAuthorizeUrl"]}