Skip to content

Commit dbd1003

Browse files
committed
fix: timeout
1 parent 761cdfe commit dbd1003

File tree

5 files changed

+81
-26
lines changed

5 files changed

+81
-26
lines changed

dev/content/notebook.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{
44
"cell_type": "code",
55
"execution_count": null,
6-
"id": "510c04f2-5e6e-4a91-8af5-f1be55e74312",
6+
"id": "29a9d2af-9c57-449d-bbcb-2df77dfe9dfe",
77
"metadata": {},
88
"outputs": [],
99
"source": []

examples/jupyter-repl/Makefile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
.PHONY: help jupyterlab repl clean
2+
3+
# Default target
4+
# anthropic:claude-sonnet-4-20250514
5+
# azure-openai:gpt-4o-mini
6+
help:
7+
@echo "Jupyter MCP Example - Makefile"
8+
@echo ""
9+
@echo "Available targets:"
10+
@echo " jupyterlab - Start JupyterLab server on http://localhost:8888"
11+
@echo " repl - Start jupyter-ai-agents REPL connected to Jupyter MCP server"
12+
@echo " clean - Clean up temporary files"
13+
@echo ""
14+
@echo "Usage:"
15+
@echo " Terminal 1: make jupyterlab # Start JupyterLab with MCP server"
16+
@echo " Terminal 2: make repl # Connect REPL to Jupyter MCP server"
17+
@echo ""
18+
@echo "Note: The REPL connects to jupyter-mcp-server at http://localhost:8888/mcp"
19+
@echo ""
20+
21+
jupyterlab: ## jupyterlab
22+
jupyter lab \
23+
--port 8888 \
24+
--ServerApp.root_dir ./../../dev/content \
25+
--IdentityProvider.token=
26+
27+
# Start REPL connected to MCP Jupyter
28+
repl:
29+
@echo "🤖 Starting jupyter-ai-agents REPL connected to Jupyter Server"
30+
@echo "Make sure the Jupyter server is running first (make jupyterlab in another terminal)"
31+
@echo ""
32+
jupyter-ai-agents repl \
33+
--verbose \
34+
--mcp-servers http://localhost:8888/mcp \
35+
--model anthropic:claude-sonnet-4-20250514

examples/jupyter-repl/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!--
2+
~ Copyright (c) 2023-2024 Datalayer, Inc.
3+
~
4+
~ BSD 3-Clause License
5+
-->
6+
7+
[![Datalayer](https://assets.datalayer.tech/datalayer-25.svg)](https://datalayer.ai)
8+
9+
[![Become a Sponsor](https://img.shields.io/static/v1?label=Become%20a%20Sponsor&message=%E2%9D%A4&logo=GitHub&style=flat&color=1ABC9C)](https://github.com/sponsors/datalayer)
10+
11+
# Jupyter REPL Example

jupyter_ai_agents/cli/app.py

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -372,10 +372,8 @@ async def list_tools_async():
372372
from jupyter_ai_agents.tools import MCPServerStreamableHTTP
373373

374374
server_urls = [s.strip() for s in mcp_servers.split(',')]
375-
typer.echo("\n🔧 Available MCP Tools:")
376375

377376
for server_url in server_urls:
378-
typer.echo(f"\n Connecting to: {server_url}")
379377
try:
380378
mcp_client = MCPServerStreamableHTTP(server_url)
381379

@@ -384,32 +382,33 @@ async def list_tools_async():
384382
tools = await mcp_client.list_tools()
385383

386384
if not tools or len(tools) == 0:
387-
typer.echo(" No tools available")
385+
typer.echo("\n No tools available")
388386
continue
389387

390-
typer.echo(f" Found {len(tools)} tools:")
388+
typer.echo(f"\n Available Tools ({len(tools)}):")
391389
for tool in tools:
392390
name = tool.name
393391
description = tool.description or ""
394392
schema = tool.inputSchema
395393

394+
# Build parameter list
396395
params = []
397396
if schema and "properties" in schema:
398397
for param_name, param_info in schema["properties"].items():
399398
param_type = param_info.get("type", "any")
400399
params.append(f"{param_name}: {param_type}")
401400

402401
param_str = f"({', '.join(params)})" if params else "()"
403-
desc_first_line = description.split('\n')[0] if description else ""
404-
typer.echo(f" {name}{param_str} - {desc_first_line}")
402+
desc_first_line = description.split('\n')[0] if description else "No description"
403+
typer.echo(f" • {name}{param_str} - {desc_first_line}")
405404
except Exception as e:
406405
logger.warning(f"Could not connect to {server_url}: {e}")
407-
typer.echo(f" ⚠️ Could not connect: {e}")
406+
typer.echo(f"\n ⚠️ Could not list tools from {server_url}")
408407

409408
except Exception as e:
410409
logger.warning(f"Could not list tools: {e}")
411-
typer.echo(f"\n⚠️ Could not list tools: {e}")
412-
typer.echo(" The agent will still work with available tools\n")
410+
typer.echo(f"\n ⚠️ Could not list tools: {e}")
411+
413412

414413
try:
415414
from pydantic_ai import Agent
@@ -460,6 +459,12 @@ async def list_tools_async():
460459
)
461460
model_display_name = model # azure-openai:deployment-name
462461
logger.info(f"Using Azure OpenAI deployment: {deployment_name}")
462+
elif model.startswith('anthropic:'):
463+
# Parse anthropic:model-name format and use create_model_with_provider
464+
model_name_part = model.split(':', 1)[1]
465+
model_obj = create_model_with_provider('anthropic', model_name_part, timeout)
466+
model_display_name = model
467+
logger.info(f"Using Anthropic model: {model_name_part} (timeout: {timeout}s)")
463468
else:
464469
model_obj = model
465470
model_display_name = model
@@ -485,7 +490,17 @@ async def list_tools_async():
485490
mcp_client = MCPServerStreamableHTTP(server_url)
486491
toolsets.append(mcp_client)
487492

488-
# List tools before starting the agent (separate asyncio.run call)
493+
# Display welcome message
494+
typer.echo("="*70)
495+
typer.echo("🪐 ✨ Jupyter AI Agents - Interactive REPL")
496+
typer.echo("="*70)
497+
typer.echo(f"Model: {model_display_name}")
498+
499+
typer.echo(f"MCP Servers: {len(server_urls)} connected")
500+
for server_url in server_urls:
501+
typer.echo(f" - {server_url}")
502+
503+
# List tools inline in welcome message
489504
asyncio.run(list_tools_async())
490505

491506
# Create default system prompt if not provided
@@ -506,17 +521,6 @@ async def list_tools_async():
506521
system_prompt=instructions,
507522
)
508523

509-
# Display welcome message
510-
typer.echo("="*70)
511-
typer.echo("🪐 ✨ Jupyter AI Agents - Interactive REPL")
512-
typer.echo("="*70)
513-
typer.echo(f"Model: {model_display_name}")
514-
515-
server_urls = [s.strip() for s in mcp_servers.split(',')]
516-
typer.echo(f"MCP Servers: {len(server_urls)} connected")
517-
for server_url in server_urls:
518-
typer.echo(f" - {server_url}")
519-
520524
typer.echo("="*70)
521525
typer.echo("\nSpecial commands:")
522526
typer.echo(" /exit - Exit the session")

jupyter_ai_agents/utils/model.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,22 @@ def create_model_with_provider(
114114
return OpenAIChatModel(model_name, provider=azure_provider_with_timeout)
115115
elif model_provider.lower() == 'anthropic':
116116
from pydantic_ai.models.anthropic import AnthropicModel
117+
from pydantic_ai.providers.anthropic import AnthropicProvider
117118
from anthropic import AsyncAnthropic
118119

119-
# Create Anthropic client with custom timeout
120-
client = AsyncAnthropic(
121-
timeout=http_timeout,
120+
# Create Anthropic client with custom timeout and longer connect timeout
121+
# Note: Many corporate networks block Anthropic API, use Azure/OpenAI if connection fails
122+
anthropic_client = AsyncAnthropic(
123+
timeout=httpx.Timeout(timeout, connect=60.0), # Longer connect timeout for slow/restricted networks
122124
max_retries=2
123125
)
124126

127+
# Wrap in AnthropicProvider
128+
anthropic_provider = AnthropicProvider(anthropic_client=anthropic_client)
129+
125130
return AnthropicModel(
126131
model_name,
127-
provider=client
132+
provider=anthropic_provider
128133
)
129134
elif model_provider.lower() in ['openai', 'github-copilot']:
130135
from pydantic_ai.models.openai import OpenAIChatModel

0 commit comments

Comments
 (0)