@vertesia/create-plugin 0.79.1 → 0.80.0-dev.20251121

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 CHANGED
@@ -1,100 +1,105 @@
1
- # @vertesia/create-agent
1
+ # @vertesia/create-plugin
2
2
 
3
- This package is scaffolding a vertesia agent project.
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
- Visit https://vertesiahq.com for more information about Vertesia.
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
- ## Requirements:
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
- ## Initialize a Vertesia agent project
10
+ ## What Can You Create?
13
11
 
14
- Run the command line command:
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
- The generated project is a typescript project and is using [Temporal](https://temporal.io/) as the workflow system.
16
+ ### Agent Tool Server
23
17
 
24
- You can implement your own workflows and activities anywhere in the src/ directory or even in a dependency project. The only requirement is that you need to export the workflows and the activities from the `src/workflow.ts` and `src/activities.ts` files.
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
- ## Developing your agent workflows / activities.
26
+ ## Prerequisites
29
27
 
30
- Export your temporal workflows `from src/workflows.ts` and your activities from `src/activities.ts`
28
+ Before creating a plugin project, you need:
31
29
 
32
- ## Test locally the workflows.
30
+ - Node.js and pnpm (or npm)
31
+ - Vertesia CLI
32
+ - An application manifest declared in Vertesia
33
33
 
34
- There are two ways to test the agent worker:
34
+ ### Declaring Your Web Application Plugin in Vertesia
35
35
 
36
- 1. Using `npm start`. This will start the worker in your terminal.
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
- **Important Note:** All `vertesia agent` commands must be executed in the agent project root.
38
+ #### Install the Vertesia CLI
40
39
 
41
- ## Debugging locally the workflows.
40
+ If not already done, install the Vertesia CLI and create a profile:
42
41
 
43
- You can debug the workflows by replaying them locally using the temporal replayer that you can found in `src/debug-replayer.ts`.
44
-
45
- See https://docs.temporal.io/develop/typescript/debugging for more information
42
+ ```bash
43
+ npm install -g @vertesia/cli
44
+ vertesia profiles create
45
+ ```
46
46
 
47
- ## Packaging and publishing your Vertesia agent
47
+ ### Create the App Manifest
48
48
 
49
- When the workflows are working you will want to publish the agent to Vertesia.
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
- ### Build the agent docker image
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
- When you are ready to test the agent image you can built it using `vertesia agent build` from you project root.
62
+ The `--install` flag will automatically install the app and grant permissions to the creator.
55
63
 
56
- This will build a docker image tagged as `your-organization/your-agent-name:latest`.
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
- ### Releasing the agent docker image
66
+ ## Initialize a Plugin Project
60
67
 
61
- When you already to push your agent to Vertesia you must first create a version using the following command:
68
+ Run the initialization command:
62
69
 
63
- ```
64
- vertesia agent release <version>
70
+ ```bash
71
+ npm init @vertesia/plugin
72
+ # or
73
+ pnpm create @vertesia/plugin
65
74
  ```
66
75
 
67
- The version must be in the `major.minor.patch[-modifier]` format. \
68
- Examples: `1.0.0`, `1.0.0-rc1`.
76
+ You will be prompted to choose a template and provide configuration:
69
77
 
70
- This command is creating a new docker tag `your-organization/your-agent-name:version` from the `latest` image tag.
78
+ ### Prompts
71
79
 
72
- ### Publishing the agent docker image to Vertesia
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
- Versioned images (using the `release` command) can be published to Vertesia. This can be done using the following command:
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
- where the version is the version of the image tag you want to publish.
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
- You can also only push the image to vertesia without deploying the agent by using the `--push-only` flag:
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
- ## Managing agent versions
100
+ ## Support
95
101
 
96
- You can see the docker image versions you created using the following command:
102
+ For issues, questions, or feature requests:
97
103
 
98
- ```
99
- vertesia agent versions
100
- ```
104
+ - [GitHub Issues](https://github.com/vertesia/composableai/issues)
105
+ - [Documentation](https://docs.vertesiahq.com/)
package/package.json CHANGED
@@ -1,37 +1,49 @@
1
1
  {
2
- "name": "@vertesia/create-plugin",
3
- "version": "0.79.1",
4
- "description": "Initialize a Vertesia plugin package",
5
- "type": "module",
6
- "bin": {
7
- "create-plugin": "./bin/create-plugin.mjs"
8
- },
9
- "main": "./lib/main.js",
10
- "types": "./lib/main.d.ts",
11
- "files": [
12
- "lib",
13
- "templates",
14
- "bin"
15
- ],
16
- "license": "Apache-2.0",
17
- "homepage": "https://docs.vertesiahq.com/",
18
- "keywords": [
19
- "vertesia",
20
- "ui",
21
- "plugin"
22
- ],
23
- "scripts": {
24
- "eslint": "eslint './src/**/*.{jsx,js,tsx,ts}'",
25
- "build": "rm -rf ./lib ./tsconfig.tsbuildinfo && tsc --build",
26
- "clean": "rimraf ./node_modules ./lib ./tsconfig.tsbuildinfo"
27
- },
28
- "dependencies": {
29
- "enquirer": "^2.4.1",
30
- "hasbin": "^1.2.3"
31
- },
32
- "devDependencies": {
33
- "@types/hasbin": "^1.2.2",
34
- "@types/node": "^22.5.0",
35
- "typescript": "^5.7.2"
36
- }
37
- }
2
+ "name": "@vertesia/create-plugin",
3
+ "version": "0.80.0-dev.20251121",
4
+ "description": "Initialize a Vertesia plugin package",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-plugin": "./bin/create-plugin.mjs"
8
+ },
9
+ "main": "./lib/main.js",
10
+ "types": "./lib/main.d.ts",
11
+ "files": [
12
+ "lib",
13
+ "templates",
14
+ "bin"
15
+ ],
16
+ "license": "Apache-2.0",
17
+ "homepage": "https://docs.vertesiahq.com/",
18
+ "keywords": [
19
+ "vertesia",
20
+ "ui",
21
+ "plugin"
22
+ ],
23
+ "dependencies": {
24
+ "enquirer": "^2.4.1",
25
+ "hasbin": "^1.2.3"
26
+ },
27
+ "devDependencies": {
28
+ "@types/hasbin": "^1.2.2",
29
+ "@types/node": "^22.5.0",
30
+ "typescript": "^5.7.2",
31
+ "hono": "^4.10.3",
32
+ "@hono/node-server": "^1.19.5",
33
+ "@llumiverse/common": "0.23.0-dev.20251121",
34
+ "@vertesia/client": "0.80.0-dev.20251121",
35
+ "@vertesia/tools-sdk": "0.80.0-dev.20251121",
36
+ "@vertesia/common": "0.80.0-dev.20251121"
37
+ },
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/vertesia/composableai.git",
41
+ "directory": "packages/create-plugin"
42
+ },
43
+ "scripts": {
44
+ "eslint": "eslint './src/**/*.{jsx,js,tsx,ts}'",
45
+ "build": "rm -rf ./lib ./tsconfig.tsbuildinfo && pnpm run typecheck:templates && tsc --build",
46
+ "typecheck:templates": "tsc --noEmit --project templates/tool/tsconfig.json",
47
+ "clean": "rimraf ./node_modules ./lib ./tsconfig.tsbuildinfo"
48
+ }
49
+ }
@@ -0,0 +1,6 @@
1
+ # Environment variables for your tool collections
2
+
3
+ # Add any API keys or configuration here
4
+ # Example:
5
+ # OPENAI_API_KEY=your-api-key-here
6
+ # WEATHER_API_KEY=your-weather-api-key
@@ -21,4 +21,4 @@
21
21
  }
22
22
  }
23
23
  ]
24
- }
24
+ }
@@ -1,31 +1,190 @@
1
- # Vertesia tools plugin
1
+ # Tool Collections
2
2
 
3
- This plugin is exposing tools to vertesia. The tools as exposed on an external webs erver providing two endpoints:
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
- Note that when deployed on vercel the endpoints are:
5
+ ## Project Structure
8
6
 
9
- 1. `GET /api`
10
- 2. `POST /api`
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
- The payload used when executing a tool must conform to the following interface:
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
- ```ts
15
- interface ToolExecutionPayload<ParamsT extends Record<string, any>> {
16
- context: {
17
- serverUrl: string,
18
- storeUrl: string,
19
- apikey: string
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
- vars: Record<string, any>,
22
- tool_input: ParamsT,
23
- tool_name: string,
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
- To launch the tools server you can start the vite dev server using `pnpm dev`.
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
- If you want to **debug** and add breakpoints in the code you must run the vite dev server from VSCode by running the `Debug Tools Server` launch configuration.
187
+ ## Learn More
30
188
 
31
- Vercel deployment is supported by wrapping the `hono` server using a vercel adapter.
189
+ - [Vertesia Documentation](https://docs.vertesiahq.com)
190
+ - [Tool SDK Reference](https://github.com/vertesia/composableai/tree/main/packages/tools-sdk)
@@ -0,0 +1,26 @@
1
+ # Dependencies
2
+
3
+ node_modules/
4
+
5
+ # Build output
6
+
7
+ dist/
8
+ lib/
9
+ \*.tsbuildinfo
10
+
11
+ # Environment
12
+
13
+ .env
14
+ .env.local
15
+
16
+ # IDE
17
+
18
+ .vscode/
19
+ .idea/
20
+ _.swp
21
+ _.swo
22
+
23
+ # OS
24
+
25
+ .DS_Store
26
+ Thumbs.db
@@ -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;
@@ -0,0 +1,7 @@
1
+ import { ExampleCollection } from "./example/index.js";
2
+
3
+ // Export all your tool collections here
4
+ export const collections = [
5
+ ExampleCollection
6
+ // Add more collections as you create them
7
+ ];
@@ -1,6 +1,5 @@
1
- import { ToolRegistry } from '@vertesia/agent-sdk';
2
- import { WeatherTool } from "./tools/WeatherTool.js";
1
+ // Export collections for use in other modules or for programmatic access
2
+ export { collections } from "./collections/index.js";
3
3
 
4
- export const registry = new ToolRegistry([
5
- WeatherTool
6
- ]);
4
+ // Export server as default for deployment
5
+ export { default } from "./server.js";
@@ -1,19 +1,71 @@
1
- import { Hono } from 'hono';
2
- import { registry } from "./index.js";
3
- import { cors } from 'hono/cors'
4
-
5
- const app = new Hono();
6
- app.get("/", cors({ origin: '*', allowMethods: ['GET'] }))
7
- app.post('/', async (c) => {
8
- const data = await c.req.json();
9
- const r = await registry.execute(data)
10
- return c.json({
11
- response: r
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.get('/', (c) => {
16
- return c.json(registry.getDefinitions())
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
- export default app;
70
+ return endpoint;
71
+ }
@@ -1,14 +1,24 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "ES2020",
3
+ "target": "ES2022",
4
4
  "module": "ESNext",
5
- "moduleResolution": "node",
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
- plugins: [
6
- devServer({
7
- entry: 'src/server.ts', // Adjust the path to your server entry file
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
+ });
@@ -1,54 +1,156 @@
1
- # React + TypeScript + Vite
2
-
3
- This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
-
5
- Currently, two official plugins are available:
6
-
7
- - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
8
- - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
-
10
- ## Expanding the ESLint configuration
11
-
12
- If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
13
-
14
- ```js
15
- export default tseslint.config({
16
- extends: [
17
- // Remove ...tseslint.configs.recommended and replace with this
18
- ...tseslint.configs.recommendedTypeChecked,
19
- // Alternatively, use this for stricter rules
20
- ...tseslint.configs.strictTypeChecked,
21
- // Optionally, add this for stylistic rules
22
- ...tseslint.configs.stylisticTypeChecked,
23
- ],
24
- languageOptions: {
25
- // other options...
26
- parserOptions: {
27
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
28
- tsconfigRootDir: import.meta.dirname,
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
- You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
35
-
36
- ```js
37
- // eslint.config.js
38
- import reactX from 'eslint-plugin-react-x'
39
- import reactDom from 'eslint-plugin-react-dom'
40
-
41
- export default tseslint.config({
42
- plugins: {
43
- // Add the react-x and react-dom plugins
44
- 'react-x': reactX,
45
- 'react-dom': reactDom,
46
- },
47
- rules: {
48
- // other rules...
49
- // Enable its recommended typescript rules
50
- ...reactX.configs['recommended-typescript'].rules,
51
- ...reactDom.configs.recommended.rules,
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 tseslint.config(
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: false,
7
+ isDocker: true,
8
8
  type: "development",
9
9
  endpoints: {
10
- studio: "http://127.0.0.1:8091",
11
- zeno: "http://127.0.0.1:8092",
12
- },
13
- firebase: {
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 applicaiton in dev mode.
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 applicaiton in dev mode
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/*": resolve(`${VERTESIA_UI_PATH}/src/*/index.ts`)
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>;
@@ -1,7 +0,0 @@
1
- {
2
- "functions": {
3
- "api/index.ts": {
4
- "runtime": "edge"
5
- }
6
- }
7
- }