feat: add /jobs API

This API will be later tied to jobs as defined for specific flows
(post-training, eval, etc.) through the common scheduler mechanism.

Note: At the moment, API does nothing useful. (Except returning Not
Implemented errors when called.)

This is an alternative to developing per-flow jobs APIs. Eventually,
once /jobs API is implemented, we should be able to deprecate existing
APIs under /v1/post-training/, /v1/eval/ etc.

See #1587 (tracker)
See #1238 (design details)

Note: This is an alternative path to #1582 and #1583.

Signed-off-by: Ihar Hrachyshka <ihar.hrachyshka@gmail.com>
This commit is contained in:
Ihar Hrachyshka 2025-03-12 16:15:30 -04:00
parent 0fdb15bcc7
commit 90799cdcee
12 changed files with 557 additions and 11 deletions

View file

@ -36,6 +36,7 @@ class Api(Enum):
# built-in API
inspect = "inspect"
jobs = "jobs"
@json_schema_type

View file

@ -0,0 +1,7 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the terms described in the LICENSE file in
# the root directory of this source tree.
from .jobs import * # noqa: F401 F403

View file

@ -0,0 +1,61 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the terms described in the LICENSE file in
# the root directory of this source tree.
from datetime import datetime
from typing import List, Optional, Protocol, runtime_checkable
from pydantic import BaseModel
from llama_stack.schema_utils import json_schema_type, webmethod
@json_schema_type
class JobArtifact(BaseModel):
name: str
type: str
uri: str
metadata: dict
@json_schema_type
class JobInfo(BaseModel):
uuid: str
type: str
status: str
scheduled_at: Optional[datetime] = None
started_at: Optional[datetime] = None
completed_at: Optional[datetime] = None
artifacts: List[JobArtifact]
class ListJobsResponse(BaseModel):
data: List[JobInfo]
@runtime_checkable
class Jobs(Protocol):
@webmethod(route="/jobs/{job_id}/cancel", method="POST")
async def cancel_job(
self,
job_id: str,
) -> None: ...
@webmethod(route="/jobs/{job_id}", method="DELETE")
async def delete_job(
self,
job_id: str,
) -> None: ...
@webmethod(route="/jobs", method="GET")
async def list_jobs(self) -> ListJobsResponse: ...
@webmethod(route="/jobs/{job_id}", method="GET")
async def get_job(
self,
job_id: str,
) -> JobInfo: ...

View file

@ -11,6 +11,7 @@ from pydantic import BaseModel, Field
class ResourceType(Enum):
model = "model"
job = "job"
shield = "shield"
vector_db = "vector_db"
dataset = "dataset"