llama-stack-api 0.4.2__py3-none-any.whl → 0.4.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. llama_stack_api/__init__.py +945 -0
  2. llama_stack_api/admin/__init__.py +45 -0
  3. llama_stack_api/admin/api.py +72 -0
  4. llama_stack_api/admin/fastapi_routes.py +117 -0
  5. llama_stack_api/admin/models.py +113 -0
  6. llama_stack_api/agents.py +173 -0
  7. llama_stack_api/batches/__init__.py +40 -0
  8. llama_stack_api/batches/api.py +53 -0
  9. llama_stack_api/batches/fastapi_routes.py +113 -0
  10. llama_stack_api/batches/models.py +78 -0
  11. llama_stack_api/benchmarks/__init__.py +43 -0
  12. llama_stack_api/benchmarks/api.py +39 -0
  13. llama_stack_api/benchmarks/fastapi_routes.py +109 -0
  14. llama_stack_api/benchmarks/models.py +109 -0
  15. llama_stack_api/common/__init__.py +5 -0
  16. llama_stack_api/common/content_types.py +101 -0
  17. llama_stack_api/common/errors.py +95 -0
  18. llama_stack_api/common/job_types.py +38 -0
  19. llama_stack_api/common/responses.py +77 -0
  20. llama_stack_api/common/training_types.py +47 -0
  21. llama_stack_api/common/type_system.py +146 -0
  22. llama_stack_api/connectors.py +146 -0
  23. llama_stack_api/conversations.py +270 -0
  24. llama_stack_api/datasetio.py +55 -0
  25. llama_stack_api/datasets/__init__.py +61 -0
  26. llama_stack_api/datasets/api.py +35 -0
  27. llama_stack_api/datasets/fastapi_routes.py +104 -0
  28. llama_stack_api/datasets/models.py +152 -0
  29. llama_stack_api/datatypes.py +373 -0
  30. llama_stack_api/eval.py +137 -0
  31. llama_stack_api/file_processors/__init__.py +27 -0
  32. llama_stack_api/file_processors/api.py +64 -0
  33. llama_stack_api/file_processors/fastapi_routes.py +78 -0
  34. llama_stack_api/file_processors/models.py +42 -0
  35. llama_stack_api/files/__init__.py +35 -0
  36. llama_stack_api/files/api.py +51 -0
  37. llama_stack_api/files/fastapi_routes.py +124 -0
  38. llama_stack_api/files/models.py +107 -0
  39. llama_stack_api/inference.py +1169 -0
  40. llama_stack_api/inspect_api/__init__.py +37 -0
  41. llama_stack_api/inspect_api/api.py +25 -0
  42. llama_stack_api/inspect_api/fastapi_routes.py +76 -0
  43. llama_stack_api/inspect_api/models.py +28 -0
  44. llama_stack_api/internal/__init__.py +9 -0
  45. llama_stack_api/internal/kvstore.py +28 -0
  46. llama_stack_api/internal/sqlstore.py +81 -0
  47. llama_stack_api/models.py +171 -0
  48. llama_stack_api/openai_responses.py +1468 -0
  49. llama_stack_api/post_training.py +370 -0
  50. llama_stack_api/prompts.py +203 -0
  51. llama_stack_api/providers/__init__.py +33 -0
  52. llama_stack_api/providers/api.py +16 -0
  53. llama_stack_api/providers/fastapi_routes.py +57 -0
  54. llama_stack_api/providers/models.py +24 -0
  55. llama_stack_api/rag_tool.py +168 -0
  56. llama_stack_api/resource.py +37 -0
  57. llama_stack_api/router_utils.py +160 -0
  58. llama_stack_api/safety.py +132 -0
  59. llama_stack_api/schema_utils.py +208 -0
  60. llama_stack_api/scoring.py +93 -0
  61. llama_stack_api/scoring_functions.py +211 -0
  62. llama_stack_api/shields.py +93 -0
  63. llama_stack_api/tools.py +226 -0
  64. llama_stack_api/vector_io.py +941 -0
  65. llama_stack_api/vector_stores.py +53 -0
  66. llama_stack_api/version.py +9 -0
  67. {llama_stack_api-0.4.2.dist-info → llama_stack_api-0.4.4.dist-info}/METADATA +1 -1
  68. llama_stack_api-0.4.4.dist-info/RECORD +70 -0
  69. {llama_stack_api-0.4.2.dist-info → llama_stack_api-0.4.4.dist-info}/WHEEL +1 -1
  70. llama_stack_api-0.4.4.dist-info/top_level.txt +1 -0
  71. llama_stack_api-0.4.2.dist-info/RECORD +0 -4
  72. llama_stack_api-0.4.2.dist-info/top_level.txt +0 -1
