Skip to content
Merged
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
4 changes: 2 additions & 2 deletions examples/demo-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
"@loaders.gl/csv": "^4.3.2",
"@loaders.gl/json": "^4.3.2",
"@loaders.gl/parquet": "^4.3.2",
"@openassistant/core": "^0.5.13",
"@openassistant/ui": "^0.5.13",
"@openassistant/core": "^0.5.17",
"@openassistant/ui": "^0.5.17",
"@types/classnames": "^2.3.1",
"@types/keymirror": "^0.1.1",
"apache-arrow": ">=15.0.0",
Expand Down
87 changes: 85 additions & 2 deletions examples/demo-app/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5049,6 +5049,44 @@ __metadata:
languageName: node
linkType: hard

"@openassistant/core@npm:0.5.18, @openassistant/core@npm:^0.5.17":
version: 0.5.18
resolution: "@openassistant/core@npm:0.5.18"
dependencies:
"@ai-sdk/openai": "npm:^1.3.21"
"@ai-sdk/react": "npm:^1.2.11"
"@ai-sdk/ui-utils": "npm:^1.2.10"
"@langchain/core": "npm:^0.3.38"
ai: "npm:^4.3.19"
openai: "npm:^4.93.0"
openai-zod-functions: "npm:^0.1.2"
zod: "npm:^3.24.4"
zod-to-json-schema: "npm:^3.24.1"
peerDependencies:
"@ai-sdk/amazon-bedrock": ^1.1.6
"@ai-sdk/anthropic": ^1.1.14
"@ai-sdk/deepseek": ^0.1.8
"@ai-sdk/google": ^1.1.8
"@ai-sdk/xai": ^1.1.8
ollama-ai-provider-v2: ^0.0.6
react: ">=18.2"
peerDependenciesMeta:
"@ai-sdk/amazon-bedrock":
optional: true
"@ai-sdk/anthropic":
optional: true
"@ai-sdk/deepseek":
optional: true
"@ai-sdk/google":
optional: true
"@ai-sdk/xai":
optional: true
ollama-ai-provider-v2:
optional: true
checksum: 10c0/3e370d3f574ae3eaa0cdbf0658812f2d5b9bacb92ee8645fc18cd29c9d0b6e0dd5d66c2377eb2d0b26382d8b9fe42ed320ad43f8b2610c068fdf1a3907098aa6
languageName: node
linkType: hard

"@openassistant/duckdb@npm:^0.5.13":
version: 0.5.18
resolution: "@openassistant/duckdb@npm:0.5.18"
Expand Down Expand Up @@ -5189,6 +5227,31 @@ __metadata:
languageName: node
linkType: hard

"@openassistant/ui@npm:^0.5.17":
version: 0.5.18
resolution: "@openassistant/ui@npm:0.5.18"
dependencies:
"@ai-sdk/ui-utils": "npm:^1.2.11"
"@heroui/react": "npm:^2.7.8"
"@heroui/use-clipboard": "npm:^2.1.8"
"@iconify/react": "npm:^5.1.0"
"@openassistant/core": "npm:0.5.18"
"@openassistant/utils": "npm:0.5.18"
ai: "npm:^4.3.19"
framer-motion: "npm:^11.15.0"
html2canvas: "npm:^1.4.1"
next-themes: "npm:^0.4.4"
react-audio-voice-recorder: "npm:^2.2.0"
react-markdown: "npm:^10.0.0"
remark-gfm: "npm:^4.0.1"
tailwindcss: "npm:^3.4.17"
peerDependencies:
react: ">=18.2"
react-dom: ">=18.2"
checksum: 10c0/d0ddada031f21e24396d0f060b629495506207b6fc875e72fd389be5a2fb6a61fc7424a924eb0709453e35e830ae5b063bb420a4edab721d303a6e0b01794b7e
languageName: node
linkType: hard

"@openassistant/utils@npm:0.5.13":
version: 0.5.13
resolution: "@openassistant/utils@npm:0.5.13"
Expand Down Expand Up @@ -9735,6 +9798,26 @@ __metadata:
languageName: node
linkType: hard

"ai@npm:^4.3.19":
version: 4.3.19
resolution: "ai@npm:4.3.19"
dependencies:
"@ai-sdk/provider": "npm:1.1.3"
"@ai-sdk/provider-utils": "npm:2.2.8"
"@ai-sdk/react": "npm:1.2.12"
"@ai-sdk/ui-utils": "npm:1.2.11"
"@opentelemetry/api": "npm:1.9.0"
jsondiffpatch: "npm:0.6.0"
peerDependencies:
react: ^18 || ^19 || ^19.0.0-rc
zod: ^3.23.8
peerDependenciesMeta:
react:
optional: true
checksum: 10c0/738ac453b3e61b2f2282941fe8af946c42696fbdcffa5ac213823377bcddf475f26923cf2ca5656d5655e5c351e355e1af62dcb04a6df6139b67bac650b01af2
languageName: node
linkType: hard

