mirror of
https://github.com/wiseguru/ReWrite-Voice-Notes.git
synced 2026-07-22 07:49:19 +00:00
Add link to models
This commit is contained in:
parent
15304c758c
commit
5e98637c76
2 changed files with 45 additions and 3 deletions
|
|
@ -107,7 +107,7 @@ The `PipelineSource` union has three variants: `audio` (recorded blob, optional
|
|||
|
||||
API keys are stored per profile on `EnvironmentProfile.transcriptionConfig.apiKey` / `llmConfig.apiKey`. Two slots per profile, one for transcription and one for the LLM. No global by-family map; the desktop and mobile profiles each carry their own keys even when both use the same provider (deliberate: per-profile keys make per-function usage tracking easier). Persistence is in [src/secrets.ts](src/secrets.ts) using the key IDs `profile:desktop:transcription`, `profile:desktop:llm`, `profile:mobile:transcription`, `profile:mobile:llm`.
|
||||
|
||||
Providers may optionally implement `listModels(config, signal)` returning a string array of model IDs the configured API key can access. Implemented by: OpenAI / Groq / Mistral (via `openai.ts` shared adapter), Mistral Voxtral (own adapter, filters Mistral's `/v1/models` catalog by ID substring `voxtral`), Anthropic, Gemini, Deepgram. Not implemented for `openai-compatible` (URL-specific, list-shape varies), AssemblyAI, Rev.ai. The settings tab caches results to `GlobalSettings.modelCache` per side and provider ID; the Refresh button in the model field triggers `listModels` and updates the cache. The model field is a single adaptive control (`populateModelField` in [src/settings/tab.ts](src/settings/tab.ts), shared by both sides via a `side: 'transcription' | 'llm'` arg): a **dropdown** when the provider supports `listModels` and the cache is non-empty, otherwise a **plain text field**. There is never both at once. The dropdown carries a trailing "Custom..." option (sentinel `CUSTOM_MODEL_OPTION`, never written to `config.model`) that toggles the same control into the text field (the `forceText` arg) so a model ID not in the catalog can still be typed; a "Back to list" button returns to the dropdown. A custom value not in the cache is shown as a selected `<id> (custom)` dropdown option. The Refresh button accompanies the dropdown (and the empty-cache text field, so the first fetch can flip it to a dropdown); on success the field re-renders in dropdown mode. `openai-compatible` / AssemblyAI / Rev.ai (no `listModels`) always show a plain text field with no Refresh. Whichever control is active, the canonical source is `profile.config.model`.
|
||||
Providers may optionally implement `listModels(config, signal)` returning a string array of model IDs the configured API key can access. Implemented by: OpenAI / Groq / Mistral (via `openai.ts` shared adapter), Mistral Voxtral (own adapter, filters Mistral's `/v1/models` catalog by ID substring `voxtral`), Anthropic, Gemini, Deepgram. Not implemented for `openai-compatible` (URL-specific, list-shape varies), AssemblyAI, Rev.ai. The settings tab caches results to `GlobalSettings.modelCache` per side and provider ID; the Refresh button in the model field triggers `listModels` and updates the cache. The model field is a single adaptive control (`populateModelField` in [src/settings/tab.ts](src/settings/tab.ts), shared by both sides via a `side: 'transcription' | 'llm'` arg): a **dropdown** when the provider supports `listModels` and the cache is non-empty, otherwise a **plain text field**. There is never both at once. The dropdown carries a trailing "Custom..." option (sentinel `CUSTOM_MODEL_OPTION`, never written to `config.model`) that toggles the same control into the text field (the `forceText` arg) so a model ID not in the catalog can still be typed; a "Back to list" button returns to the dropdown. A custom value not in the cache is shown as a selected `<id> (custom)` dropdown option. The Refresh button accompanies the dropdown (and the empty-cache text field, so the first fetch can flip it to a dropdown); on success the field re-renders in dropdown mode. `openai-compatible` / AssemblyAI / Rev.ai (no `listModels`) always show a plain text field with no Refresh. For AssemblyAI and Rev.ai the field description appends a "list of models" external link to the provider's docs (`transcriptionModelDocsUrl` + `applyModelFieldDesc` in [src/settings/tab.ts](src/settings/tab.ts)); `openai-compatible` has none (the model list is the user's own server). Whichever control is active, the canonical source is `profile.config.model`.
|
||||
|
||||
## Speaker diarization
|
||||
|
||||
|
|
|
|||
|
|
@ -555,9 +555,13 @@ export class ReWriteSettingTab extends PluginSettingTab {
|
|||
? 'empty-cache'
|
||||
: 'dropdown';
|
||||
|
||||
const docsUrl = isTranscription
|
||||
? transcriptionModelDocsUrl(profile.transcriptionProvider)
|
||||
: null;
|
||||
|
||||
const setting = new Setting(wrapper)
|
||||
.setName(isTranscription ? 'Transcription model' : 'LLM model')
|
||||
.setDesc(modelFieldDesc(hint, mode));
|
||||
.setName(isTranscription ? 'Transcription model' : 'LLM model');
|
||||
applyModelFieldDesc(setting, hint, mode, docsUrl);
|
||||
|
||||
const refresh = async (): Promise<void> => {
|
||||
if (isTranscription) {
|
||||
|
|
@ -1108,6 +1112,44 @@ function modelFieldDesc(hint: string, mode: ModelFieldMode): string {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the model-field description, appending a "list of models" external link when
|
||||
* the provider has no listModels endpoint but does publish a models doc page
|
||||
* (assemblyai, revai). Providers without a doc link get the plain string desc.
|
||||
*/
|
||||
function applyModelFieldDesc(
|
||||
setting: Setting,
|
||||
hint: string,
|
||||
mode: ModelFieldMode,
|
||||
docsUrl: string | null,
|
||||
): void {
|
||||
const text = modelFieldDesc(hint, mode);
|
||||
if (!docsUrl) {
|
||||
setting.setDesc(text);
|
||||
return;
|
||||
}
|
||||
const linkLabel = 'list of models';
|
||||
const frag = document.createDocumentFragment();
|
||||
frag.appendText(text ? `${text} See the ` : 'See the ');
|
||||
const a = frag.createEl('a', { text: linkLabel, href: docsUrl });
|
||||
a.target = '_blank';
|
||||
a.rel = 'noopener noreferrer';
|
||||
frag.appendText('.');
|
||||
setting.setDesc(frag);
|
||||
}
|
||||
|
||||
/** Models documentation page for providers that have no listModels endpoint. */
|
||||
function transcriptionModelDocsUrl(id: TranscriptionProviderID): string | null {
|
||||
switch (id) {
|
||||
case 'assemblyai':
|
||||
return 'https://www.assemblyai.com/docs/getting-started/models';
|
||||
case 'revai':
|
||||
return 'https://docs.rev.ai/api/asynchronous/transcribers/';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function transcriptionModelHint(id: TranscriptionProviderID): string {
|
||||
switch (id) {
|
||||
case 'none':
|
||||
|
|
|
|||
Loading…
Reference in a new issue