Skip to content

Commit b32ec53

Browse files
authored
Drop python 3.9 support (#434)
1 parent 2535e1f commit b32ec53

File tree

65 files changed

+376
-1462
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+376
-1462
lines changed

.changeset/loud-dingos-repair.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"llama-agents-client": minor
3+
"llama-agents-dbos": minor
4+
"llama-agents-server": minor
5+
"llama-index-utils-workflow": minor
6+
"llama-index-workflows": minor
7+
---
8+
9+
Drop python 3.9 support

.github/workflows/test.yml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
strategy:
1717
fail-fast: false
1818
matrix:
19-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
19+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
2020
package:
2121
[
2222
llama-index-workflows,
@@ -28,14 +28,7 @@ jobs:
2828
"llama-agents-dbos"
2929
]
3030
exclude:
31-
- package: llama-agents-dbos
32-
python-version: "3.9"
33-
# Integration tests on 3.14 run in test-docker job with cross-package coverage
34-
- package: llama-agents-integration-tests
35-
python-version: "3.9"
3631
# Dev CLI only needs to run on 3.14
37-
- package: llama-agents-dev
38-
python-version: "3.9"
3932
- package: llama-agents-dev
4033
python-version: "3.10"
4134
- package: llama-agents-dev

docs/api_docs/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ name = "docs"
77
version = "0.1.0"
88
description = ""
99
authors = [{name = "Your Name", email = "you@example.com"}]
10-
requires-python = ">=3.9"
10+
requires-python = ">=3.10"
1111
readme = "README.md"
1212
dependencies = [
1313
"llama-index-workflows[server,client]",

examples/agent.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
"metadata": {},
102102
"outputs": [],
103103
"source": [
104-
"from typing import Any, List\n",
104+
"from typing import Any\n",
105105
"\n",
106106
"from llama_index.core.llms.function_calling import FunctionCallingLLM\n",
107107
"from llama_index.core.memory import ChatMemoryBuffer\n",
@@ -120,7 +120,7 @@
120120
" def __init__(\n",
121121
" self,\n",
122122
" llm: FunctionCallingLLM | None = None,\n",
123-
" tools: List[BaseTool] | None = None,\n",
123+
" tools: list[BaseTool] | None = None,\n",
124124
" **workflow_kwargs: Any,\n",
125125
" ) -> None:\n",
126126
" super().__init__(**workflow_kwargs)\n",

examples/k8s-otel/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "k8s-otel-example"
33
version = "0.0.0"
4-
requires-python = ">=3.9"
4+
requires-python = ">=3.10"
55
dependencies = [
66
"llama-agents-dbos",
77
"opentelemetry-exporter-otlp",

examples/observability/workflows_observability_pt1.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@
182182
"import os\n",
183183
"from os import linesep\n",
184184
"from pathlib import Path\n",
185-
"from typing import Callable, Optional, Sequence\n",
185+
"from typing import Callable, Sequence\n",
186186
"\n",
187187
"from llama_index.observability.otel import LlamaIndexOpenTelemetry\n",
188188
"from opentelemetry.sdk.trace import ReadableSpan\n",
@@ -200,7 +200,7 @@
200200
" def __init__(\n",
201201
" self,\n",
202202
" service_name: str | None = None,\n",
203-
" file_path: Optional[os.PathLike[str]] = None,\n",
203+
" file_path: os.PathLike[str] | None = None,\n",
204204
" formatter: Callable[[ReadableSpan], str] = lambda span: json.dumps(\n",
205205
" json.loads(span.to_json())\n",
206206
" )\n",

examples/observability/workflows_observability_pt2.ipynb

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
"import os\n",
9696
"from os import linesep\n",
9797
"from pathlib import Path\n",
98-
"from typing import Callable, Optional, Sequence\n",
98+
"from typing import Callable, Sequence\n",
9999
"\n",
100100
"from llama_index.observability.otel import LlamaIndexOpenTelemetry\n",
101101
"from opentelemetry.sdk.trace import ReadableSpan\n",
@@ -113,7 +113,7 @@
113113
" def __init__(\n",
114114
" self,\n",
115115
" service_name: str | None = None,\n",
116-
" file_path: Optional[os.PathLike[str]] = None,\n",
116+
" file_path: os.PathLike[str] | None = None,\n",
117117
" formatter: Callable[[ReadableSpan], str] = lambda span: json.dumps(\n",
118118
" json.loads(span.to_json())\n",
119119
" )\n",
@@ -186,7 +186,7 @@
186186
},
187187
"outputs": [],
188188
"source": [
189-
"from typing import Dict, List, Literal\n",
189+
"from typing import Literal\n",
190190
"\n",
191191
"from workflows.events import (\n",
192192
" Event,\n",
@@ -208,20 +208,20 @@
208208
"\n",
209209
" sender_details: str\n",
210210
" support_category: Literal[\"technical\", \"sales\", \"general_information\"]\n",
211-
" support_questions: List[str]\n",
211+
" support_questions: list[str]\n",
212212
" extra_information: str\n",
213213
"\n",
214214
"\n",
215215
"class QuestionEvent(Event):\n",
216216
" \"\"\"Event containing one or more questions to retrieve information from the company database.\"\"\"\n",
217217
"\n",
218-
" questions: List[str]\n",
218+
" questions: list[str]\n",
219219
"\n",
220220
"\n",
221221
"class RetrievalEvent(Event):\n",
222222
" \"\"\"Event that contains the retrieved information\"\"\"\n",
223223
"\n",
224-
" information: Dict[str, str]\n",
224+
" information: dict[str, str]\n",
225225
"\n",
226226
"\n",
227227
"class CandidateEmailEvent(InputRequiredEvent):\n",
@@ -338,16 +338,16 @@
338338
"class SenderDetails(BaseModel):\n",
339339
" name: str = Field(description=\"Name of the sender seeking support\")\n",
340340
" email_address: str = Field(description=\"Email address of the sender\")\n",
341-
" company: Optional[str] = Field(\n",
341+
" company: str | None = Field(\n",
342342
" descrption=\"Company for which the sender works\", default=None\n",
343343
" )\n",
344-
" role: Optional[str] = Field(descrption=\"Job role of the sender\", default=None)\n",
344+
" role: str | None = Field(descrption=\"Job role of the sender\", default=None)\n",
345345
"\n",
346346
"\n",
347347
"class SupportEmailInformation(BaseModel):\n",
348348
" sender_details: SenderDetails\n",
349349
" support_category: Literal[\"technical\", \"sales\", \"general_information\"]\n",
350-
" support_questions: List[str]\n",
350+
" support_questions: list[str]\n",
351351
" extra_information: str"
352352
]
353353
},
@@ -496,7 +496,7 @@
496496
},
497497
"outputs": [],
498498
"source": [
499-
"files: List[dict] = []\n",
499+
"files: list[dict] = []\n",
500500
"fls = [os.path.join(\"data\", f) for f in os.listdir(\"data/\")]\n",
501501
"\n",
502502
"file_ids = []\n",
@@ -535,7 +535,7 @@
535535
"\n",
536536
"\n",
537537
"class SupportQuestions(BaseModel):\n",
538-
" questions: List[str] = Field(\n",
538+
" questions: list[str] = Field(\n",
539539
" description=\"Support questions to ask within the company database to retrieve the most information about the users' requests\"\n",
540540
" )\n",
541541
"\n",
@@ -604,7 +604,7 @@
604604
"outputs": [],
605605
"source": [
606606
"import uuid\n",
607-
"from typing import Annotated, Union\n",
607+
"from typing import Annotated\n",
608608
"\n",
609609
"from llama_cloud_services.extract import SourceText\n",
610610
"from llama_index.core.llms import ChatMessage\n",
@@ -620,7 +620,7 @@
620620
" event: EmailEvent,\n",
621621
" ctx: Context[WorkflowState],\n",
622622
" extraction_agent: Annotated[ExtractionAgent, Resource(get_extract_agent)],\n",
623-
" ) -> Union[InformationExtractionEvent, SendEmailEvent]:\n",
623+
" ) -> InformationExtractionEvent | SendEmailEvent:\n",
624624
" extracted_content = await extraction_agent.aextract(\n",
625625
" files=SourceText(\n",
626626
" text_content=text, filename=f\"support_email_{str(uuid.uuid4())}.txt\"\n",
@@ -656,7 +656,7 @@
656656
" event: InformationExtractionEvent,\n",
657657
" ctx: Context[WorkflowState],\n",
658658
" llm: Annotated[StructuredLLM, Resource(get_llm)],\n",
659-
" ) -> Union[QuestionEvent, SendEmailEvent]:\n",
659+
" ) -> QuestionEvent | SendEmailEvent:\n",
660660
" response = await llm.achat(\n",
661661
" messages=[\n",
662662
" ChatMessage(\n",
@@ -685,7 +685,7 @@
685685
" ctx: Context[WorkflowState],\n",
686686
" company_database: Annotated[BaseQueryEngine, Resource(get_company_database)],\n",
687687
" ) -> RetrievalEvent:\n",
688-
" q_and_a: Dict[str, str] = {}\n",
688+
" q_and_a: dict[str, str] = {}\n",
689689
" for question in event.questions:\n",
690690
" response = await company_database.aquery(question)\n",
691691
" q_and_a.update({question: response.response or \"\"})\n",
@@ -719,7 +719,7 @@
719719
" @step\n",
720720
" async def send_email_or_restart(\n",
721721
" self, event: HumanFeedbackEvent, ctx: Context[WorkflowState]\n",
722-
" ) -> Union[SendEmailEvent, EmailEvent]:\n",
722+
" ) -> SendEmailEvent | EmailEvent:\n",
723723
" if event.approved:\n",
724724
" state = await ctx.store.get_state()\n",
725725
" return SendEmailEvent(\n",
@@ -1411,7 +1411,7 @@
14111411
"source": [
14121412
"import json\n",
14131413
"import time\n",
1414-
"from typing import Annotated, Union\n",
1414+
"from typing import Annotated\n",
14151415
"\n",
14161416
"from workflows import Context, Workflow, step\n",
14171417
"from workflows.resource import Resource\n",
@@ -1425,7 +1425,7 @@
14251425
" event: EmailEvent,\n",
14261426
" ctx: Context[WorkflowState],\n",
14271427
" extraction_agent: Annotated[ExtractionAgent, Resource(get_extract_agent)],\n",
1428-
" ) -> Union[InformationExtractionEvent, SendEmailEvent]:\n",
1428+
" ) -> InformationExtractionEvent | SendEmailEvent:\n",
14291429
" async with ctx.store.edit_state() as state:\n",
14301430
" state.email_text = event.email_content\n",
14311431
"\n",
@@ -1468,7 +1468,7 @@
14681468
" event: InformationExtractionEvent,\n",
14691469
" ctx: Context[WorkflowState],\n",
14701470
" llm: Annotated[StructuredLLM, Resource(get_llm)],\n",
1471-
" ) -> Union[QuestionEvent, SendEmailEvent]:\n",
1471+
" ) -> QuestionEvent | SendEmailEvent:\n",
14721472
" response = await llm.achat(\n",
14731473
" messages=[\n",
14741474
" ChatMessage(\n",
@@ -1503,7 +1503,7 @@
15031503
" ctx: Context[WorkflowState],\n",
15041504
" company_database: Annotated[BaseQueryEngine, Resource(get_company_database)],\n",
15051505
" ) -> RetrievalEvent:\n",
1506-
" q_and_a: Dict[str, str] = {}\n",
1506+
" q_and_a: dict[str, str] = {}\n",
15071507
" st = time.time()\n",
15081508
" for question in event.questions:\n",
15091509
" response = await company_database.aquery(question)\n",
@@ -1545,7 +1545,7 @@
15451545
" @step\n",
15461546
" async def send_email_or_restart(\n",
15471547
" self, event: HumanFeedbackEvent, ctx: Context[WorkflowState]\n",
1548-
" ) -> Union[SendEmailEvent, EmailEvent]:\n",
1548+
" ) -> SendEmailEvent | EmailEvent:\n",
15491549
" if event.approved:\n",
15501550
" state = await ctx.store.get_state()\n",
15511551
" dispatcher.event(event=WorkflowDoneEvent(error=False))\n",

examples/state_management_with_vector_databases.ipynb

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
"outputs": [],
6666
"source": [
6767
"import json\n",
68-
"from typing import Any, Dict, List\n",
68+
"from typing import Any\n",
6969
"\n",
7070
"from qdrant_client import AsyncQdrantClient, models\n",
7171
"from sentence_transformers import SentenceTransformer\n",
@@ -93,7 +93,7 @@
9393
" )\n",
9494
"\n",
9595
" async def upload(\n",
96-
" self, texts: List[str], metadatas: List[Dict[str, Any]], ids: List[str]\n",
96+
" self, texts: list[str], metadatas: list[dict[str, Any]], ids: list[str]\n",
9797
" ) -> None:\n",
9898
" self._has_vectors = True\n",
9999
" embeddings = self.model.encode(texts).tolist()\n",
@@ -192,7 +192,6 @@
192192
"outputs": [],
193193
"source": [
194194
"from dataclasses import dataclass\n",
195-
"from typing import Optional\n",
196195
"\n",
197196
"from openai import AsyncOpenAI\n",
198197
"from pydantic import BaseModel, Field\n",
@@ -209,11 +208,11 @@
209208
"\n",
210209
"class DeepWikiOutput(BaseModel):\n",
211210
" summary: str = Field(description=\"Summary of the research output\")\n",
212-
" focal_points: List[str] = Field(description=\"Focal points of the research output\")\n",
213-
" references: List[str] = Field(\n",
211+
" focal_points: list[str] = Field(description=\"Focal points of the research output\")\n",
212+
" references: list[str] = Field(\n",
214213
" description=\"References contained in the reseaerch output\", default_factory=list\n",
215214
" )\n",
216-
" similar_topics: List[str] = Field(\n",
215+
" similar_topics: list[str] = Field(\n",
217216
" description=\"Topics similar to the one of the research output\"\n",
218217
" )\n",
219218
"\n",
@@ -222,7 +221,7 @@
222221
"class OpenAILlm:\n",
223222
" llm: AsyncOpenAI\n",
224223
"\n",
225-
" async def deep_wiki(self, message: str, context: Optional[str] = None) -> str:\n",
224+
" async def deep_wiki(self, message: str, context: str | None = None) -> str:\n",
226225
" if not context:\n",
227226
" response = await self.llm.responses.create(\n",
228227
" model=\"gpt-4.1\",\n",
@@ -368,7 +367,7 @@
368367
"\n",
369368
"\n",
370369
"class ContextRelevanceEvent(Event, ContextRelevance):\n",
371-
" context: Optional[str]"
370+
" context: str | None"
372371
]
373372
},
374373
{
@@ -380,7 +379,7 @@
380379
"outputs": [],
381380
"source": [
382381
"import uuid\n",
383-
"from typing import Annotated, Union\n",
382+
"from typing import Annotated\n",
384383
"\n",
385384
"from workflows import Context, Workflow, step\n",
386385
"from workflows.resource import Resource\n",
@@ -391,13 +390,13 @@
391390
" summary: str = Field(\n",
392391
" description=\"Summary of the research output\", default_factory=str\n",
393392
" )\n",
394-
" focal_points: List[str] = Field(\n",
393+
" focal_points: list[str] = Field(\n",
395394
" description=\"Focal points of the research output\", default_factory=list\n",
396395
" )\n",
397-
" references: List[str] = Field(\n",
396+
" references: list[str] = Field(\n",
398397
" description=\"References contained in the reseaerch output\", default_factory=list\n",
399398
" )\n",
400-
" similar_topics: List[str] = Field(\n",
399+
" similar_topics: list[str] = Field(\n",
401400
" description=\"Topics similar to the one of the research output\",\n",
402401
" default_factory=list,\n",
403402
" )\n",
@@ -410,7 +409,7 @@
410409
" ev: ResearchQuestionEvent,\n",
411410
" ctx: Context[WorkflowState],\n",
412411
" vdb: Annotated[QdrantVectorDatabase, Resource(get_vdb)],\n",
413-
" ) -> Union[ContextRelevanceEvent, RetrieveContextEvent]:\n",
412+
" ) -> ContextRelevanceEvent | RetrieveContextEvent:\n",
414413
" ctx.write_event_to_stream(ev)\n",
415414
" async with ctx.store.edit_state() as state:\n",
416415
" state.question = ev.question\n",

packages/llama-agents-client/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ name = "llama-agents-client"
1717
version = "0.2.3"
1818
description = "HTTP client for connecting to and interacting with LlamaIndex workflow servers"
1919
readme = "README.md"
20-
requires-python = ">=3.9"
20+
requires-python = ">=3.10"
2121
dependencies = [
2222
"httpx>=0.28.1,<1",
2323
"llama-index-workflows>=2.15.0,<3.0.0"

packages/llama-agents-client/src/llama_agents/client/client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
AsyncGenerator,
1212
AsyncIterator,
1313
Literal,
14-
Union,
1514
overload,
1615
)
1716

@@ -71,7 +70,7 @@ class _QueuedDone:
7170
pass
7271

7372

74-
_QueueItem = Union[_QueuedEvent, _QueuedError, _QueuedDone]
73+
_QueueItem = _QueuedEvent | _QueuedError | _QueuedDone
7574

7675

7776
class EventStream:

0 commit comments

Comments
 (0)