|
7 | 7 | from typing import TYPE_CHECKING, Dict, List, Optional
|
8 | 8 |
|
9 | 9 | import tornado
|
10 |
| -from jupyter_ai.chat_handlers import BaseChatHandler |
| 10 | +from jupyter_ai.chat_handlers import BaseChatHandler, SlashCommandRoutingType |
11 | 11 | from jupyter_ai.config_manager import ConfigManager, KeyEmptyError, WriteConflictError
|
12 | 12 | from jupyter_server.base.handlers import APIHandler as BaseAPIHandler
|
13 | 13 | from jupyter_server.base.handlers import JupyterHandler
|
14 | 14 | from langchain.pydantic_v1 import ValidationError
|
15 | 15 | from tornado import web, websocket
|
16 | 16 | from tornado.web import HTTPError
|
17 | 17 |
|
18 |
| -from .completions.models import InlineCompletionRequest |
19 | 18 | from .models import (
|
20 | 19 | AgentChatMessage,
|
21 | 20 | ChatClient,
|
|
27 | 26 | HumanChatMessage,
|
28 | 27 | ListProvidersEntry,
|
29 | 28 | ListProvidersResponse,
|
| 29 | + ListSlashCommandsEntry, |
| 30 | + ListSlashCommandsResponse, |
30 | 31 | Message,
|
31 | 32 | UpdateConfigRequest,
|
32 | 33 | )
|
@@ -405,3 +406,52 @@ def delete(self, api_key_name: str):
|
405 | 406 | self.config_manager.delete_api_key(api_key_name)
|
406 | 407 | except Exception as e:
|
407 | 408 | raise HTTPError(500, str(e))
|
| 409 | + |
| 410 | + |
| 411 | +class SlashCommandsInfoHandler(BaseAPIHandler): |
| 412 | + """List slash commands that are currently available to the user.""" |
| 413 | + |
| 414 | + @property |
| 415 | + def config_manager(self) -> ConfigManager: |
| 416 | + return self.settings["jai_config_manager"] |
| 417 | + |
| 418 | + @property |
| 419 | + def chat_handlers(self) -> Dict[str, "BaseChatHandler"]: |
| 420 | + return self.settings["jai_chat_handlers"] |
| 421 | + |
| 422 | + @web.authenticated |
| 423 | + def get(self): |
| 424 | + response = ListSlashCommandsResponse() |
| 425 | + |
| 426 | + # if no selected LLM, return an empty response |
| 427 | + if not self.config_manager.lm_provider: |
| 428 | + self.finish(response.json()) |
| 429 | + return |
| 430 | + |
| 431 | + for id, chat_handler in self.chat_handlers.items(): |
| 432 | + # filter out any chat handler that is not a slash command |
| 433 | + if ( |
| 434 | + id == "default" |
| 435 | + or chat_handler.routing_type.routing_method != "slash_command" |
| 436 | + ): |
| 437 | + continue |
| 438 | + |
| 439 | + # hint the type of this attribute |
| 440 | + routing_type: SlashCommandRoutingType = chat_handler.routing_type |
| 441 | + |
| 442 | + # filter out any chat handler that is unsupported by the current LLM |
| 443 | + if ( |
| 444 | + "/" + routing_type.slash_id |
| 445 | + in self.config_manager.lm_provider.unsupported_slash_commands |
| 446 | + ): |
| 447 | + continue |
| 448 | + |
| 449 | + response.slash_commands.append( |
| 450 | + ListSlashCommandsEntry( |
| 451 | + slash_id=routing_type.slash_id, description=chat_handler.help |
| 452 | + ) |
| 453 | + ) |
| 454 | + |
| 455 | + # sort slash commands by slash id and deliver the response |
| 456 | + response.slash_commands.sort(key=lambda sc: sc.slash_id) |
| 457 | + self.finish(response.json()) |
0 commit comments