This commit is contained in:
Juan V. 2026-10-20 21:46:01 -07:00 • committed by GitHub
commit a35f53a3cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 3093 additions and 4 deletions

View file

@ -109,6 +109,7 @@ GATEWAY_PATH_PREFIXES: tuple[str, ...] = (
"/vllm/",
"/mistral/",
"/typesafe/",
"/eu_jev/",
"/openrouter/",
"/nvidia_nim/",
"/groq/",

View file

@ -72264,6 +72264,28 @@
"source": "https://docs.typesafe.ai/models",
"supports_box_questions": true
},
"eu_jev/eu-jeff-1.0.0": {
"input_cost_per_token": 4.15e-08,
"litellm_provider": "eu_jev",
"max_input_tokens": 32768,
"mode": "evaluation",
"output_cost_per_token": 0.0,
"source": "https://eu-jev.com/docs",
"supported_endpoints": [
"/v1/systemone"
]
},
"eu_jev/eu-jeff-latest": {
"input_cost_per_token": 4.15e-08,
"litellm_provider": "eu_jev",
"max_input_tokens": 32768,
"mode": "evaluation",
"output_cost_per_token": 0.0,
"source": "https://eu-jev.com/docs",
"supported_endpoints": [
"/v1/systemone"
]
},
"wandb/deepseek-ai/DeepSeek-V4.1-Flash": {
"cache_read_input_token_cost": 3e-08,
"input_cost_per_token": 2e-07,

View file

@ -233,6 +233,7 @@ LAZY_FEATURES: Final[tuple[LazyFeature, ...]] = (
"/tinyfish/",
"/transcribe",
"/typesafe/",
"/eu_jev/",
"/laya/",
"/bespoke/",
"/openrouter/",

File diff suppressed because it is too large Load diff

View file

@ -411,6 +411,7 @@ class LiteLLMRoutes(enum.Enum):
"/vllm",
"/mistral",
"/typesafe",
"/eu_jev",
"/laya",
"/bespoke",
"/openrouter",

View file

@ -88,6 +88,7 @@ from litellm.proxy.common_request_processing import (
model_deployments_support_stream_options,
open_sse_before_first_byte,
)
from litellm.proxy.common_utils.custom_openapi_spec import inline_request_body
from litellm.proxy.common_utils.http_parsing_utils import ( # noqa: F401 # legacy module exports
_read_request_body, # pyright: ignore[reportPrivateUsage,reportUnusedImport] # backwards-compatible package export
_safe_get_request_headers, # pyright: ignore[reportPrivateUsage,reportUnusedImport] # backwards-compatible package export
@ -123,6 +124,7 @@ from litellm.proxy.vector_store_endpoints.utils import (
is_allowed_to_call_vector_store_endpoint,
)
from litellm.secret_managers.main import get_secret_str, normalize_nonempty_secret_str, str_to_bool
from litellm.types.passthrough_endpoints.eu_jev import EuJevDecisionRequest, EuJevDecisionResponse
from litellm.types.passthrough_endpoints.pass_through_endpoints import (
LITELLM_PASS_THROUGH_CUSTOM_BODY_STATE_KEY,
LITELLM_PASS_THROUGH_DEPLOYMENT_MODEL_INFO_STATE_KEY,
@ -691,6 +693,81 @@ async def typesafe_proxy_route(
return await endpoint_func(request, fastapi_response, user_api_key_dict)
_EU_JEV_DECISION_REQUEST_BODY: Final = inline_request_body(
EuJevDecisionRequest,
{
"model": "eu-jeff-latest",
"state": "I was charged twice. Can I get a refund?",
"questions": {
"team": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {"billing": "Payments, invoices, and refunds", "support": "Technical issues and bugs"},
},
"is_refund_request": {"type": "noul", "instructions": "Is the customer asking for a refund?"},
"frustration": {
"type": "score",
"instructions": "How frustrated is the customer?",
"criteria": ["calm", "mildly annoyed", "angry"],
},
},
},
)
@router.api_route(
"/eu_jev/{endpoint:path}",
methods=["GET", "POST", "PUT", "DELETE", "PATCH"],
tags=["eu/jev Pass-through", "pass-through"],
responses={200: {"model": EuJevDecisionResponse}},
openapi_extra={"requestBody": _EU_JEV_DECISION_REQUEST_BODY},
)
async def eu_jev_proxy_route(
endpoint: str,
request: Request,
fastapi_response: Response,
user_api_key_dict: Annotated[UserAPIKeyAuth, Depends(user_api_key_auth)],
) -> Response:
"""
Forward a request to eu/jev, an EU-hosted decision API, with `EU_JEV_API_KEY`.
`POST /eu_jev/v1/systemone` sends a `state` and one to eight named `questions` (`choice`, `noul` or `score`)
and returns one answer per question name, with spend booked from the reported `usage`. `custom_body` is
rejected with a 400.
[Docs](https://docs.litellm.ai/docs/pass_through/eu_jev)
"""
body: Final = TypeAdapter(dict[str, object]).validate_python(await read_request_body(request))
if "custom_body" in body:
raise HTTPException(status_code=400, detail="custom_body is not supported for eu_jev requests")
if body.get("stream"):
raise HTTPException(status_code=400, detail="Streaming is not supported for eu_jev requests")
base_target_url: Final = get_secret_str("EU_JEV_API_BASE") or "https://eu-jev.com"
encoded_endpoint: Final = httpx.URL(endpoint).path
normalized_endpoint: Final = encoded_endpoint if encoded_endpoint.startswith("/") else f"/{encoded_endpoint}"
base_url: Final = httpx.URL(base_target_url)
updated_url: Final = base_url.copy_with(
path=HttpPassThroughEndpointHelpers.join_base_and_endpoint_path(base_url, normalized_endpoint),
)
eu_jev_api_key: Final = passthrough_endpoint_router.get_credentials(
custom_llm_provider="eu_jev",
region_name=None,
)
endpoint_func: Final = create_pass_through_route(
endpoint=endpoint,
target=str(updated_url),
custom_headers={
"Authorization": f"Bearer {eu_jev_api_key}",
"Content-Type": "application/json",
},
custom_llm_provider="eu_jev",
is_streaming_request=False,
)
return TypeAdapter(Response, config=ConfigDict(arbitrary_types_allowed=True)).validate_python(
await endpoint_func(request, fastapi_response, user_api_key_dict)
)
@router.post(
"/laya/v1/systemone",
tags=["Laya Pass-through", "pass-through"],

View file

@ -409,9 +409,9 @@ class HttpPassThroughEndpointHelpers(BasePassthroughUtils):
@staticmethod
def get_endpoint_type(url: str, custom_llm_provider: str | None = None) -> EndpointType:
parsed_url: Final = urlparse(url)
if custom_llm_provider in ("typesafe", "laya", "bespoke") and parsed_url.path.removesuffix("/").endswith(
"/v1/systemone"
):
if custom_llm_provider in ("typesafe", "eu_jev", "laya", "bespoke") and parsed_url.path.removesuffix(
"/"
).endswith("/v1/systemone"):
return EndpointType.DECISIONS
if (
("generateContent") in url

View file

@ -338,7 +338,7 @@ class PassThroughEndpointLogging:
kwargs = transcribe_handler_result["kwargs"] # rebind-ok: elif-chain contract
elif (
self.is_typesafe_route(custom_llm_provider)
or custom_llm_provider in ("laya", "bespoke")
or custom_llm_provider in ("eu_jev", "laya", "bespoke")
or self.is_openrouter_decisions_route(url_route, custom_llm_provider)
):
from .llm_provider_handlers.typesafe_passthrough_logging_handler import (

View file

@ -0,0 +1,100 @@
from collections.abc import Mapping, Sequence
from typing import Annotated, Literal, TypeAlias
from pydantic import ConfigDict, Field
from litellm.types.decisions import ChoiceAnswer, DecisionsJSON, NoulAnswer, NoulCriteria, ScoreAnswer
from litellm.types.llms.base import LiteLLMPydanticObjectBase
EuJevEntry: TypeAlias = Annotated[
DecisionsJSON | None,
Field(description="Free text, or a JSON object, array or null that eu/jev serializes to text before inference"),
]
class EuJevChoiceQuestion(LiteLLMPydanticObjectBase):
type: Literal["choice"]
instructions: EuJevEntry
criteria: Annotated[
Mapping[str, EuJevEntry],
Field(
min_length=2,
max_length=64,
description="Two to 64 options, option name to description. A null description uses the option name",
),
]
model_config = ConfigDict(frozen=True)
class EuJevNoulQuestion(LiteLLMPydanticObjectBase):
type: Literal["noul"]
instructions: EuJevEntry
criteria: Annotated[NoulCriteria | None, Field(description="Optional descriptions of what true and false mean")] = (
None
)
model_config = ConfigDict(frozen=True)
class EuJevScoreQuestion(LiteLLMPydanticObjectBase):
type: Literal["score"]
instructions: EuJevEntry
criteria: Annotated[
Sequence[EuJevEntry],
Field(min_length=2, max_length=10, description="Two to 10 level descriptions, ordered from low to high"),
]
model_config = ConfigDict(frozen=True)
EuJevQuestion: TypeAlias = Annotated[
EuJevChoiceQuestion | EuJevNoulQuestion | EuJevScoreQuestion,
Field(discriminator="type"),
]
class EuJevDecisionRequest(LiteLLMPydanticObjectBase):
model: Annotated[str, Field(description="eu-jeff-latest follows the current release, eu-jeff-1.0.0 pins it")] = (
"eu-jeff-latest"
)
state: Annotated[
Annotated[str, Field(min_length=1, max_length=100_000)] | Mapping[str, object] | Sequence[object],
Field(description="The content to evaluate, a string of up to 100,000 characters or a JSON object or array"),
]
questions: Annotated[
Mapping[Annotated[str, Field(min_length=1, max_length=80)], EuJevQuestion],
Field(min_length=1, max_length=8, description="One to eight questions, keyed by names of up to 80 characters"),
]
model_config = ConfigDict(frozen=True)
EuJevAnswer: TypeAlias = Annotated[ChoiceAnswer | NoulAnswer | ScoreAnswer, Field(discriminator="type")]
class EuJevUsage(LiteLLMPydanticObjectBase):
input_tokens: Annotated[int, Field(ge=0)]
output_tokens: Annotated[int, Field(ge=0)]
model_config = ConfigDict(frozen=True)
class EuJevMeta(LiteLLMPydanticObjectBase):
request_id: str
mode: Literal["live"]
latency_ms: Annotated[
int, Field(description="Server-side time for token quoting, credit reservation and inference")
]
cost_eur: Annotated[str | None, Field(description="The exact charge in euros, on authenticated requests")] = None
model_config = ConfigDict(frozen=True)
class EuJevDecisionResponse(LiteLLMPydanticObjectBase):
model: Annotated[str, Field(description="The release that answered, such as eu-jeff-1.0.0")]
answers: Annotated[Mapping[str, EuJevAnswer], Field(description="One answer per question, under the same names")]
usage: EuJevUsage
meta: EuJevMeta
model_config = ConfigDict(frozen=True)

View file

@ -72264,6 +72264,28 @@
"source": "https://docs.typesafe.ai/models",
"supports_box_questions": true
},
"eu_jev/eu-jeff-1.0.0": {
"input_cost_per_token": 4.15e-08,
"litellm_provider": "eu_jev",
"max_input_tokens": 32768,
"mode": "evaluation",
"output_cost_per_token": 0.0,
"source": "https://eu-jev.com/docs",
"supported_endpoints": [
"/v1/systemone"
]
},
"eu_jev/eu-jeff-latest": {
"input_cost_per_token": 4.15e-08,
"litellm_provider": "eu_jev",
"max_input_tokens": 32768,
"mode": "evaluation",
"output_cost_per_token": 0.0,
"source": "https://eu-jev.com/docs",
"supported_endpoints": [
"/v1/systemone"
]
},
"wandb/deepseek-ai/DeepSeek-V4.1-Flash": {
"cache_read_input_token_cost": 3e-08,
"input_cost_per_token": 2e-07,

View file

@ -366,3 +366,44 @@ def test_success_handler_skips_typesafe_pricing_for_non_decisions_openrouter_rou
assert normalized["standard_logging_response_object"] is None
assert "combined_usage_object" not in normalized["kwargs"]
assert normalized["kwargs"].get("model") != "openrouter/typesafe/jev-1.13-20260917"
def test_eu_jev_decision_is_priced_from_its_registry_row():
model_cost: Final = litellm.model_cost["eu_jev/eu-jeff-1.0.0"]
response = TypeSafePassthroughLoggingHandler.typesafe_passthrough_handler(
httpx_response=_response(),
response_body={"model": "eu-jeff-1.0.0", "usage": {"input_tokens": 64, "output_tokens": 0}},
logging_obj=_logging_obj(),
url_route="https://eu-jev.com/v1/systemone",
result='{"answers": {}}',
start_time=datetime.now(),
end_time=datetime.now(),
cache_hit=False,
request_body={"model": "eu-jeff-latest"},
custom_llm_provider="eu_jev",
)
assert response["kwargs"]["model"] == "eu_jev/eu-jeff-1.0.0"
assert response["kwargs"]["custom_llm_provider"] == "eu_jev"
assert response["kwargs"]["response_cost"] == pytest.approx(64 * model_cost["input_cost_per_token"])
assert response["kwargs"]["response_cost"] > 0
assert response["kwargs"]["combined_usage_object"].prompt_tokens == 64
assert response["kwargs"]["combined_usage_object"].completion_tokens == 0
def test_success_handler_dispatches_eu_jev_to_the_shared_handler():
normalized = PassThroughEndpointLogging().normalize_llm_passthrough_logging_payload(
httpx_response=_response(),
response_body={"model": "eu-jeff-1.0.0", "usage": {"input_tokens": 64, "output_tokens": 0}},
request_body={"model": "eu-jeff-latest"},
logging_obj=_logging_obj(),
url_route="https://eu-jev.com/v1/systemone",
result="{}",
start_time=datetime.now(),
end_time=datetime.now(),
cache_hit=False,
custom_llm_provider="eu_jev",
)
assert normalized["kwargs"]["custom_llm_provider"] == "eu_jev"
assert normalized["kwargs"]["model"] == "eu_jev/eu-jeff-1.0.0"

View file

@ -51,6 +51,7 @@ from litellm.proxy.pass_through_endpoints.llm_passthrough_endpoints import (
bedrock_proxy_route,
create_pass_through_route,
cursor_proxy_route,
eu_jev_proxy_route,
fal_ai_proxy_route,
get_azure_ai_search_index_from_endpoint,
get_vertex_base_url,
@ -8324,6 +8325,120 @@ class TestTypeSafePassthroughRoute:
)
class TestEuJevPassthroughRoute:
@staticmethod
def _request(body: object, query_params: Mapping[str, str] | None = None) -> MagicMock:
request = MagicMock(spec=Request)
request.method = "POST"
request.query_params = query_params or {}
request.json = AsyncMock(return_value=body)
return request
@pytest.fixture
def client(self, monkeypatch: pytest.MonkeyPatch) -> Iterator[TestClient]:
from litellm.proxy.proxy_server import app
monkeypatch.setenv("EU_JEV_API_KEY", "eu-jev-test-key")
monkeypatch.setenv("EU_JEV_API_BASE", "https://eu-jev.example/base")
monkeypatch.delenv("SERVER_ROOT_PATH", raising=False)
monkeypatch.setattr(litellm, "disable_aiohttp_transport", True)
litellm.in_memory_llm_clients_cache.flush_cache()
monkeypatch.setitem(app.dependency_overrides, user_api_key_auth, lambda: UserAPIKeyAuth(api_key="sk-virtual"))
yield TestClient(app)
def test_forwards_a_decision_upstream_with_the_eu_jev_key(self, client: TestClient) -> None:
body: Final = {"model": "eu-jeff-latest", "state": "x"}
with respx.mock(assert_all_called=True) as upstream:
route = upstream.post("https://eu-jev.example/base/v1/systemone").mock(
return_value=httpx.Response(200, json={"id": "upstream_123"})
)
response = client.post("/eu_jev/v1/systemone", json=body)
assert (response.status_code, response.json()) == (200, {"id": "upstream_123"})
sent: Final = route.calls.last.request
assert sent.headers["authorization"] == "Bearer eu-jev-test-key"
assert json.loads(sent.content) == body
def test_rejects_custom_body_that_would_replace_the_authorized_request(self, client: TestClient) -> None:
smuggled: Final = {"model": "eu-jeff-latest", "state": "refund", "questions": {"q": {"type": "noul"}}}
with respx.mock(assert_all_called=False) as upstream:
route: Final = upstream.post("https://eu-jev.example/base/v1/systemone").respond(200, json={"answers": {}})
response: Final = client.post("/eu_jev/v1/systemone", json={"model": "gpt-4o", "custom_body": smuggled})
assert response.status_code == 400
assert "custom_body" in response.text
assert not route.called
def test_rejects_streaming_that_would_skip_spend_tracking(self, client: TestClient) -> None:
with respx.mock(assert_all_called=False) as upstream:
route: Final = upstream.post("https://eu-jev.example/base/v1/systemone").respond(200, json={"answers": {}})
response: Final = client.post(
"/eu_jev/v1/systemone", json={"model": "eu-jeff-latest", "state": "x", "stream": True}
)
assert response.status_code == 400
assert "Streaming" in response.text
assert not route.called
@pytest.mark.asyncio
async def test_forwards_target_auth_headers_provider_and_query(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("EU_JEV_API_KEY", "eu-jev-test-key")
monkeypatch.setenv("EU_JEV_API_BASE", "https://eu-jev.example/base")
async def fake_upstream(request, *_args):
target: Final = create_route.call_args.kwargs["target"]
upstream_url: Final = httpx.URL(target).copy_merge_params(request.query_params)
return Response(content=json.dumps({"upstream_query": parse_qs(upstream_url.query.decode())}))
endpoint_func = AsyncMock(side_effect=fake_upstream)
create_route = Mock(return_value=endpoint_func)
monkeypatch.setattr(
"litellm.proxy.pass_through_endpoints.llm_passthrough_endpoints.create_pass_through_route",
create_route,
)
result = await eu_jev_proxy_route(
endpoint="v1/systemone",
request=self._request({"state": "x"}, {"trace": "yes"}),
fastapi_response=MagicMock(spec=Response),
user_api_key_dict=UserAPIKeyAuth(api_key="virtual-key"),
)
assert json.loads(result.body) == {"upstream_query": {"trace": ["yes"]}}
endpoint_func.assert_awaited_once()
create_route.assert_called_once_with(
endpoint="v1/systemone",
target="https://eu-jev.example/base/v1/systemone",
custom_headers={
"Authorization": "Bearer eu-jev-test-key",
"Content-Type": "application/json",
},
custom_llm_provider="eu_jev",
is_streaming_request=False,
)
@pytest.mark.asyncio
async def test_uses_the_hosted_api_when_base_is_unset(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("EU_JEV_API_KEY", "eu-jev-test-key")
monkeypatch.delenv("EU_JEV_API_BASE", raising=False)
endpoint_func = AsyncMock(return_value=Response())
create_route = Mock(return_value=endpoint_func)
monkeypatch.setattr(
"litellm.proxy.pass_through_endpoints.llm_passthrough_endpoints.create_pass_through_route",
create_route,
)
await eu_jev_proxy_route(
endpoint="v1/systemone",
request=self._request({"state": "x"}),
fastapi_response=MagicMock(spec=Response),
user_api_key_dict=UserAPIKeyAuth(api_key="virtual-key"),
)
assert create_route.call_args.kwargs["target"] == "https://eu-jev.com/v1/systemone"
@pytest.mark.parametrize("provider", ["laya", "bespoke"])
class TestOssDecisionPassthroughRoute:
@pytest.fixture

View file

@ -5333,6 +5333,72 @@ export interface paths {
patch: operations["assemblyai_proxy_route_eu_assemblyai__endpoint__patch"];
trace?: never;
};
"/eu_jev/{endpoint}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* Eu Jev Proxy Route
* @description Forward a request to eu/jev, an EU-hosted decision API, with `EU_JEV_API_KEY`.
*
* `POST /eu_jev/v1/systemone` sends a `state` and one to eight named `questions` (`choice`, `noul` or `score`)
* and returns one answer per question name, with spend booked from the reported `usage`. `custom_body` is
* rejected with a 400.
*
* [Docs](https://docs.litellm.ai/docs/pass_through/eu_jev)
*/
get: operations["eu_jev_proxy_route_eu_jev__endpoint__get"];
/**
* Eu Jev Proxy Route
* @description Forward a request to eu/jev, an EU-hosted decision API, with `EU_JEV_API_KEY`.
*
* `POST /eu_jev/v1/systemone` sends a `state` and one to eight named `questions` (`choice`, `noul` or `score`)
* and returns one answer per question name, with spend booked from the reported `usage`. `custom_body` is
* rejected with a 400.
*
* [Docs](https://docs.litellm.ai/docs/pass_through/eu_jev)
*/
put: operations["eu_jev_proxy_route_eu_jev__endpoint__put"];
/**
* Eu Jev Proxy Route
* @description Forward a request to eu/jev, an EU-hosted decision API, with `EU_JEV_API_KEY`.
*
* `POST /eu_jev/v1/systemone` sends a `state` and one to eight named `questions` (`choice`, `noul` or `score`)
* and returns one answer per question name, with spend booked from the reported `usage`. `custom_body` is
* rejected with a 400.
*
* [Docs](https://docs.litellm.ai/docs/pass_through/eu_jev)
*/
post: operations["eu_jev_proxy_route_eu_jev__endpoint__post"];
/**
* Eu Jev Proxy Route
* @description Forward a request to eu/jev, an EU-hosted decision API, with `EU_JEV_API_KEY`.
*
* `POST /eu_jev/v1/systemone` sends a `state` and one to eight named `questions` (`choice`, `noul` or `score`)
* and returns one answer per question name, with spend booked from the reported `usage`. `custom_body` is
* rejected with a 400.
*
* [Docs](https://docs.litellm.ai/docs/pass_through/eu_jev)
*/
delete: operations["eu_jev_proxy_route_eu_jev__endpoint__delete"];
options?: never;
head?: never;
/**
* Eu Jev Proxy Route
* @description Forward a request to eu/jev, an EU-hosted decision API, with `EU_JEV_API_KEY`.
*
* `POST /eu_jev/v1/systemone` sends a `state` and one to eight named `questions` (`choice`, `noul` or `score`)
* and returns one answer per question name, with spend booked from the reported `usage`. `custom_body` is
* rejected with a 400.
*
* [Docs](https://docs.litellm.ai/docs/pass_through/eu_jev)
*/
patch: operations["eu_jev_proxy_route_eu_jev__endpoint__patch"];
trace?: never;
};
"/extraction": {
parameters: {
query?: never;
@ -32233,6 +32299,50 @@ export interface components {
[key: string]: unknown;
};
};
/** EuJevDecisionResponse */
EuJevDecisionResponse: {
/**
* Answers
* @description One answer per question, under the same names
*/
answers: {
[key: string]: components["schemas"]["ChoiceAnswer"] | components["schemas"]["NoulAnswer"] | components["schemas"]["ScoreAnswer"];
};
meta: components["schemas"]["EuJevMeta"];
/**
* Model
* @description The release that answered, such as eu-jeff-1.0.0
*/
model: string;
usage: components["schemas"]["EuJevUsage"];
};
/** EuJevMeta */
EuJevMeta: {
/**
* Cost Eur
* @description The exact charge in euros, on authenticated requests
*/
cost_eur?: string | null;
/**
* Latency Ms
* @description Server-side time for token quoting, credit reservation and inference
*/
latency_ms: number;
/**
* Mode
* @constant
*/
mode: "live";
/** Request Id */
request_id: string;
};
/** EuJevUsage */
EuJevUsage: {
/** Input Tokens */
input_tokens: number;
/** Output Tokens */
output_tokens: number;
};
/**
* Eval
* @description Represents an evaluation from the OpenAI Evals API
@ -59146,6 +59256,751 @@ export interface operations {
};
};
};
eu_jev_proxy_route_eu_jev__endpoint__get: {
parameters: {
query?: never;
header?: never;
path: {
endpoint: string;
};
cookie?: never;
};
requestBody: {
content: {
/**
* @example {
* "model": "eu-jeff-latest",
* "questions": {
* "frustration": {
* "criteria": [
* "calm",
* "mildly annoyed",
* "angry"
* ],
* "instructions": "How frustrated is the customer?",
* "type": "score"
* },
* "is_refund_request": {
* "instructions": "Is the customer asking for a refund?",
* "type": "noul"
* },
* "team": {
* "criteria": {
* "billing": "Payments, invoices, and refunds",
* "support": "Technical issues and bugs"
* },
* "instructions": "Which team should handle this?",
* "type": "choice"
* }
* },
* "state": "I was charged twice. Can I get a refund?"
* }
*/
"application/json": {
/**
* Model
* @description eu-jeff-latest follows the current release, eu-jeff-1.0.0 pins it
* @default eu-jeff-latest
*/
model?: string;
/**
* Questions
* @description One to eight questions, keyed by names of up to 80 characters
*/
questions: {
[key: string]: {
/**
* Criteria
* @description Two to 64 options, option name to description. A null description uses the option name
*/
criteria: {
[key: string]: string | {
[key: string]: unknown;
} | unknown[] | null;
};
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "choice";
} | {
/**
* Criteria
* @description Optional descriptions of what true and false mean
*/
criteria?: {
[key: string]: string | {
[key: string]: unknown;
} | unknown[] | null;
} | null;
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "noul";
} | {
/**
* Criteria
* @description Two to 10 level descriptions, ordered from low to high
*/
criteria: (string | {
[key: string]: unknown;
} | unknown[] | null)[];
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "score";
};
};
/**
* State
* @description The content to evaluate, a string of up to 100,000 characters or a JSON object or array
*/
state: string | {
[key: string]: unknown;
} | unknown[];
};
};
};
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EuJevDecisionResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
eu_jev_proxy_route_eu_jev__endpoint__put: {
parameters: {
query?: never;
header?: never;
path: {
endpoint: string;
};
cookie?: never;
};
requestBody: {
content: {
/**
* @example {
* "model": "eu-jeff-latest",
* "questions": {
* "frustration": {
* "criteria": [
* "calm",
* "mildly annoyed",
* "angry"
* ],
* "instructions": "How frustrated is the customer?",
* "type": "score"
* },
* "is_refund_request": {
* "instructions": "Is the customer asking for a refund?",
* "type": "noul"
* },
* "team": {
* "criteria": {
* "billing": "Payments, invoices, and refunds",
* "support": "Technical issues and bugs"
* },
* "instructions": "Which team should handle this?",
* "type": "choice"
* }
* },
* "state": "I was charged twice. Can I get a refund?"
* }
*/
"application/json": {
/**
* Model
* @description eu-jeff-latest follows the current release, eu-jeff-1.0.0 pins it
* @default eu-jeff-latest
*/
model?: string;
/**
* Questions
* @description One to eight questions, keyed by names of up to 80 characters
*/
questions: {
[key: string]: {
/**
* Criteria
* @description Two to 64 options, option name to description. A null description uses the option name
*/
criteria: {
[key: string]: string | {
[key: string]: unknown;
} | unknown[] | null;
};
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "choice";
} | {
/**
* Criteria
* @description Optional descriptions of what true and false mean
*/
criteria?: {
[key: string]: string | {
[key: string]: unknown;
} | unknown[] | null;
} | null;
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "noul";
} | {
/**
* Criteria
* @description Two to 10 level descriptions, ordered from low to high
*/
criteria: (string | {
[key: string]: unknown;
} | unknown[] | null)[];
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "score";
};
};
/**
* State
* @description The content to evaluate, a string of up to 100,000 characters or a JSON object or array
*/
state: string | {
[key: string]: unknown;
} | unknown[];
};
};
};
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EuJevDecisionResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
eu_jev_proxy_route_eu_jev__endpoint__post: {
parameters: {
query?: never;
header?: never;
path: {
endpoint: string;
};
cookie?: never;
};
requestBody: {
content: {
/**
* @example {
* "model": "eu-jeff-latest",
* "questions": {
* "frustration": {
* "criteria": [
* "calm",
* "mildly annoyed",
* "angry"
* ],
* "instructions": "How frustrated is the customer?",
* "type": "score"
* },
* "is_refund_request": {
* "instructions": "Is the customer asking for a refund?",
* "type": "noul"
* },
* "team": {
* "criteria": {
* "billing": "Payments, invoices, and refunds",
* "support": "Technical issues and bugs"
* },
* "instructions": "Which team should handle this?",
* "type": "choice"
* }
* },
* "state": "I was charged twice. Can I get a refund?"
* }
*/
"application/json": {
/**
* Model
* @description eu-jeff-latest follows the current release, eu-jeff-1.0.0 pins it
* @default eu-jeff-latest
*/
model?: string;
/**
* Questions
* @description One to eight questions, keyed by names of up to 80 characters
*/
questions: {
[key: string]: {
/**
* Criteria
* @description Two to 64 options, option name to description. A null description uses the option name
*/
criteria: {
[key: string]: string | {
[key: string]: unknown;
} | unknown[] | null;
};
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "choice";
} | {
/**
* Criteria
* @description Optional descriptions of what true and false mean
*/
criteria?: {
[key: string]: string | {
[key: string]: unknown;
} | unknown[] | null;
} | null;
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "noul";
} | {
/**
* Criteria
* @description Two to 10 level descriptions, ordered from low to high
*/
criteria: (string | {
[key: string]: unknown;
} | unknown[] | null)[];
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "score";
};
};
/**
* State
* @description The content to evaluate, a string of up to 100,000 characters or a JSON object or array
*/
state: string | {
[key: string]: unknown;
} | unknown[];
};
};
};
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EuJevDecisionResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
eu_jev_proxy_route_eu_jev__endpoint__delete: {
parameters: {
query?: never;
header?: never;
path: {
endpoint: string;
};
cookie?: never;
};
requestBody: {
content: {
/**
* @example {
* "model": "eu-jeff-latest",
* "questions": {
* "frustration": {
* "criteria": [
* "calm",
* "mildly annoyed",
* "angry"
* ],
* "instructions": "How frustrated is the customer?",
* "type": "score"
* },
* "is_refund_request": {
* "instructions": "Is the customer asking for a refund?",
* "type": "noul"
* },
* "team": {
* "criteria": {
* "billing": "Payments, invoices, and refunds",
* "support": "Technical issues and bugs"
* },
* "instructions": "Which team should handle this?",
* "type": "choice"
* }
* },
* "state": "I was charged twice. Can I get a refund?"
* }
*/
"application/json": {
/**
* Model
* @description eu-jeff-latest follows the current release, eu-jeff-1.0.0 pins it
* @default eu-jeff-latest
*/
model?: string;
/**
* Questions
* @description One to eight questions, keyed by names of up to 80 characters
*/
questions: {
[key: string]: {
/**
* Criteria
* @description Two to 64 options, option name to description. A null description uses the option name
*/
criteria: {
[key: string]: string | {
[key: string]: unknown;
} | unknown[] | null;
};
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "choice";
} | {
/**
* Criteria
* @description Optional descriptions of what true and false mean
*/
criteria?: {
[key: string]: string | {
[key: string]: unknown;
} | unknown[] | null;
} | null;
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "noul";
} | {
/**
* Criteria
* @description Two to 10 level descriptions, ordered from low to high
*/
criteria: (string | {
[key: string]: unknown;
} | unknown[] | null)[];
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "score";
};
};
/**
* State
* @description The content to evaluate, a string of up to 100,000 characters or a JSON object or array
*/
state: string | {
[key: string]: unknown;
} | unknown[];
};
};
};
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EuJevDecisionResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
eu_jev_proxy_route_eu_jev__endpoint__patch: {
parameters: {
query?: never;
header?: never;
path: {
endpoint: string;
};
cookie?: never;
};
requestBody: {
content: {
/**
* @example {
* "model": "eu-jeff-latest",
* "questions": {
* "frustration": {
* "criteria": [
* "calm",
* "mildly annoyed",
* "angry"
* ],
* "instructions": "How frustrated is the customer?",
* "type": "score"
* },
* "is_refund_request": {
* "instructions": "Is the customer asking for a refund?",
* "type": "noul"
* },
* "team": {
* "criteria": {
* "billing": "Payments, invoices, and refunds",
* "support": "Technical issues and bugs"
* },
* "instructions": "Which team should handle this?",
* "type": "choice"
* }
* },
* "state": "I was charged twice. Can I get a refund?"
* }
*/
"application/json": {
/**
* Model
* @description eu-jeff-latest follows the current release, eu-jeff-1.0.0 pins it
* @default eu-jeff-latest
*/
model?: string;
/**
* Questions
* @description One to eight questions, keyed by names of up to 80 characters
*/
questions: {
[key: string]: {
/**
* Criteria
* @description Two to 64 options, option name to description. A null description uses the option name
*/
criteria: {
[key: string]: string | {
[key: string]: unknown;
} | unknown[] | null;
};
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "choice";
} | {
/**
* Criteria
* @description Optional descriptions of what true and false mean
*/
criteria?: {
[key: string]: string | {
[key: string]: unknown;
} | unknown[] | null;
} | null;
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "noul";
} | {
/**
* Criteria
* @description Two to 10 level descriptions, ordered from low to high
*/
criteria: (string | {
[key: string]: unknown;
} | unknown[] | null)[];
/**
* Instructions
* @description Free text, or a JSON object, array or null that eu/jev serializes to text before inference
*/
instructions: string | {
[key: string]: unknown;
} | unknown[] | null;
/**
* Type
* @constant
*/
type: "score";
};
};
/**
* State
* @description The content to evaluate, a string of up to 100,000 characters or a JSON object or array
*/
state: string | {
[key: string]: unknown;
} | unknown[];
};
};
};
responses: {
/** @description Successful Response */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["EuJevDecisionResponse"];
};
};
/** @description Validation Error */
422: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
extraction_extraction_post: {
parameters: {
query?: never;