mirror of
https://github.com/voideditor/void
synced 2026-05-23 09:28:23 +00:00
feat: Replace Void branding with Orcide, integrate OllamaFreeAPI as default provider
- Replace Void cube logo with Orcide SVG logo on welcome page and watermark - Remove API key requirement from orcestAI provider (uses OllamaFreeAPI) - Set orcestAI endpoint to https://ollamafreeapi.orcest.ai/v1 (free, no auth) - Add orcestAI to "Free" tab as first option in onboarding - Default to orcestAI for smart/cheap/all provider selections - Update default models to ollamafreeapi models (llama3, mistral, deepseek, etc.) - Update provider display name and descriptions for Orcest ecosystem https://claude.ai/code/session_01CjDqzV3ECQxE1g4jFn7PBu
This commit is contained in:
parent
331449034e
commit
dddf47893e
6 changed files with 84 additions and 89 deletions
|
|
@ -55,7 +55,7 @@
|
|||
width: 100%;
|
||||
max-height: 100%;
|
||||
aspect-ratio: 1/1;
|
||||
background-image: url('./void_cube_noshadow.png'); /* // Void */
|
||||
background-image: url('./orcide_logo.svg'); /* Orcide */
|
||||
background-size: contain;
|
||||
background-position-x: center;
|
||||
background-repeat: no-repeat;
|
||||
|
|
@ -63,17 +63,17 @@
|
|||
|
||||
.void-void-icon,
|
||||
.monaco-workbench.vs-dark .part.editor > .content .editor-group-container .editor-group-watermark > .letterpress {
|
||||
background-image: url('./void_cube_noshadow.png'); /* // Void */
|
||||
background-image: url('./orcide_logo.svg'); /* Orcide */
|
||||
}
|
||||
|
||||
.void-void-icon,
|
||||
.monaco-workbench.hc-light .part.editor > .content .editor-group-container .editor-group-watermark > .letterpress {
|
||||
background-image: url('./void_cube_noshadow.png'); /* // Void */
|
||||
background-image: url('./orcide_logo.svg'); /* Orcide */
|
||||
}
|
||||
|
||||
.void-void-icon,
|
||||
.monaco-workbench.hc-black .part.editor > .content .editor-group-container .editor-group-watermark > .letterpress {
|
||||
background-image: url('./void_cube_noshadow.png'); /* // Void */
|
||||
background-image: url('./orcide_logo.svg'); /* Orcide */
|
||||
}
|
||||
|
||||
.monaco-workbench .part.editor > .content:not(.empty) .editor-group-container > .editor-group-watermark > .shortcuts,
|
||||
|
|
|
|||
19
src/vs/workbench/browser/parts/editor/media/orcide_logo.svg
Normal file
19
src/vs/workbench/browser/parts/editor/media/orcide_logo.svg
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Outer hexagonal frame -->
|
||||
<path d="M100 10 L180 50 L180 140 L100 180 L20 140 L20 50 Z" stroke="#888888" stroke-width="2" fill="none" opacity="0.25"/>
|
||||
<!-- Inner hexagonal frame -->
|
||||
<path d="M100 30 L165 60 L165 130 L100 160 L35 130 L35 60 Z" stroke="#888888" stroke-width="1.5" fill="none" opacity="0.15"/>
|
||||
<!-- Central O circle -->
|
||||
<circle cx="100" cy="95" r="36" stroke="#60a5fa" stroke-width="2.5" fill="none"/>
|
||||
<circle cx="100" cy="95" r="26" stroke="#60a5fa" stroke-width="1.2" fill="none" opacity="0.4"/>
|
||||
<!-- Connection nodes -->
|
||||
<circle cx="100" cy="59" r="2.5" fill="#60a5fa"/>
|
||||
<circle cx="136" cy="95" r="2.5" fill="#60a5fa"/>
|
||||
<circle cx="100" cy="131" r="2.5" fill="#60a5fa"/>
|
||||
<circle cx="64" cy="95" r="2.5" fill="#60a5fa"/>
|
||||
<!-- Connecting lines to hexagon -->
|
||||
<line x1="100" y1="59" x2="100" y2="30" stroke="#60a5fa" stroke-width="0.8" opacity="0.35"/>
|
||||
<line x1="136" y1="95" x2="165" y2="95" stroke="#60a5fa" stroke-width="0.8" opacity="0.35"/>
|
||||
<line x1="100" y1="131" x2="100" y2="160" stroke="#60a5fa" stroke-width="0.8" opacity="0.35"/>
|
||||
<line x1="64" y1="95" x2="35" y2="95" stroke="#60a5fa" stroke-width="0.8" opacity="0.35"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -3,15 +3,13 @@
|
|||
* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useAccessor, useIsDark, useSettingsState } from '../util/services.js';
|
||||
import { Brain, Check, ChevronRight, DollarSign, ExternalLink, Lock, X } from 'lucide-react';
|
||||
import { displayInfoOfProviderName, ProviderName, providerNames, localProviderNames, featureNames, FeatureName, isFeatureNameDisabled } from '../../../../common/voidSettingsTypes.js';
|
||||
import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js';
|
||||
import { OllamaSetupInstructions, OneClickSwitchButton, SettingsForProvider, ModelDump } from '../void-settings-tsx/Settings.js';
|
||||
import { ColorScheme } from '../../../../../../../platform/theme/common/theme.js';
|
||||
import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js';
|
||||
import { isLinux } from '../../../../../../../base/common/platform.js';
|
||||
|
||||
const OVERRIDE_VALUE = false
|
||||
|
||||
|
|
@ -39,29 +37,32 @@ export const VoidOnboarding = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const VoidIcon = () => {
|
||||
const accessor = useAccessor()
|
||||
const themeService = accessor.get('IThemeService')
|
||||
const OrcideIcon = () => {
|
||||
const isDark = useIsDark()
|
||||
|
||||
const divRef = useRef<HTMLDivElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
// void icon style
|
||||
const updateTheme = () => {
|
||||
const theme = themeService.getColorTheme().type
|
||||
const isDark = theme === ColorScheme.DARK || theme === ColorScheme.HIGH_CONTRAST_DARK
|
||||
if (divRef.current) {
|
||||
divRef.current.style.maxWidth = '220px'
|
||||
divRef.current.style.opacity = '50%'
|
||||
divRef.current.style.filter = isDark ? '' : 'invert(1)' //brightness(.5)
|
||||
}
|
||||
}
|
||||
updateTheme()
|
||||
const d = themeService.onDidColorThemeChange(updateTheme)
|
||||
return () => d.dispose()
|
||||
}, [])
|
||||
|
||||
return <div ref={divRef} className='@@void-void-icon' />
|
||||
return (
|
||||
<svg width="220" height="220" viewBox="0 0 220 220" fill="none" xmlns="http://www.w3.org/2000/svg" style={{ opacity: 0.7 }}>
|
||||
{/* Outer hexagonal frame */}
|
||||
<path d="M110 10 L195 55 L195 145 L110 190 L25 145 L25 55 Z" stroke={isDark ? '#ffffff' : '#1a1a2e'} strokeWidth="2" fill="none" opacity="0.3" />
|
||||
{/* Inner hexagonal frame */}
|
||||
<path d="M110 35 L175 68 L175 132 L110 165 L45 132 L45 68 Z" stroke={isDark ? '#ffffff' : '#1a1a2e'} strokeWidth="1.5" fill="none" opacity="0.2" />
|
||||
{/* Central "O" letterform with circuit-like details */}
|
||||
<circle cx="110" cy="100" r="38" stroke={isDark ? '#60a5fa' : '#2563eb'} strokeWidth="3" fill="none" />
|
||||
<circle cx="110" cy="100" r="28" stroke={isDark ? '#60a5fa' : '#2563eb'} strokeWidth="1.5" fill="none" opacity="0.5" />
|
||||
{/* Connection nodes */}
|
||||
<circle cx="110" cy="62" r="3" fill={isDark ? '#60a5fa' : '#2563eb'} />
|
||||
<circle cx="148" cy="100" r="3" fill={isDark ? '#60a5fa' : '#2563eb'} />
|
||||
<circle cx="110" cy="138" r="3" fill={isDark ? '#60a5fa' : '#2563eb'} />
|
||||
<circle cx="72" cy="100" r="3" fill={isDark ? '#60a5fa' : '#2563eb'} />
|
||||
{/* Connecting lines to hexagon */}
|
||||
<line x1="110" y1="62" x2="110" y2="35" stroke={isDark ? '#60a5fa' : '#2563eb'} strokeWidth="1" opacity="0.4" />
|
||||
<line x1="148" y1="100" x2="175" y2="100" stroke={isDark ? '#60a5fa' : '#2563eb'} strokeWidth="1" opacity="0.4" />
|
||||
<line x1="110" y1="138" x2="110" y2="165" stroke={isDark ? '#60a5fa' : '#2563eb'} strokeWidth="1" opacity="0.4" />
|
||||
<line x1="72" y1="100" x2="45" y2="100" stroke={isDark ? '#60a5fa' : '#2563eb'} strokeWidth="1" opacity="0.4" />
|
||||
{/* Brand text */}
|
||||
<text x="110" y="200" textAnchor="middle" fill={isDark ? '#ffffff' : '#1a1a2e'} fontSize="18" fontWeight="300" fontFamily="system-ui, -apple-system, sans-serif" letterSpacing="4" opacity="0.6">ORCIDE</text>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
const FADE_DURATION_MS = 2000
|
||||
|
|
@ -104,14 +105,14 @@ const cloudProviders: ProviderName[] = ['googleVertex', 'liteLLM', 'microsoftAzu
|
|||
|
||||
// Data structures for provider tabs
|
||||
const providerNamesOfTab: Record<TabName, ProviderName[]> = {
|
||||
Free: ['gemini', 'openRouter'],
|
||||
Free: ['orcestAI', 'gemini', 'openRouter'],
|
||||
Local: localProviderNames,
|
||||
Paid: providerNames.filter(pn => !(['gemini', 'openRouter', ...localProviderNames, ...cloudProviders] as string[]).includes(pn)) as ProviderName[],
|
||||
Paid: providerNames.filter(pn => !(['orcestAI', 'gemini', 'openRouter', ...localProviderNames, ...cloudProviders] as string[]).includes(pn)) as ProviderName[],
|
||||
'Cloud/Other': cloudProviders,
|
||||
};
|
||||
|
||||
const descriptionOfTab: Record<TabName, string> = {
|
||||
Free: `Providers with a 100% free tier. Add as many as you'd like!`,
|
||||
Free: `Free providers — Orcest AI works out of the box with no API key!`,
|
||||
Paid: `Connect directly with any provider (bring your own key).`,
|
||||
Local: `Active providers should appear automatically. Add as many as you'd like! `,
|
||||
'Cloud/Other': `Add as many as you'd like! Reach out for custom configuration requests.`,
|
||||
|
|
@ -204,6 +205,14 @@ const AddProvidersPage = ({ pageIndex, setPageIndex }: { pageIndex: number, setP
|
|||
<div key={providerName} className="w-full max-w-xl mb-10">
|
||||
<div className="text-xl mb-2">
|
||||
Add {displayInfoOfProviderName(providerName).title}
|
||||
{providerName === 'orcestAI' && (
|
||||
<span
|
||||
data-tooltip-id="void-tooltip-provider-info"
|
||||
data-tooltip-content="Orcest AI provides 650+ free models via OllamaFreeAPI. No API key required — just works out of the box."
|
||||
data-tooltip-place="right"
|
||||
className="ml-1 text-xs align-top text-blue-400"
|
||||
>*</span>
|
||||
)}
|
||||
{providerName === 'gemini' && (
|
||||
<span
|
||||
data-tooltip-id="void-tooltip-provider-info"
|
||||
|
|
@ -484,10 +493,10 @@ const VoidOnboardingContent = () => {
|
|||
|
||||
// Replace the single selectedProviderName with four separate states
|
||||
// page 2 state - each tab gets its own state
|
||||
const [selectedIntelligentProvider, setSelectedIntelligentProvider] = useState<ProviderName>('anthropic');
|
||||
const [selectedIntelligentProvider, setSelectedIntelligentProvider] = useState<ProviderName>('orcestAI');
|
||||
const [selectedPrivateProvider, setSelectedPrivateProvider] = useState<ProviderName>('ollama');
|
||||
const [selectedAffordableProvider, setSelectedAffordableProvider] = useState<ProviderName>('gemini');
|
||||
const [selectedAllProvider, setSelectedAllProvider] = useState<ProviderName>('anthropic');
|
||||
const [selectedAffordableProvider, setSelectedAffordableProvider] = useState<ProviderName>('orcestAI');
|
||||
const [selectedAllProvider, setSelectedAllProvider] = useState<ProviderName>('orcestAI');
|
||||
|
||||
// Helper function to get the current selected provider based on active tab
|
||||
const getSelectedProvider = (): ProviderName => {
|
||||
|
|
@ -510,9 +519,9 @@ const VoidOnboardingContent = () => {
|
|||
}
|
||||
|
||||
const providerNamesOfWantToUseOption: { [wantToUseOption in WantToUseOption]: ProviderName[] } = {
|
||||
smart: ['anthropic', 'openAI', 'gemini', 'openRouter'],
|
||||
smart: ['orcestAI', 'anthropic', 'openAI', 'gemini', 'openRouter'],
|
||||
private: ['ollama', 'vLLM', 'openAICompatible', 'lmStudio'],
|
||||
cheap: ['gemini', 'deepseek', 'openRouter', 'ollama', 'vLLM'],
|
||||
cheap: ['orcestAI', 'gemini', 'deepseek', 'openRouter', 'ollama', 'vLLM'],
|
||||
all: providerNames,
|
||||
}
|
||||
|
||||
|
|
@ -598,9 +607,9 @@ const VoidOnboardingContent = () => {
|
|||
<div className='flex flex-col items-center gap-8'>
|
||||
<div className="text-5xl font-light text-center">Welcome to Orcide</div>
|
||||
|
||||
{/* Slice of Void image */}
|
||||
{/* Orcide logo */}
|
||||
<div className='max-w-md w-full h-[30vh] mx-auto flex items-center justify-center'>
|
||||
{!isLinux && <VoidIcon />}
|
||||
<OrcideIcon />
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,7 @@ export const defaultProviderSettings = {
|
|||
endpoint: '', // optionally allow overriding default
|
||||
},
|
||||
orcestAI: {
|
||||
endpoint: 'https://rm.orcest.ai/v1',
|
||||
apiKey: '', // Will be populated from environment/SSO
|
||||
endpoint: 'https://ollamafreeapi.orcest.ai/v1',
|
||||
},
|
||||
|
||||
} as const
|
||||
|
|
@ -149,15 +148,13 @@ export const defaultModelsOfProvider = {
|
|||
awsBedrock: [],
|
||||
liteLLM: [],
|
||||
orcestAI: [
|
||||
'rainymodel-pro',
|
||||
'rainymodel-standard',
|
||||
'rainymodel-lite',
|
||||
'gpt-4o',
|
||||
'gpt-4o-mini',
|
||||
'claude-3.5-sonnet',
|
||||
'gemini-1.5-pro',
|
||||
'llama-3.1-70b',
|
||||
'mixtral-8x7b',
|
||||
'llama3.2:latest',
|
||||
'llama3.1:latest',
|
||||
'llama3.3:latest',
|
||||
'mistral:latest',
|
||||
'deepseek-r1:latest',
|
||||
'qwen2.5-coder:7b',
|
||||
'gemma:latest',
|
||||
],
|
||||
|
||||
|
||||
|
|
@ -1455,48 +1452,19 @@ const openRouterSettings: VoidStaticProviderInfo = {
|
|||
|
||||
|
||||
|
||||
// ---------------- ORCEST AI (RainyModel) ----------------
|
||||
// ---------------- ORCEST AI (OllamaFreeAPI) ----------------
|
||||
const orcestAIModelOptions = {
|
||||
'rainymodel-pro': {
|
||||
contextWindow: 128_000,
|
||||
reservedOutputTokenSpace: 8_192,
|
||||
cost: { input: 0, output: 0 },
|
||||
downloadable: false,
|
||||
supportsFIM: false,
|
||||
supportsSystemMessage: 'system-role',
|
||||
specialToolFormat: 'openai-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'rainymodel-standard': {
|
||||
contextWindow: 128_000,
|
||||
reservedOutputTokenSpace: 8_192,
|
||||
cost: { input: 0, output: 0 },
|
||||
downloadable: false,
|
||||
supportsFIM: false,
|
||||
supportsSystemMessage: 'system-role',
|
||||
specialToolFormat: 'openai-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
'rainymodel-lite': {
|
||||
contextWindow: 64_000,
|
||||
reservedOutputTokenSpace: 4_096,
|
||||
cost: { input: 0, output: 0 },
|
||||
downloadable: false,
|
||||
supportsFIM: false,
|
||||
supportsSystemMessage: 'system-role',
|
||||
specialToolFormat: 'openai-style',
|
||||
reasoningCapabilities: false,
|
||||
},
|
||||
} as const satisfies { [s: string]: VoidStaticModelInfo }
|
||||
|
||||
const orcestAISettings: VoidStaticProviderInfo = {
|
||||
modelOptions: orcestAIModelOptions,
|
||||
modelOptionsFallback: (modelName) => {
|
||||
// For non-RainyModel models served through the aggregator, use the extensive fallback
|
||||
return extensiveModelOptionsFallback(modelName)
|
||||
// OllamaFreeAPI serves 650+ open-source models, use extensive fallback for capability detection
|
||||
return extensiveModelOptionsFallback(modelName, { cost: { input: 0, output: 0 } })
|
||||
},
|
||||
providerReasoningIOSettings: {
|
||||
input: { includeInPayload: openAICompatIncludeInPayloadReasoning },
|
||||
output: { needsManualParse: true },
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ if (!isWeb) {
|
|||
groq: 'https://api.groq.com/openai/v1',
|
||||
xAI: 'https://api.x.ai/v1',
|
||||
mistral: 'https://api.mistral.ai/v1',
|
||||
orcestAI: 'https://rm.orcest.ai/v1',
|
||||
orcestAI: 'https://ollamafreeapi.orcest.ai/v1',
|
||||
};
|
||||
|
||||
class LLMMessageServiceWeb extends Disposable implements ILLMMessageService {
|
||||
|
|
@ -220,7 +220,7 @@ if (!isWeb) {
|
|||
sendLLMMessage = (params: ServiceSendLLMMessageParams): string | null => {
|
||||
const { onText, onFinalMessage, onError, modelSelection } = params;
|
||||
if (modelSelection === null) {
|
||||
onError({ message: `Please add a provider in Void's Settings.`, fullError: null });
|
||||
onError({ message: `Please add a provider in Orcide's Settings.`, fullError: null });
|
||||
return null;
|
||||
}
|
||||
const requestId = generateUuid();
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ export const displayInfoOfProviderName = (providerName: ProviderName): DisplayIn
|
|||
return { title: 'AWS Bedrock', }
|
||||
}
|
||||
else if (providerName === 'orcestAI') {
|
||||
return { title: 'Orcest AI (RainyModel)', }
|
||||
return { title: 'Orcest AI (Free)', }
|
||||
}
|
||||
|
||||
throw new Error(`descOfProviderName: Unknown provider name: "${providerName}"`)
|
||||
|
|
@ -131,7 +131,7 @@ export const subTextMdOfProviderName = (providerName: ProviderName): string => {
|
|||
if (providerName === 'vLLM') return 'Read more about custom [Endpoints here](https://docs.vllm.ai/en/latest/getting_started/quickstart.html#openai-compatible-server).'
|
||||
if (providerName === 'lmStudio') return 'Read more about custom [Endpoints here](https://lmstudio.ai/docs/app/api/endpoints/openai).'
|
||||
if (providerName === 'liteLLM') return 'Read more about endpoints [here](https://docs.litellm.ai/docs/providers/openai_compatible).'
|
||||
if (providerName === 'orcestAI') return 'Orcest AI integrated API. Models are available automatically through your SSO login. Powered by [RainyModel](https://rm.orcest.ai).'
|
||||
if (providerName === 'orcestAI') return 'Orcest AI free API. No API key required. Powered by [OllamaFreeAPI](https://ollamafreeapi.orcest.ai) with 650+ open-source models.'
|
||||
|
||||
throw new Error(`subTextMdOfProviderName: Unknown provider name: "${providerName}"`)
|
||||
}
|
||||
|
|
@ -160,7 +160,6 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName
|
|||
providerName === 'googleVertex' ? 'AIzaSy...' :
|
||||
providerName === 'microsoftAzure' ? 'key-...' :
|
||||
providerName === 'awsBedrock' ? 'key-...' :
|
||||
providerName === 'orcestAI' ? 'sk-orcest-key...' :
|
||||
'',
|
||||
|
||||
isPasswordField: true,
|
||||
|
|
@ -186,7 +185,7 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName
|
|||
: providerName === 'liteLLM' ? 'http://localhost:4000'
|
||||
: providerName === 'awsBedrock' ? 'http://localhost:4000/v1'
|
||||
: providerName === 'orcestAI' ? defaultProviderSettings.orcestAI.endpoint
|
||||
: '(never)',
|
||||
: '(never)'
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue