Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,29 @@ To override a global variable for a specific agent:
2. Add the variable with the override value
3. This session-specific value takes precedence over the global setting

## Built-in LLM Provider

Some built-in AI features call an LLM directly (rather than going through a coding
agent). The provider for these features is configured under **Settings → LLM** via the
**LLM Provider** dropdown, a **Model Slug** field, and an **API Key** field. A **Test
Connection** button sends a short prompt to verify connectivity and configuration.

| Provider | Base URL | API style | Example model slug |
| ---------- | ------------------------------------- | ---------------- | --------------------------- |
| OpenRouter | `https://openrouter.ai/api/v1` | OpenAI-compatible | `anthropic/claude-3.5-sonnet` |
| Requesty | `https://router.requesty.ai/v1` | OpenAI-compatible | `openai/gpt-4o-mini` |
| Anthropic | `https://api.anthropic.com/v1` | Messages API | `claude-3-5-sonnet-20241022` |
| Ollama | `http://localhost:11434` | Ollama (local) | `llama3:latest` |

OpenRouter and Requesty both use OpenAI-compatible `provider/model` slugs and a
`Bearer` API key. For Requesty, create a key at
[app.requesty.ai/api-keys](https://app.requesty.ai/api-keys) and browse available
models at [app.requesty.ai/router/list](https://app.requesty.ai/router/list). See the
[Requesty docs](https://docs.requesty.ai) for details.

API keys are stored locally in your Maestro settings file (see [Storage
Location](#storage-location)).

## Checking for Updates

Maestro checks for updates automatically on startup (configurable in Settings → General → **Check for updates on startup**).
Expand Down
34 changes: 34 additions & 0 deletions src/renderer/components/Settings/SettingsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,39 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro
status: 'success',
message: 'Successfully connected to OpenRouter!',
});
} else if (llmProvider === 'requesty') {
if (!apiKey) {
throw new Error('API key is required for Requesty');
}

response = await fetch('https://router.requesty.ai/v1/chat/completions', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'HTTP-Referer': 'https://maestro.local',
},
body: JSON.stringify({
model: modelSlug || 'openai/gpt-4o-mini',
messages: [{ role: 'user', content: testPrompt }],
max_tokens: 50,
}),
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.error?.message || `Requesty API error: ${response.status}`);
}

const data = await response.json();
if (!data.choices?.[0]?.message?.content) {
throw new Error('Invalid response from Requesty');
}

setTestResult({
status: 'success',
message: 'Successfully connected to Requesty!',
});
} else if (llmProvider === 'anthropic') {
if (!apiKey) {
throw new Error('API key is required for Anthropic');
Expand Down Expand Up @@ -559,6 +592,7 @@ export const SettingsModal = memo(function SettingsModal(props: SettingsModalPro
style={{ borderColor: theme.colors.border }}
>
<option value="openrouter">OpenRouter</option>
<option value="requesty">Requesty</option>
<option value="anthropic">Anthropic</option>
<option value="ollama">Ollama (Local)</option>
</select>
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export type SettingsTab =
| 'prompts';
// Note: ScratchPadMode was removed as part of the Scratchpad → Auto Run migration
export type FocusArea = 'sidebar' | 'main' | 'right';
export type LLMProvider = 'openrouter' | 'anthropic' | 'ollama';
export type LLMProvider = 'openrouter' | 'requesty' | 'anthropic' | 'ollama';

// Inline wizard types for per-session/per-tab wizard state
export type WizardMode = 'new' | 'iterate' | null;
Expand Down
3 changes: 2 additions & 1 deletion src/shared/settingsMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,8 @@ export const SETTINGS_METADATA: Record<string, SettingMetadata> = {

// --- LLM / Provider ---
llmProvider: {
description: 'LLM provider for built-in AI features. E.g., openrouter, anthropic, openai.',
description:
'LLM provider for built-in AI features. E.g., openrouter, requesty, anthropic, ollama.',
type: 'string',
default: 'openrouter',
category: 'advanced',
Expand Down