override fun executeStreaming()

in prompt/prompt-executor/prompt-executor-clients/prompt-executor-google-client/src/commonMain/kotlin/ai/koog/prompt/executor/clients/google/GoogleLLMClient.kt [166:221]


    override fun executeStreaming(
        prompt: Prompt,
        model: LLModel,
        tools: List<ToolDescriptor>
    ): Flow<StreamFrame> = streamFrameFlow {
        logger.debug { "Executing streaming prompt: $prompt with model: $model" }
        require(model.capabilities.contains(LLMCapability.Completion)) {
            "Model ${model.id} does not support chat completions"
        }

        val request = createGoogleRequest(prompt, model, tools)

        try {
            httpClient.sse(
                path = "${settings.defaultPath}/${model.id}:${settings.streamGenerateContentMethod}",
                request = request,
                requestBodyType = GoogleRequest::class,
                dataFilter = { it != "[DONE]" },
                decodeStreamingResponse = { json.decodeFromString<GoogleResponse>(it) },
                parameters = mapOf("alt" to "sse"),
                processStreamingChunk = { it }
            ).collect { response ->
                val meta = response.usageMetadata?.let {
                    ResponseMetaInfo.create(
                        clock = clock,
                        totalTokensCount = it.totalTokenCount,
                        inputTokensCount = it.promptTokenCount,
                        outputTokensCount = it.candidatesTokenCount,
                    )
                }
                response.candidates.firstOrNull()?.let { candidate ->
                    candidate.content?.parts?.forEach { part ->
                        when (part) {
                            is GooglePart.FunctionCall -> emitToolCall(
                                id = part.functionCall.id,
                                name = part.functionCall.name,
                                content = part.functionCall.args?.toString() ?: "{}"
                            )

                            is GooglePart.Text -> emitAppend(part.text)
                            else -> Unit
                        }
                    }
                    candidate.finishReason?.let { emitEnd(it, meta) }
                }
            }
        } catch (e: CancellationException) {
            throw e
        } catch (e: Exception) {
            throw LLMClientException(
                clientName = clientName,
                message = e.message,
                cause = e
            )
        }
    }