sunpeak 0.6.5 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/sunpeak.js +6 -6
- package/package.json +1 -1
- package/template/dist/chatgpt/{pizzaz.js → map.js} +3 -3
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Button.js +3 -3
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js +1 -1
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js +16 -16
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Textarea.js +3 -3
- package/template/node_modules/.vite/deps/_metadata.json +32 -32
- package/template/node_modules/.vite/deps/{chunk-LR7NKCX5.js → chunk-DQAZDQU3.js} +8 -8
- package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/template/src/components/index.ts +1 -1
- package/template/src/components/{pizzaz → map}/index.ts +1 -1
- package/template/src/components/map/map-view.test.tsx +146 -0
- package/template/src/components/{pizzaz → map}/map-view.tsx +2 -2
- package/template/src/components/{pizzaz/pizzaz.tsx → map/map.tsx} +7 -7
- package/template/src/components/map/place-card.test.tsx +76 -0
- package/template/src/components/{pizzaz → map}/place-card.tsx +1 -1
- package/template/src/components/map/place-carousel.test.tsx +84 -0
- package/template/src/components/{pizzaz → map}/place-carousel.tsx +1 -1
- package/template/src/components/map/place-inspector.test.tsx +91 -0
- package/template/src/components/{pizzaz → map}/place-inspector.tsx +2 -2
- package/template/src/components/map/place-list.test.tsx +97 -0
- package/template/src/components/{pizzaz → map}/place-list.tsx +1 -1
- package/template/src/resources/index.ts +1 -1
- package/template/src/resources/{pizzaz-resource.tsx → map-resource.tsx} +5 -5
- package/template/src/simulations/index.ts +2 -2
- package/template/src/simulations/{pizzaz-simulation.ts → map-simulation.ts} +9 -9
- /package/template/node_modules/.vite/deps/{chunk-LR7NKCX5.js.map → chunk-DQAZDQU3.js.map} +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
3
|
+
import { PlaceCarousel } from './place-carousel';
|
|
4
|
+
import type { Place } from '../../simulations/map-simulation';
|
|
5
|
+
|
|
6
|
+
describe('PlaceCarousel', () => {
|
|
7
|
+
const mockPlaces: Place[] = [
|
|
8
|
+
{
|
|
9
|
+
id: 'place-1',
|
|
10
|
+
name: 'First Place',
|
|
11
|
+
coords: [-122.4194, 37.7749],
|
|
12
|
+
description: 'First test place',
|
|
13
|
+
city: 'San Francisco',
|
|
14
|
+
rating: 4.5,
|
|
15
|
+
price: '$$',
|
|
16
|
+
thumbnail: 'https://example.com/1.jpg',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'place-2',
|
|
20
|
+
name: 'Second Place',
|
|
21
|
+
coords: [-122.4094, 37.7849],
|
|
22
|
+
description: 'Second test place',
|
|
23
|
+
city: 'Oakland',
|
|
24
|
+
rating: 4.2,
|
|
25
|
+
price: '$',
|
|
26
|
+
thumbnail: 'https://example.com/2.jpg',
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
it('renders all places in the carousel', () => {
|
|
31
|
+
render(<PlaceCarousel places={mockPlaces} selectedId={null} onSelect={vi.fn()} />);
|
|
32
|
+
|
|
33
|
+
expect(screen.getByText('First Place')).toBeInTheDocument();
|
|
34
|
+
expect(screen.getByText('Second Place')).toBeInTheDocument();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('calls onSelect with correct place when a place is clicked', () => {
|
|
38
|
+
const onSelect = vi.fn();
|
|
39
|
+
render(<PlaceCarousel places={mockPlaces} selectedId={null} onSelect={onSelect} />);
|
|
40
|
+
|
|
41
|
+
const firstPlace = screen.getByText('First Place');
|
|
42
|
+
fireEvent.click(firstPlace);
|
|
43
|
+
|
|
44
|
+
expect(onSelect).toHaveBeenCalledTimes(1);
|
|
45
|
+
expect(onSelect).toHaveBeenCalledWith(mockPlaces[0]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('highlights selected place', () => {
|
|
49
|
+
const { rerender } = render(
|
|
50
|
+
<PlaceCarousel places={mockPlaces} selectedId={null} onSelect={vi.fn()} />
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
rerender(<PlaceCarousel places={mockPlaces} selectedId="place-1" onSelect={vi.fn()} />);
|
|
54
|
+
|
|
55
|
+
const firstPlace = screen.getByText('First Place');
|
|
56
|
+
const card = firstPlace.closest('div[class*="rounded-2xl"]');
|
|
57
|
+
expect(card?.className).toContain('bg-black/5');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('renders empty carousel when no places provided', () => {
|
|
61
|
+
render(<PlaceCarousel places={[]} selectedId={null} onSelect={vi.fn()} />);
|
|
62
|
+
|
|
63
|
+
expect(screen.queryByText('First Place')).not.toBeInTheDocument();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('renders each place card with shadow and ring styles', () => {
|
|
67
|
+
const { container } = render(
|
|
68
|
+
<PlaceCarousel places={mockPlaces} selectedId={null} onSelect={vi.fn()} />
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const cards = container.querySelectorAll('div[class*="shadow-xl"]');
|
|
72
|
+
expect(cards.length).toBe(mockPlaces.length);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('renders carousel at bottom of viewport with correct positioning', () => {
|
|
76
|
+
const { container } = render(
|
|
77
|
+
<PlaceCarousel places={mockPlaces} selectedId={null} onSelect={vi.fn()} />
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const carousel = container.firstChild as HTMLElement;
|
|
81
|
+
expect(carousel.className).toContain('absolute');
|
|
82
|
+
expect(carousel.className).toContain('bottom-0');
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import useEmblaCarousel from 'embla-carousel-react';
|
|
3
3
|
import { cn } from '../../lib/index';
|
|
4
4
|
import { PlaceCard } from './place-card';
|
|
5
|
-
import type { Place } from '../../simulations/
|
|
5
|
+
import type { Place } from '../../simulations/map-simulation';
|
|
6
6
|
|
|
7
7
|
export type PlaceCarouselProps = {
|
|
8
8
|
places: Place[];
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
3
|
+
import { PlaceInspector } from './place-inspector';
|
|
4
|
+
import type { Place } from '../../simulations/map-simulation';
|
|
5
|
+
|
|
6
|
+
describe('PlaceInspector', () => {
|
|
7
|
+
const mockPlace: Place = {
|
|
8
|
+
id: 'test-place',
|
|
9
|
+
name: 'Test Pizza Place',
|
|
10
|
+
coords: [-122.4194, 37.7749],
|
|
11
|
+
description: 'Delicious test pizza',
|
|
12
|
+
city: 'San Francisco',
|
|
13
|
+
rating: 4.5,
|
|
14
|
+
price: '$$',
|
|
15
|
+
thumbnail: 'https://example.com/test.jpg',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
it('renders place details correctly', () => {
|
|
19
|
+
render(<PlaceInspector place={mockPlace} onClose={vi.fn()} />);
|
|
20
|
+
|
|
21
|
+
expect(screen.getByText('Test Pizza Place')).toBeInTheDocument();
|
|
22
|
+
expect(screen.getByText('4.5')).toBeInTheDocument();
|
|
23
|
+
expect(screen.getByText('$$', { exact: false })).toBeInTheDocument();
|
|
24
|
+
expect(screen.getByText('San Francisco', { exact: false })).toBeInTheDocument();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('renders place thumbnail with correct attributes', () => {
|
|
28
|
+
render(<PlaceInspector place={mockPlace} onClose={vi.fn()} />);
|
|
29
|
+
|
|
30
|
+
const image = screen.getByRole('img', { name: 'Test Pizza Place' });
|
|
31
|
+
expect(image).toHaveAttribute('src', 'https://example.com/test.jpg');
|
|
32
|
+
expect(image).toHaveAttribute('alt', 'Test Pizza Place');
|
|
33
|
+
expect(image).toHaveAttribute('loading', 'lazy');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('calls onClose when close button is clicked', () => {
|
|
37
|
+
const onClose = vi.fn();
|
|
38
|
+
render(<PlaceInspector place={mockPlace} onClose={onClose} />);
|
|
39
|
+
|
|
40
|
+
const closeButton = screen.getByLabelText('Close details');
|
|
41
|
+
fireEvent.click(closeButton);
|
|
42
|
+
|
|
43
|
+
expect(onClose).toHaveBeenCalledTimes(1);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('renders action buttons', () => {
|
|
47
|
+
render(<PlaceInspector place={mockPlace} onClose={vi.fn()} />);
|
|
48
|
+
|
|
49
|
+
expect(screen.getByText('Add to favorites')).toBeInTheDocument();
|
|
50
|
+
expect(screen.getByText('Contact')).toBeInTheDocument();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('renders reviews section with multiple reviews', () => {
|
|
54
|
+
render(<PlaceInspector place={mockPlace} onClose={vi.fn()} />);
|
|
55
|
+
|
|
56
|
+
expect(screen.getByText('Reviews')).toBeInTheDocument();
|
|
57
|
+
expect(screen.getByText('Leo M.')).toBeInTheDocument();
|
|
58
|
+
expect(screen.getByText('Priya S.')).toBeInTheDocument();
|
|
59
|
+
expect(screen.getByText('Maya R.')).toBeInTheDocument();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('renders review content correctly', () => {
|
|
63
|
+
render(<PlaceInspector place={mockPlace} onClose={vi.fn()} />);
|
|
64
|
+
|
|
65
|
+
expect(
|
|
66
|
+
screen.getByText('Fantastic crust and balanced toppings. The marinara is spot on!')
|
|
67
|
+
).toBeInTheDocument();
|
|
68
|
+
expect(
|
|
69
|
+
screen.getByText('Cozy vibe and friendly staff. Quick service on a Friday night.')
|
|
70
|
+
).toBeInTheDocument();
|
|
71
|
+
expect(
|
|
72
|
+
screen.getByText('Great for sharing. Will definitely come back with friends.')
|
|
73
|
+
).toBeInTheDocument();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('renders extended description', () => {
|
|
77
|
+
render(<PlaceInspector place={mockPlace} onClose={vi.fn()} />);
|
|
78
|
+
|
|
79
|
+
expect(
|
|
80
|
+
screen.getByText(/Enjoy a slice at one of SF's favorites/, { exact: false })
|
|
81
|
+
).toBeInTheDocument();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('formats rating to one decimal place', () => {
|
|
85
|
+
const placeWithRating = { ...mockPlace, rating: 4.789 };
|
|
86
|
+
render(<PlaceInspector place={placeWithRating} onClose={vi.fn()} />);
|
|
87
|
+
|
|
88
|
+
expect(screen.getByText('4.8')).toBeInTheDocument();
|
|
89
|
+
expect(screen.queryByText('4.789')).not.toBeInTheDocument();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -3,7 +3,7 @@ import { Button } from '@openai/apps-sdk-ui/components/Button';
|
|
|
3
3
|
import { Avatar } from '@openai/apps-sdk-ui/components/Avatar';
|
|
4
4
|
import { X, Star } from '@openai/apps-sdk-ui/components/Icon';
|
|
5
5
|
import { cn } from '../../lib/index';
|
|
6
|
-
import type { Place } from '../../simulations/
|
|
6
|
+
import type { Place } from '../../simulations/map-simulation';
|
|
7
7
|
|
|
8
8
|
export type PlaceInspectorProps = {
|
|
9
9
|
place: Place;
|
|
@@ -37,7 +37,7 @@ export const PlaceInspector = React.forwardRef<HTMLDivElement, PlaceInspectorPro
|
|
|
37
37
|
<div
|
|
38
38
|
ref={ref}
|
|
39
39
|
className={cn(
|
|
40
|
-
'
|
|
40
|
+
'map-inspector absolute z-30 top-0 bottom-4 left-0 right-auto xl:left-auto xl:right-6 md:z-20 w-[340px] xl:w-[360px] xl:top-6 xl:bottom-8 pointer-events-auto',
|
|
41
41
|
'animate-in fade-in slide-in-from-left-2 xl:slide-in-from-right-2 duration-200',
|
|
42
42
|
className
|
|
43
43
|
)}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
3
|
+
import { PlaceList } from './place-list';
|
|
4
|
+
import type { Place } from '../../simulations/map-simulation';
|
|
5
|
+
|
|
6
|
+
describe('PlaceList', () => {
|
|
7
|
+
const mockPlaces: Place[] = [
|
|
8
|
+
{
|
|
9
|
+
id: 'place-1',
|
|
10
|
+
name: 'First Place',
|
|
11
|
+
coords: [-122.4194, 37.7749],
|
|
12
|
+
description: 'First test place',
|
|
13
|
+
city: 'San Francisco',
|
|
14
|
+
rating: 4.5,
|
|
15
|
+
price: '$$',
|
|
16
|
+
thumbnail: 'https://example.com/1.jpg',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'place-2',
|
|
20
|
+
name: 'Second Place',
|
|
21
|
+
coords: [-122.4094, 37.7849],
|
|
22
|
+
description: 'Second test place',
|
|
23
|
+
city: 'Oakland',
|
|
24
|
+
rating: 4.2,
|
|
25
|
+
price: '$',
|
|
26
|
+
thumbnail: 'https://example.com/2.jpg',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'place-3',
|
|
30
|
+
name: 'Third Place',
|
|
31
|
+
coords: [-122.4294, 37.7649],
|
|
32
|
+
description: 'Third test place',
|
|
33
|
+
city: 'Berkeley',
|
|
34
|
+
rating: 4.8,
|
|
35
|
+
price: '$$$',
|
|
36
|
+
thumbnail: 'https://example.com/3.jpg',
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
it('renders all places in the list', () => {
|
|
41
|
+
render(<PlaceList places={mockPlaces} selectedId={null} onSelect={vi.fn()} />);
|
|
42
|
+
|
|
43
|
+
expect(screen.getByText('First Place')).toBeInTheDocument();
|
|
44
|
+
expect(screen.getByText('Second Place')).toBeInTheDocument();
|
|
45
|
+
expect(screen.getByText('Third Place')).toBeInTheDocument();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('displays correct number of results in header', () => {
|
|
49
|
+
render(<PlaceList places={mockPlaces} selectedId={null} onSelect={vi.fn()} />);
|
|
50
|
+
|
|
51
|
+
expect(screen.getByText('3 results')).toBeInTheDocument();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('calls onSelect with correct place when a place is clicked', () => {
|
|
55
|
+
const onSelect = vi.fn();
|
|
56
|
+
render(<PlaceList places={mockPlaces} selectedId={null} onSelect={onSelect} />);
|
|
57
|
+
|
|
58
|
+
const firstPlace = screen.getByText('First Place');
|
|
59
|
+
fireEvent.click(firstPlace);
|
|
60
|
+
|
|
61
|
+
expect(onSelect).toHaveBeenCalledTimes(1);
|
|
62
|
+
expect(onSelect).toHaveBeenCalledWith(mockPlaces[0]);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('highlights selected place', () => {
|
|
66
|
+
const { rerender } = render(
|
|
67
|
+
<PlaceList places={mockPlaces} selectedId={null} onSelect={vi.fn()} />
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
rerender(<PlaceList places={mockPlaces} selectedId="place-2" onSelect={vi.fn()} />);
|
|
71
|
+
|
|
72
|
+
const secondPlace = screen.getByText('Second Place');
|
|
73
|
+
const card = secondPlace.closest('div[class*="rounded-2xl"]');
|
|
74
|
+
expect(card?.className).toContain('bg-black/5');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('renders empty list when no places provided', () => {
|
|
78
|
+
render(<PlaceList places={[]} selectedId={null} onSelect={vi.fn()} />);
|
|
79
|
+
|
|
80
|
+
expect(screen.getByText('0 results')).toBeInTheDocument();
|
|
81
|
+
expect(screen.queryByText('First Place')).not.toBeInTheDocument();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('maintains selection when places update', () => {
|
|
85
|
+
const onSelect = vi.fn();
|
|
86
|
+
const { rerender } = render(
|
|
87
|
+
<PlaceList places={mockPlaces} selectedId="place-2" onSelect={onSelect} />
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const updatedPlaces = [...mockPlaces].reverse();
|
|
91
|
+
rerender(<PlaceList places={updatedPlaces} selectedId="place-2" onSelect={onSelect} />);
|
|
92
|
+
|
|
93
|
+
const secondPlace = screen.getByText('Second Place');
|
|
94
|
+
const card = secondPlace.closest('div[class*="rounded-2xl"]');
|
|
95
|
+
expect(card?.className).toContain('bg-black/5');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import { Settings } from '@openai/apps-sdk-ui/components/Icon';
|
|
3
3
|
import { cn } from '../../lib/index';
|
|
4
4
|
import { PlaceCard } from './place-card';
|
|
5
|
-
import type { Place } from '../../simulations/
|
|
5
|
+
import type { Place } from '../../simulations/map-simulation';
|
|
6
6
|
|
|
7
7
|
export type PlaceListProps = {
|
|
8
8
|
places: Place[];
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useSafeArea, useMaxHeight } from 'sunpeak';
|
|
3
|
-
import {
|
|
3
|
+
import { Map } from '../components/map/map';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Production-ready
|
|
6
|
+
* Production-ready Map Resource
|
|
7
7
|
*
|
|
8
8
|
* This resource displays a pizza restaurant finder with an interactive map,
|
|
9
9
|
* place listings, and detailed inspector view.
|
|
10
10
|
* Can be dropped into any production environment without changes.
|
|
11
11
|
*/
|
|
12
|
-
export const
|
|
12
|
+
export const MapResource = React.forwardRef<HTMLDivElement>((_props, ref) => {
|
|
13
13
|
const safeArea = useSafeArea();
|
|
14
14
|
const maxHeight = useMaxHeight();
|
|
15
15
|
|
|
@@ -25,8 +25,8 @@ export const PizzazResource = React.forwardRef<HTMLDivElement>((_props, ref) =>
|
|
|
25
25
|
maxHeight: maxHeight ?? undefined,
|
|
26
26
|
}}
|
|
27
27
|
>
|
|
28
|
-
<
|
|
28
|
+
<Map />
|
|
29
29
|
</div>
|
|
30
30
|
);
|
|
31
31
|
});
|
|
32
|
-
|
|
32
|
+
MapResource.displayName = 'MapResource';
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
import { counterSimulation } from './counter-simulation.js';
|
|
9
9
|
import { albumsSimulation } from './albums-simulation.js';
|
|
10
10
|
import { carouselSimulation } from './carousel-simulation.js';
|
|
11
|
-
import {
|
|
11
|
+
import { mapSimulation } from './map-simulation.js';
|
|
12
12
|
|
|
13
13
|
export const SIMULATIONS = {
|
|
14
14
|
counter: counterSimulation,
|
|
15
15
|
albums: albumsSimulation,
|
|
16
16
|
carousel: carouselSimulation,
|
|
17
|
-
|
|
17
|
+
map: mapSimulation,
|
|
18
18
|
} as const;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Server-safe configuration for the
|
|
2
|
+
* Server-safe configuration for the map simulation.
|
|
3
3
|
* This file contains only metadata and doesn't import React components or CSS.
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -16,11 +16,11 @@ export interface Place {
|
|
|
16
16
|
thumbnail: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export interface
|
|
19
|
+
export interface MapData extends Record<string, unknown> {
|
|
20
20
|
places: Place[];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const mapData: MapData = {
|
|
24
24
|
places: [
|
|
25
25
|
{
|
|
26
26
|
id: 'nova-slice-lab',
|
|
@@ -125,7 +125,7 @@ const pizzazData: PizzazData = {
|
|
|
125
125
|
],
|
|
126
126
|
};
|
|
127
127
|
|
|
128
|
-
export const
|
|
128
|
+
export const mapSimulation = {
|
|
129
129
|
userMessage: 'Find pizza near me',
|
|
130
130
|
|
|
131
131
|
// MCP Tool protocol - official Tool type from MCP SDK used in ListTools response
|
|
@@ -136,7 +136,7 @@ export const pizzazSimulation = {
|
|
|
136
136
|
title: 'Find Pizza',
|
|
137
137
|
annotations: { readOnlyHint: true },
|
|
138
138
|
_meta: {
|
|
139
|
-
'openai/outputTemplate': 'ui://
|
|
139
|
+
'openai/outputTemplate': 'ui://MapResource',
|
|
140
140
|
'openai/toolInvocation/invoking': 'Finding pizza places',
|
|
141
141
|
'openai/toolInvocation/invoked': 'Found pizza places',
|
|
142
142
|
'openai/widgetAccessible': true,
|
|
@@ -148,9 +148,9 @@ export const pizzazSimulation = {
|
|
|
148
148
|
// resource.name is used as the simulation identifier
|
|
149
149
|
// resource.title is used as the simulation display label
|
|
150
150
|
resource: {
|
|
151
|
-
uri: 'ui://
|
|
152
|
-
name: '
|
|
153
|
-
title: '
|
|
151
|
+
uri: 'ui://MapResource',
|
|
152
|
+
name: 'map',
|
|
153
|
+
title: 'Map',
|
|
154
154
|
description: 'Pizza restaurant finder widget',
|
|
155
155
|
mimeType: 'text/html+skybridge',
|
|
156
156
|
_meta: {
|
|
@@ -171,7 +171,7 @@ export const pizzazSimulation = {
|
|
|
171
171
|
|
|
172
172
|
// MCP CallTool protocol - data for CallTool response
|
|
173
173
|
toolCall: {
|
|
174
|
-
structuredContent:
|
|
174
|
+
structuredContent: mapData,
|
|
175
175
|
_meta: {},
|
|
176
176
|
},
|
|
177
177
|
} as const;
|
|
File without changes
|