@@ -0,0 +1,113 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the terms described in the LICENSE file in
5
+ # the root directory of this source tree.
6
+
7
+ """FastAPI router for the Batches API.
8
+
9
+ This module defines the FastAPI router for the Batches API using standard
10
+ FastAPI route decorators. The router is defined in the API package to keep
11
+ all API-related code together.
12
+ """
13
+
14
+ from typing import Annotated
15
+
16
+ from fastapi import APIRouter, Body, Depends
17
+
18
+ from llama_stack_api.batches.models import (
19
+ CancelBatchRequest,
20
+ CreateBatchRequest,
21
+ ListBatchesRequest,
22
+ RetrieveBatchRequest,
23
+ )
24
+ from llama_stack_api.router_utils import create_path_dependency, create_query_dependency, standard_responses
25
+ from llama_stack_api.version import LLAMA_STACK_API_V1
26
+
27
+ from .api import Batches
28
+ from .models import BatchObject, ListBatchesResponse
29
+
30
+ # Automatically generate dependency functions from Pydantic models
31
+ # This ensures the models are the single source of truth for descriptions
32
+ get_retrieve_batch_request = create_path_dependency(RetrieveBatchRequest)
33
+ get_cancel_batch_request = create_path_dependency(CancelBatchRequest)
34
+
35
+
36
+ # Automatically generate dependency function from Pydantic model
37
+ # This ensures the model is the single source of truth for descriptions and defaults
38
+ get_list_batches_request = create_query_dependency(ListBatchesRequest)
39
+
40
+
41
+ def create_router(impl: Batches) -> APIRouter:
42
+ """Create a FastAPI router for the Batches API.
43
+
44
+ Args:
45
+ impl: The Batches implementation instance
46
+
47
+ Returns:
48
+ APIRouter configured for the Batches API
49
+ """
50
+ router = APIRouter(
51
+ prefix=f"/{LLAMA_STACK_API_V1}",
52
+ tags=["Batches"],
53
+ responses=standard_responses,
54
+ )
55
+
56
+ @router.post(
57
+ "/batches",
58
+ response_model=BatchObject,
59
+ summary="Create a new batch for processing multiple API requests.",
60
+ description="Create a new batch for processing multiple API requests.",
61
+ responses={
62
+ 200: {"description": "The created batch object."},
63
+ 409: {"description": "Conflict: The idempotency key was previously used with different parameters."},
64
+ },
65
+ )
66
+ async def create_batch(
67
+ request: Annotated[CreateBatchRequest, Body(...)],
68
+ ) -> BatchObject:
69
+ return await impl.create_batch(request)
70
+
71
+ @router.get(
72
+ "/batches/{batch_id}",
73
+ response_model=BatchObject,
74
+ summary="Retrieve information about a specific batch.",
75
+ description="Retrieve information about a specific batch.",
76
+ responses={
77
+ 200: {"description": "The batch object."},
78
+ },
79
+ )
80
+ async def retrieve_batch(
81
+ request: Annotated[RetrieveBatchRequest, Depends(get_retrieve_batch_request)],
82
+ ) -> BatchObject:
83
+ return await impl.retrieve_batch(request)
84
+
85
+ @router.post(
86
+ "/batches/{batch_id}/cancel",
87
+ response_model=BatchObject,
88
+ summary="Cancel a batch that is in progress.",
89
+ description="Cancel a batch that is in progress.",
90
+ responses={
91
+ 200: {"description": "The updated batch object."},
92
+ },
93
+ )
94
+ async def cancel_batch(
95
+ request: Annotated[CancelBatchRequest, Depends(get_cancel_batch_request)],
96
+ ) -> BatchObject:
97
+ return await impl.cancel_batch(request)
98
+
99
+ @router.get(
100
+ "/batches",
101
+ response_model=ListBatchesResponse,
102
+ summary="List all batches for the current user.",
103
+ description="List all batches for the current user.",
104
+ responses={
105
+ 200: {"description": "A list of batch objects."},
106
+ },
107
+ )
108
+ async def list_batches(
109
+ request: Annotated[ListBatchesRequest, Depends(get_list_batches_request)],
110
+ ) -> ListBatchesResponse:
111
+ return await impl.list_batches(request)
112
+
113
+ return router
@@ -0,0 +1,78 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the terms described in the LICENSE file in
5
+ # the root directory of this source tree.
6
+
7
+ """Pydantic models for Batches API requests and responses.
8
+
9
+ This module defines the request and response models for the Batches API
10
+ using Pydantic with Field descriptions for OpenAPI schema generation.
11
+ """
12
+
13
+ from typing import Literal
14
+
15
+ from openai.types import Batch as BatchObject
16
+ from pydantic import BaseModel, Field
17
+
18
+ from llama_stack_api.schema_utils import json_schema_type
19
+
20
+
21
+ @json_schema_type
22
+ class CreateBatchRequest(BaseModel):
23
+ """Request model for creating a batch."""
24
+
25
+ input_file_id: str = Field(..., description="The ID of an uploaded file containing requests for the batch.")
26
+ endpoint: str = Field(..., description="The endpoint to be used for all requests in the batch.")
27
+ completion_window: Literal["24h"] = Field(
28
+ ..., description="The time window within which the batch should be processed."
29
+ )
30
+ metadata: dict[str, str] | None = Field(default=None, description="Optional metadata for the batch.")
31
+ idempotency_key: str | None = Field(
32
+ default=None, description="Optional idempotency key. When provided, enables idempotent behavior."
33
+ )
34
+
35
+
36
+ @json_schema_type
37
+ class ListBatchesRequest(BaseModel):
38
+ """Request model for listing batches."""
39
+
40
+ after: str | None = Field(
41
+ default=None, description="Optional cursor for pagination. Returns batches after this ID."
42
+ )
43
+ limit: int = Field(default=20, description="Maximum number of batches to return. Defaults to 20.")
44
+
45
+
46
+ @json_schema_type
47
+ class RetrieveBatchRequest(BaseModel):
48
+ """Request model for retrieving a batch."""
49
+
50
+ batch_id: str = Field(..., description="The ID of the batch to retrieve.")
51
+
52
+
53
+ @json_schema_type
54
+ class CancelBatchRequest(BaseModel):
55
+ """Request model for canceling a batch."""
56
+
57
+ batch_id: str = Field(..., description="The ID of the batch to cancel.")
58
+
59
+
60
+ @json_schema_type
61
+ class ListBatchesResponse(BaseModel):
62
+ """Response containing a list of batch objects."""
63
+
64
+ object: Literal["list"] = "list"
65
+ data: list[BatchObject] = Field(..., description="List of batch objects")
66
+ first_id: str | None = Field(default=None, description="ID of the first batch in the list")
67
+ last_id: str | None = Field(default=None, description="ID of the last batch in the list")
68
+ has_more: bool = Field(default=False, description="Whether there are more batches available")
69
+
70
+
71
+ __all__ = [
72
+ "CreateBatchRequest",
73
+ "ListBatchesRequest",
74
+ "RetrieveBatchRequest",
75
+ "CancelBatchRequest",
76
+ "ListBatchesResponse",
77
+ "BatchObject",
78
+ ]
@@ -0,0 +1,43 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the terms described in the LICENSE file in
5
+ # the root directory of this source tree.
6
+
7
+ """Benchmarks API protocol and models.
8
+
9
+ This module contains the Benchmarks protocol definition.
10
+ Pydantic models are defined in llama_stack_api.benchmarks.models.
11
+ The FastAPI router is defined in llama_stack_api.benchmarks.fastapi_routes.
12
+ """
13
+
14
+ # Import fastapi_routes for router factory access
15
+ from . import fastapi_routes
16
+
17
+ # Import protocol for re-export
18
+ from .api import Benchmarks
19
+
20
+ # Import models for re-export
21
+ from .models import (
22
+ Benchmark,
23
+ BenchmarkInput,
24
+ CommonBenchmarkFields,
25
+ GetBenchmarkRequest,
26
+ ListBenchmarksRequest,
27
+ ListBenchmarksResponse,
28
+ RegisterBenchmarkRequest,
29
+ UnregisterBenchmarkRequest,
30
+ )
31
+
32
+ __all__ = [
33
+ "Benchmarks",
34
+ "Benchmark",
35
+ "BenchmarkInput",
36
+ "CommonBenchmarkFields",
37
+ "ListBenchmarksResponse",
38
+ "ListBenchmarksRequest",
39
+ "GetBenchmarkRequest",
40
+ "RegisterBenchmarkRequest",
41
+ "UnregisterBenchmarkRequest",
42
+ "fastapi_routes",
43
+ ]
@@ -0,0 +1,39 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the terms described in the LICENSE file in
5
+ # the root directory of this source tree.
6
+
7
+ from typing import Protocol, runtime_checkable
8
+
9
+ from .models import (
10
+ Benchmark,
11
+ GetBenchmarkRequest,
12
+ ListBenchmarksRequest,
13
+ ListBenchmarksResponse,
14
+ RegisterBenchmarkRequest,
15
+ UnregisterBenchmarkRequest,
16
+ )
17
+
18
+
19
+ @runtime_checkable
20
+ class Benchmarks(Protocol):
21
+ async def list_benchmarks(
22
+ self,
23
+ request: ListBenchmarksRequest,
24
+ ) -> ListBenchmarksResponse: ...
25
+
26
+ async def get_benchmark(
27
+ self,
28
+ request: GetBenchmarkRequest,
29
+ ) -> Benchmark: ...
30
+
31
+ async def register_benchmark(
32
+ self,
33
+ request: RegisterBenchmarkRequest,
34
+ ) -> None: ...
35
+
36
+ async def unregister_benchmark(
37
+ self,
38
+ request: UnregisterBenchmarkRequest,
39
+ ) -> None: ...
@@ -0,0 +1,109 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the terms described in the LICENSE file in
5
+ # the root directory of this source tree.
6
+
7
+ """FastAPI router for the Benchmarks API.
8
+
9
+ This module defines the FastAPI router for the Benchmarks API using standard
10
+ FastAPI route decorators. The router is defined in the API package to keep
11
+ all API-related code together.
12
+ """
13
+
14
+ from typing import Annotated
15
+
16
+ from fastapi import APIRouter, Body, Depends
17
+
18
+ from llama_stack_api.router_utils import create_path_dependency, create_query_dependency, standard_responses
19
+ from llama_stack_api.version import LLAMA_STACK_API_V1ALPHA
20
+
21
+ from .api import Benchmarks
22
+ from .models import (
23
+ Benchmark,
24
+ GetBenchmarkRequest,
25
+ ListBenchmarksRequest,
26
+ ListBenchmarksResponse,
27
+ RegisterBenchmarkRequest,
28
+ UnregisterBenchmarkRequest,
29
+ )
30
+
31
+ # Automatically generate dependency functions from Pydantic models
32
+ # This ensures the models are the single source of truth for descriptions
33
+ get_list_benchmarks_request = create_query_dependency(ListBenchmarksRequest)
34
+ get_get_benchmark_request = create_path_dependency(GetBenchmarkRequest)
35
+ get_unregister_benchmark_request = create_path_dependency(UnregisterBenchmarkRequest)
36
+
37
+
38
+ def create_router(impl: Benchmarks) -> APIRouter:
39
+ """Create a FastAPI router for the Benchmarks API.
40
+
41
+ Args:
42
+ impl: The Benchmarks implementation instance
43
+
44
+ Returns:
45
+ APIRouter configured for the Benchmarks API
46
+ """
47
+ router = APIRouter(
48
+ prefix=f"/{LLAMA_STACK_API_V1ALPHA}",
49
+ tags=["Benchmarks"],
50
+ responses=standard_responses,
51
+ )
52
+
53
+ @router.get(
54
+ "/eval/benchmarks",
55
+ response_model=ListBenchmarksResponse,
56
+ summary="List all benchmarks.",
57
+ description="List all benchmarks.",
58
+ responses={
59
+ 200: {"description": "A ListBenchmarksResponse."},
60
+ },
61
+ )
62
+ async def list_benchmarks(
63
+ request: Annotated[ListBenchmarksRequest, Depends(get_list_benchmarks_request)],
64
+ ) -> ListBenchmarksResponse:
65
+ return await impl.list_benchmarks(request)
66
+
67
+ @router.get(
68
+ "/eval/benchmarks/{benchmark_id}",
69
+ response_model=Benchmark,
70
+ summary="Get a benchmark by its ID.",
71
+ description="Get a benchmark by its ID.",
72
+ responses={
73
+ 200: {"description": "A Benchmark."},
74
+ },
75
+ )
76
+ async def get_benchmark(
77
+ request: Annotated[GetBenchmarkRequest, Depends(get_get_benchmark_request)],
78
+ ) -> Benchmark:
79
+ return await impl.get_benchmark(request)
80
+
81
+ @router.post(
82
+ "/eval/benchmarks",
83
+ summary="Register a benchmark.",
84
+ description="Register a benchmark.",
85
+ responses={
86
+ 200: {"description": "The benchmark was successfully registered."},
87
+ },
88
+ deprecated=True,
89
+ )
90
+ async def register_benchmark(
91
+ request: Annotated[RegisterBenchmarkRequest, Body(...)],
92
+ ) -> None:
93
+ return await impl.register_benchmark(request)
94
+
95
+ @router.delete(
96
+ "/eval/benchmarks/{benchmark_id}",
97
+ summary="Unregister a benchmark.",
98
+ description="Unregister a benchmark.",
99
+ responses={
100
+ 200: {"description": "The benchmark was successfully unregistered."},
101
+ },
102
+ deprecated=True,
103
+ )
104
+ async def unregister_benchmark(
105
+ request: Annotated[UnregisterBenchmarkRequest, Depends(get_unregister_benchmark_request)],
106
+ ) -> None:
107
+ return await impl.unregister_benchmark(request)
108
+
109
+ return router
@@ -0,0 +1,109 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the terms described in the LICENSE file in
5
+ # the root directory of this source tree.
6
+
7
+ """Pydantic models for Benchmarks API requests and responses.
8
+
9
+ This module defines the request and response models for the Benchmarks API
10
+ using Pydantic with Field descriptions for OpenAPI schema generation.
11
+ """
12
+
13
+ from typing import Any, Literal
14
+
15
+ from pydantic import BaseModel, Field
16
+
17
+ from llama_stack_api.resource import Resource, ResourceType
18
+ from llama_stack_api.schema_utils import json_schema_type
19
+
20
+
21
+ @json_schema_type
22
+ class ListBenchmarksRequest(BaseModel):
23
+ """Request model for listing benchmarks."""
24
+
25
+ pass
26
+
27
+
28
+ @json_schema_type
29
+ class GetBenchmarkRequest(BaseModel):
30
+ """Request model for getting a benchmark."""
31
+
32
+ benchmark_id: str = Field(..., description="The ID of the benchmark to get.")
33
+
34
+
35
+ @json_schema_type
36
+ class RegisterBenchmarkRequest(BaseModel):
37
+ """Request model for registering a benchmark."""
38
+
39
+ benchmark_id: str = Field(..., description="The ID of the benchmark to register.")
40
+ dataset_id: str = Field(..., description="The ID of the dataset to use for the benchmark.")
41
+ scoring_functions: list[str] = Field(..., description="The scoring functions to use for the benchmark.")
42
+ provider_benchmark_id: str | None = Field(
43
+ default=None, description="The ID of the provider benchmark to use for the benchmark."
44
+ )
45
+ provider_id: str | None = Field(default=None, description="The ID of the provider to use for the benchmark.")
46
+ metadata: dict[str, Any] | None = Field(default=None, description="The metadata to use for the benchmark.")
47
+
48
+
49
+ @json_schema_type
50
+ class UnregisterBenchmarkRequest(BaseModel):
51
+ """Request model for unregistering a benchmark."""
52
+
53
+ benchmark_id: str = Field(..., description="The ID of the benchmark to unregister.")
54
+
55
+
56
+ class CommonBenchmarkFields(BaseModel):
57
+ dataset_id: str = Field(..., description="Identifier of the dataset to use for the benchmark evaluation.")
58
+ scoring_functions: list[str] = Field(
59
+ ..., description="List of scoring function identifiers to apply during evaluation."
60
+ )
61
+ metadata: dict[str, Any] = Field(
62
+ default_factory=dict,
63
+ description="Metadata for this evaluation task.",
64
+ )
65
+
66
+
67
+ @json_schema_type
68
+ class Benchmark(CommonBenchmarkFields, Resource):
69
+ """A benchmark resource for evaluating model performance."""
70
+
71
+ type: Literal[ResourceType.benchmark] = Field(
72
+ default=ResourceType.benchmark,
73
+ description="The resource type, always benchmark.",
74
+ )
75
+
76
+ @property
77
+ def benchmark_id(self) -> str:
78
+ return self.identifier
79
+
80
+ @property
81
+ def provider_benchmark_id(self) -> str | None:
82
+ return self.provider_resource_id
83
+
84
+
85
+ class BenchmarkInput(CommonBenchmarkFields, BaseModel):
86
+ benchmark_id: str = Field(..., description="The ID of the benchmark.")
87
+ provider_id: str | None = Field(default=None, description="The ID of the provider to use for the benchmark.")
88
+ provider_benchmark_id: str | None = Field(
89
+ default=None, description="The ID of the provider benchmark to use for the benchmark."
90
+ )
91
+
92
+
93
+ @json_schema_type
94
+ class ListBenchmarksResponse(BaseModel):
95
+ """Response containing a list of benchmark objects."""
96
+
97
+ data: list[Benchmark] = Field(..., description="List of benchmark objects.")
98
+
99
+
100
+ __all__ = [
101
+ "ListBenchmarksRequest",
102
+ "GetBenchmarkRequest",
103
+ "RegisterBenchmarkRequest",
104
+ "UnregisterBenchmarkRequest",
105
+ "CommonBenchmarkFields",
106
+ "Benchmark",
107
+ "BenchmarkInput",
108
+ "ListBenchmarksResponse",
109
+ ]
@@ -0,0 +1,5 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the terms described in the LICENSE file in
5
+ # the root directory of this source tree.
@@ -0,0 +1,101 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the terms described in the LICENSE file in
5
+ # the root directory of this source tree.
6
+
7
+ from typing import Annotated, Literal
8
+
9
+ from pydantic import BaseModel, Field, model_validator
10
+
11
+ from llama_stack_api.schema_utils import json_schema_type, register_schema
12
+
13
+
14
+ @json_schema_type
15
+ class URL(BaseModel):
16
+ """A URL reference to external content.
17
+
18
+ :param uri: The URL string pointing to the resource
19
+ """
20
+
21
+ uri: str
22
+
23
+
24
+ class _URLOrData(BaseModel):
25
+ """
26
+ A URL or a base64 encoded string
27
+
28
+ :param url: A URL of the image or data URL in the format of data:image/{type};base64,{data}. Note that URL could have length limits.
29
+ :param data: base64 encoded image data as string
30
+ """
31
+
32
+ url: URL | None = None
33
+ # data is a base64 encoded string, hint with contentEncoding=base64
34
+ data: str | None = Field(default=None, json_schema_extra={"contentEncoding": "base64"})
35
+
36
+ @model_validator(mode="before")
37
+ @classmethod
38
+ def validator(cls, values):
39
+ if isinstance(values, dict):
40
+ return values
41
+ return {"url": values}
42
+
43
+
44
+ @json_schema_type
45
+ class ImageContentItem(BaseModel):
46
+ """A image content item
47
+
48
+ :param type: Discriminator type of the content item. Always "image"
49
+ :param image: Image as a base64 encoded string or an URL
50
+ """
51
+
52
+ type: Literal["image"] = "image"
53
+ image: _URLOrData
54
+
55
+
56
+ @json_schema_type
57
+ class TextContentItem(BaseModel):
58
+ """A text content item
59
+
60
+ :param type: Discriminator type of the content item. Always "text"
61
+ :param text: Text content
62
+ """
63
+
64
+ type: Literal["text"] = "text"
65
+ text: str
66
+
67
+
68
+ # other modalities can be added here
69
+ InterleavedContentItem = Annotated[
70
+ ImageContentItem | TextContentItem,
71
+ Field(discriminator="type"),
72
+ ]
73
+ register_schema(InterleavedContentItem, name="InterleavedContentItem")
74
+
75
+ # accept a single "str" as a special case since it is common
76
+ InterleavedContent = str | InterleavedContentItem | list[InterleavedContentItem]
77
+ register_schema(InterleavedContent, name="InterleavedContent")
78
+
79
+
80
+ @json_schema_type
81
+ class TextDelta(BaseModel):
82
+ """A text content delta for streaming responses.
83
+
84
+ :param type: Discriminator type of the delta. Always "text"
85
+ :param text: The incremental text content
86
+ """
87
+
88
+ type: Literal["text"] = "text"
89
+ text: str
90
+
91
+
92
+ @json_schema_type
93
+ class ImageDelta(BaseModel):
94
+ """An image content delta for streaming responses.
95
+
96
+ :param type: Discriminator type of the delta. Always "image"
97
+ :param image: The incremental image data as bytes
98
+ """
99
+
100
+ type: Literal["image"] = "image"
101
+ image: bytes
@@ -0,0 +1,95 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+ #
4
+ # This source code is licensed under the terms described in the LICENSE file in
5
+ # the root directory of this source tree.
6
+
7
+ # Custom Llama Stack Exception classes should follow the following schema
8
+ # 1. All classes should inherit from an existing Built-In Exception class: https://docs.python.org/3/library/exceptions.html
9
+ # 2. All classes should have a custom error message with the goal of informing the Llama Stack user specifically
10
+ # 3. All classes should propogate the inherited __init__ function otherwise via 'super().__init__(message)'
11
+
12
+
13
+ class ResourceNotFoundError(ValueError):
14
+ """generic exception for a missing Llama Stack resource"""
15
+
16
+ def __init__(self, resource_name: str, resource_type: str, client_list: str) -> None:
17
+ message = (
18
+ f"{resource_type} '{resource_name}' not found. Use '{client_list}' to list available {resource_type}s."
19
+ )
20
+ super().__init__(message)
21
+
22
+
23
+ class UnsupportedModelError(ValueError):
24
+ """raised when model is not present in the list of supported models"""
25
+
26
+ def __init__(self, model_name: str, supported_models_list: list[str]):
27
+ message = f"'{model_name}' model is not supported. Supported models are: {', '.join(supported_models_list)}"
28
+ super().__init__(message)
29
+
30
+
31
+ class ModelNotFoundError(ResourceNotFoundError):
32
+ """raised when Llama Stack cannot find a referenced model"""
33
+
34
+ def __init__(self, model_name: str) -> None:
35
+ super().__init__(model_name, "Model", "client.models.list()")
36
+
37
+
38
+ class VectorStoreNotFoundError(ResourceNotFoundError):
39
+ """raised when Llama Stack cannot find a referenced vector store"""
40
+
41
+ def __init__(self, vector_store_name: str) -> None:
42
+ super().__init__(vector_store_name, "Vector Store", "client.vector_dbs.list()")
43
+
44
+
45
+ class DatasetNotFoundError(ResourceNotFoundError):
46
+ """raised when Llama Stack cannot find a referenced dataset"""
47
+
48
+ def __init__(self, dataset_name: str) -> None:
49
+ super().__init__(dataset_name, "Dataset", "client.datasets.list()")
50
+
51
+
52
+ class ToolGroupNotFoundError(ResourceNotFoundError):
53
+ """raised when Llama Stack cannot find a referenced tool group"""
54
+
55
+ def __init__(self, toolgroup_name: str) -> None:
56
+ super().__init__(toolgroup_name, "Tool Group", "client.toolgroups.list()")
57
+
58
+
59
+ class ModelTypeError(TypeError):
60
+ """raised when a model is present but not the correct type"""
61
+
62
+ def __init__(self, model_name: str, model_type: str, expected_model_type: str) -> None:
63
+ message = (
64
+ f"Model '{model_name}' is of type '{model_type}' rather than the expected type '{expected_model_type}'"
65
+ )
66
+ super().__init__(message)
67
+
68
+
69
+ class ConflictError(ValueError):
70
+ """raised when an operation cannot be performed due to a conflict with the current state"""
71
+
72
+ def __init__(self, message: str) -> None:
73
+ super().__init__(message)
74
+
75
+
76
+ class TokenValidationError(ValueError):
77
+ """raised when token validation fails during authentication"""
78
+
79
+ def __init__(self, message: str) -> None:
80
+ super().__init__(message)
81
+
82
+
83
+ class ConversationNotFoundError(ResourceNotFoundError):
84
+ """raised when Llama Stack cannot find a referenced conversation"""
85
+
86
+ def __init__(self, conversation_id: str) -> None:
87
+ super().__init__(conversation_id, "Conversation", "client.conversations.list()")
88
+
89
+
90
+ class InvalidConversationIdError(ValueError):
91
+ """raised when a conversation ID has an invalid format"""
92
+
93
+ def __init__(self, conversation_id: str) -> None:
94
+ message = f"Invalid conversation ID '{conversation_id}'. Expected an ID that begins with 'conv_'."
95
+ super().__init__(message)