@waniwani/sdk 0.11.13 → 0.11.15

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.
@@ -3,6 +3,10 @@ export { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import { z } from 'zod';
4
4
  import { ZodRawShapeCompat, ShapeOutput } from '@modelcontextprotocol/sdk/server/zod-compat.js';
5
5
  export { ZodRawShapeCompat } from '@modelcontextprotocol/sdk/server/zod-compat.js';
6
+ import * as react_jsx_runtime from 'react/jsx-runtime';
7
+ import { ContentBlock, CallToolResult } from '@modelcontextprotocol/sdk/types.js';
8
+ import React$1, { ReactNode, SetStateAction } from 'react';
9
+ import { UIMessage } from 'ai';
6
10
 
7
11
  type WidgetCSP = {
8
12
  /** Domains permitted for fetch/XHR network requests */
@@ -210,6 +214,58 @@ interface LegacyTrackEvent extends TrackingContext {
210
214
  * Public track input accepted by `client.track()`.
211
215
  */
212
216
  type TrackInput = TrackEvent | LegacyTrackEvent;
217
+ interface TrackingConfig {
218
+ /** Events API V2 endpoint path. */
219
+ endpointPath?: string;
220
+ /** Periodic flush interval for buffered events. */
221
+ flushIntervalMs?: number;
222
+ /** Max events per HTTP batch send. */
223
+ maxBatchSize?: number;
224
+ /** Max in-memory buffer size before oldest items are dropped. */
225
+ maxBufferSize?: number;
226
+ /** Number of retries for retryable failures. */
227
+ maxRetries?: number;
228
+ /** Retry backoff base delay. */
229
+ retryBaseDelayMs?: number;
230
+ /** Retry backoff max delay. */
231
+ retryMaxDelayMs?: number;
232
+ /** Default shutdown timeout when none is provided. */
233
+ shutdownTimeoutMs?: number;
234
+ }
235
+ interface TrackingShutdownOptions {
236
+ timeoutMs?: number;
237
+ }
238
+ interface TrackingShutdownResult {
239
+ timedOut: boolean;
240
+ pendingEvents: number;
241
+ }
242
+ /**
243
+ * Tracking module methods for WaniWaniClient.
244
+ */
245
+ interface TrackingClient {
246
+ /**
247
+ * Send a one-shot identify event for a user.
248
+ * userId can be any string: an email, an internal ID, etc.
249
+ */
250
+ identify: (userId: string, properties?: Record<string, unknown>, meta?: Record<string, unknown>) => Promise<{
251
+ eventId: string;
252
+ }>;
253
+ /**
254
+ * Track an event using modern or legacy input shape.
255
+ * Returns a deterministic event id immediately after enqueue.
256
+ */
257
+ track: (event: TrackInput) => Promise<{
258
+ eventId: string;
259
+ }>;
260
+ /**
261
+ * Flush all currently buffered events.
262
+ */
263
+ flush: () => Promise<void>;
264
+ /**
265
+ * Flush and stop the transport.
266
+ */
267
+ shutdown: (options?: TrackingShutdownOptions) => Promise<TrackingShutdownResult>;
268
+ }
213
269
 
214
270
  /**
215
271
  * A request-scoped WaniWani client with meta pre-attached.
@@ -332,4 +388,737 @@ declare function createTool<TInput extends z.ZodRawShape>(config: ToolConfig<TIn
332
388
  */
333
389
  declare function registerTools(server: McpServer, tools: RegisteredTool[]): Promise<void>;
334
390
 
335
- export { type RegisteredResource, type RegisteredTool, type ResourceConfig, type ToolConfig, type ToolHandler, type ToolHandlerContext, type ToolToolCallback, type WidgetCSP, createResource, createTool, registerTools };
391
+ /**
392
+ * Initializes & patches Next.js functionality so an app can run as a
393
+ * widget inside a cross-origin iframe. Used by every MCP widget host —
394
+ * ChatGPT's sandbox, the embed's `/api/mcp/chat/resource` proxy, and any
395
+ * future host that renders the widget on a domain other than its own
396
+ * `baseUrl`.
397
+ *
398
+ * See `applyIframePatches` for the patch behavior.
399
+ *
400
+ * More background on the ChatGPT case:
401
+ * https://vercel.com/blog/running-next-js-inside-chatgpt-a-deep-dive-into-native-app-integration
402
+ *
403
+ * @deprecated Legacy MCP-widget-in-host stack (used with `createResource`/`createTool`).
404
+ * Preserved for back-compat; will move to `@waniwani/sdk/legacy/react` in a future minor
405
+ * release.
406
+ */
407
+ declare function InitializeNextJsInIframe({ baseUrl, passthroughOrigins, }: {
408
+ baseUrl: string;
409
+ /**
410
+ * Origins whose fetches should skip the relative same-origin → baseUrl
411
+ * rewrite. Only needed for relative-URL calls that resolve to an
412
+ * origin you do not want forwarded to `baseUrl` — absolute URLs are
413
+ * never rewritten regardless of this list.
414
+ */
415
+ passthroughOrigins?: string[];
416
+ }): react_jsx_runtime.JSX.Element;
417
+
418
+ interface DevControlsProps {
419
+ defaultProps?: Record<string, unknown>;
420
+ widgetPaths?: string[];
421
+ }
422
+ /**
423
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
424
+ * `@waniwani/sdk/legacy/react` in a future minor release.
425
+ */
426
+ declare function DevModeProvider({ defaultProps, widgetPaths, children, }: DevControlsProps & {
427
+ children: React.ReactNode;
428
+ }): react_jsx_runtime.JSX.Element | null;
429
+
430
+ /**
431
+ * Source: https://github.com/openai/openai-apps-sdk-examples/tree/main/src
432
+ */
433
+ type OpenAIGlobals<ToolInput = UnknownObject, ToolOutput = UnknownObject, ToolResponseMetadata = UnknownObject, WidgetState = UnknownObject> = {
434
+ theme: Theme;
435
+ userAgent: UserAgent;
436
+ locale: string;
437
+ maxHeight: number;
438
+ displayMode: DisplayMode;
439
+ safeArea: SafeArea;
440
+ toolInput: ToolInput;
441
+ toolOutput: ToolOutput | null;
442
+ toolResponseMetadata: ToolResponseMetadata | null;
443
+ widgetState: WidgetState | null;
444
+ setWidgetState: (state: WidgetState) => Promise<void>;
445
+ };
446
+ type API = {
447
+ callTool: CallTool;
448
+ sendFollowUpMessage: (args: {
449
+ prompt: string;
450
+ }) => Promise<void>;
451
+ openExternal(payload: {
452
+ href: string;
453
+ }): void;
454
+ requestDisplayMode: RequestDisplayMode;
455
+ };
456
+ type UnknownObject = Record<string, unknown>;
457
+ type Theme = "light" | "dark";
458
+ type SafeAreaInsets = {
459
+ top: number;
460
+ bottom: number;
461
+ left: number;
462
+ right: number;
463
+ };
464
+ type SafeArea = {
465
+ insets: SafeAreaInsets;
466
+ };
467
+ type DeviceType = "mobile" | "tablet" | "desktop" | "unknown";
468
+ type UserAgent = {
469
+ device: {
470
+ type: DeviceType;
471
+ };
472
+ capabilities: {
473
+ hover: boolean;
474
+ touch: boolean;
475
+ };
476
+ };
477
+ /** Display mode */
478
+ type DisplayMode = "pip" | "inline" | "fullscreen";
479
+ type RequestDisplayMode = (args: {
480
+ mode: DisplayMode;
481
+ }) => Promise<{
482
+ /**
483
+ * The granted display mode. The host may reject the request.
484
+ * For mobile, PiP is always coerced to fullscreen.
485
+ */
486
+ mode: DisplayMode;
487
+ }>;
488
+ type CallToolResponse = {
489
+ result: string;
490
+ };
491
+ /** Calling APIs */
492
+ type CallTool = (name: string, args: Record<string, unknown>) => Promise<CallToolResponse>;
493
+ /** Extra events */
494
+ declare const SET_GLOBALS_EVENT_TYPE = "openai:set_globals";
495
+ declare class SetGlobalsEvent extends CustomEvent<{
496
+ globals: Partial<OpenAIGlobals>;
497
+ }> {
498
+ constructor(detail: {
499
+ globals: Partial<OpenAIGlobals>;
500
+ });
501
+ }
502
+ /**
503
+ * Global oai object injected by the web sandbox for communicating with chatgpt host page.
504
+ */
505
+ declare global {
506
+ interface Window {
507
+ openai: API & OpenAIGlobals;
508
+ innerBaseUrl: string;
509
+ }
510
+ interface WindowEventMap {
511
+ [SET_GLOBALS_EVENT_TYPE]: SetGlobalsEvent;
512
+ }
513
+ }
514
+
515
+ declare let mockState: Omit<OpenAIGlobals, "setWidgetState">;
516
+ declare function initializeMockOpenAI(initialToolOutput?: Record<string, unknown>): void;
517
+ declare function updateMockGlobal<K extends keyof OpenAIGlobals>(key: K, value: OpenAIGlobals[K]): void;
518
+ declare function getMockState(): typeof mockState;
519
+ declare function updateMockToolOutput(props: Record<string, unknown>): void;
520
+ declare function updateMockDisplayMode(mode: DisplayMode): void;
521
+ declare function updateMockTheme(theme: Theme): void;
522
+
523
+ type ModelContextContentBlock = ContentBlock;
524
+ type ModelContextUpdate = {
525
+ content?: ModelContextContentBlock[];
526
+ structuredContent?: Record<string, unknown>;
527
+ };
528
+
529
+ /**
530
+ * Result from calling a tool
531
+ */
532
+ type ToolCallResult = CallToolResult;
533
+ /**
534
+ * Tool result notification (what the host pushes to the widget)
535
+ */
536
+ type ToolResult = CallToolResult;
537
+ /**
538
+ * Host context - all values available from the host.
539
+ */
540
+ type HostContext = {
541
+ theme: Theme;
542
+ locale: string;
543
+ displayMode: DisplayMode;
544
+ maxHeight: number | null;
545
+ safeArea: SafeArea | null;
546
+ toolOutput: UnknownObject | null;
547
+ toolResponseMetadata: UnknownObject | null;
548
+ widgetState: UnknownObject | null;
549
+ };
550
+ /**
551
+ * Unified widget client interface that works on both OpenAI and MCP Apps.
552
+ *
553
+ * Platform-specific behavior:
554
+ * - Display mode: OpenAI-only. MCP Apps returns "inline" and requestDisplayMode is a no-op.
555
+ * - Follow-up messages: Unified API, different underlying implementations.
556
+ */
557
+ interface UnifiedWidgetClient {
558
+ /**
559
+ * Connect to the host. Must be called before using other methods.
560
+ * On OpenAI, this is a no-op (already connected via window.openai).
561
+ * On MCP Apps, this establishes the postMessage connection.
562
+ */
563
+ connect(): Promise<void>;
564
+ /**
565
+ * Close the connection to the host and clean up resources.
566
+ * On OpenAI, this is a no-op.
567
+ * On MCP Apps, this closes the transport and removes event listeners.
568
+ */
569
+ close(): Promise<void>;
570
+ /**
571
+ * Get the tool output (structured content returned by the tool handler).
572
+ * This is the main data source for widget rendering.
573
+ */
574
+ getToolOutput<T = Record<string, unknown>>(): T | null;
575
+ /**
576
+ * Register a callback for when tool results are received.
577
+ * On OpenAI, this subscribes to toolOutput changes.
578
+ * On MCP Apps, this sets app.ontoolresult.
579
+ */
580
+ onToolResult(callback: (result: ToolResult) => void): () => void;
581
+ /**
582
+ * Call another tool on the server.
583
+ */
584
+ callTool(name: string, args: Record<string, unknown>): Promise<ToolCallResult>;
585
+ /**
586
+ * Open an external URL.
587
+ * On OpenAI: openai.openExternal({ href })
588
+ * On MCP Apps: app.sendOpenLink(url)
589
+ */
590
+ openExternal(url: string): void;
591
+ /**
592
+ * Send a follow-up message to the AI.
593
+ * On OpenAI: openai.sendFollowUpMessage({ prompt })
594
+ * On MCP Apps: app.sendMessages([{ role: 'user', content: { type: 'text', text: prompt } }])
595
+ */
596
+ sendFollowUp(prompt: string): void | Promise<void>;
597
+ /**
598
+ * Update hidden model context for the next assistant turn.
599
+ * On MCP Apps this uses the standard `ui/update-model-context` request.
600
+ * On other hosts this may fall back to best-effort behavior.
601
+ */
602
+ updateModelContext(context: ModelContextUpdate): Promise<void> | void;
603
+ /**
604
+ * Get the current theme.
605
+ */
606
+ getTheme(): Theme;
607
+ /**
608
+ * Subscribe to theme changes.
609
+ */
610
+ onThemeChange(callback: (theme: Theme) => void): () => void;
611
+ /**
612
+ * Get the current locale.
613
+ */
614
+ getLocale(): string;
615
+ /**
616
+ * Get the current display mode.
617
+ * OpenAI-only: returns "pip" | "inline" | "fullscreen"
618
+ * MCP Apps: always returns "inline"
619
+ */
620
+ getDisplayMode(): DisplayMode;
621
+ /**
622
+ * Request a display mode change.
623
+ * OpenAI-only: requests the mode from the host.
624
+ * MCP Apps: no-op (returns current mode).
625
+ */
626
+ requestDisplayMode(mode: DisplayMode): Promise<DisplayMode>;
627
+ /**
628
+ * Subscribe to display mode changes.
629
+ * OpenAI-only: subscribes to displayMode changes.
630
+ * MCP Apps: callback is never called.
631
+ */
632
+ onDisplayModeChange(callback: (mode: DisplayMode) => void): () => void;
633
+ /**
634
+ * Get the safe area insets.
635
+ * OpenAI-only: returns insets from window.openai.safeArea.
636
+ * MCP Apps: returns null.
637
+ */
638
+ getSafeArea(): SafeArea | null;
639
+ /**
640
+ * Subscribe to safe area changes.
641
+ * OpenAI-only: subscribes to safeArea changes.
642
+ * MCP Apps: callback is never called.
643
+ */
644
+ onSafeAreaChange(callback: (safeArea: SafeArea | null) => void): () => void;
645
+ /**
646
+ * Get the max height constraint.
647
+ * OpenAI-only: returns maxHeight from window.openai.maxHeight.
648
+ * MCP Apps: returns null.
649
+ */
650
+ getMaxHeight(): number | null;
651
+ /**
652
+ * Subscribe to max height changes.
653
+ * OpenAI-only: subscribes to maxHeight changes.
654
+ * MCP Apps: callback is never called.
655
+ */
656
+ onMaxHeightChange(callback: (maxHeight: number | null) => void): () => void;
657
+ /**
658
+ * Get the tool response metadata.
659
+ * OpenAI: returns metadata from window.openai.toolResponseMetadata.
660
+ * MCP Apps: returns `_meta` from the latest `ui/notifications/tool-result`, if provided by host.
661
+ */
662
+ getToolResponseMetadata(): UnknownObject | null;
663
+ /**
664
+ * Subscribe to tool response metadata changes.
665
+ * OpenAI: subscribes to toolResponseMetadata changes.
666
+ * MCP Apps: fires when tool result `_meta` changes.
667
+ */
668
+ onToolResponseMetadataChange(callback: (metadata: UnknownObject | null) => void): () => void;
669
+ /**
670
+ * Get the widget state.
671
+ * OpenAI-only: returns state from window.openai.widgetState.
672
+ * MCP Apps: returns null.
673
+ */
674
+ getWidgetState(): UnknownObject | null;
675
+ /**
676
+ * Subscribe to widget state changes.
677
+ * OpenAI-only: subscribes to widgetState changes.
678
+ * MCP Apps: callback is never called.
679
+ */
680
+ onWidgetStateChange(callback: (state: UnknownObject | null) => void): () => void;
681
+ }
682
+
683
+ /**
684
+ * Get a function to call other tools.
685
+ * Works on both OpenAI widgets and MCP Apps.
686
+ *
687
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
688
+ * `@waniwani/sdk/legacy/react` in a future minor release.
689
+ * @returns A function to call tools with their name and arguments
690
+ */
691
+ declare function useCallTool(): (name: string, args: Record<string, unknown>) => Promise<ToolCallResult>;
692
+
693
+ /**
694
+ * Get the current display mode.
695
+ * Works on both OpenAI widgets and MCP Apps.
696
+ *
697
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
698
+ * `@waniwani/sdk/legacy/react` in a future minor release.
699
+ * @returns The current display mode ("pip" | "inline" | "fullscreen")
700
+ */
701
+ declare function useDisplayMode(): DisplayMode;
702
+
703
+ /** Return type of the useFlowAction hook */
704
+ type FlowActionResult<T> = {
705
+ /** Current widget data from structuredContent. */
706
+ data: T | null;
707
+ };
708
+ /**
709
+ * Hook for reading flow widget data from structuredContent.
710
+ * Lightweight wrapper over `useToolOutput` — will be extended
711
+ * with flow-specific features in the future.
712
+ *
713
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
714
+ * `@waniwani/sdk/legacy/react` in a future minor release.
715
+ *
716
+ * @example
717
+ * ```tsx
718
+ * const { data } = useFlowAction<{ plans: string[] }>();
719
+ * if (!data) return null;
720
+ * return <PricingTable plans={data.plans} />;
721
+ * ```
722
+ */
723
+ declare function useFlowAction<T extends Record<string, unknown>>(): FlowActionResult<T>;
724
+
725
+ /**
726
+ * Check if running in ChatGPT app (OpenAI-only).
727
+ * Returns false on MCP Apps.
728
+ *
729
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
730
+ * `@waniwani/sdk/legacy/react` in a future minor release.
731
+ * @returns Whether the widget is running in ChatGPT app
732
+ */
733
+ declare function useIsChatGptApp(): boolean;
734
+
735
+ /**
736
+ * Get the current locale.
737
+ * Works on both OpenAI widgets and MCP Apps.
738
+ *
739
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
740
+ * `@waniwani/sdk/legacy/react` in a future minor release.
741
+ * @returns The current locale string (e.g., "en-US")
742
+ */
743
+ declare function useLocale(): string;
744
+
745
+ /**
746
+ * Get the maximum height available for the widget (OpenAI-only).
747
+ * Useful for responsive layouts that need to adapt to container constraints.
748
+ * Returns null on MCP Apps.
749
+ *
750
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
751
+ * `@waniwani/sdk/legacy/react` in a future minor release.
752
+ * @returns The maximum height in pixels, or null if not available
753
+ */
754
+ declare function useMaxHeight(): number | null;
755
+
756
+ /**
757
+ * Get a function to open external URLs.
758
+ * Works on both OpenAI widgets and MCP Apps.
759
+ *
760
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
761
+ * `@waniwani/sdk/legacy/react` in a future minor release.
762
+ * @returns A function that opens external URLs
763
+ */
764
+ declare function useOpenExternal(): (url: string) => void;
765
+
766
+ /**
767
+ * Get a function to request display mode changes.
768
+ * On MCP Apps, this may be a no-op depending on host support.
769
+ *
770
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
771
+ * `@waniwani/sdk/legacy/react` in a future minor release.
772
+ * @returns A function to request a specific display mode
773
+ */
774
+ declare function useRequestDisplayMode(): (mode: DisplayMode) => Promise<DisplayMode>;
775
+
776
+ /**
777
+ * Get safe area insets (OpenAI-only).
778
+ * Useful for ensuring UI elements don't get hidden behind the chat input.
779
+ * Returns null on MCP Apps.
780
+ *
781
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
782
+ * `@waniwani/sdk/legacy/react` in a future minor release.
783
+ * @returns The safe area insets, or null if not available
784
+ */
785
+ declare function useSafeArea(): SafeArea | null;
786
+
787
+ interface SendFollowUpOptions {
788
+ modelContext?: ModelContextUpdate | null;
789
+ }
790
+ /**
791
+ * Get a function to send follow-up messages to the AI.
792
+ * Works on both OpenAI widgets and MCP Apps.
793
+ *
794
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
795
+ * `@waniwani/sdk/legacy/react` in a future minor release.
796
+ * @returns A function that sends a follow-up message
797
+ */
798
+ declare function useSendFollowUp(): (prompt: string, options?: SendFollowUpOptions) => void;
799
+
800
+ /**
801
+ * Get the current theme.
802
+ * Works on both OpenAI widgets and MCP Apps.
803
+ *
804
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
805
+ * `@waniwani/sdk/legacy/react` in a future minor release.
806
+ * @returns The current theme ("light" | "dark")
807
+ */
808
+ declare function useTheme(): Theme;
809
+
810
+ /**
811
+ * Get the tool output (structured content returned by the tool handler).
812
+ * Works on both OpenAI widgets and MCP Apps.
813
+ *
814
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
815
+ * `@waniwani/sdk/legacy/react` in a future minor release.
816
+ * @returns The tool output or null
817
+ */
818
+ declare function useToolOutput<T extends Record<string, unknown>>(): T | null;
819
+
820
+ /**
821
+ * Get tool response metadata.
822
+ * Contains host/tool metadata (for example identifiers like
823
+ * `openai/widgetSessionId` and custom tool `_meta` fields).
824
+ * Returns null when the host does not provide metadata.
825
+ *
826
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
827
+ * `@waniwani/sdk/legacy/react` in a future minor release.
828
+ * @returns The tool response metadata object or null if not available
829
+ */
830
+ declare function useToolResponseMetadata(): UnknownObject | null;
831
+
832
+ /**
833
+ * Get a function to update hidden model context for the next assistant turn.
834
+ * Uses the MCP Apps `ui/update-model-context` request when available.
835
+ *
836
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
837
+ * `@waniwani/sdk/legacy/react` in a future minor release.
838
+ */
839
+ declare function useUpdateModelContext(): (context: ModelContextUpdate) => Promise<void>;
840
+
841
+ /**
842
+ * Provider props
843
+ */
844
+ interface WidgetProviderProps {
845
+ children: ReactNode;
846
+ /** Optional loading component while connecting */
847
+ loading?: ReactNode;
848
+ /** Optional error component */
849
+ onError?: (error: Error) => ReactNode;
850
+ }
851
+ /**
852
+ * Provider component that initializes the correct widget client based on platform.
853
+ * Wrap your widget component with this provider.
854
+ *
855
+ * @deprecated Part of the legacy MCP-widget-in-host stack (used with `createResource` /
856
+ * `createTool`). Preserved for back-compat; will move to `@waniwani/sdk/legacy/react` in
857
+ * a future minor release. For new code, use `createFlow` from `@waniwani/sdk/mcp` and
858
+ * `useWaniwani` from `@waniwani/sdk/mcp/react`.
859
+ *
860
+ * @example
861
+ * ```tsx
862
+ * function App() {
863
+ * return (
864
+ * <WidgetProvider loading={<Spinner />}>
865
+ * <MyWidget />
866
+ * </WidgetProvider>
867
+ * );
868
+ * }
869
+ * ```
870
+ */
871
+ declare function WidgetProvider({ children, loading, onError, }: WidgetProviderProps): React$1.FunctionComponentElement<React$1.FragmentProps> | React$1.FunctionComponentElement<React$1.ProviderProps<UnifiedWidgetClient | null>>;
872
+ /**
873
+ * Keys that can be selected from the widget client.
874
+ */
875
+ type WidgetKey = "toolOutput" | "theme" | "displayMode" | "locale" | "safeArea" | "maxHeight" | "toolResponseMetadata" | "widgetState";
876
+ /**
877
+ * Value types for each widget key.
878
+ */
879
+ type WidgetKeyValues = {
880
+ toolOutput: Record<string, unknown> | null;
881
+ theme: Theme;
882
+ displayMode: DisplayMode;
883
+ locale: string;
884
+ safeArea: SafeArea | null;
885
+ maxHeight: number | null;
886
+ toolResponseMetadata: UnknownObject | null;
887
+ widgetState: UnknownObject | null;
888
+ };
889
+ /**
890
+ * Get the unified widget client instance.
891
+ * Must be used within a WidgetProvider.
892
+ *
893
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
894
+ * `@waniwani/sdk/legacy/react` in a future minor release.
895
+ *
896
+ * @example
897
+ * ```tsx
898
+ * // Full client for actions
899
+ * const client = useWidgetClient();
900
+ * client.callTool("foo", {});
901
+ *
902
+ * // Key selector for reactive values
903
+ * const toolOutput = useWidgetClient("toolOutput");
904
+ * const theme = useWidgetClient("theme");
905
+ * ```
906
+ */
907
+ declare function useWidgetClient(): UnifiedWidgetClient;
908
+ declare function useWidgetClient<K extends WidgetKey>(key: K): WidgetKeyValues[K];
909
+
910
+ /**
911
+ * Widget state that persists across widget lifecycles (OpenAI-only).
912
+ * State is synchronized with the ChatGPT parent window and survives widget minimize/restore.
913
+ * On MCP Apps, returns [null, no-op].
914
+ *
915
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
916
+ * `@waniwani/sdk/legacy/react` in a future minor release.
917
+ * @param defaultState - Initial state value or function to compute it
918
+ * @returns A tuple of [state, setState] similar to useState
919
+ */
920
+ declare function useWidgetState<T extends UnknownObject>(defaultState?: T | (() => T | null) | null): readonly [T | null, (state: SetStateAction<T | null>) => void];
921
+
922
+ /**
923
+ * Default loading fallback for legacy MCP widgets.
924
+ *
925
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
926
+ * `@waniwani/sdk/legacy/react` in a future minor release.
927
+ */
928
+ declare const LoadingWidget: () => react_jsx_runtime.JSX.Element;
929
+
930
+ /**
931
+ * Widget platform types
932
+ */
933
+ type WidgetPlatform = "openai" | "mcp-apps";
934
+ /**
935
+ * Detects which platform the widget is running on.
936
+ *
937
+ * OpenAI injects a global `window.openai` object.
938
+ * MCP Apps runs in a sandboxed iframe and uses postMessage.
939
+ *
940
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
941
+ * `@waniwani/sdk/legacy/react` in a future minor release.
942
+ */
943
+ declare function detectPlatform(): WidgetPlatform;
944
+ /**
945
+ * Check if running on OpenAI platform.
946
+ *
947
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
948
+ * `@waniwani/sdk/legacy/react` in a future minor release.
949
+ */
950
+ declare function isOpenAI(): boolean;
951
+ /**
952
+ * Check if running on MCP Apps platform.
953
+ *
954
+ * @deprecated Legacy MCP-widget-in-host stack. Preserved for back-compat; will move to
955
+ * `@waniwani/sdk/legacy/react` in a future minor release.
956
+ */
957
+ declare function isMCPApps(): boolean;
958
+
959
+ /**
960
+ * WaniWani SDK Client
961
+ *
962
+ * Extends with each module:
963
+ * - TrackingClient: track(), flush(), shutdown()
964
+ *
965
+ * Pass this client to framework adapters:
966
+ * - `toNextJsHandler(wani, { ... })` for Next.js route handlers
967
+ */
968
+ interface WaniWaniClient extends TrackingClient {
969
+ /** @internal Resolved config — used by framework adapters */
970
+ readonly _config: InternalConfig;
971
+ /** Knowledge base client for ingestion, search, and source listing */
972
+ readonly kb: KbClient;
973
+ }
974
+ interface InternalConfig {
975
+ apiUrl: string;
976
+ apiKey: string | undefined;
977
+ tracking: Required<TrackingConfig>;
978
+ }
979
+
980
+ /**
981
+ * Server-side geolocation extracted from platform headers (Vercel, Cloudflare).
982
+ * All fields are optional — in local dev, no headers are present.
983
+ */
984
+ interface GeoLocation {
985
+ city?: string;
986
+ country?: string;
987
+ countryRegion?: string;
988
+ latitude?: string;
989
+ longitude?: string;
990
+ timezone?: string;
991
+ ip?: string;
992
+ }
993
+
994
+ /** Client-side visitor context sent in the request body */
995
+ interface ClientVisitorContext {
996
+ timezone: string;
997
+ language: string;
998
+ languages: string[];
999
+ deviceType: "mobile" | "tablet" | "desktop";
1000
+ referrer: string;
1001
+ visitorId: string;
1002
+ }
1003
+ /** Combined visitor context: server geo + client context */
1004
+ interface VisitorMeta {
1005
+ geo: GeoLocation;
1006
+ client: ClientVisitorContext | null;
1007
+ }
1008
+ interface BeforeRequestContext {
1009
+ /** The conversation messages from the client */
1010
+ messages: UIMessage[];
1011
+ /** Session identifier for conversation continuity */
1012
+ sessionId?: string;
1013
+ /** Hidden widget-provided model context for the next assistant turn */
1014
+ modelContext?: ModelContextUpdate;
1015
+ /** The original HTTP Request object */
1016
+ request: Request;
1017
+ /** Server-extracted geo location + client-provided visitor context */
1018
+ visitor: VisitorMeta;
1019
+ }
1020
+ type BeforeRequestResult = {
1021
+ /** Override messages (e.g., filtered, augmented) */
1022
+ messages?: UIMessage[];
1023
+ /** Override the system prompt for this request */
1024
+ systemPrompt?: string;
1025
+ /** Override sessionId */
1026
+ sessionId?: string;
1027
+ /** Override hidden widget-provided model context */
1028
+ modelContext?: ModelContextUpdate;
1029
+ };
1030
+ interface WebSearchConfig {
1031
+ /** Restrict web search results to these domains */
1032
+ includeDomains?: string[];
1033
+ /** Exclude these domains from web search results */
1034
+ excludeDomains?: string[];
1035
+ }
1036
+ interface ChatOptions {
1037
+ /**
1038
+ * System prompt for the assistant.
1039
+ * Can be overridden per-request via `beforeRequest`.
1040
+ */
1041
+ systemPrompt?: string;
1042
+ /**
1043
+ * Maximum number of tool call steps. Defaults to 5.
1044
+ */
1045
+ maxSteps?: number;
1046
+ /**
1047
+ * Hook called before each request is forwarded to the WaniWani API.
1048
+ * - Return void to use defaults.
1049
+ * - Return an object to override messages, systemPrompt, or sessionId.
1050
+ * - Throw to reject the request (the error message is returned as JSON).
1051
+ */
1052
+ beforeRequest?: (context: BeforeRequestContext) => Promise<BeforeRequestResult | undefined> | BeforeRequestResult | undefined;
1053
+ /**
1054
+ * Override the MCP server URL directly, bypassing config resolution.
1055
+ * Useful for development/testing when pointing to a local MCP server.
1056
+ */
1057
+ mcpServerUrl?: string;
1058
+ /**
1059
+ * Enable web search as an additional tool alongside MCP tools.
1060
+ * Pass `true` to enable with defaults, or a config object to restrict domains.
1061
+ */
1062
+ webSearch?: boolean | WebSearchConfig;
1063
+ }
1064
+
1065
+ interface NextJsHandlerOptions {
1066
+ /** Chat handler configuration */
1067
+ chat?: ChatOptions;
1068
+ /**
1069
+ * Identifies this chatbar instance in analytics.
1070
+ * Use a descriptive name like "hamilton-support" or "pricing-page".
1071
+ * Shows up as `source` on tracked events.
1072
+ */
1073
+ source: string;
1074
+ /**
1075
+ * Enable verbose debug logging for all handler steps.
1076
+ * Logs request details, response codes, resolved URLs, and caught errors.
1077
+ */
1078
+ debug?: boolean;
1079
+ }
1080
+ interface NextJsHandlerResult {
1081
+ /** GET handler: routes sub-paths (e.g. /resource for MCP widget content) */
1082
+ GET: (request: Request) => Promise<Response>;
1083
+ /** POST handler: proxies chat messages to the WaniWani API */
1084
+ POST: (request: Request) => Promise<Response>;
1085
+ /** PATCH handler: routes updates (e.g. /scenarios/:id) */
1086
+ PATCH: (request: Request) => Promise<Response>;
1087
+ /** OPTIONS handler: CORS preflight */
1088
+ OPTIONS: (request: Request) => Response;
1089
+ }
1090
+
1091
+ /**
1092
+ * Create Next.js route handlers from a WaniWani client.
1093
+ *
1094
+ * Returns `{ GET, POST }` for use with catch-all routes.
1095
+ * Mount at `app/api/waniwani/[[...path]]/route.ts`:
1096
+ *
1097
+ * - `POST /api/waniwani` → chat (proxied to WaniWani API)
1098
+ * - `GET /api/waniwani/resource?uri=…` → MCP resource content
1099
+ *
1100
+ * @deprecated The chat-server catch-all adapters are being phased out. The chat widget
1101
+ * will talk directly to `app.waniwani.ai` in a future release, removing the need for a
1102
+ * self-hosted BFF. This export is preserved for back-compat with existing customer MCPs
1103
+ * but is no longer documented; it will move to `@waniwani/sdk/legacy/next-js` in a future
1104
+ * minor release.
1105
+ *
1106
+ * @example
1107
+ * ```typescript
1108
+ * // app/api/waniwani/[[...path]]/route.ts
1109
+ * import { waniwani } from "@waniwani/sdk";
1110
+ * import { toNextJsHandler } from "@waniwani/sdk/next-js";
1111
+ *
1112
+ * const wani = waniwani();
1113
+ *
1114
+ * export const { GET, POST } = toNextJsHandler(wani, {
1115
+ * chat: {
1116
+ * systemPrompt: "You are a helpful assistant.",
1117
+ * mcpServerUrl: process.env.MCP_SERVER_URL!,
1118
+ * },
1119
+ * });
1120
+ * ```
1121
+ */
1122
+ declare function toNextJsHandler(client: WaniWaniClient, options: NextJsHandlerOptions): NextJsHandlerResult;
1123
+
1124
+ export { DevModeProvider, type DeviceType, type DisplayMode, type FlowActionResult, type HostContext, InitializeNextJsInIframe, LoadingWidget, type ModelContextContentBlock, type ModelContextUpdate, type NextJsHandlerOptions, type NextJsHandlerResult, type RegisteredResource, type RegisteredTool, type ResourceConfig, type SafeArea, type SafeAreaInsets, type SendFollowUpOptions, type Theme, type ToolCallResult, type ToolConfig, type ToolHandler, type ToolHandlerContext, type ToolResult, type ToolToolCallback, type UnifiedWidgetClient, type UnknownObject, type UserAgent, type WidgetCSP, type WidgetPlatform, WidgetProvider, createResource, createTool, detectPlatform, getMockState, initializeMockOpenAI, isMCPApps, isOpenAI, registerTools, toNextJsHandler, updateMockDisplayMode, updateMockGlobal, updateMockTheme, updateMockToolOutput, useCallTool, useDisplayMode, useFlowAction, useIsChatGptApp, useLocale, useMaxHeight, useOpenExternal, useRequestDisplayMode, useSafeArea, useSendFollowUp, useTheme, useToolOutput, useToolResponseMetadata, useUpdateModelContext, useWidgetClient, useWidgetState };