@vertesia/create-plugin 0.79.1 → 0.80.0-dev-20251118
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 +68 -63
- package/package.json +15 -3
- package/templates/tool/.env.example +6 -0
- package/templates/tool/.vscode/launch.json +1 -1
- package/templates/tool/README.md +179 -20
- package/templates/tool/gitignore +26 -0
- package/templates/tool/rollup.config.js +30 -0
- package/templates/tool/src/collections/example/icon.svg.ts +6 -0
- package/templates/tool/src/collections/example/index.ts +14 -0
- package/templates/tool/src/collections/example/weather/WeatherTool.ts +32 -0
- package/templates/tool/src/collections/example/weather/manifest.ts +16 -0
- package/templates/tool/src/collections/index.ts +7 -0
- package/templates/tool/src/index.ts +4 -5
- package/templates/tool/src/server.ts +68 -16
- package/templates/tool/tsconfig.json +14 -4
- package/templates/tool/vite.config.js +46 -8
- package/templates/web/README.md +153 -51
- package/templates/web/eslint.config.js +2 -1
- package/templates/web/gitignore +25 -0
- package/templates/web/src/env.ts.tmpl +5 -11
- package/templates/web/vite.config.ts.tmpl +6 -4
- package/templates/tool/src/tools/WeatherTool.ts +0 -25
- package/templates/tool/vercel.json +0 -7
package/README.md
CHANGED
|
@@ -1,100 +1,105 @@
|
|
|
1
|
-
# @vertesia/create-
|
|
1
|
+
# @vertesia/create-plugin
|
|
2
2
|
|
|
3
|
-
This package
|
|
4
|
-
Vertesia agents are used to deploy custom workflows to Vertesia cloud.
|
|
3
|
+
This package scaffolds Vertesia plugin projects. Use it to create either:
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
- **Web Application Plugins**: React-based web applications that extend Vertesia Studio
|
|
6
|
+
- **Agent Tool Server**: Custom agent tools accessible via API endpoints
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
1. docker (with buildx support) installed locally.
|
|
10
|
-
2. vertesia CLI application. The CLI will be automatically installed when initializing the agent project if you didn't installed it previously.
|
|
8
|
+
Visit <https://vertesiahq.com> for more information about Vertesia.
|
|
11
9
|
|
|
12
|
-
##
|
|
10
|
+
## What Can You Create?
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
### Web Application Plugin (UI Extensions)
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
npm init @vertesia/agent
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Follow the instructions on screen. You need to define an organization and a name for your agent. The organization must be unique inside Vertesia and is usually the name of your Vertesia organization account. The agent name is identifying the project in your organization.
|
|
14
|
+
Vertesia web plugins are React-based web application that can be embedded into the Vertesia Studio interface. They allow you to create custom user experiences focused on specific use cases and business processes, while seamlessly leveraging all the vertesia platform features.
|
|
21
15
|
|
|
22
|
-
|
|
16
|
+
### Agent Tool Server
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
These generated files are containing a "Hello world!" workflow and activity as an example that you should remove and export your own definitions.
|
|
18
|
+
An Agent Tool Server extends the capabilities of AI agents in Vertesia. It allows you to:
|
|
26
19
|
|
|
20
|
+
- Create custom tools that agents can use
|
|
21
|
+
- Integrate with external APIs and services
|
|
22
|
+
- Organize tools into logical collections
|
|
23
|
+
- Expose tools via REST API endpoints
|
|
24
|
+
- Support authentication and context-aware execution
|
|
27
25
|
|
|
28
|
-
##
|
|
26
|
+
## Prerequisites
|
|
29
27
|
|
|
30
|
-
|
|
28
|
+
Before creating a plugin project, you need:
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
- Node.js and pnpm (or npm)
|
|
31
|
+
- Vertesia CLI
|
|
32
|
+
- An application manifest declared in Vertesia
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
### Declaring Your Web Application Plugin in Vertesia
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
2. Using `vertesia agent run` from your project root. This will run the agent worker in side the docker image you previously built. See the [Build](build-the-agent-docker-image) section.
|
|
36
|
+
Before you can develop and integrate your web application plugin with Vertesia, you must declare an application manifest in the Vertesia platform using the Vertesia CLI.
|
|
38
37
|
|
|
39
|
-
|
|
38
|
+
#### Install the Vertesia CLI
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
If not already done, install the Vertesia CLI and create a profile:
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g @vertesia/cli
|
|
44
|
+
vertesia profiles create
|
|
45
|
+
```
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
### Create the App Manifest
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
The agent should be packaged as a docker image and then published to the Vertesia cloud.
|
|
49
|
+
Create the app manifest using the Vertesia CLI:
|
|
51
50
|
|
|
52
|
-
|
|
51
|
+
```bash
|
|
52
|
+
vertesia apps create --manifest '{
|
|
53
|
+
"name": "my-app",
|
|
54
|
+
"title": "My App",
|
|
55
|
+
"description": "A sample app",
|
|
56
|
+
"publisher": "your-org",
|
|
57
|
+
"private": true,
|
|
58
|
+
"status": "beta"
|
|
59
|
+
}' --install
|
|
60
|
+
```
|
|
53
61
|
|
|
54
|
-
|
|
62
|
+
The `--install` flag will automatically install the app and grant permissions to the creator.
|
|
55
63
|
|
|
56
|
-
|
|
57
|
-
This image is only useable to test locally. You cannot push it to Vertesia.
|
|
64
|
+
**Important**: The `name` field from your manifest (e.g., `my-app`) is what you'll use as your plugin name in the next step.
|
|
58
65
|
|
|
59
|
-
|
|
66
|
+
## Initialize a Plugin Project
|
|
60
67
|
|
|
61
|
-
|
|
68
|
+
Run the initialization command:
|
|
62
69
|
|
|
63
|
-
```
|
|
64
|
-
|
|
70
|
+
```bash
|
|
71
|
+
npm init @vertesia/plugin
|
|
72
|
+
# or
|
|
73
|
+
pnpm create @vertesia/plugin
|
|
65
74
|
```
|
|
66
75
|
|
|
67
|
-
|
|
68
|
-
Examples: `1.0.0`, `1.0.0-rc1`.
|
|
76
|
+
You will be prompted to choose a template and provide configuration:
|
|
69
77
|
|
|
70
|
-
|
|
78
|
+
### Prompts
|
|
71
79
|
|
|
72
|
-
|
|
80
|
+
1. **Template type**: Choose between:
|
|
81
|
+
- **Web application plugin**: For UI extensions
|
|
82
|
+
- **Agent tool server**: For custom agent tools
|
|
83
|
+
2. **Package manager**: Choose between npm or pnpm
|
|
84
|
+
3. **Plugin name**: Use kebab-case (e.g., my-plugin or my-tools)
|
|
85
|
+
4. **Plugin version**: Semantic version (e.g., 1.0.0)
|
|
86
|
+
5. **Description**: Optional description of your plugin
|
|
73
87
|
|
|
74
|
-
|
|
88
|
+
### Web Application Plugin Specific
|
|
75
89
|
|
|
76
|
-
|
|
77
|
-
vertesia agent publish <version>
|
|
78
|
-
```
|
|
90
|
+
If you select the **Web application plugin** template, you'll also be asked:
|
|
79
91
|
|
|
80
|
-
|
|
92
|
+
1. **Isolation strategy**:
|
|
93
|
+
- **Shadow DOM**: Fully isolated plugin using Shadow DOM (recommended)
|
|
94
|
+
- **CSS-only isolation**: Lighter isolation using CSS scope, but may have style conflicts
|
|
81
95
|
|
|
82
|
-
|
|
96
|
+
## Working with Plugins
|
|
83
97
|
|
|
84
|
-
|
|
85
|
-
vertesia agent publish <version> --push-only
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
The you can deploy an agent that you previously uploaded to Vertesia by using the command:
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
vertesia agent publish <version> --deploy-only
|
|
92
|
-
```
|
|
98
|
+
After creating your project, see the README file in the generated project for comprehensive development instructions.
|
|
93
99
|
|
|
94
|
-
##
|
|
100
|
+
## Support
|
|
95
101
|
|
|
96
|
-
|
|
102
|
+
For issues, questions, or feature requests:
|
|
97
103
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
```
|
|
104
|
+
- [GitHub Issues](https://github.com/vertesia/composableai/issues)
|
|
105
|
+
- [Documentation](https://docs.vertesiahq.com/)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertesia/create-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.80.0-dev-20251118",
|
|
4
4
|
"description": "Initialize a Vertesia plugin package",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"eslint": "eslint './src/**/*.{jsx,js,tsx,ts}'",
|
|
25
|
-
"build": "rm -rf ./lib ./tsconfig.tsbuildinfo && tsc --build",
|
|
25
|
+
"build": "rm -rf ./lib ./tsconfig.tsbuildinfo && pnpm run typecheck:templates && tsc --build",
|
|
26
|
+
"typecheck:templates": "tsc --noEmit --project templates/tool/tsconfig.json",
|
|
26
27
|
"clean": "rimraf ./node_modules ./lib ./tsconfig.tsbuildinfo"
|
|
27
28
|
},
|
|
28
29
|
"dependencies": {
|
|
@@ -32,6 +33,17 @@
|
|
|
32
33
|
"devDependencies": {
|
|
33
34
|
"@types/hasbin": "^1.2.2",
|
|
34
35
|
"@types/node": "^22.5.0",
|
|
35
|
-
"typescript": "^5.7.2"
|
|
36
|
+
"typescript": "^5.7.2",
|
|
37
|
+
"hono": "^4.10.3",
|
|
38
|
+
"@hono/node-server": "^1.19.5",
|
|
39
|
+
"@llumiverse/common": "workspace:*",
|
|
40
|
+
"@vertesia/client": "workspace:*",
|
|
41
|
+
"@vertesia/common": "workspace:*",
|
|
42
|
+
"@vertesia/tools-sdk": "workspace:*"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "https://github.com/vertesia/composableai.git",
|
|
47
|
+
"directory": "packages/create-plugin"
|
|
36
48
|
}
|
|
37
49
|
}
|
package/templates/tool/README.md
CHANGED
|
@@ -1,31 +1,190 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Tool Collections
|
|
2
2
|
|
|
3
|
-
This
|
|
4
|
-
1. `GET /` - show tool descriptions
|
|
5
|
-
2. `POST /` - execute a tool given an execution payload.
|
|
3
|
+
This project contains custom tool collections for Vertesia.
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
## Project Structure
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
```txt
|
|
8
|
+
src/
|
|
9
|
+
├── collections/ # Tool collections
|
|
10
|
+
│ ├── example/ # Example collection
|
|
11
|
+
│ │ ├── icon.svg.ts # Collection icon
|
|
12
|
+
│ │ ├── index.ts # Collection definition
|
|
13
|
+
│ │ └── weather/ # Weather tool
|
|
14
|
+
│ │ ├── manifest.ts # Tool schema/metadata
|
|
15
|
+
│ │ └── WeatherTool.ts # Tool implementation
|
|
16
|
+
│ └── index.ts # Export all collections
|
|
17
|
+
├── server.ts # Hono server with collection endpoints
|
|
18
|
+
└── index.ts # Main exports
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Development
|
|
22
|
+
|
|
23
|
+
Start the development server:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm install
|
|
27
|
+
pnpm dev
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The server will be available at `http://localhost:5174/api`
|
|
31
|
+
|
|
32
|
+
### API Endpoints
|
|
11
33
|
|
|
12
|
-
|
|
34
|
+
- `GET /api` - List all collections
|
|
35
|
+
- `GET /api/{collection}` - Get collection metadata and tool definitions
|
|
36
|
+
- `POST /api/{collection}` - Execute a tool in the collection
|
|
13
37
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
38
|
+
### Testing the API
|
|
39
|
+
|
|
40
|
+
Get the example collection tools:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
curl http://localhost:5174/api/example
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Execute the weather tool:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl -X POST http://localhost:5174/api/example \
|
|
50
|
+
-H "Content-Type: application/json" \
|
|
51
|
+
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
52
|
+
-d '{
|
|
53
|
+
"tool_use": {
|
|
54
|
+
"id": "test-123",
|
|
55
|
+
"tool_name": "weather",
|
|
56
|
+
"tool_input": {
|
|
57
|
+
"location": "New York, NY"
|
|
20
58
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
59
|
+
}
|
|
60
|
+
}'
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Creating New Tools
|
|
64
|
+
|
|
65
|
+
### 1. Create a new tool in an existing collection
|
|
66
|
+
|
|
67
|
+
1. Create a new directory under `src/collections/example/` (e.g., `my-tool/`)
|
|
68
|
+
2. Create `manifest.ts` with your tool's schema
|
|
69
|
+
3. Create `MyTool.ts` with the implementation
|
|
70
|
+
4. Add the tool to `src/collections/example/index.ts`
|
|
71
|
+
|
|
72
|
+
### 2. Create a new collection
|
|
73
|
+
|
|
74
|
+
1. Create a new directory under `src/collections/` (e.g., `my-collection/`)
|
|
75
|
+
2. Create `icon.svg.ts` with an SVG icon
|
|
76
|
+
3. Create `index.ts` to define the collection
|
|
77
|
+
4. Add your tools in subdirectories
|
|
78
|
+
5. Export the collection in `src/collections/index.ts`
|
|
79
|
+
|
|
80
|
+
## Authentication
|
|
81
|
+
|
|
82
|
+
Tools receive authentication context through the `ToolExecutionContext` parameter:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
export async function myTool(
|
|
86
|
+
payload: ToolExecutionPayload<MyToolParams>,
|
|
87
|
+
context: ToolExecutionContext
|
|
88
|
+
) {
|
|
89
|
+
// Access the decoded JWT token
|
|
90
|
+
const userId = context.payload.sub;
|
|
91
|
+
|
|
92
|
+
// Get a Vertesia client instance
|
|
93
|
+
const client = await context.getClient();
|
|
94
|
+
|
|
95
|
+
// Your tool logic here
|
|
96
|
+
return {
|
|
97
|
+
is_error: false,
|
|
98
|
+
content: "Tool result"
|
|
99
|
+
};
|
|
24
100
|
}
|
|
25
101
|
```
|
|
26
102
|
|
|
27
|
-
|
|
103
|
+
## Building for Production
|
|
104
|
+
|
|
105
|
+
Build the project:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
pnpm build
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This creates an optimized build in the `dist/` directory.
|
|
112
|
+
|
|
113
|
+
## Deployment
|
|
114
|
+
|
|
115
|
+
Your Agent Tool Server can be deployed to various platforms. The server is built with Hono, which supports multiple runtimes including Node.js, Vercel Edge Functions, Cloudflare Workers, AWS Lambda, and more.
|
|
116
|
+
|
|
117
|
+
For detailed guides on deploying to different platforms, visit the [Hono documentation](https://hono.dev/docs/). The documentation provides comprehensive examples for various deployment targets and runtimes.
|
|
118
|
+
|
|
119
|
+
### Deploying to Vercel (Example)
|
|
120
|
+
|
|
121
|
+
This section demonstrates deploying to Vercel as an example, since Vercel offers a generous free tier and simple deployment process. The project includes `api/index.ts` which serves as the entry point for Vercel deployment using the Hono Vercel adapter. Vercel automatically detects and configures the Edge Function.
|
|
122
|
+
|
|
123
|
+
#### Setup
|
|
124
|
+
|
|
125
|
+
Install the Vercel CLI globally:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npm i -g vercel
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Deployment Steps
|
|
132
|
+
|
|
133
|
+
1. **Login to Vercel**:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
vercel login
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
2. **Deploy to preview**:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
vercel
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This will create a preview deployment and provide you with a URL to test your tool server.
|
|
146
|
+
|
|
147
|
+
3. **Deploy to production**:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
vercel --prod
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Your tool server will be available at `https://your-project.vercel.app/api`
|
|
154
|
+
|
|
155
|
+
For more information, visit the [Vercel CLI documentation](https://vercel.com/docs/cli).
|
|
156
|
+
|
|
157
|
+
#### Verify Your Deployment
|
|
158
|
+
|
|
159
|
+
Test that your server is responding correctly:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
curl https://your-project.vercel.app/api
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
You should see a JSON response with the API information and available endpoints.
|
|
166
|
+
|
|
167
|
+
#### Configure Your Tool Server in Vertesia
|
|
168
|
+
|
|
169
|
+
After deploying to Vercel, update your app manifest to point to the deployed URL using the vertesia CLI:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
vertesia apps update <appId> --manifest '{
|
|
173
|
+
"name": "my-app",
|
|
174
|
+
"title": "My App",
|
|
175
|
+
"description": "A sample app",
|
|
176
|
+
"publisher": "your-org",
|
|
177
|
+
"private": true,
|
|
178
|
+
"status": "beta",
|
|
179
|
+
"tool_collections": [
|
|
180
|
+
"https://your-app.vercel.app/api/example"
|
|
181
|
+
],
|
|
182
|
+
}'
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Replace `appId` by the actual ID and `https://your-app.vercel.app` with your actual Vercel deployment URL.
|
|
28
186
|
|
|
29
|
-
|
|
187
|
+
## Learn More
|
|
30
188
|
|
|
31
|
-
|
|
189
|
+
- [Vertesia Documentation](https://docs.vertesiahq.com)
|
|
190
|
+
- [Tool SDK Reference](https://github.com/vertesia/composableai/tree/main/packages/tools-sdk)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import commonjs from '@rollup/plugin-commonjs';
|
|
2
|
+
import json from '@rollup/plugin-json';
|
|
3
|
+
import resolve from '@rollup/plugin-node-resolve';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
input: './dist/server.js',
|
|
7
|
+
output: {
|
|
8
|
+
file: './dist/bundle.js',
|
|
9
|
+
format: 'es',
|
|
10
|
+
sourcemap: false
|
|
11
|
+
},
|
|
12
|
+
plugins: [
|
|
13
|
+
resolve({
|
|
14
|
+
preferBuiltins: true,
|
|
15
|
+
exportConditions: ['node']
|
|
16
|
+
}),
|
|
17
|
+
commonjs(),
|
|
18
|
+
json()
|
|
19
|
+
],
|
|
20
|
+
external: [
|
|
21
|
+
// Keep these as external dependencies
|
|
22
|
+
'hono',
|
|
23
|
+
'jose',
|
|
24
|
+
'dotenv',
|
|
25
|
+
'@vertesia/client',
|
|
26
|
+
'@vertesia/common',
|
|
27
|
+
'@vertesia/tools-sdk',
|
|
28
|
+
'@hono/node-server'
|
|
29
|
+
]
|
|
30
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Simple SVG icon for the collection
|
|
2
|
+
// You can replace this with your own icon
|
|
3
|
+
export const icon = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
4
|
+
<circle cx="12" cy="12" r="10"/>
|
|
5
|
+
<path d="M12 6v6l4 2"/>
|
|
6
|
+
</svg>`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ToolCollection } from "@vertesia/tools-sdk";
|
|
2
|
+
import { icon } from "./icon.svg.js";
|
|
3
|
+
import { WeatherTool } from "./weather/WeatherTool.js";
|
|
4
|
+
|
|
5
|
+
export const ExampleCollection = new ToolCollection({
|
|
6
|
+
name: "example",
|
|
7
|
+
title: "Example Tools",
|
|
8
|
+
description: "A collection of example tools to get you started",
|
|
9
|
+
icon,
|
|
10
|
+
tools: [
|
|
11
|
+
WeatherTool
|
|
12
|
+
// Add more tools here
|
|
13
|
+
]
|
|
14
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Tool, ToolExecutionPayload, ToolExecutionContext } from "@vertesia/tools-sdk";
|
|
2
|
+
import manifest from "./manifest.js";
|
|
3
|
+
import { ToolResultContent } from "@vertesia/common";
|
|
4
|
+
|
|
5
|
+
interface WeatherToolParams {
|
|
6
|
+
location: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Tool implementation function
|
|
10
|
+
export async function weather(
|
|
11
|
+
payload: ToolExecutionPayload<WeatherToolParams>,
|
|
12
|
+
context: ToolExecutionContext
|
|
13
|
+
) {
|
|
14
|
+
const { location } = payload.tool_use.tool_input!;
|
|
15
|
+
|
|
16
|
+
console.log(`Caller: ${context.payload.user_id}`);
|
|
17
|
+
|
|
18
|
+
// Simulate fetching weather data
|
|
19
|
+
// In a real implementation, you would call a weather API here
|
|
20
|
+
// You can use context.getClient() to access Vertesia services if needed
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
is_error: false,
|
|
24
|
+
content: `The current weather in ${location} is sunny with a temperature of 75°F.`
|
|
25
|
+
} satisfies ToolResultContent;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Export the complete tool with manifest and implementation
|
|
29
|
+
export const WeatherTool = {
|
|
30
|
+
...manifest,
|
|
31
|
+
run: weather
|
|
32
|
+
} satisfies Tool<WeatherToolParams>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ToolDefinition } from "@vertesia/tools-sdk";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
name: "weather",
|
|
5
|
+
description: "Get the current weather for a given location.",
|
|
6
|
+
input_schema: {
|
|
7
|
+
type: "object",
|
|
8
|
+
properties: {
|
|
9
|
+
location: {
|
|
10
|
+
type: "string",
|
|
11
|
+
description: "The location to get the weather for, e.g., 'New York, NY'."
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
required: ["location"]
|
|
15
|
+
},
|
|
16
|
+
} satisfies ToolDefinition;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// Export collections for use in other modules or for programmatic access
|
|
2
|
+
export { collections } from "./collections/index.js";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
]);
|
|
4
|
+
// Export server as default for deployment
|
|
5
|
+
export { default } from "./server.js";
|
|
@@ -1,19 +1,71 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { cors } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { ToolCollection } from "@vertesia/tools-sdk";
|
|
2
|
+
import { Context, Hono } from "hono";
|
|
3
|
+
import { cors } from "hono/cors";
|
|
4
|
+
import { collections } from "./collections/index.js";
|
|
5
|
+
import { HTTPException } from "hono/http-exception";
|
|
6
|
+
|
|
7
|
+
function createServer(collections: ToolCollection[], prefix = '/api') {
|
|
8
|
+
prefix = prefix.trim();
|
|
9
|
+
const app = new Hono();
|
|
10
|
+
|
|
11
|
+
// Add CORS middleware globally
|
|
12
|
+
app.use('*', cors({ origin: '*', allowMethods: ['GET', 'POST', 'OPTIONS'] }));
|
|
13
|
+
|
|
14
|
+
// Add base API route
|
|
15
|
+
app.get(prefix, (c) => {
|
|
16
|
+
return c.json({
|
|
17
|
+
message: 'Tool Collections API',
|
|
18
|
+
version: '1.0.0',
|
|
19
|
+
endpoints: {
|
|
20
|
+
collections: collections.map(col => `${prefix}/${col.name}`)
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Create endpoints for tool collections
|
|
26
|
+
for (const col of collections) {
|
|
27
|
+
app.route(`${prefix}/${col.name}`, createCollectionEndpoints(col));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Global error handler
|
|
31
|
+
app.onError((err, c) => {
|
|
32
|
+
if (err instanceof HTTPException) {
|
|
33
|
+
return c.json({
|
|
34
|
+
error: err.message,
|
|
35
|
+
}, err.status);
|
|
36
|
+
}
|
|
37
|
+
console.error('Uncaught Error:', err);
|
|
38
|
+
return c.json({
|
|
39
|
+
error: 'Internal Server Error',
|
|
40
|
+
}, 500)
|
|
12
41
|
})
|
|
13
|
-
})
|
|
14
42
|
|
|
15
|
-
app
|
|
16
|
-
|
|
17
|
-
|
|
43
|
+
return app;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const server = createServer(collections);
|
|
47
|
+
|
|
48
|
+
export default server;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Create endpoints for a tool collection
|
|
52
|
+
*/
|
|
53
|
+
function createCollectionEndpoints(coll: ToolCollection) {
|
|
54
|
+
const endpoint = new Hono();
|
|
55
|
+
|
|
56
|
+
// POST endpoint to execute tools
|
|
57
|
+
endpoint.post('/', (c: Context) => {
|
|
58
|
+
return coll.execute(c);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// GET endpoint to retrieve collection metadata and tool definitions
|
|
62
|
+
endpoint.get('/', (c) => {
|
|
63
|
+
return c.json({
|
|
64
|
+
title: coll.title || coll.name,
|
|
65
|
+
description: coll.description,
|
|
66
|
+
tools: coll.getToolDefinitions()
|
|
67
|
+
});
|
|
68
|
+
});
|
|
18
69
|
|
|
19
|
-
|
|
70
|
+
return endpoint;
|
|
71
|
+
}
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
"target": "
|
|
3
|
+
"target": "ES2022",
|
|
4
4
|
"module": "ESNext",
|
|
5
|
-
"moduleResolution": "
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
6
|
"esModuleInterop": true,
|
|
7
7
|
"strict": true,
|
|
8
8
|
"skipLibCheck": true,
|
|
9
|
+
"resolveJsonModule": true,
|
|
10
|
+
"allowSyntheticDefaultImports": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"noUnusedLocals": true,
|
|
13
|
+
"noUnusedParameters": true,
|
|
14
|
+
"noImplicitReturns": true,
|
|
9
15
|
"outDir": "dist"
|
|
10
16
|
},
|
|
11
17
|
"include": [
|
|
12
|
-
"src"
|
|
18
|
+
"src/**/*"
|
|
19
|
+
],
|
|
20
|
+
"exclude": [
|
|
21
|
+
"node_modules",
|
|
22
|
+
"dist"
|
|
13
23
|
]
|
|
14
|
-
}
|
|
24
|
+
}
|
|
@@ -1,10 +1,48 @@
|
|
|
1
|
-
import { defineConfig } from 'vite';
|
|
2
1
|
import devServer from '@hono/vite-dev-server';
|
|
2
|
+
import { defineConfig, loadEnv } from 'vite';
|
|
3
3
|
|
|
4
|
-
export default defineConfig({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
export default defineConfig(({ mode }) => {
|
|
5
|
+
// Load env files
|
|
6
|
+
const env = loadEnv(mode, process.cwd(), '');
|
|
7
|
+
|
|
8
|
+
// Dev config
|
|
9
|
+
if (mode === 'development') {
|
|
10
|
+
return {
|
|
11
|
+
plugins: [
|
|
12
|
+
devServer({
|
|
13
|
+
prefix: '/api', // mount the tool endpoints under /api
|
|
14
|
+
entry: './src/server.ts',
|
|
15
|
+
}),
|
|
16
|
+
],
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Build config
|
|
21
|
+
return {
|
|
22
|
+
build: {
|
|
23
|
+
minify: false,
|
|
24
|
+
lib: {
|
|
25
|
+
entry: {
|
|
26
|
+
server: './src/server.ts',
|
|
27
|
+
},
|
|
28
|
+
formats: ['es']
|
|
29
|
+
},
|
|
30
|
+
rollupOptions: {
|
|
31
|
+
external: (id) => {
|
|
32
|
+
// Keep relative imports as part of the bundle
|
|
33
|
+
if (id.startsWith('.') || id.startsWith('/')) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
// Externalize all node modules and absolute imports
|
|
37
|
+
return true;
|
|
38
|
+
},
|
|
39
|
+
output: {
|
|
40
|
+
preserveModules: true,
|
|
41
|
+
preserveModulesRoot: 'src',
|
|
42
|
+
entryFileNames: '[name].js'
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
outDir: 'dist'
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
});
|
package/templates/web/README.md
CHANGED
|
@@ -1,54 +1,156 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
1
|
+
# Vertesia Custom App Sample
|
|
2
|
+
|
|
3
|
+
A sample project demonstrating how to build a custom app/plugin for the Vertesia platform using React, TypeScript, and Vite.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This project serves as a template for building Vertesia plugins that can be integrated into the Vertesia platform. It includes:
|
|
8
|
+
|
|
9
|
+
- React 19 with TypeScript for type-safe component development
|
|
10
|
+
- Tailwind CSS for styling
|
|
11
|
+
- Vite for fast development and optimized builds
|
|
12
|
+
- Dual build modes: standalone app and plugin library
|
|
13
|
+
|
|
14
|
+
## Project Structure
|
|
15
|
+
|
|
16
|
+
```txt
|
|
17
|
+
src/
|
|
18
|
+
├── app.tsx # Main app component with router
|
|
19
|
+
├── plugin.tsx # Plugin entry point for Vertesia integration
|
|
20
|
+
├── routes.tsx # Application route definitions
|
|
21
|
+
├── pages.tsx # Page components
|
|
22
|
+
└── main.tsx # Dev mode entry point
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Getting Started
|
|
26
|
+
|
|
27
|
+
### Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm install
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Development
|
|
34
|
+
|
|
35
|
+
Run the app in development mode with hot module replacement:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pnpm dev
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The app will be available at `https://localhost:5173`.
|
|
42
|
+
|
|
43
|
+
### Building
|
|
44
|
+
|
|
45
|
+
Build both standalone app and plugin library:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pnpm build
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or build individually:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Build standalone app
|
|
55
|
+
pnpm build:app
|
|
56
|
+
|
|
57
|
+
# Build plugin library
|
|
58
|
+
pnpm build:lib
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The plugin library will be output to the `dist/lib/` directory.
|
|
62
|
+
|
|
63
|
+
## Deployment
|
|
64
|
+
|
|
65
|
+
Since this is a standard web application, you can deploy it to any static hosting provider (Vercel, Netlify, Cloudflare Pages, AWS S3, etc.).
|
|
66
|
+
|
|
67
|
+
### Deploying to Vercel
|
|
68
|
+
|
|
69
|
+
Vercel is a practical deployment option with a generous free tier. You can very simply deploy your standalone app using the Vercel CLI.
|
|
70
|
+
|
|
71
|
+
#### Setup
|
|
72
|
+
|
|
73
|
+
Install the Vercel CLI globally:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm i -g vercel
|
|
32
77
|
```
|
|
33
78
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
79
|
+
#### Deployment Steps
|
|
80
|
+
|
|
81
|
+
1. **Login to Vercel**:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
vercel login
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
2. **Deploy to preview**:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
vercel
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This will create a preview deployment and provide you with a URL to test your app.
|
|
94
|
+
|
|
95
|
+
3. **Deploy to production**:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
vercel --prod
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
For more information, visit the [Vercel CLI documentation](https://vercel.com/docs/cli).
|
|
102
|
+
|
|
103
|
+
#### Update App Manifest with Deployment URL
|
|
104
|
+
|
|
105
|
+
After deploying to Vercel, update your app manifest to point to the deployed URL using the vertesia CLI:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
vertesia apps update <appId> --manifest '{
|
|
109
|
+
"name": "my-app",
|
|
110
|
+
"title": "My App",
|
|
111
|
+
"description": "A sample app",
|
|
112
|
+
"publisher": "your-org",
|
|
113
|
+
"private": true,
|
|
114
|
+
"status": "beta",
|
|
115
|
+
"ui": {
|
|
116
|
+
"src": "https://your-app.vercel.app/lib/plugin.js",
|
|
117
|
+
"isolation": "shadow"
|
|
118
|
+
}
|
|
119
|
+
}'
|
|
54
120
|
```
|
|
121
|
+
|
|
122
|
+
Replace `appId` by the actual ID and `https://your-app.vercel.app` with your actual Vercel deployment URL.
|
|
123
|
+
|
|
124
|
+
## Key Features
|
|
125
|
+
|
|
126
|
+
### Dual Build Modes
|
|
127
|
+
|
|
128
|
+
- **App Mode**: Builds a standalone application for development and testing
|
|
129
|
+
- **Library Mode**: Builds a plugin that can be integrated into the Vertesia platform
|
|
130
|
+
|
|
131
|
+
### External Dependencies
|
|
132
|
+
|
|
133
|
+
When building as a plugin, React and Vertesia dependencies are externalized to prevent duplication:
|
|
134
|
+
|
|
135
|
+
- `react` / `react-dom`
|
|
136
|
+
- `@vertesia/common`
|
|
137
|
+
- `@vertesia/ui`
|
|
138
|
+
|
|
139
|
+
## Tech Stack
|
|
140
|
+
|
|
141
|
+
- **React 19** - UI framework
|
|
142
|
+
- **TypeScript** - Type safety
|
|
143
|
+
- **Vite** - Build tool and dev server
|
|
144
|
+
- **Tailwind CSS 4** - Styling
|
|
145
|
+
- **@vertesia/ui** - Vertesia UI components
|
|
146
|
+
- **@vertesia/plugin-builder** - Plugin build utilities
|
|
147
|
+
|
|
148
|
+
## Development Notes
|
|
149
|
+
|
|
150
|
+
- The dev server uses HTTPS (via `@vitejs/plugin-basic-ssl`)
|
|
151
|
+
- CSS can be inlined in the plugin bundle or kept separate (configured in [vite.config.ts](vite.config.ts))
|
|
152
|
+
- For debugging Vertesia UI sources, set `VERTESIA_UI_PATH` in [vite.config.ts](vite.config.ts)
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
See package.json for license information.
|
|
@@ -3,8 +3,9 @@ import globals from 'globals'
|
|
|
3
3
|
import reactHooks from 'eslint-plugin-react-hooks'
|
|
4
4
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
5
5
|
import tseslint from 'typescript-eslint'
|
|
6
|
+
import { defineConfig } from 'eslint/config';
|
|
6
7
|
|
|
7
|
-
export default
|
|
8
|
+
export default defineConfig(
|
|
8
9
|
{ ignores: ['dist'] },
|
|
9
10
|
{
|
|
10
11
|
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
dist
|
|
12
|
+
dist-ssr
|
|
13
|
+
lib
|
|
14
|
+
*.local
|
|
15
|
+
|
|
16
|
+
# Editor directories and files
|
|
17
|
+
.vscode/*
|
|
18
|
+
!.vscode/extensions.json
|
|
19
|
+
.idea
|
|
20
|
+
.DS_Store
|
|
21
|
+
*.suo
|
|
22
|
+
*.ntvs*
|
|
23
|
+
*.njsproj
|
|
24
|
+
*.sln
|
|
25
|
+
*.sw?
|
|
@@ -4,17 +4,11 @@ Env.init({
|
|
|
4
4
|
name: "${plugin_title}",
|
|
5
5
|
version: "1.0.0",
|
|
6
6
|
isLocalDev: true,
|
|
7
|
-
isDocker:
|
|
7
|
+
isDocker: true,
|
|
8
8
|
type: "development",
|
|
9
9
|
endpoints: {
|
|
10
|
-
studio: "
|
|
11
|
-
zeno: "
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
|
|
15
|
-
authDomain: window.location.host,
|
|
16
|
-
projectId: "dengenlabs",
|
|
17
|
-
appId: "1:265888598630:web:6e5e76c8ecde887e5afba7"
|
|
18
|
-
},
|
|
19
|
-
datadog: false,
|
|
10
|
+
studio: "https://api.vertesia.io",
|
|
11
|
+
zeno: "https://api.vertesia.io",
|
|
12
|
+
sts: "https://sts.vertesia.io",
|
|
13
|
+
}
|
|
20
14
|
});
|
|
@@ -40,7 +40,7 @@ const inlineCss = ${ inlineCss };
|
|
|
40
40
|
* Vite configuration to build the plugin as a library or as a standalone application or to run the application in dev mode.
|
|
41
41
|
* Use `vite build --mode lib` to build a library (plugin)
|
|
42
42
|
* Use `vite build` or `vite build --mode app`to build a standalone application
|
|
43
|
-
* Use `vite dev` to run the
|
|
43
|
+
* Use `vite dev` to run the application in dev mode.
|
|
44
44
|
*/
|
|
45
45
|
export default defineConfig((env) => {
|
|
46
46
|
if (env.mode === 'lib') {
|
|
@@ -83,7 +83,7 @@ function defineLibConfig({ command }: ConfigEnv): UserConfig {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
|
-
* Vite configuration to run the
|
|
86
|
+
* Vite configuration to run the application in dev mode
|
|
87
87
|
* or to build a standalone application.
|
|
88
88
|
* @returns
|
|
89
89
|
*/
|
|
@@ -115,8 +115,10 @@ function defineAppConfig(): UserConfig {
|
|
|
115
115
|
resolve: {
|
|
116
116
|
// For debug support in vertesia ui sources - link to the vertesia/ui location
|
|
117
117
|
alias: VERTESIA_UI_PATH ? {
|
|
118
|
-
"@vertesia/ui
|
|
119
|
-
} : undefined
|
|
118
|
+
"@vertesia/ui": resolve(`${VERTESIA_UI_PATH}/src`)
|
|
119
|
+
} : undefined,
|
|
120
|
+
// Deduplicate React to prevent multiple instances
|
|
121
|
+
dedupe: ['react', 'react-dom']
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { Tool, ToolFunctionParams } from "@vertesia/agent-sdk";
|
|
2
|
-
|
|
3
|
-
interface WeatherToolParams {
|
|
4
|
-
location: string;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export const WeatherTool = {
|
|
8
|
-
name: "weather",
|
|
9
|
-
description: "Get the current weather for a given location.",
|
|
10
|
-
input_schema: {
|
|
11
|
-
type: "object",
|
|
12
|
-
properties: {
|
|
13
|
-
location: {
|
|
14
|
-
type: "string",
|
|
15
|
-
description: "The location to get the weather for, e.g., 'New York, NY'."
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
required: ["location"]
|
|
19
|
-
},
|
|
20
|
-
run: async (params: ToolFunctionParams<WeatherToolParams>) => {
|
|
21
|
-
const { location } = params.input;
|
|
22
|
-
// Simulate fetching weather data
|
|
23
|
-
return `The current weather in ${location} is sunny with a temperature of 75°F.`;
|
|
24
|
-
}
|
|
25
|
-
} satisfies Tool<WeatherToolParams>;
|