Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6da0463

Browse files
committed
Allow multiline autosuggest and draft of LLM completion.
This is a preview-draft of modification to IPython in order to allow multi-line suggestion in the terminal, and add the necesarry hooks and examples, in order to trigger LLM autocomplation via a shortcut. This will not be complete, but will be available as a preview in IPython 8.32 in order to gather feedback. This tries to be as compatible as possible with jupyter_ai and jupyter_ai_magics, except the Provider cannot take parameters in their constructor.
1 parent 788e252 commit 6da0463

3 files changed

Lines changed: 434 additions & 16 deletions

File tree

IPython/terminal/interactiveshell.py

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
default,
2727
observe,
2828
validate,
29+
DottedObjectName,
2930
)
31+
from traitlets.utils.importstring import import_item
32+
3033

3134
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
3235
from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
@@ -224,7 +227,9 @@ class TerminalInteractiveShell(InteractiveShell):
224227

225228
pt_app: UnionType[PromptSession, None] = None
226229
auto_suggest: UnionType[
227-
AutoSuggestFromHistory, NavigableAutoSuggestFromHistory, None
230+
AutoSuggestFromHistory,
231+
NavigableAutoSuggestFromHistory,
232+
None,
228233
] = None
229234
debugger_history = None
230235

@@ -431,6 +436,37 @@ def _displayhook_class_default(self):
431436
allow_none=True,
432437
).tag(config=True)
433438

439+
llm_provider_class = DottedObjectName(
440+
None,
441+
allow_none=True,
442+
help="""\
443+
Provisional:
444+
This is a provisinal API in IPython 8.32, before stabilisation
445+
in 9.0, it may change without warnings.
446+
447+
class to use for the `NavigableAutoSuggestFromHistory` to request
448+
completions from a LLM, this should inherit from
449+
`jupyter_ai_magics:BaseProvider` and implement
450+
`stream_inline_completions`
451+
""",
452+
).tag(config=True)
453+
454+
@observe("llm_provider_class")
455+
def _llm_provider_class_changed(self, change):
456+
provider_class = change.new
457+
if provider_class is not None:
458+
warn(
459+
"TerminalInteractiveShell.llm_provider_class is a provisional"
460+
" API as of IPython 8.32, and may change without warnings."
461+
)
462+
if isinstance(self.auto_suggest, NavigableAutoSuggestFromHistory):
463+
self.auto_suggest._llm_provider = provider_class()
464+
else:
465+
self.log.warn(
466+
"llm_provider_class only has effects when using"
467+
"`NavigableAutoSuggestFromHistory` as auto_suggest."
468+
)
469+
434470
def _set_autosuggestions(self, provider):
435471
# disconnect old handler
436472
if self.auto_suggest and isinstance(
@@ -442,7 +478,15 @@ def _set_autosuggestions(self, provider):
442478
elif provider == "AutoSuggestFromHistory":
443479
self.auto_suggest = AutoSuggestFromHistory()
444480
elif provider == "NavigableAutoSuggestFromHistory":
481+
# LLM stuff are all Provisional in 8.32
482+
if self.llm_provider_class:
483+
llm_provider_constructor = import_item(self.llm_provider_class)
484+
llm_provider = llm_provider_constructor()
485+
else:
486+
llm_provider = None
445487
self.auto_suggest = NavigableAutoSuggestFromHistory()
488+
# Provisinal in 8.32
489+
self.auto_suggest._llm_provider = llm_provider
446490
else:
447491
raise ValueError("No valid provider.")
448492
if self.pt_app:
@@ -832,7 +876,8 @@ def get_message():
832876
& ~IsDone()
833877
& Condition(
834878
lambda: isinstance(
835-
self.auto_suggest, NavigableAutoSuggestFromHistory
879+
self.auto_suggest,
880+
NavigableAutoSuggestFromHistory,
836881
)
837882
),
838883
),

0 commit comments

Comments
 (0)