override fun prepareRequest()

in anthropic-java-vertex/src/main/kotlin/com/anthropic/vertex/backends/VertexBackend.kt [49:124]


    override fun prepareRequest(request: HttpRequest): HttpRequest {
        val pathSegments = request.pathSegments

        // Check that the request is valid. Unlike for Bedrock, Vertex *will*
        // still have a first "v1" path segment.
        if (pathSegments.isEmpty() || pathSegments[0] != "v1") {
            throw AnthropicInvalidDataException("Expected first 'v1' path segment.")
        }

        if (pathSegments.size <= 1) {
            throw AnthropicInvalidDataException("Missing service name from request URL.")
        }

        var isCountTokens = false

        when (pathSegments[1]) {
            "projects" -> {
                throw IllegalArgumentException("Request already prepared for Vertex.")
            }
            "messages" -> {
                if (pathSegments.size > 2) {
                    when (pathSegments[2]) {
                        "batches" ->
                            throw AnthropicException("Batch API is not supported for Vertex.")
                        "count_tokens" -> isCountTokens = true
                    } // For now, ignore any other path segments.
                }
            }
            "complete" -> {
                // Do nothing special.
            }
            else ->
                throw AnthropicException("Service is not supported for Vertex: ${pathSegments[1]}.")
        }

        val jsonBody: ObjectNode? = bodyToJson(jsonMapper, request.body)

        if (jsonBody != null) {
            jsonBody.put("anthropic_version", ANTHROPIC_VERSION)
        } else {
            throw AnthropicInvalidDataException("Request has no body.")
        }

        val endpoint: String

        if (isCountTokens) {
            endpoint = "count-tokens:rawPredict"
        } else {
            val model =
                jsonBody.remove("model")
                    ?: throw AnthropicInvalidDataException("No model found in body.")
            val modelId = model.asText()
            // For Vertex, the "stream" property must be retained in the body.
            // This differs from Bedrock where the property is removed.
            val isStream = jsonBody["stream"]?.asBoolean() ?: false
            val specifier = if (isStream) "streamRawPredict" else "rawPredict"

            endpoint = "$modelId:$specifier"
        }

        return request
            .toBuilder()
            .replaceAllPathSegments(
                "v1",
                "projects",
                project,
                "locations",
                region,
                "publishers",
                "anthropic",
                "models",
                endpoint,
            )
            .body(json(jsonMapper, jsonBody))
            .build()
    }