"almost-equal@npm:^1.1.0":
version: 1.1.0
resolution: "almost-equal@npm:1.1.0"
Expand Down Expand Up @@ -16002,8 +16085,8 @@ __metadata:
"@loaders.gl/csv": "npm:^4.3.2"
"@loaders.gl/json": "npm:^4.3.2"
"@loaders.gl/parquet": "npm:^4.3.2"
"@openassistant/core": "npm:^0.5.13"
"@openassistant/ui": "npm:^0.5.13"
"@openassistant/core": "npm:^0.5.17"
"@openassistant/ui": "npm:^0.5.17"
"@types/classnames": "npm:^2.3.1"
"@types/keymirror": "npm:^0.1.1"
apache-arrow: "npm:>=15.0.0"
Expand Down
18 changes: 9 additions & 9 deletions src/ai-assistant/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@
"@kepler.gl/table": "3.2.0",
"@kepler.gl/types": "3.2.0",
"@kepler.gl/utils": "3.2.0",
"@openassistant/core": "^0.5.13",
"@openassistant/duckdb": "^0.5.13",
"@openassistant/echarts": "^0.5.13",
"@openassistant/geoda": "^0.5.13",
"@openassistant/osm": "^0.5.13",
"@openassistant/plots": "^0.5.13",
"@openassistant/tables": "^0.5.13",
"@openassistant/ui": "^0.5.13",
"@openassistant/utils": "^0.5.13",
"@openassistant/core": "^0.5.17",
"@openassistant/duckdb": "^0.5.17",
"@openassistant/echarts": "^0.5.17",
"@openassistant/geoda": "^0.5.17",
"@openassistant/osm": "^0.5.17",
"@openassistant/plots": "^0.5.17",
"@openassistant/tables": "^0.5.17",
"@openassistant/ui": "^0.5.17",
"@openassistant/utils": "^0.5.17",
"color-interpolate": "^1.0.5",
"global": "^4.3.0",
"ollama-ai-provider-v2": "^0.0.5",
Expand Down
67 changes: 39 additions & 28 deletions src/ai-assistant/src/components/ai-assistant-config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '@kepler.gl/components';
import {State} from '../index';
import ApiKey from '../icons/api-key';
import {PROVIDER_MODELS} from '../config/models';
import {PROVIDER_MODELS, PROVIDER_DEFAULT_BASE_URLS} from '../config/models';
import {useLocalStorage} from 'usehooks-ts';
import {GetAssistantModelByProvider} from '@openassistant/core';
import {updateAiAssistantConfig} from '../actions';
Expand Down Expand Up @@ -152,7 +152,7 @@ export function AiAssistantConfig() {
const [topP, setTopP] = useLocalStorage('ai-assistant-top-p', aiAssistantConfig.topP || 1.0);
const [baseUrl, setBaseUrl] = useLocalStorage(
'ai-assistant-base-url',
aiAssistantConfig.baseUrl || 'http://localhost:11434/api'
aiAssistantConfig.baseUrl || PROVIDER_DEFAULT_BASE_URLS[provider]
);
const [mapboxToken, setMapboxToken] = useLocalStorage(
'ai-assistant-mapbox-token',
Expand All @@ -168,6 +168,7 @@ export function AiAssistantConfig() {
if (typeof value === 'string') {
setProvider(value);
setModel(PROVIDER_MODELS[value][0]);
setBaseUrl(PROVIDER_DEFAULT_BASE_URLS[value]);
setConnectionError(false);
setErrorMessage('');
}
Expand Down Expand Up @@ -224,19 +225,32 @@ export function AiAssistantConfig() {
setTimeout(() => reject(new Error('Connection timeout after 15 seconds')), 15000);
});

const AssistantModel = GetAssistantModelByProvider({
const AssistantModel = await GetAssistantModelByProvider({
provider: provider
});

if (!AssistantModel || !AssistantModel.configure || !AssistantModel.testConnection) {
throw new Error('Failed to initialize AI model');
}

// configure model
AssistantModel.configure({
model: model,
baseURL: baseUrl || PROVIDER_DEFAULT_BASE_URLS[provider],
apiKey: apiKey,
temperature: Number(temperature),
topP: Number(topP)
});

const success = (await Promise.race([
AssistantModel?.testConnection(apiKey, model),
AssistantModel.testConnection(apiKey, model),
timeoutPromise
])) as boolean;

const errorMessage = !success
? provider === 'ollama'
? 'Connection failed: maybe invalid Ollama Base URL'
: 'Connection failed: maybe invalid API Key'
? 'Connection failed: maybe invalid Base URL'
: 'Connection failed: maybe invalid API Key or Base URL'
: '';
setConnectionError(!success);
setErrorMessage(errorMessage);
Expand All @@ -245,7 +259,7 @@ export function AiAssistantConfig() {
provider: provider,
model: model,
apiKey: apiKey,
baseUrl: baseUrl,
baseUrl: baseUrl || PROVIDER_DEFAULT_BASE_URLS[provider],
isReady: success,
temperature: temperature,
topP: topP,
Expand Down Expand Up @@ -322,11 +336,11 @@ export function AiAssistantConfig() {
/>
</OllamaModelInputWrapper>
)}
{provider !== 'ollama' ? (
{provider !== 'ollama' && (
<>
<PanelLabelWrapper>
<SectionTitle>
<FormattedMessage id="aiAssistantManager.apiKey.placeholder" />
<FormattedMessage id="aiAssistantManager.apiKey.title" />
</SectionTitle>
</PanelLabelWrapper>
<div className="api-key-input">
Expand All @@ -341,26 +355,23 @@ export function AiAssistantConfig() {
/>
</div>
</>
) : (
<>
<PanelLabelWrapper>
<SectionTitle>
<FormattedMessage id="aiAssistantManager.baseUrl.placeholder" />
</SectionTitle>
</PanelLabelWrapper>
<div className="api-key-input">
<div className="api-key-input__icon">
<ApiKey height="20px" />
</div>
<Input
type="text"
onChange={onBaseUrlChange}
placeholder={intl.formatMessage({id: 'aiAssistantManager.baseUrl.placeholder'})}
value={baseUrl}
/>
</div>
</>
)}
<PanelLabelWrapper>
<SectionTitle>
<FormattedMessage id="aiAssistantManager.baseUrl.title" />
</SectionTitle>
</PanelLabelWrapper>
<div className="api-key-input">
<div className="api-key-input__icon">
<ApiKey height="20px" />
</div>
<Input
type="text"
onChange={onBaseUrlChange}
placeholder={PROVIDER_DEFAULT_BASE_URLS[provider]}
value={baseUrl}
/>
</div>
{connectionError && (
<StyleErrorMessage className="error-message">{errorMessage}</StyleErrorMessage>
)}
Expand Down
62 changes: 37 additions & 25 deletions src/ai-assistant/src/config/models.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,45 @@
// SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project

export const PROVIDER_DEFAULT_BASE_URLS = {
"openai": "https://api.openai.com/v1",
"anthropic": "https://api.anthropic.com/v1",
"google": "https://generativelanguage.googleapis.com/v1beta",
"deepseek": "https://api.deepseek.com/v1",
"xai": "https://api.x.ai/v1",
"ollama": "http://localhost:11434/api"
};

export const PROVIDER_MODELS = {
"openai": [
"gpt-4.1",
"gpt-4o",
"gpt-4o-mini",
"gpt-4",
"gpt-3.5-turbo",
"o1",
"o1-preview",
"o1-mini"
openai: [
'gpt-4.1',
'gpt-4o',
'gpt-4o-mini',
'gpt-4',
'gpt-3.5-turbo',
'o1',
'o1-preview',
'o1-mini'
],
"google": [
"gemini-2.5-flash-preview-04-17",
"gemini-2.5-pro-preview-05-06",
"gemini-2.0-flash",
"gemini-1.5-flash",
"gemini-1.5-pro"
google: [
'gemini-2.5-flash',
'gemini-2.5-pro',
'gemini-2.0-flash',
'gemini-1.5-flash',
'gemini-1.5-pro'
],
"deepseek": ["deepseek-chat"],
"anthropic": [
"claude-3.7-sonnet",
"claude-3.5-sonnet",
"claude-3.5-haiku",
"claude-3-opus",
"claude-3-sonnet",
"claude-3-haiku"
deepseek: ['deepseek-chat'],
anthropic: [
'claude-opus-4-1',
'claude-opus-4-0',
'claude-sonnet-4-0',
'claude-3.7-sonnet',
'claude-3.5-sonnet',
'claude-3.5-haiku',
'claude-3-opus',
'claude-3-sonnet',
'claude-3-haiku'
],
"xai": ["grok-3", "grok-3-fast", "grok-3-mini", "grok-3-mini-fast"],
"ollama": ["deepseek-r1", "gemma3", "llama4", "llama3.3", "mistral", "phi4", "qwen3", "qwen2.5"]
xai: ['grok-3', 'grok-3-fast', 'grok-3-mini', 'grok-3-mini-fast'],
ollama: ['qwen3:32b', 'gpt-oss']
};
12 changes: 6 additions & 6 deletions src/ai-assistant/src/localization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export const messages = {
placeholder: 'Enter your API Key'
},
baseUrl: {
title: 'Ollama Base URL',
placeholder: 'Enter OllamaBase URL'
title: 'Base URL',
placeholder: 'Enter Base URL'
},
temperature: {
title: 'Temperature'
Expand All @@ -49,8 +49,8 @@ export const messages = {
placeholder: 'Syötä API-avain'
},
baseUrl: {
title: 'Ollama Base URL',
placeholder: 'Syötä Ollama Base URL'
title: 'Base URL',
placeholder: 'Syötä Base URL'
},
temperature: {
title: 'Lämpötila'
Expand Down Expand Up @@ -161,8 +161,8 @@ export const messages = {
placeholder: 'API キーを入力'
},
baseUrl: {
title: 'Ollama Base URL',
placeholder: 'OllamaBase URL を入力'
title: 'Base URL',
placeholder: 'Base URL を入力'
},
temperature: {
title: '温度'
Expand Down
Loading