@@ -38,59 +38,77 @@ const ui = SwaggerUIBundle({
3838 } ,
3939} ) ;
4040
41- const HIERARCHY = {
42- overview : {
43- displayName : "Overview" ,
44- description : null ,
45- tags : [ "embeddings" , "svd" ] ,
46- } ,
47- computations : {
48- displayName : "Computations" ,
49- description : null ,
50- tags : [ "embed" , "logits" , "attn" , "score" , "generate" ] ,
51- } ,
52- openprotein : {
53- displayName : "OpenProtein" ,
54- description : "Proprietary protein language models developed in-house." ,
55- tags : [
56- "poet" ,
57- "prot-seq" ,
58- "rotaprot-large-uniref50w" ,
59- "rotaprot-large-uniref90-ft" ,
60- ] ,
61- } ,
62- esm1 : {
63- displayName : "ESM1" ,
64- description :
65- "Community based ESM1 models, with different versions having different model parameters and training data" ,
66- tags : [
67- "esm1b_t33_650M_UR50S" ,
68- "esm1v_t33_650M_UR90S_1" ,
69- "esm1v_t33_650M_UR90S_2" ,
70- "esm1v_t33_650M_UR90S_3" ,
71- "esm1v_t33_650M_UR90S_4" ,
72- "esm1v_t33_650M_UR90S_5" ,
73- ] ,
74- } ,
75- esm2 : {
76- displayName : "ESM2" ,
77- description :
78- "Community based ESM2 models, with different versions having different model parameters and training data" ,
79- tags : [
80- "esm2_t6_8M_UR50D" ,
81- "esm2_t12_35M_UR50D" ,
82- "esm2_t30_150M_UR50D" ,
83- "esm2_t33_650M_UR50D" ,
84- "esm2_t36_3B_UR50D" ,
85- ] ,
86- } ,
87- community : {
88- displayName : "Community-based" ,
89- description : "Other community-based foundational models." ,
90- tags : [ "prott5-xl" , "proteinmpnn" ] ,
91- } ,
41+ const GROUP_DISPLAY_NAMES = {
42+ openprotein : "OpenProtein" ,
43+ esm1 : "ESM1" ,
44+ esm2 : "ESM2" ,
45+ community : "Community-based" ,
9246} ;
9347
48+ function buildHierarchy ( spec ) {
49+ const tagOrder = { } ;
50+ const tagDescriptions = { } ;
51+ if ( spec . tags ) {
52+ spec . tags . forEach ( ( tag , i ) => {
53+ tagOrder [ tag . name ] = i ;
54+ tagDescriptions [ tag . name ] = tag . description ;
55+ } ) ;
56+ }
57+ const bySpecOrder = ( a , b ) => ( tagOrder [ a ] ?? Infinity ) - ( tagOrder [ b ] ?? Infinity ) ;
58+
59+ const overviewTags = new Set ( ) ;
60+ const computationTypes = new Set ( ) ;
61+ const groupChildren = { } ;
62+
63+ // Scan all operations to discover tag structure:
64+ // - Single-tag operations → overview tags (e.g. ["embeddings"])
65+ // - Multi-tag operations → [group, ...models, computationType]
66+ for ( const path in spec . paths ) {
67+ for ( const method in spec . paths [ path ] ) {
68+ const op = spec . paths [ path ] [ method ] ;
69+ if ( ! op . tags ) continue ;
70+
71+ if ( op . tags . length === 1 ) {
72+ overviewTags . add ( op . tags [ 0 ] ) ;
73+ } else if ( op . tags . length >= 3 ) {
74+ const group = op . tags [ 0 ] ;
75+ computationTypes . add ( op . tags [ op . tags . length - 1 ] ) ;
76+ if ( ! groupChildren [ group ] ) groupChildren [ group ] = new Set ( ) ;
77+ for ( let i = 1 ; i < op . tags . length - 1 ; i ++ ) {
78+ groupChildren [ group ] . add ( op . tags [ i ] ) ;
79+ }
80+ }
81+ }
82+ }
83+
84+ const hierarchy = {
85+ overview : {
86+ displayName : "Overview" ,
87+ description : null ,
88+ tags : [ ...overviewTags ] . sort ( bySpecOrder ) ,
89+ } ,
90+ computations : {
91+ displayName : "Computations" ,
92+ description : null ,
93+ tags : [ ...computationTypes ] . sort ( bySpecOrder ) ,
94+ } ,
95+ } ;
96+
97+ for ( const group of Object . keys ( groupChildren ) . sort ( bySpecOrder ) ) {
98+ hierarchy [ group ] = {
99+ displayName :
100+ GROUP_DISPLAY_NAMES [ group ] ||
101+ group . charAt ( 0 ) . toUpperCase ( ) + group . slice ( 1 ) ,
102+ description : tagDescriptions [ group ] || null ,
103+ tags : [ ...groupChildren [ group ] ] . sort ( bySpecOrder ) ,
104+ } ;
105+ }
106+
107+ return hierarchy ;
108+ }
109+
110+ const HIERARCHY = buildHierarchy ( embeddingsSpec ) ;
111+
94112function adjustDescriptions ( ) {
95113 // adjust group descriptions
96114 for ( const groupName in HIERARCHY ) {
0 commit comments