@notebook-intelligence/notebook-intelligence
Version:
AI coding assistant for JupyterLab
522 lines (521 loc) • 36.7 kB
JavaScript
// Copyright (c) Mehmet Bektas <mbektasgh@outlook.com>
import React, { useEffect, useRef, useState } from 'react';
import { ReactWidget } from '@jupyterlab/apputils';
import { VscWarning } from 'react-icons/vsc';
import * as path from 'path';
import copySvgstr from '../../style/icons/copy.svg';
import claudeSvgStr from '../../style/icons/claude.svg';
import { ClaudeModelType, ClaudeToolType, NBIAPI } from '../api';
import { CheckBoxItem } from './checkbox';
import { PillItem } from './pill';
import { mcpServerSettingsToEnabledState } from './mcp-util';
const OPENAI_COMPATIBLE_CHAT_MODEL_ID = 'openai-compatible-chat-model';
const LITELLM_COMPATIBLE_CHAT_MODEL_ID = 'litellm-compatible-chat-model';
const OPENAI_COMPATIBLE_INLINE_COMPLETION_MODEL_ID = 'openai-compatible-inline-completion-model';
const LITELLM_COMPATIBLE_INLINE_COMPLETION_MODEL_ID = 'litellm-compatible-inline-completion-model';
export class SettingsPanel extends ReactWidget {
constructor(options) {
super();
this._onSave = options.onSave;
this._onEditMCPConfigClicked = options.onEditMCPConfigClicked;
}
render() {
return (React.createElement(SettingsPanelComponent, { onSave: this._onSave, onEditMCPConfigClicked: this._onEditMCPConfigClicked }));
}
}
function SettingsPanelComponent(props) {
const [activeTab, setActiveTab] = useState('general');
const onTabSelected = (tab) => {
setActiveTab(tab);
};
return (React.createElement("div", { className: "nbi-settings-panel" },
React.createElement("div", { className: "nbi-settings-panel-tabs" },
React.createElement(SettingsPanelTabsComponent, { onTabSelected: onTabSelected, activeTab: activeTab })),
React.createElement("div", { className: "nbi-settings-panel-tab-content" },
activeTab === 'general' && (React.createElement(SettingsPanelComponentGeneral, { onSave: props.onSave, onEditMCPConfigClicked: props.onEditMCPConfigClicked })),
activeTab === 'mcp-servers' && (React.createElement(SettingsPanelComponentMCPServers, { onEditMCPConfigClicked: props.onEditMCPConfigClicked })),
activeTab === 'claude' && (React.createElement(SettingsPanelComponentClaude, { onEditMCPConfigClicked: props.onEditMCPConfigClicked })))));
}
function SettingsPanelTabsComponent(props) {
const [activeTab, setActiveTab] = useState(props.activeTab);
return (React.createElement("div", null,
React.createElement("div", { className: `nbi-settings-panel-tab ${activeTab === 'general' ? 'active' : ''}`, onClick: () => {
setActiveTab('general');
props.onTabSelected('general');
} }, "General"),
React.createElement("div", { className: `nbi-settings-panel-tab ${activeTab === 'claude' ? 'active' : ''}`, onClick: () => {
setActiveTab('claude');
props.onTabSelected('claude');
} },
React.createElement("span", { className: "claude-icon", dangerouslySetInnerHTML: { __html: claudeSvgStr } }),
"Claude"),
React.createElement("div", { className: `nbi-settings-panel-tab ${activeTab === 'mcp-servers' ? 'active' : ''}`, onClick: () => {
setActiveTab('mcp-servers');
props.onTabSelected('mcp-servers');
} }, "MCP Servers")));
}
function SettingsPanelComponentGeneral(props) {
const nbiConfig = NBIAPI.config;
const llmProviders = nbiConfig.llmProviders;
const [chatModels, setChatModels] = useState([]);
const [inlineCompletionModels, setInlineCompletionModels] = useState([]);
const handleSaveSettings = async () => {
const config = {
default_chat_mode: defaultChatMode,
chat_model: {
provider: chatModelProvider,
model: chatModel,
properties: chatModelProperties
},
inline_completion_model: {
provider: inlineCompletionModelProvider,
model: inlineCompletionModel,
properties: inlineCompletionModelProperties
}
};
if (chatModelProvider === 'github-copilot' ||
inlineCompletionModelProvider === 'github-copilot') {
config.store_github_access_token = storeGitHubAccessToken;
}
await NBIAPI.setConfig(config);
props.onSave();
};
const handleRefreshOllamaModelListClick = async () => {
await NBIAPI.updateOllamaModelList();
updateModelOptionsForProvider(chatModelProvider, 'chat');
};
const [chatModelProvider, setChatModelProvider] = useState(nbiConfig.chatModel.provider || 'none');
const [inlineCompletionModelProvider, setInlineCompletionModelProvider] = useState(nbiConfig.inlineCompletionModel.provider || 'none');
const [defaultChatMode, setDefaultChatMode] = useState(nbiConfig.defaultChatMode);
const [chatModel, setChatModel] = useState(nbiConfig.chatModel.model);
const [chatModelProperties, setChatModelProperties] = useState([]);
const [inlineCompletionModelProperties, setInlineCompletionModelProperties] = useState([]);
const [inlineCompletionModel, setInlineCompletionModel] = useState(nbiConfig.inlineCompletionModel.model);
const [storeGitHubAccessToken, setStoreGitHubAccessToken] = useState(nbiConfig.storeGitHubAccessToken);
const updateModelOptionsForProvider = (providerId, modelType) => {
if (modelType === 'chat') {
setChatModelProvider(providerId);
}
else {
setInlineCompletionModelProvider(providerId);
}
const models = modelType === 'chat'
? nbiConfig.chatModels
: nbiConfig.inlineCompletionModels;
const selectedModelId = modelType === 'chat'
? nbiConfig.chatModel.model
: nbiConfig.inlineCompletionModel.model;
const providerModels = models.filter((model) => model.provider === providerId);
if (modelType === 'chat') {
setChatModels(providerModels);
}
else {
setInlineCompletionModels(providerModels);
}
let selectedModel = providerModels.find((model) => model.id === selectedModelId);
if (!selectedModel) {
selectedModel = providerModels === null || providerModels === void 0 ? void 0 : providerModels[0];
}
if (selectedModel) {
if (modelType === 'chat') {
setChatModel(selectedModel.id);
setChatModelProperties(selectedModel.properties);
}
else {
setInlineCompletionModel(selectedModel.id);
setInlineCompletionModelProperties(selectedModel.properties);
}
}
else {
if (modelType === 'chat') {
setChatModelProperties([]);
}
else {
setInlineCompletionModelProperties([]);
}
}
};
const onModelPropertyChange = (modelType, propertyId, value) => {
const modelProperties = modelType === 'chat'
? chatModelProperties
: inlineCompletionModelProperties;
const updatedProperties = modelProperties.map((property) => {
if (property.id === propertyId) {
return { ...property, value };
}
return property;
});
if (modelType === 'chat') {
setChatModelProperties(updatedProperties);
}
else {
setInlineCompletionModelProperties(updatedProperties);
}
};
useEffect(() => {
updateModelOptionsForProvider(chatModelProvider, 'chat');
updateModelOptionsForProvider(inlineCompletionModelProvider, 'inline-completion');
}, []);
useEffect(() => {
handleSaveSettings();
}, [
defaultChatMode,
chatModelProvider,
chatModel,
chatModelProperties,
inlineCompletionModelProvider,
inlineCompletionModel,
inlineCompletionModelProperties,
storeGitHubAccessToken
]);
return (React.createElement("div", { className: "config-dialog" },
React.createElement("div", { className: "config-dialog-body" },
React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header" }, "Default chat mode"),
React.createElement("div", { className: "model-config-section-body" },
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null,
React.createElement("select", { className: "jp-mod-styled", value: defaultChatMode, onChange: event => setDefaultChatMode(event.target.value) },
React.createElement("option", { value: "ask" }, "Ask"),
React.createElement("option", { value: "agent" }, "Agent")))),
React.createElement("div", { className: "model-config-section-column" }, " ")))),
React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header" }, "Chat model"),
React.createElement("div", { className: "model-config-section-body" },
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null, "Provider"),
React.createElement("div", null,
React.createElement("select", { className: "jp-mod-styled", onChange: event => updateModelOptionsForProvider(event.target.value, 'chat') },
llmProviders.map((provider, index) => (React.createElement("option", { key: index, value: provider.id, selected: provider.id === chatModelProvider }, provider.name))),
React.createElement("option", { key: -1, value: "none", selected: chatModelProvider === 'none' ||
!llmProviders.find(provider => provider.id === chatModelProvider) }, "None")))),
!['openai-compatible', 'litellm-compatible', 'none'].includes(chatModelProvider) &&
chatModels.length > 0 && (React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null, "Model"),
![
OPENAI_COMPATIBLE_CHAT_MODEL_ID,
LITELLM_COMPATIBLE_CHAT_MODEL_ID
].includes(chatModel) &&
chatModels.length > 0 && (React.createElement("div", null,
React.createElement("select", { className: "jp-mod-styled", onChange: event => setChatModel(event.target.value) }, chatModels.map((model, index) => (React.createElement("option", { key: index, value: model.id, selected: model.id === chatModel }, model.name))))))))),
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" }, chatModelProvider === 'ollama' && chatModels.length === 0 && (React.createElement("div", { className: "ollama-warning-message" },
"No Ollama models found! Make sure",
' ',
React.createElement("a", { href: "https://ollama.com/", target: "_blank" }, "Ollama"),
' ',
"is running and models are downloaded to your computer.",
' ',
React.createElement("a", { href: "javascript:void(0)", onClick: handleRefreshOllamaModelListClick }, "Try again"),
' ',
"once ready.")))),
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" }, chatModelProperties.map((property, index) => (React.createElement("div", { className: "form-field-row", key: index },
React.createElement("div", { className: "form-field-description" },
property.name,
" ",
property.optional ? '(optional)' : ''),
React.createElement("input", { name: "chat-model-id-input", placeholder: property.description, className: "jp-mod-styled", spellCheck: false, value: property.value, onChange: event => onModelPropertyChange('chat', property.id, event.target.value) })))))))),
React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header" }, "Auto-complete model"),
React.createElement("div", { className: "model-config-section-body" },
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null, "Provider"),
React.createElement("div", null,
React.createElement("select", { className: "jp-mod-styled", onChange: event => updateModelOptionsForProvider(event.target.value, 'inline-completion') },
llmProviders.map((provider, index) => (React.createElement("option", { key: index, value: provider.id, selected: provider.id === inlineCompletionModelProvider }, provider.name))),
React.createElement("option", { key: -1, value: "none", selected: inlineCompletionModelProvider === 'none' ||
!llmProviders.find(provider => provider.id === inlineCompletionModelProvider) }, "None")))),
!['openai-compatible', 'litellm-compatible', 'none'].includes(inlineCompletionModelProvider) && (React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null, "Model"),
![
OPENAI_COMPATIBLE_INLINE_COMPLETION_MODEL_ID,
LITELLM_COMPATIBLE_INLINE_COMPLETION_MODEL_ID
].includes(inlineCompletionModel) && (React.createElement("div", null,
React.createElement("select", { className: "jp-mod-styled", onChange: event => setInlineCompletionModel(event.target.value) }, inlineCompletionModels.map((model, index) => (React.createElement("option", { key: index, value: model.id, selected: model.id === inlineCompletionModel }, model.name))))))))),
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" }, inlineCompletionModelProperties.map((property, index) => (React.createElement("div", { className: "form-field-row", key: index },
React.createElement("div", { className: "form-field-description" },
property.name,
" ",
property.optional ? '(optional)' : ''),
React.createElement("input", { name: "inline-completion-model-id-input", placeholder: property.description, className: "jp-mod-styled", spellCheck: false, value: property.value, onChange: event => onModelPropertyChange('inline-completion', property.id, event.target.value) })))))))),
(chatModelProvider === 'github-copilot' ||
inlineCompletionModelProvider === 'github-copilot') && (React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header access-token-config-header" },
"GitHub Copilot login",
' ',
React.createElement("a", { href: "https://github.com/notebook-intelligence/notebook-intelligence/blob/main/README.md#remembering-github-copilot-login", target: "_blank" },
' ',
React.createElement(VscWarning, { className: "access-token-warning", title: "Click to learn more about security implications" }))),
React.createElement("div", { className: "model-config-section-body" },
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("label", null,
React.createElement("input", { type: "checkbox", checked: storeGitHubAccessToken, onChange: event => {
setStoreGitHubAccessToken(event.target.checked);
} }),
"Remember my GitHub Copilot access token")))))),
React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header" }, "Config file path"),
React.createElement("div", { className: "model-config-section-body" },
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("span", { className: "user-code-span", onClick: () => {
navigator.clipboard.writeText(path.join(NBIAPI.config.userConfigDir, 'config.json'));
return true;
} },
path.join(NBIAPI.config.userConfigDir, 'config.json'),
' ',
React.createElement("span", { className: "copy-icon", dangerouslySetInnerHTML: { __html: copySvgstr } })))))))));
}
function SettingsPanelComponentMCPServers(props) {
const nbiConfig = NBIAPI.config;
const mcpServersRef = useRef(nbiConfig.toolConfig.mcpServers);
const mcpServerSettingsRef = useRef(nbiConfig.mcpServerSettings);
const [renderCount, setRenderCount] = useState(1);
const [mcpServerEnabledState, setMCPServerEnabledState] = useState(new Map(mcpServerSettingsToEnabledState(mcpServersRef.current, mcpServerSettingsRef.current)));
const mcpServerEnabledStateToMcpServerSettings = () => {
const mcpServerSettings = {};
for (const mcpServer of mcpServersRef.current) {
if (mcpServerEnabledState.has(mcpServer.id)) {
const disabledTools = [];
for (const tool of mcpServer.tools) {
if (!mcpServerEnabledState.get(mcpServer.id).has(tool.name)) {
disabledTools.push(tool.name);
}
}
mcpServerSettings[mcpServer.id] = {
disabled: false,
disabled_tools: disabledTools
};
}
else {
mcpServerSettings[mcpServer.id] = { disabled: true };
}
}
return mcpServerSettings;
};
const syncSettingsToServerState = () => {
NBIAPI.setConfig({
mcp_server_settings: mcpServerSettingsRef.current
});
};
const handleReloadMCPServersClick = async () => {
await NBIAPI.reloadMCPServers();
};
useEffect(() => {
syncSettingsToServerState();
}, [mcpServerSettingsRef.current]);
useEffect(() => {
mcpServerSettingsRef.current = mcpServerEnabledStateToMcpServerSettings();
setRenderCount(renderCount => renderCount + 1);
}, [mcpServerEnabledState]);
const setMCPServerEnabled = (serverId, enabled) => {
var _a;
const currentState = new Map(mcpServerEnabledState);
if (enabled) {
if (!(serverId in currentState)) {
currentState.set(serverId, new Set((_a = mcpServersRef.current
.find((server) => server.id === serverId)) === null || _a === void 0 ? void 0 : _a.tools.map((tool) => tool.name)));
}
}
else {
currentState.delete(serverId);
}
setMCPServerEnabledState(currentState);
};
const getMCPServerEnabled = (serverId) => {
return mcpServerEnabledState.has(serverId);
};
const getMCPServerToolEnabled = (serverId, toolName) => {
return (mcpServerEnabledState.has(serverId) &&
mcpServerEnabledState.get(serverId).has(toolName));
};
const setMCPServerToolEnabled = (serverId, toolName, enabled) => {
const currentState = new Map(mcpServerEnabledState);
const serverState = currentState.get(serverId);
if (enabled) {
serverState.add(toolName);
}
else {
serverState.delete(toolName);
}
setMCPServerEnabledState(currentState);
};
useEffect(() => {
NBIAPI.configChanged.connect(() => {
mcpServersRef.current = nbiConfig.toolConfig.mcpServers;
mcpServerSettingsRef.current = nbiConfig.mcpServerSettings;
setRenderCount(renderCount => renderCount + 1);
});
}, []);
return (React.createElement("div", { className: "config-dialog" },
React.createElement("div", { className: "config-dialog-body" },
React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header", style: { display: 'flex' } },
React.createElement("div", { style: { flexGrow: 1 } }, "MCP Servers"),
React.createElement("div", null,
React.createElement("button", { className: "jp-toast-button jp-mod-small jp-Button", onClick: handleReloadMCPServersClick },
React.createElement("div", { className: "jp-Dialog-buttonLabel" }, "Reload")))),
React.createElement("div", { className: "model-config-section-body" },
mcpServersRef.current.length === 0 && renderCount > 0 && (React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null, "No MCP servers found. Add MCP servers in the configuration file.")))),
mcpServersRef.current.length > 0 && renderCount > 0 && (React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" }, mcpServersRef.current.map((server) => (React.createElement("div", { key: server.id },
React.createElement("div", { style: { display: 'flex', alignItems: 'center' } },
React.createElement(CheckBoxItem, { header: true, label: server.id, checked: getMCPServerEnabled(server.id), onClick: () => {
setMCPServerEnabled(server.id, !getMCPServerEnabled(server.id));
} }),
React.createElement("div", { className: `server-status-indicator ${server.status}`, title: server.status })),
getMCPServerEnabled(server.id) && (React.createElement("div", null,
server.tools.length > 0 && (React.createElement("div", { className: "mcp-server-tools" },
React.createElement("div", { className: "mcp-server-tools-header" }, "Tools"),
React.createElement("div", null, server.tools.map((tool) => (React.createElement(PillItem, { label: tool.name, title: tool.description, checked: getMCPServerToolEnabled(server.id, tool.name), onClick: () => {
setMCPServerToolEnabled(server.id, tool.name, !getMCPServerToolEnabled(server.id, tool.name));
} })))))),
server.prompts.length > 0 && (React.createElement("div", { className: "mcp-server-prompts" },
React.createElement("div", { className: "mcp-server-prompts-header" }, "Prompts"),
React.createElement("div", null, server.prompts.map((prompt) => (React.createElement(PillItem, { label: prompt.name, title: prompt.description, checked: true })))))))))))))),
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column", style: { flexGrow: 'initial' } },
React.createElement("button", { className: "jp-Dialog-button jp-mod-accept jp-mod-styled", style: { width: 'max-content' }, onClick: props.onEditMCPConfigClicked },
React.createElement("div", { className: "jp-Dialog-buttonLabel" }, "Add / Edit")))))))));
}
function SettingsPanelComponentClaude(props) {
var _a, _b, _c, _d, _e, _f;
const nbiConfig = NBIAPI.config;
const claudeSettingsRef = useRef(nbiConfig.claudeSettings);
const [_renderCount, setRenderCount] = useState(1);
const [claudeEnabled, setClaudeEnabled] = useState(nbiConfig.isInClaudeCodeMode);
const [chatModel, setChatModel] = useState((_a = nbiConfig.claudeSettings.chat_model) !== null && _a !== void 0 ? _a : ClaudeModelType.Default);
const [inlineCompletionModel, setInlineCompletionModel] = useState((_b = nbiConfig.claudeSettings.inline_completion_model) !== null && _b !== void 0 ? _b : ClaudeModelType.Default);
const [apiKey, setApiKey] = useState((_c = nbiConfig.claudeSettings.api_key) !== null && _c !== void 0 ? _c : '');
const [baseUrl, setBaseUrl] = useState((_d = nbiConfig.claudeSettings.base_url) !== null && _d !== void 0 ? _d : '');
const [settingSources, setSettingSources] = useState((_e = nbiConfig.claudeSettings.setting_sources) !== null && _e !== void 0 ? _e : []);
const [tools, setTools] = useState((_f = nbiConfig.claudeSettings.tools) !== null && _f !== void 0 ? _f : [
ClaudeToolType.ClaudeCodeTools,
ClaudeToolType.JupyterUITools
]);
useEffect(() => {
NBIAPI.configChanged.connect(() => {
claudeSettingsRef.current = nbiConfig.claudeSettings;
setRenderCount(renderCount => renderCount + 1);
});
}, []);
const syncSettingsToServerState = () => {
NBIAPI.setConfig({
claude_settings: {
enabled: claudeEnabled,
chat_model: chatModel,
inline_completion_model: inlineCompletionModel,
api_key: apiKey,
base_url: baseUrl,
setting_sources: settingSources,
tools: tools
}
});
};
useEffect(() => {
syncSettingsToServerState();
}, [
claudeEnabled,
chatModel,
inlineCompletionModel,
apiKey,
baseUrl,
settingSources,
tools
]);
return (React.createElement("div", { className: "config-dialog claude-mode-config-dialog" },
React.createElement("div", { className: "config-dialog-body" },
React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header" }, "Enable Claude mode"),
React.createElement("div", { className: "model-config-section-body" },
React.createElement("div", { className: "model-config-section-row" },
React.createElement("span", null,
"This requires a",
' ',
React.createElement("a", { href: "https://claude.ai", target: "_blank" }, "Claude"),
' ',
"account and",
' ',
React.createElement("a", { href: "https://code.claude.com/", target: "_blank" }, "Claude Code"),
' ',
"installed in your system.")),
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null,
React.createElement(CheckBoxItem, { header: true, label: "Enable Claude mode", checked: claudeEnabled, onClick: () => {
setClaudeEnabled(!claudeEnabled);
} })))))),
React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header" }, "Models"),
React.createElement("div", { className: "model-config-section-body" },
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null, "Chat model"),
React.createElement("div", null,
React.createElement("select", { className: "jp-mod-styled", onChange: event => setChatModel(event.target.value) },
React.createElement("option", { value: ClaudeModelType.Default, selected: chatModel === ClaudeModelType.Default }, "Default (recommended)"),
React.createElement("option", { value: ClaudeModelType.ClaudeOpus45, selected: chatModel === ClaudeModelType.ClaudeOpus45 }, "Claude Opus 4.5"),
React.createElement("option", { value: ClaudeModelType.ClaudeHaiku45, selected: chatModel === ClaudeModelType.ClaudeHaiku45 }, "Claude Haiku 4.5")))),
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null, "Auto-complete model"),
React.createElement("div", null,
React.createElement("select", { className: "jp-mod-styled", onChange: event => setInlineCompletionModel(event.target.value) },
React.createElement("option", { value: ClaudeModelType.Default, selected: inlineCompletionModel === ClaudeModelType.Default }, "Default (recommended)"),
React.createElement("option", { value: ClaudeModelType.ClaudeOpus45, selected: inlineCompletionModel === ClaudeModelType.ClaudeOpus45 }, "Claude Opus 4.5"),
React.createElement("option", { value: ClaudeModelType.ClaudeHaiku45, selected: inlineCompletionModel === ClaudeModelType.ClaudeHaiku45 }, "Claude Haiku 4.5"))))))),
React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header" }, "Chat Agent setting sources"),
React.createElement("div", { className: "model-config-section-body" },
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null,
React.createElement(CheckBoxItem, { header: true, label: "User", checked: settingSources.includes('user'), onClick: () => {
setSettingSources(settingSources.includes('user')
? settingSources.filter((source) => source !== 'user')
: [...settingSources, 'user']);
} }))),
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null,
React.createElement(CheckBoxItem, { header: true, label: "Project (Jupyter root directory)", checked: settingSources.includes('project'), onClick: () => {
setSettingSources(settingSources.includes('project')
? settingSources.filter((source) => source !== 'project')
: [...settingSources, 'project']);
} })))))),
React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header" }, "Chat Agent tools"),
React.createElement("div", { className: "model-config-section-body" },
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null,
React.createElement(CheckBoxItem, { header: true, label: "Claude Code tools", checked: tools.includes(ClaudeToolType.ClaudeCodeTools), disabled: true, onClick: () => {
setTools(tools.includes(ClaudeToolType.ClaudeCodeTools)
? tools.filter((tool) => tool !== ClaudeToolType.ClaudeCodeTools)
: [...tools, ClaudeToolType.ClaudeCodeTools]);
} }))),
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", null,
React.createElement(CheckBoxItem, { header: true, label: "Jupyter UI tools", checked: tools.includes(ClaudeToolType.JupyterUITools), onClick: () => {
setTools(tools.includes(ClaudeToolType.JupyterUITools)
? tools.filter((tool) => tool !== ClaudeToolType.JupyterUITools)
: [...tools, ClaudeToolType.JupyterUITools]);
} })))))),
React.createElement("div", { className: "model-config-section" },
React.createElement("div", { className: "model-config-section-header" }, "Claude account"),
React.createElement("div", { className: "model-config-section-body" },
React.createElement("div", { className: "model-config-section-row" },
React.createElement("div", { className: "model-config-section-column" },
React.createElement("div", { className: "form-field-row" },
React.createElement("div", { className: "form-field-description" }, "API Key (optional)"),
React.createElement("input", { name: "chat-model-id-input", placeholder: "API Key", className: "jp-mod-styled", spellCheck: false, value: apiKey, onChange: event => setApiKey(event.target.value) })),
React.createElement("div", { className: "form-field-row" },
React.createElement("div", { className: "form-field-description" }, "Base URL (optional)"),
React.createElement("input", { name: "chat-model-id-input", placeholder: "https://api.anthropic.com", className: "jp-mod-styled", spellCheck: false, value: baseUrl, onChange: event => setBaseUrl(event.target.value) })))))))));
}