import {
  BaseLanguageModelStrategy
} from "./chunk-KO5GBKZB.js";
import {
  convertToSAPMessages
} from "./chunk-G2BVB5LB.js";
import {
  buildModelParams,
  convertResponseFormat,
  convertToolsToSAPFormat,
  hasKeys,
  mapToolChoice
} from "./chunk-VSBPOUOR.js";
import {
  deepMerge,
  getProviderName,
  orchestrationConfigRefSchema,
  sapAILanguageModelProviderOptions
} from "./chunk-7VLWN7WJ.js";

// src/orchestration-language-model-strategy.ts
import { parseProviderOptions } from "@ai-sdk/provider-utils";
var RESOLVED_CONFIG_REF_KEY = "_resolvedConfigRef";
var RESOLVED_PROMPT_TEMPLATE_REF_KEY = "_resolvedPromptTemplateRef";
var RESOLVED_TOOLS_KEY = "_resolvedTools";
function buildTemplateRefObject(ref) {
  return isTemplateRefById(ref) ? {
    id: ref.id,
    ...ref.scope && { scope: ref.scope }
  } : {
    name: ref.name,
    scenario: ref.scenario,
    version: ref.version,
    ...ref.scope && { scope: ref.scope }
  };
}
function isTemplateRefById(ref) {
  return "id" in ref;
}
function resolvePlaceholderValues(settings, sapOptions) {
  const merged = deepMerge(
    settings.placeholderValues,
    sapOptions?.placeholderValues
  );
  return hasKeys(merged) ? merged : void 0;
}
var ORCHESTRATION_MODULE_KEYS = ["masking", "filtering", "grounding", "translation"];
var CONFIG_REF_IGNORED_MODULES = [
  ...ORCHESTRATION_MODULE_KEYS,
  "promptTemplateRef",
  "responseFormat",
  "tools",
  "modelParams",
  "modelVersion"
];
var CONFIG_REF_IGNORED_PROVIDER_OPTIONS = ["promptTemplateRef", "modelParams"];
function copyOrchestrationModules(target, source) {
  for (const key of ORCHESTRATION_MODULE_KEYS) {
    const value = source[key];
    if (value && hasKeys(value)) {
      target[key] = value;
    }
  }
}
function isOrchestrationConfigRef(value) {
  return orchestrationConfigRefSchema.safeParse(value).success;
}
var ORCHESTRATION_PARAM_MAPPINGS = [
  ...BaseLanguageModelStrategy.COMMON_PARAM_MAPPINGS,
  { camelCaseKey: "topK", optionKey: "topK", outputKey: "top_k" }
];
var OrchestrationLanguageModelStrategy = class extends BaseLanguageModelStrategy {
  ClientClass;
  constructor(ClientClass) {
    super();
    this.ClientClass = ClientClass;
  }
  /**
   * Builds common parts with orchestration-specific configRef resolution.
   *
   * Resolves configRef once and stores it in sapOptions for use by
   * createClient and buildRequest, avoiding duplicate resolution.
   * @param config - Strategy configuration.
   * @param settings - Model settings.
   * @param options - AI SDK call options.
   * @returns Common build result with resolved configRef in sapOptions.
   * @internal
   */
  async buildCommonParts(config, settings, options) {
    const providerName = getProviderName(config.provider);
    const sapOptions = await parseProviderOptions({
      provider: providerName,
      providerOptions: options.providerOptions,
      schema: sapAILanguageModelProviderOptions
    });
    const configRef = this.resolveConfigRef(sapOptions, settings);
    const promptTemplateRef = this.resolvePromptTemplateRef(sapOptions, settings);
    const warnings = [];
    const messages = convertToSAPMessages(options.prompt, {
      escapeTemplatePlaceholders: this.getEscapeTemplatePlaceholders(sapOptions, settings),
      includeReasoning: this.getIncludeReasoning(sapOptions, settings)
    });
    const { modelParams, warnings: paramWarnings } = buildModelParams({
      options,
      paramMappings: this.getParamMappings(),
      providerModelParams: sapOptions?.modelParams,
      settingsModelParams: settings.modelParams
    });
    warnings.push(...paramWarnings);
    const toolChoice = mapToolChoice(options.toolChoice);
    const tools = this.resolveTools(settings, options, warnings);
    return {
      messages,
      modelParams,
      providerName,
      sapOptions: {
        ...sapOptions,
        [RESOLVED_CONFIG_REF_KEY]: configRef,
        [RESOLVED_PROMPT_TEMPLATE_REF_KEY]: promptTemplateRef,
        [RESOLVED_TOOLS_KEY]: tools
      },
      toolChoice,
      warnings
    };
  }
  buildRequest(config, settings, options, commonParts) {
    const warnings = [];
    const configRef = commonParts.sapOptions?.[RESOLVED_CONFIG_REF_KEY];
    if (configRef) {
      return this.buildConfigRefRequest(settings, options, commonParts, configRef, warnings);
    }
    return this.buildStandardRequest(config, settings, options, commonParts, warnings);
  }
  createClient(config, settings, commonParts) {
    const configRef = commonParts.sapOptions?.[RESOLVED_CONFIG_REF_KEY];
    if (configRef) {
      return new this.ClientClass(configRef, config.deploymentConfig, config.destination);
    }
    const promptTemplateRef = commonParts.sapOptions?.[RESOLVED_PROMPT_TEMPLATE_REF_KEY];
    const tools = commonParts.sapOptions?.[RESOLVED_TOOLS_KEY];
    const promptConfig = promptTemplateRef ? this.buildTemplateRefPromptConfig(promptTemplateRef, tools) : this.buildInlineTemplateConfig(tools, void 0);
    const clientConfig = {
      promptTemplating: {
        model: {
          name: config.modelId,
          ...settings.modelVersion ? { version: settings.modelVersion } : {}
        },
        prompt: promptConfig
      }
    };
    return new this.ClientClass(clientConfig, config.deploymentConfig, config.destination);
  }
  async executeApiCall(client, request, abortSignal) {
    const response = await client.chatCompletion(
      request,
      abortSignal ? { signal: abortSignal } : void 0
    );
    return {
      getContent: () => response.getContent(),
      getFinishReason: () => response.getFinishReason(),
      getTokenUsage: () => response.getTokenUsage(),
      getToolCalls: () => response.getToolCalls(),
      // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- SAP SDK types headers as any
      rawResponse: { headers: response.rawResponse.headers }
    };
  }
  async executeStreamCall(client, request, abortSignal) {
    const streamResponse = await client.stream(request, abortSignal, {
      promptTemplating: { include_usage: true }
    });
    return {
      getFinishReason: () => streamResponse.getFinishReason(),
      getTokenUsage: () => streamResponse.getTokenUsage(),
      stream: streamResponse.stream
    };
  }
  getEscapeTemplatePlaceholders(sapOptions, settings) {
    return sapOptions?.escapeTemplatePlaceholders ?? settings.escapeTemplatePlaceholders ?? true;
  }
  getParamMappings() {
    return ORCHESTRATION_PARAM_MAPPINGS;
  }
  getUrl() {
    return "sap-ai:orchestration";
  }
  /**
   * Builds request for orchestrationConfigRef mode.
   *
   * In configRef mode, the full configuration is managed server-side.
   * We only send messages and placeholderValues.
   * @param settings - Model settings.
   * @param options - Call options.
   * @param commonParts - Common build result.
   * @param _configRef - The config reference (unused, passed for signature consistency).
   * @param warnings - Warnings array to populate.
   * @returns Request body and warnings.
   * @internal
   */
  buildConfigRefRequest(settings, options, commonParts, _configRef, warnings) {
    warnings.push(
      ...this.collectConfigRefIgnoredWarnings(settings, options, commonParts.sapOptions)
    );
    const placeholderValues = resolvePlaceholderValues(settings, commonParts.sapOptions);
    const request = {
      messagesHistory: commonParts.messages,
      ...placeholderValues ? { placeholderValues } : {}
    };
    return { request, warnings };
  }
  /**
   * Builds inline template configuration.
   * @param tools - Optional tools.
   * @param responseFormat - Optional response format.
   * @returns Prompt configuration.
   * @internal
   */
  buildInlineTemplateConfig(tools, responseFormat) {
    return {
      template: [],
      ...tools && tools.length > 0 ? { tools } : {},
      ...responseFormat ? { response_format: responseFormat } : {}
    };
  }
  /**
   * Builds the orchestration module configuration.
   * @param config - Strategy configuration.
   * @param settings - Model settings.
   * @param params - Build parameters.
   * @param params.modelParams - LLM model parameters.
   * @param params.promptTemplateRef - Optional prompt template reference.
   * @param params.responseFormat - Optional response format specification.
   * @param params.toolChoice - Optional tool choice specification.
   * @param params.tools - Optional tools for function calling.
   * @returns Orchestration module configuration.
   * @internal
   */
  buildOrchestrationModuleConfig(config, settings, params) {
    const { modelParams, promptTemplateRef, responseFormat, toolChoice, tools } = params;
    const promptConfig = promptTemplateRef ? this.buildTemplateRefPromptConfig(promptTemplateRef, tools, responseFormat) : this.buildInlineTemplateConfig(tools, responseFormat);
    const effectiveModelParams = toolChoice ? { ...modelParams, tool_choice: toolChoice } : modelParams;
    const moduleConfig = {
      promptTemplating: {
        model: {
          name: config.modelId,
          params: effectiveModelParams,
          ...settings.modelVersion ? { version: settings.modelVersion } : {}
        },
        prompt: promptConfig
      }
    };
    copyOrchestrationModules(
      moduleConfig,
      settings
    );
    return moduleConfig;
  }
  /**
   * Builds the final request body for the orchestration API.
   * @param messages - Chat messages.
   * @param orchestrationConfig - Module configuration.
   * @param placeholderValues - Optional placeholder values.
   * @param hasTemplateRef - Whether template_ref mode is active.
   * @returns Request body.
   * @internal
   */
  buildRequestBody(messages, orchestrationConfig, placeholderValues, hasTemplateRef) {
    const promptTemplating = orchestrationConfig.promptTemplating;
    const messagesField = hasTemplateRef ? { messagesHistory: messages } : { messages };
    const requestBody = {
      ...messagesField,
      model: {
        ...orchestrationConfig.promptTemplating.model
      },
      ...placeholderValues ? { placeholderValues } : {},
      ...promptTemplating.prompt.tools ? { tools: promptTemplating.prompt.tools } : {},
      ...promptTemplating.prompt.response_format ? { response_format: promptTemplating.prompt.response_format } : {}
    };
    copyOrchestrationModules(
      requestBody,
      orchestrationConfig
    );
    return requestBody;
  }
  /**
   * Builds request for standard (non-configRef) mode.
   * @param config - Strategy configuration.
   * @param settings - Model settings.
   * @param options - Call options.
   * @param commonParts - Common build result.
   * @param warnings - Warnings array to populate.
   * @returns Request body and warnings.
   * @internal
   */
  buildStandardRequest(config, settings, options, commonParts, warnings) {
    const tools = commonParts.sapOptions?.[RESOLVED_TOOLS_KEY];
    const { responseFormat, warning: responseFormatWarning } = convertResponseFormat(
      options.responseFormat,
      settings.responseFormat
    );
    if (responseFormatWarning) {
      warnings.push(responseFormatWarning);
    }
    const { toolChoice } = commonParts;
    const promptTemplateRef = commonParts.sapOptions?.[RESOLVED_PROMPT_TEMPLATE_REF_KEY];
    const orchestrationConfig = this.buildOrchestrationModuleConfig(config, settings, {
      modelParams: commonParts.modelParams,
      promptTemplateRef,
      responseFormat,
      toolChoice,
      tools
    });
    const placeholderValues = resolvePlaceholderValues(settings, commonParts.sapOptions);
    const request = this.buildRequestBody(
      commonParts.messages,
      orchestrationConfig,
      placeholderValues,
      Boolean(promptTemplateRef)
    );
    return { request, warnings };
  }
  /**
   * Builds prompt configuration for template reference with optional tools/response_format.
   * @param ref - Template reference.
   * @param tools - Optional tools.
   * @param responseFormat - Optional response format.
   * @returns Prompt configuration.
   * @internal
   */
  buildTemplateRefPromptConfig(ref, tools, responseFormat) {
    return {
      template_ref: buildTemplateRefObject(ref),
      ...tools && tools.length > 0 ? { tools } : {},
      ...responseFormat ? { response_format: responseFormat } : {}
    };
  }
  /**
   * Collects warnings for settings that will be ignored when using orchestrationConfigRef.
   * @param settings - The orchestration model settings.
   * @param options - The call options (for tools and responseFormat).
   * @param sapOptions - Parsed provider options (for promptTemplateRef in providerOptions).
   * @returns Array of warnings for ignored settings.
   * @internal
   */
  collectConfigRefIgnoredWarnings(settings, options, sapOptions) {
    const warnings = [];
    const ignoredSettings = [];
    for (const key of CONFIG_REF_IGNORED_MODULES) {
      const value = settings[key];
      if (value !== void 0) {
        if (typeof value === "object" && Object.keys(value).length === 0) {
          continue;
        }
        ignoredSettings.push(key);
      }
    }
    for (const key of CONFIG_REF_IGNORED_PROVIDER_OPTIONS) {
      if (sapOptions?.[key] && !settings[key]) {
        ignoredSettings.push(`providerOptions.${key}`);
      }
    }
    if (options.tools && options.tools.length > 0) {
      ignoredSettings.push("options.tools");
    }
    if (options.responseFormat) {
      ignoredSettings.push("options.responseFormat");
    }
    if (options.toolChoice) {
      ignoredSettings.push("options.toolChoice");
    }
    if (ignoredSettings.length > 0) {
      warnings.push({
        message: `orchestrationConfigRef is set; the following local settings are ignored: ${ignoredSettings.join(", ")}. The full configuration is managed by the referenced config.`,
        type: "other"
      });
    }
    return warnings;
  }
  /**
   * Resolves the orchestrationConfigRef from provider options or settings.
   * Provider options take priority over settings.
   * @param sapOptions - Parsed provider options from commonParts.
   * @param settings - The model settings.
   * @returns The resolved config reference or undefined.
   * @internal
   */
  resolveConfigRef(sapOptions, settings) {
    const configRefCandidate = sapOptions?.orchestrationConfigRef ?? settings.orchestrationConfigRef;
    if (configRefCandidate && isOrchestrationConfigRef(configRefCandidate)) {
      return configRefCandidate;
    }
    return void 0;
  }
  /**
   * Resolves promptTemplateRef from provider options or settings.
   *
   * Provider options take priority over settings.
   * @param sapOptions - Parsed provider options from commonParts.
   * @param settings - The model settings.
   * @returns The resolved prompt template reference or undefined.
   * @internal
   */
  resolvePromptTemplateRef(sapOptions, settings) {
    const rawTemplateRef = sapOptions?.promptTemplateRef ?? settings.promptTemplateRef;
    if (rawTemplateRef && typeof rawTemplateRef === "object" && ("id" in rawTemplateRef || "name" in rawTemplateRef)) {
      return rawTemplateRef;
    }
    return void 0;
  }
  /**
   * Resolves tools from settings or options with orchestration-specific priority.
   *
   * Orchestration allows tools to be defined in settings (unlike Foundation Models),
   * with options.tools taking priority.
   * @param settings - Model settings.
   * @param options - Call options.
   * @param warnings - Warnings array to populate.
   * @returns Resolved tools or undefined.
   * @internal
   */
  resolveTools(settings, options, warnings) {
    const settingsTools = settings.tools;
    const optionsTools = options.tools;
    if (settingsTools && settingsTools.length > 0 && optionsTools && optionsTools.length > 0) {
      warnings.push({
        message: "Both settings.tools and call options.tools were provided; preferring call options.tools.",
        type: "other"
      });
    }
    if (settingsTools && settingsTools.length > 0 && (!optionsTools || optionsTools.length === 0)) {
      return settingsTools;
    }
    if (optionsTools && optionsTools.length > 0) {
      const result = convertToolsToSAPFormat(optionsTools);
      warnings.push(...result.warnings);
      return result.tools;
    }
    return void 0;
  }
};
export {
  OrchestrationLanguageModelStrategy
};
//# sourceMappingURL=orchestration-language-model-strategy-QN56X3Z2.js.map