@vertesia/tools-sdk 1.0.0-dev.20260203.130115Z → 1.0.0-dev.20260227.112605Z
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/lib/cjs/ContentTypesCollection.js +43 -0
- package/lib/cjs/ContentTypesCollection.js.map +1 -0
- package/lib/cjs/InteractionCollection.js +43 -0
- package/lib/cjs/InteractionCollection.js.map +1 -0
- package/lib/cjs/RenderingTemplateCollection.js +43 -0
- package/lib/cjs/RenderingTemplateCollection.js.map +1 -0
- package/lib/cjs/SkillCollection.js +384 -0
- package/lib/cjs/SkillCollection.js.map +1 -0
- package/lib/cjs/ToolCollection.js +221 -0
- package/lib/cjs/ToolCollection.js.map +1 -0
- package/lib/cjs/ToolRegistry.js +95 -0
- package/lib/cjs/ToolRegistry.js.map +1 -0
- package/lib/cjs/auth.js +131 -0
- package/lib/cjs/auth.js.map +1 -0
- package/lib/cjs/build/validate.js +7 -0
- package/lib/cjs/build/validate.js.map +1 -0
- package/lib/cjs/copy-assets.js +84 -0
- package/lib/cjs/copy-assets.js.map +1 -0
- package/lib/cjs/index.js +33 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/package.json +3 -0
- package/lib/cjs/server/app-package.js +141 -0
- package/lib/cjs/server/app-package.js.map +1 -0
- package/lib/cjs/server/content-types.js +73 -0
- package/lib/cjs/server/content-types.js.map +1 -0
- package/lib/cjs/server/interactions.js +89 -0
- package/lib/cjs/server/interactions.js.map +1 -0
- package/lib/cjs/server/mcp.js +45 -0
- package/lib/cjs/server/mcp.js.map +1 -0
- package/lib/cjs/server/site.js +42 -0
- package/lib/cjs/server/site.js.map +1 -0
- package/lib/cjs/server/skills.js +114 -0
- package/lib/cjs/server/skills.js.map +1 -0
- package/lib/cjs/server/templates.js +67 -0
- package/lib/cjs/server/templates.js.map +1 -0
- package/lib/cjs/server/tools.js +87 -0
- package/lib/cjs/server/tools.js.map +1 -0
- package/lib/cjs/server/types.js +3 -0
- package/lib/cjs/server/types.js.map +1 -0
- package/lib/cjs/server/widgets.js +27 -0
- package/lib/cjs/server/widgets.js.map +1 -0
- package/lib/cjs/server.js +139 -0
- package/lib/cjs/server.js.map +1 -0
- package/lib/cjs/site/styles.js +692 -0
- package/lib/cjs/site/styles.js.map +1 -0
- package/lib/cjs/site/templates.js +1185 -0
- package/lib/cjs/site/templates.js.map +1 -0
- package/lib/cjs/types.js +3 -0
- package/lib/cjs/types.js.map +1 -0
- package/lib/cjs/utils.js +44 -0
- package/lib/cjs/utils.js.map +1 -0
- package/lib/esm/ContentTypesCollection.js +39 -0
- package/lib/esm/ContentTypesCollection.js.map +1 -0
- package/lib/esm/InteractionCollection.js +39 -0
- package/lib/esm/InteractionCollection.js.map +1 -0
- package/lib/esm/RenderingTemplateCollection.js +39 -0
- package/lib/esm/RenderingTemplateCollection.js.map +1 -0
- package/lib/esm/SkillCollection.js +377 -0
- package/lib/esm/SkillCollection.js.map +1 -0
- package/lib/esm/ToolCollection.js +183 -0
- package/lib/esm/ToolCollection.js.map +1 -0
- package/lib/esm/ToolRegistry.js +90 -0
- package/lib/esm/ToolRegistry.js.map +1 -0
- package/lib/esm/auth.js +124 -0
- package/lib/esm/auth.js.map +1 -0
- package/lib/esm/build/validate.js +4 -0
- package/lib/esm/build/validate.js.map +1 -0
- package/lib/esm/copy-assets.js +81 -0
- package/lib/esm/copy-assets.js.map +1 -0
- package/lib/esm/index.js +13 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/server/app-package.js +138 -0
- package/lib/esm/server/app-package.js.map +1 -0
- package/lib/esm/server/content-types.js +70 -0
- package/lib/esm/server/content-types.js.map +1 -0
- package/lib/esm/server/interactions.js +86 -0
- package/lib/esm/server/interactions.js.map +1 -0
- package/lib/esm/server/mcp.js +42 -0
- package/lib/esm/server/mcp.js.map +1 -0
- package/lib/esm/server/site.js +39 -0
- package/lib/esm/server/site.js.map +1 -0
- package/lib/esm/server/skills.js +111 -0
- package/lib/esm/server/skills.js.map +1 -0
- package/lib/esm/server/templates.js +64 -0
- package/lib/esm/server/templates.js.map +1 -0
- package/lib/esm/server/tools.js +84 -0
- package/lib/esm/server/tools.js.map +1 -0
- package/lib/esm/server/types.js +2 -0
- package/lib/esm/server/types.js.map +1 -0
- package/lib/esm/server/widgets.js +24 -0
- package/lib/esm/server/widgets.js.map +1 -0
- package/lib/esm/server.js +135 -0
- package/lib/esm/server.js.map +1 -0
- package/lib/esm/site/styles.js +689 -0
- package/lib/esm/site/styles.js.map +1 -0
- package/lib/esm/site/templates.js +1170 -0
- package/lib/esm/site/templates.js.map +1 -0
- package/lib/esm/types.js +2 -0
- package/lib/esm/types.js.map +1 -0
- package/lib/esm/utils.js +38 -0
- package/lib/esm/utils.js.map +1 -0
- package/lib/types/ContentTypesCollection.d.ts +18 -0
- package/lib/types/ContentTypesCollection.d.ts.map +1 -0
- package/lib/types/InteractionCollection.d.ts +18 -0
- package/lib/types/InteractionCollection.d.ts.map +1 -0
- package/lib/types/RenderingTemplateCollection.d.ts +17 -0
- package/lib/types/RenderingTemplateCollection.d.ts.map +1 -0
- package/lib/types/SkillCollection.d.ts +119 -0
- package/lib/types/SkillCollection.d.ts.map +1 -0
- package/lib/types/ToolCollection.d.ts +67 -0
- package/lib/types/ToolCollection.d.ts.map +1 -0
- package/lib/types/ToolRegistry.d.ts +22 -0
- package/lib/types/ToolRegistry.d.ts.map +1 -0
- package/lib/types/auth.d.ts +32 -0
- package/lib/types/auth.d.ts.map +1 -0
- package/lib/types/build/validate.d.ts +2 -0
- package/lib/types/build/validate.d.ts.map +1 -0
- package/lib/types/copy-assets.d.ts +14 -0
- package/lib/types/copy-assets.d.ts.map +1 -0
- package/lib/types/index.d.ts +13 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/server/app-package.d.ts +4 -0
- package/lib/types/server/app-package.d.ts.map +1 -0
- package/lib/types/server/content-types.d.ts +4 -0
- package/lib/types/server/content-types.d.ts.map +1 -0
- package/lib/types/server/interactions.d.ts +4 -0
- package/lib/types/server/interactions.d.ts.map +1 -0
- package/lib/types/server/mcp.d.ts +4 -0
- package/lib/types/server/mcp.d.ts.map +1 -0
- package/lib/types/server/site.d.ts +4 -0
- package/lib/types/server/site.d.ts.map +1 -0
- package/lib/types/server/skills.d.ts +4 -0
- package/lib/types/server/skills.d.ts.map +1 -0
- package/lib/types/server/templates.d.ts +4 -0
- package/lib/types/server/templates.d.ts.map +1 -0
- package/lib/types/server/tools.d.ts +4 -0
- package/lib/types/server/tools.d.ts.map +1 -0
- package/lib/types/server/types.d.ts +93 -0
- package/lib/types/server/types.d.ts.map +1 -0
- package/lib/types/server/widgets.d.ts +4 -0
- package/lib/types/server/widgets.d.ts.map +1 -0
- package/lib/types/server.d.ts +27 -0
- package/lib/types/server.d.ts.map +1 -0
- package/lib/types/site/styles.d.ts +5 -0
- package/lib/types/site/styles.d.ts.map +1 -0
- package/lib/types/site/templates.d.ts +71 -0
- package/lib/types/site/templates.d.ts.map +1 -0
- package/lib/types/types.d.ts +294 -0
- package/lib/types/types.d.ts.map +1 -0
- package/lib/types/utils.d.ts +10 -0
- package/lib/types/utils.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/ContentTypesCollection.ts +8 -8
- package/src/RenderingTemplateCollection.ts +51 -0
- package/src/SkillCollection.ts +11 -2
- package/src/ToolCollection.ts +9 -18
- package/src/ToolRegistry.ts +17 -56
- package/src/auth.ts +27 -0
- package/src/index.ts +1 -0
- package/src/server/app-package.ts +101 -43
- package/src/server/{conyent-types.ts → content-types.ts} +29 -11
- package/src/server/interactions.ts +11 -6
- package/src/server/site.ts +9 -0
- package/src/server/templates.ts +80 -0
- package/src/server/tools.ts +3 -22
- package/src/server/types.ts +14 -1
- package/src/server/widgets.ts +2 -6
- package/src/server.ts +5 -1
- package/src/site/templates.ts +179 -2
- package/src/types.ts +38 -1
- package/src/utils.ts +15 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// ================== Template Endpoints ==================
|
|
2
|
+
|
|
3
|
+
import { RenderingTemplateDefinition, RenderingTemplateDefinitionRef } from "@vertesia/common";
|
|
4
|
+
import { Context, Hono } from "hono";
|
|
5
|
+
import { HTTPException } from "hono/http-exception";
|
|
6
|
+
import { RenderingTemplateCollection } from "../RenderingTemplateCollection.js";
|
|
7
|
+
import { ToolServerConfig } from "./types.js";
|
|
8
|
+
|
|
9
|
+
function toRef(basePath: string, collectionName: string, { instructions: _, ...ref }: RenderingTemplateDefinition): RenderingTemplateDefinitionRef {
|
|
10
|
+
return { ...ref, path: `${basePath}/${collectionName}/${ref.name}` };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function createTemplatesRoute(app: Hono, basePath: string, config: ToolServerConfig) {
|
|
14
|
+
const { templates = [] } = config;
|
|
15
|
+
|
|
16
|
+
// GET /api/templates - Returns all templates from all collections (without instructions)
|
|
17
|
+
app.get(basePath, (c) => {
|
|
18
|
+
const allTemplates = templates.flatMap(coll =>
|
|
19
|
+
coll.templates.map(t => toRef(basePath, coll.name, t))
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
return c.json({
|
|
23
|
+
title: 'All Templates',
|
|
24
|
+
description: 'All available templates across all collections',
|
|
25
|
+
templates: allTemplates,
|
|
26
|
+
collections: templates.map(t => ({
|
|
27
|
+
name: t.name,
|
|
28
|
+
title: t.title,
|
|
29
|
+
description: t.description,
|
|
30
|
+
})),
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Create template collection endpoints
|
|
35
|
+
for (const coll of templates) {
|
|
36
|
+
app.route(`${basePath}/${coll.name}`, createTemplateEndpoints(basePath, coll));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// GET /api/templates/:name - Direct access by "collection:name" id format
|
|
40
|
+
app.get(`${basePath}/:id`, async (c) => {
|
|
41
|
+
const id = c.req.param('id');
|
|
42
|
+
const parts = id.split(':');
|
|
43
|
+
if (parts.length !== 2) {
|
|
44
|
+
throw new HTTPException(400, {
|
|
45
|
+
message: "Invalid template id. Expected format 'collection:name'"
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const collName = parts[0];
|
|
49
|
+
const templateName = parts[1];
|
|
50
|
+
const template = templates.find(t => t.name === collName)?.getTemplate(templateName);
|
|
51
|
+
if (template) {
|
|
52
|
+
return c.json(template);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
throw new HTTPException(404, {
|
|
56
|
+
message: "No template found with id: " + id
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function createTemplateEndpoints(basePath: string, coll: RenderingTemplateCollection): Hono {
|
|
62
|
+
const endpoint = new Hono();
|
|
63
|
+
|
|
64
|
+
endpoint.get('/', (c: Context) => {
|
|
65
|
+
return c.json(coll.templates.map(t => toRef(basePath, coll.name, t)));
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
endpoint.get('/:name', (c: Context) => {
|
|
69
|
+
const name = c.req.param('name');
|
|
70
|
+
const template = coll.templates.find(t => t.name === name);
|
|
71
|
+
if (!template) {
|
|
72
|
+
throw new HTTPException(404, {
|
|
73
|
+
message: "No template found with name: " + name
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return c.json(template);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return endpoint;
|
|
80
|
+
}
|
package/src/server/tools.ts
CHANGED
|
@@ -22,20 +22,11 @@ export function createToolsRoute(app: Hono, basePath: string, config: ToolServer
|
|
|
22
22
|
|
|
23
23
|
app.get(basePath, (c) => {
|
|
24
24
|
const url = new URL(c.req.url);
|
|
25
|
-
const defaultOnly = c.req.query('defaultOnly') === 'true';
|
|
26
|
-
const unlockedParam = c.req.query('unlocked');
|
|
27
|
-
const unlockedTools = unlockedParam ? unlockedParam.split(',').map(t => t.trim()).filter(Boolean) : [];
|
|
28
|
-
|
|
29
|
-
const filterOptions = defaultOnly ? { defaultOnly, unlockedTools } : undefined;
|
|
30
25
|
|
|
31
26
|
const allTools: ToolDefinition[] = [];
|
|
32
|
-
let reserveToolCount = 0;
|
|
33
27
|
|
|
34
28
|
for (const coll of tools) {
|
|
35
|
-
allTools.push(...coll.getToolDefinitions(
|
|
36
|
-
if (defaultOnly) {
|
|
37
|
-
reserveToolCount += coll.getReserveTools(unlockedTools).length;
|
|
38
|
-
}
|
|
29
|
+
allTools.push(...coll.getToolDefinitions());
|
|
39
30
|
}
|
|
40
31
|
|
|
41
32
|
return c.json({
|
|
@@ -43,7 +34,6 @@ export function createToolsRoute(app: Hono, basePath: string, config: ToolServer
|
|
|
43
34
|
title: 'All Tools',
|
|
44
35
|
description: 'All available tools across all collections',
|
|
45
36
|
tools: allTools,
|
|
46
|
-
reserveToolCount: defaultOnly ? reserveToolCount : undefined,
|
|
47
37
|
collections: tools.map(t => ({
|
|
48
38
|
name: t.name,
|
|
49
39
|
title: t.title,
|
|
@@ -97,27 +87,18 @@ function createToolEndpoints(coll: ToolCollection): Hono {
|
|
|
97
87
|
// - unlocked=tool1,tool2: Comma-separated list of unlocked tool names
|
|
98
88
|
endpoint.get('/', (c) => {
|
|
99
89
|
const importSourceUrl = c.req.query('import') != null;
|
|
100
|
-
const defaultOnly = c.req.query('defaultOnly') === 'true';
|
|
101
|
-
const unlockedParam = c.req.query('unlocked');
|
|
102
|
-
const unlockedTools = unlockedParam ? unlockedParam.split(',').map(t => t.trim()).filter(Boolean) : [];
|
|
103
90
|
|
|
104
|
-
const filterOptions = defaultOnly ? { defaultOnly, unlockedTools } : undefined;
|
|
105
91
|
const url = new URL(c.req.url);
|
|
106
92
|
|
|
107
|
-
const response: ToolCollectionDefinition
|
|
93
|
+
const response: ToolCollectionDefinition = {
|
|
108
94
|
src: importSourceUrl
|
|
109
95
|
? `${url.origin}/libs/vertesia-tools-${coll.name}.js`
|
|
110
96
|
: `${url.origin}${url.pathname}`,
|
|
111
97
|
title: coll.title || coll.name,
|
|
112
98
|
description: coll.description || '',
|
|
113
|
-
tools: coll.getToolDefinitions(
|
|
99
|
+
tools: coll.getToolDefinitions()
|
|
114
100
|
};
|
|
115
101
|
|
|
116
|
-
// Include reserve count when filtering
|
|
117
|
-
if (defaultOnly) {
|
|
118
|
-
response.reserveToolCount = coll.getReserveTools(unlockedTools).length;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
102
|
return c.json(response);
|
|
122
103
|
});
|
|
123
104
|
|
package/src/server/types.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Context } from "hono";
|
|
2
2
|
import { InteractionCollection } from "../InteractionCollection.js";
|
|
3
3
|
import { SkillCollection } from "../SkillCollection.js";
|
|
4
|
+
import { RenderingTemplateCollection } from "../RenderingTemplateCollection.js";
|
|
4
5
|
import { ToolCollection } from "../ToolCollection.js";
|
|
5
6
|
import { ToolExecutionPayload } from "../types.js";
|
|
6
7
|
import { JSONSchema } from "@llumiverse/common";
|
|
7
|
-
import { AppUIConfig } from "@vertesia/common";
|
|
8
|
+
import { AppUIConfig, ProjectConfiguration } from "@vertesia/common";
|
|
8
9
|
import { ContentTypesCollection } from "../ContentTypesCollection.js";
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -60,6 +61,10 @@ export interface ToolServerConfig {
|
|
|
60
61
|
* Skill collections to expose
|
|
61
62
|
*/
|
|
62
63
|
skills?: SkillCollection[];
|
|
64
|
+
/**
|
|
65
|
+
* Template collections to expose
|
|
66
|
+
*/
|
|
67
|
+
templates?: RenderingTemplateCollection[];
|
|
63
68
|
/**
|
|
64
69
|
* MCP providers to expose
|
|
65
70
|
*/
|
|
@@ -83,5 +88,13 @@ export interface ToolServerConfig {
|
|
|
83
88
|
* Hide UI app links on the index page (default: false)
|
|
84
89
|
*/
|
|
85
90
|
hideUILinks?: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* If a filter is provided, it will be called with the project configuration when requesting tool definitions, and can be used to filter which tools are returned based on the project configuration.
|
|
94
|
+
* This allows for dynamic enabling/disabling of tools based on project settings.
|
|
95
|
+
* @param projectConfig
|
|
96
|
+
* @returns
|
|
97
|
+
*/
|
|
98
|
+
toolFilter?: (projectConfig: ProjectConfiguration) => boolean;
|
|
86
99
|
}
|
|
87
100
|
|
package/src/server/widgets.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
+
import { AppWidgetInfo } from "@vertesia/common";
|
|
1
2
|
import { Hono } from "hono";
|
|
2
3
|
import { ToolServerConfig } from "./types.js";
|
|
3
4
|
|
|
4
|
-
export interface WidgetInfo {
|
|
5
|
-
collection: string;
|
|
6
|
-
skill: string;
|
|
7
|
-
url: string;
|
|
8
|
-
}
|
|
9
5
|
|
|
10
6
|
export function createWidgetsRoute(app: Hono, basePath: string, config: ToolServerConfig) {
|
|
11
7
|
|
|
@@ -15,7 +11,7 @@ export function createWidgetsRoute(app: Hono, basePath: string, config: ToolServ
|
|
|
15
11
|
app.get(basePath, (c) => {
|
|
16
12
|
const url = new URL(c.req.url);
|
|
17
13
|
|
|
18
|
-
const widgets: Record<string,
|
|
14
|
+
const widgets: Record<string, AppWidgetInfo> = {};
|
|
19
15
|
for (const coll of skills) {
|
|
20
16
|
const collWidgets = coll.getWidgets();
|
|
21
17
|
for (const widget of collWidgets) {
|
package/src/server.ts
CHANGED
|
@@ -9,9 +9,10 @@ import { createSkillsRoute } from "./server/skills.js";
|
|
|
9
9
|
import { createToolsRoute } from "./server/tools.js";
|
|
10
10
|
import { ToolContext, ToolServerConfig } from "./server/types.js";
|
|
11
11
|
import { ToolExecutionPayload } from "./types.js";
|
|
12
|
+
import { createTemplatesRoute } from "./server/templates.js";
|
|
12
13
|
import { createWidgetsRoute } from "./server/widgets.js";
|
|
13
14
|
import { createPackageRoute } from "./server/app-package.js";
|
|
14
|
-
import { createContentTypesRoute } from "./server/
|
|
15
|
+
import { createContentTypesRoute } from "./server/content-types.js";
|
|
15
16
|
|
|
16
17
|
// Schema for tool execution payload
|
|
17
18
|
const ToolExecutionPayloadSchema = z.object({
|
|
@@ -46,6 +47,7 @@ export function createToolServer(config: ToolServerConfig): Hono {
|
|
|
46
47
|
tools = [],
|
|
47
48
|
interactions = [],
|
|
48
49
|
skills = [],
|
|
50
|
+
templates = [],
|
|
49
51
|
mcpProviders = [],
|
|
50
52
|
disableHtml = false,
|
|
51
53
|
} = config;
|
|
@@ -95,6 +97,7 @@ export function createToolServer(config: ToolServerConfig): Hono {
|
|
|
95
97
|
endpoints: {
|
|
96
98
|
tools: allToolEndpoints,
|
|
97
99
|
interactions: interactions.map(col => `${prefix}/interactions/${col.name}`),
|
|
100
|
+
templates: templates.map(col => `${prefix}/templates/${col.name}`),
|
|
98
101
|
mcp: mcpProviders.map(p => `${prefix}/mcp/${p.name}`),
|
|
99
102
|
}
|
|
100
103
|
});
|
|
@@ -106,6 +109,7 @@ export function createToolServer(config: ToolServerConfig): Hono {
|
|
|
106
109
|
createSkillsRoute(app, `${prefix}/skills`, config);
|
|
107
110
|
createWidgetsRoute(app, `${prefix}/widgets`, config);
|
|
108
111
|
createInteractionsRoute(app, `${prefix}/interactions`, config);
|
|
112
|
+
createTemplatesRoute(app, `${prefix}/templates`, config);
|
|
109
113
|
createContentTypesRoute(app, `${prefix}/types`, config);
|
|
110
114
|
createMcpRoute(app, `${prefix}/mcp`, config);
|
|
111
115
|
|
package/src/site/templates.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { InteractionCollection } from "../InteractionCollection.js";
|
|
2
2
|
import { ToolServerConfig } from "../server/types.js";
|
|
3
3
|
import type { SkillCollection } from "../SkillCollection.js";
|
|
4
|
+
import type { RenderingTemplateCollection } from "../RenderingTemplateCollection.js";
|
|
4
5
|
import type { ToolCollection } from "../ToolCollection.js";
|
|
5
6
|
import type { ContentTypesCollection } from "../ContentTypesCollection.js";
|
|
6
|
-
import type { ICollection, SkillDefinition, Tool } from "../types.js";
|
|
7
|
+
import type { ICollection, SkillDefinition, RenderingTemplateDefinition, Tool } from "../types.js";
|
|
7
8
|
import { join } from "../utils.js";
|
|
8
9
|
import { baseStyles } from "./styles.js";
|
|
9
10
|
|
|
@@ -25,6 +26,15 @@ const skillIcon = /*html*/`
|
|
|
25
26
|
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
|
|
26
27
|
</svg>`;
|
|
27
28
|
|
|
29
|
+
const templateIcon = /*html*/`
|
|
30
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
31
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
|
|
32
|
+
<polyline points="14 2 14 8 20 8"/>
|
|
33
|
+
<line x1="16" y1="13" x2="8" y2="13"/>
|
|
34
|
+
<line x1="16" y1="17" x2="8" y2="17"/>
|
|
35
|
+
<polyline points="10 9 9 9 8 9"/>
|
|
36
|
+
</svg>`;
|
|
37
|
+
|
|
28
38
|
/**
|
|
29
39
|
* Extended styles for detail pages
|
|
30
40
|
*/
|
|
@@ -247,6 +257,19 @@ ${baseStyles}
|
|
|
247
257
|
color: white;
|
|
248
258
|
}
|
|
249
259
|
|
|
260
|
+
.template-type-badge {
|
|
261
|
+
background: #f59e0b;
|
|
262
|
+
color: white;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.template-type-badge.document {
|
|
266
|
+
background: #f59e0b;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.template-type-badge.presentation {
|
|
270
|
+
background: #8b5cf6;
|
|
271
|
+
}
|
|
272
|
+
|
|
250
273
|
@media (prefers-color-scheme: dark) {
|
|
251
274
|
.nav a {
|
|
252
275
|
color: #9ca3af;
|
|
@@ -584,6 +607,140 @@ export function skillDetailCard(skill: SkillDefinition, collection: SkillCollect
|
|
|
584
607
|
</div>`;
|
|
585
608
|
}
|
|
586
609
|
|
|
610
|
+
/**
|
|
611
|
+
* Render a template endpoint URL with copy button
|
|
612
|
+
*/
|
|
613
|
+
function renderTemplateUrl(template: RenderingTemplateDefinition, collectionName: string): string {
|
|
614
|
+
const templatePath = `/api/templates/${collectionName}/${template.name}`;
|
|
615
|
+
return /*html*/`<div class="script-item" style='display: flex; align-items: center; gap: 0.5rem; width:100%;justify-content: space-between;'><span class="script-name">${templatePath}</span>
|
|
616
|
+
<button class="copy-btn" onclick="navigator.clipboard.writeText(window.location.origin + '${templatePath}')" title="Copy endpoint URL">
|
|
617
|
+
${copyIcon}
|
|
618
|
+
</button>
|
|
619
|
+
</div>`;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* Render a tag list
|
|
624
|
+
*/
|
|
625
|
+
function tagList(tags: string[] | undefined): string {
|
|
626
|
+
if (!tags || tags.length === 0) return '';
|
|
627
|
+
return /*html*/`
|
|
628
|
+
<div class="detail-section">
|
|
629
|
+
<h4 class="detail-section-title">Tags</h4>
|
|
630
|
+
<div class="keyword-list">
|
|
631
|
+
${tags.map(tag => `<span class="keyword-tag">${tag}</span>`).join('')}
|
|
632
|
+
</div>
|
|
633
|
+
</div>`;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Render an asset file list
|
|
638
|
+
*/
|
|
639
|
+
function assetList(assets: string[]): string {
|
|
640
|
+
if (assets.length === 0) return '';
|
|
641
|
+
return /*html*/`
|
|
642
|
+
<div class="detail-section">
|
|
643
|
+
<h4 class="detail-section-title">Assets</h4>
|
|
644
|
+
<div class="script-list">
|
|
645
|
+
${assets.map(asset => /*html*/`
|
|
646
|
+
<div class="script-item">
|
|
647
|
+
${fileIcon}
|
|
648
|
+
<span class="script-name">${asset}</span>
|
|
649
|
+
</div>
|
|
650
|
+
`).join('')}
|
|
651
|
+
</div>
|
|
652
|
+
</div>`;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Render an instructions preview section
|
|
657
|
+
*/
|
|
658
|
+
function instructionsPreview(instructions: string): string {
|
|
659
|
+
return /*html*/`
|
|
660
|
+
<div class="detail-section">
|
|
661
|
+
<h4 class="detail-section-title">Instructions Preview</h4>
|
|
662
|
+
<div class="instructions-preview">${escapeHtml(instructions.slice(0, 1000))}${instructions.length > 1000 ? '...' : ''}</div>
|
|
663
|
+
</div>`;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Render a detailed template card
|
|
668
|
+
*/
|
|
669
|
+
export function templateDetailCard(template: RenderingTemplateDefinition, collection: RenderingTemplateCollection): string {
|
|
670
|
+
return /*html*/`
|
|
671
|
+
<div class="detail-card">
|
|
672
|
+
<div class="detail-header">
|
|
673
|
+
<div>
|
|
674
|
+
<h3 class="detail-title">${template.title || template.name}</h3>
|
|
675
|
+
<p class="detail-desc">${template.description || 'No description'}</p>
|
|
676
|
+
${renderTemplateUrl(template, collection.name)}
|
|
677
|
+
</div>
|
|
678
|
+
<div class="detail-badges">
|
|
679
|
+
<span class="badge template-type-badge ${template.type}">${template.type}</span>
|
|
680
|
+
</div>
|
|
681
|
+
</div>
|
|
682
|
+
<div class="detail-body">
|
|
683
|
+
<div class="info-grid">
|
|
684
|
+
<div class="info-item">
|
|
685
|
+
<div class="info-label">Type</div>
|
|
686
|
+
<div class="info-value"><code>${template.type}</code></div>
|
|
687
|
+
</div>
|
|
688
|
+
<div class="info-item">
|
|
689
|
+
<div class="info-label">Assets</div>
|
|
690
|
+
<div class="info-value">${template.assets.length} file${template.assets.length !== 1 ? 's' : ''}</div>
|
|
691
|
+
</div>
|
|
692
|
+
</div>
|
|
693
|
+
|
|
694
|
+
${tagList(template.tags)}
|
|
695
|
+
${assetList(template.assets)}
|
|
696
|
+
${instructionsPreview(template.instructions)}
|
|
697
|
+
</div>
|
|
698
|
+
</div>`;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Render a template collection detail page
|
|
703
|
+
*/
|
|
704
|
+
export function templateCollectionPage(collection: RenderingTemplateCollection): string {
|
|
705
|
+
const templatesArray = Array.from(collection);
|
|
706
|
+
return /*html*/`
|
|
707
|
+
<!DOCTYPE html>
|
|
708
|
+
<html lang="en">
|
|
709
|
+
<head>
|
|
710
|
+
<meta charset="UTF-8">
|
|
711
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
712
|
+
<title>${collection.title || collection.name} - Templates</title>
|
|
713
|
+
<style>${detailStyles}</style>
|
|
714
|
+
</head>
|
|
715
|
+
<body>
|
|
716
|
+
<nav class="nav">
|
|
717
|
+
<a href="/">${backArrow} Back to all collections</a>
|
|
718
|
+
</nav>
|
|
719
|
+
|
|
720
|
+
<div class="header">
|
|
721
|
+
<div class="header-icon">${collection.icon || templateIcon}</div>
|
|
722
|
+
<div>
|
|
723
|
+
<h1>${collection.title || collection.name}</h1>
|
|
724
|
+
<p style="color: #6b7280; margin: 0.25rem 0 0 0;">${collection.description || ''}</p>
|
|
725
|
+
<div class="endpoint-box">
|
|
726
|
+
<code>/api/templates/${collection.name}</code>
|
|
727
|
+
<button class="copy-btn" onclick="navigator.clipboard.writeText(window.location.origin + '/api/templates/${collection.name}')" title="Copy endpoint URL">
|
|
728
|
+
${copyIcon}
|
|
729
|
+
</button>
|
|
730
|
+
</div>
|
|
731
|
+
</div>
|
|
732
|
+
</div>
|
|
733
|
+
|
|
734
|
+
<h2>${templatesArray.length} Template${templatesArray.length !== 1 ? 's' : ''}</h2>
|
|
735
|
+
|
|
736
|
+
${templatesArray.length > 0 ?
|
|
737
|
+
templatesArray.map(template => templateDetailCard(template, collection)).join('') :
|
|
738
|
+
'<div class="empty-state">No templates in this collection</div>'
|
|
739
|
+
}
|
|
740
|
+
</body>
|
|
741
|
+
</html>`;
|
|
742
|
+
}
|
|
743
|
+
|
|
587
744
|
/**
|
|
588
745
|
* Escape HTML for safe rendering
|
|
589
746
|
*/
|
|
@@ -656,6 +813,8 @@ function copyPluginUrl(btn) {
|
|
|
656
813
|
* Note: The fourth argument is backward compatible:
|
|
657
814
|
* - If a string is passed, it is treated as the title.
|
|
658
815
|
* - If an array is passed, it is treated as MCP providers and the fifth argument (if any) is the title.
|
|
816
|
+
* @deprecated Static templates were replaced by a React site. Do not use them anymore.
|
|
817
|
+
* Will be removed.
|
|
659
818
|
*/
|
|
660
819
|
export function indexPage(
|
|
661
820
|
config: ToolServerConfig
|
|
@@ -665,6 +824,7 @@ export function indexPage(
|
|
|
665
824
|
tools = [],
|
|
666
825
|
interactions = [],
|
|
667
826
|
skills = [],
|
|
827
|
+
templates = [],
|
|
668
828
|
types = [],
|
|
669
829
|
mcpProviders = [],
|
|
670
830
|
hideUILinks = false,
|
|
@@ -698,6 +858,7 @@ export function indexPage(
|
|
|
698
858
|
${skills.length ? /*html*/`<span><dot></dot> ${skills.length} skill collection${skills.length !== 1 ? 's' : ''}</span>` : ''}
|
|
699
859
|
${interactions.length ? /*html*/`<span><dot></dot> ${interactions.length} interaction collection${interactions.length !== 1 ? 's' : ''}</span>` : ''}
|
|
700
860
|
${types.length ? /*html*/`<span><dot></dot> ${types.length} content type collection${types.length !== 1 ? 's' : ''}</span>` : ''}
|
|
861
|
+
${templates.length ? /*html*/`<span><dot></dot> ${templates.length} template collection${templates.length !== 1 ? 's' : ''}</span>` : ''}
|
|
701
862
|
${mcpProviders.length ? /*html*/`<span><dot></dot> ${mcpProviders.length} MCP provider${mcpProviders.length !== 1 ? 's' : ''}</span>` : ''}
|
|
702
863
|
</div>
|
|
703
864
|
${hideUILinks ? '' : renderUILinks()}
|
|
@@ -725,7 +886,7 @@ export function indexPage(
|
|
|
725
886
|
type="search"
|
|
726
887
|
id="collection-search"
|
|
727
888
|
class="search-input"
|
|
728
|
-
placeholder="Search tools, skills, interactions, types..."
|
|
889
|
+
placeholder="Search tools, skills, interactions, types, templates..."
|
|
729
890
|
aria-label="Search collections"
|
|
730
891
|
autocomplete="off"
|
|
731
892
|
/>
|
|
@@ -794,6 +955,22 @@ export function indexPage(
|
|
|
794
955
|
</section>
|
|
795
956
|
` : ''}
|
|
796
957
|
|
|
958
|
+
${templates.length > 0 ? /*html*/`
|
|
959
|
+
<section data-section="templates">
|
|
960
|
+
<hr>
|
|
961
|
+
<div class="section-header">
|
|
962
|
+
<h2>Rendering Template Collections</h2>
|
|
963
|
+
<p class="section-subtitle">Document and presentation templates for content generation.</p>
|
|
964
|
+
</div>
|
|
965
|
+
<div class="card-grid">
|
|
966
|
+
${templates.map((t: RenderingTemplateCollection) => {
|
|
967
|
+
const count = t.getTemplateDefinitions().length;
|
|
968
|
+
return collectionCard(t, 'templates', `${count} template${count !== 1 ? 's' : ''}`);
|
|
969
|
+
}).join('')}
|
|
970
|
+
</div>
|
|
971
|
+
</section>
|
|
972
|
+
` : ''}
|
|
973
|
+
|
|
797
974
|
${mcpProviders.length > 0 ? /*html*/`
|
|
798
975
|
<section data-section="mcp">
|
|
799
976
|
<hr>
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ToolDefinition, ToolUse } from "@llumiverse/common";
|
|
2
2
|
import { VertesiaClient } from "@vertesia/client";
|
|
3
|
-
import { AgentToolDefinition, AuthTokenPayload, ToolExecutionMetadata, ToolResult, ToolResultContent } from "@vertesia/common";
|
|
3
|
+
import { AgentToolDefinition, AuthTokenPayload, ProjectConfiguration, RenderingTemplateDefinition, ToolExecutionMetadata, ToolResult, ToolResultContent } from "@vertesia/common";
|
|
4
4
|
|
|
5
5
|
export type { ToolExecutionMetadata };
|
|
6
6
|
|
|
@@ -87,6 +87,15 @@ export interface ToolExecutionPayload<ParamsT extends Record<string, any>> {
|
|
|
87
87
|
|
|
88
88
|
export type ToolFn<ParamsT extends Record<string, any>> = (payload: ToolExecutionPayload<ParamsT>, context: ToolExecutionContext) => Promise<ToolExecutionResult>;
|
|
89
89
|
|
|
90
|
+
export interface ToolUseContext {
|
|
91
|
+
project_id?: string,
|
|
92
|
+
account_id?: string,
|
|
93
|
+
project_name?: string,
|
|
94
|
+
project_ns?: string,
|
|
95
|
+
configuration?: ProjectConfiguration;
|
|
96
|
+
vars?: Record<string, any>;
|
|
97
|
+
}
|
|
98
|
+
|
|
90
99
|
export interface Tool<ParamsT extends Record<string, any>> extends ToolDefinition {
|
|
91
100
|
run: ToolFn<ParamsT>;
|
|
92
101
|
/**
|
|
@@ -95,6 +104,15 @@ export interface Tool<ParamsT extends Record<string, any>> extends ToolDefinitio
|
|
|
95
104
|
* - false: Tool is only available when activated by a skill's related_tools
|
|
96
105
|
*/
|
|
97
106
|
default?: boolean;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Optional filter to check if the tool is enabled for the given project configuration.
|
|
110
|
+
* This can be used to dynamically enable/disable tools based on project settings, environment variables, or any other logic.
|
|
111
|
+
* If no filter is provided, the tool will be enabled by default.
|
|
112
|
+
* @param payload
|
|
113
|
+
* @returns
|
|
114
|
+
*/
|
|
115
|
+
isEnabled?: (payload: ToolUseContext) => boolean;
|
|
98
116
|
}
|
|
99
117
|
|
|
100
118
|
|
|
@@ -127,8 +145,17 @@ export interface MCPConnectionDetails {
|
|
|
127
145
|
* If an empty string no authentication will be done
|
|
128
146
|
*/
|
|
129
147
|
token: string;
|
|
148
|
+
/**
|
|
149
|
+
* Optional additional HTTP headers to include with requests to the MCP server.
|
|
150
|
+
* Merged with the Authorization header derived from the token.
|
|
151
|
+
*/
|
|
152
|
+
headers?: Record<string, string>;
|
|
130
153
|
}
|
|
131
154
|
|
|
155
|
+
// ================== Template Types ==================
|
|
156
|
+
|
|
157
|
+
export type { RenderingTemplateDefinition };
|
|
158
|
+
|
|
132
159
|
// ================== Skill Types ==================
|
|
133
160
|
|
|
134
161
|
/**
|
|
@@ -234,6 +261,16 @@ export interface SkillDefinition {
|
|
|
234
261
|
* The widget file must be located in the skill directory under the name {{widget-name}}.tsx.
|
|
235
262
|
*/
|
|
236
263
|
widgets?: string[];
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Optional filter to check if the tool is enabled for the given project configuration.
|
|
267
|
+
* This can be used to dynamically enable/disable tools based on project settings, environment variables, or any other logic.
|
|
268
|
+
* If no filter is provided, the tool will be enabled by default.
|
|
269
|
+
* @param payload
|
|
270
|
+
* @returns
|
|
271
|
+
*/
|
|
272
|
+
isEnabled?: (payload: ToolUseContext) => boolean;
|
|
273
|
+
|
|
237
274
|
}
|
|
238
275
|
|
|
239
276
|
/**
|
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a name to a URL-safe path segment.
|
|
3
|
+
* If the name contains spaces or underscores, convert to PascalCase.
|
|
4
|
+
* Otherwise return as-is. Any characters not in [a-zA-Z0-9$_\-@] are replaced with '-'.
|
|
5
|
+
*/
|
|
6
|
+
export function toPathName(name: string): string {
|
|
7
|
+
let result = name;
|
|
8
|
+
if (result.includes(' ') || result.includes('_')) {
|
|
9
|
+
result = result.split(/[\s_]+/).map(w => w.charAt(0).toUpperCase() + w.slice(1)).join('');
|
|
10
|
+
}
|
|
11
|
+
return result.replace(/[^a-zA-Z0-9$_\-@]/g, '-');
|
|
12
|
+
}
|
|
13
|
+
|
|
1
14
|
export function kebabCaseToTitle(name: string) {
|
|
2
15
|
return name.split('-').map(p => p[0].toUpperCase() + p.substring(1)).join(' ');
|
|
3
16
|
}
|
|
@@ -20,4 +33,5 @@ export function join(left: string, right: string) {
|
|
|
20
33
|
} else {
|
|
21
34
|
return left + '/' + right;
|
|
22
35
|
}
|
|
23
|
-
}
|
|
36
|
+
}
|
|
37
|
+
|