@vertesia/tools-sdk 1.0.0-dev.20260225.024852Z → 1.0.0-dev.20260305.083323Z

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 (59) hide show
  1. package/lib/cjs/RenderingTemplateCollection.js +43 -0
  2. package/lib/cjs/RenderingTemplateCollection.js.map +1 -0
  3. package/lib/cjs/auth.js +27 -0
  4. package/lib/cjs/auth.js.map +1 -1
  5. package/lib/cjs/index.js +1 -0
  6. package/lib/cjs/index.js.map +1 -1
  7. package/lib/cjs/server/app-package.js +11 -0
  8. package/lib/cjs/server/app-package.js.map +1 -1
  9. package/lib/cjs/server/site.js +7 -1
  10. package/lib/cjs/server/site.js.map +1 -1
  11. package/lib/cjs/server/templates.js +67 -0
  12. package/lib/cjs/server/templates.js.map +1 -0
  13. package/lib/cjs/server.js +4 -1
  14. package/lib/cjs/server.js.map +1 -1
  15. package/lib/cjs/site/templates.js +173 -2
  16. package/lib/cjs/site/templates.js.map +1 -1
  17. package/lib/esm/RenderingTemplateCollection.js +39 -0
  18. package/lib/esm/RenderingTemplateCollection.js.map +1 -0
  19. package/lib/esm/auth.js +27 -0
  20. package/lib/esm/auth.js.map +1 -1
  21. package/lib/esm/index.js +1 -0
  22. package/lib/esm/index.js.map +1 -1
  23. package/lib/esm/server/app-package.js +11 -0
  24. package/lib/esm/server/app-package.js.map +1 -1
  25. package/lib/esm/server/site.js +8 -2
  26. package/lib/esm/server/site.js.map +1 -1
  27. package/lib/esm/server/templates.js +64 -0
  28. package/lib/esm/server/templates.js.map +1 -0
  29. package/lib/esm/server.js +4 -1
  30. package/lib/esm/server.js.map +1 -1
  31. package/lib/esm/site/templates.js +171 -2
  32. package/lib/esm/site/templates.js.map +1 -1
  33. package/lib/types/RenderingTemplateCollection.d.ts +17 -0
  34. package/lib/types/RenderingTemplateCollection.d.ts.map +1 -0
  35. package/lib/types/auth.d.ts.map +1 -1
  36. package/lib/types/index.d.ts +1 -0
  37. package/lib/types/index.d.ts.map +1 -1
  38. package/lib/types/server/app-package.d.ts.map +1 -1
  39. package/lib/types/server/site.d.ts.map +1 -1
  40. package/lib/types/server/templates.d.ts +4 -0
  41. package/lib/types/server/templates.d.ts.map +1 -0
  42. package/lib/types/server/types.d.ts +5 -0
  43. package/lib/types/server/types.d.ts.map +1 -1
  44. package/lib/types/server.d.ts.map +1 -1
  45. package/lib/types/site/templates.d.ts +12 -1
  46. package/lib/types/site/templates.d.ts.map +1 -1
  47. package/lib/types/types.d.ts +2 -1
  48. package/lib/types/types.d.ts.map +1 -1
  49. package/package.json +3 -3
  50. package/src/RenderingTemplateCollection.ts +51 -0
  51. package/src/auth.ts +27 -0
  52. package/src/index.ts +1 -0
  53. package/src/server/app-package.ts +13 -0
  54. package/src/server/site.ts +9 -0
  55. package/src/server/templates.ts +80 -0
  56. package/src/server/types.ts +5 -0
  57. package/src/server.ts +4 -0
  58. package/src/site/templates.ts +179 -2
  59. package/src/types.ts +5 -1
@@ -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, ProjectConfiguration, 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
 
@@ -152,6 +152,10 @@ export interface MCPConnectionDetails {
152
152
  headers?: Record<string, string>;
153
153
  }
154
154
 
155
+ // ================== Template Types ==================
156
+
157
+ export type { RenderingTemplateDefinition };
158
+
155
159
  // ================== Skill Types ==================
156
160
 
157
161
  /**