notebook-intelligence 5.0.0__tar.gz → 5.0.1__tar.gz

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.
Files changed (189) hide show
  1. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/PKG-INFO +6 -6
  2. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/README.md +5 -5
  3. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/_version.py +1 -1
  4. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/github_copilot.py +353 -1
  5. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/package.json +2 -2
  6. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/schemas/@plmbr/notebook-intelligence/package.json.orig +1 -1
  7. notebook_intelligence-5.0.1/notebook_intelligence/labextension/static/703.b2a16c3edc281d79d13a.js +1 -0
  8. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/editor.worker.js +2 -2
  9. notebook_intelligence-5.0.1/notebook_intelligence/labextension/static/remoteEntry.e77a2554241f4d36341c.js +1 -0
  10. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/llm_providers/github_copilot_llm_provider.py +2 -2
  11. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/package.json +1 -1
  12. notebook_intelligence-5.0.1/tests/test_github_copilot_llm_provider.py +651 -0
  13. notebook_intelligence-5.0.1/tests/ts/markdown-renderer.test.tsx +247 -0
  14. notebook_intelligence-5.0.1/tests/ts/safe-anchor.test.tsx +96 -0
  15. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/utils.test.ts +30 -0
  16. notebook_intelligence-5.0.0/notebook_intelligence/labextension/static/784.e320c845743830167ef6.js +0 -1
  17. notebook_intelligence-5.0.0/notebook_intelligence/labextension/static/remoteEntry.4708b983f8e8c8f2abe1.js +0 -1
  18. notebook_intelligence-5.0.0/tests/test_github_copilot_llm_provider.py +0 -166
  19. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/.copier-answers.yml +0 -0
  20. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/.gitignore +0 -0
  21. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/.prettierignore +0 -0
  22. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/.yarnrc.yml +0 -0
  23. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/CHANGELOG.md +0 -0
  24. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/CONTRIBUTING.md +0 -0
  25. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/LICENSE +0 -0
  26. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/PRIVACY.md +0 -0
  27. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/RELEASE.md +0 -0
  28. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/SECURITY.md +0 -0
  29. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/docs/admin-guide.md +0 -0
  30. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/docs/admin-tour-config.md +0 -0
  31. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/docs/rulesets.md +0 -0
  32. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/docs/skills.md +0 -0
  33. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/docs/troubleshooting.md +0 -0
  34. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/install.json +0 -0
  35. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/jest.config.js +0 -0
  36. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/jupyter-config/server-config/notebook_intelligence.json +0 -0
  37. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/__init__.py +0 -0
  38. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/_claude_cli.py +0 -0
  39. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/ai_service_manager.py +0 -0
  40. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/api.py +0 -0
  41. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/base_chat_participant.py +0 -0
  42. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/built_in_toolsets.py +0 -0
  43. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/cell_output.py +0 -0
  44. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/claude.py +0 -0
  45. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/claude_mcp_manager.py +0 -0
  46. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/claude_sessions.py +0 -0
  47. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/config.py +0 -0
  48. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/context_factory.py +0 -0
  49. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/extension.py +0 -0
  50. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/feature_flags.py +0 -0
  51. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/github_copilot_chat_participant.py +0 -0
  52. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/schemas/@plmbr/notebook-intelligence/plugin.json +0 -0
  53. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/196.da0c2020639344d5c419.js +0 -0
  54. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/1b55f12eca93ba6743e7.ttf +0 -0
  55. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/327.47473c656f6c27efa1dc.js +0 -0
  56. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/327.47473c656f6c27efa1dc.js.LICENSE.txt +0 -0
  57. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/537.02c6edab4e3a352bb107.js +0 -0
  58. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/631.f00d05d8305a78ec8301.js +0 -0
  59. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/671.1b1a53f5f75bff82950b.js +0 -0
  60. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/694.2ebfa9714301d9260bf0.js +0 -0
  61. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/728.cae98e1655349e508971.js +0 -0
  62. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/745.f63673e66e02301096f4.js +0 -0
  63. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/745.f63673e66e02301096f4.js.LICENSE.txt +0 -0
  64. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/977.b917f705175326af0e5d.js +0 -0
  65. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/be02dcbf2787b0b29ec8.module.wasm +0 -0
  66. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/e589c9ba04e3e5a90081.module.wasm +0 -0
  67. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/editor.worker.js.LICENSE.txt +0 -0
  68. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/style.js +0 -0
  69. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/labextension/static/third-party-licenses.json +0 -0
  70. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/llm_providers/litellm_compatible_llm_provider.py +0 -0
  71. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/llm_providers/ollama_llm_provider.py +0 -0
  72. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/llm_providers/openai_compatible_llm_provider.py +0 -0
  73. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/mcp_client.py +0 -0
  74. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/mcp_config_validation.py +0 -0
  75. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/mcp_manager.py +0 -0
  76. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/plugin_manager.py +0 -0
  77. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/prompts.py +0 -0
  78. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/rule_injector.py +0 -0
  79. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/rule_manager.py +0 -0
  80. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/ruleset.py +0 -0
  81. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/skill_github_import.py +0 -0
  82. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/skill_manager.py +0 -0
  83. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/skill_manifest.py +0 -0
  84. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/skill_reconciler.py +0 -0
  85. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/skillset.py +0 -0
  86. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/tour_config.py +0 -0
  87. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/notebook_intelligence/util.py +0 -0
  88. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/pyproject.toml +0 -0
  89. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/schema/plugin.json +0 -0
  90. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/setup.py +0 -0
  91. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/conftest.py +0 -0
  92. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/fixtures/rules/01-test-global.md +0 -0
  93. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/fixtures/rules/02-test-security.md +0 -0
  94. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/fixtures/rules/03-invalid-rule.md +0 -0
  95. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/fixtures/rules/modes/agent/01-test-production.md +0 -0
  96. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/fixtures/rules/modes/ask/01-test-exploration.md +0 -0
  97. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/fixtures/rules/modes/inline-chat/01-test-quick.md +0 -0
  98. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_ai_service_manager_integration.py +0 -0
  99. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_api_hygiene.py +0 -0
  100. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_base_chat_participant_integration.py +0 -0
  101. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_builtin_toolset_cwd_sandbox.py +0 -0
  102. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_cell_output.py +0 -0
  103. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_cell_output_features_response.py +0 -0
  104. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_claude_client.py +0 -0
  105. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_claude_mcp_manager.py +0 -0
  106. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_claude_models.py +0 -0
  107. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_claude_sessions.py +0 -0
  108. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_claude_sessions_handler.py +0 -0
  109. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_claude_system_prompt.py +0 -0
  110. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_claude_tool_humanizer.py +0 -0
  111. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_claude_tool_path_sandbox.py +0 -0
  112. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_coding_agent_launchers.py +0 -0
  113. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_config_atomic_save.py +0 -0
  114. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_config_integration.py +0 -0
  115. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_context_factory.py +0 -0
  116. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_end_to_end_rule_integration.py +0 -0
  117. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_feature_flags.py +0 -0
  118. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_feedback.py +0 -0
  119. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_file_upload.py +0 -0
  120. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_github_copilot_user_data_mode.py +0 -0
  121. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_image_context.py +0 -0
  122. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_mcp_client_shim.py +0 -0
  123. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_mcp_config_validation.py +0 -0
  124. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_mcp_manager.py +0 -0
  125. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_models.py +0 -0
  126. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_openai_compatible_llm_provider.py +0 -0
  127. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_plugin_manager.py +0 -0
  128. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_policy_gate.py +0 -0
  129. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_redact_process_secrets.py +0 -0
  130. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_response_emitter.py +0 -0
  131. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_rule_auto_reload.py +0 -0
  132. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_rule_injector.py +0 -0
  133. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_rule_manager.py +0 -0
  134. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_safe_anchor_uri.py +0 -0
  135. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_skill_fetch_redirects.py +0 -0
  136. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_skill_github_import.py +0 -0
  137. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_skill_manager.py +0 -0
  138. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_skill_manifest.py +0 -0
  139. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_skill_reconciler.py +0 -0
  140. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_skills_handlers.py +0 -0
  141. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_tour_config.py +0 -0
  142. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_websocket_handler_integration.py +0 -0
  143. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_ws_callback_handler_leak.py +0 -0
  144. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/test_ws_handler_auth.py +0 -0
  145. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/__mocks__/jupyterlab-apputils.ts +0 -0
  146. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/__mocks__/jupyterlab-filebrowser.ts +0 -0
  147. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/__mocks__/svg.ts +0 -0
  148. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/__mocks__/tiktoken.ts +0 -0
  149. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/ask-user-question.test.tsx +0 -0
  150. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/cell-output-bundle.test.ts +0 -0
  151. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/cell-output-features.test.ts +0 -0
  152. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/cell-output-toolbar.test.ts +0 -0
  153. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/chat-progress-feedback.test.ts +0 -0
  154. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/checkbox.test.tsx +0 -0
  155. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/choose-workspace-directory.test.ts +0 -0
  156. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/claude-mcp-paste.test.ts +0 -0
  157. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/coding-agent-launchers.test.ts +0 -0
  158. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/launcher-picker.test.tsx +0 -0
  159. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/mcp-util.test.ts +0 -0
  160. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/notebook-generation.test.ts +0 -0
  161. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/open-file-refresh-watcher.test.ts +0 -0
  162. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/plugins-panel.test.tsx +0 -0
  163. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/setup.ts +0 -0
  164. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/skill-wire-format.test.ts +0 -0
  165. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/task-target-notebook.test.ts +0 -0
  166. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/terminal-drag.test.ts +0 -0
  167. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/tour-config.test.ts +0 -0
  168. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/tour-events.test.ts +0 -0
  169. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/tour-overlay.test.tsx +0 -0
  170. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/tour-state.test.ts +0 -0
  171. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/tsconfig.json +0 -0
  172. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tests/ts/workspace-skips.test.ts +0 -0
  173. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/tsconfig.json +0 -0
  174. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/.eslintrc.js +0 -0
  175. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/README.md +0 -0
  176. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/jupyter_server_test_config.py +0 -0
  177. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/package.json +0 -0
  178. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/playwright.config.ts +0 -0
  179. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/tests/cell-output.spec.ts +0 -0
  180. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/tests/chat-sidebar.spec.ts +0 -0
  181. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/tests/claude-mcp-patch.spec.ts +0 -0
  182. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/tests/extension.spec.ts +0 -0
  183. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/tests/helpers.ts +0 -0
  184. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/tests/launcher.spec.ts +0 -0
  185. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/tests/notebook-toolbar.spec.ts +0 -0
  186. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/tsconfig.json +0 -0
  187. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/ui-tests/yarn.lock +0 -0
  188. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/webpack.config.js +0 -0
  189. {notebook_intelligence-5.0.0 → notebook_intelligence-5.0.1}/yarn.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: notebook_intelligence
