@assistant-ui/mcp-docs-server 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docs/organized/code-examples/waterfall.md +2 -2
- package/.docs/organized/code-examples/with-a2a.md +4 -3
- package/.docs/organized/code-examples/with-ag-ui.md +5 -4
- package/.docs/organized/code-examples/with-ai-sdk-v7.md +12 -11
- package/.docs/organized/code-examples/with-artifacts.md +10 -9
- package/.docs/organized/code-examples/with-assistant-transport.md +4 -3
- package/.docs/organized/code-examples/with-browser-extension.md +3 -3
- package/.docs/organized/code-examples/with-chain-of-thought.md +14 -12
- package/.docs/organized/code-examples/with-cloud-standalone.md +5 -5
- package/.docs/organized/code-examples/with-cloud.md +9 -8
- package/.docs/organized/code-examples/with-custom-thread-list.md +8 -7
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +12 -11
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +12 -11
- package/.docs/organized/code-examples/with-eve.md +5 -4
- package/.docs/organized/code-examples/with-expo.md +214 -31
- package/.docs/organized/code-examples/with-external-store.md +4 -3
- package/.docs/organized/code-examples/with-ffmpeg.md +9 -8
- package/.docs/organized/code-examples/with-generative-ui.md +13 -15
- package/.docs/organized/code-examples/with-google-adk.md +4 -3
- package/.docs/organized/code-examples/with-heat-graph.md +2 -2
- package/.docs/organized/code-examples/with-image-generation.md +7 -6
- package/.docs/organized/code-examples/with-interactables.md +9 -8
- package/.docs/organized/code-examples/with-langchain.md +6 -5
- package/.docs/organized/code-examples/with-langgraph.md +6 -5
- package/.docs/organized/code-examples/with-livekit.md +13 -12
- package/.docs/organized/code-examples/with-mcp.md +11 -9
- package/.docs/organized/code-examples/with-nuxt.md +502 -502
- package/.docs/organized/code-examples/with-opencode.md +3 -3
- package/.docs/organized/code-examples/with-openui.md +14 -13
- package/.docs/organized/code-examples/with-pi.md +5 -4
- package/.docs/organized/code-examples/with-react-hook-form.md +13 -10
- package/.docs/organized/code-examples/with-react-ink-web.md +64 -14
- package/.docs/organized/code-examples/with-react-ink.md +3 -2
- package/.docs/organized/code-examples/with-react-router.md +6 -5
- package/.docs/organized/code-examples/with-resumable-stream.md +10 -9
- package/.docs/organized/code-examples/with-store.md +2 -2
- package/.docs/organized/code-examples/with-svelte.md +3 -3
- package/.docs/organized/code-examples/with-sveltekit.md +9 -9
- package/.docs/organized/code-examples/with-tanstack.md +8 -7
- package/.docs/organized/code-examples/with-tap-runtime.md +4 -3
- package/.docs/organized/code-examples/with-virtualized-thread.md +5 -4
- package/.docs/organized/code-examples/with-vue.md +2 -2
- package/.docs/raw/docs/{(docs) → (getting-started)}/devtools.mdx +1 -1
- package/.docs/raw/docs/{(docs) → (getting-started)}/index.mdx +4 -2
- package/.docs/raw/docs/{(docs) → (getting-started)}/installation.mdx +24 -24
- package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +6 -0
- package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +6 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/{react-ai-sdk.mdx → ai-sdk.mdx} +19 -19
- package/.docs/raw/docs/(reference)/api-reference/integrations/eve.mdx +22 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +3 -3
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +2 -2
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +20 -2
- package/.docs/raw/docs/(reference)/api-reference/tools/interactables.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +3 -0
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +10 -10
- package/.docs/raw/docs/cloud/ai-sdk.mdx +2 -0
- package/.docs/raw/docs/copilots/assistant-frame.mdx +19 -8
- package/.docs/raw/docs/guides/attachments.mdx +2 -2
- package/.docs/raw/docs/guides/branching.mdx +1 -1
- package/.docs/raw/docs/guides/chatgpt-subscription.mdx +1 -1
- package/.docs/raw/docs/guides/dictation.mdx +1 -1
- package/.docs/raw/docs/guides/electron.mdx +1 -1
- package/.docs/raw/docs/guides/latex.mdx +1 -1
- package/.docs/raw/docs/guides/message-timing.mdx +11 -5
- package/.docs/raw/docs/guides/quoting.mdx +1 -1
- package/.docs/raw/docs/guides/resumable-streams.mdx +3 -3
- package/.docs/raw/docs/guides/speech.mdx +1 -1
- package/.docs/raw/docs/guides/suggestions.mdx +2 -2
- package/.docs/raw/docs/guides/voice.mdx +1 -1
- package/.docs/raw/docs/ink/hooks.mdx +1 -1
- package/.docs/raw/docs/ink/index.mdx +3 -2
- package/.docs/raw/docs/ink/migration.mdx +1 -1
- package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +3 -3
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +3 -3
- package/.docs/raw/docs/integrations/frameworks/{cloudflare-agents/overview.mdx → cloudflare-agents.mdx} +4 -3
- package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +1 -1
- package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
- package/.docs/raw/docs/integrations/index.mdx +2 -2
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +3 -3
- package/.docs/raw/docs/migrations/toolkit-tools.mdx +2 -2
- package/.docs/raw/docs/primitives/action-bar.mdx +1 -1
- package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -1
- package/.docs/raw/docs/primitives/attachment.mdx +1 -1
- package/.docs/raw/docs/primitives/branch-picker.mdx +1 -1
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +3 -3
- package/.docs/raw/docs/primitives/composer.mdx +1 -1
- package/.docs/raw/docs/primitives/error.mdx +1 -1
- package/.docs/raw/docs/primitives/message.mdx +1 -1
- package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -1
- package/.docs/raw/docs/primitives/suggestion.mdx +1 -1
- package/.docs/raw/docs/primitives/thread-list.mdx +1 -1
- package/.docs/raw/docs/primitives/thread.mdx +1 -1
- package/.docs/raw/docs/react-native/adapters.mdx +1 -1
- package/.docs/raw/docs/react-native/index.mdx +2 -2
- package/.docs/raw/docs/react-native/migration.mdx +2 -2
- package/.docs/raw/docs/react-native/primitives.mdx +142 -5
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +13 -1
- package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +3 -3
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +4 -4
- package/.docs/raw/docs/runtimes/ai-sdk/v7.mdx +31 -16
- package/.docs/raw/docs/runtimes/concepts/adapters.mdx +3 -3
- package/.docs/raw/docs/runtimes/concepts/architecture.mdx +3 -3
- package/.docs/raw/docs/runtimes/concepts/threads.mdx +5 -5
- package/.docs/raw/docs/runtimes/langchain.mdx +1 -1
- package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +1 -1
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +1 -1
- package/.docs/raw/docs/tools/backend.mdx +4 -4
- package/.docs/raw/docs/tools/defining-tools.mdx +2 -2
- package/.docs/raw/docs/tools/generative-ui.mdx +2 -2
- package/.docs/raw/docs/tools/interactables.mdx +3 -3
- package/.docs/raw/docs/tools/mcp-apps.mdx +18 -1
- package/.docs/raw/docs/tools/mcp.mdx +2 -2
- package/.docs/raw/docs/tools/openui.mdx +2 -2
- package/.docs/raw/docs/tools/tool-ui.mdx +17 -5
- package/.docs/raw/docs/tools/user-managed-mcp.mdx +2 -2
- package/.docs/raw/docs/ui/assistant-modal.mdx +3 -3
- package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -1
- package/.docs/raw/docs/ui/attachment.mdx +30 -10
- package/.docs/raw/docs/ui/composer-trigger-popover.mdx +36 -1
- package/.docs/raw/docs/ui/context-display.mdx +1 -1
- package/.docs/raw/docs/ui/directive-text.mdx +1 -1
- package/.docs/raw/docs/ui/file.mdx +1 -1
- package/.docs/raw/docs/ui/follow-up-suggestions.mdx +1 -1
- package/.docs/raw/docs/ui/image.mdx +1 -1
- package/.docs/raw/docs/ui/markdown.mdx +40 -1
- package/.docs/raw/docs/ui/mermaid.mdx +1 -1
- package/.docs/raw/docs/ui/message-timing.mdx +1 -1
- package/.docs/raw/docs/ui/model-selector.mdx +4 -4
- package/.docs/raw/docs/ui/part-grouping.mdx +1 -1
- package/.docs/raw/docs/ui/quote.mdx +3 -3
- package/.docs/raw/docs/ui/reasoning.mdx +31 -3
- package/.docs/raw/docs/ui/scrollbar.mdx +1 -1
- package/.docs/raw/docs/ui/sources.mdx +10 -1
- package/.docs/raw/docs/ui/streamdown.mdx +2 -2
- package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -1
- package/.docs/raw/docs/ui/thread-list.mdx +40 -1
- package/.docs/raw/docs/ui/thread.mdx +49 -2
- package/.docs/raw/docs/ui/tool-fallback.mdx +23 -9
- package/.docs/raw/docs/ui/tool-group.mdx +1 -1
- package/.docs/raw/docs/ui/voice.mdx +1 -1
- package/.docs/raw/docs/utilities/react-o11y.mdx +2 -2
- package/dist/xulux/catalog-client.d.ts.map +1 -1
- package/dist/xulux/catalog-client.js +51 -6
- package/dist/xulux/catalog-client.js.map +1 -1
- package/dist/xulux/types.d.ts +7 -7
- package/dist/xulux/types.d.ts.map +1 -1
- package/dist/xulux/types.js.map +1 -1
- package/package.json +3 -3
- package/src/tools/tests/docs.test.ts +10 -7
- package/src/tools/tests/path-traversal.test.ts +5 -2
- package/src/tools/tests/xulux-templates.test.ts +63 -0
- package/src/xulux/catalog-client.ts +68 -23
- package/src/xulux/types.ts +17 -13
- package/.docs/raw/docs/ui/accordion.mdx +0 -266
- package/.docs/raw/docs/ui/badge.mdx +0 -150
- package/.docs/raw/docs/ui/diff-viewer.mdx +0 -280
- package/.docs/raw/docs/ui/dot-matrix.mdx +0 -133
- package/.docs/raw/docs/ui/number-roll.mdx +0 -154
- package/.docs/raw/docs/ui/select.mdx +0 -254
- package/.docs/raw/docs/ui/tabs.mdx +0 -271
- /package/.docs/raw/docs/{(docs) → (getting-started)}/architecture.mdx +0 -0
- /package/.docs/raw/docs/{(docs) → (getting-started)}/base-ui.mdx +0 -0
- /package/.docs/raw/docs/{(docs) → (getting-started)}/cli.mdx +0 -0
- /package/.docs/raw/docs/{(docs) → (getting-started)}/llm.mdx +0 -0
- /package/.docs/raw/docs/{(docs) → (getting-started)}/rtl.mdx +0 -0
|
@@ -4,7 +4,12 @@ description: Sidebar or dropdown component for switching between AI chat convers
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { ThreadListSample } from "@/components/docs/samples/threadlist";
|
|
7
|
+
import { ThreadListSample } from "@/components/pages/docs/samples/threadlist";
|
|
8
|
+
import { PreviewCode } from "@/components/pages/docs/preview-code.server";
|
|
9
|
+
import { ThreadListSidebarSample } from "@/components/pages/docs/samples/thread-list/sidebar-composition";
|
|
10
|
+
import { ThreadListActiveSample } from "@/components/pages/docs/samples/thread-list/active-threads";
|
|
11
|
+
import { ThreadListNewSample } from "@/components/pages/docs/samples/thread-list/new-thread";
|
|
12
|
+
import { ThreadListArchiveSample } from "@/components/pages/docs/samples/thread-list/archive-thread";
|
|
8
13
|
|
|
9
14
|
<ThreadListSample />
|
|
10
15
|
|
|
@@ -104,6 +109,40 @@ import { ThreadListPrimitive, ThreadListItemPrimitive } from "@assistant-ui/reac
|
|
|
104
109
|
</ThreadListPrimitive.Root>
|
|
105
110
|
```
|
|
106
111
|
|
|
112
|
+
## Examples
|
|
113
|
+
|
|
114
|
+
### Active Threads
|
|
115
|
+
|
|
116
|
+
Select a different seeded conversation, or use the search field to filter the threads by title.
|
|
117
|
+
|
|
118
|
+
<PreviewCode file="components/pages/docs/samples/thread-list/active-threads" name="ActiveThreadList">
|
|
119
|
+
<ThreadListActiveSample />
|
|
120
|
+
</PreviewCode>
|
|
121
|
+
|
|
122
|
+
### New Thread
|
|
123
|
+
|
|
124
|
+
The list starts empty, thus only the New Thread button shows. Click New Thread to make an active thread. The search field shows when a thread exists.
|
|
125
|
+
|
|
126
|
+
<PreviewCode file="components/pages/docs/samples/thread-list/new-thread" name="EmptyThreadList">
|
|
127
|
+
<ThreadListNewSample />
|
|
128
|
+
</PreviewCode>
|
|
129
|
+
|
|
130
|
+
### Sidebar Composition
|
|
131
|
+
|
|
132
|
+
`ThreadListSidebar` wraps the same `ThreadList` in a complete sidebar shell.
|
|
133
|
+
|
|
134
|
+
<PreviewCode file="components/pages/docs/samples/thread-list/sidebar-composition" name="ThreadListSidebarDemo" className="p-0">
|
|
135
|
+
<ThreadListSidebarSample />
|
|
136
|
+
</PreviewCode>
|
|
137
|
+
|
|
138
|
+
### Archive a Thread
|
|
139
|
+
|
|
140
|
+
Open the More menu of the active thread, then select Archive. The `onArchive` callback moves the thread to the archived list. Select Restore (`ThreadListItemPrimitive.Unarchive`) to move the thread back to the regular list.
|
|
141
|
+
|
|
142
|
+
<PreviewCode file="components/pages/docs/samples/thread-list/archive-thread" name="ArchivableThreadList">
|
|
143
|
+
<ThreadListArchiveSample />
|
|
144
|
+
</PreviewCode>
|
|
145
|
+
|
|
107
146
|
## API Reference
|
|
108
147
|
|
|
109
148
|
### ThreadListPrimitive.Root
|
|
@@ -4,7 +4,13 @@ description: Stream-ready React chat container with message list, composer, auto
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { ThreadSample } from "@/components/docs/samples/thread";
|
|
7
|
+
import { ThreadSample } from "@/components/pages/docs/samples/thread";
|
|
8
|
+
import { ThreadHistorySample } from "@/components/pages/docs/samples/thread/thread-history";
|
|
9
|
+
import { ThreadActionsSample } from "@/components/pages/docs/samples/thread/message-actions";
|
|
10
|
+
import { PreviewCode } from "@/components/pages/docs/preview-code.server";
|
|
11
|
+
import { ThreadWelcomeSuggestionsSample } from "@/components/pages/docs/samples/thread/welcome-with-suggestions";
|
|
12
|
+
import { ThreadBranchSample } from "@/components/pages/docs/samples/thread/branching-response";
|
|
13
|
+
import { ThreadRunningSample } from "@/components/pages/docs/samples/thread/running-response";
|
|
8
14
|
|
|
9
15
|
A complete chat interface that combines message rendering, auto-scrolling, composer input,
|
|
10
16
|
attachments, and conditional UI states. Fully customizable and composable.
|
|
@@ -90,6 +96,13 @@ export default function Chat() {
|
|
|
90
96
|
</AuiIf>
|
|
91
97
|
```
|
|
92
98
|
|
|
99
|
+
### Thread with History
|
|
100
|
+
|
|
101
|
+
The thread shows a completed multi-turn conversation. The composer stays below the
|
|
102
|
+
messages, ready for the next input.
|
|
103
|
+
|
|
104
|
+
<ThreadHistorySample />
|
|
105
|
+
|
|
93
106
|
### Conditional Send/Cancel Button
|
|
94
107
|
|
|
95
108
|
```tsx
|
|
@@ -106,10 +119,23 @@ export default function Chat() {
|
|
|
106
119
|
</AuiIf>
|
|
107
120
|
```
|
|
108
121
|
|
|
122
|
+
While the last assistant response runs, the composer shows the cancel action, not the send action, and the action bar of the response stays hidden. Click the stop button to cancel the run. The composer then shows the send action again.
|
|
123
|
+
|
|
124
|
+
<ThreadRunningSample />
|
|
125
|
+
|
|
109
126
|
### Suggestions
|
|
110
127
|
|
|
111
128
|
Display suggested prompts using the Suggestions API. See the [Suggestions guide](/docs/guides/suggestions) for detailed configuration.
|
|
112
129
|
|
|
130
|
+
An empty thread centers the welcome screen and shows the configured suggestion chips. When you select a chip, the thread sends its prompt.
|
|
131
|
+
|
|
132
|
+
<PreviewCode
|
|
133
|
+
file="components/pages/docs/samples/thread/welcome-with-suggestions"
|
|
134
|
+
name="ChatWithSuggestions"
|
|
135
|
+
>
|
|
136
|
+
<ThreadWelcomeSuggestionsSample />
|
|
137
|
+
</PreviewCode>
|
|
138
|
+
|
|
113
139
|
```tsx
|
|
114
140
|
import type { ReactNode } from "react";
|
|
115
141
|
import {
|
|
@@ -119,7 +145,7 @@ import {
|
|
|
119
145
|
Suggestions,
|
|
120
146
|
ThreadPrimitive,
|
|
121
147
|
} from "@assistant-ui/react";
|
|
122
|
-
import { useChatRuntime } from "@assistant-ui/
|
|
148
|
+
import { useChatRuntime } from "@assistant-ui/ai-sdk";
|
|
123
149
|
|
|
124
150
|
// Configure suggestions in your runtime provider
|
|
125
151
|
const config = AuiConfig({
|
|
@@ -152,6 +178,27 @@ const SuggestionItem = () => (
|
|
|
152
178
|
);
|
|
153
179
|
```
|
|
154
180
|
|
|
181
|
+
### Branching Response
|
|
182
|
+
|
|
183
|
+
Select the refresh action below the assistant response to make an alternate branch. The built-in branch picker then shows `2 / 2` with arrows that switch between the two branches.
|
|
184
|
+
|
|
185
|
+
<PreviewCode
|
|
186
|
+
file="components/pages/docs/samples/thread/branching-response"
|
|
187
|
+
name="Chat"
|
|
188
|
+
>
|
|
189
|
+
<ThreadBranchSample />
|
|
190
|
+
</PreviewCode>
|
|
191
|
+
|
|
192
|
+
### Message Actions
|
|
193
|
+
|
|
194
|
+
Hover over the first assistant response to show its action bar. When the thread is idle, the last response always shows its actions. The copied `Thread` component sets `hideWhenRunning` and `autohide="not-last"` on `ActionBarPrimitive.Root`. Refer to the [ActionBar primitive](/docs/primitives/action-bar) to change this behavior.
|
|
195
|
+
|
|
196
|
+
<ThreadActionsSample />
|
|
197
|
+
|
|
198
|
+
## Composer Focus
|
|
199
|
+
|
|
200
|
+
Set `autoFocus={false}` to keep the page focus. This setting stops composer focus when the thread mounts, starts a run, changes threads, or scrolls to the bottom. The default value is `true`.
|
|
201
|
+
|
|
155
202
|
## Component Overrides
|
|
156
203
|
|
|
157
204
|
`Thread` accepts an optional `components` prop that swaps parts of the rendering without editing the copied file. All slots are optional; omitted slots keep the built-in rendering.
|
|
@@ -6,11 +6,13 @@ platforms: ["react"]
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
ToolFallbackSample,
|
|
9
|
-
|
|
9
|
+
ToolFallbackCompletedSample,
|
|
10
10
|
ToolFallbackCancelledSample,
|
|
11
11
|
ToolFallbackStreamingSample,
|
|
12
|
-
|
|
13
|
-
} from "@/components/docs/
|
|
12
|
+
} from "@/components/pages/docs/samples/tool-fallback";
|
|
13
|
+
import { PreviewCode } from "@/components/pages/docs/preview-code.server";
|
|
14
|
+
import { ToolFallbackApprovalSample } from "@/components/pages/docs/samples/tool-fallback/approval";
|
|
15
|
+
import { ToolFallbackErrorSample } from "@/components/pages/docs/samples/tool-fallback/failed-with-error";
|
|
14
16
|
|
|
15
17
|
<ToolFallbackSample />
|
|
16
18
|
|
|
@@ -60,23 +62,34 @@ Interactive demo showing the full tool call lifecycle: running → complete.
|
|
|
60
62
|
|
|
61
63
|
<ToolFallbackStreamingSample />
|
|
62
64
|
|
|
63
|
-
###
|
|
65
|
+
### Completed With Result
|
|
64
66
|
|
|
65
|
-
Shows
|
|
67
|
+
Shows the arguments and the structured result for the completed call.
|
|
66
68
|
|
|
67
|
-
<
|
|
69
|
+
<ToolFallbackCompletedSample />
|
|
70
|
+
|
|
71
|
+
### Failed With Error State
|
|
72
|
+
|
|
73
|
+
Shows a service error above its arguments.
|
|
74
|
+
|
|
75
|
+
<ToolFallbackErrorSample />
|
|
68
76
|
|
|
69
77
|
### Cancelled State
|
|
70
78
|
|
|
71
|
-
|
|
79
|
+
The "Cancelled tool" label has a line through it. The arguments are muted after you open the call.
|
|
72
80
|
|
|
73
81
|
<ToolFallbackCancelledSample />
|
|
74
82
|
|
|
75
83
|
### Approval State
|
|
76
84
|
|
|
77
|
-
|
|
85
|
+
Select Allow or Deny. The `resume` callback records the choice, removes the buttons, and shows the result. The block opens automatically for `requires-action`, so you can select a decision without an extra click. A tool call whose approval gate is decided shows no buttons. Edit your project's copy of `tool-fallback.tsx` to add trust escalation, edit-args, custom labels, or analytics hooks.
|
|
78
86
|
|
|
79
|
-
<
|
|
87
|
+
<PreviewCode
|
|
88
|
+
file="components/pages/docs/samples/tool-fallback/approval"
|
|
89
|
+
name="ToolWithApproval"
|
|
90
|
+
>
|
|
91
|
+
<ToolFallbackApprovalSample />
|
|
92
|
+
</PreviewCode>
|
|
80
93
|
|
|
81
94
|
## Composable API
|
|
82
95
|
|
|
@@ -116,6 +129,7 @@ import {
|
|
|
116
129
|
interrupt={interrupt}
|
|
117
130
|
approval={approval}
|
|
118
131
|
respondToApproval={respondToApproval}
|
|
132
|
+
status={status}
|
|
119
133
|
/>
|
|
120
134
|
<ToolFallback.Result result={result} />
|
|
121
135
|
</ToolFallback.Content>
|
|
@@ -7,7 +7,7 @@ platforms: ["react"]
|
|
|
7
7
|
import {
|
|
8
8
|
ToolGroupSample,
|
|
9
9
|
ToolGroupStreamingSample,
|
|
10
|
-
} from "@/components/docs/samples/tool-group";
|
|
10
|
+
} from "@/components/pages/docs/samples/tool-group";
|
|
11
11
|
|
|
12
12
|
A wrapper component that groups consecutive tool calls together, displaying them in a collapsible container with auto-expand behavior during streaming.
|
|
13
13
|
|
|
@@ -4,7 +4,7 @@ description: Realtime voice session controls with connect, mute, and status indi
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { VoiceSample, VoiceVariantsSample, VoiceStatesSample } from "@/components/docs/samples/voice";
|
|
7
|
+
import { VoiceSample, VoiceVariantsSample, VoiceStatesSample } from "@/components/pages/docs/samples/voice";
|
|
8
8
|
|
|
9
9
|
A control bar for realtime bidirectional voice sessions with an animated orb indicator. Works with any `RealtimeVoiceAdapter` (LiveKit, ElevenLabs, etc.).
|
|
10
10
|
|
|
@@ -4,12 +4,12 @@ description: Headless primitives for visualizing observability spans as collapsi
|
|
|
4
4
|
platforms: ["react"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
import { WaterfallSample } from "@/components/docs/samples/o11y/waterfall";
|
|
7
|
+
import { WaterfallSample } from "@/components/pages/docs/samples/o11y/waterfall";
|
|
8
8
|
import {
|
|
9
9
|
StatusSample,
|
|
10
10
|
CollapseSample,
|
|
11
11
|
StreamingSample,
|
|
12
|
-
} from "@/components/docs/samples/o11y/capability-samples";
|
|
12
|
+
} from "@/components/pages/docs/samples/o11y/capability-samples";
|
|
13
13
|
|
|
14
14
|
<Callout type="warn">
|
|
15
15
|
`@assistant-ui/react-o11y` is experimental. The API may change without notice.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-client.d.ts","names":[],"sources":["../../src/xulux/catalog-client.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"catalog-client.d.ts","names":[],"sources":["../../src/xulux/catalog-client.ts"],"mappings":";;cASa;iBAsDG;iBAiCA;;;;;;iBAoBM,mBAAmB,QAAQ"}
|
|
@@ -1,18 +1,63 @@
|
|
|
1
1
|
import { logger } from "../utils/logger.js";
|
|
2
|
+
import "./types.js";
|
|
2
3
|
import { FALLBACK_CATALOG, FALLBACK_NOTE } from "./fallback-catalog.js";
|
|
4
|
+
import { z } from "zod";
|
|
3
5
|
//#region src/xulux/catalog-client.ts
|
|
4
6
|
const DEFAULT_CATALOG_URL = "https://www.assistant-ui.com/api/xulux/mcp-catalog";
|
|
5
7
|
const CATALOG_TTL_MS = 3e5;
|
|
8
|
+
const catalogUrlSchema = z.url();
|
|
9
|
+
const catalogVersionSchema = z.looseObject({
|
|
10
|
+
id: z.string(),
|
|
11
|
+
entryId: z.string(),
|
|
12
|
+
name: z.string(),
|
|
13
|
+
description: z.string(),
|
|
14
|
+
previewUrl: catalogUrlSchema,
|
|
15
|
+
downloadUrl: catalogUrlSchema
|
|
16
|
+
});
|
|
17
|
+
const catalogTemplateSchema = z.looseObject({
|
|
18
|
+
id: z.string(),
|
|
19
|
+
templateId: z.string(),
|
|
20
|
+
versionId: z.string().nullable(),
|
|
21
|
+
kind: z.enum(["template", "example"]),
|
|
22
|
+
name: z.string(),
|
|
23
|
+
summary: z.string(),
|
|
24
|
+
assistantPlacement: z.string(),
|
|
25
|
+
features: z.array(z.string()),
|
|
26
|
+
customizable: z.array(z.string()),
|
|
27
|
+
versions: z.array(catalogVersionSchema),
|
|
28
|
+
previewUrl: catalogUrlSchema.optional(),
|
|
29
|
+
downloadUrl: catalogUrlSchema.optional(),
|
|
30
|
+
sandboxBaseUrl: catalogUrlSchema.optional(),
|
|
31
|
+
configRoots: z.record(z.string(), z.unknown()).optional(),
|
|
32
|
+
rules: z.looseObject({
|
|
33
|
+
required: z.array(z.string()),
|
|
34
|
+
unsupported: z.array(z.string()).optional()
|
|
35
|
+
}).optional(),
|
|
36
|
+
tools: z.looseObject({
|
|
37
|
+
builtIn: z.array(z.unknown()),
|
|
38
|
+
customToolSupported: z.boolean(),
|
|
39
|
+
renderers: z.array(z.unknown())
|
|
40
|
+
}).optional()
|
|
41
|
+
});
|
|
42
|
+
const catalogSchema = z.looseObject({
|
|
43
|
+
version: z.literal(1),
|
|
44
|
+
generatedAt: z.string(),
|
|
45
|
+
docsOrigin: z.string(),
|
|
46
|
+
templates: z.array(catalogTemplateSchema)
|
|
47
|
+
});
|
|
6
48
|
function getCatalogUrl() {
|
|
7
49
|
return process.env.XULUX_CATALOG_URL?.trim() || "https://www.assistant-ui.com/api/xulux/mcp-catalog";
|
|
8
50
|
}
|
|
9
51
|
function validateCatalog(data) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (!
|
|
14
|
-
|
|
15
|
-
|
|
52
|
+
const version = data?.version;
|
|
53
|
+
if (version !== void 0 && version !== 1) throw new Error(`Unsupported catalog version: ${String(version)}. Expected 1.`);
|
|
54
|
+
const result = catalogSchema.safeParse(data);
|
|
55
|
+
if (!result.success) {
|
|
56
|
+
const issue = result.error.issues[0];
|
|
57
|
+
const path = issue?.path.length ? ` at ${issue.path.join(".")}` : "";
|
|
58
|
+
throw new Error(`Catalog response is malformed${path}: ${issue?.message ?? "invalid catalog"}.`);
|
|
59
|
+
}
|
|
60
|
+
return result.data;
|
|
16
61
|
}
|
|
17
62
|
let cache = null;
|
|
18
63
|
function clearCatalogCache() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-client.js","names":[],"sources":["../../src/xulux/catalog-client.ts"],"sourcesContent":["import { logger } from \"../utils/logger.js\";\nimport { FALLBACK_CATALOG, FALLBACK_NOTE } from \"./fallback-catalog.js\";\nimport type
|
|
1
|
+
{"version":3,"file":"catalog-client.js","names":[],"sources":["../../src/xulux/catalog-client.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { logger } from \"../utils/logger.js\";\nimport { FALLBACK_CATALOG, FALLBACK_NOTE } from \"./fallback-catalog.js\";\nimport {\n XULUX_MCP_CATALOG_VERSION,\n type XuluxCatalog,\n type XuluxCatalogResult,\n} from \"./types.js\";\n\nexport const DEFAULT_CATALOG_URL =\n \"https://www.assistant-ui.com/api/xulux/mcp-catalog\";\n\nconst CATALOG_TTL_MS = 5 * 60 * 1000;\nconst catalogUrlSchema = z.url();\n\nconst catalogVersionSchema = z.looseObject({\n id: z.string(),\n entryId: z.string(),\n name: z.string(),\n description: z.string(),\n previewUrl: catalogUrlSchema,\n downloadUrl: catalogUrlSchema,\n});\n\nconst catalogTemplateSchema = z.looseObject({\n id: z.string(),\n templateId: z.string(),\n versionId: z.string().nullable(),\n kind: z.enum([\"template\", \"example\"]),\n name: z.string(),\n summary: z.string(),\n assistantPlacement: z.string(),\n features: z.array(z.string()),\n customizable: z.array(z.string()),\n versions: z.array(catalogVersionSchema),\n previewUrl: catalogUrlSchema.optional(),\n downloadUrl: catalogUrlSchema.optional(),\n sandboxBaseUrl: catalogUrlSchema.optional(),\n configRoots: z.record(z.string(), z.unknown()).optional(),\n rules: z\n .looseObject({\n required: z.array(z.string()),\n unsupported: z.array(z.string()).optional(),\n })\n .optional(),\n tools: z\n .looseObject({\n builtIn: z.array(z.unknown()),\n customToolSupported: z.boolean(),\n renderers: z.array(z.unknown()),\n })\n .optional(),\n});\n\nconst catalogSchema = z.looseObject({\n version: z.literal(XULUX_MCP_CATALOG_VERSION),\n // Not read anywhere in the package; validated for shape only, so an unused\n // field cannot veto the whole catalog.\n generatedAt: z.string(),\n docsOrigin: z.string(),\n templates: z.array(catalogTemplateSchema),\n});\n\nexport function getCatalogUrl(): string {\n const override = process.env.XULUX_CATALOG_URL?.trim();\n return override || DEFAULT_CATALOG_URL;\n}\n\nfunction validateCatalog(data: unknown): XuluxCatalog {\n // Checked ahead of the schema so a catalog rollout reports its version\n // rather than reading as a malformed payload.\n const version = (data as { version?: unknown } | null)?.version;\n if (version !== undefined && version !== XULUX_MCP_CATALOG_VERSION) {\n throw new Error(\n `Unsupported catalog version: ${String(version)}. Expected ${XULUX_MCP_CATALOG_VERSION}.`,\n );\n }\n const result = catalogSchema.safeParse(data);\n if (!result.success) {\n const issue = result.error.issues[0];\n const path = issue?.path.length ? ` at ${issue.path.join(\".\")}` : \"\";\n throw new Error(\n `Catalog response is malformed${path}: ${issue?.message ?? \"invalid catalog\"}.`,\n );\n }\n return result.data;\n}\n\ninterface CacheEntry {\n catalog: XuluxCatalog;\n fetchedAt: number;\n url: string;\n}\n\nlet cache: CacheEntry | null = null;\n\nexport function clearCatalogCache(): void {\n cache = null;\n}\n\nasync function fetchCatalog(url: string): Promise<XuluxCatalog> {\n const res = await fetch(url, {\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) {\n throw new Error(`Catalog fetch failed: HTTP ${res.status}`);\n }\n const data: unknown = await res.json();\n return validateCatalog(data);\n}\n\n/**\n * Returns the assistant-ui template catalog. Uses an in-memory five-minute cache, and falls\n * back to a minimal bundled catalog (marked degraded) when the live fetch\n * fails and no cached copy exists.\n */\nexport async function getXuluxCatalog(): Promise<XuluxCatalogResult> {\n const url = getCatalogUrl();\n const now = Date.now();\n\n if (cache && cache.url === url && now - cache.fetchedAt < CATALOG_TTL_MS) {\n return { catalog: cache.catalog, degraded: false };\n }\n\n try {\n const catalog = await fetchCatalog(url);\n cache = { catalog, fetchedAt: now, url };\n return { catalog, degraded: false };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.warn(\n `assistant-ui template catalog fetch failed (${url}): ${message}`,\n );\n\n // Prefer a stale cached copy over the minimal fallback.\n if (cache && cache.url === url) {\n return {\n catalog: cache.catalog,\n degraded: true,\n degradedReason: `Live catalog refresh failed (${message}); using previously fetched catalog.`,\n };\n }\n\n return {\n catalog: FALLBACK_CATALOG,\n degraded: true,\n degradedReason: `${message} ${FALLBACK_NOTE}`,\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/xulux/types.d.ts
CHANGED
|
@@ -19,19 +19,19 @@ interface XuluxCatalogTemplate {
|
|
|
19
19
|
features: string[];
|
|
20
20
|
customizable: string[];
|
|
21
21
|
versions: XuluxCatalogVersion[];
|
|
22
|
-
previewUrl?: string;
|
|
23
|
-
downloadUrl?: string;
|
|
24
|
-
sandboxBaseUrl?: string;
|
|
25
|
-
configRoots?: Record<string, unknown
|
|
22
|
+
previewUrl?: string | undefined;
|
|
23
|
+
downloadUrl?: string | undefined;
|
|
24
|
+
sandboxBaseUrl?: string | undefined;
|
|
25
|
+
configRoots?: Record<string, unknown> | undefined;
|
|
26
26
|
rules?: {
|
|
27
27
|
required: string[];
|
|
28
|
-
unsupported?: string[];
|
|
29
|
-
};
|
|
28
|
+
unsupported?: string[] | undefined;
|
|
29
|
+
} | undefined;
|
|
30
30
|
tools?: {
|
|
31
31
|
builtIn: unknown[];
|
|
32
32
|
customToolSupported: boolean;
|
|
33
33
|
renderers: unknown[];
|
|
34
|
-
};
|
|
34
|
+
} | undefined;
|
|
35
35
|
}
|
|
36
36
|
interface XuluxCatalog {
|
|
37
37
|
version: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/xulux/types.ts"],"mappings":";cAIa;UAEI;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV;EACA;EACA;EACA,cAAc;EACd;
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/xulux/types.ts"],"mappings":";cAIa;UAEI;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV;EACA;EACA;EACA,cAAc;EACd;IAEM;IACA;;EAGN;IAEM;IACA;IACA;;;UAKS;EACf;EACA;EACA;EACA,WAAW;;UAGI;EACf,SAAS;;EAET;;EAEA;;UAGe;EACf;EACA"}
|
package/dist/xulux/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../src/xulux/types.ts"],"sourcesContent":["// MCP-safe assistant-ui template catalog types. These mirror the payload served by the docs\n// app at GET /api/xulux/mcp-catalog. The MCP package never imports docs-app\n// internals; the endpoint payload is the contract.\n\nexport const XULUX_MCP_CATALOG_VERSION = 1;\n\nexport interface XuluxCatalogVersion {\n id: string;\n entryId: string;\n name: string;\n description: string;\n previewUrl: string;\n downloadUrl: string;\n}\n\nexport interface XuluxCatalogTemplate {\n id: string;\n templateId: string;\n versionId: string | null;\n kind: \"template\" | \"example\";\n name: string;\n summary: string;\n assistantPlacement: string;\n features: string[];\n customizable: string[];\n versions: XuluxCatalogVersion[];\n previewUrl?: string;\n downloadUrl?: string;\n sandboxBaseUrl?: string;\n configRoots?: Record<string, unknown
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../src/xulux/types.ts"],"sourcesContent":["// MCP-safe assistant-ui template catalog types. These mirror the payload served by the docs\n// app at GET /api/xulux/mcp-catalog. The MCP package never imports docs-app\n// internals; the endpoint payload is the contract.\n\nexport const XULUX_MCP_CATALOG_VERSION = 1;\n\nexport interface XuluxCatalogVersion {\n id: string;\n entryId: string;\n name: string;\n description: string;\n previewUrl: string;\n downloadUrl: string;\n}\n\nexport interface XuluxCatalogTemplate {\n id: string;\n templateId: string;\n versionId: string | null;\n kind: \"template\" | \"example\";\n name: string;\n summary: string;\n assistantPlacement: string;\n features: string[];\n customizable: string[];\n versions: XuluxCatalogVersion[];\n previewUrl?: string | undefined;\n downloadUrl?: string | undefined;\n sandboxBaseUrl?: string | undefined;\n configRoots?: Record<string, unknown> | undefined;\n rules?:\n | {\n required: string[];\n unsupported?: string[] | undefined;\n }\n | undefined;\n tools?:\n | {\n builtIn: unknown[];\n customToolSupported: boolean;\n renderers: unknown[];\n }\n | undefined;\n}\n\nexport interface XuluxCatalog {\n version: number;\n generatedAt: string;\n docsOrigin: string;\n templates: XuluxCatalogTemplate[];\n}\n\nexport interface XuluxCatalogResult {\n catalog: XuluxCatalog;\n /** True when the bundled fallback catalog was used instead of live data. */\n degraded: boolean;\n /** Present when the live fetch failed and the fallback was used. */\n degradedReason?: string;\n}\n\nexport interface XuluxCatalogError {\n error: string;\n hint?: string;\n}\n"],"mappings":";AAIA,MAAa,4BAA4B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/mcp-docs-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "MCP server for assistant-ui documentation and examples",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
"zod": "^4.4.3"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
+
"@assistant-ui/x-buildutils": "0.0.24",
|
|
40
41
|
"@modelcontextprotocol/core": "^2.0.0",
|
|
41
42
|
"@types/node": "^26.2.0",
|
|
42
43
|
"tsx": "^4.23.12",
|
|
43
|
-
"vitest": "^4.1.
|
|
44
|
-
"@assistant-ui/x-buildutils": "0.0.23"
|
|
44
|
+
"vitest": "^4.1.11"
|
|
45
45
|
},
|
|
46
46
|
"publishConfig": {
|
|
47
47
|
"access": "public",
|
|
@@ -28,17 +28,17 @@ describe("assistantUIDocs", () => {
|
|
|
28
28
|
expect(result.path).toBe("/");
|
|
29
29
|
expect(result.found).toBe(true);
|
|
30
30
|
expect(result.type).toBe("directory");
|
|
31
|
-
expect(result.directories).toContain("(
|
|
31
|
+
expect(result.directories).toContain("(getting-started)");
|
|
32
32
|
expect(result.directories).toContain("(reference)");
|
|
33
33
|
expect(result.directories).toContain("ui");
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it("should retrieve specific documentation file", async () => {
|
|
37
37
|
const result = await testContext.callTool("assistantUIDocs", {
|
|
38
|
-
paths: ["(
|
|
38
|
+
paths: ["(getting-started)/index"],
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
expect(result.path).toBe("(
|
|
41
|
+
expect(result.path).toBe("(getting-started)/index");
|
|
42
42
|
expect(result.found).toBe(true);
|
|
43
43
|
expect(result.type).toBe("file");
|
|
44
44
|
expect(result.content).toBeDefined();
|
|
@@ -57,12 +57,15 @@ describe("assistantUIDocs", () => {
|
|
|
57
57
|
|
|
58
58
|
it("should support multiple path requests", async () => {
|
|
59
59
|
const result = await testContext.callTool("assistantUIDocs", {
|
|
60
|
-
paths: [
|
|
60
|
+
paths: [
|
|
61
|
+
"(getting-started)/index",
|
|
62
|
+
"(reference)/api-reference/primitives/thread",
|
|
63
|
+
],
|
|
61
64
|
});
|
|
62
65
|
|
|
63
66
|
expect(result.results).toBeDefined();
|
|
64
67
|
expect(result.results).toHaveLength(2);
|
|
65
|
-
expect(result.results[0].path).toBe("(
|
|
68
|
+
expect(result.results[0].path).toBe("(getting-started)/index");
|
|
66
69
|
expect(result.results[1].path).toBe(
|
|
67
70
|
"(reference)/api-reference/primitives/thread",
|
|
68
71
|
);
|
|
@@ -83,7 +86,7 @@ describe("assistantUIDocs", () => {
|
|
|
83
86
|
|
|
84
87
|
it("should parse MDX files with frontmatter", async () => {
|
|
85
88
|
const result = await testContext.callTool("assistantUIDocs", {
|
|
86
|
-
paths: ["(
|
|
89
|
+
paths: ["(getting-started)/index"],
|
|
87
90
|
});
|
|
88
91
|
|
|
89
92
|
expect(result.content).toBeDefined();
|
|
@@ -93,7 +96,7 @@ describe("assistantUIDocs", () => {
|
|
|
93
96
|
|
|
94
97
|
it("includes title and excerpt on a file response", async () => {
|
|
95
98
|
const result = await testContext.callTool("assistantUIDocs", {
|
|
96
|
-
paths: ["(
|
|
99
|
+
paths: ["(getting-started)/index"],
|
|
97
100
|
});
|
|
98
101
|
expect(result.type).toBe("file");
|
|
99
102
|
expect(result.title ?? result.excerpt).toBeDefined();
|
|
@@ -26,7 +26,7 @@ describe("Path Traversal Security", () => {
|
|
|
26
26
|
|
|
27
27
|
it("should handle multiple paths with one malicious", async () => {
|
|
28
28
|
const result = await testContext.callTool("assistantUIDocs", {
|
|
29
|
-
paths: ["(
|
|
29
|
+
paths: ["(getting-started)/index", "../../../../etc/passwd", "guides"],
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
expect(result.results).toBeDefined();
|
|
@@ -63,7 +63,10 @@ describe("Path Traversal Security", () => {
|
|
|
63
63
|
describe("Valid paths should still work", () => {
|
|
64
64
|
it("should allow valid documentation paths", async () => {
|
|
65
65
|
const result = await testContext.callTool("assistantUIDocs", {
|
|
66
|
-
paths: [
|
|
66
|
+
paths: [
|
|
67
|
+
"(getting-started)/index",
|
|
68
|
+
"(reference)/api-reference/primitives/thread",
|
|
69
|
+
],
|
|
67
70
|
});
|
|
68
71
|
|
|
69
72
|
expect(result.results).toBeDefined();
|
|
@@ -134,6 +134,69 @@ describe("assistant-ui template MCP tools", () => {
|
|
|
134
134
|
);
|
|
135
135
|
});
|
|
136
136
|
|
|
137
|
+
it("uses the fallback catalog when a live template entry is malformed", async () => {
|
|
138
|
+
vi.stubGlobal(
|
|
139
|
+
"fetch",
|
|
140
|
+
vi.fn(async () =>
|
|
141
|
+
jsonResponse({
|
|
142
|
+
...LIVE_CATALOG,
|
|
143
|
+
templates: [
|
|
144
|
+
{
|
|
145
|
+
id: "broken",
|
|
146
|
+
templateId: "broken",
|
|
147
|
+
kind: "template",
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
}),
|
|
151
|
+
),
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const result = await callTool(xuluxTemplatesListTool, {});
|
|
155
|
+
expect(result.catalogDegraded).toBe(true);
|
|
156
|
+
expect(result.catalogDegradedReason).toContain(
|
|
157
|
+
"Catalog response is malformed",
|
|
158
|
+
);
|
|
159
|
+
expect(result.templates.map((t: { id: string }) => t.id)).toContain(
|
|
160
|
+
"base-assistant-ui",
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("names the version when the live catalog is a newer revision", async () => {
|
|
165
|
+
vi.stubGlobal(
|
|
166
|
+
"fetch",
|
|
167
|
+
vi.fn(async () => jsonResponse({ ...LIVE_CATALOG, version: 2 })),
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const result = await callTool(xuluxTemplatesListTool, {});
|
|
171
|
+
expect(result.catalogDegraded).toBe(true);
|
|
172
|
+
expect(result.catalogDegradedReason).toContain(
|
|
173
|
+
"Unsupported catalog version: 2. Expected 1.",
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("uses the fallback catalog when a live template URL is malformed", async () => {
|
|
178
|
+
vi.stubGlobal(
|
|
179
|
+
"fetch",
|
|
180
|
+
vi.fn(async () =>
|
|
181
|
+
jsonResponse({
|
|
182
|
+
...LIVE_CATALOG,
|
|
183
|
+
templates: [
|
|
184
|
+
{
|
|
185
|
+
...LIVE_CATALOG.templates[0],
|
|
186
|
+
sandboxBaseUrl: "not a URL",
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
}),
|
|
190
|
+
),
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const result = await callTool(xuluxTemplatesListTool, {});
|
|
194
|
+
expect(result.catalogDegraded).toBe(true);
|
|
195
|
+
expect(result.catalogDegradedReason).toContain(
|
|
196
|
+
"Catalog response is malformed",
|
|
197
|
+
);
|
|
198
|
+
});
|
|
199
|
+
|
|
137
200
|
it("returns details and fetches exampleConfig from the selected sandbox contract", async () => {
|
|
138
201
|
const fetchMock = vi.fn(async (url: string | URL) => {
|
|
139
202
|
const href = String(url);
|