@notebook-intelligence/notebook-intelligence 4.3.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/api.d.ts CHANGED
@@ -13,9 +13,12 @@ export interface IDeviceVerificationInfo {
13
13
  export declare enum ClaudeModelType {
14
14
  None = "none",
15
15
  Inherit = "inherit",
16
- Default = "",
17
- ClaudeOpus45 = "claude-opus-4-5",
18
- ClaudeHaiku45 = "claude-haiku-4-5"
16
+ Default = ""
17
+ }
18
+ export interface IClaudeModelInfo {
19
+ id: string;
20
+ name: string;
21
+ context_window: number;
19
22
  }
20
23
  export declare enum ClaudeToolType {
21
24
  ClaudeCodeTools = "claude-code:built-in-tools",
@@ -39,6 +42,7 @@ export declare class NBIConfig {
39
42
  getMCPServerPrompt(serverId: string, promptName: string): any;
40
43
  get mcpServerSettings(): any;
41
44
  get claudeSettings(): any;
45
+ get claudeModels(): IClaudeModelInfo[];
42
46
  get isInClaudeCodeMode(): boolean;
43
47
  capabilities: any;
44
48
  chatParticipants: IChatParticipant[];
@@ -65,6 +69,7 @@ export declare class NBIAPI {
65
69
  static fetchCapabilities(): Promise<void>;
66
70
  static setConfig(config: any): Promise<void>;
67
71
  static updateOllamaModelList(): Promise<void>;
72
+ static updateClaudeModelList(): Promise<void>;
68
73
  static getMCPConfigFile(): Promise<any>;
69
74
  static setMCPConfigFile(config: any): Promise<any>;
70
75
  static chatRequest(messageId: string, chatId: string, prompt: string, language: string, currentDirectory: string, filename: string, additionalContext: IContextItem[], chatMode: string, toolSelections: IToolSelections, responseEmitter: IChatCompletionResponseEmitter): Promise<void>;
package/lib/api.js CHANGED
@@ -18,8 +18,6 @@ export var ClaudeModelType;
18
18
  ClaudeModelType["None"] = "none";
19
19
  ClaudeModelType["Inherit"] = "inherit";
20
20
  ClaudeModelType["Default"] = "";
21
- ClaudeModelType["ClaudeOpus45"] = "claude-opus-4-5";
22
- ClaudeModelType["ClaudeHaiku45"] = "claude-haiku-4-5";
23
21
  })(ClaudeModelType || (ClaudeModelType = {}));
24
22
  export var ClaudeToolType;
25
23
  (function (ClaudeToolType) {
@@ -90,6 +88,10 @@ export class NBIConfig {
90
88
  get claudeSettings() {
91
89
  return this.capabilities.claude_settings;
92
90
  }
91
+ get claudeModels() {
92
+ var _b;
93
+ return (_b = this.capabilities.claude_models) !== null && _b !== void 0 ? _b : [];
94
+ }
93
95
  get isInClaudeCodeMode() {
94
96
  return this.claudeSettings.enabled === true;
95
97
  }
@@ -253,6 +255,22 @@ class NBIAPI {
253
255
  });
254
256
  });
255
257
  }
258
+ static async updateClaudeModelList() {
259
+ return new Promise((resolve, reject) => {
260
+ requestAPI('update-provider-models', {
261
+ method: 'POST',
262
+ body: JSON.stringify({ provider: 'claude' })
263
+ })
264
+ .then(async (data) => {
265
+ await NBIAPI.fetchCapabilities();
266
+ resolve();
267
+ })
268
+ .catch(reason => {
269
+ console.error(`Failed to update Claude model list.\n${reason}`);
270
+ reject(reason);
271
+ });
272
+ });
273
+ }
256
274
  static async getMCPConfigFile() {
257
275
  return new Promise((resolve, reject) => {
258
276
  requestAPI('mcp-config-file', { method: 'GET' })
@@ -1338,7 +1338,7 @@ function SidebarComponent(props) {
1338
1338
  msg.from === 'copilot' &&
1339
1339
  copilotRequestInProgress }))),
1340
1340
  React.createElement("div", { ref: messagesEndRef })))),
