-
-
Notifications
You must be signed in to change notification settings - Fork 446
Jupyternaut V3: Agentic tool-calling #1479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
4e4a3ae
to
f09caf5
Compare
Hey folks, I will be AFK from tomorrow to Monday. Feel free to review & test, but note that I may not be able to reply until Monday. Thanks! |
f09caf5
to
5223fa6
Compare
I have completed refactoring this branch using |
@Zsailer Hey Zach! This PR is mostly complete right now. I've unified all of the agent logic under a new "agent flow" that uses the Brian would love it if you can give this PR a review. He had mentioned that you were meeting w/ the Anthropic team about Jupyter AI, and seeing how outputs are rendered here might be helpful. |
It should take `content: str` and `tool_call_ui_elements: str` as format arguments. | ||
""" | ||
|
||
toolkit: Toolkit | None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this too limiting? For example, there could be tools from multiple toolkits that I might end up using.
""" | ||
Name of the tool function to be called. | ||
|
||
TODO: Check if this attribute is defined for non-function tools, e.g. tools |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dlqqq
I used the dev-install script and have litellm v1.77.1 installed. numpydoc seems to be an optional dependency in litellm. |
@3coins Thanks for the review! Yes, I forgot that I've also noticed that the tools don't always work. I'm having a hard time distinguishing between the LLM calling the tool incorrectly v.s. the tool not working at all. I think we can address this by adding more logging + improving the system prompt. Finally, make sure to run |
if (!props.id || !props.type || !props.function_name) { | ||
return null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello. Overall, everything seems to be working well for me.
However, I noticed that the id
prop is undefined in my environment when using the JaiToolCall
component. Interestingly, it functions correctly after renaming all instances of id
to tool_id
in the files toolcall_list.py
, web-components-plugin.ts
, and jai-tool-call.tsx
.
Am I understanding this correctly?
Description
This PR adds tool-calling capabilities to Jupyternaut. See the "code changes" section on implementation details. Key points:
Tool calls & their outputs are rendered using a new
<jai-tool-call>
custom web component. This leverages the custom elements API available in browsers, which lets us define custom HTML elements.r2wc
, a new NPM dependency that stands for "React to Web Component", which provides a simple utility to define a custom element's rendering lifecycle as a React component.BasePersona.stream_message() has been removed. This was previously the main method used by personas to write back to the
YChat
.All of the streaming, output rendering, and agentic tool-calling logic has been unified under the
default_flow
module, which usespocketflow
to define all of the "core logic" as an agent flow (a graph of nodes that can call each other).pocketflow
has been added as a new PyPI dependency.Defines a new default toolkit under
jupyter_ai.tools.default_toolkit
. This is a very minimal "starter set" of tools which may be upgraded/superseded in a future release.Demo
Screen.Recording.2025-09-08.at.10.51.52.AM.mov
Code changes
Frontend
Adds the
r2wc
NPM dependency.Adds a new
web-components
labextension plugin that provides the<jai-tool-call>
custom element, defined in a newJaiToolCall
React component.Each
<JaiToolCall />
component takes the following props:When a message contains tool calls, each tool call is rendered in one of these elements with
output
being unset. This shows the tool name & a loading spinner.After Jupyternaut runs each tool, the
output
property is set, which hides the loading spinner and shows a green check mark.Backend
Adds a
jupyter_ai.litellm_lib
module:Provides a
ToolCallList
class that aggregates the tool calls specified in each stream chunk. It provides arender()
method that can be used to convert the list into a string of<jai-tool-call>
elements so its consumers can easily render tool calls in real time.Provides a
run_tools()
function which accepts aToolCallList
& a toolkit.Adds a new
jupyter_ai.default_flow
module:@
-mentioning it. This includes chat streaming, output rendering, tool-calling capabilities, and agentic recursion.BasePersona.stream_message()
.run_default_flow()
, which accepts a dictionary of parameters that govern how the flow is run. Custom personas can tweak our default flow without re-inventing the wheel by changing the parameters.Removes
BasePersona.stream_message()
.Edits
Jupyternaut.process_message()
to just callawait run_default_flow()
to have everything handled automatically.Implements a default toolkit under
jupyter_ai.tools.default_toolkit
. This is what Jupyternaut will use for now.User-facing changes
Jupyternaut is now way more useful.
Backwards-incompatible changes
BasePersona.stream_message()
has been removed.Follow-up items
Error handling in response - Jupyternaut just halts whenever this occurs, with no message surfaced to the user.
Tool call success/failure state - right now each tool call is either "loading" or "success". We should allow it to show a red X if a tool call raised an exception.
Can't open the tool element while the AI response is streaming.