Skip to content

Commit c382a25

Browse files
github copilot integration
1 parent db7e4f8 commit c382a25

File tree

16 files changed

+127
-58
lines changed

16 files changed

+127
-58
lines changed

README.md

+9-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
*The Jupyter AI Agents are equipped with tools like 'execute', 'insert_cell', and more, to transform your Jupyter Notebooks into an intelligent, interactive workspace!*
1717

18-
![Jupyter AI Agents](https://assets.datalayer.tech/jupyter-ai-agents/ai-agents-prompt-demo-terminal.gif)
18+
![Jupyter AI Agents](https://assets.datalayer.tech/jupyter-ai-agent/ai-agent-prompt-demo-terminal.gif)
1919

2020
```
2121
Jupyter AI Agents <-----------> JupyterLab
@@ -73,6 +73,8 @@ Start JupyterLab, setting a `port` and a `token` to be reused by the agent, and
7373
jupyter lab --port 8888 --IdentityProvider.token MY_TOKEN
7474
```
7575

76+
Jupyter AI Agents supports multiple AI model providers (more information on [here](https://jupyter-ai-agents.datalayer.tech/docs/models/)). Here is an example with the Azure OpenAI provider.
77+
7678
Read the [Azure Documentation](https://learn.microsoft.com/en-us/azure/ai-services/openai) to get the needed credentials and make sure you define them in the following `.env` file.
7779

7880
```bash
@@ -90,23 +92,25 @@ To use the Jupyter AI Agents, an easy way is to launch a CLI (update the Azure d
9092
jupyter-ai-agents prompt \
9193
--url http://localhost:8888 \
9294
--token MY_TOKEN \
93-
--azure-ai-deployment-name gpt-40-mini \
95+
--model-provider azure-openai \
96+
--model-name gpt-4o-mini \
9497
--path test.ipynb \
9598
--input "Create a matplotlib example"
9699
```
97100

98-
![Jupyter AI Agents](https://assets.datalayer.tech/jupyter-ai-agents/ai-agents-prompt-demo-terminal.gif)
101+
![Jupyter AI Agents](https://assets.datalayer.tech/jupyter-ai-agent/ai-agent-prompt-demo-terminal.gif)
99102

100103
```bash
101104
# Explain Error agent example.
102105
jupyter-ai-agents explain-error \
103106
--url http://localhost:8888 \
104107
--token MY_TOKEN \
105-
--azure-ai-deployment-name gpt-40-mini \
108+
--model-provider azure-openai \
109+
--model-name gpt-4o-mini \
106110
--path test.ipynb
107111
```
108112

109-
![Jupyter AI Agents](https://assets.datalayer.tech/jupyter-ai-agents/ai-agents-explainerror-demo-terminal.gif)
113+
![Jupyter AI Agents](https://assets.datalayer.tech/jupyter-ai-agent/ai-agent-explainerror-demo-terminal.gif)
110114

111115
## Uninstall
112116

docs/docs/agents/explain_error/index.mdx

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ The Explain Error Agent explains an error encountered in a notebook. It leverage
1111
jupyter-ai-agents explain-error \
1212
--url http://localhost:8888 \
1313
--token MY_TOKEN \
14-
--azure-ai-deployment-name gpt-40-mini \
14+
--model-provider azure-openai \
15+
--model-name gpt-4o-mini \
1516
--path test.ipynb
1617
```
1718

1819
## Parameters
1920

2021
- `--url`: JupyterLab URL.
2122
- `--token`: JupyterLab token.
22-
- `--azure-ai-deployment-name`: Azure AI model deployment name.
23+
- `--model-provider`: `azure-openai` or `github-copilot`.
24+
- `--model-name`: Azure AI model deployment name or Github Copilot model to use.
2325
- `--path`: Notebook to modify path.
2426
- `--current-cell-index`: Optional flag to provide the index of the cell where the error is encountered. If not provided, the error considered is the first one in the notebook.

docs/docs/agents/prompt/index.mdx

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# Prompt Agent
22

3-
The Prompt Agent generates code cells based on natural language input. It leverages AI models to generate code, add new cells, and modify the notebook content. This is a great Agent to support the following use cases:
3+
The Prompt Agent generates code cells based on natural language input. It leverages AI models to generate code, markdown, add new cells, and modify the notebook content. This is a great Agent to support the following use cases:
44

55
- Code Generation: Generate cells code based on natural language input.
6-
- Notebook Modification: Add new cells based on existing one.
6+
- Markdown Generation: Generate markdown cells based on natural language input.
7+
- Notebook Modification: Insert new cells based on existing one to your notebook.
78

89
![Jupyter AI Agents](https://assets.datalayer.tech/jupyter-ai-agents/ai-agent-prompt-demo-terminal.gif)
910

@@ -13,7 +14,8 @@ To use the Jupyter AI Agents, an easy way is to launch a CLI (update the Azure d
1314
jupyter-ai-agents prompt \
1415
--url http://localhost:8888 \
1516
--token MY_TOKEN \
16-
--azure-ai-deployment-name gpt-40-mini \
17+
- model-provider azure-openai \
18+
--model-name gpt-4o-mini \
1719
--path test.ipynb \
1820
--input "Create a matplotlib example"
1921
```
@@ -23,7 +25,8 @@ jupyter-ai-agents prompt \
2325
The Prompt Agent can be configured with the following parameters:
2426
- `--url`: JupyterLab URL.
2527
- `--token`: JupyterLab token.
26-
- `--azure-ai-deployment-name`: Azure AI model deployment name.
28+
- `--model-provider`: `azure-openai` or `github-copilot`.
29+
- `--model-name`: Azure AI model deployment name or Github Copilot model to use.
2730
- `--path`: Notebook to modify path.
2831
- `--input`: Natural language input.
2932
- `--full-context`: Optional flag to provide the full notebook context i.e. notebook content to the AI model (default: False).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
label: "GitHub Copilot"
2+
position: 2
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# GitHub Copilot
2+
3+
Jupyter AI Agents supports models from [GitHub Copilot](https://copilot.github.com/).
4+
5+
Read the [Langchain GitHubCopilot README](https://github.com/datalayer/langchain-github-copilot) to get the `GITHUB` token and make sur you define it in the following environment variable.
6+
7+
```bash
8+
export GITHUB_TOKEN="..."
9+
```
10+
11+
GitHub Copilot supports different models that you can specify using the `--model-name` parameter. The available models as of 2024-02-07 are
12+
- gpt-4o
13+
- o1
14+
- o3-mini
15+
16+
Make sure you have a GitHubCopilot subscription and have enabled the model you want to use in your GitHubCopilot settings.
17+

docs/docs/models/index.mdx

+2
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ import DocCardList from '@theme/DocCardList';
22

33
# Models
44

5+
Jupyter AI Agents can be used with multiple AI models providers.
6+
57
<DocCardList />

jupyter_ai_agents/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
"""Jupyter AI Agents."""
66

7-
__version__ = "0.2.0"
7+
__version__ = "0.3.0"

jupyter_ai_agents/agents/explain_error.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@
55
import logging
66

77
from langchain.agents import tool
8-
from langchain.agents import AgentExecutor
98

10-
from jupyter_ydoc import YNotebook
119
from jupyter_nbmodel_client import NbModelClient
1210
from jupyter_kernel_client import KernelClient
1311

14-
from jupyter_ai_agents.providers.azure_openai import create_azure_open_ai_agents
12+
from jupyter_ai_agents.agents.utils import create_ai_agent
1513
from jupyter_ai_agents.tools import insert_execute_code_cell_tool
1614
from jupyter_ai_agents.utils import retrieve_cells_content_until_first_error, retrieve_cells_content_error
1715

@@ -25,7 +23,7 @@
2523
"""
2624

2725

28-
def explain_error(notebook: NbModelClient, kernel: KernelClient, azure_deployment_name: str, current_cell_index: int) -> list:
26+
def explain_error(notebook: NbModelClient, kernel: KernelClient, model_provider: str, model_name: str, current_cell_index: int) -> list:
2927
"""Explain and correct an error in a notebook based on the prior cells."""
3028

3129
@tool
@@ -61,7 +59,6 @@ def insert_execute_code_cell(cell_index: int, cell_content: str) -> str:
6159
logger.debug("Prompt with content", system_prompt_final)
6260
logger.debug("Input", input)
6361

64-
agent = create_azure_open_ai_agents(azure_deployment_name, system_prompt_final, tools)
65-
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
66-
67-
return list(agent_executor.stream({"input": input}))
62+
agent = create_ai_agent(model_provider, model_name, system_prompt_final, tools)
63+
64+
return list(agent.stream({"input": input}))

jupyter_ai_agents/agents/prompt.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
# BSD 3-Clause License
44

55
from langchain.agents import tool
6-
from langchain.agents import AgentExecutor
76

87
from jupyter_nbmodel_client import NbModelClient
98
from jupyter_kernel_client import KernelClient
109

11-
from jupyter_ai_agents.providers.azure_openai import create_azure_open_ai_agents
10+
from jupyter_ai_agents.agents.utils import create_ai_agent
1211
from jupyter_ai_agents.tools import insert_execute_code_cell_tool, insert_markdown_cell_tool
1312
from jupyter_ai_agents.utils import retrieve_cells_content
1413

@@ -19,7 +18,7 @@
1918
Ensure updates to cell indexing when new cells are inserted. Maintain the logical flow of execution by adjusting cell index as needed.
2019
"""
2120

22-
def prompt(notebook: NbModelClient, kernel: KernelClient, input: str, azure_deployment_name: str, full_context: bool, current_cell_index: int) -> list:
21+
def prompt(notebook: NbModelClient, kernel: KernelClient, input: str, model_provider: str, model_name: str, full_context: bool, current_cell_index: int) -> list:
2322
"""From a given instruction, code and markdown cells are added to a notebook."""
2423

2524
@tool
@@ -54,7 +53,6 @@ def insert_markdown_cell(cell_index: int, cell_content: str) -> str:
5453
else:
5554
system_prompt_final = system_prompt_enriched
5655

57-
agent = create_azure_open_ai_agents(azure_deployment_name, system_prompt_final, tools)
58-
agent_executor = AgentExecutor(name="NotebookPromptAgent", agent=agent, tools=tools, verbose=True)
56+
agent = create_ai_agent(model_provider, model_name, system_prompt_final, tools)
5957

60-
return list(agent_executor.stream({"input": input}))
58+
return list(agent.stream({"input": input}))

jupyter_ai_agents/agents/utils.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright (c) 2023-2024 Datalayer, Inc.
2+
#
3+
# BSD 3-Clause License
4+
5+
from jupyter_ai_agents.providers.azure_openai import create_azure_openai_agent
6+
from jupyter_ai_agents.providers.github_copilot import create_github_copilot_agent
7+
8+
def create_ai_agent(model_provider: str, model_name: str, system_prompt_final: str, tools: list):
9+
"""Create an AI agent based on the model provider."""
10+
if model_provider == "azure-openai":
11+
agent = create_azure_openai_agent(model_name, system_prompt_final, tools)
12+
elif model_provider == "github-copilot":
13+
agent = create_github_copilot_agent(model_name, system_prompt_final, tools)
14+
else:
15+
raise ValueError(f"Model provider {model_provider} is not supported.")
16+
return agent

jupyter_ai_agents/app.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def initialize(self, *args, **kwargs):
5353
super(PromptAgentApp, self).initialize(*args, **kwargs)
5454

5555
def ask(self):
56-
reply = prompt(self.notebook, self.kernel, super().input, super().azure_ai_deployment_name, self.full_context, self.current_cell_index)
56+
reply = prompt(self.notebook, self.kernel, super().input, super().model_provider, super().model_name, self.full_context, self.current_cell_index)
5757
logger.debug("Reply", reply)
5858

5959
def start(self):
@@ -78,7 +78,7 @@ def initialize(self, *args, **kwargs):
7878
super(ExplainErrorAgentApp, self).initialize(*args, **kwargs)
7979

8080
def ask(self):
81-
reply = explain_error(self.notebook, self.kernel, super().azure_ai_deployment_name, self.current_cell_index)
81+
reply = explain_error(self.notebook, self.kernel, super().model_provider, super().model_name, self.current_cell_index)
8282
logger.debug("Reply", reply)
8383

8484
def start(self):

jupyter_ai_agents/base.py

+20-7
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@
4040
"path": "JupyterAIAgentBaseApp.path",
4141
"agent": "JupyterAIAgentBaseApp.agent_name",
4242
"input": "JupyterAIAgentBaseApp.input",
43+
"model-provider": "JupyterAIAgentBaseApp.model_provider",
4344
"openai-api-version": "JupyterAIAgentBaseApp.openai_api_version",
4445
"azure-openai-version": "JupyterAIAgentBaseApp.azure_openai_version",
4546
"azure-openai-api-key": "JupyterAIAgentBaseApp.azure_openai_api_key",
46-
"azure-ai-deployment-name": "JupyterAIAgentBaseApp.azure_ai_deployment_name",
47+
"model-name": "JupyterAIAgentBaseApp.model_name",
4748
"current-cell-index": "JupyterAIAgentBaseApp.current_cell_index",
4849
}
4950
)
@@ -73,9 +74,8 @@ class JupyterAIAgentBaseApp(JupyterApp):
7374
path = Unicode(
7475
"",
7576
config=True,
76-
help="Jupyter Notebok path."
77+
help="Jupyter Notebook path."
7778
)
78-
7979
agent_name = Unicode(
8080
"prompt",
8181
config=True,
@@ -86,7 +86,11 @@ class JupyterAIAgentBaseApp(JupyterApp):
8686
config=True,
8787
help="Input."
8888
)
89-
89+
model_provider = Unicode(
90+
"github-copilot",
91+
config=True,
92+
help="Model provider can be 'azure-openai' or 'github-copilot'."
93+
)
9094
openai_api_version = Unicode(
9195
os.environ.get("OPENAI_API_VERSION"),
9296
help="""OpenAI version.""",
@@ -102,9 +106,18 @@ class JupyterAIAgentBaseApp(JupyterApp):
102106
help="""Azure OpenAI key.""",
103107
config=True,
104108
)
105-
azure_ai_deployment_name = Unicode(
106-
"",
107-
help="""Azure AI deployment name.""",
109+
github_token = Unicode(
110+
os.environ.get("GITHUB_TOKEN"),
111+
help="""Github token.""",
112+
config=True,
113+
)
114+
model_name = Unicode(
115+
"gpt-4o",
116+
help=(
117+
"The 'Azure AI deployment' name for 'azure-openai' model provider."
118+
"For 'github-copilot' model provider, gpt-4o, o1, or o3-mini (as of 2024-02-07) "
119+
"- check your GithubCopilot settings to make sure the model you want to use is enabled."""
120+
),
108121
config=True,
109122
)
110123
current_cell_index = Integer(

jupyter_ai_agents/providers/azure_openai.py

+10-19
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,15 @@
22
#
33
# BSD 3-Clause License
44

5-
from langchain.agents import tool
65
from langchain_openai import AzureChatOpenAI
6+
from langchain.agents import AgentExecutor, create_openai_tools_agent
77
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
8-
from langchain.agents.format_scratchpad.openai_tools import format_to_openai_tool_messages
9-
from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser
108

119

12-
def create_azure_open_ai_agents(azure_deployment_name: str, system_prompt: str, tools: list) -> dict:
13-
"""Create an agent from a set of tools and an Azure deployment name."""
14-
15-
llm = AzureChatOpenAI(azure_deployment=azure_deployment_name)
16-
llm_with_tools = llm.bind_tools(tools)
10+
def create_azure_openai_agent(model_name: str, system_prompt: str, tools: list) -> dict:
11+
"""Create an agent from a set of tools and an Azure deployment"""
12+
13+
llm = AzureChatOpenAI(azure_deployment=model_name)
1714

1815
prompt = ChatPromptTemplate.from_messages(
1916
[
@@ -22,15 +19,9 @@ def create_azure_open_ai_agents(azure_deployment_name: str, system_prompt: str,
2219
MessagesPlaceholder(variable_name="agent_scratchpad"),
2320
])
2421

25-
agent = (
26-
{
27-
"input": lambda x: x["input"],
28-
"agent_scratchpad": lambda x: format_to_openai_tool_messages(
29-
x["intermediate_steps"]
30-
),
31-
}
32-
| prompt
33-
| llm_with_tools
34-
| OpenAIToolsAgentOutputParser())
22+
# Create the agent using LangChain's built-in tool handling
23+
agent = create_openai_tools_agent(llm, tools, prompt)
24+
25+
agent_executor = AgentExecutor(name="NotebookPromptAgent", agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
3526

36-
return agent
27+
return agent_executor
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright (c) 2023-2024 Datalayer, Inc.
2+
#
3+
# BSD 3-Clause License
4+
5+
from langchain_github_copilot import ChatGithubCopilot
6+
from langchain.agents import AgentExecutor, create_openai_tools_agent
7+
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
8+
9+
10+
def create_github_copilot_agent(model_name: str, system_prompt: str, tools: list) -> dict:
11+
"""Create an agent from a set of tools and a Github Copilot model"""
12+
13+
llm = ChatGithubCopilot(model_name=model_name)
14+
15+
prompt = ChatPromptTemplate.from_messages(
16+
[
17+
("system", system_prompt),
18+
("user", "{input}"),
19+
MessagesPlaceholder(variable_name="agent_scratchpad"),
20+
])
21+
22+
# Create the agent using LangChain's built-in tool handling
23+
agent = create_openai_tools_agent(llm, tools, prompt)
24+
25+
agent_executor = AgentExecutor(name="NotebookPromptAgent", agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
26+
27+
return agent_executor

jupyter_ai_agents/tools.py

-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
#
33
# BSD 3-Clause License
44

5-
from dotenv import load_dotenv, find_dotenv
6-
7-
from langchain.agents import tool
8-
95
from jupyter_nbmodel_client import NbModelClient
106
from jupyter_kernel_client import KernelClient
117

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ classifiers = [
2323
dependencies = [
2424
"langchain",
2525
"langchain-openai",
26+
"langchain-github-copilot",
2627
"jupyter_kernel_client",
2728
"jupyter_nbmodel_client",
2829
"python-dotenv",

0 commit comments

Comments
 (0)