1341
- chatEnabled && (React.createElement("div", { className: `sidebar-user-input ${copilotRequestInProgress ? 'generating' : ''}` },
1341
+ chatEnabled && (React.createElement("div", { id: "sidebar-user-input", className: `sidebar-user-input ${copilotRequestInProgress ? 'generating' : ''}` },
1342
1342
  React.createElement("textarea", { ref: promptInputRef, rows: 3, onChange: onPromptChange, onKeyDown: onPromptKeyDown, placeholder: "Ask Notebook Intelligence...", spellCheck: false, value: prompt }),
1343
1343
  (activeDocumentInfo === null || activeDocumentInfo === void 0 ? void 0 : activeDocumentInfo.filename) && (React.createElement("div", { className: "user-input-context-row" },
1344
1344
  React.createElement("div", { className: `user-input-context user-input-context-active-file ${contextOn ? 'on' : 'off'}` },
@@ -419,12 +419,27 @@ function SettingsPanelComponentClaude(props) {
419
419
  ClaudeToolType.JupyterUITools
420
420
  ]);
421
421
  const [continueConversation, setContinueConversation] = useState((_g = nbiConfig.claudeSettings.continue_conversation) !== null && _g !== void 0 ? _g : false);
422
+ const [claudeModels, setClaudeModels] = useState(nbiConfig.claudeModels);
423
+ const [loadingModels, setLoadingModels] = useState(false);
422
424
  useEffect(() => {
423
425
  NBIAPI.configChanged.connect(() => {
424
426
  claudeSettingsRef.current = nbiConfig.claudeSettings;
427
+ setClaudeModels(nbiConfig.claudeModels);
425
428
  setRenderCount(renderCount => renderCount + 1);
426
429
  });
427
430
  }, []);
431
+ const refreshClaudeModels = async () => {
432
+ setLoadingModels(true);
433
+ try {
434
+ await NBIAPI.updateClaudeModelList();
435
+ const models = nbiConfig.claudeModels;
436
+ console.log('claude_models after refresh:', models);
437
+ setClaudeModels(models);
438
+ }
439
+ finally {
440
+ setLoadingModels(false);
441
+ }
442
+ };
428
443
  const syncSettingsToServerState = () => {
429
444
  NBIAPI.setConfig({
430
445
  claude_settings: {
@@ -474,7 +489,11 @@ function SettingsPanelComponentClaude(props) {
474
489
  setClaudeEnabled(!claudeEnabled);
475
490
  } })))))),
476
491
  React.createElement("div", { className: "model-config-section" },
477
- React.createElement("div", { className: "model-config-section-header" }, "Models"),
492
+ React.createElement("div", { className: "model-config-section-header", style: { display: 'flex' } },
493
+ React.createElement("div", { style: { flexGrow: 1 } }, "Models"),
494
+ React.createElement("div", null,
495
+ React.createElement("button", { className: "jp-toast-button jp-mod-small jp-Button", onClick: refreshClaudeModels, disabled: loadingModels },
496
+ React.createElement("div", { className: "jp-Dialog-buttonLabel" }, loadingModels ? 'Loading...' : 'Refresh')))),
478
497
  React.createElement("div", { className: "model-config-section-body" },
479
498
  React.createElement("div", { className: "model-config-section-row" },
480
499
  React.createElement("div", { className: "model-config-section-column" },
@@ -482,8 +501,7 @@ function SettingsPanelComponentClaude(props) {
482
501
  React.createElement("div", null,
483
502
  React.createElement("select", { className: "jp-mod-styled", onChange: event => setChatModel(event.target.value) },
484
503
  React.createElement("option", { value: ClaudeModelType.Default, selected: chatModel === ClaudeModelType.Default }, "Default (recommended)"),
485
- React.createElement("option", { value: ClaudeModelType.ClaudeOpus45, selected: chatModel === ClaudeModelType.ClaudeOpus45 }, "Claude Opus 4.5"),
486
- React.createElement("option", { value: ClaudeModelType.ClaudeHaiku45, selected: chatModel === ClaudeModelType.ClaudeHaiku45 }, "Claude Haiku 4.5")))),
504
+ claudeModels.map(model => (React.createElement("option", { key: model.id, value: model.id, selected: chatModel === model.id }, model.name)))))),
487
505
  React.createElement("div", { className: "model-config-section-column" },
488
506
  React.createElement("div", null, "Auto-complete model"),
489
507
  React.createElement("div", null,
@@ -491,8 +509,7 @@ function SettingsPanelComponentClaude(props) {
491
509
  React.createElement("option", { value: ClaudeModelType.None, selected: inlineCompletionModel === ClaudeModelType.None }, "None"),
492
510
  React.createElement("option", { value: ClaudeModelType.Inherit, selected: inlineCompletionModel === ClaudeModelType.Inherit }, "Inherit from general settings"),
493
511
  React.createElement("option", { value: ClaudeModelType.Default, selected: inlineCompletionModel === ClaudeModelType.Default }, "Default (recommended)"),
494
- React.createElement("option", { value: ClaudeModelType.ClaudeOpus45, selected: inlineCompletionModel === ClaudeModelType.ClaudeOpus45 }, "Claude Opus 4.5"),
495
- React.createElement("option", { value: ClaudeModelType.ClaudeHaiku45, selected: inlineCompletionModel === ClaudeModelType.ClaudeHaiku45 }, "Claude Haiku 4.5"))))))),
512
+ claudeModels.map(model => (React.createElement("option", { key: model.id, value: model.id, selected: inlineCompletionModel === model.id }, model.name))))))))),
496
513
  React.createElement("div", { className: "model-config-section" },
497
514
  React.createElement("div", { className: "model-config-section-header" }, "Chat Agent setting sources"),
498
515
  React.createElement("div", { className: "model-config-section-body" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notebook-intelligence/notebook-intelligence",
3
- "version": "4.3.0",
3
+ "version": "4.4.0",
4
4
  "description": "AI coding assistant for JupyterLab",
5
5
  "keywords": [
6
6
  "AI",
package/src/api.ts CHANGED
@@ -32,9 +32,13 @@ export interface IDeviceVerificationInfo {
32
32
  export enum ClaudeModelType {
33
33
  None = 'none',
34
34
  Inherit = 'inherit',
35
- Default = '',
36
- ClaudeOpus45 = 'claude-opus-4-5',
37
- ClaudeHaiku45 = 'claude-haiku-4-5'
35
+ Default = ''
36
+ }
37
+
38
+ export interface IClaudeModelInfo {
39
+ id: string;
40
+ name: string;
41
+ context_window: number;
38
42
  }
39
43
 
40
44
  export enum ClaudeToolType {
@@ -122,6 +126,10 @@ export class NBIConfig {
122
126
  return this.capabilities.claude_settings;
123
127
  }
124
128
 
129
+ get claudeModels(): IClaudeModelInfo[] {
130
+ return this.capabilities.claude_models ?? [];
131
+ }
132
+
125
133
  get isInClaudeCodeMode(): boolean {
126
134
  return this.claudeSettings.enabled === true;
127
135
  }
@@ -342,6 +350,23 @@ export class NBIAPI {
342
350
  });
343
351
  }
344
352
 
353
+ static async updateClaudeModelList(): Promise<void> {
354
+ return new Promise<void>((resolve, reject) => {
355
+ requestAPI<any>('update-provider-models', {
356
+ method: 'POST',
357
+ body: JSON.stringify({ provider: 'claude' })
358
+ })
359
+ .then(async data => {
360
+ await NBIAPI.fetchCapabilities();
361
+ resolve();
362
+ })
363
+ .catch(reason => {
364
+ console.error(`Failed to update Claude model list.\n${reason}`);
365
+ reject(reason);
366
+ });
367
+ });
368
+ }
369
+
345
370
  static async getMCPConfigFile(): Promise<any> {
346
371
  return new Promise<any>((resolve, reject) => {
347
372
  requestAPI<any>('mcp-config-file', { method: 'GET' })
@@ -2007,6 +2007,7 @@ function SidebarComponent(props: any) {
2007
2007
  ))}
2008
2008
  {chatEnabled && (
2009
2009
  <div
2010
+ id="sidebar-user-input"
2010
2011
  className={`sidebar-user-input ${copilotRequestInProgress ? 'generating' : ''}`}
2011
2012
  >
2012
2013
  <textarea
@@ -7,7 +7,12 @@ import * as path from 'path';
7
7
 
8
8
  import copySvgstr from '../../style/icons/copy.svg';
9
9
  import claudeSvgStr from '../../style/icons/claude.svg';
10
- import { ClaudeModelType, ClaudeToolType, NBIAPI } from '../api';
10
+ import {
11
+ ClaudeModelType,
12
+ ClaudeToolType,
13
+ IClaudeModelInfo,
14
+ NBIAPI
15
+ } from '../api';
11
16
  import { CheckBoxItem } from './checkbox';
12
17
  import { PillItem } from './pill';
13
18
  import { mcpServerSettingsToEnabledState } from './mcp-util';
@@ -893,14 +898,31 @@ function SettingsPanelComponentClaude(props: any) {
893
898
  const [continueConversation, setContinueConversation] = useState(
894
899
  nbiConfig.claudeSettings.continue_conversation ?? false
895
900
  );
901
+ const [claudeModels, setClaudeModels] = useState<IClaudeModelInfo[]>(
902
+ nbiConfig.claudeModels
903
+ );
904
+ const [loadingModels, setLoadingModels] = useState(false);
896
905
 
897
906
  useEffect(() => {
898
907
  NBIAPI.configChanged.connect(() => {
899
908
  claudeSettingsRef.current = nbiConfig.claudeSettings;
909
+ setClaudeModels(nbiConfig.claudeModels);
900
910
  setRenderCount(renderCount => renderCount + 1);
901
911
  });
902
912
  }, []);
903
913
 
914
+ const refreshClaudeModels = async () => {
915
+ setLoadingModels(true);
916
+ try {
917
+ await NBIAPI.updateClaudeModelList();
918
+ const models = nbiConfig.claudeModels;
919
+ console.log('claude_models after refresh:', models);
920
+ setClaudeModels(models);
921
+ } finally {
922
+ setLoadingModels(false);
923
+ }
924
+ };
925
+
904
926
  const syncSettingsToServerState = () => {
905
927
  NBIAPI.setConfig({
906
928
  claude_settings: {
@@ -966,7 +988,23 @@ function SettingsPanelComponentClaude(props: any) {
966
988
  </div>
967
989
 
968
990
  <div className="model-config-section">
969
- <div className="model-config-section-header">Models</div>
991
+ <div
992
+ className="model-config-section-header"
993
+ style={{ display: 'flex' }}
994
+ >
995
+ <div style={{ flexGrow: 1 }}>Models</div>
996
+ <div>
997
+ <button
998
+ className="jp-toast-button jp-mod-small jp-Button"
999
+ onClick={refreshClaudeModels}
1000
+ disabled={loadingModels}
1001
+ >
1002
+ <div className="jp-Dialog-buttonLabel">
1003
+ {loadingModels ? 'Loading...' : 'Refresh'}
1004
+ </div>
1005
+ </button>
1006
+ </div>
1007
+ </div>
970
1008
  <div className="model-config-section-body">
971
1009
  <div className="model-config-section-row">
972
1010
  <div className="model-config-section-column">
@@ -982,18 +1020,15 @@ function SettingsPanelComponentClaude(props: any) {
982
1020
  >
983
1021
  Default (recommended)
984
1022
  </option>
985
- <option
986
- value={ClaudeModelType.ClaudeOpus45}
987
- selected={chatModel === ClaudeModelType.ClaudeOpus45}
988
- >
989
- Claude Opus 4.5
990
- </option>
991
- <option
992
- value={ClaudeModelType.ClaudeHaiku45}
993
- selected={chatModel === ClaudeModelType.ClaudeHaiku45}
994
- >
995
- Claude Haiku 4.5
996
- </option>
1023
+ {claudeModels.map(model => (
1024
+ <option
1025
+ key={model.id}
1026
+ value={model.id}
1027
+ selected={chatModel === model.id}
1028
+ >
1029
+ {model.name}
1030
+ </option>
1031
+ ))}
997
1032
  </select>
998
1033
  </div>
999
1034
  </div>
@@ -1028,22 +1063,15 @@ function SettingsPanelComponentClaude(props: any) {
1028
1063
  >
1029
1064
  Default (recommended)
1030
1065
  </option>
1031
- <option
1032
- value={ClaudeModelType.ClaudeOpus45}
1033
- selected={
1034
- inlineCompletionModel === ClaudeModelType.ClaudeOpus45
1035
- }
1036
- >
1037
- Claude Opus 4.5
1038
- </option>
1039
- <option
1040
- value={ClaudeModelType.ClaudeHaiku45}
1041
- selected={
1042
- inlineCompletionModel === ClaudeModelType.ClaudeHaiku45
1043
- }
1044
- >
1045
- Claude Haiku 4.5
1046
- </option>
1066
+ {claudeModels.map(model => (
1067
+ <option
1068
+ key={model.id}
1069
+ value={model.id}
1070
+ selected={inlineCompletionModel === model.id}
1071
+ >
1072
+ {model.name}
1073
+ </option>
1074
+ ))}
1047
1075
  </select>
1048
1076
  </div>
1049
1077
  </div>
package/style/base.css CHANGED
@@ -29,6 +29,12 @@
29
29
  padding: 5px;
30
30
  }
31
31
 
32
+ #sidebar-user-input {
33
+ /* stylelint-disable */
34
+ anchor-name: --sidebaruserinput;
35
+ /* stylelint-enable */
36
+ }
37
+
32
38
  .sidebar-user-input {
33
39
  height: auto;
34
40
  padding: 5px;
@@ -355,8 +361,11 @@ pre:has(.code-block-header) {
355
361
  border: 1px solid var(--jp-border-color1);
356
362
  flex-direction: column;
357
363
  position: absolute;
358
- bottom: 80px;
359
- left: 4px;
364
+ /* stylelint-disable */
365
+ position-anchor: --sidebaruserinput;
366
+ position-area: top;
367
+ /* stylelint-enable */
368
+ width: calc(100% - 16px);
360
369
  gap: 2px;
361
370
  /* stylelint-disable */
362
371
  max-height: min(calc(100% - 120px), 400px);