@vertesia/tools-sdk 1.0.0-dev.20260128.144200 → 1.0.0-dev.20260203.130115Z

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.
Files changed (137) hide show
  1. package/package.json +5 -5
  2. package/src/ContentTypesCollection.ts +51 -0
  3. package/src/InteractionCollection.ts +1 -94
  4. package/src/SkillCollection.ts +3 -2
  5. package/src/ToolCollection.ts +6 -4
  6. package/src/ToolRegistry.ts +10 -4
  7. package/src/index.ts +1 -0
  8. package/src/server/app-package.ts +102 -0
  9. package/src/server/conyent-types.ts +71 -0
  10. package/src/server/interactions.ts +24 -3
  11. package/src/server/site.ts +9 -0
  12. package/src/server/types.ts +18 -0
  13. package/src/server.ts +5 -0
  14. package/src/site/styles.ts +55 -0
  15. package/src/site/templates.ts +107 -84
  16. package/src/types.ts +2 -18
  17. package/lib/cjs/InteractionCollection.js +0 -164
  18. package/lib/cjs/InteractionCollection.js.map +0 -1
  19. package/lib/cjs/SkillCollection.js +0 -376
  20. package/lib/cjs/SkillCollection.js.map +0 -1
  21. package/lib/cjs/ToolCollection.js +0 -228
  22. package/lib/cjs/ToolCollection.js.map +0 -1
  23. package/lib/cjs/ToolRegistry.js +0 -111
  24. package/lib/cjs/ToolRegistry.js.map +0 -1
  25. package/lib/cjs/auth.js +0 -104
  26. package/lib/cjs/auth.js.map +0 -1
  27. package/lib/cjs/build/validate.js +0 -7
  28. package/lib/cjs/build/validate.js.map +0 -1
  29. package/lib/cjs/copy-assets.js +0 -84
  30. package/lib/cjs/copy-assets.js.map +0 -1
  31. package/lib/cjs/index.js +0 -31
  32. package/lib/cjs/index.js.map +0 -1
  33. package/lib/cjs/package.json +0 -3
  34. package/lib/cjs/server/interactions.js +0 -66
  35. package/lib/cjs/server/interactions.js.map +0 -1
  36. package/lib/cjs/server/mcp.js +0 -45
  37. package/lib/cjs/server/mcp.js.map +0 -1
  38. package/lib/cjs/server/site.js +0 -30
  39. package/lib/cjs/server/site.js.map +0 -1
  40. package/lib/cjs/server/skills.js +0 -114
  41. package/lib/cjs/server/skills.js.map +0 -1
  42. package/lib/cjs/server/tools.js +0 -104
  43. package/lib/cjs/server/tools.js.map +0 -1
  44. package/lib/cjs/server/types.js +0 -3
  45. package/lib/cjs/server/types.js.map +0 -1
  46. package/lib/cjs/server/widgets.js +0 -27
  47. package/lib/cjs/server/widgets.js.map +0 -1
  48. package/lib/cjs/server.js +0 -132
  49. package/lib/cjs/server.js.map +0 -1
  50. package/lib/cjs/site/styles.js +0 -637
  51. package/lib/cjs/site/styles.js.map +0 -1
  52. package/lib/cjs/site/templates.js +0 -995
  53. package/lib/cjs/site/templates.js.map +0 -1
  54. package/lib/cjs/types.js +0 -3
  55. package/lib/cjs/types.js.map +0 -1
  56. package/lib/cjs/utils.js +0 -31
  57. package/lib/cjs/utils.js.map +0 -1
  58. package/lib/esm/InteractionCollection.js +0 -125
  59. package/lib/esm/InteractionCollection.js.map +0 -1
  60. package/lib/esm/SkillCollection.js +0 -369
  61. package/lib/esm/SkillCollection.js.map +0 -1
  62. package/lib/esm/ToolCollection.js +0 -190
  63. package/lib/esm/ToolCollection.js.map +0 -1
  64. package/lib/esm/ToolRegistry.js +0 -106
  65. package/lib/esm/ToolRegistry.js.map +0 -1
  66. package/lib/esm/auth.js +0 -97
  67. package/lib/esm/auth.js.map +0 -1
  68. package/lib/esm/build/validate.js +0 -4
  69. package/lib/esm/build/validate.js.map +0 -1
  70. package/lib/esm/copy-assets.js +0 -81
  71. package/lib/esm/copy-assets.js.map +0 -1
  72. package/lib/esm/index.js +0 -11
  73. package/lib/esm/index.js.map +0 -1
  74. package/lib/esm/server/interactions.js +0 -63
  75. package/lib/esm/server/interactions.js.map +0 -1
  76. package/lib/esm/server/mcp.js +0 -42
  77. package/lib/esm/server/mcp.js.map +0 -1
  78. package/lib/esm/server/site.js +0 -27
  79. package/lib/esm/server/site.js.map +0 -1
  80. package/lib/esm/server/skills.js +0 -111
  81. package/lib/esm/server/skills.js.map +0 -1
  82. package/lib/esm/server/tools.js +0 -101
  83. package/lib/esm/server/tools.js.map +0 -1
  84. package/lib/esm/server/types.js +0 -2
  85. package/lib/esm/server/types.js.map +0 -1
  86. package/lib/esm/server/widgets.js +0 -24
  87. package/lib/esm/server/widgets.js.map +0 -1
  88. package/lib/esm/server.js +0 -128
  89. package/lib/esm/server.js.map +0 -1
  90. package/lib/esm/site/styles.js +0 -634
  91. package/lib/esm/site/styles.js.map +0 -1
  92. package/lib/esm/site/templates.js +0 -983
  93. package/lib/esm/site/templates.js.map +0 -1
  94. package/lib/esm/types.js +0 -2
  95. package/lib/esm/types.js.map +0 -1
  96. package/lib/esm/utils.js +0 -26
  97. package/lib/esm/utils.js.map +0 -1
  98. package/lib/types/InteractionCollection.d.ts +0 -48
  99. package/lib/types/InteractionCollection.d.ts.map +0 -1
  100. package/lib/types/SkillCollection.d.ts +0 -118
  101. package/lib/types/SkillCollection.d.ts.map +0 -1
  102. package/lib/types/ToolCollection.d.ts +0 -72
  103. package/lib/types/ToolCollection.d.ts.map +0 -1
  104. package/lib/types/ToolRegistry.d.ts +0 -41
  105. package/lib/types/ToolRegistry.d.ts.map +0 -1
  106. package/lib/types/auth.d.ts +0 -32
  107. package/lib/types/auth.d.ts.map +0 -1
  108. package/lib/types/build/validate.d.ts +0 -2
  109. package/lib/types/build/validate.d.ts.map +0 -1
  110. package/lib/types/copy-assets.d.ts +0 -14
  111. package/lib/types/copy-assets.d.ts.map +0 -1
  112. package/lib/types/index.d.ts +0 -11
  113. package/lib/types/index.d.ts.map +0 -1
  114. package/lib/types/server/interactions.d.ts +0 -4
  115. package/lib/types/server/interactions.d.ts.map +0 -1
  116. package/lib/types/server/mcp.d.ts +0 -4
  117. package/lib/types/server/mcp.d.ts.map +0 -1
  118. package/lib/types/server/site.d.ts +0 -4
  119. package/lib/types/server/site.d.ts.map +0 -1
  120. package/lib/types/server/skills.d.ts +0 -4
  121. package/lib/types/server/skills.d.ts.map +0 -1
  122. package/lib/types/server/tools.d.ts +0 -4
  123. package/lib/types/server/tools.d.ts.map +0 -1
  124. package/lib/types/server/types.d.ts +0 -66
  125. package/lib/types/server/types.d.ts.map +0 -1
  126. package/lib/types/server/widgets.d.ts +0 -9
  127. package/lib/types/server/widgets.d.ts.map +0 -1
  128. package/lib/types/server.d.ts +0 -27
  129. package/lib/types/server.d.ts.map +0 -1
  130. package/lib/types/site/styles.d.ts +0 -5
  131. package/lib/types/site/styles.d.ts.map +0 -1
  132. package/lib/types/site/templates.d.ts +0 -55
  133. package/lib/types/site/templates.d.ts.map +0 -1
  134. package/lib/types/types.d.ts +0 -280
  135. package/lib/types/types.d.ts.map +0 -1
  136. package/lib/types/utils.d.ts +0 -4
  137. package/lib/types/utils.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertesia/tools-sdk",
