Skip to content

Commit 311b974

Browse files
authored
bump: versions (#38)
* chore: better server extension * bump: versions
1 parent 05aa551 commit 311b974

File tree

13 files changed

+74
-85
lines changed

13 files changed

+74
-85
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ We ask you to take additional actions to overcome limitations and bugs of the py
5959

6060
```bash
6161
pip uninstall -y pycrdt datalayer_pycrdt
62-
pip install datalayer_pycrdt==0.12.15
62+
pip install datalayer_pycrdt==0.12.17
6363
```
6464

6565
## Use from the CLI

docs/_tmp/fine-tuned/_category_.yaml

Lines changed: 0 additions & 2 deletions
This file was deleted.

docs/_tmp/fine-tuned/index.mdx

Lines changed: 0 additions & 7 deletions
This file was deleted.

docs/_tmp/llama3/_category_.yaml

Lines changed: 0 additions & 2 deletions
This file was deleted.

docs/_tmp/llama3/index.mdx

Lines changed: 0 additions & 3 deletions
This file was deleted.

jupyter_ai_agents/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

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

7-
__version__ = "0.10.2"
7+
__version__ = "0.11.1"
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
# Copyright (c) 2023-2024 Datalayer, Inc.
22
#
33
# Datalayer License
4-

jupyter_ai_agents/handlers/agents/handler.py

Lines changed: 41 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,42 @@
22
#
33
# BSD 3-Clause License
44

5-
# Copyright (c) 2021-2024 Datalayer, Inc.
6-
#
7-
# Datalayer License
8-
95
from __future__ import annotations
106

117
import json
128
import logging
139

14-
from pydantic import BaseModel
15-
from typing import Optional
16-
1710
from concurrent import futures
1811
from concurrent.futures import as_completed
1912

2013
from anyio import create_task_group, sleep
2114
from anyio.from_thread import start_blocking_portal
2215

23-
from jupyter_kernel_client import KernelClient
24-
2516
from jupyter_server.utils import url_path_join
2617
from jupyter_server.base.handlers import APIHandler
2718

28-
from jupyter_ai_agents import __version__
19+
from jupyter_kernel_client import KernelClient
20+
21+
from jupyter_ai_agents.handlers.agents.manager import AIAgentsManager
2922
from jupyter_ai_agents.agents.prompt import PromptAgent
30-
from jupyter_ai_agents.handlers.agents.agents import AIAgentsManager
23+
from jupyter_ai_agents.models import AgentRequestModel
3124
from jupyter_ai_agents.utils import http_to_ws
25+
from jupyter_ai_agents import __version__
3226

3327

3428
logger = logging.getLogger(__name__)
3529

30+
3631
EXECUTOR = futures.ThreadPoolExecutor(8)
3732

38-
MANAGER = None
33+
AI_AGENTS_MANAGER: AIAgentsManager | None = None
3934

40-
ROOMS = {}
35+
# COLLABORATION_ROOMS = {}
4136

4237

4338
def prompt_ai_agent(room_id, jupyter_ingress, jupyter_token, kernel_id):
4439
async def long_running_prompt():
45-
global MANAGER
40+
global AI_AGENTS_MANAGER
4641
room_ws_url = http_to_ws(url_path_join(jupyter_ingress, "/api/collaboration/room", room_id))
4742
logger.info("AI Agent will connect to room [%s]…", room_ws_url)
4843
has_runtime = jupyter_ingress and jupyter_token and kernel_id
@@ -56,55 +51,46 @@ async def long_running_prompt():
5651
log=logger,
5752
)
5853
logger.info("Starting AI Agent for room [%s]…", room_id)
59-
async def sometask() -> None:
60-
print('Task running')
54+
async def prompt_task() -> None:
55+
logger.info('Starting Prompt Agent.')
6156
await prompt_agent.start()
6257
if prompt_agent.runtime_client is not None:
6358
prompt_agent.runtime_client.start()
64-
print('Task finished')
59+
logger.info('Prompt Agent is started.')
6560
async with create_task_group() as tg:
66-
tg.start_soon(sometask)
67-
await sleep(20)
68-
# await MANAGER.track_agent(room_id, prompt_agent)
69-
print('Task running...')
70-
return 'Task return value'
61+
tg.start_soon(prompt_task)
62+
AI_AGENTS_MANAGER.register_ai_agent(room_id, prompt_agent)
63+
# Sleep forever to keep the ai agent alive.
64+
# TODO Replace with AI_AGENTS_MANAGER
65+
while True:
66+
await sleep(10)
67+
# await AI_AGENTS_MANAGER.track_agent(room_id, prompt_agent)
68+
return 'Prompt task is finished.'
7169
with start_blocking_portal() as portal:
7270
futures = [portal.start_task_soon(long_running_prompt)]
7371
for future in as_completed(futures):
74-
print(future.result())
75-
76-
77-
class RuntimeModel(BaseModel):
78-
ingress: Optional[str] = None
79-
token: Optional[str] = None
80-
kernel_id: Optional[str] = None
81-
jupyter_pod_name: Optional[str] = None
82-
83-
84-
class AgentRequestModel(BaseModel):
85-
room_id: Optional[str] = None
86-
runtime: Optional[RuntimeModel] = None
72+
logger.info("Future is completed with result [%s]", future.result())
8773

