mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-12-12 04:00:42 +00:00
updates
This commit is contained in:
parent
e21db79d6c
commit
13b6f3df65
12 changed files with 1238 additions and 605 deletions
|
|
@ -15,7 +15,7 @@ info:
|
|||
servers:
|
||||
- url: http://any-hosted-llama-stack.com
|
||||
paths:
|
||||
/v1/admin/providers:
|
||||
/v1/admin/providers/{api}:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
|
|
@ -44,7 +44,14 @@ paths:
|
|||
Register a new provider instance at runtime. The provider will be validated,
|
||||
|
||||
instantiated, and persisted to the kvstore. Requires appropriate ABAC permissions.
|
||||
parameters: []
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: >-
|
||||
API namespace this provider implements (e.g., 'inference', 'vector_io').
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
|
|
@ -52,7 +59,7 @@ paths:
|
|||
$ref: '#/components/schemas/RegisterProviderRequest'
|
||||
required: true
|
||||
deprecated: false
|
||||
/v1/admin/providers/{provider_id}:
|
||||
/v1/admin/providers/{api}/{provider_id}:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
|
|
@ -81,10 +88,14 @@ paths:
|
|||
|
||||
Update the configuration and/or attributes of a dynamic provider. The provider
|
||||
|
||||
will be re-instantiated with the new configuration (hot-reload). Static providers
|
||||
|
||||
from run.yaml cannot be updated.
|
||||
will be re-instantiated with the new configuration (hot-reload).
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: API namespace the provider implements
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to update
|
||||
|
|
@ -120,8 +131,14 @@ paths:
|
|||
|
||||
Remove a dynamic provider, shutting down its instance and removing it from
|
||||
|
||||
the kvstore. Static providers from run.yaml cannot be unregistered.
|
||||
the kvstore.
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: API namespace the provider implements
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to unregister.
|
||||
|
|
@ -129,6 +146,47 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/admin/providers/{api}/{provider_id}/test:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
description: >-
|
||||
TestProviderConnectionResponse with health status.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TestProviderConnectionResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest400'
|
||||
'429':
|
||||
$ref: >-
|
||||
#/components/responses/TooManyRequests429
|
||||
'500':
|
||||
$ref: >-
|
||||
#/components/responses/InternalServerError500
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: Test a provider connection.
|
||||
description: >-
|
||||
Test a provider connection.
|
||||
|
||||
Execute a health check on a provider to verify it is reachable and functioning.
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: API namespace the provider implements.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to test.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/chat/completions:
|
||||
get:
|
||||
responses:
|
||||
|
|
@ -1368,7 +1426,43 @@ paths:
|
|||
List all available providers.
|
||||
parameters: []
|
||||
deprecated: false
|
||||
/v1/providers/{provider_id}:
|
||||
/v1/providers/{api}:
|
||||
get:
|
||||
responses:
|
||||
'200':
|
||||
description: >-
|
||||
A ListProvidersResponse containing providers for the specified API.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ListProvidersResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest400'
|
||||
'429':
|
||||
$ref: >-
|
||||
#/components/responses/TooManyRequests429
|
||||
'500':
|
||||
$ref: >-
|
||||
#/components/responses/InternalServerError500
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: List providers for a specific API.
|
||||
description: >-
|
||||
List providers for a specific API.
|
||||
|
||||
List all providers that implement a specific API.
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: >-
|
||||
The API namespace to filter by (e.g., 'inference', 'vector_io')
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/providers/{api}/{provider_id}:
|
||||
get:
|
||||
responses:
|
||||
'200':
|
||||
|
|
@ -1390,52 +1484,21 @@ paths:
|
|||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: Get provider.
|
||||
summary: Get provider for specific API.
|
||||
description: >-
|
||||
Get provider.
|
||||
Get provider for specific API.
|
||||
|
||||
Get detailed information about a specific provider.
|
||||
Get detailed information about a specific provider for a specific API.
|
||||
parameters:
|
||||
- name: provider_id
|
||||
- name: api
|
||||
in: path
|
||||
description: The ID of the provider to inspect.
|
||||
description: The API namespace.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/providers/{provider_id}/test:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
description: >-
|
||||
TestProviderConnectionResponse with health status.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TestProviderConnectionResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest400'
|
||||
'429':
|
||||
$ref: >-
|
||||
#/components/responses/TooManyRequests429
|
||||
'500':
|
||||
$ref: >-
|
||||
#/components/responses/InternalServerError500
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: Test a provider connection.
|
||||
description: >-
|
||||
Test a provider connection.
|
||||
|
||||
Execute a health check on a provider to verify it is reachable and functioning.
|
||||
|
||||
Works for both static and dynamic providers.
|
||||
parameters:
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to test.
|
||||
description: The ID of the provider to inspect.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
|
|
@ -4370,9 +4433,6 @@ components:
|
|||
type: string
|
||||
description: >-
|
||||
Unique identifier for this provider instance.
|
||||
api:
|
||||
type: string
|
||||
description: API namespace this provider implements.
|
||||
provider_type:
|
||||
type: string
|
||||
description: Provider type (e.g., 'remote::openai').
|
||||
|
|
@ -4399,7 +4459,6 @@ components:
|
|||
additionalProperties: false
|
||||
required:
|
||||
- provider_id
|
||||
- api
|
||||
- provider_type
|
||||
- config
|
||||
title: RegisterProviderRequest
|
||||
|
|
@ -4608,6 +4667,32 @@ components:
|
|||
- provider
|
||||
title: UpdateProviderResponse
|
||||
description: Response after updating a provider.
|
||||
TestProviderConnectionResponse:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
description: Whether the connection test succeeded
|
||||
health:
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- type: 'null'
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: string
|
||||
- type: array
|
||||
- type: object
|
||||
description: Health status from the provider
|
||||
error_message:
|
||||
type: string
|
||||
description: Error message if test failed
|
||||
additionalProperties: false
|
||||
required:
|
||||
- success
|
||||
title: TestProviderConnectionResponse
|
||||
description: >-
|
||||
Response from testing a provider connection.
|
||||
Order:
|
||||
type: string
|
||||
enum:
|
||||
|
|
@ -7076,32 +7161,6 @@ components:
|
|||
title: ListProvidersResponse
|
||||
description: >-
|
||||
Response containing a list of all available providers.
|
||||
TestProviderConnectionResponse:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
description: Whether the connection test succeeded
|
||||
health:
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- type: 'null'
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: string
|
||||
- type: array
|
||||
- type: object
|
||||
description: Health status from the provider
|
||||
error_message:
|
||||
type: string
|
||||
description: Error message if test failed
|
||||
additionalProperties: false
|
||||
required:
|
||||
- success
|
||||
title: TestProviderConnectionResponse
|
||||
description: >-
|
||||
Response from testing a provider connection.
|
||||
ListOpenAIResponseObject:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
|||
148
docs/static/deprecated-llama-stack-spec.html
vendored
148
docs/static/deprecated-llama-stack-spec.html
vendored
|
|
@ -3526,6 +3526,51 @@
|
|||
},
|
||||
"deprecated": true
|
||||
}
|
||||
},
|
||||
"/v1/providers/{provider_id}": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A ListProvidersResponse containing all providers with matching provider_id.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ListProvidersResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/components/responses/BadRequest400"
|
||||
},
|
||||
"429": {
|
||||
"$ref": "#/components/responses/TooManyRequests429"
|
||||
},
|
||||
"500": {
|
||||
"$ref": "#/components/responses/InternalServerError500"
|
||||
},
|
||||
"default": {
|
||||
"$ref": "#/components/responses/DefaultError"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Providers"
|
||||
],
|
||||
"summary": "Get providers by ID (deprecated - use /providers/{api}/{provider_id} instead).",
|
||||
"description": "Get providers by ID (deprecated - use /providers/{api}/{provider_id} instead).\nDEPRECATED: Returns all providers with the given provider_id across all APIs.\nThis can return multiple providers if the same ID is used for different APIs.\nUse /providers/{api}/{provider_id} for unambiguous access.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "provider_id",
|
||||
"in": "path",
|
||||
"description": "The ID of the provider(s) to inspect.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"deprecated": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||
|
|
@ -13350,6 +13395,103 @@
|
|||
"logger_config"
|
||||
],
|
||||
"title": "SupervisedFineTuneRequest"
|
||||
},
|
||||
"ProviderInfo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"api": {
|
||||
"type": "string",
|
||||
"description": "The API name this provider implements"
|
||||
},
|
||||
"provider_id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier for the provider"
|
||||
},
|
||||
"provider_type": {
|
||||
"type": "string",
|
||||
"description": "The type of provider implementation"
|
||||
},
|
||||
"config": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Configuration parameters for the provider"
|
||||
},
|
||||
"health": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Current health status of the provider"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"api",
|
||||
"provider_id",
|
||||
"provider_type",
|
||||
"config",
|
||||
"health"
|
||||
],
|
||||
"title": "ProviderInfo",
|
||||
"description": "Information about a registered provider including its configuration and health status."
|
||||
},
|
||||
"ListProvidersResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ProviderInfo"
|
||||
},
|
||||
"description": "List of provider information objects"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"title": "ListProvidersResponse",
|
||||
"description": "Response containing a list of all available providers."
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
|
|
@ -13461,6 +13603,11 @@
|
|||
"name": "PostTraining (Coming Soon)",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"name": "Providers",
|
||||
"description": "Providers API for inspecting, listing, and modifying providers and their configurations.",
|
||||
"x-displayName": "Providers"
|
||||
},
|
||||
{
|
||||
"name": "Safety",
|
||||
"description": "OpenAI-compatible Moderations API.",
|
||||
|
|
@ -13484,6 +13631,7 @@
|
|||
"Inference",
|
||||
"Models",
|
||||
"PostTraining (Coming Soon)",
|
||||
"Providers",
|
||||
"Safety",
|
||||
"VectorIO"
|
||||
]
|
||||
|
|
|
|||
105
docs/static/deprecated-llama-stack-spec.yaml
vendored
105
docs/static/deprecated-llama-stack-spec.yaml
vendored
|
|
@ -2600,6 +2600,46 @@ paths:
|
|||
$ref: '#/components/schemas/SupervisedFineTuneRequest'
|
||||
required: true
|
||||
deprecated: true
|
||||
/v1/providers/{provider_id}:
|
||||
get:
|
||||
responses:
|
||||
'200':
|
||||
description: >-
|
||||
A ListProvidersResponse containing all providers with matching provider_id.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ListProvidersResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest400'
|
||||
'429':
|
||||
$ref: >-
|
||||
#/components/responses/TooManyRequests429
|
||||
'500':
|
||||
$ref: >-
|
||||
#/components/responses/InternalServerError500
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: >-
|
||||
Get providers by ID (deprecated - use /providers/{api}/{provider_id} instead).
|
||||
description: >-
|
||||
Get providers by ID (deprecated - use /providers/{api}/{provider_id} instead).
|
||||
|
||||
DEPRECATED: Returns all providers with the given provider_id across all APIs.
|
||||
|
||||
This can return multiple providers if the same ID is used for different APIs.
|
||||
|
||||
Use /providers/{api}/{provider_id} for unambiguous access.
|
||||
parameters:
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: The ID of the provider(s) to inspect.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
deprecated: true
|
||||
jsonSchemaDialect: >-
|
||||
https://json-schema.org/draft/2020-12/schema
|
||||
components:
|
||||
|
|
@ -10121,6 +10161,66 @@ components:
|
|||
- hyperparam_search_config
|
||||
- logger_config
|
||||
title: SupervisedFineTuneRequest
|
||||
ProviderInfo:
|
||||
type: object
|
||||
properties:
|
||||
api:
|
||||
type: string
|
||||
description: The API name this provider implements
|
||||
provider_id:
|
||||
type: string
|
||||
description: Unique identifier for the provider
|
||||
provider_type:
|
||||
type: string
|
||||
description: The type of provider implementation
|
||||
config:
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- type: 'null'
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: string
|
||||
- type: array
|
||||
- type: object
|
||||
description: >-
|
||||
Configuration parameters for the provider
|
||||
health:
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- type: 'null'
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: string
|
||||
- type: array
|
||||
- type: object
|
||||
description: Current health status of the provider
|
||||
additionalProperties: false
|
||||
required:
|
||||
- api
|
||||
- provider_id
|
||||
- provider_type
|
||||
- config
|
||||
- health
|
||||
title: ProviderInfo
|
||||
description: >-
|
||||
Information about a registered provider including its configuration and health
|
||||
status.
|
||||
ListProvidersResponse:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ProviderInfo'
|
||||
description: List of provider information objects
|
||||
additionalProperties: false
|
||||
required:
|
||||
- data
|
||||
title: ListProvidersResponse
|
||||
description: >-
|
||||
Response containing a list of all available providers.
|
||||
responses:
|
||||
BadRequest400:
|
||||
description: The request was invalid or malformed
|
||||
|
|
@ -10226,6 +10326,10 @@ tags:
|
|||
description: ''
|
||||
- name: PostTraining (Coming Soon)
|
||||
description: ''
|
||||
- name: Providers
|
||||
description: >-
|
||||
Providers API for inspecting, listing, and modifying providers and their configurations.
|
||||
x-displayName: Providers
|
||||
- name: Safety
|
||||
description: OpenAI-compatible Moderations API.
|
||||
x-displayName: Safety
|
||||
|
|
@ -10243,5 +10347,6 @@ x-tagGroups:
|
|||
- Inference
|
||||
- Models
|
||||
- PostTraining (Coming Soon)
|
||||
- Providers
|
||||
- Safety
|
||||
- VectorIO
|
||||
|
|
|
|||
280
docs/static/llama-stack-spec.html
vendored
280
docs/static/llama-stack-spec.html
vendored
|
|
@ -40,7 +40,7 @@
|
|||
}
|
||||
],
|
||||
"paths": {
|
||||
"/v1/admin/providers": {
|
||||
"/v1/admin/providers/{api}": {
|
||||
"post": {
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -71,7 +71,17 @@
|
|||
],
|
||||
"summary": "Register a new dynamic provider.",
|
||||
"description": "Register a new dynamic provider.\nRegister a new provider instance at runtime. The provider will be validated,\ninstantiated, and persisted to the kvstore. Requires appropriate ABAC permissions.",
|
||||
"parameters": [],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "API namespace this provider implements (e.g., 'inference', 'vector_io').",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
|
|
@ -85,7 +95,7 @@
|
|||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/admin/providers/{provider_id}": {
|
||||
"/v1/admin/providers/{api}/{provider_id}": {
|
||||
"post": {
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -115,8 +125,17 @@
|
|||
"Providers"
|
||||
],
|
||||
"summary": "Update an existing provider's configuration.",
|
||||
"description": "Update an existing provider's configuration.\nUpdate the configuration and/or attributes of a dynamic provider. The provider\nwill be re-instantiated with the new configuration (hot-reload). Static providers\nfrom run.yaml cannot be updated.",
|
||||
"description": "Update an existing provider's configuration.\nUpdate the configuration and/or attributes of a dynamic provider. The provider\nwill be re-instantiated with the new configuration (hot-reload).",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "API namespace the provider implements",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "provider_id",
|
||||
"in": "path",
|
||||
|
|
@ -161,8 +180,17 @@
|
|||
"Providers"
|
||||
],
|
||||
"summary": "Unregister a dynamic provider.",
|
||||
"description": "Unregister a dynamic provider.\nRemove a dynamic provider, shutting down its instance and removing it from\nthe kvstore. Static providers from run.yaml cannot be unregistered.",
|
||||
"description": "Unregister a dynamic provider.\nRemove a dynamic provider, shutting down its instance and removing it from\nthe kvstore.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "API namespace the provider implements",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "provider_id",
|
||||
"in": "path",
|
||||
|
|
@ -176,6 +204,60 @@
|
|||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/admin/providers/{api}/{provider_id}/test": {
|
||||
"post": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "TestProviderConnectionResponse with health status.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TestProviderConnectionResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/components/responses/BadRequest400"
|
||||
},
|
||||
"429": {
|
||||
"$ref": "#/components/responses/TooManyRequests429"
|
||||
},
|
||||
"500": {
|
||||
"$ref": "#/components/responses/InternalServerError500"
|
||||
},
|
||||
"default": {
|
||||
"$ref": "#/components/responses/DefaultError"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Providers"
|
||||
],
|
||||
"summary": "Test a provider connection.",
|
||||
"description": "Test a provider connection.\nExecute a health check on a provider to verify it is reachable and functioning.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "API namespace the provider implements.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "provider_id",
|
||||
"in": "path",
|
||||
"description": "ID of the provider to test.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/chat/completions": {
|
||||
"get": {
|
||||
"responses": {
|
||||
|
|
@ -1771,7 +1853,52 @@
|
|||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/providers/{provider_id}": {
|
||||
"/v1/providers/{api}": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A ListProvidersResponse containing providers for the specified API.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ListProvidersResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/components/responses/BadRequest400"
|
||||
},
|
||||
"429": {
|
||||
"$ref": "#/components/responses/TooManyRequests429"
|
||||
},
|
||||
"500": {
|
||||
"$ref": "#/components/responses/InternalServerError500"
|
||||
},
|
||||
"default": {
|
||||
"$ref": "#/components/responses/DefaultError"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Providers"
|
||||
],
|
||||
"summary": "List providers for a specific API.",
|
||||
"description": "List providers for a specific API.\nList all providers that implement a specific API.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "The API namespace to filter by (e.g., 'inference', 'vector_io')",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/providers/{api}/{provider_id}": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -1800,58 +1927,22 @@
|
|||
"tags": [
|
||||
"Providers"
|
||||
],
|
||||
"summary": "Get provider.",
|
||||
"description": "Get provider.\nGet detailed information about a specific provider.",
|
||||
"summary": "Get provider for specific API.",
|
||||
"description": "Get provider for specific API.\nGet detailed information about a specific provider for a specific API.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "provider_id",
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "The ID of the provider to inspect.",
|
||||
"description": "The API namespace.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/providers/{provider_id}/test": {
|
||||
"post": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "TestProviderConnectionResponse with health status.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TestProviderConnectionResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/components/responses/BadRequest400"
|
||||
},
|
||||
"429": {
|
||||
"$ref": "#/components/responses/TooManyRequests429"
|
||||
},
|
||||
"500": {
|
||||
"$ref": "#/components/responses/InternalServerError500"
|
||||
},
|
||||
"default": {
|
||||
"$ref": "#/components/responses/DefaultError"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Providers"
|
||||
],
|
||||
"summary": "Test a provider connection.",
|
||||
"description": "Test a provider connection.\nExecute a health check on a provider to verify it is reachable and functioning.\nWorks for both static and dynamic providers.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "provider_id",
|
||||
"in": "path",
|
||||
"description": "ID of the provider to test.",
|
||||
"description": "The ID of the provider to inspect.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
|
|
@ -4193,10 +4284,6 @@
|
|||
"type": "string",
|
||||
"description": "Unique identifier for this provider instance."
|
||||
},
|
||||
"api": {
|
||||
"type": "string",
|
||||
"description": "API namespace this provider implements."
|
||||
},
|
||||
"provider_type": {
|
||||
"type": "string",
|
||||
"description": "Provider type (e.g., 'remote::openai')."
|
||||
|
|
@ -4241,7 +4328,6 @@
|
|||
"additionalProperties": false,
|
||||
"required": [
|
||||
"provider_id",
|
||||
"api",
|
||||
"provider_type",
|
||||
"config"
|
||||
],
|
||||
|
|
@ -4531,6 +4617,51 @@
|
|||
"title": "UpdateProviderResponse",
|
||||
"description": "Response after updating a provider."
|
||||
},
|
||||
"TestProviderConnectionResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the connection test succeeded"
|
||||
},
|
||||
"health": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Health status from the provider"
|
||||
},
|
||||
"error_message": {
|
||||
"type": "string",
|
||||
"description": "Error message if test failed"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"success"
|
||||
],
|
||||
"title": "TestProviderConnectionResponse",
|
||||
"description": "Response from testing a provider connection."
|
||||
},
|
||||
"Order": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
|
@ -7768,51 +7899,6 @@
|
|||
"title": "ListProvidersResponse",
|
||||
"description": "Response containing a list of all available providers."
|
||||
},
|
||||
"TestProviderConnectionResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the connection test succeeded"
|
||||
},
|
||||
"health": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Health status from the provider"
|
||||
},
|
||||
"error_message": {
|
||||
"type": "string",
|
||||
"description": "Error message if test failed"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"success"
|
||||
],
|
||||
"title": "TestProviderConnectionResponse",
|
||||
"description": "Response from testing a provider connection."
|
||||
},
|
||||
"ListOpenAIResponseObject": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
|||
209
docs/static/llama-stack-spec.yaml
vendored
209
docs/static/llama-stack-spec.yaml
vendored
|
|
@ -12,7 +12,7 @@ info:
|
|||
servers:
|
||||
- url: http://any-hosted-llama-stack.com
|
||||
paths:
|
||||
/v1/admin/providers:
|
||||
/v1/admin/providers/{api}:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
|
|
@ -41,7 +41,14 @@ paths:
|
|||
Register a new provider instance at runtime. The provider will be validated,
|
||||
|
||||
instantiated, and persisted to the kvstore. Requires appropriate ABAC permissions.
|
||||
parameters: []
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: >-
|
||||
API namespace this provider implements (e.g., 'inference', 'vector_io').
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
|
|
@ -49,7 +56,7 @@ paths:
|
|||
$ref: '#/components/schemas/RegisterProviderRequest'
|
||||
required: true
|
||||
deprecated: false
|
||||
/v1/admin/providers/{provider_id}:
|
||||
/v1/admin/providers/{api}/{provider_id}:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
|
|
@ -78,10 +85,14 @@ paths:
|
|||
|
||||
Update the configuration and/or attributes of a dynamic provider. The provider
|
||||
|
||||
will be re-instantiated with the new configuration (hot-reload). Static providers
|
||||
|
||||
from run.yaml cannot be updated.
|
||||
will be re-instantiated with the new configuration (hot-reload).
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: API namespace the provider implements
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to update
|
||||
|
|
@ -117,8 +128,14 @@ paths:
|
|||
|
||||
Remove a dynamic provider, shutting down its instance and removing it from
|
||||
|
||||
the kvstore. Static providers from run.yaml cannot be unregistered.
|
||||
the kvstore.
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: API namespace the provider implements
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to unregister.
|
||||
|
|
@ -126,6 +143,47 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/admin/providers/{api}/{provider_id}/test:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
description: >-
|
||||
TestProviderConnectionResponse with health status.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TestProviderConnectionResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest400'
|
||||
'429':
|
||||
$ref: >-
|
||||
#/components/responses/TooManyRequests429
|
||||
'500':
|
||||
$ref: >-
|
||||
#/components/responses/InternalServerError500
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: Test a provider connection.
|
||||
description: >-
|
||||
Test a provider connection.
|
||||
|
||||
Execute a health check on a provider to verify it is reachable and functioning.
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: API namespace the provider implements.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to test.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/chat/completions:
|
||||
get:
|
||||
responses:
|
||||
|
|
@ -1365,7 +1423,43 @@ paths:
|
|||
List all available providers.
|
||||
parameters: []
|
||||
deprecated: false
|
||||
/v1/providers/{provider_id}:
|
||||
/v1/providers/{api}:
|
||||
get:
|
||||
responses:
|
||||
'200':
|
||||
description: >-
|
||||
A ListProvidersResponse containing providers for the specified API.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ListProvidersResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest400'
|
||||
'429':
|
||||
$ref: >-
|
||||
#/components/responses/TooManyRequests429
|
||||
'500':
|
||||
$ref: >-
|
||||
#/components/responses/InternalServerError500
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: List providers for a specific API.
|
||||
description: >-
|
||||
List providers for a specific API.
|
||||
|
||||
List all providers that implement a specific API.
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: >-
|
||||
The API namespace to filter by (e.g., 'inference', 'vector_io')
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/providers/{api}/{provider_id}:
|
||||
get:
|
||||
responses:
|
||||
'200':
|
||||
|
|
@ -1387,52 +1481,21 @@ paths:
|
|||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: Get provider.
|
||||
summary: Get provider for specific API.
|
||||
description: >-
|
||||
Get provider.
|
||||
Get provider for specific API.
|
||||
|
||||
Get detailed information about a specific provider.
|
||||
Get detailed information about a specific provider for a specific API.
|
||||
parameters:
|
||||
- name: provider_id
|
||||
- name: api
|
||||
in: path
|
||||
description: The ID of the provider to inspect.
|
||||
description: The API namespace.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/providers/{provider_id}/test:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
description: >-
|
||||
TestProviderConnectionResponse with health status.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TestProviderConnectionResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest400'
|
||||
'429':
|
||||
$ref: >-
|
||||
#/components/responses/TooManyRequests429
|
||||
'500':
|
||||
$ref: >-
|
||||
#/components/responses/InternalServerError500
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: Test a provider connection.
|
||||
description: >-
|
||||
Test a provider connection.
|
||||
|
||||
Execute a health check on a provider to verify it is reachable and functioning.
|
||||
|
||||
Works for both static and dynamic providers.
|
||||
parameters:
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to test.
|
||||
description: The ID of the provider to inspect.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
|
|
@ -3157,9 +3220,6 @@ components:
|
|||
type: string
|
||||
description: >-
|
||||
Unique identifier for this provider instance.
|
||||
api:
|
||||
type: string
|
||||
description: API namespace this provider implements.
|
||||
provider_type:
|
||||
type: string
|
||||
description: Provider type (e.g., 'remote::openai').
|
||||
|
|
@ -3186,7 +3246,6 @@ components:
|
|||
additionalProperties: false
|
||||
required:
|
||||
- provider_id
|
||||
- api
|
||||
- provider_type
|
||||
- config
|
||||
title: RegisterProviderRequest
|
||||
|
|
@ -3395,6 +3454,32 @@ components:
|
|||
- provider
|
||||
title: UpdateProviderResponse
|
||||
description: Response after updating a provider.
|
||||
TestProviderConnectionResponse:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
description: Whether the connection test succeeded
|
||||
health:
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- type: 'null'
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: string
|
||||
- type: array
|
||||
- type: object
|
||||
description: Health status from the provider
|
||||
error_message:
|
||||
type: string
|
||||
description: Error message if test failed
|
||||
additionalProperties: false
|
||||
required:
|
||||
- success
|
||||
title: TestProviderConnectionResponse
|
||||
description: >-
|
||||
Response from testing a provider connection.
|
||||
Order:
|
||||
type: string
|
||||
enum:
|
||||
|
|
@ -5863,32 +5948,6 @@ components:
|
|||
title: ListProvidersResponse
|
||||
description: >-
|
||||
Response containing a list of all available providers.
|
||||
TestProviderConnectionResponse:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
description: Whether the connection test succeeded
|
||||
health:
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- type: 'null'
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: string
|
||||
- type: array
|
||||
- type: object
|
||||
description: Health status from the provider
|
||||
error_message:
|
||||
type: string
|
||||
description: Error message if test failed
|
||||
additionalProperties: false
|
||||
required:
|
||||
- success
|
||||
title: TestProviderConnectionResponse
|
||||
description: >-
|
||||
Response from testing a provider connection.
|
||||
ListOpenAIResponseObject:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
|||
280
docs/static/stainless-llama-stack-spec.html
vendored
280
docs/static/stainless-llama-stack-spec.html
vendored
|
|
@ -40,7 +40,7 @@
|
|||
}
|
||||
],
|
||||
"paths": {
|
||||
"/v1/admin/providers": {
|
||||
"/v1/admin/providers/{api}": {
|
||||
"post": {
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -71,7 +71,17 @@
|
|||
],
|
||||
"summary": "Register a new dynamic provider.",
|
||||
"description": "Register a new dynamic provider.\nRegister a new provider instance at runtime. The provider will be validated,\ninstantiated, and persisted to the kvstore. Requires appropriate ABAC permissions.",
|
||||
"parameters": [],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "API namespace this provider implements (e.g., 'inference', 'vector_io').",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
|
|
@ -85,7 +95,7 @@
|
|||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/admin/providers/{provider_id}": {
|
||||
"/v1/admin/providers/{api}/{provider_id}": {
|
||||
"post": {
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -115,8 +125,17 @@
|
|||
"Providers"
|
||||
],
|
||||
"summary": "Update an existing provider's configuration.",
|
||||
"description": "Update an existing provider's configuration.\nUpdate the configuration and/or attributes of a dynamic provider. The provider\nwill be re-instantiated with the new configuration (hot-reload). Static providers\nfrom run.yaml cannot be updated.",
|
||||
"description": "Update an existing provider's configuration.\nUpdate the configuration and/or attributes of a dynamic provider. The provider\nwill be re-instantiated with the new configuration (hot-reload).",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "API namespace the provider implements",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "provider_id",
|
||||
"in": "path",
|
||||
|
|
@ -161,8 +180,17 @@
|
|||
"Providers"
|
||||
],
|
||||
"summary": "Unregister a dynamic provider.",
|
||||
"description": "Unregister a dynamic provider.\nRemove a dynamic provider, shutting down its instance and removing it from\nthe kvstore. Static providers from run.yaml cannot be unregistered.",
|
||||
"description": "Unregister a dynamic provider.\nRemove a dynamic provider, shutting down its instance and removing it from\nthe kvstore.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "API namespace the provider implements",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "provider_id",
|
||||
"in": "path",
|
||||
|
|
@ -176,6 +204,60 @@
|
|||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/admin/providers/{api}/{provider_id}/test": {
|
||||
"post": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "TestProviderConnectionResponse with health status.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TestProviderConnectionResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/components/responses/BadRequest400"
|
||||
},
|
||||
"429": {
|
||||
"$ref": "#/components/responses/TooManyRequests429"
|
||||
},
|
||||
"500": {
|
||||
"$ref": "#/components/responses/InternalServerError500"
|
||||
},
|
||||
"default": {
|
||||
"$ref": "#/components/responses/DefaultError"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Providers"
|
||||
],
|
||||
"summary": "Test a provider connection.",
|
||||
"description": "Test a provider connection.\nExecute a health check on a provider to verify it is reachable and functioning.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "API namespace the provider implements.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "provider_id",
|
||||
"in": "path",
|
||||
"description": "ID of the provider to test.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/chat/completions": {
|
||||
"get": {
|
||||
"responses": {
|
||||
|
|
@ -1771,7 +1853,52 @@
|
|||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/providers/{provider_id}": {
|
||||
"/v1/providers/{api}": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A ListProvidersResponse containing providers for the specified API.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ListProvidersResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/components/responses/BadRequest400"
|
||||
},
|
||||
"429": {
|
||||
"$ref": "#/components/responses/TooManyRequests429"
|
||||
},
|
||||
"500": {
|
||||
"$ref": "#/components/responses/InternalServerError500"
|
||||
},
|
||||
"default": {
|
||||
"$ref": "#/components/responses/DefaultError"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Providers"
|
||||
],
|
||||
"summary": "List providers for a specific API.",
|
||||
"description": "List providers for a specific API.\nList all providers that implement a specific API.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "The API namespace to filter by (e.g., 'inference', 'vector_io')",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/providers/{api}/{provider_id}": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
|
|
@ -1800,58 +1927,22 @@
|
|||
"tags": [
|
||||
"Providers"
|
||||
],
|
||||
"summary": "Get provider.",
|
||||
"description": "Get provider.\nGet detailed information about a specific provider.",
|
||||
"summary": "Get provider for specific API.",
|
||||
"description": "Get provider for specific API.\nGet detailed information about a specific provider for a specific API.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "provider_id",
|
||||
"name": "api",
|
||||
"in": "path",
|
||||
"description": "The ID of the provider to inspect.",
|
||||
"description": "The API namespace.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"deprecated": false
|
||||
}
|
||||
},
|
||||
"/v1/providers/{provider_id}/test": {
|
||||
"post": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "TestProviderConnectionResponse with health status.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TestProviderConnectionResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/components/responses/BadRequest400"
|
||||
},
|
||||
"429": {
|
||||
"$ref": "#/components/responses/TooManyRequests429"
|
||||
},
|
||||
"500": {
|
||||
"$ref": "#/components/responses/InternalServerError500"
|
||||
},
|
||||
"default": {
|
||||
"$ref": "#/components/responses/DefaultError"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Providers"
|
||||
],
|
||||
"summary": "Test a provider connection.",
|
||||
"description": "Test a provider connection.\nExecute a health check on a provider to verify it is reachable and functioning.\nWorks for both static and dynamic providers.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "provider_id",
|
||||
"in": "path",
|
||||
"description": "ID of the provider to test.",
|
||||
"description": "The ID of the provider to inspect.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
|
|
@ -5865,10 +5956,6 @@
|
|||
"type": "string",
|
||||
"description": "Unique identifier for this provider instance."
|
||||
},
|
||||
"api": {
|
||||
"type": "string",
|
||||
"description": "API namespace this provider implements."
|
||||
},
|
||||
"provider_type": {
|
||||
"type": "string",
|
||||
"description": "Provider type (e.g., 'remote::openai')."
|
||||
|
|
@ -5913,7 +6000,6 @@
|
|||
"additionalProperties": false,
|
||||
"required": [
|
||||
"provider_id",
|
||||
"api",
|
||||
"provider_type",
|
||||
"config"
|
||||
],
|
||||
|
|
@ -6203,6 +6289,51 @@
|
|||
"title": "UpdateProviderResponse",
|
||||
"description": "Response after updating a provider."
|
||||
},
|
||||
"TestProviderConnectionResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the connection test succeeded"
|
||||
},
|
||||
"health": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Health status from the provider"
|
||||
},
|
||||
"error_message": {
|
||||
"type": "string",
|
||||
"description": "Error message if test failed"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"success"
|
||||
],
|
||||
"title": "TestProviderConnectionResponse",
|
||||
"description": "Response from testing a provider connection."
|
||||
},
|
||||
"Order": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
|
@ -9440,51 +9571,6 @@
|
|||
"title": "ListProvidersResponse",
|
||||
"description": "Response containing a list of all available providers."
|
||||
},
|
||||
"TestProviderConnectionResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the connection test succeeded"
|
||||
},
|
||||
"health": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Health status from the provider"
|
||||
},
|
||||
"error_message": {
|
||||
"type": "string",
|
||||
"description": "Error message if test failed"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"success"
|
||||
],
|
||||
"title": "TestProviderConnectionResponse",
|
||||
"description": "Response from testing a provider connection."
|
||||
},
|
||||
"ListOpenAIResponseObject": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
|||
209
docs/static/stainless-llama-stack-spec.yaml
vendored
209
docs/static/stainless-llama-stack-spec.yaml
vendored
|
|
@ -15,7 +15,7 @@ info:
|
|||
servers:
|
||||
- url: http://any-hosted-llama-stack.com
|
||||
paths:
|
||||
/v1/admin/providers:
|
||||
/v1/admin/providers/{api}:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
|
|
@ -44,7 +44,14 @@ paths:
|
|||
Register a new provider instance at runtime. The provider will be validated,
|
||||
|
||||
instantiated, and persisted to the kvstore. Requires appropriate ABAC permissions.
|
||||
parameters: []
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: >-
|
||||
API namespace this provider implements (e.g., 'inference', 'vector_io').
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
|
|
@ -52,7 +59,7 @@ paths:
|
|||
$ref: '#/components/schemas/RegisterProviderRequest'
|
||||
required: true
|
||||
deprecated: false
|
||||
/v1/admin/providers/{provider_id}:
|
||||
/v1/admin/providers/{api}/{provider_id}:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
|
|
@ -81,10 +88,14 @@ paths:
|
|||
|
||||
Update the configuration and/or attributes of a dynamic provider. The provider
|
||||
|
||||
will be re-instantiated with the new configuration (hot-reload). Static providers
|
||||
|
||||
from run.yaml cannot be updated.
|
||||
will be re-instantiated with the new configuration (hot-reload).
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: API namespace the provider implements
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to update
|
||||
|
|
@ -120,8 +131,14 @@ paths:
|
|||
|
||||
Remove a dynamic provider, shutting down its instance and removing it from
|
||||
|
||||
the kvstore. Static providers from run.yaml cannot be unregistered.
|
||||
the kvstore.
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: API namespace the provider implements
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to unregister.
|
||||
|
|
@ -129,6 +146,47 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/admin/providers/{api}/{provider_id}/test:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
description: >-
|
||||
TestProviderConnectionResponse with health status.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TestProviderConnectionResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest400'
|
||||
'429':
|
||||
$ref: >-
|
||||
#/components/responses/TooManyRequests429
|
||||
'500':
|
||||
$ref: >-
|
||||
#/components/responses/InternalServerError500
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: Test a provider connection.
|
||||
description: >-
|
||||
Test a provider connection.
|
||||
|
||||
Execute a health check on a provider to verify it is reachable and functioning.
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: API namespace the provider implements.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to test.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/chat/completions:
|
||||
get:
|
||||
responses:
|
||||
|
|
@ -1368,7 +1426,43 @@ paths:
|
|||
List all available providers.
|
||||
parameters: []
|
||||
deprecated: false
|
||||
/v1/providers/{provider_id}:
|
||||
/v1/providers/{api}:
|
||||
get:
|
||||
responses:
|
||||
'200':
|
||||
description: >-
|
||||
A ListProvidersResponse containing providers for the specified API.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ListProvidersResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest400'
|
||||
'429':
|
||||
$ref: >-
|
||||
#/components/responses/TooManyRequests429
|
||||
'500':
|
||||
$ref: >-
|
||||
#/components/responses/InternalServerError500
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: List providers for a specific API.
|
||||
description: >-
|
||||
List providers for a specific API.
|
||||
|
||||
List all providers that implement a specific API.
|
||||
parameters:
|
||||
- name: api
|
||||
in: path
|
||||
description: >-
|
||||
The API namespace to filter by (e.g., 'inference', 'vector_io')
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/providers/{api}/{provider_id}:
|
||||
get:
|
||||
responses:
|
||||
'200':
|
||||
|
|
@ -1390,52 +1484,21 @@ paths:
|
|||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: Get provider.
|
||||
summary: Get provider for specific API.
|
||||
description: >-
|
||||
Get provider.
|
||||
Get provider for specific API.
|
||||
|
||||
Get detailed information about a specific provider.
|
||||
Get detailed information about a specific provider for a specific API.
|
||||
parameters:
|
||||
- name: provider_id
|
||||
- name: api
|
||||
in: path
|
||||
description: The ID of the provider to inspect.
|
||||
description: The API namespace.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
deprecated: false
|
||||
/v1/providers/{provider_id}/test:
|
||||
post:
|
||||
responses:
|
||||
'200':
|
||||
description: >-
|
||||
TestProviderConnectionResponse with health status.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TestProviderConnectionResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest400'
|
||||
'429':
|
||||
$ref: >-
|
||||
#/components/responses/TooManyRequests429
|
||||
'500':
|
||||
$ref: >-
|
||||
#/components/responses/InternalServerError500
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultError'
|
||||
tags:
|
||||
- Providers
|
||||
summary: Test a provider connection.
|
||||
description: >-
|
||||
Test a provider connection.
|
||||
|
||||
Execute a health check on a provider to verify it is reachable and functioning.
|
||||
|
||||
Works for both static and dynamic providers.
|
||||
parameters:
|
||||
- name: provider_id
|
||||
in: path
|
||||
description: ID of the provider to test.
|
||||
description: The ID of the provider to inspect.
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
|
|
@ -4370,9 +4433,6 @@ components:
|
|||
type: string
|
||||
description: >-
|
||||
Unique identifier for this provider instance.
|
||||
api:
|
||||
type: string
|
||||
description: API namespace this provider implements.
|
||||
provider_type:
|
||||
type: string
|
||||
description: Provider type (e.g., 'remote::openai').
|
||||
|
|
@ -4399,7 +4459,6 @@ components:
|
|||
additionalProperties: false
|
||||
required:
|
||||
- provider_id
|
||||
- api
|
||||
- provider_type
|
||||
- config
|
||||
title: RegisterProviderRequest
|
||||
|
|
@ -4608,6 +4667,32 @@ components:
|
|||
- provider
|
||||
title: UpdateProviderResponse
|
||||
description: Response after updating a provider.
|
||||
TestProviderConnectionResponse:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
description: Whether the connection test succeeded
|
||||
health:
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- type: 'null'
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: string
|
||||
- type: array
|
||||
- type: object
|
||||
description: Health status from the provider
|
||||
error_message:
|
||||
type: string
|
||||
description: Error message if test failed
|
||||
additionalProperties: false
|
||||
required:
|
||||
- success
|
||||
title: TestProviderConnectionResponse
|
||||
description: >-
|
||||
Response from testing a provider connection.
|
||||
Order:
|
||||
type: string
|
||||
enum:
|
||||
|
|
@ -7076,32 +7161,6 @@ components:
|
|||
title: ListProvidersResponse
|
||||
description: >-
|
||||
Response containing a list of all available providers.
|
||||
TestProviderConnectionResponse:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
description: Whether the connection test succeeded
|
||||
health:
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- type: 'null'
|
||||
- type: boolean
|
||||
- type: number
|
||||
- type: string
|
||||
- type: array
|
||||
- type: object
|
||||
description: Health status from the provider
|
||||
error_message:
|
||||
type: string
|
||||
description: Error message if test failed
|
||||
additionalProperties: false
|
||||
required:
|
||||
- success
|
||||
title: TestProviderConnectionResponse
|
||||
description: >-
|
||||
Response from testing a provider connection.
|
||||
ListOpenAIResponseObject:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
|||
|
|
@ -137,24 +137,26 @@ class Providers(Protocol):
|
|||
"""
|
||||
...
|
||||
|
||||
@webmethod(route="/providers/{provider_id}", method="GET", level=LLAMA_STACK_API_V1)
|
||||
async def inspect_provider(self, provider_id: str) -> ProviderInfo:
|
||||
"""Get provider.
|
||||
@webmethod(route="/providers/{provider_id}", method="GET", level=LLAMA_STACK_API_V1, deprecated=True)
|
||||
async def inspect_provider(self, provider_id: str) -> ListProvidersResponse:
|
||||
"""Get providers by ID (deprecated - use /providers/{api}/{provider_id} instead).
|
||||
|
||||
Get detailed information about a specific provider.
|
||||
DEPRECATED: Returns all providers with the given provider_id across all APIs.
|
||||
This can return multiple providers if the same ID is used for different APIs.
|
||||
Use /providers/{api}/{provider_id} for unambiguous access.
|
||||
|
||||
:param provider_id: The ID of the provider to inspect.
|
||||
:returns: A ProviderInfo object containing the provider's details.
|
||||
:param provider_id: The ID of the provider(s) to inspect.
|
||||
:returns: A ListProvidersResponse containing all providers with matching provider_id.
|
||||
"""
|
||||
...
|
||||
|
||||
# ===== Dynamic Provider Management Methods =====
|
||||
|
||||
@webmethod(route="/admin/providers", method="POST", level=LLAMA_STACK_API_V1)
|
||||
@webmethod(route="/admin/providers/{api}", method="POST", level=LLAMA_STACK_API_V1)
|
||||
async def register_provider(
|
||||
self,
|
||||
provider_id: str,
|
||||
api: str,
|
||||
provider_id: str,
|
||||
provider_type: str,
|
||||
config: dict[str, Any],
|
||||
attributes: dict[str, list[str]] | None = None,
|
||||
|
|
@ -164,8 +166,8 @@ class Providers(Protocol):
|
|||
Register a new provider instance at runtime. The provider will be validated,
|
||||
instantiated, and persisted to the kvstore. Requires appropriate ABAC permissions.
|
||||
|
||||
:param api: API namespace this provider implements (e.g., 'inference', 'vector_io').
|
||||
:param provider_id: Unique identifier for this provider instance.
|
||||
:param api: API namespace this provider implements.
|
||||
:param provider_type: Provider type (e.g., 'remote::openai').
|
||||
:param config: Provider configuration (API keys, endpoints, etc.).
|
||||
:param attributes: Optional attributes for ABAC access control.
|
||||
|
|
@ -173,9 +175,10 @@ class Providers(Protocol):
|
|||
"""
|
||||
...
|
||||
|
||||
@webmethod(route="/admin/providers/{provider_id}", method="PUT", level=LLAMA_STACK_API_V1)
|
||||
@webmethod(route="/admin/providers/{api}/{provider_id}", method="PUT", level=LLAMA_STACK_API_V1)
|
||||
async def update_provider(
|
||||
self,
|
||||
api: str,
|
||||
provider_id: str,
|
||||
config: dict[str, Any] | None = None,
|
||||
attributes: dict[str, list[str]] | None = None,
|
||||
|
|
@ -183,9 +186,9 @@ class Providers(Protocol):
|
|||
"""Update an existing provider's configuration.
|
||||
|
||||
Update the configuration and/or attributes of a dynamic provider. The provider
|
||||
will be re-instantiated with the new configuration (hot-reload). Static providers
|
||||
from run.yaml cannot be updated.
|
||||
will be re-instantiated with the new configuration (hot-reload).
|
||||
|
||||
:param api: API namespace the provider implements
|
||||
:param provider_id: ID of the provider to update
|
||||
:param config: New configuration parameters (merged with existing)
|
||||
:param attributes: New attributes for access control
|
||||
|
|
@ -193,25 +196,49 @@ class Providers(Protocol):
|
|||
"""
|
||||
...
|
||||
|
||||
@webmethod(route="/admin/providers/{provider_id}", method="DELETE", level=LLAMA_STACK_API_V1)
|
||||
async def unregister_provider(self, provider_id: str) -> None:
|
||||
@webmethod(route="/admin/providers/{api}/{provider_id}", method="DELETE", level=LLAMA_STACK_API_V1)
|
||||
async def unregister_provider(self, api: str, provider_id: str) -> None:
|
||||
"""Unregister a dynamic provider.
|
||||
|
||||
Remove a dynamic provider, shutting down its instance and removing it from
|
||||
the kvstore. Static providers from run.yaml cannot be unregistered.
|
||||
the kvstore.
|
||||
|
||||
:param api: API namespace the provider implements
|
||||
:param provider_id: ID of the provider to unregister.
|
||||
"""
|
||||
...
|
||||
|
||||
@webmethod(route="/providers/{provider_id}/test", method="POST", level=LLAMA_STACK_API_V1)
|
||||
async def test_provider_connection(self, provider_id: str) -> TestProviderConnectionResponse:
|
||||
@webmethod(route="/admin/providers/{api}/{provider_id}/test", method="POST", level=LLAMA_STACK_API_V1)
|
||||
async def test_provider_connection(self, api: str, provider_id: str) -> TestProviderConnectionResponse:
|
||||
"""Test a provider connection.
|
||||
|
||||
Execute a health check on a provider to verify it is reachable and functioning.
|
||||
Works for both static and dynamic providers.
|
||||
|
||||
:param api: API namespace the provider implements.
|
||||
:param provider_id: ID of the provider to test.
|
||||
:returns: TestProviderConnectionResponse with health status.
|
||||
"""
|
||||
...
|
||||
|
||||
@webmethod(route="/providers/{api}", method="GET", level=LLAMA_STACK_API_V1)
|
||||
async def list_providers_for_api(self, api: str) -> ListProvidersResponse:
|
||||
"""List providers for a specific API.
|
||||
|
||||
List all providers that implement a specific API.
|
||||
|
||||
:param api: The API namespace to filter by (e.g., 'inference', 'vector_io')
|
||||
:returns: A ListProvidersResponse containing providers for the specified API.
|
||||
"""
|
||||
...
|
||||
|
||||
@webmethod(route="/providers/{api}/{provider_id}", method="GET", level=LLAMA_STACK_API_V1)
|
||||
async def inspect_provider_for_api(self, api: str, provider_id: str) -> ProviderInfo:
|
||||
"""Get provider for specific API.
|
||||
|
||||
Get detailed information about a specific provider for a specific API.
|
||||
|
||||
:param api: The API namespace.
|
||||
:param provider_id: The ID of the provider to inspect.
|
||||
:returns: A ProviderInfo object containing the provider's details.
|
||||
"""
|
||||
...
|
||||
|
|
|
|||
|
|
@ -79,29 +79,24 @@ class ProviderImpl(Providers):
|
|||
from llama_stack.providers.utils.kvstore import kvstore_impl
|
||||
|
||||
self.kvstore = await kvstore_impl(self.config.run_config.storage.stores.metadata)
|
||||
logger.info("✅ Initialized kvstore for dynamic provider management")
|
||||
logger.info("Initialized kvstore for dynamic provider management")
|
||||
|
||||
# Load existing dynamic providers from kvstore
|
||||
await self._load_dynamic_providers()
|
||||
logger.info(f"📦 Loaded {len(self.dynamic_providers)} existing dynamic providers from kvstore")
|
||||
logger.info(f"Loaded {len(self.dynamic_providers)} existing dynamic providers from kvstore")
|
||||
|
||||
# Auto-instantiate connected providers on startup
|
||||
if self.provider_registry:
|
||||
for provider_id, conn_info in self.dynamic_providers.items():
|
||||
if conn_info.status == ProviderConnectionStatus.connected:
|
||||
try:
|
||||
impl = await self._instantiate_provider(conn_info)
|
||||
self.dynamic_provider_impls[provider_id] = impl
|
||||
logger.info(f"♻️ Auto-instantiated provider {provider_id} from kvstore")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to auto-instantiate provider {provider_id}: {e}")
|
||||
# Update status to failed
|
||||
conn_info.status = ProviderConnectionStatus.failed
|
||||
conn_info.error_message = str(e)
|
||||
conn_info.updated_at = datetime.now(UTC)
|
||||
await self._store_connection(conn_info)
|
||||
else:
|
||||
logger.warning("Provider registry not available, skipping auto-instantiation")
|
||||
for provider_id, conn_info in self.dynamic_providers.items():
|
||||
if conn_info.status == ProviderConnectionStatus.connected:
|
||||
try:
|
||||
impl = await self._instantiate_provider(conn_info)
|
||||
self.dynamic_provider_impls[provider_id] = impl
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to instantiate provider {provider_id}: {e}")
|
||||
# Update status to failed
|
||||
conn_info.status = ProviderConnectionStatus.failed
|
||||
conn_info.error_message = str(e)
|
||||
conn_info.updated_at = datetime.now(UTC)
|
||||
await self._store_connection(conn_info)
|
||||
|
||||
async def shutdown(self) -> None:
|
||||
logger.debug("ProviderImpl.shutdown")
|
||||
|
|
@ -174,13 +169,34 @@ class ProviderImpl(Providers):
|
|||
|
||||
return ListProvidersResponse(data=ret)
|
||||
|
||||
async def inspect_provider(self, provider_id: str) -> ProviderInfo:
|
||||
async def inspect_provider(self, provider_id: str) -> ListProvidersResponse:
|
||||
"""Get all providers with the given provider_id (deprecated).
|
||||
|
||||
Returns all providers across all APIs that have this provider_id.
|
||||
This is deprecated - use inspect_provider_for_api() for unambiguous access.
|
||||
"""
|
||||
all_providers = await self.list_providers()
|
||||
matching = [p for p in all_providers.data if p.provider_id == provider_id]
|
||||
|
||||
if not matching:
|
||||
raise ValueError(f"Provider {provider_id} not found")
|
||||
|
||||
return ListProvidersResponse(data=matching)
|
||||
|
||||
async def list_providers_for_api(self, api: str) -> ListProvidersResponse:
|
||||
"""List providers for a specific API."""
|
||||
all_providers = await self.list_providers()
|
||||
filtered = [p for p in all_providers.data if p.api == api]
|
||||
return ListProvidersResponse(data=filtered)
|
||||
|
||||
async def inspect_provider_for_api(self, api: str, provider_id: str) -> ProviderInfo:
|
||||
"""Get a specific provider for a specific API."""
|
||||
all_providers = await self.list_providers()
|
||||
for p in all_providers.data:
|
||||
if p.provider_id == provider_id:
|
||||
if p.api == api and p.provider_id == provider_id:
|
||||
return p
|
||||
|
||||
raise ValueError(f"Provider {provider_id} not found")
|
||||
raise ValueError(f"Provider {provider_id} not found for API {api}")
|
||||
|
||||
async def get_providers_health(self) -> dict[str, dict[str, HealthResponse]]:
|
||||
"""Get health status for all providers.
|
||||
|
|
@ -272,17 +288,19 @@ class ProviderImpl(Providers):
|
|||
return ProviderConnectionInfo.model_validate_json(value)
|
||||
return None
|
||||
|
||||
async def _delete_connection(self, provider_id: str) -> None:
|
||||
async def _delete_connection(self, api: str, provider_id: str) -> None:
|
||||
"""Delete provider connection from kvstore.
|
||||
|
||||
:param api: API namespace
|
||||
:param provider_id: Provider ID to delete
|
||||
"""
|
||||
if not self.kvstore:
|
||||
raise RuntimeError("KVStore not initialized")
|
||||
|
||||
key = f"{PROVIDER_CONNECTIONS_PREFIX}{provider_id}"
|
||||
# Use composite key: provider_connections:v1::{api}::{provider_id}
|
||||
key = f"{PROVIDER_CONNECTIONS_PREFIX}{api}::{provider_id}"
|
||||
await self.kvstore.delete(key)
|
||||
logger.debug(f"Deleted provider connection: {provider_id}")
|
||||
logger.debug(f"Deleted provider connection: {api}::{provider_id}")
|
||||
|
||||
async def _list_connections(self) -> list[ProviderConnectionInfo]:
|
||||
"""List all dynamic provider connections from kvstore.
|
||||
|
|
@ -306,6 +324,17 @@ class ProviderImpl(Providers):
|
|||
self.dynamic_providers[cache_key] = conn
|
||||
logger.debug(f"Loaded dynamic provider: {cache_key} (status: {conn.status})")
|
||||
|
||||
def _find_provider_cache_key(self, provider_id: str) -> str | None:
|
||||
"""Find the cache key for a provider by its provider_id.
|
||||
|
||||
Since we use composite keys ({api}::{provider_id}), this searches for the matching key.
|
||||
Returns None if not found.
|
||||
"""
|
||||
for key in self.dynamic_providers.keys():
|
||||
if key.endswith(f"::{provider_id}"):
|
||||
return key
|
||||
return None
|
||||
|
||||
# Helper methods for dynamic provider management
|
||||
|
||||
def _redact_sensitive_config(self, config: dict[str, Any]) -> dict[str, Any]:
|
||||
|
|
@ -380,8 +409,8 @@ class ProviderImpl(Providers):
|
|||
|
||||
async def register_provider(
|
||||
self,
|
||||
provider_id: str,
|
||||
api: str,
|
||||
provider_id: str,
|
||||
provider_type: str,
|
||||
config: dict[str, Any],
|
||||
attributes: dict[str, list[str]] | None = None,
|
||||
|
|
@ -394,7 +423,6 @@ class ProviderImpl(Providers):
|
|||
|
||||
All providers are stored in kvstore and treated equally.
|
||||
"""
|
||||
logger.info(f"📝 REGISTER_PROVIDER called: provider_id={provider_id}, api={api}, type={provider_type}")
|
||||
|
||||
if not self.kvstore:
|
||||
raise RuntimeError("Dynamic provider management is not enabled (no kvstore configured)")
|
||||
|
|
@ -427,25 +455,15 @@ class ProviderImpl(Providers):
|
|||
# Store in kvstore
|
||||
await self._store_connection(conn_info)
|
||||
|
||||
# Instantiate provider if we have a provider registry
|
||||
if self.provider_registry:
|
||||
impl = await self._instantiate_provider(conn_info)
|
||||
# Use composite key for impl cache too
|
||||
self.dynamic_provider_impls[cache_key] = impl
|
||||
impl = await self._instantiate_provider(conn_info)
|
||||
# Use composite key for impl cache too
|
||||
self.dynamic_provider_impls[cache_key] = impl
|
||||
|
||||
# Update status to connected after successful instantiation
|
||||
conn_info.status = ProviderConnectionStatus.connected
|
||||
conn_info.updated_at = datetime.now(UTC)
|
||||
# Update status to connected after successful instantiation
|
||||
conn_info.status = ProviderConnectionStatus.connected
|
||||
conn_info.updated_at = datetime.now(UTC)
|
||||
|
||||
logger.info(
|
||||
f"Registered and instantiated dynamic provider {provider_id} (api={api}, type={provider_type})"
|
||||
)
|
||||
else:
|
||||
# No registry available - just mark as connected without instantiation
|
||||
# This can happen during testing or if provider management is disabled
|
||||
conn_info.status = ProviderConnectionStatus.connected
|
||||
conn_info.updated_at = datetime.now(UTC)
|
||||
logger.warning(f"Registered provider {provider_id} without instantiation (no registry)")
|
||||
logger.info(f"Registered and instantiated dynamic provider {provider_id} (api={api}, type={provider_type})")
|
||||
|
||||
# Store updated status
|
||||
await self._store_connection(conn_info)
|
||||
|
|
@ -468,6 +486,7 @@ class ProviderImpl(Providers):
|
|||
|
||||
async def update_provider(
|
||||
self,
|
||||
api: str,
|
||||
provider_id: str,
|
||||
config: dict[str, Any] | None = None,
|
||||
attributes: dict[str, list[str]] | None = None,
|
||||
|
|
@ -477,16 +496,16 @@ class ProviderImpl(Providers):
|
|||
Updates persist to kvstore and survive server restarts.
|
||||
This works for all providers (whether originally from run.yaml or API).
|
||||
"""
|
||||
logger.info(f"🔄 UPDATE_PROVIDER called: provider_id={provider_id}, has_config={config is not None}, has_attributes={attributes is not None}")
|
||||
|
||||
if not self.kvstore:
|
||||
raise RuntimeError("Dynamic provider management is not enabled (no kvstore configured)")
|
||||
|
||||
# Check if provider exists
|
||||
if provider_id not in self.dynamic_providers:
|
||||
raise ValueError(f"Provider {provider_id} not found")
|
||||
# Use composite key
|
||||
cache_key = f"{api}::{provider_id}"
|
||||
if cache_key not in self.dynamic_providers:
|
||||
raise ValueError(f"Provider {provider_id} not found for API {api}")
|
||||
|
||||
conn_info = self.dynamic_providers[provider_id]
|
||||
conn_info = self.dynamic_providers[cache_key]
|
||||
|
||||
# Update config if provided
|
||||
if config is not None:
|
||||
|
|
@ -504,33 +523,26 @@ class ProviderImpl(Providers):
|
|||
await self._store_connection(conn_info)
|
||||
|
||||
# Hot-reload: Shutdown old instance and reinstantiate with new config
|
||||
if self.provider_registry:
|
||||
# Shutdown old instance if it exists
|
||||
if provider_id in self.dynamic_provider_impls:
|
||||
old_impl = self.dynamic_provider_impls[provider_id]
|
||||
if hasattr(old_impl, "shutdown"):
|
||||
try:
|
||||
await old_impl.shutdown()
|
||||
logger.debug(f"Shutdown old instance of provider {provider_id}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error shutting down old instance of {provider_id}: {e}")
|
||||
# Shutdown old instance if it exists
|
||||
if cache_key in self.dynamic_provider_impls:
|
||||
old_impl = self.dynamic_provider_impls[cache_key]
|
||||
if hasattr(old_impl, "shutdown"):
|
||||
try:
|
||||
await old_impl.shutdown()
|
||||
logger.debug(f"Shutdown old instance of provider {provider_id}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error shutting down old instance of {provider_id}: {e}")
|
||||
|
||||
# Reinstantiate with new config
|
||||
impl = await self._instantiate_provider(conn_info)
|
||||
self.dynamic_provider_impls[provider_id] = impl
|
||||
# Reinstantiate with new config
|
||||
impl = await self._instantiate_provider(conn_info)
|
||||
self.dynamic_provider_impls[cache_key] = impl
|
||||
|
||||
# Update status to connected after successful reinstantiation
|
||||
conn_info.status = ProviderConnectionStatus.connected
|
||||
conn_info.updated_at = datetime.now(UTC)
|
||||
await self._store_connection(conn_info)
|
||||
# Update status to connected after successful reinstantiation
|
||||
conn_info.status = ProviderConnectionStatus.connected
|
||||
conn_info.updated_at = datetime.now(UTC)
|
||||
await self._store_connection(conn_info)
|
||||
|
||||
logger.info(f"Hot-reloaded dynamic provider {provider_id}")
|
||||
else:
|
||||
# No registry - just update config without reinstantiation
|
||||
conn_info.status = ProviderConnectionStatus.connected
|
||||
conn_info.updated_at = datetime.now(UTC)
|
||||
await self._store_connection(conn_info)
|
||||
logger.warning(f"Updated provider {provider_id} config without hot-reload (no registry)")
|
||||
logger.info(f"Hot-reloaded dynamic provider {provider_id}")
|
||||
|
||||
return UpdateProviderResponse(provider=conn_info)
|
||||
|
||||
|
|
@ -543,34 +555,36 @@ class ProviderImpl(Providers):
|
|||
logger.error(f"Failed to update provider {provider_id}: {e}")
|
||||
raise RuntimeError(f"Failed to update provider: {e}") from e
|
||||
|
||||
async def unregister_provider(self, provider_id: str) -> None:
|
||||
async def unregister_provider(self, api: str, provider_id: str) -> None:
|
||||
"""Unregister a provider.
|
||||
|
||||
Removes the provider from kvstore and shuts down its instance.
|
||||
This works for all providers (whether originally from run.yaml or API).
|
||||
"""
|
||||
logger.info(f"🗑️ UNREGISTER_PROVIDER called: provider_id={provider_id}")
|
||||
|
||||
if not self.kvstore:
|
||||
raise RuntimeError("Dynamic provider management is not enabled (no kvstore configured)")
|
||||
|
||||
# Check if provider exists
|
||||
if provider_id not in self.dynamic_providers:
|
||||
raise ValueError(f"Provider {provider_id} not found")
|
||||
# Use composite key
|
||||
cache_key = f"{api}::{provider_id}"
|
||||
if cache_key not in self.dynamic_providers:
|
||||
raise ValueError(f"Provider {provider_id} not found for API {api}")
|
||||
|
||||
conn_info = self.dynamic_providers[cache_key]
|
||||
|
||||
try:
|
||||
# Shutdown provider instance if it exists
|
||||
if provider_id in self.dynamic_provider_impls:
|
||||
impl = self.dynamic_provider_impls[provider_id]
|
||||
if cache_key in self.dynamic_provider_impls:
|
||||
impl = self.dynamic_provider_impls[cache_key]
|
||||
if hasattr(impl, "shutdown"):
|
||||
await impl.shutdown()
|
||||
del self.dynamic_provider_impls[provider_id]
|
||||
del self.dynamic_provider_impls[cache_key]
|
||||
|
||||
# Remove from kvstore
|
||||
await self._delete_connection(provider_id)
|
||||
# Remove from kvstore (using the api and provider_id from conn_info)
|
||||
await self._delete_connection(conn_info.api, provider_id)
|
||||
|
||||
# Remove from runtime cache
|
||||
del self.dynamic_providers[provider_id]
|
||||
del self.dynamic_providers[cache_key]
|
||||
|
||||
logger.info(f"Unregistered dynamic provider {provider_id}")
|
||||
|
||||
|
|
@ -578,23 +592,24 @@ class ProviderImpl(Providers):
|
|||
logger.error(f"Failed to unregister provider {provider_id}: {e}")
|
||||
raise RuntimeError(f"Failed to unregister provider: {e}") from e
|
||||
|
||||
async def test_provider_connection(self, provider_id: str) -> TestProviderConnectionResponse:
|
||||
async def test_provider_connection(self, api: str, provider_id: str) -> TestProviderConnectionResponse:
|
||||
"""Test a provider connection."""
|
||||
logger.info(f"🔍 TEST_PROVIDER_CONNECTION called: provider_id={provider_id}")
|
||||
|
||||
# Check if provider exists (static or dynamic)
|
||||
provider_impl = None
|
||||
cache_key = f"{api}::{provider_id}"
|
||||
|
||||
# Check dynamic providers first (using composite keys)
|
||||
if cache_key in self.dynamic_provider_impls:
|
||||
provider_impl = self.dynamic_provider_impls[cache_key]
|
||||
|
||||
# Check dynamic providers first
|
||||
if provider_id in self.dynamic_provider_impls:
|
||||
provider_impl = self.dynamic_provider_impls[provider_id]
|
||||
# Check static providers
|
||||
elif provider_id in self.deps:
|
||||
if not provider_impl and provider_id in self.deps:
|
||||
provider_impl = self.deps[provider_id]
|
||||
|
||||
if not provider_impl:
|
||||
return TestProviderConnectionResponse(
|
||||
success=False, error_message=f"Provider {provider_id} not found or not initialized"
|
||||
success=False, error_message=f"Provider {provider_id} not found for API {api}"
|
||||
)
|
||||
|
||||
# Check if provider has health method
|
||||
|
|
@ -611,8 +626,8 @@ class ProviderImpl(Providers):
|
|||
health_result = await asyncio.wait_for(provider_impl.health(), timeout=5.0)
|
||||
|
||||
# Update health in dynamic provider cache if applicable
|
||||
if provider_id in self.dynamic_providers:
|
||||
conn_info = self.dynamic_providers[provider_id]
|
||||
if cache_key and cache_key in self.dynamic_providers:
|
||||
conn_info = self.dynamic_providers[cache_key]
|
||||
conn_info.health = ProviderHealth.from_health_response(health_result)
|
||||
conn_info.last_health_check = datetime.now(UTC)
|
||||
await self._store_connection(conn_info)
|
||||
|
|
|
|||
|
|
@ -34,16 +34,21 @@ from llama_stack.apis.synthetic_data_generation import SyntheticDataGeneration
|
|||
from llama_stack.apis.telemetry import Telemetry
|
||||
from llama_stack.apis.tools import RAGToolRuntime, ToolGroups, ToolRuntime
|
||||
from llama_stack.apis.vector_io import VectorIO
|
||||
from llama_stack.core.access_control.datatypes import AccessRule
|
||||
from llama_stack.core.conversations.conversations import ConversationServiceConfig, ConversationServiceImpl
|
||||
from llama_stack.core.datatypes import Provider, SafetyConfig, StackRunConfig, VectorStoresConfig
|
||||
from llama_stack.core.distribution import get_provider_registry
|
||||
from llama_stack.core.distribution import builtin_automatically_routed_apis, get_provider_registry
|
||||
from llama_stack.core.inspect import DistributionInspectConfig, DistributionInspectImpl
|
||||
from llama_stack.core.prompts.prompts import PromptServiceConfig, PromptServiceImpl
|
||||
from llama_stack.core.providers import ProviderImpl, ProviderImplConfig
|
||||
from llama_stack.core.resolver import ProviderRegistry, resolve_impls
|
||||
from llama_stack.core.resolver import (
|
||||
ProviderRegistry,
|
||||
instantiate_provider,
|
||||
sort_providers_by_deps,
|
||||
specs_for_autorouted_apis,
|
||||
validate_and_prepare_providers,
|
||||
)
|
||||
from llama_stack.core.routing_tables.common import CommonRoutingTableImpl
|
||||
from llama_stack.core.access_control.datatypes import AccessRule
|
||||
from llama_stack.core.store.registry import DistributionRegistry
|
||||
from llama_stack.core.storage.datatypes import (
|
||||
InferenceStoreReference,
|
||||
KVStoreReference,
|
||||
|
|
@ -54,10 +59,12 @@ from llama_stack.core.storage.datatypes import (
|
|||
StorageBackendConfig,
|
||||
StorageConfig,
|
||||
)
|
||||
from llama_stack.core.store.registry import create_dist_registry
|
||||
from llama_stack.core.store.registry import DistributionRegistry, create_dist_registry
|
||||
from llama_stack.core.utils.dynamic import instantiate_class_type
|
||||
from llama_stack.log import get_logger
|
||||
from llama_stack.providers.datatypes import Api
|
||||
from llama_stack.providers.utils.kvstore.kvstore import register_kvstore_backends
|
||||
from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends
|
||||
|
||||
logger = get_logger(name=__name__, category="core")
|
||||
|
||||
|
|
@ -401,9 +408,6 @@ def _initialize_storage(run_config: StackRunConfig):
|
|||
else:
|
||||
raise ValueError(f"Unknown storage backend type: {type}")
|
||||
|
||||
from llama_stack.providers.utils.kvstore.kvstore import register_kvstore_backends
|
||||
from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends
|
||||
|
||||
register_kvstore_backends(kv_backends)
|
||||
register_sqlstore_backends(sql_backends)
|
||||
|
||||
|
|
@ -429,9 +433,6 @@ async def resolve_impls_via_provider_registration(
|
|||
Returns:
|
||||
Dictionary mapping API to implementation instances
|
||||
"""
|
||||
from llama_stack.core.distribution import builtin_automatically_routed_apis
|
||||
from llama_stack.core.resolver import sort_providers_by_deps, specs_for_autorouted_apis, validate_and_prepare_providers
|
||||
|
||||
routing_table_apis = {x.routing_table_api for x in builtin_automatically_routed_apis()}
|
||||
router_apis = {x.router_api for x in builtin_automatically_routed_apis()}
|
||||
|
||||
|
|
@ -455,50 +456,29 @@ async def resolve_impls_via_provider_registration(
|
|||
# Register each provider through ProviderImpl
|
||||
impls = internal_impls.copy()
|
||||
|
||||
logger.info(f"🚀 Starting provider registration for {len(sorted_providers)} providers from run.yaml")
|
||||
logger.info(f"Provider registration for {len(sorted_providers)} providers from run.yaml")
|
||||
|
||||
for api_str, provider in sorted_providers:
|
||||
# Skip providers that are not enabled
|
||||
if provider.provider_id is None:
|
||||
continue
|
||||
|
||||
# Skip internal APIs that need special handling
|
||||
# - providers: already initialized as internal_impls
|
||||
# - inspect: already initialized as internal_impls
|
||||
# - telemetry: internal observability, directly instantiated below
|
||||
# Skip internal APIs (already initialized)
|
||||
if api_str in ["providers", "inspect"]:
|
||||
continue
|
||||
|
||||
# Telemetry is an internal API that should be directly instantiated
|
||||
if api_str == "telemetry":
|
||||
logger.info(f"Instantiating {provider.provider_id} for {api_str}")
|
||||
|
||||
from llama_stack.core.resolver import instantiate_provider
|
||||
|
||||
deps = {a: impls[a] for a in provider.spec.api_dependencies if a in impls}
|
||||
for a in provider.spec.optional_api_dependencies:
|
||||
if a in impls:
|
||||
deps[a] = impls[a]
|
||||
|
||||
impl = await instantiate_provider(provider, deps, {}, dist_registry, run_config, policy)
|
||||
api = Api(api_str)
|
||||
impls[api] = impl
|
||||
providers_impl.deps[api] = impl
|
||||
continue
|
||||
|
||||
# Handle different provider types
|
||||
try:
|
||||
# Check if this is a routing table or router (system infrastructure)
|
||||
is_routing_table = api_str.startswith("inner-") or provider.spec.provider_type in ["routing_table", "router"]
|
||||
is_router = not api_str.startswith("inner-") and (Api(api_str) in router_apis or provider.spec.provider_type == "router")
|
||||
# Check if this is a router (system infrastructure)
|
||||
is_router = not api_str.startswith("inner-") and (
|
||||
Api(api_str) in router_apis or provider.spec.provider_type == "router"
|
||||
)
|
||||
|
||||
if api_str.startswith("inner-") or provider.spec.provider_type == "routing_table":
|
||||
# Inner providers or routing tables cannot be registered through the API
|
||||
# They need to be instantiated directly
|
||||
logger.info(f"Instantiating {provider.provider_id} for {api_str}")
|
||||
|
||||
from llama_stack.core.resolver import instantiate_provider
|
||||
|
||||
deps = {a: impls[a] for a in provider.spec.api_dependencies if a in impls}
|
||||
for a in provider.spec.optional_api_dependencies:
|
||||
if a in impls:
|
||||
|
|
@ -510,8 +490,9 @@ async def resolve_impls_via_provider_registration(
|
|||
# For routing tables of autorouted APIs, get inner impls from the router API
|
||||
# E.g., tool_groups routing table needs inner-tool_runtime providers
|
||||
if provider.spec.provider_type == "routing_table":
|
||||
from llama_stack.core.distribution import builtin_automatically_routed_apis
|
||||
autorouted_map = {info.routing_table_api: info.router_api for info in builtin_automatically_routed_apis()}
|
||||
autorouted_map = {
|
||||
info.routing_table_api: info.router_api for info in builtin_automatically_routed_apis()
|
||||
}
|
||||
if Api(api_str) in autorouted_map:
|
||||
router_api_str = autorouted_map[Api(api_str)].value
|
||||
inner_key = f"inner-{router_api_str}"
|
||||
|
|
@ -540,8 +521,6 @@ async def resolve_impls_via_provider_registration(
|
|||
# Router providers also need special handling
|
||||
logger.info(f"Instantiating router {provider.provider_id} for {api_str}")
|
||||
|
||||
from llama_stack.core.resolver import instantiate_provider
|
||||
|
||||
deps = {a: impls[a] for a in provider.spec.api_dependencies if a in impls}
|
||||
for a in provider.spec.optional_api_dependencies:
|
||||
if a in impls:
|
||||
|
|
@ -564,9 +543,9 @@ async def resolve_impls_via_provider_registration(
|
|||
api = Api(api_str)
|
||||
logger.info(f"Registering {provider.provider_id} for {api.value}")
|
||||
|
||||
response = await providers_impl.register_provider(
|
||||
provider_id=provider.provider_id,
|
||||
await providers_impl.register_provider(
|
||||
api=api.value,
|
||||
provider_id=provider.provider_id,
|
||||
provider_type=provider.spec.provider_type,
|
||||
config=provider.config,
|
||||
attributes=getattr(provider, "attributes", None),
|
||||
|
|
@ -580,10 +559,10 @@ async def resolve_impls_via_provider_registration(
|
|||
# IMPORTANT: Update providers_impl.deps so subsequent providers can depend on this one
|
||||
providers_impl.deps[api] = impl
|
||||
|
||||
logger.info(f"✅ Successfully registered startup provider: {provider.provider_id}")
|
||||
logger.info(f"Successfully registered startup provider: {provider.provider_id}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Failed to handle provider {provider.provider_id}: {e}")
|
||||
logger.error(f"Failed to handle provider {provider.provider_id}: {e}")
|
||||
raise
|
||||
|
||||
return impls
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ storage:
|
|||
backends:
|
||||
kv_default:
|
||||
type: kv_sqlite
|
||||
db_path: ":memory:"
|
||||
db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/kvstore.db
|
||||
sql_default:
|
||||
type: sql_sqlite
|
||||
db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/sql_store.db
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register a mock inference provider
|
||||
response = await provider_impl.register_provider(
|
||||
provider_id="test-inference-1",
|
||||
api=Api.inference.value,
|
||||
provider_id="test-inference-1",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "test-key", "url": "https://api.openai.com/v1"},
|
||||
attributes={"team": ["test-team"]},
|
||||
|
|
@ -98,9 +98,9 @@ class TestDynamicProviderManagement:
|
|||
assert response.provider.config["api_key"] == "test-key"
|
||||
assert response.provider.attributes == {"team": ["test-team"]}
|
||||
|
||||
# Verify provider is stored
|
||||
assert "test-inference-1" in provider_impl.dynamic_providers
|
||||
assert "test-inference-1" in provider_impl.dynamic_provider_impls
|
||||
# Verify provider is stored (using composite key)
|
||||
assert "inference::test-inference-1" in provider_impl.dynamic_providers
|
||||
assert "inference::test-inference-1" in provider_impl.dynamic_provider_impls
|
||||
|
||||
async def test_register_vector_store_provider(self, provider_impl):
|
||||
"""Test registering a new vector store provider."""
|
||||
|
|
@ -111,8 +111,8 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register a mock vector_io provider
|
||||
response = await provider_impl.register_provider(
|
||||
provider_id="test-vector-store-1",
|
||||
api=Api.vector_io.value,
|
||||
provider_id="test-vector-store-1",
|
||||
provider_type="inline::faiss",
|
||||
config={"dimension": 768, "index_path": "/tmp/faiss_index"},
|
||||
)
|
||||
|
|
@ -132,8 +132,8 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register first provider
|
||||
await provider_impl.register_provider(
|
||||
provider_id="test-duplicate",
|
||||
api=Api.inference.value,
|
||||
provider_id="test-duplicate",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "key1"},
|
||||
)
|
||||
|
|
@ -141,8 +141,8 @@ class TestDynamicProviderManagement:
|
|||
# Try to register with same ID
|
||||
with pytest.raises(ValueError, match="already exists"):
|
||||
await provider_impl.register_provider(
|
||||
provider_id="test-duplicate",
|
||||
api=Api.inference.value,
|
||||
provider_id="test-duplicate",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "key2"},
|
||||
)
|
||||
|
|
@ -155,14 +155,15 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register provider
|
||||
await provider_impl.register_provider(
|
||||
provider_id="test-update",
|
||||
api=Api.inference.value,
|
||||
provider_id="test-update",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "old-key", "timeout": 30},
|
||||
)
|
||||
|
||||
# Update configuration
|
||||
response = await provider_impl.update_provider(
|
||||
api=Api.inference.value,
|
||||
provider_id="test-update",
|
||||
config={"api_key": "new-key", "timeout": 60},
|
||||
)
|
||||
|
|
@ -181,8 +182,8 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register provider with initial attributes
|
||||
await provider_impl.register_provider(
|
||||
provider_id="test-attributes",
|
||||
api=Api.inference.value,
|
||||
provider_id="test-attributes",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "test-key"},
|
||||
attributes={"team": ["team-a"]},
|
||||
|
|
@ -190,6 +191,7 @@ class TestDynamicProviderManagement:
|
|||
|
||||
# Update attributes
|
||||
response = await provider_impl.update_provider(
|
||||
api=Api.inference.value,
|
||||
provider_id="test-attributes",
|
||||
attributes={"team": ["team-a", "team-b"], "environment": ["prod"]},
|
||||
)
|
||||
|
|
@ -201,6 +203,7 @@ class TestDynamicProviderManagement:
|
|||
"""Test that updating a non-existent provider fails."""
|
||||
with pytest.raises(ValueError, match="not found"):
|
||||
await provider_impl.update_provider(
|
||||
api=Api.inference.value,
|
||||
provider_id="nonexistent",
|
||||
config={"api_key": "new-key"},
|
||||
)
|
||||
|
|
@ -214,21 +217,22 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register provider
|
||||
await provider_impl.register_provider(
|
||||
provider_id="test-unregister",
|
||||
api=Api.inference.value,
|
||||
provider_id="test-unregister",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "test-key"},
|
||||
)
|
||||
|
||||
# Verify it exists
|
||||
assert "test-unregister" in provider_impl.dynamic_providers
|
||||
cache_key = f"{Api.inference.value}::test-unregister"
|
||||
assert cache_key in provider_impl.dynamic_providers
|
||||
|
||||
# Unregister provider
|
||||
await provider_impl.unregister_provider(provider_id="test-unregister")
|
||||
await provider_impl.unregister_provider(api=Api.inference.value, provider_id="test-unregister")
|
||||
|
||||
# Verify it's removed
|
||||
assert "test-unregister" not in provider_impl.dynamic_providers
|
||||
assert "test-unregister" not in provider_impl.dynamic_provider_impls
|
||||
assert cache_key not in provider_impl.dynamic_providers
|
||||
assert cache_key not in provider_impl.dynamic_provider_impls
|
||||
|
||||
# Verify shutdown was called
|
||||
mock_provider_instance.shutdown.assert_called_once()
|
||||
|
|
@ -236,7 +240,7 @@ class TestDynamicProviderManagement:
|
|||
async def test_unregister_nonexistent_provider_fails(self, provider_impl):
|
||||
"""Test that unregistering a non-existent provider fails."""
|
||||
with pytest.raises(ValueError, match="not found"):
|
||||
await provider_impl.unregister_provider(provider_id="nonexistent")
|
||||
await provider_impl.unregister_provider(api=Api.inference.value, provider_id="nonexistent")
|
||||
|
||||
async def test_test_provider_connection_healthy(self, provider_impl):
|
||||
"""Test testing a healthy provider connection."""
|
||||
|
|
@ -246,14 +250,14 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register provider
|
||||
await provider_impl.register_provider(
|
||||
provider_id="test-health",
|
||||
api=Api.inference.value,
|
||||
provider_id="test-health",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "test-key"},
|
||||
)
|
||||
|
||||
# Test connection
|
||||
response = await provider_impl.test_provider_connection(provider_id="test-health")
|
||||
response = await provider_impl.test_provider_connection(api=Api.inference.value, provider_id="test-health")
|
||||
|
||||
# Verify response
|
||||
assert response.success is True
|
||||
|
|
@ -271,14 +275,16 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register provider
|
||||
await provider_impl.register_provider(
|
||||
provider_id="test-unhealthy",
|
||||
api=Api.inference.value,
|
||||
provider_id="test-unhealthy",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "invalid-key"},
|
||||
)
|
||||
|
||||
# Test connection
|
||||
response = await provider_impl.test_provider_connection(provider_id="test-unhealthy")
|
||||
response = await provider_impl.test_provider_connection(
|
||||
api=Api.inference.value, provider_id="test-unhealthy"
|
||||
)
|
||||
|
||||
# Verify response shows unhealthy status
|
||||
assert response.success is False
|
||||
|
|
@ -292,15 +298,15 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register multiple providers
|
||||
await provider_impl.register_provider(
|
||||
provider_id="dynamic-1",
|
||||
api=Api.inference.value,
|
||||
provider_id="dynamic-1",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "key1"},
|
||||
)
|
||||
|
||||
await provider_impl.register_provider(
|
||||
provider_id="dynamic-2",
|
||||
api=Api.vector_io.value,
|
||||
provider_id="dynamic-2",
|
||||
provider_type="inline::faiss",
|
||||
config={"dimension": 768},
|
||||
)
|
||||
|
|
@ -321,8 +327,8 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register provider
|
||||
await provider_impl.register_provider(
|
||||
provider_id="test-inspect",
|
||||
api=Api.inference.value,
|
||||
provider_id="test-inspect",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "test-key", "model": "gpt-4"},
|
||||
)
|
||||
|
|
@ -330,14 +336,17 @@ class TestDynamicProviderManagement:
|
|||
# Update the stored health info to reflect OK status
|
||||
# (In reality, the health check happens during registration,
|
||||
# but our mock may not have been properly called)
|
||||
conn_info = provider_impl.dynamic_providers["test-inspect"]
|
||||
cache_key = f"{Api.inference.value}::test-inspect"
|
||||
conn_info = provider_impl.dynamic_providers[cache_key]
|
||||
|
||||
conn_info.health = ProviderHealth.from_health_response({"status": HealthStatus.OK})
|
||||
|
||||
# Inspect provider
|
||||
provider_info = await provider_impl.inspect_provider(provider_id="test-inspect")
|
||||
response = await provider_impl.inspect_provider(provider_id="test-inspect")
|
||||
|
||||
# Verify provider info
|
||||
# Verify response
|
||||
assert len(response.data) == 1
|
||||
provider_info = response.data[0]
|
||||
assert provider_info.provider_id == "test-inspect"
|
||||
assert provider_info.api == Api.inference.value
|
||||
assert provider_info.provider_type == "remote::openai"
|
||||
|
|
@ -352,8 +361,8 @@ class TestDynamicProviderManagement:
|
|||
with patch.object(provider_impl, "_instantiate_provider", return_value=mock_provider_instance):
|
||||
# Register provider
|
||||
await provider_impl.register_provider(
|
||||
provider_id="test-persist",
|
||||
api=Api.inference.value,
|
||||
provider_id="test-persist",
|
||||
provider_type="remote::openai",
|
||||
config={"api_key": "persist-key"},
|
||||
)
|
||||
|
|
@ -397,5 +406,6 @@ class TestDynamicProviderManagement:
|
|||
await new_impl._load_dynamic_providers()
|
||||
|
||||
# Verify the provider was loaded from kvstore
|
||||
assert "test-persist" in new_impl.dynamic_providers
|
||||
assert new_impl.dynamic_providers["test-persist"].config["api_key"] == "persist-key"
|
||||
cache_key = f"{Api.inference.value}::test-persist"
|
||||
assert cache_key in new_impl.dynamic_providers
|
||||
assert new_impl.dynamic_providers[cache_key].config["api_key"] == "persist-key"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue