Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ class FeedbackPoint(BaseModel):
# Model representing the structured analysis of the customer feedback call
class CallFeedbackOutput(BaseModel):
"""Structured analysis of the customer feedback call."""
positive_points: List[FeedbackPoint] = Field(
positive_points: list[FeedbackPoint] = Field(
default_factory=list,
description="List of positive feedback points, each with a supporting quote."
)
negative_points: List[FeedbackPoint] = Field(
negative_points: list[FeedbackPoint] = Field(
default_factory=list,
description="List of negative feedback points, each with a supporting quote."
)
Expand Down Expand Up @@ -267,7 +267,6 @@ async for chunk in analyze_call_feedback(feedback_input):
> For example, a function with the signature `async def foo() -> AsyncIterator[int]` may be called
> `async for c in await foo():...` in certain cases...


#### Streaming the run object

Use `AsyncIterator[Run[Output]]` to get the **run** object as it is generated, which allows you, for the **last chunk**, to access the cost and duration of the run.
Expand Down Expand Up @@ -331,7 +330,7 @@ class PDFQuestionInput(BaseModel):

class PDFAnswerOutput(BaseModel):
answer: str = Field(description="The answer to the question based on the PDF content")
quotes: List[str] = Field(description="Relevant quotes from the PDF that support the answer")
quotes: list[str] = Field(description="Relevant quotes from the PDF that support the answer")

@workflowai.agent(id="pdf-answer", model=Model.CLAUDE_3_5_SONNET_LATEST)
async def answer_pdf_question(input: PDFQuestionInput) -> PDFAnswerOutput:
Expand Down Expand Up @@ -610,8 +609,8 @@ values.

```python
class CallFeedbackOutputStrict(BaseModel):
positive_points: List[FeedbackPoint]
negative_points: List[FeedbackPoint]
positive_points: list[FeedbackPoint]
negative_points: list[FeedbackPoint]

@workflowai.agent()
async def analyze_call_feedback_strict(input: CallFeedbackInput) -> CallFeedbackOutputStrict:
Expand All @@ -628,8 +627,8 @@ except WorkflowAIError as e:
print(e.code) # "invalid_generation" error code means that the generation did not match the schema

class CallFeedbackOutputTolerant(BaseModel):
positive_points: List[FeedbackPoint] = Field(default_factory=list)
negative_points: List[FeedbackPoint] = Field(default_factory=list)
positive_points: list[FeedbackPoint] = Field(default_factory=list)
negative_points: list[FeedbackPoint] = Field(default_factory=list)

@workflowai.agent()
async def analyze_call_feedback_tolerant(input: CallFeedbackInput) -> CallFeedbackOutputTolerant:
Expand Down
3 changes: 1 addition & 2 deletions examples/08_pdf_agent.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import asyncio
import os
from typing import List

from dotenv import load_dotenv
from pydantic import BaseModel, Field # pyright: ignore [reportUnknownVariableType]
Expand All @@ -18,7 +17,7 @@ class PDFQuestionInput(BaseModel):

class PDFAnswerOutput(BaseModel):
answer: str = Field(description="The answer to the question based on the PDF content")
quotes: List[str] = Field(description="Relevant quotes from the PDF that support the answer")
quotes: list[str] = Field(description="Relevant quotes from the PDF that support the answer")


@workflowai.agent(id="pdf-answer", model=Model.CLAUDE_3_5_SONNET_LATEST)
Expand Down
12 changes: 9 additions & 3 deletions examples/11_ecommerce_chatbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import asyncio
from enum import Enum
from typing import List, Optional
from typing import Optional

from pydantic import BaseModel, Field

Expand All @@ -18,12 +18,14 @@

class Role(str, Enum):
"""Enum representing possible message roles."""

USER = "user"
ASSISTANT = "assistant"


class Product(BaseModel):
"""Model representing a product recommendation."""

name: str = Field(
description="Name of the product",
examples=["Wireless Noise-Cancelling Headphones", "4K Smart TV"],
Expand Down Expand Up @@ -56,6 +58,7 @@ class Product(BaseModel):

class Message(BaseModel):
"""Model representing a chat message."""

role: Role = Field()
content: str = Field(
description="The content of the message",
Expand All @@ -64,28 +67,31 @@ class Message(BaseModel):
"Based on your requirements, here are some great headphone options...",
],
)
recommended_products: Optional[List[Product]] = Field(
recommended_products: Optional[list[Product]] = Field(
default=None,
description="Product recommendations included with this message, if any",
)


class AssistantMessage(Message):
"""Model representing a message from the assistant."""

role: Role = Role.ASSISTANT
content: str = ""


class ChatbotOutput(BaseModel):
"""Output model for the chatbot response."""

assistant_message: AssistantMessage = Field(
description="The chatbot's response message",
)


class ChatInput(BaseModel):
"""Input model containing the user's message and conversation history."""
conversation_history: Optional[List[Message]] = Field(

conversation_history: Optional[list[Message]] = Field(
default=None,
description="Previous messages in the conversation, if any",
)
Expand Down
15 changes: 11 additions & 4 deletions examples/13_rag.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import asyncio
from enum import Enum
from typing import List, Optional
from typing import Optional

from pydantic import BaseModel, Field

Expand All @@ -22,12 +22,14 @@

class Role(str, Enum):
"""Enum representing possible message roles."""

USER = "user"
ASSISTANT = "assistant"


class SearchResult(BaseModel):
"""Model representing a search result from the knowledge base."""

content: str = Field(
description="The content of the search result",
)
Expand All @@ -38,7 +40,7 @@ class SearchResult(BaseModel):

# Simulated knowledge base search tool
# ruff: noqa: ARG001
async def search_faq(query: str) -> List[SearchResult]:
async def search_faq(query: str) -> list[SearchResult]:
"""
Search the knowledge base for relevant information.

Expand Down Expand Up @@ -79,6 +81,7 @@ async def search_faq(query: str) -> List[SearchResult]:

class Message(BaseModel):
"""Model representing a chat message."""

role: Role
content: str = Field(
description="The content of the message",
Expand All @@ -87,20 +90,24 @@ class Message(BaseModel):

class AssistantMessage(Message):
"""Model representing a message from the assistant."""

role: Role = Role.ASSISTANT
content: str = ""


class ChatbotOutput(BaseModel):
"""Output model for the chatbot response."""
assistant_message: AssistantMessage = Field(default_factory=AssistantMessage,

assistant_message: AssistantMessage = Field(
default_factory=AssistantMessage,
description="The chatbot's response message",
)


class ChatInput(BaseModel):
"""Input model containing the user's message and conversation history."""
conversation_history: Optional[List[Message]] = Field(

conversation_history: Optional[list[Message]] = Field(
default=None,
description="Previous messages in the conversation, if any",
)
Expand Down
5 changes: 2 additions & 3 deletions examples/workflows/chain_of_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"""

import asyncio
from typing import List

from pydantic import BaseModel, Field # pyright: ignore [reportUnknownVariableType]

Expand Down Expand Up @@ -47,7 +46,7 @@ class WorkerOutput(BaseModel):
findings: str = Field(
description="Key findings and information extracted from this chunk.",
)
evidence: List[str] = Field(
evidence: list[str] = Field(
default_factory=list,
description="Supporting evidence or quotes from the chunk.",
)
Expand All @@ -70,7 +69,7 @@ class ManagerOutput(BaseModel):

answer: str = Field(description="The final answer to the query.")
reasoning: str = Field(description="Explanation of how the answer was derived.")
supporting_evidence: List[str] = Field(
supporting_evidence: list[str] = Field(
default_factory=list,
description="Key evidence supporting the answer.",
)
Expand Down
10 changes: 5 additions & 5 deletions examples/workflows/evaluator_optimizer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import asyncio
from typing import List, TypedDict
from typing import TypedDict

from pydantic import BaseModel, Field # pyright: ignore [reportUnknownVariableType]

Expand Down Expand Up @@ -45,8 +45,8 @@ class TranslationEvaluationOutput(BaseModel):
preserves_tone: bool = Field(description="Whether the translation preserves the original tone.")
preserves_nuance: bool = Field(description="Whether the translation preserves subtle nuances.")
culturally_accurate: bool = Field(description="Whether the translation is culturally appropriate.")
specific_issues: List[str] = Field(description="List of specific issues identified.")
improvement_suggestions: List[str] = Field(description="List of suggested improvements.")
specific_issues: list[str] = Field(description="List of specific issues identified.")
improvement_suggestions: list[str] = Field(description="List of suggested improvements.")


# Uses O1 for its strong analytical and evaluation capabilities
Expand All @@ -65,8 +65,8 @@ class TranslationImprovementInput(BaseModel):
original_text: str = Field(description="The original text.")
current_translation: str = Field(description="The current translation.")
target_language: str = Field(description="The target language.")
specific_issues: List[str] = Field(description="Issues to address.")
improvement_suggestions: List[str] = Field(description="Suggestions for improvement.")
specific_issues: list[str] = Field(description="Issues to address.")
improvement_suggestions: list[str] = Field(description="Suggestions for improvement.")


class TranslationImprovementOutput(BaseModel):
Expand Down
8 changes: 4 additions & 4 deletions examples/workflows/orchestrator_worker.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import asyncio
from enum import Enum
from typing import List, TypedDict
from typing import TypedDict

from pydantic import BaseModel, Field # pyright: ignore [reportUnknownVariableType]

Expand Down Expand Up @@ -37,7 +37,7 @@ class ImplementationPlanInput(BaseModel):
class ImplementationPlanOutput(BaseModel):
"""Output containing the implementation plan."""

files: List[FileChange] = Field(description="List of files to be changed.")
files: list[FileChange] = Field(description="List of files to be changed.")
estimated_complexity: ComplexityLevel = Field(description="Estimated complexity of the implementation.")


Expand Down Expand Up @@ -86,7 +86,7 @@ class ImplementationChange(TypedDict):

class FeatureImplementationResult(TypedDict):
plan: ImplementationPlanOutput
changes: List[ImplementationChange]
changes: list[ImplementationChange]


async def implement_feature(feature_request: str) -> FeatureImplementationResult:
Expand Down Expand Up @@ -117,7 +117,7 @@ async def implement_feature(feature_request: str) -> FeatureImplementationResult
)

# Combine results
changes: List[ImplementationChange] = [
changes: list[ImplementationChange] = [
{
"file": implementation_plan.files[i],
"implementation": change,
Expand Down
14 changes: 7 additions & 7 deletions examples/workflows/parallel_processing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import asyncio
from enum import Enum
from typing import List, TypedDict
from typing import TypedDict

from pydantic import BaseModel, Field # pyright: ignore [reportUnknownVariableType]

Expand All @@ -23,9 +23,9 @@ class SecurityReviewInput(BaseModel):
class SecurityReviewOutput(BaseModel):
"""Output from security code review."""

vulnerabilities: List[str] = Field(description="List of identified security vulnerabilities.")
vulnerabilities: list[str] = Field(description="List of identified security vulnerabilities.")
risk_level: RiskLevel = Field(description="Overall security risk level.")
suggestions: List[str] = Field(description="Security improvement suggestions.")
suggestions: list[str] = Field(description="Security improvement suggestions.")


# Uses Claude 3.5 Sonnet for its strong security analysis capabilities
Expand All @@ -47,9 +47,9 @@ class PerformanceReviewInput(BaseModel):
class PerformanceReviewOutput(BaseModel):
"""Output from performance code review."""

issues: List[str] = Field(description="List of identified performance issues.")
issues: list[str] = Field(description="List of identified performance issues.")
impact: RiskLevel = Field(description="Impact level of performance issues.")
optimizations: List[str] = Field(description="Performance optimization suggestions.")
optimizations: list[str] = Field(description="Performance optimization suggestions.")


# Uses O1 Mini for its expertise in performance optimization
Expand All @@ -71,9 +71,9 @@ class MaintainabilityReviewInput(BaseModel):
class MaintainabilityReviewOutput(BaseModel):
"""Output from maintainability code review."""

concerns: List[str] = Field(description="List of maintainability concerns.")
concerns: list[str] = Field(description="List of maintainability concerns.")
quality_score: int = Field(description="Code quality score (1-10).", ge=1, le=10)
recommendations: List[str] = Field(description="Maintainability improvement recommendations.")
recommendations: list[str] = Field(description="Maintainability improvement recommendations.")


# Uses Claude 3.5 Sonnet for its strong code quality and readability analysis
Expand Down
Loading