Improve OpenRouter model lists in extensions (#5459) * fix: extensions OpenRouter model lists * fix: update JSDoc for optional mapping function parameter in fetchModelsByModality * fix: update JSDoc to clarify return type of fetchModelsByModality function * fix: encode output modality in fetchModelsByModality API request

3f72d3df80fa446bf9a9f6625306a0990037650e

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
1 files changed, +10 -10Ignore whitespace
src/endpoints/openrouter.js+10 -10
@@ -38,11 +38,11 @@ router.post('/models/providers', async (req, res) => {
38 * @param {string} endpoint - The API endpoint to fetch from38 * @param {string} endpoint - The API endpoint to fetch from
39 * @param {string} inputModality - Required input modality39 * @param {string} inputModality - Required input modality
40 * @param {string} outputModality - Required output modality40 * @param {string} outputModality - Required output modality
41 * @param {boolean} [idsOnly=false] - Whether to return only model IDs41 * @param {((model: any) => any) | null} [mapFn=null] - Optional mapping function to transform the results
42 * @returns {Promise<any[]>} Filtered models or model IDs42 * @returns {Promise<any[]>} Filtered and/or mapped models
43 */43 */
44async function fetchModelsByModality(endpoint, inputModality, outputModality, idsOnly = false) {44async function fetchModelsByModality(endpoint, inputModality, outputModality, mapFn = null) {
45 const response = await fetch(`${API_OPENROUTER}${endpoint}`, {45 const response = await fetch(`${API_OPENROUTER}${endpoint}?output_modalities=${encodeURIComponent(outputModality)}`, {
46 method: 'GET',46 method: 'GET',
47 headers: { 'Accept': 'application/json' },47 headers: { 'Accept': 'application/json' },
48 });48 });
@@ -67,12 +67,12 @@ async function fetchModelsByModality(endpoint, inputModality, outputModality, id
67 .filter(m => m.architecture.output_modalities.includes(outputModality))67 .filter(m => m.architecture.output_modalities.includes(outputModality))
68 .sort((a, b) => a?.id && b?.id ? a.id.localeCompare(b.id) : 0);68 .sort((a, b) => a?.id && b?.id ? a.id.localeCompare(b.id) : 0);
6969
70 return idsOnly ? filtered.map(m => m.id) : filtered;70 return typeof mapFn === 'function' ? filtered.map(mapFn) : filtered;
71}71}
7272
73router.post('/models/multimodal', async (_req, res) => {73router.post('/models/multimodal', async (_req, res) => {
74 try {74 try {
75 const models = await fetchModelsByModality('/models', 'image', 'text', true);75 const models = await fetchModelsByModality('/models', 'image', 'text', m => m.id);
76 return res.json(models);76 return res.json(models);
77 } catch (error) {77 } catch (error) {
78 console.error(error);78 console.error(error);
@@ -82,7 +82,7 @@ router.post('/models/multimodal', async (_req, res) => {
8282
83router.post('/models/embedding', async (_req, res) => {83router.post('/models/embedding', async (_req, res) => {
84 try {84 try {
85 const models = await fetchModelsByModality('/embeddings/models', 'text', 'embeddings');85 const models = await fetchModelsByModality('/models', 'text', 'embeddings', m => ({ id: m.id, name: m.name }));
86 return res.json(models);86 return res.json(models);
87 } catch (error) {87 } catch (error) {
88 console.error(error);88 console.error(error);
@@ -92,8 +92,8 @@ router.post('/models/embedding', async (_req, res) => {
9292
93router.post('/models/image', async (_req, res) => {93router.post('/models/image', async (_req, res) => {
94 try {94 try {
95 const models = await fetchModelsByModality('/models', 'text', 'image');95 const models = await fetchModelsByModality('/models', 'text', 'image', m => ({ value: m.id, text: m.name || m.id }));
96 return res.json(models.map(m => ({ value: m.id, text: m.name || m.id })));96 return res.json(models);
97 } catch (error) {97 } catch (error) {
98 console.error(error);98 console.error(error);
99 return res.sendStatus(500);99 return res.sendStatus(500);
@@ -132,7 +132,7 @@ router.post('/image/generate', async (req, res) => {
132 content: prompt,132 content: prompt,
133 },133 },
134 ],134 ],
135 modalities: ['image', 'text'],135 modalities: ['image'],
136 image_config: {136 image_config: {
137 aspect_ratio: req.body.aspect_ratio || '1:1',137 aspect_ratio: req.body.aspect_ratio || '1:1',
138 },138 },