nitrostack 1.0.25 → 1.0.27
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/package.json
CHANGED
package/src/studio/app/page.tsx
CHANGED
|
@@ -305,13 +305,21 @@ export default function ToolsPage() {
|
|
|
305
305
|
</div>
|
|
306
306
|
|
|
307
307
|
{/* Widget UI Rendering */}
|
|
308
|
-
{(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
308
|
+
{(() => {
|
|
309
|
+
// Get widget URI from multiple sources (same as ToolCard)
|
|
310
|
+
const widgetUri =
|
|
311
|
+
selectedTool.widget?.route ||
|
|
312
|
+
selectedTool.outputTemplate ||
|
|
313
|
+
selectedTool._meta?.['ui/template'] ||
|
|
314
|
+
selectedTool._meta?.['openai/outputTemplate'];
|
|
315
|
+
|
|
316
|
+
return widgetUri && toolResult ? (
|
|
317
|
+
<div>
|
|
318
|
+
<h3 className="font-semibold text-foreground mb-3">UI Widget:</h3>
|
|
319
|
+
<div className="border border-border rounded-lg overflow-hidden h-64 bg-background shadow-inner">
|
|
320
|
+
<WidgetRenderer
|
|
321
|
+
uri={widgetUri}
|
|
322
|
+
data={(() => {
|
|
315
323
|
// Try to parse JSON from content[0].text, otherwise use raw result
|
|
316
324
|
if (toolResult.content?.[0]?.text) {
|
|
317
325
|
try {
|
|
@@ -327,11 +335,12 @@ export default function ToolsPage() {
|
|
|
327
335
|
}
|
|
328
336
|
return toolResult;
|
|
329
337
|
})()}
|
|
330
|
-
|
|
331
|
-
|
|
338
|
+
className="w-full h-full"
|
|
339
|
+
/>
|
|
340
|
+
</div>
|
|
332
341
|
</div>
|
|
333
|
-
|
|
334
|
-
)}
|
|
342
|
+
) : null;
|
|
343
|
+
})()}
|
|
335
344
|
</div>
|
|
336
345
|
)}
|
|
337
346
|
</div>
|
|
@@ -21,6 +21,16 @@ export function EnlargeModal() {
|
|
|
21
21
|
|
|
22
22
|
// Get data from item's examples or responseData
|
|
23
23
|
const widgetData = item.examples?.response || item.responseData || {};
|
|
24
|
+
|
|
25
|
+
// Debug logging
|
|
26
|
+
console.log('EnlargeModal - Widget info:', {
|
|
27
|
+
type,
|
|
28
|
+
itemName: item.name,
|
|
29
|
+
componentUri,
|
|
30
|
+
hasWidgetData: !!widgetData && Object.keys(widgetData).length > 0,
|
|
31
|
+
widgetDataType: widgetData ? typeof widgetData : 'none',
|
|
32
|
+
itemMeta: item._meta,
|
|
33
|
+
});
|
|
24
34
|
|
|
25
35
|
const handleUseInChat = () => {
|
|
26
36
|
if (type !== 'tool') return;
|
|
@@ -21,10 +21,21 @@ export function ToolCard({ tool, onExecute }: ToolCardProps) {
|
|
|
21
21
|
tool.outputTemplate ||
|
|
22
22
|
tool._meta?.['ui/template'] ||
|
|
23
23
|
tool._meta?.['openai/outputTemplate'];
|
|
24
|
-
const hasWidget = !!widgetUri;
|
|
24
|
+
const hasWidget = !!widgetUri && widgetUri.trim().length > 0;
|
|
25
25
|
|
|
26
26
|
// Get example data for preview
|
|
27
27
|
const exampleData = tool.examples?.response;
|
|
28
|
+
|
|
29
|
+
// Debug logging for widget detection
|
|
30
|
+
if (hasWidget) {
|
|
31
|
+
console.log('ToolCard - Widget detected:', {
|
|
32
|
+
toolName: tool.name,
|
|
33
|
+
widgetUri,
|
|
34
|
+
hasExampleData: !!exampleData,
|
|
35
|
+
exampleDataType: exampleData ? typeof exampleData : 'none',
|
|
36
|
+
toolMeta: tool._meta,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
28
39
|
|
|
29
40
|
const handleUseInChat = (e: React.MouseEvent) => {
|
|
30
41
|
e.stopPropagation();
|
|
@@ -77,8 +88,8 @@ export function ToolCard({ tool, onExecute }: ToolCardProps) {
|
|
|
77
88
|
{tool.description || 'No description'}
|
|
78
89
|
</p>
|
|
79
90
|
|
|
80
|
-
{/* Widget Preview */}
|
|
81
|
-
{hasWidget && exampleData && (
|
|
91
|
+
{/* Widget Preview - Show if widget exists AND has example data */}
|
|
92
|
+
{hasWidget && widgetUri && exampleData && (
|
|
82
93
|
<div className="relative mb-4 rounded-lg overflow-hidden border border-border bg-muted/20">
|
|
83
94
|
<div className="absolute top-2 left-2 z-10 flex items-center gap-1 bg-primary/90 backdrop-blur-sm text-black px-2 py-1 rounded-md text-xs font-semibold shadow-lg">
|
|
84
95
|
<Sparkles className="w-3 h-3" />
|
|
@@ -96,7 +107,7 @@ export function ToolCard({ tool, onExecute }: ToolCardProps) {
|
|
|
96
107
|
|
|
97
108
|
{/* Action Buttons */}
|
|
98
109
|
<div className="flex flex-wrap items-center gap-2" onClick={(e) => e.stopPropagation()}>
|
|
99
|
-
{hasWidget &&
|
|
110
|
+
{hasWidget && (
|
|
100
111
|
<button
|
|
101
112
|
onClick={handleEnlarge}
|
|
102
113
|
className="btn btn-secondary flex-1 min-w-[90px] text-xs sm:text-sm gap-1.5 px-2.5 py-1.5 sm:px-4 sm:py-2"
|
|
@@ -55,7 +55,18 @@ export function WidgetRenderer({ uri, data, className = '' }: WidgetRendererProp
|
|
|
55
55
|
// Production mode: fetch and render
|
|
56
56
|
const loadProductionWidget = async () => {
|
|
57
57
|
try {
|
|
58
|
-
|
|
58
|
+
// Convert widget route/path to resource URI format if needed
|
|
59
|
+
// Routes like "/calculator-result" or "calculator-result" should become "widget://calculator-result"
|
|
60
|
+
let resourceUri = uri;
|
|
61
|
+
if (!uri.startsWith('widget://') && !uri.startsWith('http://') && !uri.startsWith('https://')) {
|
|
62
|
+
// Remove leading slash if present
|
|
63
|
+
const widgetPath = uri.startsWith('/') ? uri.substring(1) : uri;
|
|
64
|
+
resourceUri = `widget://${widgetPath}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log('Loading widget in production mode:', { originalUri: uri, resourceUri, data });
|
|
68
|
+
|
|
69
|
+
const response = await fetch(`/api/resources/${encodeURIComponent(resourceUri)}`);
|
|
59
70
|
const result = await response.json();
|
|
60
71
|
|
|
61
72
|
if (result.contents && result.contents.length > 0) {
|
|
@@ -72,9 +83,17 @@ export function WidgetRenderer({ uri, data, className = '' }: WidgetRendererProp
|
|
|
72
83
|
URL.revokeObjectURL(blobUrl);
|
|
73
84
|
};
|
|
74
85
|
}
|
|
86
|
+
console.log('✅ Widget loaded successfully:', { resourceUri, hasHtml: !!html, hasData: !!data });
|
|
87
|
+
} else {
|
|
88
|
+
console.warn('⚠️ Widget resource found but no content:', { resourceUri, result });
|
|
75
89
|
}
|
|
76
90
|
} catch (error) {
|
|
77
|
-
console.error('Failed to load widget:',
|
|
91
|
+
console.error('❌ Failed to load widget:', {
|
|
92
|
+
originalUri: uri,
|
|
93
|
+
resourceUri,
|
|
94
|
+
error: error instanceof Error ? error.message : String(error),
|
|
95
|
+
stack: error instanceof Error ? error.stack : undefined
|
|
96
|
+
});
|
|
78
97
|
}
|
|
79
98
|
};
|
|
80
99
|
|