import {
  deepMerge,
  validateModelParamsWithWarnings
} from "./chunk-LSTAKB2E.js";

// src/strategy-utils.ts
import { z } from "zod";
var StreamIdGenerator = class {
  /**
   * @returns A UUID string for identifying the response.
   */
  generateResponseId() {
    return crypto.randomUUID();
  }
  /**
   * @returns A UUID string for identifying a text block.
   */
  generateTextBlockId() {
    return crypto.randomUUID();
  }
};
function applyParameterOverrides(modelParams, options, sapModelParams, settingsModelParams, mappings) {
  for (const mapping of mappings) {
    const value = (mapping.optionKey ? options[mapping.optionKey] : void 0) ?? (mapping.camelCaseKey ? sapModelParams?.[mapping.camelCaseKey] : void 0) ?? (mapping.camelCaseKey ? settingsModelParams?.[mapping.camelCaseKey] : void 0);
    if (value !== void 0) {
      modelParams[mapping.outputKey] = value;
    }
    if (mapping.camelCaseKey && mapping.camelCaseKey !== mapping.outputKey) {
      delete modelParams[mapping.camelCaseKey];
    }
  }
}
function buildGenerateResult(config) {
  const { modelId, providerName, requestBody, response, responseHeaders, version, warnings } = config;
  const content = extractResponseContent(response);
  const tokenUsage = response.getTokenUsage();
  const finishReasonRaw = response.getFinishReason();
  const finishReason = mapFinishReason(finishReasonRaw);
  const textContent = response.getContent();
  const toolCalls = response.getToolCalls();
  const rawResponseBody = {
    content: textContent,
    finishReason: finishReasonRaw,
    tokenUsage,
    toolCalls
  };
  return {
    content,
    finishReason,
    providerMetadata: {
      [providerName]: {
        finishReason: finishReasonRaw ?? "unknown",
        finishReasonMapped: finishReason,
        ...typeof responseHeaders?.["x-request-id"] === "string" ? { requestId: responseHeaders["x-request-id"] } : {},
        version
      }
    },
    request: {
      body: requestBody
    },
    response: {
      body: rawResponseBody,
      headers: responseHeaders,
      modelId,
      timestamp: /* @__PURE__ */ new Date()
    },
    usage: {
      inputTokens: {
        cacheRead: void 0,
        cacheWrite: void 0,
        noCache: tokenUsage?.prompt_tokens,
        total: tokenUsage?.prompt_tokens
      },
      outputTokens: {
        reasoning: void 0,
        text: tokenUsage?.completion_tokens,
        total: tokenUsage?.completion_tokens
      }
    },
    warnings
  };
}
function buildModelDeployment(config, modelVersion) {
  const deploymentConfig = config.deploymentConfig;
  if ("deploymentId" in deploymentConfig) {
    return { deploymentId: deploymentConfig.deploymentId };
  }
  const resourceGroup = "resourceGroup" in deploymentConfig ? deploymentConfig.resourceGroup : void 0;
  return {
    modelName: config.modelId,
    ...modelVersion && { modelVersion },
    ...resourceGroup && { resourceGroup }
  };
}
function buildModelParams(config) {
  const { options, paramMappings, providerModelParams, settingsModelParams } = config;
  const warnings = [];
  const modelParams = deepMerge(
    settingsModelParams ?? {},
    providerModelParams ?? {}
  );
  applyParameterOverrides(
    modelParams,
    options,
    providerModelParams,
    settingsModelParams,
    paramMappings
  );
  if (options.stopSequences && options.stopSequences.length > 0) {
    modelParams.stop = options.stopSequences;
  }
  validateModelParamsWithWarnings(
    {
      frequencyPenalty: options.frequencyPenalty,
      maxTokens: options.maxOutputTokens,
      presencePenalty: options.presencePenalty,
      temperature: options.temperature,
      topP: options.topP
    },
    warnings
  );
  return { modelParams, warnings };
}
function buildSAPToolParameters(schema) {
  const schemaType = schema.type;
  if (schemaType !== void 0 && schemaType !== "object") {
    return {
      properties: {},
      required: [],
      type: "object"
    };
  }
  const properties = schema.properties && typeof schema.properties === "object" ? schema.properties : {};
  const required = Array.isArray(schema.required) && schema.required.every((item) => typeof item === "string") ? schema.required : [];
  const additionalFields = Object.fromEntries(
    Object.entries(schema).filter(
      ([key]) => key !== "type" && key !== "properties" && key !== "required"
    )
  );
  return {
    properties,
    required,
    type: "object",
    ...additionalFields
  };
}
function convertResponseFormat(optionsResponseFormat, settingsResponseFormat) {
  let responseFormat;
  let warning;
  if (optionsResponseFormat?.type === "json") {
    responseFormat = optionsResponseFormat.schema ? {
      json_schema: {
        description: optionsResponseFormat.description,
        name: optionsResponseFormat.name ?? "response",
        schema: optionsResponseFormat.schema,
        strict: null
      },
      type: "json_schema"
    } : { type: "json_object" };
  } else if (settingsResponseFormat) {
    responseFormat = settingsResponseFormat;
  }
  if (responseFormat && responseFormat.type !== "text") {
    warning = {
      message: "responseFormat JSON mode is forwarded to the underlying model; support and schema adherence depend on the model/deployment.",
      type: "other"
    };
  }
  return { responseFormat, warning };
}
function convertToolsToSAPFormat(tools) {
  const warnings = [];
  if (!tools || tools.length === 0) {
    return { tools: void 0, warnings };
  }
  const convertedTools = tools.map((tool) => {
    if (tool.type === "function") {
      const { parameters, warning } = extractToolParameters(tool);
      if (warning) {
        warnings.push(warning);
      }
      return {
        function: {
          name: tool.name,
          parameters,
          ...tool.description ? { description: tool.description } : {}
        },
        type: "function"
      };
    } else {
      warnings.push({
        details: "Only 'function' tool type is supported.",
        feature: `tool type for ${tool.name}`,
        type: "unsupported"
      });
      return null;
    }
  }).filter((t) => t !== null);
  return {
    tools: convertedTools.length > 0 ? convertedTools : void 0,
    warnings
  };
}
function createAISDKRequestBodySummary(options) {
  return {
    hasImageParts: options.prompt.some(
      (message) => message.role === "user" && message.content.some((part) => part.type === "file" && part.mediaType.startsWith("image/"))
    ),
    maxOutputTokens: options.maxOutputTokens,
    promptMessages: options.prompt.length,
    responseFormatType: options.responseFormat?.type,
    seed: options.seed,
    stopSequences: options.stopSequences?.length,
    temperature: options.temperature,
    toolChoiceType: options.toolChoice?.type,
    tools: options.tools?.length ?? 0,
    topK: options.topK,
    topP: options.topP
  };
}
function createInitialStreamState() {
  return {
    activeText: false,
    finishReason: {
      raw: void 0,
      unified: "other"
    },
    isFirstChunk: true,
    usage: {
      inputTokens: {
        cacheRead: void 0,
        cacheWrite: void 0,
        noCache: void 0,
        total: void 0
      },
      outputTokens: {
        reasoning: void 0,
        text: void 0,
        total: void 0
      }
    }
  };
}
function createStreamTransformer(config) {
  const {
    convertToAISDKError,
    idGenerator,
    includeRawChunks,
    modelId,
    options,
    providerName,
    responseId,
    sdkStream,
    streamResponseGetFinishReason,
    streamResponseGetTokenUsage,
    url,
    version,
    warnings
  } = config;
  let textBlockId = null;
  const streamState = createInitialStreamState();
  const toolCallsInProgress = /* @__PURE__ */ new Map();
  return new ReadableStream({
    cancel() {
    },
    async start(controller) {
      controller.enqueue({
        type: "stream-start",
        warnings: [...warnings]
      });
      try {
        for await (const chunk of sdkStream) {
          if (includeRawChunks) {
            controller.enqueue({
              rawValue: chunk._data ?? chunk,
              type: "raw"
            });
          }
          if (streamState.isFirstChunk) {
            streamState.isFirstChunk = false;
            controller.enqueue({
              id: responseId,
              modelId,
              timestamp: /* @__PURE__ */ new Date(),
              type: "response-metadata"
            });
          }
          const deltaToolCalls = chunk.getDeltaToolCalls();
          if (Array.isArray(deltaToolCalls) && deltaToolCalls.length > 0) {
            streamState.finishReason = {
              raw: void 0,
              unified: "tool-calls"
            };
          }
          const deltaContent = chunk.getDeltaContent();
          if (typeof deltaContent === "string" && deltaContent.length > 0 && streamState.finishReason.unified !== "tool-calls") {
            if (!streamState.activeText) {
              textBlockId = idGenerator.generateTextBlockId();
              controller.enqueue({ id: textBlockId, type: "text-start" });
              streamState.activeText = true;
            }
            if (textBlockId) {
              controller.enqueue({
                delta: deltaContent,
                id: textBlockId,
                type: "text-delta"
              });
            }
          }
          if (Array.isArray(deltaToolCalls) && deltaToolCalls.length > 0) {
            for (const toolCallChunk of deltaToolCalls) {
              const index = toolCallChunk.index;
              if (typeof index !== "number" || !Number.isFinite(index)) {
                continue;
              }
              if (!toolCallsInProgress.has(index)) {
                toolCallsInProgress.set(index, {
                  arguments: "",
                  didEmitCall: false,
                  didEmitInputStart: false,
                  id: toolCallChunk.id ?? `tool_${String(index)}`,
                  toolName: toolCallChunk.function?.name
                });
              }
              const tc = toolCallsInProgress.get(index);
              if (!tc) continue;
              if (toolCallChunk.id) {
                tc.id = toolCallChunk.id;
              }
              const nextToolName = toolCallChunk.function?.name;
              if (typeof nextToolName === "string" && nextToolName.length > 0) {
                tc.toolName = nextToolName;
              }
              if (!tc.didEmitInputStart && tc.toolName) {
                tc.didEmitInputStart = true;
                controller.enqueue({
                  id: tc.id,
                  toolName: tc.toolName,
                  type: "tool-input-start"
                });
              }
              const argumentsDelta = toolCallChunk.function?.arguments;
              if (typeof argumentsDelta === "string" && argumentsDelta.length > 0) {
                tc.arguments += argumentsDelta;
                if (tc.didEmitInputStart) {
                  controller.enqueue({
                    delta: argumentsDelta,
                    id: tc.id,
                    type: "tool-input-delta"
                  });
                }
              }
            }
          }
          const chunkFinishReason = chunk.getFinishReason();
          if (chunkFinishReason) {
            streamState.finishReason = mapFinishReason(chunkFinishReason);
            if (streamState.finishReason.unified === "tool-calls") {
              const toolCalls2 = Array.from(toolCallsInProgress.values());
              for (const tc of toolCalls2) {
                if (tc.didEmitCall) {
                  continue;
                }
                if (!tc.didEmitInputStart) {
                  tc.didEmitInputStart = true;
                  controller.enqueue({
                    id: tc.id,
                    toolName: tc.toolName ?? "",
                    type: "tool-input-start"
                  });
                }
                tc.didEmitCall = true;
                controller.enqueue({ id: tc.id, type: "tool-input-end" });
                controller.enqueue({
                  input: tc.arguments,
                  toolCallId: tc.id,
                  toolName: tc.toolName ?? "",
                  type: "tool-call"
                });
              }
              if (streamState.activeText && textBlockId) {
                controller.enqueue({ id: textBlockId, type: "text-end" });
                streamState.activeText = false;
              }
            }
          }
        }
        const toolCalls = Array.from(toolCallsInProgress.values());
        let didEmitAnyToolCalls = false;
        for (const tc of toolCalls) {
          if (tc.didEmitCall) {
            continue;
          }
          if (!tc.didEmitInputStart) {
            tc.didEmitInputStart = true;
            controller.enqueue({
              id: tc.id,
              toolName: tc.toolName ?? "",
              type: "tool-input-start"
            });
          }
          didEmitAnyToolCalls = true;
          tc.didEmitCall = true;
          controller.enqueue({ id: tc.id, type: "tool-input-end" });
          controller.enqueue({
            input: tc.arguments,
            toolCallId: tc.id,
            toolName: tc.toolName ?? "",
            type: "tool-call"
          });
        }
        if (streamState.activeText && textBlockId) {
          controller.enqueue({ id: textBlockId, type: "text-end" });
        }
        const finalFinishReason = streamResponseGetFinishReason();
        if (finalFinishReason) {
          streamState.finishReason = mapFinishReason(finalFinishReason);
        } else if (didEmitAnyToolCalls) {
          streamState.finishReason = {
            raw: void 0,
            unified: "tool-calls"
          };
        }
        const finalUsage = streamResponseGetTokenUsage();
        if (finalUsage) {
          streamState.usage.inputTokens.total = finalUsage.prompt_tokens;
          streamState.usage.inputTokens.noCache = finalUsage.prompt_tokens;
          streamState.usage.outputTokens.total = finalUsage.completion_tokens;
          streamState.usage.outputTokens.text = finalUsage.completion_tokens;
        }
        controller.enqueue({
          finishReason: streamState.finishReason,
          providerMetadata: {
            [providerName]: {
              finishReason: streamState.finishReason.raw,
              responseId,
              version
            }
          },
          type: "finish",
          usage: streamState.usage
        });
        controller.close();
      } catch (error) {
        const aiError = convertToAISDKError(error, {
          operation: "doStream",
          requestBody: createAISDKRequestBodySummary(options),
          url
        });
        controller.enqueue({
          error: aiError instanceof Error ? aiError : new Error(String(aiError)),
          type: "error"
        });
        controller.close();
      }
    }
  });
}
function extractResponseContent(response) {
  const content = [];
  const textContent = response.getContent();
  if (textContent) {
    content.push({
      text: textContent,
      type: "text"
    });
  }
  const toolCalls = response.getToolCalls();
  if (toolCalls) {
    for (const toolCall of toolCalls) {
      content.push({
        input: toolCall.function.arguments,
        toolCallId: toolCall.id,
        toolName: toolCall.function.name,
        type: "tool-call"
      });
    }
  }
  return content;
}
function extractToolParameters(tool) {
  const inputSchema = tool.inputSchema;
  const toolWithParams = tool;
  if (toolWithParams.parameters && isZodSchema(toolWithParams.parameters)) {
    try {
      const jsonSchema = z.toJSONSchema(toolWithParams.parameters);
      const schemaRecord = jsonSchema;
      delete schemaRecord.$schema;
      return { parameters: buildSAPToolParameters(schemaRecord) };
    } catch (error) {
      return {
        parameters: buildSAPToolParameters({}),
        warning: {
          details: `Failed to convert tool Zod schema: ${error instanceof Error ? error.message : String(error)}. Falling back to empty object schema.`,
          feature: `tool schema conversion for ${tool.name}`,
          type: "unsupported"
        }
      };
    }
  }
  if (inputSchema && Object.keys(inputSchema).length > 0) {
    const hasProperties = inputSchema.properties && typeof inputSchema.properties === "object" && Object.keys(inputSchema.properties).length > 0;
    if (hasProperties) {
      return { parameters: buildSAPToolParameters(inputSchema) };
    }
  }
  return { parameters: buildSAPToolParameters({}) };
}
function hasCallableParse(obj) {
  return typeof obj.parse === "function";
}
function isZodSchema(obj) {
  if (obj === null || typeof obj !== "object") {
    return false;
  }
  const record = obj;
  return "_def" in record && "parse" in record && hasCallableParse(record);
}
function mapFinishReason(reason) {
  const raw = reason ?? void 0;
  if (!reason) {
    return { raw, unified: "other" };
  }
  switch (reason.toLowerCase()) {
    case "content_filter":
      return { raw, unified: "content-filter" };
    case "end_turn":
    case "eos":
    case "stop":
    case "stop_sequence":
      return { raw, unified: "stop" };
    case "error":
      return { raw, unified: "error" };
    case "function_call":
    case "tool_call":
    case "tool_calls":
      return { raw, unified: "tool-calls" };
    case "length":
    case "max_tokens":
    case "max_tokens_reached":
      return { raw, unified: "length" };
    default:
      return { raw, unified: "other" };
  }
}
function mapToolChoice(toolChoice) {
  if (!toolChoice) {
    return void 0;
  }
  switch (toolChoice.type) {
    case "auto":
      return "auto";
    case "none":
      return "none";
    case "required":
      return "required";
    case "tool":
      return {
        function: { name: toolChoice.toolName },
        type: "function"
      };
    default:
      return void 0;
  }
}
function normalizeEmbedding(embedding) {
  if (Array.isArray(embedding)) {
    return embedding;
  }
  const buffer = Buffer.from(embedding, "base64");
  const float32Array = new Float32Array(
    buffer.buffer,
    buffer.byteOffset,
    buffer.length / Float32Array.BYTES_PER_ELEMENT
  );
  return Array.from(float32Array);
}

export {
  StreamIdGenerator,
  buildGenerateResult,
  buildModelDeployment,
  buildModelParams,
  convertResponseFormat,
  convertToolsToSAPFormat,
  createAISDKRequestBodySummary,
  createStreamTransformer,
  mapToolChoice,
  normalizeEmbedding
};
//# sourceMappingURL=chunk-24QM3M77.js.map