mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-06-27 18:50:41 +00:00
feat: drop python 3.10 support (#2469)
# What does this PR do? dropped python3.10, updated pyproject and dependencies, and also removed some blocks of code with special handling for enum.StrEnum Closes #2458 Signed-off-by: Charlie Doern <cdoern@redhat.com>
This commit is contained in:
parent
db2cd9e8f3
commit
d12f195f56
32 changed files with 63 additions and 104 deletions
2
.github/actions/setup-runner/action.yml
vendored
2
.github/actions/setup-runner/action.yml
vendored
|
@ -4,7 +4,7 @@ inputs:
|
||||||
python-version:
|
python-version:
|
||||||
description: The Python version to use
|
description: The Python version to use
|
||||||
required: false
|
required: false
|
||||||
default: "3.10"
|
default: "3.11"
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
|
|
2
.github/workflows/integration-tests.yml
vendored
2
.github/workflows/integration-tests.yml
vendored
|
@ -26,7 +26,7 @@ jobs:
|
||||||
# TODO: generate matrix list from tests/integration when fixed
|
# TODO: generate matrix list from tests/integration when fixed
|
||||||
test-type: [agents, inference, datasets, inspect, scoring, post_training, providers, tool_runtime, vector_io]
|
test-type: [agents, inference, datasets, inspect, scoring, post_training, providers, tool_runtime, vector_io]
|
||||||
client-type: [library, http]
|
client-type: [library, http]
|
||||||
python-version: ["3.10", "3.11", "3.12"]
|
python-version: ["3.11", "3.12"]
|
||||||
fail-fast: false # we want to run all tests regardless of failure
|
fail-fast: false # we want to run all tests regardless of failure
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
1
.github/workflows/unit-tests.yml
vendored
1
.github/workflows/unit-tests.yml
vendored
|
@ -25,7 +25,6 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python:
|
python:
|
||||||
- "3.10"
|
|
||||||
- "3.11"
|
- "3.11"
|
||||||
- "3.12"
|
- "3.12"
|
||||||
- "3.13"
|
- "3.13"
|
||||||
|
|
|
@ -4,10 +4,9 @@
|
||||||
# This source code is licensed under the terms described in the LICENSE file in
|
# This source code is licensed under the terms described in the LICENSE file in
|
||||||
# the root directory of this source tree.
|
# the root directory of this source tree.
|
||||||
|
|
||||||
import sys
|
|
||||||
from collections.abc import AsyncIterator
|
from collections.abc import AsyncIterator
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import StrEnum
|
||||||
from typing import Annotated, Any, Literal, Protocol, runtime_checkable
|
from typing import Annotated, Any, Literal, Protocol, runtime_checkable
|
||||||
|
|
||||||
from pydantic import BaseModel, ConfigDict, Field
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
|
@ -40,14 +39,6 @@ from .openai_responses import (
|
||||||
OpenAIResponseText,
|
OpenAIResponseText,
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: use enum.StrEnum when we drop support for python 3.10
|
|
||||||
if sys.version_info >= (3, 11):
|
|
||||||
from enum import StrEnum
|
|
||||||
else:
|
|
||||||
|
|
||||||
class StrEnum(str, Enum):
|
|
||||||
"""Backport of StrEnum for Python 3.10 and below."""
|
|
||||||
|
|
||||||
|
|
||||||
class Attachment(BaseModel):
|
class Attachment(BaseModel):
|
||||||
"""An attachment to an agent turn.
|
"""An attachment to an agent turn.
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
# This source code is licensed under the terms described in the LICENSE file in
|
# This source code is licensed under the terms described in the LICENSE file in
|
||||||
# the root directory of this source tree.
|
# the root directory of this source tree.
|
||||||
|
|
||||||
import sys
|
|
||||||
from collections.abc import AsyncIterator
|
from collections.abc import AsyncIterator
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import (
|
from typing import (
|
||||||
|
@ -37,15 +36,7 @@ register_schema(ToolCall)
|
||||||
register_schema(ToolParamDefinition)
|
register_schema(ToolParamDefinition)
|
||||||
register_schema(ToolDefinition)
|
register_schema(ToolDefinition)
|
||||||
|
|
||||||
# TODO: use enum.StrEnum when we drop support for python 3.10
|
|
||||||
if sys.version_info >= (3, 11):
|
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
else:
|
|
||||||
|
|
||||||
class StrEnum(str, Enum):
|
|
||||||
"""Backport of StrEnum for Python 3.10 and below."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@json_schema_type
|
@json_schema_type
|
||||||
|
|
|
@ -4,21 +4,11 @@
|
||||||
# This source code is licensed under the terms described in the LICENSE file in
|
# This source code is licensed under the terms described in the LICENSE file in
|
||||||
# the root directory of this source tree.
|
# the root directory of this source tree.
|
||||||
|
|
||||||
import sys
|
|
||||||
from enum import Enum
|
from enum import StrEnum
|
||||||
|
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
# TODO: use enum.StrEnum when we drop support for python 3.10
|
|
||||||
if sys.version_info >= (3, 11):
|
|
||||||
from enum import StrEnum
|
|
||||||
else:
|
|
||||||
|
|
||||||
class StrEnum(str, Enum):
|
|
||||||
"""Backport of StrEnum for Python 3.10 and below."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ResourceType(StrEnum):
|
class ResourceType(StrEnum):
|
||||||
model = "model"
|
model = "model"
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
# the root directory of this source tree.
|
# the root directory of this source tree.
|
||||||
|
|
||||||
# TODO: use enum.StrEnum when we drop support for python 3.10
|
# TODO: use enum.StrEnum when we drop support for python 3.10
|
||||||
import sys
|
from enum import StrEnum
|
||||||
from enum import Enum
|
|
||||||
from typing import (
|
from typing import (
|
||||||
Annotated,
|
Annotated,
|
||||||
Any,
|
Any,
|
||||||
|
@ -21,15 +20,6 @@ from llama_stack.apis.common.type_system import ParamType
|
||||||
from llama_stack.apis.resource import Resource, ResourceType
|
from llama_stack.apis.resource import Resource, ResourceType
|
||||||
from llama_stack.schema_utils import json_schema_type, register_schema, webmethod
|
from llama_stack.schema_utils import json_schema_type, register_schema, webmethod
|
||||||
|
|
||||||
if sys.version_info >= (3, 11):
|
|
||||||
from enum import StrEnum
|
|
||||||
else:
|
|
||||||
|
|
||||||
class StrEnum(str, Enum):
|
|
||||||
"""Backport of StrEnum for Python 3.10 and below."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# Perhaps more structure can be imposed on these functions. Maybe they could be associated
|
# Perhaps more structure can be imposed on these functions. Maybe they could be associated
|
||||||
# with standard metrics so they can be rolled up?
|
# with standard metrics so they can be rolled up?
|
||||||
|
|
|
@ -11,7 +11,7 @@ import os
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ def _download_from_manifest(manifest_file: str, max_concurrent_downloads: int):
|
||||||
d = json.load(f)
|
d = json.load(f)
|
||||||
manifest = Manifest(**d)
|
manifest = Manifest(**d)
|
||||||
|
|
||||||
if datetime.now(timezone.utc) > manifest.expires_on.astimezone(timezone.utc):
|
if datetime.now(UTC) > manifest.expires_on.astimezone(UTC):
|
||||||
raise ValueError(f"Manifest URLs have expired on {manifest.expires_on}")
|
raise ValueError(f"Manifest URLs have expired on {manifest.expires_on}")
|
||||||
|
|
||||||
console = Console()
|
console = Console()
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
# the root directory of this source tree.
|
# the root directory of this source tree.
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from typing import Self
|
||||||
|
|
||||||
from pydantic import BaseModel, model_validator
|
from pydantic import BaseModel, model_validator
|
||||||
from typing_extensions import Self
|
|
||||||
|
|
||||||
from .conditions import parse_conditions
|
from .conditions import parse_conditions
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ def build_image(
|
||||||
template_or_config: str,
|
template_or_config: str,
|
||||||
run_config: str | None = None,
|
run_config: str | None = None,
|
||||||
):
|
):
|
||||||
container_base = build_config.distribution_spec.container_image or "python:3.10-slim"
|
container_base = build_config.distribution_spec.container_image or "python:3.11-slim"
|
||||||
|
|
||||||
normal_deps, special_deps = get_provider_dependencies(build_config)
|
normal_deps, special_deps = get_provider_dependencies(build_config)
|
||||||
normal_deps += SERVER_DEPENDENCIES
|
normal_deps += SERVER_DEPENDENCIES
|
||||||
|
|
|
@ -49,7 +49,7 @@ ensure_conda_env_python310() {
|
||||||
local env_name="$1"
|
local env_name="$1"
|
||||||
local pip_dependencies="$2"
|
local pip_dependencies="$2"
|
||||||
local special_pip_deps="$3"
|
local special_pip_deps="$3"
|
||||||
local python_version="3.10"
|
local python_version="3.11"
|
||||||
|
|
||||||
# Check if conda command is available
|
# Check if conda command is available
|
||||||
if ! is_command_available conda; then
|
if ! is_command_available conda; then
|
||||||
|
|
|
@ -99,7 +99,7 @@ class ProviderImpl(Providers):
|
||||||
try:
|
try:
|
||||||
health = await asyncio.wait_for(impl.health(), timeout=timeout)
|
health = await asyncio.wait_for(impl.health(), timeout=timeout)
|
||||||
return api_name, health
|
return api_name, health
|
||||||
except (asyncio.TimeoutError, TimeoutError):
|
except TimeoutError:
|
||||||
return (
|
return (
|
||||||
api_name,
|
api_name,
|
||||||
HealthResponse(
|
HealthResponse(
|
||||||
|
|
|
@ -615,7 +615,7 @@ class InferenceRouter(Inference):
|
||||||
continue
|
continue
|
||||||
health = await asyncio.wait_for(impl.health(), timeout=timeout)
|
health = await asyncio.wait_for(impl.health(), timeout=timeout)
|
||||||
health_statuses[provider_id] = health
|
health_statuses[provider_id] = health
|
||||||
except (asyncio.TimeoutError, TimeoutError):
|
except TimeoutError:
|
||||||
health_statuses[provider_id] = HealthResponse(
|
health_statuses[provider_id] = HealthResponse(
|
||||||
status=HealthStatus.ERROR,
|
status=HealthStatus.ERROR,
|
||||||
message=f"Health check timed out after {timeout} seconds",
|
message=f"Health check timed out after {timeout} seconds",
|
||||||
|
|
|
@ -9,12 +9,12 @@ import time
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from asyncio import Lock
|
from asyncio import Lock
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Self
|
||||||
from urllib.parse import parse_qs
|
from urllib.parse import parse_qs
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
from jose import jwt
|
from jose import jwt
|
||||||
from pydantic import BaseModel, Field, field_validator, model_validator
|
from pydantic import BaseModel, Field, field_validator, model_validator
|
||||||
from typing_extensions import Self
|
|
||||||
|
|
||||||
from llama_stack.distribution.datatypes import AuthenticationConfig, AuthProviderType, User
|
from llama_stack.distribution.datatypes import AuthenticationConfig, AuthProviderType, User
|
||||||
from llama_stack.log import get_logger
|
from llama_stack.log import get_logger
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import UTC, datetime, timedelta
|
||||||
|
|
||||||
from starlette.types import ASGIApp, Receive, Scope, Send
|
from starlette.types import ASGIApp, Receive, Scope, Send
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ class QuotaMiddleware:
|
||||||
|
|
||||||
if int(prev) == 0:
|
if int(prev) == 0:
|
||||||
# Set with expiration datetime when it is the first request in the window.
|
# Set with expiration datetime when it is the first request in the window.
|
||||||
expiration = datetime.now(timezone.utc) + timedelta(seconds=self.window_seconds)
|
expiration = datetime.now(UTC) + timedelta(seconds=self.window_seconds)
|
||||||
await kv.set(key, str(count), expiration=expiration)
|
await kv.set(key, str(count), expiration=expiration)
|
||||||
else:
|
else:
|
||||||
await kv.set(key, str(count))
|
await kv.set(key, str(count))
|
||||||
|
|
|
@ -145,7 +145,7 @@ async def shutdown(app):
|
||||||
await asyncio.wait_for(impl.shutdown(), timeout=5)
|
await asyncio.wait_for(impl.shutdown(), timeout=5)
|
||||||
else:
|
else:
|
||||||
logger.warning("No shutdown method for %s", impl_name)
|
logger.warning("No shutdown method for %s", impl_name)
|
||||||
except (asyncio.TimeoutError, TimeoutError):
|
except TimeoutError:
|
||||||
logger.exception("Shutdown timeout for %s ", impl_name, exc_info=True)
|
logger.exception("Shutdown timeout for %s ", impl_name, exc_info=True)
|
||||||
except (Exception, asyncio.CancelledError) as e:
|
except (Exception, asyncio.CancelledError) as e:
|
||||||
logger.exception("Failed to shutdown %s: %s", impl_name, {e})
|
logger.exception("Failed to shutdown %s: %s", impl_name, {e})
|
||||||
|
|
|
@ -11,7 +11,7 @@ import secrets
|
||||||
import string
|
import string
|
||||||
import uuid
|
import uuid
|
||||||
from collections.abc import AsyncGenerator
|
from collections.abc import AsyncGenerator
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
in_progress_tool_call_step = await self.storage.get_in_progress_tool_call_step(
|
in_progress_tool_call_step = await self.storage.get_in_progress_tool_call_step(
|
||||||
request.session_id, request.turn_id
|
request.session_id, request.turn_id
|
||||||
)
|
)
|
||||||
now = datetime.now(timezone.utc).isoformat()
|
now = datetime.now(UTC).isoformat()
|
||||||
tool_execution_step = ToolExecutionStep(
|
tool_execution_step = ToolExecutionStep(
|
||||||
step_id=(in_progress_tool_call_step.step_id if in_progress_tool_call_step else str(uuid.uuid4())),
|
step_id=(in_progress_tool_call_step.step_id if in_progress_tool_call_step else str(uuid.uuid4())),
|
||||||
turn_id=request.turn_id,
|
turn_id=request.turn_id,
|
||||||
|
@ -267,7 +267,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
start_time = last_turn.started_at
|
start_time = last_turn.started_at
|
||||||
else:
|
else:
|
||||||
messages.extend(request.messages)
|
messages.extend(request.messages)
|
||||||
start_time = datetime.now(timezone.utc).isoformat()
|
start_time = datetime.now(UTC).isoformat()
|
||||||
input_messages = request.messages
|
input_messages = request.messages
|
||||||
|
|
||||||
output_message = None
|
output_message = None
|
||||||
|
@ -298,7 +298,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
input_messages=input_messages,
|
input_messages=input_messages,
|
||||||
output_message=output_message,
|
output_message=output_message,
|
||||||
started_at=start_time,
|
started_at=start_time,
|
||||||
completed_at=datetime.now(timezone.utc).isoformat(),
|
completed_at=datetime.now(UTC).isoformat(),
|
||||||
steps=steps,
|
steps=steps,
|
||||||
)
|
)
|
||||||
await self.storage.add_turn_to_session(request.session_id, turn)
|
await self.storage.add_turn_to_session(request.session_id, turn)
|
||||||
|
@ -389,7 +389,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
return
|
return
|
||||||
|
|
||||||
step_id = str(uuid.uuid4())
|
step_id = str(uuid.uuid4())
|
||||||
shield_call_start_time = datetime.now(timezone.utc).isoformat()
|
shield_call_start_time = datetime.now(UTC).isoformat()
|
||||||
try:
|
try:
|
||||||
yield AgentTurnResponseStreamChunk(
|
yield AgentTurnResponseStreamChunk(
|
||||||
event=AgentTurnResponseEvent(
|
event=AgentTurnResponseEvent(
|
||||||
|
@ -413,7 +413,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
turn_id=turn_id,
|
turn_id=turn_id,
|
||||||
violation=e.violation,
|
violation=e.violation,
|
||||||
started_at=shield_call_start_time,
|
started_at=shield_call_start_time,
|
||||||
completed_at=datetime.now(timezone.utc).isoformat(),
|
completed_at=datetime.now(UTC).isoformat(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -436,7 +436,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
turn_id=turn_id,
|
turn_id=turn_id,
|
||||||
violation=None,
|
violation=None,
|
||||||
started_at=shield_call_start_time,
|
started_at=shield_call_start_time,
|
||||||
completed_at=datetime.now(timezone.utc).isoformat(),
|
completed_at=datetime.now(UTC).isoformat(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -491,7 +491,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
client_tools[tool.name] = tool
|
client_tools[tool.name] = tool
|
||||||
while True:
|
while True:
|
||||||
step_id = str(uuid.uuid4())
|
step_id = str(uuid.uuid4())
|
||||||
inference_start_time = datetime.now(timezone.utc).isoformat()
|
inference_start_time = datetime.now(UTC).isoformat()
|
||||||
yield AgentTurnResponseStreamChunk(
|
yield AgentTurnResponseStreamChunk(
|
||||||
event=AgentTurnResponseEvent(
|
event=AgentTurnResponseEvent(
|
||||||
payload=AgentTurnResponseStepStartPayload(
|
payload=AgentTurnResponseStepStartPayload(
|
||||||
|
@ -603,7 +603,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
turn_id=turn_id,
|
turn_id=turn_id,
|
||||||
model_response=copy.deepcopy(message),
|
model_response=copy.deepcopy(message),
|
||||||
started_at=inference_start_time,
|
started_at=inference_start_time,
|
||||||
completed_at=datetime.now(timezone.utc).isoformat(),
|
completed_at=datetime.now(UTC).isoformat(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -681,7 +681,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
"input": message.model_dump_json(),
|
"input": message.model_dump_json(),
|
||||||
},
|
},
|
||||||
) as span:
|
) as span:
|
||||||
tool_execution_start_time = datetime.now(timezone.utc).isoformat()
|
tool_execution_start_time = datetime.now(UTC).isoformat()
|
||||||
tool_result = await self.execute_tool_call_maybe(
|
tool_result = await self.execute_tool_call_maybe(
|
||||||
session_id,
|
session_id,
|
||||||
tool_call,
|
tool_call,
|
||||||
|
@ -710,7 +710,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
started_at=tool_execution_start_time,
|
started_at=tool_execution_start_time,
|
||||||
completed_at=datetime.now(timezone.utc).isoformat(),
|
completed_at=datetime.now(UTC).isoformat(),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Yield the step completion event
|
# Yield the step completion event
|
||||||
|
@ -747,7 +747,7 @@ class ChatAgent(ShieldRunnerMixin):
|
||||||
turn_id=turn_id,
|
turn_id=turn_id,
|
||||||
tool_calls=client_tool_calls,
|
tool_calls=client_tool_calls,
|
||||||
tool_responses=[],
|
tool_responses=[],
|
||||||
started_at=datetime.now(timezone.utc).isoformat(),
|
started_at=datetime.now(UTC).isoformat(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
import logging
|
import logging
|
||||||
import uuid
|
import uuid
|
||||||
from collections.abc import AsyncGenerator
|
from collections.abc import AsyncGenerator
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
|
|
||||||
from llama_stack.apis.agents import (
|
from llama_stack.apis.agents import (
|
||||||
Agent,
|
Agent,
|
||||||
|
@ -93,7 +93,7 @@ class MetaReferenceAgentsImpl(Agents):
|
||||||
agent_config: AgentConfig,
|
agent_config: AgentConfig,
|
||||||
) -> AgentCreateResponse:
|
) -> AgentCreateResponse:
|
||||||
agent_id = str(uuid.uuid4())
|
agent_id = str(uuid.uuid4())
|
||||||
created_at = datetime.now(timezone.utc)
|
created_at = datetime.now(UTC)
|
||||||
|
|
||||||
agent_info = AgentInfo(
|
agent_info = AgentInfo(
|
||||||
**agent_config.model_dump(),
|
**agent_config.model_dump(),
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
|
|
||||||
from llama_stack.apis.agents import AgentConfig, Session, ToolExecutionStep, Turn
|
from llama_stack.apis.agents import AgentConfig, Session, ToolExecutionStep, Turn
|
||||||
from llama_stack.distribution.access_control.access_control import AccessDeniedError, is_action_allowed
|
from llama_stack.distribution.access_control.access_control import AccessDeniedError, is_action_allowed
|
||||||
|
@ -47,7 +47,7 @@ class AgentPersistence:
|
||||||
session_info = AgentSessionInfo(
|
session_info = AgentSessionInfo(
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
session_name=name,
|
session_name=name,
|
||||||
started_at=datetime.now(timezone.utc),
|
started_at=datetime.now(UTC),
|
||||||
owner=user,
|
owner=user,
|
||||||
turns=[],
|
turns=[],
|
||||||
identifier=name, # should this be qualified in any way?
|
identifier=name, # should this be qualified in any way?
|
||||||
|
|
|
@ -11,7 +11,7 @@ import multiprocessing
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
@ -670,7 +670,7 @@ class HFFinetuningSingleDevice:
|
||||||
# Create checkpoint
|
# Create checkpoint
|
||||||
checkpoint = Checkpoint(
|
checkpoint = Checkpoint(
|
||||||
identifier=f"{model}-sft-{config.n_epochs}",
|
identifier=f"{model}-sft-{config.n_epochs}",
|
||||||
created_at=datetime.now(timezone.utc),
|
created_at=datetime.now(UTC),
|
||||||
epoch=config.n_epochs,
|
epoch=config.n_epochs,
|
||||||
post_training_job_id=job_uuid,
|
post_training_job_id=job_uuid,
|
||||||
path=str(output_dir_path / "merged_model"),
|
path=str(output_dir_path / "merged_model"),
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
@ -537,7 +537,7 @@ class LoraFinetuningSingleDevice:
|
||||||
checkpoint_path = await self.save_checkpoint(epoch=curr_epoch)
|
checkpoint_path = await self.save_checkpoint(epoch=curr_epoch)
|
||||||
checkpoint = Checkpoint(
|
checkpoint = Checkpoint(
|
||||||
identifier=f"{self.model_id}-sft-{curr_epoch}",
|
identifier=f"{self.model_id}-sft-{curr_epoch}",
|
||||||
created_at=datetime.now(timezone.utc),
|
created_at=datetime.now(UTC),
|
||||||
epoch=curr_epoch,
|
epoch=curr_epoch,
|
||||||
post_training_job_id=self.job_uuid,
|
post_training_job_id=self.job_uuid,
|
||||||
path=checkpoint_path,
|
path=checkpoint_path,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
# the root directory of this source tree.
|
# the root directory of this source tree.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
|
|
||||||
from opentelemetry.sdk.trace import ReadableSpan
|
from opentelemetry.sdk.trace import ReadableSpan
|
||||||
from opentelemetry.sdk.trace.export import SpanProcessor
|
from opentelemetry.sdk.trace.export import SpanProcessor
|
||||||
|
@ -34,7 +34,7 @@ class ConsoleSpanProcessor(SpanProcessor):
|
||||||
if span.attributes and span.attributes.get("__autotraced__"):
|
if span.attributes and span.attributes.get("__autotraced__"):
|
||||||
return
|
return
|
||||||
|
|
||||||
timestamp = datetime.fromtimestamp(span.start_time / 1e9, tz=timezone.utc).strftime("%H:%M:%S.%f")[:-3]
|
timestamp = datetime.fromtimestamp(span.start_time / 1e9, tz=UTC).strftime("%H:%M:%S.%f")[:-3]
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"{COLORS['dim']}{timestamp}{COLORS['reset']} "
|
f"{COLORS['dim']}{timestamp}{COLORS['reset']} "
|
||||||
|
@ -46,7 +46,7 @@ class ConsoleSpanProcessor(SpanProcessor):
|
||||||
if span.attributes and span.attributes.get("__autotraced__"):
|
if span.attributes and span.attributes.get("__autotraced__"):
|
||||||
return
|
return
|
||||||
|
|
||||||
timestamp = datetime.fromtimestamp(span.end_time / 1e9, tz=timezone.utc).strftime("%H:%M:%S.%f")[:-3]
|
timestamp = datetime.fromtimestamp(span.end_time / 1e9, tz=UTC).strftime("%H:%M:%S.%f")[:-3]
|
||||||
|
|
||||||
span_context = (
|
span_context = (
|
||||||
f"{COLORS['dim']}{timestamp}{COLORS['reset']} "
|
f"{COLORS['dim']}{timestamp}{COLORS['reset']} "
|
||||||
|
@ -74,7 +74,7 @@ class ConsoleSpanProcessor(SpanProcessor):
|
||||||
print(f" {COLORS['dim']}{key}: {str_value}{COLORS['reset']}")
|
print(f" {COLORS['dim']}{key}: {str_value}{COLORS['reset']}")
|
||||||
|
|
||||||
for event in span.events:
|
for event in span.events:
|
||||||
event_time = datetime.fromtimestamp(event.timestamp / 1e9, tz=timezone.utc).strftime("%H:%M:%S.%f")[:-3]
|
event_time = datetime.fromtimestamp(event.timestamp / 1e9, tz=UTC).strftime("%H:%M:%S.%f")[:-3]
|
||||||
|
|
||||||
severity = event.attributes.get("severity", "info")
|
severity = event.attributes.get("severity", "info")
|
||||||
message = event.attributes.get("message", event.name)
|
message = event.attributes.get("message", event.name)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import json
|
||||||
import os
|
import os
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import threading
|
import threading
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
|
|
||||||
from opentelemetry.sdk.trace import SpanProcessor
|
from opentelemetry.sdk.trace import SpanProcessor
|
||||||
from opentelemetry.trace import Span
|
from opentelemetry.trace import Span
|
||||||
|
@ -125,8 +125,8 @@ class SQLiteSpanProcessor(SpanProcessor):
|
||||||
trace_id,
|
trace_id,
|
||||||
service_name,
|
service_name,
|
||||||
(span_id if span.attributes.get("__root_span__") == "true" else None),
|
(span_id if span.attributes.get("__root_span__") == "true" else None),
|
||||||
datetime.fromtimestamp(span.start_time / 1e9, timezone.utc).isoformat(),
|
datetime.fromtimestamp(span.start_time / 1e9, UTC).isoformat(),
|
||||||
datetime.fromtimestamp(span.end_time / 1e9, timezone.utc).isoformat(),
|
datetime.fromtimestamp(span.end_time / 1e9, UTC).isoformat(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -144,8 +144,8 @@ class SQLiteSpanProcessor(SpanProcessor):
|
||||||
trace_id,
|
trace_id,
|
||||||
parent_span_id,
|
parent_span_id,
|
||||||
span.name,
|
span.name,
|
||||||
datetime.fromtimestamp(span.start_time / 1e9, timezone.utc).isoformat(),
|
datetime.fromtimestamp(span.start_time / 1e9, UTC).isoformat(),
|
||||||
datetime.fromtimestamp(span.end_time / 1e9, timezone.utc).isoformat(),
|
datetime.fromtimestamp(span.end_time / 1e9, UTC).isoformat(),
|
||||||
json.dumps(dict(span.attributes)),
|
json.dumps(dict(span.attributes)),
|
||||||
span.status.status_code.name,
|
span.status.status_code.name,
|
||||||
span.kind.name,
|
span.kind.name,
|
||||||
|
@ -162,7 +162,7 @@ class SQLiteSpanProcessor(SpanProcessor):
|
||||||
(
|
(
|
||||||
span_id,
|
span_id,
|
||||||
event.name,
|
event.name,
|
||||||
datetime.fromtimestamp(event.timestamp / 1e9, timezone.utc).isoformat(),
|
datetime.fromtimestamp(event.timestamp / 1e9, UTC).isoformat(),
|
||||||
json.dumps(dict(event.attributes)),
|
json.dumps(dict(event.attributes)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -87,9 +87,7 @@ class RefreshableBotoSession:
|
||||||
"access_key": session_credentials.access_key,
|
"access_key": session_credentials.access_key,
|
||||||
"secret_key": session_credentials.secret_key,
|
"secret_key": session_credentials.secret_key,
|
||||||
"token": session_credentials.token,
|
"token": session_credentials.token,
|
||||||
"expiry_time": datetime.datetime.fromtimestamp(
|
"expiry_time": datetime.datetime.fromtimestamp(time() + self.session_ttl, datetime.UTC).isoformat(),
|
||||||
time() + self.session_ttl, datetime.timezone.utc
|
|
||||||
).isoformat(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return credentials
|
return credentials
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
# the root directory of this source tree.
|
# the root directory of this source tree.
|
||||||
|
|
||||||
from collections.abc import AsyncIterator
|
from collections.abc import AsyncIterator
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from llama_stack.apis.inference import (
|
from llama_stack.apis.inference import (
|
||||||
|
@ -122,7 +122,7 @@ async def stream_and_store_openai_completion(
|
||||||
final_response = OpenAIChatCompletion(
|
final_response = OpenAIChatCompletion(
|
||||||
id=id,
|
id=id,
|
||||||
choices=assembled_choices,
|
choices=assembled_choices,
|
||||||
created=created or int(datetime.now(timezone.utc).timestamp()),
|
created=created or int(datetime.now(UTC).timestamp()),
|
||||||
model=model,
|
model=model,
|
||||||
object="chat.completion",
|
object="chat.completion",
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import asyncio
|
||||||
import functools
|
import functools
|
||||||
import threading
|
import threading
|
||||||
from collections.abc import Callable, Coroutine, Iterable
|
from collections.abc import Callable, Coroutine, Iterable
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any, TypeAlias
|
from typing import Any, TypeAlias
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ class Job:
|
||||||
self._handler = handler
|
self._handler = handler
|
||||||
self._artifacts: list[JobArtifact] = []
|
self._artifacts: list[JobArtifact] = []
|
||||||
self._logs: list[LogMessage] = []
|
self._logs: list[LogMessage] = []
|
||||||
self._state_transitions: list[tuple[datetime, JobStatus]] = [(datetime.now(timezone.utc), JobStatus.new)]
|
self._state_transitions: list[tuple[datetime, JobStatus]] = [(datetime.now(UTC), JobStatus.new)]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def handler(self) -> JobHandler:
|
def handler(self) -> JobHandler:
|
||||||
|
@ -77,7 +77,7 @@ class Job:
|
||||||
raise ValueError(f"Job is already in a completed state ({self.status})")
|
raise ValueError(f"Job is already in a completed state ({self.status})")
|
||||||
if self.status == status:
|
if self.status == status:
|
||||||
return
|
return
|
||||||
self._state_transitions.append((datetime.now(timezone.utc), status))
|
self._state_transitions.append((datetime.now(UTC), status))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def artifacts(self) -> list[JobArtifact]:
|
def artifacts(self) -> list[JobArtifact]:
|
||||||
|
@ -215,7 +215,7 @@ class Scheduler:
|
||||||
self._backend = _get_backend_impl(backend)
|
self._backend = _get_backend_impl(backend)
|
||||||
|
|
||||||
def _on_log_message_cb(self, job: Job, message: str) -> None:
|
def _on_log_message_cb(self, job: Job, message: str) -> None:
|
||||||
msg = (datetime.now(timezone.utc), message)
|
msg = (datetime.now(UTC), message)
|
||||||
# At least for the time being, until there's a better way to expose
|
# At least for the time being, until there's a better way to expose
|
||||||
# logs to users, log messages on console
|
# logs to users, log messages on console
|
||||||
logger.info(f"Job {job.id}: {message}")
|
logger.info(f"Job {job.id}: {message}")
|
||||||
|
|
|
@ -11,7 +11,7 @@ import queue
|
||||||
import random
|
import random
|
||||||
import threading
|
import threading
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ class TraceContext:
|
||||||
span_id=generate_span_id(),
|
span_id=generate_span_id(),
|
||||||
trace_id=self.trace_id,
|
trace_id=self.trace_id,
|
||||||
name=name,
|
name=name,
|
||||||
start_time=datetime.now(timezone.utc),
|
start_time=datetime.now(UTC),
|
||||||
parent_span_id=current_span.span_id if current_span else None,
|
parent_span_id=current_span.span_id if current_span else None,
|
||||||
attributes=attributes,
|
attributes=attributes,
|
||||||
)
|
)
|
||||||
|
@ -239,7 +239,7 @@ class TelemetryHandler(logging.Handler):
|
||||||
UnstructuredLogEvent(
|
UnstructuredLogEvent(
|
||||||
trace_id=span.trace_id,
|
trace_id=span.trace_id,
|
||||||
span_id=span.span_id,
|
span_id=span.span_id,
|
||||||
timestamp=datetime.now(timezone.utc),
|
timestamp=datetime.now(UTC),
|
||||||
message=self.format(record),
|
message=self.format(record),
|
||||||
severity=severity(record.levelname),
|
severity=severity(record.levelname),
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,7 +8,7 @@ version = "0.2.11"
|
||||||
authors = [{ name = "Meta Llama", email = "llama-oss@meta.com" }]
|
authors = [{ name = "Meta Llama", email = "llama-oss@meta.com" }]
|
||||||
description = "Llama Stack"
|
description = "Llama Stack"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.11"
|
||||||
license = { "text" = "MIT" }
|
license = { "text" = "MIT" }
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"License :: OSI Approved :: MIT License",
|
"License :: OSI Approved :: MIT License",
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# This source code is licensed under the terms described in the LICENSE file in
|
# This source code is licensed under the terms described in the LICENSE file in
|
||||||
# the root directory of this source tree.
|
# the root directory of this source tree.
|
||||||
|
|
||||||
PYTHON_VERSION=${PYTHON_VERSION:-3.10}
|
PYTHON_VERSION=${PYTHON_VERSION:-3.11}
|
||||||
|
|
||||||
command -v uv >/dev/null 2>&1 || { echo >&2 "uv is required but it's not installed. Exiting."; exit 1; }
|
command -v uv >/dev/null 2>&1 || { echo >&2 "uv is required but it's not installed. Exiting."; exit 1; }
|
||||||
|
|
||||||
|
|
|
@ -40,4 +40,4 @@ name = "llama-stack-provider-ollama"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "External provider for Ollama using the Llama Stack API"
|
description = "External provider for Ollama using the Llama Stack API"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.11"
|
||||||
|
|
|
@ -13,7 +13,7 @@ Any additional arguments are passed to pytest. For example, you can specify a te
|
||||||
./scripts/unit-tests.sh tests/unit/registry/test_registry.py -vvv
|
./scripts/unit-tests.sh tests/unit/registry/test_registry.py -vvv
|
||||||
```
|
```
|
||||||
|
|
||||||
If you'd like to run for a non-default version of Python (currently 3.10), pass `PYTHON_VERSION` variable as follows:
|
If you'd like to run for a non-default version of Python (currently 3.11), pass `PYTHON_VERSION` variable as follows:
|
||||||
|
|
||||||
```
|
```
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
|
|
2
uv.lock
generated
2
uv.lock
generated
|
@ -1,6 +1,6 @@
|
||||||
version = 1
|
version = 1
|
||||||
revision = 2
|
revision = 2
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.11"
|
||||||
resolution-markers = [
|
resolution-markers = [
|
||||||
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')",
|
"(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')",
|
||||||
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
|
"python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue