Files
HadTavern/static/js/providerTemplates.js

158 lines
5.9 KiB
JavaScript

/* global window */
(function (w) {
'use strict';
// Centralized registry for provider-specific defaults (base_url, endpoint, headers, template)
// Exposes window.ProviderTemplates with:
// .register(name, { defaultConfig: () => ({ base_url, endpoint, headers, template }) })
// .defaults(provider)
// .ensureConfigs(nodeData)
// .getActiveProv(nodeData)
// .getActiveCfg(nodeData)
// .providers()
const PT = {};
const _registry = new Map();
function norm(p) {
return String(p == null ? 'openai' : p).toLowerCase().trim();
}
PT.register = function register(name, def) {
const key = norm(name);
if (!def || typeof def.defaultConfig !== 'function') {
throw new Error('ProviderTemplates.register: def.defaultConfig() required');
}
_registry.set(key, { defaultConfig: def.defaultConfig });
};
PT.providers = function providers() {
return Array.from(_registry.keys());
};
PT.defaults = function defaults(provider) {
const key = norm(provider);
const rec = _registry.get(key);
if (rec && typeof rec.defaultConfig === 'function') {
try { return rec.defaultConfig(); } catch (_) {}
}
return { base_url: '', endpoint: '', headers: `{}`, template: `{}` };
};
PT.ensureConfigs = function ensureConfigs(d) {
if (!d) return;
if (!d.provider) d.provider = 'openai';
if (!d.provider_configs || typeof d.provider_configs !== 'object') d.provider_configs = {};
for (const p of PT.providers()) {
if (!d.provider_configs[p]) d.provider_configs[p] = PT.defaults(p);
}
};
PT.getActiveProv = function getActiveProv(d) {
return norm(d && d.provider);
};
PT.getActiveCfg = function getActiveCfg(d) {
PT.ensureConfigs(d);
const p = PT.getActiveProv(d);
return d && d.provider_configs ? (d.provider_configs[p] || {}) : {};
};
// --- Built-in providers (default presets) ---
// Templates mirror original editor.html logic; use macros [[...]] and {{ ... }} as-is.
function T_OPENAI() { return `{
"model": "{{ model }}",
[[PROMPT]],
"temperature": {{ incoming.json.temperature|default(params.temperature|default(0.7)) }},
"top_p": {{ incoming.json.top_p|default(params.top_p|default(1)) }},
"max_tokens": {{ incoming.json.max_tokens|default(params.max_tokens|default(256)) }},
"max_completion_tokens": {{ incoming.json.max_completion_tokens|default(params.max_tokens|default(256)) }},
"presence_penalty": {{ incoming.json.presence_penalty|default(0) }},
"frequency_penalty": {{ incoming.json.frequency_penalty|default(0) }},
"stop": {{ incoming.json.stop|default(params.stop|default([])) }},
"stream": {{ incoming.json.stream|default(false) }}
}`; }
function T_GEMINI() { return `{
"model": "{{ model }}",
[[PROMPT]],
"safetySettings": {{ incoming.json.safetySettings|default([]) }},
"generationConfig": {
"temperature": {{ incoming.json.generationConfig.temperature|default(params.temperature|default(0.7)) }},
"topP": {{ incoming.json.generationConfig.topP|default(params.top_p|default(1)) }},
"maxOutputTokens": {{ incoming.json.generationConfig.maxOutputTokens|default(params.max_tokens|default(256)) }},
"stopSequences": {{ incoming.json.generationConfig.stopSequences|default(params.stop|default([])) }},
"candidateCount": {{ incoming.json.generationConfig.candidateCount|default(1) }},
"thinkingConfig": {
"includeThoughts": {{ incoming.json.generationConfig.thinkingConfig.includeThoughts|default(false) }},
"thinkingBudget": {{ incoming.json.generationConfig.thinkingConfig.thinkingBudget|default(0) }}
}
}
}`; }
function T_GEMINI_IMAGE() { return `{
"model": "{{ model }}",
[[PROMPT]]
}`; }
function T_CLAUDE() { return `{
"model": "{{ model }}",
[[PROMPT]],
"temperature": {{ incoming.json.temperature|default(params.temperature|default(0.7)) }},
"top_p": {{ incoming.json.top_p|default(params.top_p|default(1)) }},
"max_tokens": {{ incoming.json.max_tokens|default(params.max_tokens|default(256)) }},
"stop_sequences": {{ incoming.json.stop_sequences|default(params.stop|default([])) }},
"stream": {{ incoming.json.stream|default(false) }},
"thinking": {
"type": "{{ incoming.json.thinking.type|default('disabled') }}",
"budget_tokens": {{ incoming.json.thinking.budget_tokens|default(0) }}
},
"anthropic_version": "{{ anthropic_version|default('2023-06-01') }}"
}`; }
// Register built-ins
PT.register('openai', {
defaultConfig: () => ({
base_url: 'https://api.openai.com',
endpoint: '/v1/chat/completions',
headers: `{"Authorization":"Bearer [[VAR:incoming.headers.authorization]]"}`,
template: T_OPENAI()
})
});
PT.register('gemini', {
defaultConfig: () => ({
base_url: 'https://generativelanguage.googleapis.com',
endpoint: '/v1beta/models/{{ model }}:generateContent?key=[[VAR:incoming.api_keys.key]]',
headers: `{}`,
template: T_GEMINI()
})
});
PT.register('gemini_image', {
defaultConfig: () => ({
base_url: 'https://generativelanguage.googleapis.com',
endpoint: '/v1beta/models/{{ model }}:generateContent',
headers: `{"x-goog-api-key":"[[VAR:incoming.api_keys.key]]"}`,
template: T_GEMINI_IMAGE()
})
});
PT.register('claude', {
defaultConfig: () => ({
base_url: 'https://api.anthropic.com',
endpoint: '/v1/messages',
headers: `{"x-api-key":"[[VAR:incoming.headers.x-api-key]]","anthropic-version":"2023-06-01","anthropic-beta":"[[VAR:incoming.headers.anthropic-beta]]"}`,
template: T_CLAUDE()
})
});
try { console.debug('[ProviderTemplates] providers:', PT.providers()); } catch (_) {}
// Export globals and compatibility shims
try {
w.ProviderTemplates = PT;
// Back-compat shims so existing code can call global helpers
w.providerDefaults = PT.defaults;
w.ensureProviderConfigs = PT.ensureConfigs;
w.getActiveProv = PT.getActiveProv;
w.getActiveCfg = PT.getActiveCfg;
} catch (_) {}
})(window);