3
- "version": "1.0.0-dev.20260128.144200",
3
+ "version": "1.0.0-dev.20260203.130115Z",
4
4
  "description": "Tools SDK - utilities for building remote tools",
5
5
  "type": "module",
6
6
  "types": "./lib/types/index.d.ts",
@@ -27,14 +27,14 @@
27
27
  "outDir": "lib"
28
28
  },
29
29
  "peerDependencies": {
30
- "hono": "^4.11.4"
30
+ "hono": "^4.11.7"
31
31
  },
32
32
  "dependencies": {
33
33
  "jose": "^6.0.11",
34
34
  "zod": "^4.3.5",
35
- "@llumiverse/common": "1.0.0-dev.20260128.144200",
36
- "@vertesia/client": "1.0.0-dev.20260128.144200",
37
- "@vertesia/common": "1.0.0-dev.20260128.144200"
35
+ "@llumiverse/common": "1.0.0-dev.20260202.145450Z",
36
+ "@vertesia/common": "1.0.0-dev.20260203.130115Z",
37
+ "@vertesia/client": "1.0.0-dev.20260203.130115Z"
38
38
  },
39
39
  "repository": {
40
40
  "type": "git",
@@ -0,0 +1,51 @@
1
+ import { InCodeTypeDefinition } from "@vertesia/common";
2
+ import { CollectionProperties, ICollection } from "./types.js";
3
+ import { kebabCaseToTitle } from "./utils.js";
4
+
5
+ export interface ContentTypesCollectionProps extends CollectionProperties {
6
+ types: InCodeTypeDefinition[];
7
+ }
8
+ export class ContentTypesCollection implements ICollection<InCodeTypeDefinition> {
9
+ types: InCodeTypeDefinition[];
10
+ name: string;
11
+ title?: string;
12
+ icon?: string;
13
+ description?: string;
14
+ constructor({
15
+ name, title, icon, description, types
16
+ }: ContentTypesCollectionProps) {
17
+ this.name = name;
18
+ this.title = title || kebabCaseToTitle(name);
19
+ this.icon = icon;
20
+ this.description = description;
21
+ this.types = types;
22
+ }
23
+
24
+ getContentTypes() {
25
+ return this.types;
26
+ }
27
+
28
+ [Symbol.iterator](): Iterator<InCodeTypeDefinition> {
29
+ let index = 0;
30
+ const types = this.types;
31
+
32
+ return {
33
+ next(): IteratorResult<InCodeTypeDefinition> {
34
+ if (index < types.length) {
35
+ return { value: types[index++], done: false };
36
+ } else {
37
+ return { done: true, value: undefined };
38
+ }
39
+ }
40
+ };
41
+ }
42
+
43
+ map<U>(callback: (type: InCodeTypeDefinition, index: number) => U): U[] {
44
+ return this.types.map(callback);
45
+ }
46
+
47
+ getTypeByName(name: string): InCodeTypeDefinition | undefined {
48
+ return this.types.find(type => type.name === name);
49
+ }
50
+
51
+ }
@@ -1,8 +1,5 @@
1
- import { readdirSync, statSync, existsSync, readFileSync } from "fs";
2
- import { join } from "path";
3
- import { pathToFileURL } from "url";
4
1
  import { InteractionSpec } from "@vertesia/common";
5
- import { ICollection, CollectionProperties } from "./types.js";
2
+ import { CollectionProperties, ICollection } from "./types.js";
6
3
  import { kebabCaseToTitle } from "./utils.js";
7
4
 
8
5
  export interface InteractionCollectionProps extends CollectionProperties {
@@ -23,9 +20,6 @@ export class InteractionCollection implements ICollection<InteractionSpec> {
23
20
  this.description = description;
24
21
  this.interactions = interactions;
25
22
  }
26
- addInteraction(interaction: any) {
27
- this.interactions.push(interaction);
28
- }
29
23
 
30
24
  getInteractions() {
31
25
  return this.interactions;
@@ -54,90 +48,3 @@ export class InteractionCollection implements ICollection<InteractionSpec> {
54
48
  return this.interactions.find(interaction => interaction.name === name);
55
49
  }
56
50
  }
57
-
58
- /**
59
- * Load all interactions from a directory.
60
- * Scans for subdirectories containing index.ts/index.js files.
61
- *
62
- * Directory structure:
63
- * ```
64
- * interactions/
65
- * nagare/
66
- * extract-fund-actuals/
67
- * index.ts # exports default InteractionSpec
68
- * prompt.jst # prompt template (read via readPromptFile helper)
69
- * parse-fund-document/
70
- * index.ts
71
- * prompt.md
72
- * ```
73
- *
74
- * @param interactionsDir - Path to the interactions collection directory
75
- * @returns Promise resolving to array of InteractionSpec objects
76
- */
77
- export async function loadInteractionsFromDirectory(interactionsDir: string): Promise<InteractionSpec[]> {
78
- const interactions: InteractionSpec[] = [];
79
-
80
- if (!existsSync(interactionsDir)) {
81
- console.warn(`Interactions directory not found: ${interactionsDir}`);
82
- return interactions;
83
- }
84
-
85
- let entries: string[];
86
- try {
87
- entries = readdirSync(interactionsDir);
88
- } catch {
89
- console.warn(`Could not read interactions directory: ${interactionsDir}`);
90
- return interactions;
91
- }
92
-
93
- for (const entry of entries) {
94
- // Skip hidden files and index files
95
- if (entry.startsWith('.')) continue;
96
- if (entry === 'index.ts' || entry === 'index.js') continue;
97
-
98
- const entryPath = join(interactionsDir, entry);
99
-
100
- try {
101
- const stat = statSync(entryPath);
102
- if (!stat.isDirectory()) continue;
103
-
104
- // Look for index.ts or index.js in the subdirectory
105
- const indexTs = join(entryPath, 'index.ts');
106
- const indexJs = join(entryPath, 'index.js');
107
- const indexPath = existsSync(indexTs) ? indexTs : existsSync(indexJs) ? indexJs : null;
108
-
109
- if (!indexPath) {
110
- continue; // No index file, skip
111
- }
112
-
113
- // Dynamic import
114
- const fileUrl = pathToFileURL(indexPath).href;
115
- const module = await import(fileUrl);
116
-
117
- const interaction = module.default || module.interaction;
118
-
119
- if (interaction && typeof interaction.name === 'string') {
120
- interactions.push(interaction);
121
- } else {
122
- console.warn(`No valid InteractionSpec export found in ${entry}/index`);
123
- }
124
- } catch (err) {
125
- console.warn(`Error loading interaction from ${entry}:`, err);
126
- }
127
- }
128
-
129
- return interactions;
130
- }
131
-
132
- /**
133
- * Helper to read a prompt file from the same directory as the interaction.
134
- * Use this in interaction index.ts files to load prompt templates.
135
- *
136
- * @param dirname - Pass __dirname or dirname(fileURLToPath(import.meta.url))
137
- * @param filename - Prompt filename (e.g., 'prompt.jst' or 'prompt.md')
138
- * @returns File contents as string
139
- */
140
- export function readPromptFile(dirname: string, filename: string): string {
141
- const filePath = join(dirname, filename);
142
- return readFileSync(filePath, 'utf-8');
143
- }
@@ -11,11 +11,11 @@ import type {
11
11
  SkillDefinition,
12
12
  SkillExecutionResult,
13
13
  ToolCollectionDefinition,
14
- ToolDefinitionWithDefault,
15
14
  ToolExecutionPayload,
16
15
  ToolExecutionResult,
17
16
  } from "./types.js";
18
17
  import { kebabCaseToTitle } from "./utils.js";
18
+ import { AgentToolDefinition } from "@vertesia/common";
19
19
 
20
20
  export interface SkillCollectionProperties extends CollectionProperties {
21
21
  /**
@@ -87,7 +87,7 @@ export class SkillCollection implements ICollection<SkillDefinition> {
87
87
  * When called, they return rendered instructions.
88
88
  * Includes related_tools for dynamic tool discovery.
89
89
  */
90
- getToolDefinitions(): ToolDefinitionWithDefault[] {
90
+ getToolDefinitions(): AgentToolDefinition[] {
91
91
  const defaultSchema: ToolDefinition['input_schema'] = {
92
92
  type: 'object',
93
93
  properties: {
@@ -110,6 +110,7 @@ export class SkillCollection implements ICollection<SkillDefinition> {
110
110
  description,
111
111
  input_schema: skill.input_schema || defaultSchema,
112
112
  related_tools: skill.related_tools,
113
+ category: this.name,
113
114
  };
114
115
  });
115
116
  }
@@ -6,8 +6,9 @@ import { HTTPException } from "hono/http-exception";
6
6
  import { authorize } from "./auth.js";
7
7
  import { ToolFilterOptions, ToolRegistry } from "./ToolRegistry.js";
8
8
  import { ToolContext } from "./server/types.js";
9
- import type { CollectionProperties, ICollection, Tool, ToolDefinitionWithDefault, ToolExecutionPayload, ToolExecutionResponse, ToolExecutionResponseError } from "./types.js";
9
+ import type { CollectionProperties, ICollection, Tool, ToolExecutionPayload, ToolExecutionResponse, ToolExecutionResponseError } from "./types.js";
10
10
  import { kebabCaseToTitle } from "./utils.js";
11
+ import { AgentToolDefinition } from "@vertesia/common";
11
12
 
12
13
  export interface ToolCollectionProperties extends CollectionProperties {
13
14
  /**
@@ -52,7 +53,8 @@ export class ToolCollection implements ICollection<Tool<any>> {
52
53
  this.title = title || kebabCaseToTitle(name);
53
54
  this.icon = icon;
54
55
  this.description = description;
55
- this.tools = new ToolRegistry(tools);
56
+ // we add the collection name info
57
+ this.tools = new ToolRegistry(name, tools);
56
58
  }
57
59
 
58
60
  [Symbol.iterator](): Iterator<Tool<any>> {
@@ -126,7 +128,7 @@ export class ToolCollection implements ICollection<Tool<any>> {
126
128
  * @param options - Filtering options for default/unlocked tools
127
129
  * @returns Filtered tool definitions
128
130
  */
129
- getToolDefinitions(options?: ToolFilterOptions): ToolDefinitionWithDefault[] {
131
+ getToolDefinitions(options?: ToolFilterOptions): AgentToolDefinition[] {
130
132
  return this.tools.getDefinitions(options);
131
133
  }
132
134
 
@@ -135,7 +137,7 @@ export class ToolCollection implements ICollection<Tool<any>> {
135
137
  * @param unlockedTools - List of tool names that are unlocked
136
138
  * @returns Tool definitions for reserve tools
137
139
  */
138
- getReserveTools(unlockedTools: string[] = []): ToolDefinitionWithDefault[] {
140
+ getReserveTools(unlockedTools: string[] = []): AgentToolDefinition[] {
139
141
  return this.tools.getReserveTools(unlockedTools);
140
142
  }
141
143
 
@@ -1,5 +1,6 @@
1
+ import { AgentToolDefinition } from "@vertesia/common";
1
2
  import { HTTPException } from "hono/http-exception";
2
- import { Tool, ToolDefinitionWithDefault, ToolExecutionContext, ToolExecutionPayload, ToolExecutionResult } from "./types.js";
3
+ import { Tool, ToolExecutionContext, ToolExecutionPayload, ToolExecutionResult } from "./types.js";
3
4
 
4
5
  /**
5
6
  * Options for filtering tool definitions
@@ -19,9 +20,12 @@ export interface ToolFilterOptions {
19
20
 
20
21
  export class ToolRegistry {
21
22
 
23
+ // The category name usinfg this registry
24
+ category: string;
22
25
  registry: Record<string, Tool<any>> = {};
23
26
 
24
- constructor(tools: Tool<any>[] = []) {
27
+ constructor(category: string, tools: Tool<any>[] = []) {
28
+ this.category = category;
25
29
  for (const tool of tools) {
26
30
  this.registry[tool.name] = tool;
27
31
  }
@@ -32,7 +36,7 @@ export class ToolRegistry {
32
36
  * @param options - Filtering options
33
37
  * @returns Filtered tool definitions
34
38
  */
35
- getDefinitions(options?: ToolFilterOptions): ToolDefinitionWithDefault[] {
39
+ getDefinitions(options?: ToolFilterOptions): AgentToolDefinition[] {
36
40
  const { defaultOnly, unlockedTools = [] } = options || {};
37
41
  const unlockedSet = new Set(unlockedTools);
38
42
 
@@ -50,6 +54,7 @@ export class ToolRegistry {
50
54
  name: tool.name,
51
55
  description: tool.description,
52
56
  input_schema: tool.input_schema,
57
+ category: this.category,
53
58
  default: tool.default,
54
59
  }));
55
60
  }
@@ -59,7 +64,7 @@ export class ToolRegistry {
59
64
  * @param unlockedTools - List of tool names that are unlocked
60
65
  * @returns Tool definitions for reserve tools
61
66
  */
62
- getReserveTools(unlockedTools: string[] = []): ToolDefinitionWithDefault[] {
67
+ getReserveTools(unlockedTools: string[] = []): AgentToolDefinition[] {
63
68
  const unlockedSet = new Set(unlockedTools);
64
69
 
65
70
  return Object.values(this.registry)
@@ -68,6 +73,7 @@ export class ToolRegistry {
68
73
  name: tool.name,
69
74
  description: tool.description,
70
75
  input_schema: tool.input_schema,
76
+ category: this.category,
71
77
  default: tool.default,
72
78
  }));
73
79
  }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { authorize, AuthSession } from "./auth.js";
2
+ export * from "./ContentTypesCollection.js";
2
3
  export { copyRuntimeAssets } from "./copy-assets.js";
3
4
  export * from "./InteractionCollection.js";
4
5
  export * from "./server.js";
@@ -0,0 +1,102 @@
1
+ import { AppPackage, AppPackageScope, CatalogInteractionRef, InCodeTypeDefinition } from "@vertesia/common";
2
+ import { Context, Hono } from "hono";
3
+ import { ToolServerConfig } from "./types.js";
4
+
5
+
6
+ const builders: Record<Exclude<AppPackageScope, 'all'>, (pkg: AppPackage, config: ToolServerConfig, c: Context) => void> = {
7
+ tools(pkg: AppPackage, config: ToolServerConfig) {
8
+ const { tools: toolCollections = [], skills: skillCollections = [] } = config;
9
+
10
+ // Aggregate all tools from all collections
11
+ const allTools = toolCollections.flatMap(collection =>
12
+ collection.getToolDefinitions()
13
+ );
14
+
15
+ // same for skills
16
+ const allSkills = skillCollections.flatMap(collection =>
17
+ collection.getToolDefinitions()
18
+ );
19
+
20
+ pkg.tools = allSkills.concat(allTools);
21
+ },
22
+ interactions(pkg: AppPackage, config: ToolServerConfig) {
23
+ const allInteractions: CatalogInteractionRef[] = [];
24
+ for (const coll of (config.interactions || [])) {
25
+ for (const inter of coll.interactions) {
26
+ allInteractions.push({
27
+ type: "app",
28
+ id: coll.name + ":" + inter.name,
29
+ name: inter.name,
30
+ title: inter.title || inter.name,
31
+ description: inter.description,
32
+ tags: inter.tags || [],
33
+ });
34
+ }
35
+ }
36
+ pkg.interactions = allInteractions;
37
+ },
38
+ types(pkg: AppPackage, config: ToolServerConfig) {
39
+ const allTypes: InCodeTypeDefinition[] = [];
40
+ for (const coll of config.types || []) {
41
+ for (const type of coll.types) {
42
+ allTypes.push(type);
43
+ }
44
+ }
45
+ pkg.types = allTypes;
46
+ },
47
+ ui(pkg: AppPackage, config: ToolServerConfig, c: Context) {
48
+ if (config.uiConfig) {
49
+ pkg.ui = { ...config.uiConfig };
50
+ const origin = new URL(c.req.url).origin;
51
+ pkg.ui.src = new URL(pkg.ui.src, origin).toString();
52
+ if (!pkg.ui.isolation) {
53
+ pkg.ui.isolation = "shadow";
54
+ }
55
+ }
56
+ },
57
+ settings(pkg: AppPackage, config: ToolServerConfig) {
58
+ if (config.settings) {
59
+ pkg.settings_schema = { ...config.settings };
60
+ }
61
+ },
62
+ }
63
+
64
+
65
+ export function createPackageRoute(app: Hono, basePath: string, config: ToolServerConfig) {
66
+ const { interactions = [], tools: toolCollections = [], mcpProviders = [] } = config;
67
+
68
+ app.get(basePath, (c: Context) => {
69
+ const scope = c.req.query('scope') || 'all';
70
+ const pkg: AppPackage = {};
71
+ interactions; toolCollections; mcpProviders;
72
+
73
+ const scopes = new Set<AppPackageScope>(scope.split(',') as AppPackageScope[]);
74
+ // TODO build pkg based on the query param scope
75
+ if (scopes.has('all')) {
76
+ builders.tools(pkg, config, c);
77
+ builders.interactions(pkg, config, c);
78
+ builders.types(pkg, config, c);
79
+ builders.ui(pkg, config, c);
80
+ builders.settings(pkg, config, c);
81
+ } else {
82
+ if (scopes.has('tools')) {
83
+ builders.tools(pkg, config, c);
84
+ }
85
+ if (scopes.has('interactions')) {
86
+ builders.interactions(pkg, config, c);
87
+ }
88
+ if (scopes.has('types')) {
89
+ builders.types(pkg, config, c);
90
+ }
91
+ if (scopes.has('ui')) {
92
+ builders.ui(pkg, config, c);
93
+ }
94
+ if (scopes.has('settings')) {
95
+ builders.settings(pkg, config, c);
96
+ }
97
+ }
98
+
99
+ return c.json(pkg);
100
+ });
101
+ }
102
+
@@ -0,0 +1,71 @@
1
+ // ================== Content Type Endpoints ==================
2
+
3
+ import { InCodeTypeDefinition } from "@vertesia/common";
4
+ import { Context, Hono } from "hono";
5
+ import { ContentTypesCollection } from "../ContentTypesCollection.js";
6
+ import { ToolServerConfig } from "./types.js";
7
+ import { HTTPException } from "hono/http-exception";
8
+
9
+ export function createContentTypesRoute(app: Hono, basePath: string, config: ToolServerConfig) {
10
+ const { types = [] } = config;
11
+
12
+ // GET /api/types - Returns all interactions from all collections
13
+ app.get(basePath, (c) => {
14
+ const allTypes: InCodeTypeDefinition[] = [];
15
+
16
+ for (const coll of types) {
17
+ for (const type of coll.types) {
18
+ allTypes.push(type);
19
+ }
20
+ }
21
+
22
+ return c.json({
23
+ title: 'All Content Types',
24
+ description: 'All available content types across all collections',
25
+ types: allTypes,
26
+ collections: types.map(i => ({
27
+ name: i.name,
28
+ title: i.title,
29
+ description: i.description,
30
+ })),
31
+ });
32
+ });
33
+
34
+ // Create interaction collection endpoints
35
+ for (const coll of types) {
36
+ app.route(`${basePath}/${coll.name}`, createContentTypeEndpoints(coll));
37
+ }
38
+
39
+ // GET /api/types/:name - Direct access to content type
40
+ app.get(`${basePath}/:name`, async (c) => {
41
+ const name = c.req.param('name');
42
+
43
+ // Search across all collections for the interaction
44
+ for (const coll of types) {
45
+ const inter = coll.getTypeByName(name);
46
+ if (inter) {
47
+ return c.json(inter);
48
+ }
49
+ }
50
+
51
+ throw new HTTPException(404, {
52
+ message: "No interaction found with name: " + name
53
+ });
54
+ });
55
+
56
+ }
57
+
58
+
59
+
60
+
61
+ function createContentTypeEndpoints(coll: ContentTypesCollection): Hono {
62
+ const endpoint = new Hono();
63
+
64
+ endpoint.get('/', (c: Context) => {
65
+ return c.json(coll.types);
66
+ });
67
+
68
+
69
+
70
+ return endpoint;
71
+ }
@@ -18,7 +18,7 @@ export function createInteractionsRoute(app: Hono, basePath: string, config: Too
18
18
  for (const inter of coll.interactions) {
19
19
  allInteractions.push({
20
20
  type: "app",
21
- id: inter.name,
21
+ id: coll.name + ":" + inter.name,
22
22
  name: inter.name,
23
23
  title: inter.title || inter.name,
24
24
  description: inter.description,
@@ -44,6 +44,24 @@ export function createInteractionsRoute(app: Hono, basePath: string, config: Too
44
44
  app.route(`${basePath}/${coll.name}`, createInteractionEndpoints(coll));
45
45
  }
46
46
 
47
+ // GET /api/interactions/:name - Direct access to interaction by name (searches all collections)
48
+ app.get(`${basePath}/:name`, async (c) => {
49
+ await authorize(c);
50
+ const name = c.req.param('name');
51
+
52
+ // Search across all collections for the interaction
53
+ for (const coll of interactions) {
54
+ const inter = coll.getInteractionByName(name);
55
+ if (inter) {
56
+ return c.json(inter);
57
+ }
58
+ }
59
+
60
+ throw new HTTPException(404, {
61
+ message: "No interaction found with name: " + name
62
+ });
63
+ });
64
+
47
65
  }
48
66
 
49
67
 
@@ -55,7 +73,7 @@ function createInteractionEndpoints(coll: InteractionCollection): Hono {
55
73
  endpoint.get('/', (c: Context) => {
56
74
  return c.json(coll.interactions.map(inter => ({
57
75
  type: "app",
58
- id: inter.name,
76
+ id: coll.name + ":" + inter.name,
59
77
  name: inter.name,
60
78
  title: inter.title || inter.name,
61
79
  description: inter.description,
@@ -72,7 +90,10 @@ function createInteractionEndpoints(coll: InteractionCollection): Hono {
72
90
  message: "No interaction found with name: " + name
73
91
  });
74
92
  }
75
- return c.json(inter);
93
+ return c.json({
94
+ ...inter,
95
+ id: coll.name + ":" + inter.name,
96
+ });
76
97
  });
77
98
 
78
99
  return endpoint;
@@ -1,5 +1,6 @@
1
1
  import { Hono } from "hono";
2
2
  import {
3
+ contentTypeCollectionPage,
3
4
  indexPage,
4
5
  interactionCollectionPage,
5
6
  skillCollectionPage,
@@ -12,6 +13,7 @@ export function createSiteRoute(app: Hono, basePath: string, config: ToolServerC
12
13
  const {
13
14
  tools = [],
14
15
  interactions = [],
16
+ types = [],
15
17
  skills = [],
16
18
  } = config;
17
19
 
@@ -41,4 +43,11 @@ export function createSiteRoute(app: Hono, basePath: string, config: ToolServerC
41
43
  });
42
44
  }
43
45
 
46
+ // Content type collection pages
47
+ for (const coll of types) {
48
+ app.get(`${basePath}/types/${coll.name}`, (c) => {
49
+ return c.html(contentTypeCollectionPage(coll));
50
+ });
51
+ }
52
+
44
53
  }
@@ -3,6 +3,9 @@ import { InteractionCollection } from "../InteractionCollection.js";
3
3
  import { SkillCollection } from "../SkillCollection.js";
4
4
  import { ToolCollection } from "../ToolCollection.js";
5
5
  import { ToolExecutionPayload } from "../types.js";
6
+ import { JSONSchema } from "@llumiverse/common";
7
+ import { AppUIConfig } from "@vertesia/common";
8
+ import { ContentTypesCollection } from "../ContentTypesCollection.js";
6
9
 
7
10
  /**
8
11
  * Extended context with parsed payload for tool/skill execution
@@ -49,6 +52,10 @@ export interface ToolServerConfig {
49
52
  * Interaction collections to expose
50
53
  */
51
54
  interactions?: InteractionCollection[];
55
+ /**
56
+ * Content type collections to expose
57
+ */
58
+ types?: ContentTypesCollection[];
52
59
  /**
53
60
  * Skill collections to expose
54
61
  */
@@ -57,6 +64,17 @@ export interface ToolServerConfig {
57
64
  * MCP providers to expose
58
65
  */
59
66
  mcpProviders?: MCPProviderConfig[];
67
+
68
+ /**
69
+ * A JSON schema defining settings for the application using this server
70
+ */
71
+ settings?: JSONSchema;
72
+
73
+ /**
74
+ * The UI configuration for the application using this server
75
+ */
76
+ uiConfig?: AppUIConfig;
77
+
60
78
  /**
61
79
  * Disable HTML pages (default: false)
62
80
  */
package/src/server.ts CHANGED
@@ -10,6 +10,8 @@ import { createToolsRoute } from "./server/tools.js";
10
10
  import { ToolContext, ToolServerConfig } from "./server/types.js";
11
11
  import { ToolExecutionPayload } from "./types.js";
12
12
  import { createWidgetsRoute } from "./server/widgets.js";
13
+ import { createPackageRoute } from "./server/app-package.js";
14
+ import { createContentTypesRoute } from "./server/conyent-types.js";
13
15
 
14
16
  // Schema for tool execution payload
15
17
  const ToolExecutionPayloadSchema = z.object({
@@ -98,10 +100,13 @@ export function createToolServer(config: ToolServerConfig): Hono {
98
100
  });
99
101
  });
100
102
 
103
+
104
+ createPackageRoute(app, `${prefix}/package`, config);
101
105
  createToolsRoute(app, `${prefix}/tools`, config);
102
106
  createSkillsRoute(app, `${prefix}/skills`, config);
103
107
  createWidgetsRoute(app, `${prefix}/widgets`, config);
104
108
  createInteractionsRoute(app, `${prefix}/interactions`, config);
109
+ createContentTypesRoute(app, `${prefix}/types`, config);
105
110
  createMcpRoute(app, `${prefix}/mcp`, config);
106
111
 
107
112