Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions apis/paios/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,8 @@ paths:
- $ref: '#/components/parameters/id'
/shares:
get:
security:
- jwt: []
tags:
- Share Management
summary: Retrieve all share links
Expand All @@ -721,6 +723,8 @@ paths:
X-Total-Count:
$ref: '#/components/headers/X-Total-Count'
post:
security:
- jwt: []
summary: Create new share link
tags:
- Share Management
Expand All @@ -737,6 +741,8 @@ paths:
$ref: '#/components/schemas/ShareCreate'
'/shares/{id}':
get:
security:
- jwt: []
tags:
- Share Management
summary: Retrieve share link by id
Expand All @@ -751,6 +757,8 @@ paths:
schema:
$ref: '#/components/schemas/Share'
put:
security:
- jwt: []
tags:
- Share Management
summary: Update share link by id
Expand All @@ -766,6 +774,8 @@ paths:
'200':
description: OK
delete:
security:
- jwt: []
tags:
- Share Management
summary: Delete share link by id
Expand All @@ -777,6 +787,84 @@ paths:
description: No Content
'404':
description: Not Found
/llms:
get:
security:
- jwt: []
tags:
- LLM Management
summary: Retrieve all available LLMs
description: Get all installed / available LLMs.
parameters:
- $ref: '#/components/parameters/sort'
- $ref: '#/components/parameters/range'
- $ref: '#/components/parameters/filter'
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Llm'
headers:
X-Total-Count:
$ref: '#/components/headers/X-Total-Count'
'/llms/{id}':
get:
security:
- jwt: []
tags:
- LLM Management
summary: Retrieve LLM by id
description: Retrieve the LLM with the specified id.
parameters:
- $ref: '#/components/parameters/kebab-dot_id'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Llm'
'404':
description: LLM not found
'/llms/{id}/completion':
post:
security:
- jwt: []
tags:
- LLM Management
summary: Invoke Completion on LLM
description: Invoke Completion on the LLM with the specified id.
operationId: backend.api.LlmsView.completion
parameters:
- $ref: '#/components/parameters/kebab-dot_id'
requestBody:
description: Messages to input to Completion function.
content:
application/json:
schema:
type: object
properties:
messages:
$ref: '#/components/schemas/messagesList'
optional_params:
$ref: '#/components/schemas/completionParamList'
required:
- messages
responses:
'200':
description: Completion succeeded
content:
application/json:
schema:
type: string
'400':
description: Completion failed
'404':
description: LLM not found
/auth/webauthn/register-options:
post:
summary: Generate WebAuthn registration options
Expand Down Expand Up @@ -901,6 +989,8 @@ tags:
description: Management of personas
- name: Share Management
description: Management of share links
- name: LLM Management
description: Discovery and invocation of LLM functionality
components:
securitySchemes:
jwt:
Expand Down Expand Up @@ -936,6 +1026,13 @@ components:
required: true
schema:
$ref: '#/components/schemas/kebab-snake_id'
kebab-dot_id:
name: id
in: path
description: id of the object
required: true
schema:
$ref: '#/components/schemas/kebab-dot_id'
key:
name: key
in: path
Expand Down Expand Up @@ -1003,6 +1100,12 @@ components:
maxLength: 100
example: langchain-core
pattern: ^[a-z0-9]+([_-][a-z0-9]+)*$
kebab-dot_id:
type: string
minLength: 2
maxLength: 100
example: ollama-llama3.2
pattern: ^[a-z0-9]+([.-][a-z0-9]+)*$
semVer:
type: string
example: '1.1.0'
Expand Down Expand Up @@ -1068,6 +1171,19 @@ components:
readOnly: true
example: abcd-efgh-ijkl
pattern: ^[a-z]{4}-[a-z]{4}-[a-z]{4}$
messagesList:
type: array
example: [{"role": "user", "content": "What is Personal AI?"}]
items:
type: object
properties:
role:
type: string
content:
type: string
completionParamList:
type: object
example: {"max_tokens": 50, "temperature": 0.2}
download:
type: object
properties:
Expand Down Expand Up @@ -1390,6 +1506,29 @@ components:
example: false
required:
- resource_id
Llm:
type: object
title: Llm
properties:
id:
type: string
name:
type: string
full_name:
type: string
provider:
type: string
api_base:
type: string
nullable: true
is_active:
type: boolean
required:
- id
- name
- full_name
- provider
- is_active
RegistrationOptions:
type: object
properties:
Expand Down
54 changes: 54 additions & 0 deletions backend/api/LlmsView.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from starlette.responses import JSONResponse
from backend.managers.ModelsManager import ModelsManager
from backend.pagination import parse_pagination_params
from backend.schemas import LlmSchema
from litellm.exceptions import BadRequestError

class LlmsView:
def __init__(self):
self.mm = ModelsManager()

async def get(self, id: str):
llm = await self.mm.get_llm(id)
if llm is None:
return JSONResponse(headers={"error": "LLM not found"}, status_code=404)
llm_schema = LlmSchema(id=llm.id, name=llm.name, provider=llm.provider, full_name=llm.aisuite_name,
api_base=llm.api_base, is_active=llm.is_active)
return JSONResponse(llm_schema.model_dump(), status_code=200)

async def search(self, filter: str = None, range: str = None, sort: str = None):
result = parse_pagination_params(filter, range, sort)
if isinstance(result, JSONResponse):
return result

offset, limit, sort_by, sort_order, filters = result

llms, total_count = await self.mm.retrieve_llms(limit=limit, offset=offset, sort_by=sort_by, sort_order=sort_order, filters=filters)
results = [LlmSchema(id=llm.id, name=llm.name, provider=llm.provider, full_name=llm.aisuite_name,
api_base=llm.api_base, is_active=llm.is_active)
for llm in llms]
headers = {
'X-Total-Count': str(total_count),
'Content-Range': f'shares {offset}-{offset + len(llms) - 1}/{total_count}'
}
return JSONResponse([llm.model_dump() for llm in results], status_code=200, headers=headers)

async def completion(self, id: str, body: dict):
print("completion. body: {}".format(body))
llm = await self.mm.get_llm(id)
if llm:
messages = []
if 'messages' in body and body['messages']:
messages = body['messages']
opt_params = {}
if 'optional_params' in body and body['optional_params']:
opt_params = body['optional_params']
try:
response = self.mm.completion(llm, messages, **opt_params)
return JSONResponse(response.choices[0].message.content, status_code=200)
except BadRequestError as e:
return JSONResponse(status_code=400, content={"message": e.message})
except Exception as e:
return JSONResponse(status_code=400, content={"message": "Completion failed."})
else:
return JSONResponse(status_code=404, content={"message": "LLM not found"})
1 change: 1 addition & 0 deletions backend/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
from .PersonasView import PersonasView
from .SharesView import SharesView
from .AuthView import AuthView
from .LlmsView import LlmsView
Loading
Loading