3
- Version: 5.0.0
3
+ Version: 5.0.1
4
4
  Summary: AI coding assistant for JupyterLab
5
5
  Project-URL: Homepage, https://github.com/plmbr/notebook-intelligence
6
6
  Project-URL: Bug Tracker, https://github.com/plmbr/notebook-intelligence/issues
@@ -876,7 +876,7 @@ NBI reloads open document tabs when their files change on disk, so edits an AI a
876
876
 
877
877
  ## Configuration
878
878
 
879
- Configure your provider, model, and API key from NBI Settings — the gear icon in the chat panel, the `/settings` chat command, or the JupyterLab command palette. For background, see the [provider blog post](https://notebook-intelligence.github.io/notebook-intelligence/blog/2025/03/05/support-for-any-llm-provider.html).
879
+ Configure your provider, model, and API key from NBI Settings — the gear icon in the chat panel, the `/settings` chat command, or the JupyterLab command palette. For background, see the [provider blog post](https://plmbr.dev/blog/archive/support-for-any-llm-provider/).
880
880
 
881
881
  <img src="media/provider-list.png" alt="Settings dialog" width=500 />
882
882
 
@@ -1115,10 +1115,10 @@ The feedback fires an in-process `telemetry` event. Nothing leaves the process b
1115
1115
 
1116
1116
  ## Further reading
1117
1117
 
1118
- - [Introducing Notebook Intelligence!](https://notebook-intelligence.github.io/notebook-intelligence/blog/2025/01/08/introducing-notebook-intelligence.html)
1119
- - [Building AI Extensions for JupyterLab](https://notebook-intelligence.github.io/notebook-intelligence/blog/2025/02/05/building-ai-extensions-for-jupyterlab.html)
1120
- - [Building AI Agents for JupyterLab](https://notebook-intelligence.github.io/notebook-intelligence/blog/2025/02/09/building-ai-agents-for-jupyterlab.html)
1121
- - [Notebook Intelligence now supports any LLM Provider and AI Model!](https://notebook-intelligence.github.io/notebook-intelligence/blog/2025/03/05/support-for-any-llm-provider.html)
1118
+ - [Introducing Notebook Intelligence!](https://plmbr.dev/blog/archive/introducing-notebook-intelligence/)
1119
+ - [Building AI Extensions for JupyterLab](https://plmbr.dev/blog/archive/building-ai-extensions-for-jupyterlab/)
1120
+ - [Building AI Agents for JupyterLab](https://plmbr.dev/blog/archive/building-ai-agents-for-jupyterlab/)
1121
+ - [Notebook Intelligence now supports any LLM Provider and AI Model!](https://plmbr.dev/blog/archive/support-for-any-llm-provider/)
1122
1122
 
1123
1123
  ## Roadmap
1124
1124
 
@@ -159,7 +159,7 @@ NBI reloads open document tabs when their files change on disk, so edits an AI a
159
159
 
160
160
  ## Configuration
161
161
 
162
- Configure your provider, model, and API key from NBI Settings — the gear icon in the chat panel, the `/settings` chat command, or the JupyterLab command palette. For background, see the [provider blog post](https://notebook-intelligence.github.io/notebook-intelligence/blog/2025/03/05/support-for-any-llm-provider.html).
162
+ Configure your provider, model, and API key from NBI Settings — the gear icon in the chat panel, the `/settings` chat command, or the JupyterLab command palette. For background, see the [provider blog post](https://plmbr.dev/blog/archive/support-for-any-llm-provider/).
163
163
 
164
164
  <img src="media/provider-list.png" alt="Settings dialog" width=500 />
165
165
 
@@ -398,10 +398,10 @@ The feedback fires an in-process `telemetry` event. Nothing leaves the process b
398
398
 
399
399
  ## Further reading
400
400
 
401
- - [Introducing Notebook Intelligence!](https://notebook-intelligence.github.io/notebook-intelligence/blog/2025/01/08/introducing-notebook-intelligence.html)
402
- - [Building AI Extensions for JupyterLab](https://notebook-intelligence.github.io/notebook-intelligence/blog/2025/02/05/building-ai-extensions-for-jupyterlab.html)
403
- - [Building AI Agents for JupyterLab](https://notebook-intelligence.github.io/notebook-intelligence/blog/2025/02/09/building-ai-agents-for-jupyterlab.html)
404
- - [Notebook Intelligence now supports any LLM Provider and AI Model!](https://notebook-intelligence.github.io/notebook-intelligence/blog/2025/03/05/support-for-any-llm-provider.html)
401
+ - [Introducing Notebook Intelligence!](https://plmbr.dev/blog/archive/introducing-notebook-intelligence/)
402
+ - [Building AI Extensions for JupyterLab](https://plmbr.dev/blog/archive/building-ai-extensions-for-jupyterlab/)
403
+ - [Building AI Agents for JupyterLab](https://plmbr.dev/blog/archive/building-ai-agents-for-jupyterlab/)
404
+ - [Notebook Intelligence now supports any LLM Provider and AI Model!](https://plmbr.dev/blog/archive/support-for-any-llm-provider/)
405
405
 
406
406
  ## Roadmap
407
407
 
@@ -1,4 +1,4 @@
1
1
  # This file is auto-generated by Hatchling. As such, do not:
2
2
  # - modify
3
3
  # - track in version control e.g. be sure to add to .gitignore
4
- __version__ = VERSION = '5.0.0'
4
+ __version__ = VERSION = '5.0.1'
@@ -59,6 +59,16 @@ github_auth = {
59
59
  # stay current.
60
60
  copilot_models_cache: list[dict] = []
61
61
 
62
+ # Per-model HTTP path under API_ENDPOINT. Codex-class models advertise only
63
+ # `/responses` (the OpenAI Responses API mirror) and 400 on `/chat/completions`;
64
+ # everything else stays on `/chat/completions`. Populated by
65
+ # `fetch_copilot_models` from each model entry's `supported_endpoints` field.
66
+ # Lookup falls back to `/chat/completions` for unknown ids so the hardcoded
67
+ # fallback model list keeps working before the first live fetch.
68
+ _COPILOT_CHAT_ENDPOINT = "/chat/completions"
69
+ _COPILOT_RESPONSES_ENDPOINT = "/responses"
70
+ copilot_model_endpoints: dict[str, str] = {}
71
+
62
72
  # Conservative floor when the Copilot API omits limits for a model. Picked
63
73
  # to match the smallest token cap any Copilot-served model has historically
64
74
  # carried, so the token-budget meter (extension.py: `remaining_token_budget`)
@@ -419,6 +429,7 @@ def fetch_copilot_models() -> list[dict]:
419
429
 
420
430
  raw_models = payload.get("data", []) if isinstance(payload, dict) else []
421
431
  normalized: list[dict] = []
432
+ endpoints: dict[str, str] = {}
422
433
  seen_ids: set[str] = set()
423
434
  for entry in raw_models:
424
435
  if not isinstance(entry, dict):
@@ -426,7 +437,15 @@ def fetch_copilot_models() -> list[dict]:
426
437
  if not entry.get("model_picker_enabled"):
427
438
  continue
428
439
  caps = entry.get("capabilities", {}) or {}
429
- if caps.get("type") != "chat":
440
+ supported = entry.get("supported_endpoints") or []
441
+ if not isinstance(supported, list):
442
+ supported = []
443
+ # Codex-class models advertise only `/responses` and may report a
444
+ # non-chat capability `type`. Accept them when the endpoint list says
445
+ # they're chattable, so they reach the dispatcher in `chat(...)`.
446
+ is_chat_type = caps.get("type") == "chat"
447
+ has_responses = _COPILOT_RESPONSES_ENDPOINT in supported
448
+ if not (is_chat_type or has_responses):
430
449
  continue
431
450
  model_id = entry.get("id")
432
451
  if not isinstance(model_id, str) or not model_id or model_id in seen_ids:
@@ -445,6 +464,15 @@ def fetch_copilot_models() -> list[dict]:
445
464
  context_window = _COPILOT_DEFAULT_CONTEXT_WINDOW
446
465
  if context_window <= 0:
447
466
  context_window = _COPILOT_DEFAULT_CONTEXT_WINDOW
467
+ # Prefer `/chat/completions` whenever the model advertises it; only
468
+ # route through `/responses` when that's the model's sole supported
469
+ # path. Mirrors codecompanion.nvim's Copilot adapter: dual-listing
470
+ # exists for forward compatibility, but established chat flows are
471
+ # still cheaper on the older endpoint.
472
+ if has_responses and _COPILOT_CHAT_ENDPOINT not in supported:
473
+ endpoints[model_id] = _COPILOT_RESPONSES_ENDPOINT
474
+ else:
475
+ endpoints[model_id] = _COPILOT_CHAT_ENDPOINT
448
476
  normalized.append({
449
477
  "id": model_id,
450
478
  "name": str(name),
@@ -460,12 +488,33 @@ def fetch_copilot_models() -> list[dict]:
460
488
 
461
489
  copilot_models_cache.clear()
462
490
  copilot_models_cache.extend(normalized)
491
+ copilot_model_endpoints.clear()
492
+ copilot_model_endpoints.update(endpoints)
463
493
  return list(copilot_models_cache)
464
494
 
465
495
 
466
496
  def invalidate_copilot_models_cache() -> None:
467
497
  """Clear the memoized Copilot chat-model list. Mostly used by tests."""
468
498
  copilot_models_cache.clear()
499
+ copilot_model_endpoints.clear()
500
+
501
+
502
+ def _model_chat_endpoint(model_id: str) -> str:
503
+ """Pick the HTTP path for a Copilot chat request.
504
+
505
+ Trusts the live catalogue first: `fetch_copilot_models` populates
506
+ `copilot_model_endpoints` after login from each model's
507
+ `supported_endpoints` field. For ids the cache doesn't know (the
508
+ hardcoded fallback list, an offline session, a /models fetch that
509
+ failed), falls back to a substring heuristic: any id containing `codex`
510
+ routes to `/responses`, since the entire Codex family only accepts that
511
+ endpoint. Everything else stays on `/chat/completions`.
512
+ """
513
+ if model_id in copilot_model_endpoints:
514
+ return copilot_model_endpoints[model_id]
515
+ if "codex" in model_id.lower():
516
+ return _COPILOT_RESPONSES_ENDPOINT
517
+ return _COPILOT_CHAT_ENDPOINT
469
518
 
470
519
  def get_token_thread_func():
471
520
  global github_auth, get_token_thread, last_token_fetch_time
@@ -627,6 +676,309 @@ def _aggregate_streaming_response(client: sseclient.SSEClient) -> dict:
627
676
 
628
677
  return _format_llm_response()
629
678
 
679
+ def _messages_to_responses_input(messages: list[dict]) -> tuple[list[dict], str | None]:
680
+ """Translate an OpenAI chat-completions `messages` array into the shape
681
+ Copilot's `/responses` endpoint accepts.
682
+
683
+ System messages collapse into the top-level ``instructions`` field
684
+ (newline-joined when more than one is present). Assistant tool calls
685
+ expand to `function_call` items, tool results to `function_call_output`
686
+ items, and the remaining role/content pairs pass through with their
687
+ original role. Matches what codecompanion.nvim sends and what OpenAI's
688
+ own Responses migration guide documents.
689
+ """
690
+ instructions_parts: list[str] = []
691
+ input_items: list[dict] = []
692
+ for msg in messages:
693
+ if not isinstance(msg, dict):
694
+ continue
695
+ role = msg.get("role")
696
+ content = msg.get("content")
697
+ if role == "system":
698
+ if isinstance(content, str) and content:
699
+ instructions_parts.append(content)
700
+ continue
701
+ if role == "tool":
702
+ output = content if isinstance(content, str) else json.dumps(content)
703
+ input_items.append({
704
+ "type": "function_call_output",
705
+ "call_id": msg.get("tool_call_id"),
706
+ "output": output,
707
+ })
708
+ continue
709
+ if role == "assistant" and msg.get("tool_calls"):
710
+ for tc in msg["tool_calls"]:
711
+ fn = (tc.get("function") or {}) if isinstance(tc, dict) else {}
712
+ call_id = tc.get("id") if isinstance(tc, dict) else None
713
+ input_items.append({
714
+ "type": "function_call",
715
+ "call_id": call_id,
716
+ "name": fn.get("name"),
717
+ "arguments": fn.get("arguments", ""),
718
+ })
719
+ if isinstance(content, str) and content:
720
+ input_items.append({"role": role, "content": content})
721
+ continue
722
+ input_items.append({"role": role, "content": content if content is not None else ""})
723
+ instructions = "\n".join(instructions_parts) if instructions_parts else None
724
+ return input_items, instructions
725
+
726
+
727
+ def _chat_tools_to_responses_tools(tools: list[dict] | None) -> list[dict] | None:
728
+ """Flatten chat-completions tool schemas to Responses-API shape.
729
+
730
+ Chat completions nests under ``{type: "function", function: {name, ...}}``;
731
+ Responses expects the function fields at the top level. The transform is
732
+ purely structural so a caller can keep emitting one schema upstream.
733
+ """
734
+ if not tools:
735
+ return None
736
+ out: list[dict] = []
737
+ for tool in tools:
738
+ if not isinstance(tool, dict) or tool.get("type") != "function":
739
+ out.append(tool)
740
+ continue
741
+ fn = tool.get("function") or {}
742
+ out.append({
743
+ "type": "function",
744
+ "name": fn.get("name"),
745
+ "description": fn.get("description"),
746
+ "parameters": fn.get("parameters"),
747
+ })
748
+ return out
749
+
750
+
751
+ # Responses-API SSE event types that mean the server gave up mid-stream.
752
+ # Treated as hard failures so callers see an exception instead of a silent
753
+ # empty assistant turn; `response.incomplete` (max-tokens cap, etc.) is
754
+ # included because Codex emits it in place of `response.completed` and the
755
+ # partial content alone isn't enough signal for the chat sidebar.
756
+ _RESPONSES_TERMINAL_ERROR_EVENTS = frozenset({
757
+ "response.failed",
758
+ "response.error",
759
+ "response.incomplete",
760
+ "error",
761
+ })
762
+
763
+
764
+ def _responses_error_message(chunk: dict) -> str:
765
+ """Extract the most descriptive error string a `response.failed` /
766
+ `response.error` event carries. Falls back to the raw type when the
767
+ server omits a message field."""
768
+ if not isinstance(chunk, dict):
769
+ return "GitHub Copilot returned an unparseable error event."
770
+ response_obj = chunk.get("response") or {}
771
+ for source in (chunk, response_obj):
772
+ if not isinstance(source, dict):
773
+ continue
774
+ err = source.get("error") if isinstance(source.get("error"), dict) else None
775
+ if err:
776
+ msg = err.get("message") or err.get("code")
777
+ if isinstance(msg, str) and msg:
778
+ return msg
779
+ msg = source.get("message")
780
+ if isinstance(msg, str) and msg:
781
+ return msg
782
+ return f"GitHub Copilot Responses stream emitted {chunk.get('type', 'unknown')!r} without a message."
783
+
784
+
785
+ def _function_call_item_to_chat_tool(item: dict, *, fallback_arguments: str = "") -> dict | None:
786
+ """Turn a Responses-API `function_call` output item into the
787
+ chat-completions tool_call shape the rest of the codebase expects.
788
+ Returns None if the item should be skipped (wrong type, in-progress
789
+ status).
790
+ """
791
+ if not isinstance(item, dict) or item.get("type") != "function_call":
792
+ return None
793
+ if item.get("status") not in (None, "completed"):
794
+ return None
795
+ return {
796
+ "id": item.get("call_id") or item.get("id"),
797
+ "type": "function",
798
+ "function": {
799
+ "name": item.get("name") or "",
800
+ "arguments": item.get("arguments") or fallback_arguments or "{}",
801
+ },
802
+ }
803
+
804
+
805
+ def _aggregate_responses_streaming(client: sseclient.SSEClient) -> dict:
806
+ """Drain a `/responses` SSE stream and return the same chat-completions
807
+ shape `_aggregate_streaming_response` emits, so callers see one wire
808
+ format regardless of which endpoint served the model.
809
+ """
810
+ final_content = ""
811
+ final_tool_calls: list[dict] = []
812
+ # Some Codex variants stream function-call arguments incrementally as
813
+ # `response.function_call_arguments.delta` events and only ship a
814
+ # zero-byte `arguments` field in the terminal `response.completed`
815
+ # item. Accumulate by `item_id` so we can stitch them back together
816
+ # if the terminal payload comes through empty.
817
+ arg_buffers: dict[str, str] = {}
818
+ for event in client.events():
819
+ if not event.data:
820
+ continue
821
+ try:
822
+ chunk = json.loads(event.data)
823
+ except (ValueError, json.JSONDecodeError):
824
+ continue
825
+ event_type = chunk.get("type")
826
+ if event_type in _RESPONSES_TERMINAL_ERROR_EVENTS:
827
+ raise Exception(_responses_error_message(chunk))
828
+ if event_type == "response.output_text.delta":
829
+ delta = chunk.get("delta")
830
+ if isinstance(delta, str):
831
+ final_content += delta
832
+ elif event_type == "response.function_call_arguments.delta":
833
+ item_id = chunk.get("item_id")
834
+ delta = chunk.get("delta")
835
+ if isinstance(item_id, str) and isinstance(delta, str):
836
+ arg_buffers[item_id] = arg_buffers.get(item_id, "") + delta
837
+ elif event_type == "response.completed":
838
+ resp_obj = chunk.get("response") or {}
839
+ for item in resp_obj.get("output") or []:
840
+ if not isinstance(item, dict):
841
+ continue
842
+ buffered = arg_buffers.get(item.get("id") or "")
843
+ tc = _function_call_item_to_chat_tool(item, fallback_arguments=buffered or "")
844
+ if tc is not None:
845
+ final_tool_calls.append(tc)
846
+ break
847
+ return {
848
+ "choices": [{
849
+ "message": {
850
+ "role": "assistant",
851
+ "content": final_content,
852
+ "tool_calls": final_tool_calls if final_tool_calls else None,
853
+ }
854
+ }]
855
+ }
856
+
857
+
858
+ def responses(model_id, messages, tools = None, response: ChatResponse = None, cancel_token: CancelToken = None, options: dict = {}) -> Any:
859
+ """Send a chat turn through Copilot's `/responses` endpoint.
860
+
861
+ Required for Codex-class models, which 400 on `/chat/completions`. The
862
+ aggregate and streaming return shapes match `completions()` so callers
863
+ don't need an endpoint branch above this layer.
864
+ """
865
+ aggregate = response is None
866
+
867
+ try:
868
+ input_items, instructions = _messages_to_responses_input(messages)
869
+ data: dict[str, Any] = {
870
+ "model": model_id,
871
+ "input": input_items,
872
+ "stream": True,
873
+ }
874
+ if instructions:
875
+ data["instructions"] = instructions
876
+ responses_tools = _chat_tools_to_responses_tools(tools)
877
+ if responses_tools:
878
+ data["tools"] = responses_tools
879
+ if "tool_choice" in options:
880
+ data["tool_choice"] = options["tool_choice"]
881
+
882
+ if cancel_token is not None and cancel_token.is_cancel_requested:
883
+ if response is not None:
884
+ response.finish()
885
+ return
886
+
887
+ request = requests.post(
888
+ f"{API_ENDPOINT}{_COPILOT_RESPONSES_ENDPOINT}",
889
+ headers=generate_copilot_headers(),
890
+ json=data,
891
+ stream=True,
892
+ )
893
+
894
+ if request.status_code != 200:
895
+ msg = f"Failed to get responses from GitHub Copilot: [{request.status_code}]: {request.text}"
896
+ log.error(msg)
897
+ if response is not None:
898
+ response.stream(MarkdownData(msg))
899
+ response.finish()
900
+ raise Exception(msg)
901
+
902
+ client = sseclient.SSEClient(request)
903
+ if aggregate:
904
+ return _aggregate_responses_streaming(client)
905
+
906
+ # Streaming: translate typed Responses events into chat-completions
907
+ # delta chunks the existing frontend consumer already knows how to
908
+ # render. The shape `{choices: [{delta: {role, content}}]}` matches
909
+ # what `_aggregate_streaming_response` and `response.stream(...)`
910
+ # below produce for `/chat/completions`.
911
+ arg_buffers: dict[str, str] = {}
912
+ for event in client.events():
913
+ if cancel_token is not None and cancel_token.is_cancel_requested:
914
+ response.finish()
915
+ return
916
+ if not event.data:
917
+ continue
918
+ try:
919
+ chunk = json.loads(event.data)
920
+ except (ValueError, json.JSONDecodeError):
921
+ continue
922
+ event_type = chunk.get("type")
923
+ if event_type in _RESPONSES_TERMINAL_ERROR_EVENTS:
924
+ msg = _responses_error_message(chunk)
925
+ log.error(f"GitHub Copilot Responses stream failed: {msg}")
926
+ response.stream(MarkdownData(msg))
927
+ response.finish()
928
+ raise Exception(msg)
929
+ if event_type == "response.output_text.delta":
930
+ delta = chunk.get("delta")
931
+ if isinstance(delta, str) and delta:
932
+ response.stream({
933
+ "choices": [{
934
+ "delta": {"role": "assistant", "content": delta}
935
+ }]
936
+ })
937
+ elif event_type == "response.function_call_arguments.delta":
938
+ item_id = chunk.get("item_id")
939
+ delta = chunk.get("delta")
940
+ if isinstance(item_id, str) and isinstance(delta, str):
941
+ arg_buffers[item_id] = arg_buffers.get(item_id, "") + delta
942
+ elif event_type == "response.completed":
943
+ resp_obj = chunk.get("response") or {}
944
+ tool_calls: list[dict] = []
945
+ for idx, item in enumerate(resp_obj.get("output") or []):
946
+ if not isinstance(item, dict):
947
+ continue
948
+ buffered = arg_buffers.get(item.get("id") or "")
949
+ tc = _function_call_item_to_chat_tool(item, fallback_arguments=buffered or "")
950
+ if tc is None:
951
+ continue
952
+ tc["index"] = idx
953
+ tool_calls.append(tc)
954
+ if tool_calls:
955
+ response.stream({
956
+ "choices": [{
957
+ "delta": {"role": "assistant", "tool_calls": tool_calls}
958
+ }]
959
+ })
960
+ response.finish()
961
+ return
962
+ response.finish()
963
+ return
964
+ except requests.exceptions.ConnectionError:
965
+ raise Exception("Connection error")
966
+ except Exception as e:
967
+ log.error(f"Failed to get responses from GitHub Copilot: {e}")
968
+ raise e
969
+
970
+
971
+ def chat(model_id, messages, tools = None, response: ChatResponse = None, cancel_token: CancelToken = None, options: dict = {}) -> Any:
972
+ """Endpoint-aware chat entry point. Routes Codex-class models to
973
+ `/responses` and everything else to `/chat/completions`. Callers from
974
+ the LLM provider should go through this rather than `completions(...)`
975
+ directly so per-model dispatch stays in one place.
976
+ """
977
+ if _model_chat_endpoint(model_id) == _COPILOT_RESPONSES_ENDPOINT:
978
+ return responses(model_id, messages, tools, response, cancel_token, options)
979
+ return completions(model_id, messages, tools, response, cancel_token, options)
980
+
981
+
630
982
  def completions(model_id, messages, tools = None, response: ChatResponse = None, cancel_token: CancelToken = None, options: dict = {}) -> Any:
631
983
  aggregate = response is None
632
984
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plmbr/notebook-intelligence",
3
- "version": "5.0.0",
3
+ "version": "5.0.1",
4
4
  "description": "AI coding assistant for JupyterLab",
5
5
  "keywords": [
6
6
  "AI",
@@ -149,7 +149,7 @@
149
149
  }
150
150
  },
151
151
  "_build": {
152
- "load": "static/remoteEntry.4708b983f8e8c8f2abe1.js",
152
+ "load": "static/remoteEntry.e77a2554241f4d36341c.js",
153
153
  "extension": "./extension",
154
154
  "style": "./style"
155
155
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plmbr/notebook-intelligence",
3
- "version": "5.0.0",
3
+ "version": "5.0.1",
4
4
  "description": "AI coding assistant for JupyterLab",
5
5
  "keywords": [
6
6
  "AI",