8874

89-
class AIAgentHandler(APIHandler):
75+
class AIAgentsInstanceHandler(APIHandler):
9076

9177
# @web.authenticated
9278
async def get(self, matched_part=None, *args, **kwargs):
93-
global MANAGER
94-
if MANAGER is None:
95-
MANAGER = AIAgentsManager()
79+
global AI_AGENTS_MANAGER
80+
if AI_AGENTS_MANAGER is None:
81+
AI_AGENTS_MANAGER = AIAgentsManager()
9682
self.write({
9783
"success": True,
9884
"matched_part": matched_part,
9985
})
10086

10187
# @web.authenticated
10288
async def post(self, matched_part=None, *args, **kwargs):
103-
global MANAGER
104-
if MANAGER is None:
105-
MANAGER = AIAgentsManager()
89+
global AI_AGENTS_MANAGER
90+
if AI_AGENTS_MANAGER is None:
91+
AI_AGENTS_MANAGER = AIAgentsManager()
10692
body_data = json.loads(self.request.body)
107-
print(body_data)
93+
logger.info("Body data", body_data)
10894
self.write({
10995
"success": True,
11096
"matched_part": matched_part,
@@ -115,26 +101,26 @@ class AIAgentsHandler(APIHandler):
115101

116102
# @web.authenticated
117103
async def get(self, *args, **kwargs):
118-
global MANAGER
119-
if MANAGER is None:
120-
MANAGER = AIAgentsManager()
104+
global AI_AGENTS_MANAGER
105+
if AI_AGENTS_MANAGER is None:
106+
AI_AGENTS_MANAGER = AIAgentsManager()
121107
self.write({
122108
"success": True,
123109
})
124110

125111
# @web.authenticated
126112
async def post(self, *args, **kwargs):
127113
"""Endpoint creating an AI Agent for a given room."""
128-
global MANAGER
129-
if MANAGER is None:
130-
MANAGER = AIAgentsManager()
114+
global AI_AGENTS_MANAGER
115+
if AI_AGENTS_MANAGER is None:
116+
AI_AGENTS_MANAGER = AIAgentsManager()
131117
request_body = json.loads(self.request.body)
132118
agent_request = AgentRequestModel(**request_body)
133-
self.log.info("Create AI Agents is requested [%s]", agent_request.model_dump())
119+
self.log.info("AI Agents create handler requested with [%s]", agent_request.model_dump())
134120
room_id = agent_request.room_id
135-
if room_id in MANAGER:
121+
if room_id in AI_AGENTS_MANAGER:
136122
self.log.info("AI Agent for room [%s] already exists.", room_id)
137-
# TODO check agent
123+
# TODO check the ai agent.
138124
return {
139125
"success": True,
140126
"message": "AI Agent already exists",
@@ -145,11 +131,11 @@ async def post(self, *args, **kwargs):
145131
jupyter_ingress = runtime.ingress
146132
jupyter_token = runtime.token
147133
kernel_id = runtime.kernel_id
148-
# Start AI Agent
134+
# Start AI Agent in a ThreadPoolExecutor.
149135
EXECUTOR.submit(prompt_ai_agent, room_id, jupyter_ingress, jupyter_token, kernel_id)
150136
res = json.dumps({
151137
"success": True,
152-
"message": f"AI Agent started for room '{room_id}'.",
138+
"message": f"AI Agent is started for room '{room_id}'.",
153139
})
154-
print(res)
140+
logger.info("AI Agent create request exiting with reponse [%s]", res)
155141
self.finish(res)

jupyter_ai_agents/handlers/agents/agents.py renamed to jupyter_ai_agents/handlers/agents/manager.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,12 @@ def __init__(self) -> None:
4141
# A usefull task will be set when the first agent is added.
4242
self._stop_task: asyncio.Task = asyncio.create_task(asyncio.sleep(0))
4343

44-
4544
def __contains__(self, key: str) -> bool:
4645
return key in self._agents
4746

48-
4947
def __getitem__(self, key: str) -> RuntimeAgent:
5048
return self._agents[key]
5149

52-
5350
async def _stop_lonely_agents(self) -> None:
5451
"""Periodically check if an agent as connected peer.
5552
@@ -83,7 +80,6 @@ async def _stop_lonely_agents(self) -> None:
8380
self._to_stop_counter.pop(key, None)
8481
logger.info("AI Agent for room [%s] stopped.", key)
8582

86-
8783
async def stop_all(self) -> None:
8884
"""Stop all background tasks and reset the state."""
8985
if self._stop_task.cancel():
@@ -98,23 +94,23 @@ async def stop_all(self) -> None:
9894
self._agents_to_stop.clear()
9995
self._to_stop_counter.clear()
10096

101-
10297
def get_user_agents(self, user: str) -> list[str]:
10398
return [k for k, a in self._agents.items() if a._username == user]
10499

100+
def register_ai_agent(self, key: str, agent: RuntimeAgent):
101+
self._agents[key] = agent
105102

106103
async def track_agent(self, key: str, agent: RuntimeAgent) -> None:
107104
"""Add an agent and start it."""
108105
if self._stop_task.done():
109106
self._stop_task = asyncio.create_task(self._stop_lonely_agents())
110-
self._agents[key] = agent
107+
self.register_ai_agent(key, agent)
111108
start = asyncio.create_task(await agent.start())
112109
self._background_tasks.append(start)
113110
start.add_done_callback(lambda task: self._background_tasks.remove(task))
114111
if agent.runtime_client is not None:
115112
agent.runtime_client.start()
116113

117-
118114
def forget_agent(self, key: str) -> None:
119115
if key in self:
120116
logger.info("Removing AI Agent in room [%s].", key)

jupyter_ai_agents/models.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright (c) 2023-2024 Datalayer, Inc.
2+
#
3+
# BSD 3-Clause License
4+
5+
from __future__ import annotations
6+
7+
8+
from typing import Optional
9+
10+
from pydantic import BaseModel
11+
12+
13+
class RuntimeModel(BaseModel):
14+
ingress: Optional[str] = None
15+
token: Optional[str] = None
16+
kernel_id: Optional[str] = None
17+
jupyter_pod_name: Optional[str] = None
18+
19+
20+
class AgentRequestModel(BaseModel):
21+
room_id: Optional[str] = None
22+
runtime: Optional[RuntimeModel] = None

0 commit comments

Comments
 (0)