Files
vecna/pkg/server/spec/openapi.yaml
T
warkanum 1953a4f4f9 feat(server): add passthrough proxy for OpenAI-compatible endpoints
* implement proxy handler for various OpenAI API routes
* add error handling for request body and response streaming
* introduce new error response format for API compatibility
* add tests for recover middleware to handle panics gracefully
2026-08-01 20:15:59 +02:00

453 lines
12 KiB
YAML

openapi: "3.1.0"
info:
title: vecna Embedding Adapter
description: >
Proxies text to a backing embedding model and adapts the result vectors
between dimensions. Also forwards the rest of the OpenAI-compatible API
surface (chat, completions, models, audio, images, moderations, rerank)
verbatim to the resolved target, with no adaptation applied.
version: "1.0.0"
servers:
- url: http://localhost:8080
security:
- BearerAuth: []
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
schemas:
Error:
type: object
properties:
error:
type: object
properties:
message:
type: string
type:
type: string
code:
type: integer
OpenAIEmbedRequest:
type: object
required: [input, model]
properties:
input:
oneOf:
- type: string
- type: array
items:
type: string
model:
type: string
OpenAIEmbedResponse:
type: object
properties:
object:
type: string
example: list
model:
type: string
data:
type: array
items:
type: object
properties:
object:
type: string
example: embedding
index:
type: integer
embedding:
type: array
items:
type: number
format: float
usage:
type: object
properties:
prompt_tokens:
type: integer
total_tokens:
type: integer
GoogleEmbedContentRequest:
type: object
required: [content]
properties:
content:
type: object
properties:
parts:
type: array
items:
type: object
properties:
text:
type: string
taskType:
type: string
GoogleEmbedContentResponse:
type: object
properties:
embedding:
type: object
properties:
values:
type: array
items:
type: number
format: float
GoogleBatchRequest:
type: object
required: [requests]
properties:
requests:
type: array
items:
$ref: '#/components/schemas/GoogleEmbedContentRequest'
GoogleBatchResponse:
type: object
properties:
embeddings:
type: array
items:
type: object
properties:
values:
type: array
items:
type: number
format: float
headers:
X-Vecna-Forward-Ms:
description: Time spent forwarding the request to the backing model (milliseconds).
schema:
type: integer
X-Vecna-Translate-Ms:
description: Time spent in the dimension adapter (milliseconds).
schema:
type: integer
X-Vecna-Total-Ms:
description: Total request wall-clock time (milliseconds).
schema:
type: integer
paths:
/v1/embeddings:
post:
summary: OpenAI-compatible embeddings
operationId: openaiEmbeddings
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OpenAIEmbedRequest'
responses:
"200":
description: Adapted embeddings
headers:
X-Vecna-Forward-Ms:
$ref: '#/components/headers/X-Vecna-Forward-Ms'
X-Vecna-Translate-Ms:
$ref: '#/components/headers/X-Vecna-Translate-Ms'
X-Vecna-Total-Ms:
$ref: '#/components/headers/X-Vecna-Total-Ms'
content:
application/json:
schema:
$ref: '#/components/schemas/OpenAIEmbedResponse'
"400":
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
"401":
description: Unauthorized
"502":
description: Backing model error
get:
summary: OpenAI-compatible embeddings (query-param convenience form)
operationId: openaiEmbeddingsGet
parameters:
- name: input
in: query
required: true
description: Repeatable — one or more texts to embed.
schema:
type: array
items:
type: string
- name: model
in: query
schema:
type: string
responses:
"200":
description: Adapted embeddings
content:
application/json:
schema:
$ref: '#/components/schemas/OpenAIEmbedResponse'
"400":
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/models/{model}:embedContent:
post:
summary: Google-compatible single embedContent
operationId: googleEmbedContent
parameters:
- name: model
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/GoogleEmbedContentRequest'
responses:
"200":
description: Adapted embedding
headers:
X-Vecna-Forward-Ms:
$ref: '#/components/headers/X-Vecna-Forward-Ms'
X-Vecna-Translate-Ms:
$ref: '#/components/headers/X-Vecna-Translate-Ms'
X-Vecna-Total-Ms:
$ref: '#/components/headers/X-Vecna-Total-Ms'
content:
application/json:
schema:
$ref: '#/components/schemas/GoogleEmbedContentResponse'
"400":
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/models/{model}:batchEmbedContents:
post:
summary: Google-compatible batch batchEmbedContents
operationId: googleBatchEmbedContents
parameters:
- name: model
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/GoogleBatchRequest'
responses:
"200":
description: Adapted embeddings
headers:
X-Vecna-Forward-Ms:
$ref: '#/components/headers/X-Vecna-Forward-Ms'
X-Vecna-Translate-Ms:
$ref: '#/components/headers/X-Vecna-Translate-Ms'
X-Vecna-Total-Ms:
$ref: '#/components/headers/X-Vecna-Total-Ms'
content:
application/json:
schema:
$ref: '#/components/schemas/GoogleBatchResponse'
"400":
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
"401":
description: Unauthorized
"502":
description: Backing model error
# --- Generic OpenAI-compatible passthrough -------------------------------
# Forwarded verbatim to the resolved target (chosen by the body's "model"
# field, falling back to forward.default). No vecna-specific processing —
# request/response shape is whatever the backing model's API defines.
# Each also exists under /map/{mapping}/... to force a specific target.
/v1/models:
get:
summary: List models (passthrough)
operationId: listModels
responses:
"200":
description: Backend-defined model list
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/models/{model}:
get:
summary: Retrieve a model (passthrough)
operationId: retrieveModel
parameters:
- name: model
in: path
required: true
schema:
type: string
responses:
"200":
description: Backend-defined model object
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/chat/completions:
post:
summary: Chat completions (passthrough, streaming supported)
operationId: chatCompletions
responses:
"200":
description: Backend-defined chat completion (or SSE stream if "stream":true)
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/completions:
post:
summary: Legacy completions (passthrough, streaming supported)
operationId: completions
responses:
"200":
description: Backend-defined completion (or SSE stream if "stream":true)
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/moderations:
post:
summary: Moderations (passthrough)
operationId: moderations
responses:
"200":
description: Backend-defined moderation result
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/images/generations:
post:
summary: Image generation (passthrough)
operationId: imageGenerations
responses:
"200":
description: Backend-defined image result
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/images/edits:
post:
summary: Image edits (passthrough, multipart/form-data)
operationId: imageEdits
responses:
"200":
description: Backend-defined image result
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/images/variations:
post:
summary: Image variations (passthrough, multipart/form-data)
operationId: imageVariations
responses:
"200":
description: Backend-defined image result
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/audio/speech:
post:
summary: Text-to-speech (passthrough)
operationId: audioSpeech
responses:
"200":
description: Backend-defined audio bytes
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/audio/transcriptions:
post:
summary: Speech-to-text (passthrough, multipart/form-data)
operationId: audioTranscriptions
responses:
"200":
description: Backend-defined transcription
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/audio/translations:
post:
summary: Speech translation (passthrough, multipart/form-data)
operationId: audioTranslations
responses:
"200":
description: Backend-defined translation
"401":
description: Unauthorized
"502":
description: Backing model error
/v1/rerank:
post:
summary: Rerank (passthrough — Cohere/Infinity/vLLM-style)
operationId: rerank
responses:
"200":
description: Backend-defined rerank result
"401":
description: Unauthorized
"502":
description: Backing model error