Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
f09e0fc
Fix import sorting and unused imports
prassanna-ravishankar Sep 25, 2025
fea615b
Replace print statements with logger in core library files
prassanna-ravishankar Sep 25, 2025
ad13443
Fix simple unused arguments with underscore prefix
prassanna-ravishankar Sep 25, 2025
1a03a33
Fix exception handling issues
prassanna-ravishankar Sep 25, 2025
5110dc8
Fix remaining linting issues
prassanna-ravishankar Sep 25, 2025
058c70e
Fix print statements in Jinja template
prassanna-ravishankar Sep 25, 2025
25ba606
Add inline ignores for obvious unused argument cases
prassanna-ravishankar Sep 25, 2025
c3924d7
Fix remaining linting issues with comprehensive approach
prassanna-ravishankar Sep 25, 2025
fa874e0
Final linting cleanup - fix remaining edge cases
prassanna-ravishankar Sep 25, 2025
b0c1b98
Remove LINTING-CALLOUTS.md from git tracking
prassanna-ravishankar Sep 25, 2025
9593eed
Fix typing: safely extract content from TaskMessageContent in hello_a…
prassanna-ravishankar Sep 25, 2025
e6d6f57
Fix typing: safely access TaskMessageContent attributes in multiturn …
prassanna-ravishankar Sep 25, 2025
606fc5e
Fix typing: safely access TaskMessageContent attributes in streaming …
prassanna-ravishankar Sep 25, 2025
0b19233
Fix typing: add null checks and safe access in agentic multiturn tuto…
prassanna-ravishankar Sep 25, 2025
5e74015
Fix typing: add null checks and safe access in agentic streaming tuto…
prassanna-ravishankar Sep 25, 2025
f2d0b61
Fix typing: add missing type annotations and fix author value in test…
prassanna-ravishankar Sep 25, 2025
0702875
Fix typing: add type annotations to test_model_utils.py
prassanna-ravishankar Sep 25, 2025
6f81860
Fix typing: improve return type annotations in secret_handlers.py
prassanna-ravishankar Sep 25, 2025
8648883
Fix typing: add type annotation for serializable_tasks list in tasks.py
prassanna-ravishankar Sep 25, 2025
53fe8f7
Fix typing: improve safe content extraction in tutorials to avoid unn…
prassanna-ravishankar Sep 25, 2025
2a69d3c
Fix import formatting in tasks.py
prassanna-ravishankar Sep 25, 2025
a51e586
Add pyright ignore rules for common generated SDK code issues
prassanna-ravishankar Sep 25, 2025
8f5d4fc
Configure pyright for strict checking only on controlled directories
prassanna-ravishankar Sep 25, 2025
a898520
Fix additional typing issues in agentic tutorials
prassanna-ravishankar Sep 25, 2025
0981979
Fix simple typing issues in lib directory
prassanna-ravishankar Sep 25, 2025
b2614ab
Fix content type extraction in temporal state machine tutorials
prassanna-ravishankar Sep 25, 2025
923bbfc
Add type ignores for OpenAI Agent parameter mismatches in ADK providers
prassanna-ravishankar Sep 25, 2025
c20cdb4
Fix simple None assignment typing issues
prassanna-ravishankar Sep 25, 2025
7f9e8be
Configure pyright for flexible typing on tests and SDK boundaries
prassanna-ravishankar Sep 25, 2025
eb03f71
Fix ACP factory typing and override method annotations
prassanna-ravishankar Sep 25, 2025
ce8f5ab
Fix CLI handler typing and add tutorial type ignores for readability
prassanna-ravishankar Sep 25, 2025
c8b68de
Fix test imports and exclude tutorials from type checking
prassanna-ravishankar Sep 25, 2025
6d6f4a3
Fix test imports with proper relative imports, remove pythonPath
prassanna-ravishankar Sep 25, 2025
1f82b96
Phase 1: Fix external API boundary typing with strategic type ignores
prassanna-ravishankar Sep 25, 2025
a5cfae0
intermediate cleanup of stash-friendly files
prassanna-ravishankar Sep 25, 2025
0d89ad7
Clean architectural fixes: LLM adapters, temporal client, and OpenAI …
prassanna-ravishankar Sep 25, 2025
bf111af
Clean solutions for core SDK and business logic typing
prassanna-ravishankar Sep 25, 2025
7d1a174
Fix test infrastructure and service architecture issues
prassanna-ravishankar Sep 25, 2025
373e98c
Final clean typing solutions: utilities and service boundaries
prassanna-ravishankar Sep 25, 2025
2999495
COMPLETE: Achieve zero typing errors with final inline ignores
prassanna-ravishankar Sep 25, 2025
ba922e3
intermediate cleanup of stash-friendly files
prassanna-ravishankar Sep 25, 2025
8a8f62f
FINAL: Complete typing cleanup with perfect linting
prassanna-ravishankar Sep 25, 2025
d0f5003
Merge branch 'main' into fix/linting-issues
prassanna-ravishankar Sep 25, 2025
2fdcc1c
Merge branch 'main' into fix/linting-issues
prassanna-ravishankar Sep 30, 2025
f96d492
Add TODO comment for Stainless generator override issue
prassanna-ravishankar Sep 30, 2025
c698a6a
restore async for in litellm calls
prassanna-ravishankar Sep 30, 2025
ec9aeac
fix circular import
prassanna-ravishankar Oct 1, 2025
abec38f
fix tutorial bug
prassanna-ravishankar Oct 1, 2025
c842473
fix: let launch tutorials pass through root .env
prassanna-ravishankar Oct 1, 2025
77e9b5c
Merge main and resolve conflict in base_acp_server.py
prassanna-ravishankar Oct 1, 2025
2633ef0
fix: new ddtrace linting
prassanna-ravishankar Oct 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions examples/launch-tutorials.sh
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,14 @@ run_tutorial() {
print_colored $GREEN "🚀 Executing: cd .. && uv run agentex agents run --manifest examples/$manifest_path"
print_colored $YELLOW "💡 Press Ctrl+C to stop the tutorial"
echo ""

# Run the tutorial directly (need to go to parent dir where uv project is)
(cd .. && uv run agentex agents run --manifest "examples/$manifest_path")
# Load .env file if it exists and pass variables to the subshell
if [[ -f "../.env" ]]; then
(cd .. && set -a && source .env && set +a && uv run agentex agents run --manifest "examples/$manifest_path")
else
(cd .. && uv run agentex agents run --manifest "examples/$manifest_path")
fi

local exit_code=$?
if [[ $exit_code -eq 0 ]]; then
Expand Down
3 changes: 1 addition & 2 deletions examples/tutorials/00_sync/000_hello_acp/dev.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@
"outputs": [],
"source": [
"# Test streaming response\n",
"from agentex.types.task_message_update import StreamTaskMessageDelta, StreamTaskMessageFull\n",
"from agentex.types.text_delta import TextDelta\n",
"\n",
"from agentex.types.task_message_update import StreamTaskMessageFull, StreamTaskMessageDelta\n",
"\n",
"# The result object of message/send will be a TaskMessageUpdate which is a union of the following types:\n",
"# - StreamTaskMessageStart: \n",
Expand Down
19 changes: 13 additions & 6 deletions examples/tutorials/00_sync/000_hello_acp/project/acp.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from typing import AsyncGenerator, Union
from agentex.lib.sdk.fastacp.fastacp import FastACP
from agentex.lib.types.acp import SendMessageParams
from typing import Union, AsyncGenerator

from agentex.types.task_message_update import TaskMessageUpdate
from agentex.lib.types.acp import SendMessageParams
from agentex.lib.utils.logging import make_logger
from agentex.types.task_message import TaskMessageContent
from agentex.lib.sdk.fastacp.fastacp import FastACP
from agentex.types.task_message_update import TaskMessageUpdate
from agentex.types.task_message_content import TextContent
from agentex.lib.utils.logging import make_logger

logger = make_logger(__name__)

Expand All @@ -21,8 +21,15 @@ async def handle_message_send(
params: SendMessageParams
) -> Union[TaskMessageContent, AsyncGenerator[TaskMessageUpdate, None]]:
"""Default message handler with streaming support"""
# Extract content safely from the message
message_text = ""
if hasattr(params.content, 'content'):
content_val = getattr(params.content, 'content', '')
if isinstance(content_val, str):
message_text = content_val

return TextContent(
author="agent",
content=f"Hello! I've received your message. Here's a generic response, but in future tutorials we'll see how you can get me to intelligently respond to your message. This is what I heard you say: {params.content.content}",
content=f"Hello! I've received your message. Here's a generic response, but in future tutorials we'll see how you can get me to intelligently respond to your message. This is what I heard you say: {message_text}",
)

3 changes: 1 addition & 2 deletions examples/tutorials/00_sync/010_multiturn/dev.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@
"outputs": [],
"source": [
"# Test streaming response\n",
"from agentex.types.task_message_update import StreamTaskMessageDelta, StreamTaskMessageFull\n",
"from agentex.types.text_delta import TextDelta\n",
"\n",
"from agentex.types.task_message_update import StreamTaskMessageFull, StreamTaskMessageDelta\n",
"\n",
"# The result object of message/send will be a TaskMessageUpdate which is a union of the following types:\n",
"# - StreamTaskMessageStart: \n",
Expand Down
22 changes: 11 additions & 11 deletions examples/tutorials/00_sync/010_multiturn/project/acp.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import os
from typing import AsyncGenerator, Union
from typing import Union, AsyncGenerator

from agentex.lib import adk
from agentex.lib.sdk.fastacp.fastacp import FastACP
from agentex.lib.types.acp import SendMessageParams
from agentex.lib.types.llm_messages import AssistantMessage, LLMConfig, SystemMessage, UserMessage
from agentex.types.task_message_update import TaskMessageUpdate
from agentex.types.task_message import TaskMessageContent
from agentex.types.task_message_content import TextContent
from agentex.lib.utils.model_utils import BaseModel
from agentex.lib.types.llm_messages import LLMConfig, UserMessage, SystemMessage, AssistantMessage
from agentex.lib.sdk.fastacp.fastacp import FastACP
from agentex.types.task_message_update import TaskMessageUpdate
from agentex.types.task_message_content import TextContent

# Create an ACP server
acp = FastACP.create(
Expand All @@ -33,11 +33,11 @@ async def handle_message_send(
# 0. Validate the message.
#########################################################

if params.content.type != "text":
raise ValueError(f"Expected text message, got {params.content.type}")
if not hasattr(params.content, 'type') or params.content.type != "text":
raise ValueError(f"Expected text message, got {getattr(params.content, 'type', 'unknown')}")

if params.content.author != "user":
raise ValueError(f"Expected user message, got {params.content.author}")
if not hasattr(params.content, 'author') or params.content.author != "user":
raise ValueError(f"Expected user message, got {getattr(params.content, 'author', 'unknown')}")

if not os.environ.get("OPENAI_API_KEY"):
return TextContent(
Expand Down Expand Up @@ -74,9 +74,9 @@ async def handle_message_send(
llm_messages = [
SystemMessage(content=state.system_prompt),
*[
UserMessage(content=message.content.content) if message.content.author == "user" else AssistantMessage(content=message.content.content)
UserMessage(content=getattr(message.content, 'content', '')) if getattr(message.content, 'author', None) == "user" else AssistantMessage(content=getattr(message.content, 'content', ''))
for message in task_messages
if message.content.type == "text"
if getattr(message.content, 'type', None) == "text"
]
]

Expand Down
3 changes: 1 addition & 2 deletions examples/tutorials/00_sync/020_streaming/dev.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@
"outputs": [],
"source": [
"# Test streaming response\n",
"from agentex.types.task_message_update import StreamTaskMessageDelta, StreamTaskMessageFull\n",
"from agentex.types.text_delta import TextDelta\n",
"\n",
"from agentex.types.task_message_update import StreamTaskMessageFull, StreamTaskMessageDelta\n",
"\n",
"# The result object of message/send will be a TaskMessageUpdate which is a union of the following types:\n",
"# - StreamTaskMessageStart: \n",
Expand Down
31 changes: 18 additions & 13 deletions examples/tutorials/00_sync/020_streaming/project/acp.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import os
from typing import AsyncGenerator, Union
from typing import Union, AsyncGenerator

from agentex.lib import adk
from agentex.lib.sdk.fastacp.fastacp import FastACP
from agentex.lib.types.acp import SendMessageParams
from agentex.lib.types.llm_messages import AssistantMessage, LLMConfig, SystemMessage, UserMessage
from agentex.types.task_message_update import StreamTaskMessageDelta, StreamTaskMessageDone, StreamTaskMessageFull, TaskMessageUpdate
from agentex.types.task_message_delta import TextDelta
from agentex.lib.utils.model_utils import BaseModel
from agentex.types.task_message_content import TaskMessageContent, TextContent
from agentex.lib.types.llm_messages import LLMConfig, UserMessage, SystemMessage, AssistantMessage
from agentex.lib.sdk.fastacp.fastacp import FastACP
from agentex.types.task_message_delta import TextDelta
from agentex.types.task_message_update import (
TaskMessageUpdate,
StreamTaskMessageDone,
StreamTaskMessageFull,
StreamTaskMessageDelta,
)
from agentex.types.task_message_content import TextContent, TaskMessageContent

# Create an ACP server
acp = FastACP.create(
Expand Down Expand Up @@ -36,11 +41,11 @@ async def handle_message_send(
if not params.content:
return

if params.content.type != "text":
raise ValueError(f"Expected text message, got {params.content.type}")
if not hasattr(params.content, 'type') or params.content.type != "text":
raise ValueError(f"Expected text message, got {getattr(params.content, 'type', 'unknown')}")

if params.content.author != "user":
raise ValueError(f"Expected user message, got {params.content.author}")
if not hasattr(params.content, 'author') or params.content.author != "user":
raise ValueError(f"Expected user message, got {getattr(params.content, 'author', 'unknown')}")

if not os.environ.get("OPENAI_API_KEY"):
yield StreamTaskMessageFull(
Expand All @@ -67,9 +72,9 @@ async def handle_message_send(
llm_messages = [
SystemMessage(content=state.system_prompt),
*[
UserMessage(content=message.content.content) if message.content.author == "user" else AssistantMessage(content=message.content.content)
UserMessage(content=getattr(message.content, 'content', '')) if getattr(message.content, 'author', None) == "user" else AssistantMessage(content=getattr(message.content, 'content', ''))
for message in task_messages
if message.content and message.content.type == "text"
if message.content and getattr(message.content, 'type', None) == "text"
]
]

Expand All @@ -92,7 +97,7 @@ async def handle_message_send(
yield StreamTaskMessageDelta(
type="delta",
index=message_index,
delta=TextDelta(text_delta=chunk.choices[0].delta.content or ""),
delta=TextDelta(type="text", text_delta=chunk.choices[0].delta.content or ""),
)

yield StreamTaskMessageDone(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import json

from agentex.lib import adk
from agentex.lib.sdk.fastacp.fastacp import FastACP
from agentex.lib.types.acp import SendEventParams, CancelTaskParams, CreateTaskParams
from agentex.lib.types.fastacp import AgenticACPConfig
from agentex.lib.types.acp import CancelTaskParams, CreateTaskParams, SendEventParams

from agentex.types.text_content import TextContent
from agentex.lib.utils.logging import make_logger
from agentex.types.text_content import TextContent
from agentex.lib.sdk.fastacp.fastacp import FastACP

logger = make_logger(__name__)

Expand Down
39 changes: 25 additions & 14 deletions examples/tutorials/10_agentic/00_base/010_multiturn/project/acp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@
from typing import List

from agentex.lib import adk
from agentex.lib.core.tracing.tracing_processor_manager import (
add_tracing_processor_config,
)
from agentex.lib.sdk.fastacp.fastacp import FastACP
from agentex.lib.types.acp import CancelTaskParams, CreateTaskParams, SendEventParams
from agentex.lib.types.acp import SendEventParams, CancelTaskParams, CreateTaskParams
from agentex.lib.types.fastacp import AgenticACPConfig
from agentex.lib.types.tracing import SGPTracingProcessorConfig
from agentex.lib.utils.logging import make_logger
from agentex.types.text_content import TextContent
from agentex.lib.utils.model_utils import BaseModel
from agentex.lib.types.llm_messages import (
AssistantMessage,
LLMConfig,
Message,
SystemMessage,
LLMConfig,
UserMessage,
SystemMessage,
AssistantMessage,
)
from agentex.lib.sdk.fastacp.fastacp import FastACP
from agentex.lib.core.tracing.tracing_processor_manager import (
add_tracing_processor_config,
)
from agentex.lib.types.tracing import SGPTracingProcessorConfig
from agentex.lib.utils.logging import make_logger
from agentex.lib.utils.model_utils import BaseModel
from agentex.types.text_content import TextContent

logger = make_logger(__name__)

Expand Down Expand Up @@ -97,13 +97,21 @@ async def handle_event_send(params: SendEventParams):
#########################################################

task_state = await adk.state.get_by_task_and_agent(task_id=params.task.id, agent_id=params.agent.id)
if not task_state:
raise ValueError("Task state not found - ensure task was properly initialized")
state = StateModel.model_validate(task_state.state)

#########################################################
# 6. (👋) Add the new user message to the message history
#########################################################

state.messages.append(UserMessage(content=params.event.content.content))
# Safely extract content from the event
content_text = ""
if hasattr(params.event.content, 'content'):
content_val = getattr(params.event.content, 'content', '')
if isinstance(content_val, str):
content_text = content_val
state.messages.append(UserMessage(content=content_text))

#########################################################
# 7. (👋) Call an LLM to respond to the user's message
Expand All @@ -114,7 +122,10 @@ async def handle_event_send(params: SendEventParams):
llm_config=LLMConfig(model="gpt-4o-mini", messages=state.messages),
trace_id=params.task.id,
)
state.messages.append(AssistantMessage(content=chat_completion.choices[0].message.content))
response_content = ""
if chat_completion.choices[0].message:
response_content = chat_completion.choices[0].message.content or ""
state.messages.append(AssistantMessage(content=response_content))

#########################################################
# 8. (👋) Send agent response to client
Expand Down
26 changes: 20 additions & 6 deletions examples/tutorials/10_agentic/00_base/020_streaming/project/acp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
from typing import List

from agentex.lib import adk
from agentex.lib.sdk.fastacp.fastacp import FastACP
from agentex.lib.types.acp import CancelTaskParams, CreateTaskParams, SendEventParams
from agentex.lib.types.acp import SendEventParams, CancelTaskParams, CreateTaskParams
from agentex.lib.types.fastacp import AgenticACPConfig
from agentex.lib.types.llm_messages import AssistantMessage, LLMConfig, Message, SystemMessage, UserMessage
from agentex.lib.utils.logging import make_logger
from agentex.lib.utils.model_utils import BaseModel
from agentex.types.text_content import TextContent
from agentex.lib.utils.model_utils import BaseModel
from agentex.lib.types.llm_messages import Message, LLMConfig, UserMessage, SystemMessage, AssistantMessage
from agentex.lib.sdk.fastacp.fastacp import FastACP

logger = make_logger(__name__)

Expand Down Expand Up @@ -82,13 +82,21 @@ async def handle_event_send(params: SendEventParams):
#########################################################

task_state = await adk.state.get_by_task_and_agent(task_id=params.task.id, agent_id=params.agent.id)
if not task_state:
raise ValueError("Task state not found - ensure task was properly initialized")
state = StateModel.model_validate(task_state.state)

#########################################################
# 6. Add the new user message to the message history
#########################################################

state.messages.append(UserMessage(content=params.event.content.content))
# Safely extract content from the event
content_text = ""
if hasattr(params.event.content, 'content'):
content_val = getattr(params.event.content, 'content', '')
if isinstance(content_val, str):
content_text = content_val
state.messages.append(UserMessage(content=content_text))

#########################################################
# 7. (👋) Call an LLM to respond to the user's message
Expand All @@ -109,7 +117,13 @@ async def handle_event_send(params: SendEventParams):
trace_id=params.task.id,
)

state.messages.append(AssistantMessage(content=task_message.content.content))
# Safely extract content from the task message
response_text = ""
if task_message.content and hasattr(task_message.content, 'content'): # type: ignore[union-attr]
content_val = getattr(task_message.content, 'content', '') # type: ignore[union-attr]
if isinstance(content_val, str):
response_text = content_val
state.messages.append(AssistantMessage(content=response_text))

#########################################################
# 8. Store the messages in the task state for the next turn
Expand Down
Loading