@optimizely-opal/opal-tools-sdk 0.1.6-dev → 0.1.9-dev
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/README.md +201 -216
- package/dist/decorators.d.ts +2 -0
- package/dist/decorators.js +2 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +5 -4
- package/dist/models.d.ts +22 -1
- package/dist/models.js +28 -2
- package/dist/proteus.d.ts +1587 -0
- package/dist/proteus.js +98 -0
- package/dist/registerResource.d.ts +60 -0
- package/dist/registerResource.js +59 -0
- package/dist/registerTool.d.ts +18 -7
- package/dist/registerTool.js +52 -3
- package/dist/service.d.ts +15 -3
- package/dist/service.js +80 -21
- package/package.json +2 -2
- package/scripts/generate-proteus.ts +135 -0
- package/src/decorators.ts +4 -0
- package/src/index.ts +3 -2
- package/src/models.ts +27 -0
- package/src/proteus.ts +2314 -0
- package/src/registerResource.ts +82 -0
- package/src/registerTool.ts +19 -29
- package/src/service.ts +110 -23
- package/tests/integration.test.ts +252 -73
- package/tests/proteus.test.ts +122 -0
- package/dist/block.d.ts +0 -4760
- package/dist/block.js +0 -104
- package/scripts/generate-block.ts +0 -167
- package/src/block.ts +0 -11761
- package/tests/block.test.ts +0 -115
package/README.md
CHANGED
|
@@ -4,83 +4,36 @@ This SDK simplifies the creation of tools services compatible with the Opal Tool
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- Adaptive Block Document support for rich interactive UIs
|
|
11
|
-
- Runtime validation with Zod (registerTool only)
|
|
12
|
-
- Automatic discovery endpoint generation
|
|
7
|
+
- Easy definition of tool functions with decorators
|
|
8
|
+
- Automatic generation of discovery endpoints
|
|
9
|
+
- Parameter validation and type checking
|
|
13
10
|
- Authentication helpers
|
|
14
11
|
- Express integration
|
|
12
|
+
- Island components for interactive UI responses
|
|
15
13
|
|
|
16
14
|
## Installation
|
|
17
15
|
|
|
18
16
|
```bash
|
|
19
|
-
npm install @optimizely-opal/opal-tools-sdk
|
|
17
|
+
npm install @optimizely-opal/opal-tools-sdk
|
|
20
18
|
```
|
|
21
19
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
### `registerTool`
|
|
20
|
+
## Usage
|
|
25
21
|
|
|
26
22
|
```typescript
|
|
27
|
-
import
|
|
28
|
-
import
|
|
29
|
-
import { ToolsService, registerTool } from "@optimizely-opal/opal-tools-sdk";
|
|
23
|
+
import { ToolsService, tool, IslandResponse, IslandConfig } from '@optimizely-opal/opal-tools-sdk';
|
|
24
|
+
import express from 'express';
|
|
30
25
|
|
|
31
26
|
const app = express();
|
|
32
27
|
const toolsService = new ToolsService(app);
|
|
33
28
|
|
|
34
|
-
// ✨ Types are automatically inferred from the inputSchema!
|
|
35
|
-
const getWeather = registerTool(
|
|
36
|
-
"get_weather",
|
|
37
|
-
{
|
|
38
|
-
description: "Gets current weather for a location",
|
|
39
|
-
inputSchema: {
|
|
40
|
-
location: z.string().describe("City name or location"),
|
|
41
|
-
units: z
|
|
42
|
-
.enum(["metric", "imperial"])
|
|
43
|
-
.optional()
|
|
44
|
-
.describe("Temperature units"),
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
async (params) => {
|
|
48
|
-
// params.location is typed as string
|
|
49
|
-
// params.units is typed as 'metric' | 'imperial' | undefined
|
|
50
|
-
return { temperature: 22, condition: "sunny" };
|
|
51
|
-
},
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
app.listen(3000);
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Legacy `@tool` Decorator API
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
import { ToolsService, tool, ParameterType } from '@optimizely-opal/opal-tools-sdk';
|
|
61
|
-
|
|
62
29
|
interface WeatherParameters {
|
|
63
30
|
location: string;
|
|
64
|
-
units
|
|
31
|
+
units: string;
|
|
65
32
|
}
|
|
66
33
|
|
|
67
34
|
@tool({
|
|
68
35
|
name: 'get_weather',
|
|
69
|
-
description: 'Gets current weather for a location'
|
|
70
|
-
parameters: [
|
|
71
|
-
{
|
|
72
|
-
name: 'location',
|
|
73
|
-
type: ParameterType.String,
|
|
74
|
-
description: 'City name or location',
|
|
75
|
-
required: true,
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
name: 'units',
|
|
79
|
-
type: ParameterType.String,
|
|
80
|
-
description: 'Temperature units',
|
|
81
|
-
required: false,
|
|
82
|
-
},
|
|
83
|
-
],
|
|
36
|
+
description: 'Gets current weather for a location'
|
|
84
37
|
})
|
|
85
38
|
async function getWeather(parameters: WeatherParameters) {
|
|
86
39
|
// Implementation...
|
|
@@ -92,210 +45,242 @@ async function getWeather(parameters: WeatherParameters) {
|
|
|
92
45
|
|
|
93
46
|
## Authentication
|
|
94
47
|
|
|
95
|
-
|
|
48
|
+
The SDK provides two ways to require authentication for your tools:
|
|
96
49
|
|
|
97
|
-
###
|
|
50
|
+
### 1. Using the `@requiresAuth` decorator
|
|
98
51
|
|
|
99
52
|
```typescript
|
|
100
|
-
import {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
53
|
+
import { ToolsService, tool } from '@optimizely-opal/opal-tools-sdk';
|
|
54
|
+
import { requiresAuth } from '@optimizely-opal/opal-tools-sdk/auth';
|
|
55
|
+
import express from 'express';
|
|
56
|
+
|
|
57
|
+
const app = express();
|
|
58
|
+
const toolsService = new ToolsService(app);
|
|
59
|
+
|
|
60
|
+
interface CalendarParameters {
|
|
61
|
+
date: string;
|
|
62
|
+
timezone?: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Single authentication requirement
|
|
66
|
+
@requiresAuth({ provider: 'google', scopeBundle: 'calendar', required: true })
|
|
67
|
+
@tool({
|
|
68
|
+
name: 'get_calendar_events',
|
|
69
|
+
description: 'Gets calendar events for a date'
|
|
70
|
+
})
|
|
71
|
+
async function getCalendarEvents(parameters: CalendarParameters, authData?: any) {
|
|
72
|
+
// The authData parameter contains authentication information
|
|
73
|
+
const token = authData?.credentials?.token || '';
|
|
74
|
+
|
|
75
|
+
// Use the token to make authenticated requests
|
|
76
|
+
// ...
|
|
77
|
+
|
|
78
|
+
return { events: ['Meeting at 10:00', 'Lunch at 12:00'] };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Multiple authentication requirements (tool can work with either provider)
|
|
82
|
+
@requiresAuth({ provider: 'google', scopeBundle: 'calendar', required: true })
|
|
83
|
+
@requiresAuth({ provider: 'microsoft', scopeBundle: 'outlook', required: true })
|
|
84
|
+
@tool({
|
|
85
|
+
name: 'get_calendar_availability',
|
|
86
|
+
description: 'Check calendar availability'
|
|
87
|
+
})
|
|
88
|
+
async function getCalendarAvailability(parameters: CalendarParameters, authData?: any) {
|
|
89
|
+
const provider = authData?.provider || '';
|
|
90
|
+
const token = authData?.credentials?.token || '';
|
|
91
|
+
|
|
92
|
+
if (provider === 'google') {
|
|
93
|
+
// Use Google Calendar API
|
|
94
|
+
} else if (provider === 'microsoft') {
|
|
95
|
+
// Use Microsoft Outlook API
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return { available: true, provider_used: provider };
|
|
99
|
+
}
|
|
125
100
|
```
|
|
126
101
|
|
|
127
|
-
###
|
|
102
|
+
### 2. Specifying auth requirements in the `@tool` decorator
|
|
128
103
|
|
|
129
104
|
```typescript
|
|
105
|
+
interface EmailParameters {
|
|
106
|
+
limit?: number;
|
|
107
|
+
folder?: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
130
110
|
@tool({
|
|
131
|
-
name: '
|
|
132
|
-
description: 'Gets
|
|
133
|
-
parameters: [
|
|
134
|
-
{
|
|
135
|
-
name: 'date',
|
|
136
|
-
type: ParameterType.String,
|
|
137
|
-
description: 'Date in YYYY-MM-DD format',
|
|
138
|
-
required: true,
|
|
139
|
-
},
|
|
140
|
-
],
|
|
111
|
+
name: 'get_email',
|
|
112
|
+
description: 'Gets emails from the user\'s inbox',
|
|
141
113
|
authRequirements: {
|
|
142
114
|
provider: 'google',
|
|
143
|
-
scopeBundle: '
|
|
144
|
-
required: true
|
|
145
|
-
}
|
|
115
|
+
scopeBundle: 'gmail',
|
|
116
|
+
required: true
|
|
117
|
+
}
|
|
146
118
|
})
|
|
147
|
-
async function
|
|
148
|
-
|
|
149
|
-
return {
|
|
119
|
+
async function getEmail(parameters: EmailParameters, authData?: any) {
|
|
120
|
+
// Implementation...
|
|
121
|
+
return { emails: ['Email 1', 'Email 2'] };
|
|
150
122
|
}
|
|
151
123
|
```
|
|
152
124
|
|
|
153
|
-
##
|
|
154
|
-
|
|
155
|
-
Adaptive Block Documents enable rich, interactive UI responses with forms, buttons, and dynamic content.
|
|
125
|
+
## Authentication
|
|
156
126
|
|
|
157
|
-
|
|
127
|
+
The SDK provides authentication support for tools that require user credentials:
|
|
158
128
|
|
|
159
129
|
```typescript
|
|
160
|
-
import {
|
|
161
|
-
import
|
|
162
|
-
|
|
163
|
-
const createTask = registerTool(
|
|
164
|
-
"create_task",
|
|
165
|
-
{
|
|
166
|
-
description: "Create a new task",
|
|
167
|
-
type: "block", // Specify this is an Adaptive Block tool
|
|
168
|
-
inputSchema: {
|
|
169
|
-
title: z.string().describe("Task title"),
|
|
170
|
-
description: z.string().optional().describe("Task description"),
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
async (params) => {
|
|
174
|
-
// Return a BlockResponse (plain object with content/data/artifact/etc)
|
|
175
|
-
return {
|
|
176
|
-
content: Block.Document({
|
|
177
|
-
children: [
|
|
178
|
-
Block.Heading({ children: "Task Created!", level: "1" }),
|
|
179
|
-
Block.Text({ children: `Created: ${params.title}` }),
|
|
180
|
-
Block.Input({
|
|
181
|
-
name: "notes",
|
|
182
|
-
placeholder: "Add notes...",
|
|
183
|
-
value: params.description || "",
|
|
184
|
-
}),
|
|
185
|
-
],
|
|
186
|
-
actions: [
|
|
187
|
-
Block.Action({ name: "save", children: "Save Changes" }),
|
|
188
|
-
Block.Action({
|
|
189
|
-
name: "delete",
|
|
190
|
-
children: "Delete",
|
|
191
|
-
variant: "danger",
|
|
192
|
-
}),
|
|
193
|
-
],
|
|
194
|
-
}),
|
|
195
|
-
data: { task_id: "123", created_at: new Date().toISOString() },
|
|
196
|
-
artifact: {
|
|
197
|
-
type: "task",
|
|
198
|
-
id: "task-123",
|
|
199
|
-
data: { title: params.title },
|
|
200
|
-
},
|
|
201
|
-
};
|
|
202
|
-
},
|
|
203
|
-
);
|
|
204
|
-
```
|
|
130
|
+
import { ToolsService, tool, requiresAuth, AuthData } from '@optimizely-opal/opal-tools-sdk';
|
|
131
|
+
import express from 'express';
|
|
205
132
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
133
|
+
interface CalendarParameters {
|
|
134
|
+
date: string;
|
|
135
|
+
timezone?: string;
|
|
136
|
+
}
|
|
209
137
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
- `Block.Text()` - Text content
|
|
213
|
-
- `Block.Input()` - Text input fields
|
|
214
|
-
- `Block.Textarea()` - Multi-line text areas
|
|
215
|
-
- `Block.Checkbox()` - Checkbox inputs
|
|
216
|
-
- `Block.Select()` - Dropdown selects
|
|
217
|
-
- `Block.Button()` - Action buttons
|
|
218
|
-
- `Block.Action()` - Document-level actions
|
|
219
|
-
- `Block.List()` - Ordered/unordered lists
|
|
220
|
-
- `Block.Table()` - Data tables
|
|
221
|
-
- And more...
|
|
138
|
+
const app = express();
|
|
139
|
+
const toolsService = new ToolsService(app);
|
|
222
140
|
|
|
223
|
-
|
|
141
|
+
@requiresAuth({ provider: 'google', scopeBundle: 'calendar', required: true })
|
|
142
|
+
@tool({
|
|
143
|
+
name: 'get_calendar_events',
|
|
144
|
+
description: 'Gets calendar events for a date'
|
|
145
|
+
})
|
|
146
|
+
async function getCalendarEvents(parameters: CalendarParameters, authData?: AuthData) {
|
|
147
|
+
// The authData parameter contains authentication information
|
|
148
|
+
if (authData) {
|
|
149
|
+
const token = authData.credentials.access_token;
|
|
150
|
+
// Use the token to make authenticated requests
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return { events: ['Meeting at 10:00', 'Lunch at 12:00'] };
|
|
154
|
+
}
|
|
155
|
+
```
|
|
224
156
|
|
|
225
|
-
|
|
157
|
+
## Island Components
|
|
226
158
|
|
|
227
|
-
The
|
|
159
|
+
The SDK includes Island components for creating interactive UI responses:
|
|
228
160
|
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
|
|
161
|
+
```typescript
|
|
162
|
+
import {
|
|
163
|
+
ToolsService,
|
|
164
|
+
tool,
|
|
165
|
+
IslandResponse,
|
|
166
|
+
IslandConfig
|
|
167
|
+
} from '@optimizely-opal/opal-tools-sdk';
|
|
168
|
+
import express from 'express';
|
|
232
169
|
|
|
233
|
-
|
|
170
|
+
interface WeatherParameters {
|
|
171
|
+
location: string;
|
|
172
|
+
units?: string;
|
|
173
|
+
}
|
|
234
174
|
|
|
235
|
-
|
|
175
|
+
const app = express();
|
|
176
|
+
const toolsService = new ToolsService(app);
|
|
236
177
|
|
|
237
|
-
|
|
178
|
+
@tool({
|
|
179
|
+
name: 'get_weather',
|
|
180
|
+
description: 'Gets current weather for a location'
|
|
181
|
+
})
|
|
182
|
+
async function getWeather(parameters: WeatherParameters) {
|
|
183
|
+
// Get weather data (implementation details omitted)
|
|
184
|
+
const weatherData = { temperature: 22, condition: 'sunny', humidity: 65 };
|
|
185
|
+
|
|
186
|
+
// Create an interactive island for weather settings
|
|
187
|
+
const island = new IslandConfig(
|
|
188
|
+
[
|
|
189
|
+
new IslandConfig.Field(
|
|
190
|
+
'location',
|
|
191
|
+
'Location',
|
|
192
|
+
'string',
|
|
193
|
+
parameters.location
|
|
194
|
+
),
|
|
195
|
+
new IslandConfig.Field(
|
|
196
|
+
'units',
|
|
197
|
+
'Temperature Units',
|
|
198
|
+
'string',
|
|
199
|
+
parameters.units || 'metric',
|
|
200
|
+
false,
|
|
201
|
+
['metric', 'imperial', 'kelvin']
|
|
202
|
+
),
|
|
203
|
+
new IslandConfig.Field(
|
|
204
|
+
'current_temp',
|
|
205
|
+
'Current Temperature',
|
|
206
|
+
'string',
|
|
207
|
+
`${weatherData.temperature}°${parameters.units === 'metric' ? 'C' : 'F'}`
|
|
208
|
+
)
|
|
209
|
+
],
|
|
210
|
+
[
|
|
211
|
+
new IslandConfig.Action(
|
|
212
|
+
'refresh_weather',
|
|
213
|
+
'Refresh Weather',
|
|
214
|
+
'button',
|
|
215
|
+
'/tools/get_weather',
|
|
216
|
+
'update'
|
|
217
|
+
)
|
|
218
|
+
],
|
|
219
|
+
'button', // Optional island type
|
|
220
|
+
'plus' // Optional island icon
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
return IslandResponse.create([island]);
|
|
224
|
+
}
|
|
225
|
+
```
|
|
238
226
|
|
|
239
|
-
|
|
227
|
+
### Island Components
|
|
240
228
|
|
|
241
|
-
|
|
229
|
+
#### IslandConfig.Field
|
|
242
230
|
|
|
243
|
-
|
|
244
|
-
- `Credentials` - Access tokens and org details
|
|
245
|
-
- `Environment` - Execution context with auth data
|
|
231
|
+
Fields represent data inputs in the UI:
|
|
246
232
|
|
|
247
|
-
|
|
233
|
+
- `name`: Programmatic field identifier
|
|
234
|
+
- `label`: Human-readable label
|
|
235
|
+
- `type`: Field type (`'string'`, `'boolean'`, `'json'`)
|
|
236
|
+
- `value`: Current field value (optional)
|
|
237
|
+
- `hidden`: Whether to hide from user (optional, default: false)
|
|
238
|
+
- `options`: Available options for selection (optional)
|
|
248
239
|
|
|
249
|
-
|
|
250
|
-
- `Parameter` - Tool parameter definitions
|
|
251
|
-
- `Function` - Complete tool function definitions
|
|
240
|
+
#### IslandConfig.Action
|
|
252
241
|
|
|
253
|
-
|
|
242
|
+
Actions represent buttons or operations:
|
|
254
243
|
|
|
255
|
-
|
|
244
|
+
- `name`: Programmatic action identifier
|
|
245
|
+
- `label`: Human-readable button label
|
|
246
|
+
- `type`: UI element type (typically `'button'`)
|
|
247
|
+
- `endpoint`: API endpoint to call
|
|
248
|
+
- `operation`: Operation type (default: `'create'`)
|
|
256
249
|
|
|
257
|
-
|
|
250
|
+
#### IslandConfig
|
|
258
251
|
|
|
259
|
-
|
|
252
|
+
Contains the complete island configuration:
|
|
260
253
|
|
|
261
|
-
|
|
254
|
+
- `fields`: Array of IslandConfig.Field objects
|
|
255
|
+
- `actions`: Array of IslandConfig.Action objects
|
|
256
|
+
- `type`: Optional island type for custom rendering (optional)
|
|
257
|
+
- `icon`: Optional icon identifier for the island (optional)
|
|
262
258
|
|
|
263
|
-
|
|
259
|
+
#### IslandResponse
|
|
264
260
|
|
|
265
|
-
|
|
266
|
-
- `options: ToolOptions` - Configuration object
|
|
267
|
-
- `description: string` - Tool description (required)
|
|
268
|
-
- `inputSchema: Record<string, z.ZodTypeAny>` - Zod schema for parameters (required)
|
|
269
|
-
- `type?: 'json' | 'block'` - Response type (default: 'json')
|
|
270
|
-
- `authRequirements?` - Authentication requirements
|
|
271
|
-
- `handler: (params, extra?) => Result` - Tool implementation
|
|
272
|
-
- `params` - Validated input parameters (typed from schema)
|
|
273
|
-
- `extra?` - Optional extra context
|
|
274
|
-
- `mode: 'headless' | 'interactive'` - Execution mode
|
|
275
|
-
- `auth?: { provider, credentials }` - Auth data if provided
|
|
261
|
+
The response wrapper for islands:
|
|
276
262
|
|
|
277
|
-
|
|
263
|
+
- Use `IslandResponse.create([islands])` to create responses
|
|
264
|
+
- Supports multiple islands per response
|
|
278
265
|
|
|
279
|
-
|
|
266
|
+
## Type Definitions
|
|
280
267
|
|
|
281
|
-
|
|
268
|
+
The SDK provides comprehensive TypeScript type definitions:
|
|
282
269
|
|
|
283
|
-
|
|
270
|
+
### Authentication Types
|
|
284
271
|
|
|
285
|
-
- `
|
|
286
|
-
- `
|
|
287
|
-
- `
|
|
288
|
-
- `authRequirements?` - Authentication requirements
|
|
272
|
+
- `AuthData`: Interface containing provider and credentials information
|
|
273
|
+
- `Credentials`: Interface with access_token, org_sso_id, customer_id, instance_id, and product_sku
|
|
274
|
+
- `Environment`: Interface specifying execution mode (`'headless'` or `'interactive'`)
|
|
289
275
|
|
|
290
|
-
###
|
|
276
|
+
### Parameter Types
|
|
291
277
|
|
|
292
|
-
|
|
278
|
+
- `ParameterType`: Enum for supported parameter types
|
|
279
|
+
- `Parameter`: Class for tool parameter definitions
|
|
280
|
+
- `Function`: Class for complete tool function definitions
|
|
293
281
|
|
|
294
|
-
|
|
295
|
-
const toolsService = new ToolsService(app);
|
|
296
|
-
// Automatically creates /discovery endpoint
|
|
297
|
-
```
|
|
282
|
+
These types provide full IDE support and compile-time type checking for better development experience.
|
|
298
283
|
|
|
299
|
-
##
|
|
284
|
+
## Documentation
|
|
300
285
|
|
|
301
|
-
|
|
286
|
+
See full documentation for more examples and configuration options.
|
package/dist/decorators.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ interface ToolOptions {
|
|
|
15
15
|
description: string;
|
|
16
16
|
name: string;
|
|
17
17
|
parameters?: ParameterDefinition[];
|
|
18
|
+
uiResource?: string;
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
20
21
|
* Decorator to register a function as an Opal tool
|
|
@@ -24,6 +25,7 @@ interface ToolOptions {
|
|
|
24
25
|
* - authRequirements: (Optional) Authentication requirements
|
|
25
26
|
* Format: { provider: "oauth_provider", scopeBundle: "permissions_scope", required: true }
|
|
26
27
|
* Example: { provider: "google", scopeBundle: "calendar", required: true }
|
|
28
|
+
* - uiResource: (Optional) URI of associated UI resource for dynamic rendering (e.g., "ui://my-app/create-form")
|
|
27
29
|
*
|
|
28
30
|
* Note: If your tool requires authentication, define your handler function with two parameters:
|
|
29
31
|
* ```
|
package/dist/decorators.js
CHANGED
|
@@ -13,6 +13,7 @@ const registry_1 = require("./registry");
|
|
|
13
13
|
* - authRequirements: (Optional) Authentication requirements
|
|
14
14
|
* Format: { provider: "oauth_provider", scopeBundle: "permissions_scope", required: true }
|
|
15
15
|
* Example: { provider: "google", scopeBundle: "calendar", required: true }
|
|
16
|
+
* - uiResource: (Optional) URI of associated UI resource for dynamic rendering (e.g., "ui://my-app/create-form")
|
|
16
17
|
*
|
|
17
18
|
* Note: If your tool requires authentication, define your handler function with two parameters:
|
|
18
19
|
* ```
|
|
@@ -44,7 +45,7 @@ function tool(options) {
|
|
|
44
45
|
}
|
|
45
46
|
// Register the tool with all services
|
|
46
47
|
for (const service of registry_1.registry.services) {
|
|
47
|
-
service.registerTool(options.name, options.description, handler, parameters, endpoint, authRequirements);
|
|
48
|
+
service.registerTool(options.name, options.description, handler, parameters, endpoint, authRequirements, false, options.uiResource);
|
|
48
49
|
}
|
|
49
50
|
return isMethod ? descriptor : target;
|
|
50
51
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
2
|
export { requiresAuth } from "./auth";
|
|
3
|
-
export { Block, isBlockResponse } from "./block";
|
|
4
|
-
export type * from "./block";
|
|
5
3
|
export { tool } from "./decorators";
|
|
6
4
|
export * from "./models";
|
|
5
|
+
export { UI } from "./proteus";
|
|
6
|
+
export type * from "./proteus";
|
|
7
|
+
export { registerResource } from "./registerResource";
|
|
7
8
|
export { registerTool } from "./registerTool";
|
|
8
9
|
export type { RequestHandlerExtra } from "./registerTool";
|
|
9
10
|
export { ToolsService } from "./service";
|
package/dist/index.js
CHANGED
|
@@ -14,16 +14,17 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.ToolsService = exports.registerTool = exports.
|
|
17
|
+
exports.ToolsService = exports.registerTool = exports.registerResource = exports.UI = exports.tool = exports.requiresAuth = void 0;
|
|
18
18
|
require("reflect-metadata");
|
|
19
19
|
var auth_1 = require("./auth");
|
|
20
20
|
Object.defineProperty(exports, "requiresAuth", { enumerable: true, get: function () { return auth_1.requiresAuth; } });
|
|
21
|
-
var block_1 = require("./block");
|
|
22
|
-
Object.defineProperty(exports, "Block", { enumerable: true, get: function () { return block_1.Block; } });
|
|
23
|
-
Object.defineProperty(exports, "isBlockResponse", { enumerable: true, get: function () { return block_1.isBlockResponse; } });
|
|
24
21
|
var decorators_1 = require("./decorators");
|
|
25
22
|
Object.defineProperty(exports, "tool", { enumerable: true, get: function () { return decorators_1.tool; } });
|
|
26
23
|
__exportStar(require("./models"), exports);
|
|
24
|
+
var proteus_1 = require("./proteus");
|
|
25
|
+
Object.defineProperty(exports, "UI", { enumerable: true, get: function () { return proteus_1.UI; } });
|
|
26
|
+
var registerResource_1 = require("./registerResource");
|
|
27
|
+
Object.defineProperty(exports, "registerResource", { enumerable: true, get: function () { return registerResource_1.registerResource; } });
|
|
27
28
|
var registerTool_1 = require("./registerTool");
|
|
28
29
|
Object.defineProperty(exports, "registerTool", { enumerable: true, get: function () { return registerTool_1.registerTool; } });
|
|
29
30
|
var service_1 = require("./service");
|
package/dist/models.d.ts
CHANGED
|
@@ -64,6 +64,7 @@ export declare class Function {
|
|
|
64
64
|
parameters: Parameter[];
|
|
65
65
|
endpoint: string;
|
|
66
66
|
authRequirements?: AuthRequirement[] | undefined;
|
|
67
|
+
uiResource?: string | undefined;
|
|
67
68
|
/**
|
|
68
69
|
* HTTP method for the endpoint (default: POST)
|
|
69
70
|
*/
|
|
@@ -75,8 +76,9 @@ export declare class Function {
|
|
|
75
76
|
* @param parameters Function parameters
|
|
76
77
|
* @param endpoint API endpoint
|
|
77
78
|
* @param authRequirements Authentication requirements (optional)
|
|
79
|
+
* @param uiResource URI of associated UI resource for dynamic rendering (optional)
|
|
78
80
|
*/
|
|
79
|
-
constructor(name: string, description: string, parameters: Parameter[], endpoint: string, authRequirements?: AuthRequirement[] | undefined);
|
|
81
|
+
constructor(name: string, description: string, parameters: Parameter[], endpoint: string, authRequirements?: AuthRequirement[] | undefined, uiResource?: string | undefined);
|
|
80
82
|
/**
|
|
81
83
|
* Convert to JSON for the discovery endpoint
|
|
82
84
|
*/
|
|
@@ -287,3 +289,22 @@ export declare class Parameter {
|
|
|
287
289
|
type: ParameterType;
|
|
288
290
|
};
|
|
289
291
|
}
|
|
292
|
+
/**
|
|
293
|
+
* Resource definition for MCP resources
|
|
294
|
+
*/
|
|
295
|
+
export declare class Resource {
|
|
296
|
+
uri: string;
|
|
297
|
+
name: string;
|
|
298
|
+
description?: string | undefined;
|
|
299
|
+
mimeType?: string | undefined;
|
|
300
|
+
title?: string | undefined;
|
|
301
|
+
/**
|
|
302
|
+
* Create a new resource definition
|
|
303
|
+
* @param uri The unique URI for this resource (e.g., "ui://my-app/create-form")
|
|
304
|
+
* @param name Name of the resource
|
|
305
|
+
* @param description Description of the resource (optional)
|
|
306
|
+
* @param mimeType MIME type of the resource content (optional)
|
|
307
|
+
* @param title Human-readable title for the resource (optional)
|
|
308
|
+
*/
|
|
309
|
+
constructor(uri: string, name: string, description?: string | undefined, mimeType?: string | undefined, title?: string | undefined);
|
|
310
|
+
}
|
package/dist/models.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Parameter = exports.IslandResponse = exports.IslandResponseConfig = exports.IslandConfig = exports.IslandField = exports.IslandAction = exports.Function = exports.AuthRequirement = exports.ParameterType = void 0;
|
|
3
|
+
exports.Resource = exports.Parameter = exports.IslandResponse = exports.IslandResponseConfig = exports.IslandConfig = exports.IslandField = exports.IslandAction = exports.Function = exports.AuthRequirement = exports.ParameterType = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Types of parameters supported by Opal tools
|
|
6
6
|
*/
|
|
@@ -51,13 +51,15 @@ class Function {
|
|
|
51
51
|
* @param parameters Function parameters
|
|
52
52
|
* @param endpoint API endpoint
|
|
53
53
|
* @param authRequirements Authentication requirements (optional)
|
|
54
|
+
* @param uiResource URI of associated UI resource for dynamic rendering (optional)
|
|
54
55
|
*/
|
|
55
|
-
constructor(name, description, parameters, endpoint, authRequirements) {
|
|
56
|
+
constructor(name, description, parameters, endpoint, authRequirements, uiResource) {
|
|
56
57
|
this.name = name;
|
|
57
58
|
this.description = description;
|
|
58
59
|
this.parameters = parameters;
|
|
59
60
|
this.endpoint = endpoint;
|
|
60
61
|
this.authRequirements = authRequirements;
|
|
62
|
+
this.uiResource = uiResource;
|
|
61
63
|
/**
|
|
62
64
|
* HTTP method for the endpoint (default: POST)
|
|
63
65
|
*/
|
|
@@ -78,6 +80,9 @@ class Function {
|
|
|
78
80
|
if (this.authRequirements && this.authRequirements.length > 0) {
|
|
79
81
|
result.auth_requirements = this.authRequirements.map((auth) => auth.toJSON());
|
|
80
82
|
}
|
|
83
|
+
if (this.uiResource !== undefined) {
|
|
84
|
+
result.ui_resource = this.uiResource;
|
|
85
|
+
}
|
|
81
86
|
return result;
|
|
82
87
|
}
|
|
83
88
|
}
|
|
@@ -266,3 +271,24 @@ class Parameter {
|
|
|
266
271
|
}
|
|
267
272
|
}
|
|
268
273
|
exports.Parameter = Parameter;
|
|
274
|
+
/**
|
|
275
|
+
* Resource definition for MCP resources
|
|
276
|
+
*/
|
|
277
|
+
class Resource {
|
|
278
|
+
/**
|
|
279
|
+
* Create a new resource definition
|
|
280
|
+
* @param uri The unique URI for this resource (e.g., "ui://my-app/create-form")
|
|
281
|
+
* @param name Name of the resource
|
|
282
|
+
* @param description Description of the resource (optional)
|
|
283
|
+
* @param mimeType MIME type of the resource content (optional)
|
|
284
|
+
* @param title Human-readable title for the resource (optional)
|
|
285
|
+
*/
|
|
286
|
+
constructor(uri, name, description, mimeType, title) {
|
|
287
|
+
this.uri = uri;
|
|
288
|
+
this.name = name;
|
|
289
|
+
this.description = description;
|
|
290
|
+
this.mimeType = mimeType;
|
|
291
|
+
this.title = title;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
exports.Resource = Resource;
|