@jerome-benoit/sap-ai-provider 4.6.8 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +1 -1
  3. package/dist/{chunk-M3AV2YUV.js → chunk-36DFHUVQ.js} +414 -277
  4. package/dist/chunk-36DFHUVQ.js.map +1 -0
  5. package/dist/{chunk-IIBSUXGT.js → chunk-4JIMBRMV.js} +44 -7
  6. package/dist/chunk-4JIMBRMV.js.map +1 -0
  7. package/dist/{chunk-6BVUDEKZ.js → chunk-BZZJKLDG.js} +60 -6
  8. package/dist/chunk-BZZJKLDG.js.map +1 -0
  9. package/dist/chunk-GMMX46AH.js +93 -0
  10. package/dist/chunk-GMMX46AH.js.map +1 -0
  11. package/dist/{chunk-7OGNFVGC.js → chunk-TVXWNZQT.js} +5276 -5608
  12. package/dist/chunk-TVXWNZQT.js.map +1 -0
  13. package/dist/chunk-WDUOKIKD.js +188 -0
  14. package/dist/chunk-WDUOKIKD.js.map +1 -0
  15. package/dist/{foundation-models-embedding-model-strategy-GXJRGM4X.js → foundation-models-embedding-model-strategy-YWPDIJEN.js} +8 -4
  16. package/dist/foundation-models-embedding-model-strategy-YWPDIJEN.js.map +1 -0
  17. package/dist/{foundation-models-language-model-strategy-FGUGQPBL.js → foundation-models-language-model-strategy-WDSQWU64.js} +16 -13
  18. package/dist/foundation-models-language-model-strategy-WDSQWU64.js.map +1 -0
  19. package/dist/index.cjs +6357 -6418
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +66 -66
  22. package/dist/index.d.ts +66 -66
  23. package/dist/index.js +11 -172
  24. package/dist/index.js.map +1 -1
  25. package/dist/{orchestration-embedding-model-strategy-663QYZL7.js → orchestration-embedding-model-strategy-66QYAO64.js} +14 -4
  26. package/dist/orchestration-embedding-model-strategy-66QYAO64.js.map +1 -0
  27. package/dist/{orchestration-language-model-strategy-X3LKHORW.js → orchestration-language-model-strategy-4TKRZK7U.js} +52 -77
  28. package/dist/orchestration-language-model-strategy-4TKRZK7U.js.map +1 -0
  29. package/package.json +27 -21
  30. package/LICENSE.md +0 -187
  31. package/dist/chunk-6BVUDEKZ.js.map +0 -1
  32. package/dist/chunk-7OGNFVGC.js.map +0 -1
  33. package/dist/chunk-IIBSUXGT.js.map +0 -1
  34. package/dist/chunk-M3AV2YUV.js.map +0 -1
  35. package/dist/chunk-X66RDDSB.js +0 -61
  36. package/dist/chunk-X66RDDSB.js.map +0 -1
  37. package/dist/foundation-models-embedding-model-strategy-GXJRGM4X.js.map +0 -1
  38. package/dist/foundation-models-language-model-strategy-FGUGQPBL.js.map +0 -1
  39. package/dist/orchestration-embedding-model-strategy-663QYZL7.js.map +0 -1
  40. package/dist/orchestration-language-model-strategy-X3LKHORW.js.map +0 -1
@@ -0,0 +1,188 @@
1
+ import {createRequire as __createRequire} from 'module';var require=__createRequire(import.meta.url);
2
+ import {
3
+ ApiSwitchError,
4
+ UnsupportedFeatureError,
5
+ deepMerge
6
+ } from "./chunk-TVXWNZQT.js";
7
+
8
+ // src/sap-ai-validation.ts
9
+ function validateEscapeTemplatePlaceholders(api, escapeTemplatePlaceholders) {
10
+ if (api === "foundation-models" && escapeTemplatePlaceholders === true) {
11
+ throw new UnsupportedFeatureError(
12
+ ESCAPE_TEMPLATE_PLACEHOLDERS_DESCRIPTION,
13
+ "foundation-models",
14
+ "orchestration"
15
+ );
16
+ }
17
+ }
18
+ function validateFoundationModelsOnlyOptions(settings) {
19
+ if (!settings) return;
20
+ const fmSettings = settings;
21
+ for (const feature of FOUNDATION_MODELS_ONLY_FEATURE_KEYS) {
22
+ if (fmSettings[feature] !== void 0) {
23
+ throw new UnsupportedFeatureError(
24
+ FOUNDATION_MODELS_ONLY_FEATURES[feature],
25
+ "orchestration",
26
+ "foundation-models"
27
+ );
28
+ }
29
+ }
30
+ }
31
+ function validateOrchestrationOnlyEmbeddingOptions(settings) {
32
+ if (!settings) return;
33
+ for (const feature of ORCHESTRATION_ONLY_EMBEDDING_FEATURE_KEYS) {
34
+ if (settings[feature] !== void 0) {
35
+ throw new UnsupportedFeatureError(
36
+ ORCHESTRATION_ONLY_EMBEDDING_FEATURES[feature],
37
+ "foundation-models",
38
+ "orchestration"
39
+ );
40
+ }
41
+ }
42
+ }
43
+ function validateOrchestrationOnlyOptions(settings) {
44
+ if (!settings) return;
45
+ const orchSettings = settings;
46
+ for (const feature of ORCHESTRATION_ONLY_FEATURE_KEYS) {
47
+ if (orchSettings[feature] !== void 0) {
48
+ throw new UnsupportedFeatureError(
49
+ ORCHESTRATION_ONLY_FEATURES[feature],
50
+ "foundation-models",
51
+ "orchestration"
52
+ );
53
+ }
54
+ }
55
+ }
56
+ var ORCHESTRATION_ONLY_FEATURE_KEYS = [
57
+ "filtering",
58
+ "grounding",
59
+ "masking",
60
+ "orchestrationConfigRef",
61
+ "placeholderValues",
62
+ "promptTemplateRef",
63
+ "streamOptions",
64
+ "tools",
65
+ "translation"
66
+ ];
67
+ var ORCHESTRATION_ONLY_FEATURES = {
68
+ filtering: "Content filtering",
69
+ grounding: "Document grounding",
70
+ masking: "Data masking",
71
+ orchestrationConfigRef: "Orchestration config reference (orchestrationConfigRef)",
72
+ placeholderValues: "Placeholder values (placeholderValues)",
73
+ promptTemplateRef: "Prompt template reference (promptTemplateRef)",
74
+ streamOptions: "Stream options for post-LLM modules",
75
+ tools: "SAP-format tool definitions (use AI SDK tools instead)",
76
+ translation: "Translation"
77
+ };
78
+ var FOUNDATION_MODELS_ONLY_FEATURE_KEYS = ["dataSources"];
79
+ var FOUNDATION_MODELS_ONLY_FEATURES = {
80
+ dataSources: "Azure On Your Data (dataSources)"
81
+ };
82
+ var ORCHESTRATION_ONLY_INVOCATION_FEATURE_KEYS = [
83
+ "orchestrationConfigRef",
84
+ "placeholderValues",
85
+ "promptTemplateRef"
86
+ ];
87
+ var ORCHESTRATION_ONLY_EMBEDDING_FEATURE_KEYS = ["masking"];
88
+ var ORCHESTRATION_ONLY_EMBEDDING_FEATURES = {
89
+ masking: ORCHESTRATION_ONLY_FEATURES.masking
90
+ };
91
+ var ESCAPE_TEMPLATE_PLACEHOLDERS_DESCRIPTION = "escapeTemplatePlaceholders (Jinja2 template escaping)";
92
+ function validateApiSwitch(fromApi, toApi, modelSettings) {
93
+ if (fromApi === toApi) return;
94
+ if (!modelSettings) return;
95
+ if (fromApi === "orchestration" && toApi === "foundation-models") {
96
+ const orchSettings = modelSettings;
97
+ for (const feature of ORCHESTRATION_ONLY_FEATURE_KEYS) {
98
+ if (orchSettings[feature] !== void 0) {
99
+ throw new ApiSwitchError(fromApi, toApi, feature);
100
+ }
101
+ }
102
+ }
103
+ if (fromApi === "foundation-models" && toApi === "orchestration") {
104
+ const fmSettings = modelSettings;
105
+ for (const feature of FOUNDATION_MODELS_ONLY_FEATURE_KEYS) {
106
+ if (fmSettings[feature] !== void 0) {
107
+ throw new ApiSwitchError(fromApi, toApi, feature);
108
+ }
109
+ }
110
+ }
111
+ }
112
+ var VALID_API_TYPES = ["orchestration", "foundation-models"];
113
+ function mergeSettingsWithApi(defaultSettings, callSettings, fallbackApi) {
114
+ return {
115
+ ...deepMerge(defaultSettings, callSettings),
116
+ api: callSettings.api ?? defaultSettings?.api ?? fallbackApi
117
+ };
118
+ }
119
+ function resolveApi(providerApi, modelApi, invocationApi) {
120
+ return invocationApi ?? modelApi ?? providerApi ?? "orchestration";
121
+ }
122
+ function validateApiInput(api) {
123
+ if (api === void 0) return;
124
+ if (typeof api !== "string" || !VALID_API_TYPES.includes(api)) {
125
+ throw new Error(
126
+ `Invalid API type: ${JSON.stringify(api)}. Valid values are: ${VALID_API_TYPES.map((t) => `"${t}"`).join(", ")}`
127
+ );
128
+ }
129
+ }
130
+ function validateMaskingProvidersDeprecation(modelSettings, warnings) {
131
+ const masking = modelSettings?.masking;
132
+ if (!masking || typeof masking !== "object") {
133
+ return;
134
+ }
135
+ const maskingRecord = masking;
136
+ const hasDeprecated = maskingRecord.masking_providers !== void 0;
137
+ const hasPreferred = maskingRecord.providers !== void 0;
138
+ if (hasDeprecated && !hasPreferred) {
139
+ warnings.push({
140
+ message: "settings.masking.masking_providers is deprecated and will be removed by SAP on 2027-03-20. Migrate to settings.masking.providers.",
141
+ type: "other"
142
+ });
143
+ }
144
+ }
145
+ function validateSettings(options) {
146
+ const { api, embeddingSettings, invocationSettings, modelApi, modelSettings } = options;
147
+ validateApiInput(api);
148
+ if (invocationSettings?.api !== void 0) {
149
+ validateApiInput(invocationSettings.api);
150
+ }
151
+ if (invocationSettings?.api !== void 0) {
152
+ const effectiveModelApi = modelApi ?? "orchestration";
153
+ if (effectiveModelApi !== invocationSettings.api) {
154
+ validateApiSwitch(effectiveModelApi, invocationSettings.api, modelSettings);
155
+ }
156
+ }
157
+ if (api === "foundation-models") {
158
+ validateOrchestrationOnlyOptions(modelSettings);
159
+ validateOrchestrationOnlyInvocationOptions(invocationSettings);
160
+ validateOrchestrationOnlyEmbeddingOptions(embeddingSettings);
161
+ } else {
162
+ validateFoundationModelsOnlyOptions(modelSettings);
163
+ }
164
+ const modelEscape = modelSettings?.escapeTemplatePlaceholders;
165
+ const invocationEscape = invocationSettings?.escapeTemplatePlaceholders;
166
+ const effectiveEscape = invocationEscape ?? modelEscape;
167
+ validateEscapeTemplatePlaceholders(api, effectiveEscape);
168
+ }
169
+ function validateOrchestrationOnlyInvocationOptions(invocationSettings) {
170
+ if (!invocationSettings) return;
171
+ for (const feature of ORCHESTRATION_ONLY_INVOCATION_FEATURE_KEYS) {
172
+ if (invocationSettings[feature] !== void 0) {
173
+ throw new UnsupportedFeatureError(
174
+ ORCHESTRATION_ONLY_FEATURES[feature],
175
+ "foundation-models",
176
+ "orchestration"
177
+ );
178
+ }
179
+ }
180
+ }
181
+
182
+ export {
183
+ mergeSettingsWithApi,
184
+ resolveApi,
185
+ validateMaskingProvidersDeprecation,
186
+ validateSettings
187
+ };
188
+ //# sourceMappingURL=chunk-WDUOKIKD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sap-ai-validation.ts"],"sourcesContent":["/** Validation and resolution functions for SAP AI API-specific features. */\nimport type { SharedV3Warning } from \"@ai-sdk/provider\";\n\nimport type {\n FoundationModelsModelSettings,\n OrchestrationModelSettings,\n SAPAIApiType,\n SAPAIEmbeddingSettings,\n SAPAIModelSettings,\n SAPAISettings,\n} from \"./sap-ai-settings.js\";\n\nimport { deepMerge } from \"./deep-merge.js\";\nimport { ApiSwitchError, UnsupportedFeatureError } from \"./sap-ai-error.js\";\n\n/**\n * Type guard for Foundation Models API settings.\n * @param settings - Settings to check.\n * @returns True if settings are for Foundation Models API.\n */\nexport function isFoundationModelsSettings(\n settings: SAPAIModelSettings | SAPAISettings,\n): settings is FoundationModelsModelSettings {\n return settings.api === \"foundation-models\";\n}\n\n/**\n * Type guard for Orchestration API settings.\n * @param settings - Settings to check.\n * @returns True if settings are for Orchestration API.\n */\nexport function isOrchestrationSettings(\n settings: SAPAIModelSettings | SAPAISettings,\n): settings is OrchestrationModelSettings {\n return settings.api === undefined || settings.api === \"orchestration\";\n}\n\n/**\n * Validates escapeTemplatePlaceholders option based on API type.\n *\n * Jinja2 template escaping is only supported by the Orchestration API.\n * @param api - SAP AI API type.\n * @param escapeTemplatePlaceholders - Whether to escape template placeholders.\n * @throws {UnsupportedFeatureError} When escapeTemplatePlaceholders is true with Foundation Models API.\n * @internal\n */\nfunction validateEscapeTemplatePlaceholders(\n api: SAPAIApiType,\n escapeTemplatePlaceholders: boolean | undefined,\n): void {\n if (api === \"foundation-models\" && escapeTemplatePlaceholders === true) {\n throw new UnsupportedFeatureError(\n ESCAPE_TEMPLATE_PLACEHOLDERS_DESCRIPTION,\n \"foundation-models\",\n \"orchestration\",\n );\n }\n}\n\n/**\n * Validates that Foundation Models-only options are not used with Orchestration API.\n *\n * Foundation Models-only features:\n * - `dataSources` - Azure On Your Data configuration\n * @param settings - Settings to validate.\n * @throws {UnsupportedFeatureError} When dataSources is set with Orchestration API.\n * @internal\n */\nfunction validateFoundationModelsOnlyOptions(\n settings: SAPAIModelSettings | SAPAISettings | undefined,\n): void {\n if (!settings) return;\n\n const fmSettings = settings as FoundationModelsModelSettings;\n\n for (const feature of FOUNDATION_MODELS_ONLY_FEATURE_KEYS) {\n if (fmSettings[feature] !== undefined) {\n throw new UnsupportedFeatureError(\n FOUNDATION_MODELS_ONLY_FEATURES[feature],\n \"orchestration\",\n \"foundation-models\",\n );\n }\n }\n}\n\n/**\n * Validates that Orchestration-only embedding options are not used with Foundation Models API.\n *\n * Orchestration-only embedding features:\n * - `masking` - Data masking module\n * @param settings - Embedding settings to validate.\n * @throws {UnsupportedFeatureError} When masking is set with Foundation Models API.\n * @internal\n */\nfunction validateOrchestrationOnlyEmbeddingOptions(\n settings: SAPAIEmbeddingSettings | undefined,\n): void {\n if (!settings) return;\n\n for (const feature of ORCHESTRATION_ONLY_EMBEDDING_FEATURE_KEYS) {\n if (settings[feature] !== undefined) {\n throw new UnsupportedFeatureError(\n ORCHESTRATION_ONLY_EMBEDDING_FEATURES[feature],\n \"foundation-models\",\n \"orchestration\",\n );\n }\n }\n}\n\n/**\n * Validates that Orchestration-only options are not used with Foundation Models API.\n *\n * Orchestration-only features:\n * - `filtering` - Content filtering module\n * - `grounding` - Document grounding module\n * - `masking` - Data masking module\n * - `orchestrationConfigRef` - Prompt Registry configuration reference\n * - `placeholderValues` - Jinja2 template placeholder values\n * - `promptTemplateRef` - Prompt Registry template reference\n * - `tools` - SAP-format tool definitions (use AI SDK tools instead)\n * - `translation` - Translation module\n * @param settings - Settings to validate.\n * @throws {UnsupportedFeatureError} When any Orchestration-only feature is set with Foundation Models API.\n * @internal\n */\nfunction validateOrchestrationOnlyOptions(\n settings: SAPAIModelSettings | SAPAISettings | undefined,\n): void {\n if (!settings) return;\n\n const orchSettings = settings as OrchestrationModelSettings;\n\n for (const feature of ORCHESTRATION_ONLY_FEATURE_KEYS) {\n if (orchSettings[feature] !== undefined) {\n throw new UnsupportedFeatureError(\n ORCHESTRATION_ONLY_FEATURES[feature],\n \"foundation-models\",\n \"orchestration\",\n );\n }\n }\n}\n\n/**\n * Keys for Orchestration-only features.\n * @internal\n */\nconst ORCHESTRATION_ONLY_FEATURE_KEYS = [\n \"filtering\",\n \"grounding\",\n \"masking\",\n \"orchestrationConfigRef\",\n \"placeholderValues\",\n \"promptTemplateRef\",\n \"streamOptions\",\n \"tools\",\n \"translation\",\n] as const;\n\n/**\n * Mapping of Orchestration-only feature keys to human-readable descriptions.\n * Used for generating consistent error messages.\n * @internal\n */\nconst ORCHESTRATION_ONLY_FEATURES: Readonly<\n Record<(typeof ORCHESTRATION_ONLY_FEATURE_KEYS)[number], string>\n> = {\n filtering: \"Content filtering\",\n grounding: \"Document grounding\",\n masking: \"Data masking\",\n orchestrationConfigRef: \"Orchestration config reference (orchestrationConfigRef)\",\n placeholderValues: \"Placeholder values (placeholderValues)\",\n promptTemplateRef: \"Prompt template reference (promptTemplateRef)\",\n streamOptions: \"Stream options for post-LLM modules\",\n tools: \"SAP-format tool definitions (use AI SDK tools instead)\",\n translation: \"Translation\",\n} as const;\n\n/**\n * Keys for Foundation Models-only features.\n * @internal\n */\nconst FOUNDATION_MODELS_ONLY_FEATURE_KEYS = [\"dataSources\"] as const;\n\n/**\n * Mapping of Foundation Models-only feature keys to human-readable descriptions.\n * Used for generating consistent error messages.\n * @internal\n */\nconst FOUNDATION_MODELS_ONLY_FEATURES: Readonly<\n Record<(typeof FOUNDATION_MODELS_ONLY_FEATURE_KEYS)[number], string>\n> = {\n dataSources: \"Azure On Your Data (dataSources)\",\n} as const;\n\n/**\n * Subset of Orchestration-only features that can be set at invocation level.\n * @internal\n */\nconst ORCHESTRATION_ONLY_INVOCATION_FEATURE_KEYS = [\n \"orchestrationConfigRef\",\n \"placeholderValues\",\n \"promptTemplateRef\",\n] as const;\n\n/**\n * Keys for Orchestration-only embedding features.\n * @internal\n */\nconst ORCHESTRATION_ONLY_EMBEDDING_FEATURE_KEYS = [\"masking\"] as const;\n\n/**\n * Mapping of Orchestration-only embedding feature keys to human-readable descriptions.\n * Uses the same descriptions as the main ORCHESTRATION_ONLY_FEATURES for consistency.\n * @internal\n */\nconst ORCHESTRATION_ONLY_EMBEDDING_FEATURES: Readonly<\n Record<(typeof ORCHESTRATION_ONLY_EMBEDDING_FEATURE_KEYS)[number], string>\n> = {\n masking: ORCHESTRATION_ONLY_FEATURES.masking,\n} as const;\n\n/**\n * Human-readable description for escapeTemplatePlaceholders feature.\n * Used for generating consistent error messages.\n * @internal\n */\nconst ESCAPE_TEMPLATE_PLACEHOLDERS_DESCRIPTION =\n \"escapeTemplatePlaceholders (Jinja2 template escaping)\";\n\n/**\n * Validates that switching APIs at invocation time is allowed.\n *\n * API switching is blocked when the model was configured with features\n * that are specific to one API and incompatible with the target API.\n * @param fromApi - Source API type (configured at model creation).\n * @param toApi - Target API type (requested at invocation time).\n * @param modelSettings - Model settings to validate for conflicts.\n * @throws {ApiSwitchError} When the model has features incompatible with the target API.\n * @internal\n */\nfunction validateApiSwitch(\n fromApi: SAPAIApiType,\n toApi: SAPAIApiType,\n modelSettings: SAPAIModelSettings | SAPAISettings | undefined,\n): void {\n if (fromApi === toApi) return;\n if (!modelSettings) return;\n\n if (fromApi === \"orchestration\" && toApi === \"foundation-models\") {\n const orchSettings = modelSettings as OrchestrationModelSettings;\n\n for (const feature of ORCHESTRATION_ONLY_FEATURE_KEYS) {\n if (orchSettings[feature] !== undefined) {\n throw new ApiSwitchError(fromApi, toApi, feature);\n }\n }\n }\n\n if (fromApi === \"foundation-models\" && toApi === \"orchestration\") {\n const fmSettings = modelSettings as FoundationModelsModelSettings;\n\n for (const feature of FOUNDATION_MODELS_ONLY_FEATURE_KEYS) {\n if (fmSettings[feature] !== undefined) {\n throw new ApiSwitchError(fromApi, toApi, feature);\n }\n }\n }\n}\n\n/**\n * @internal\n */\nconst VALID_API_TYPES: readonly SAPAIApiType[] = [\"orchestration\", \"foundation-models\"];\n\n/** Options for the main validation function. */\nexport interface ValidateSettingsOptions {\n readonly api: SAPAIApiType;\n readonly embeddingSettings?: SAPAIEmbeddingSettings;\n readonly invocationSettings?: {\n readonly api?: SAPAIApiType;\n readonly escapeTemplatePlaceholders?: boolean;\n readonly orchestrationConfigRef?: unknown;\n readonly placeholderValues?: unknown;\n readonly promptTemplateRef?: unknown;\n };\n readonly modelApi?: SAPAIApiType;\n readonly modelSettings?: SAPAIModelSettings | SAPAISettings;\n}\n\n/**\n * Gets the effective escapeTemplatePlaceholders value based on API and settings.\n * @param api - SAP AI API type.\n * @param modelSettings - Model settings.\n * @param invocationEscape - Invocation-level escape setting.\n * @returns Effective escapeTemplatePlaceholders value.\n */\nexport function getEffectiveEscapeTemplatePlaceholders(\n api: SAPAIApiType,\n modelSettings: SAPAIModelSettings | SAPAISettings | undefined,\n invocationEscape: boolean | undefined,\n): boolean {\n if (api === \"foundation-models\") {\n return false;\n }\n\n if (invocationEscape !== undefined) {\n return invocationEscape;\n }\n\n const modelValue = (modelSettings as OrchestrationModelSettings | undefined)\n ?.escapeTemplatePlaceholders;\n if (modelValue !== undefined) {\n return modelValue;\n }\n\n return true;\n}\n\n/**\n * Merges settings with proper API precedence (callSettings > defaultSettings > fallbackApi).\n * @param defaultSettings - Provider-level default settings.\n * @param callSettings - Per-call settings that override defaults.\n * @param fallbackApi - Fallback API type when neither settings specify one.\n * @returns Merged settings with correct API precedence.\n * @internal\n */\nexport function mergeSettingsWithApi<T extends { api?: string }>(\n defaultSettings: Record<string, unknown> | undefined,\n callSettings: Partial<T>,\n fallbackApi: string,\n): T {\n return {\n ...deepMerge(defaultSettings, callSettings as Record<string, unknown>),\n api: callSettings.api ?? (defaultSettings?.api as string | undefined) ?? fallbackApi,\n } as T;\n}\n\n/**\n * Resolves the effective API type using the full precedence chain.\n * @param providerApi - Provider-level API type.\n * @param modelApi - Model-level API type.\n * @param invocationApi - Invocation-level API type.\n * @returns Resolved API type.\n */\nexport function resolveApi(\n providerApi: SAPAIApiType | undefined,\n modelApi: SAPAIApiType | undefined,\n invocationApi: SAPAIApiType | undefined,\n): SAPAIApiType {\n return invocationApi ?? modelApi ?? providerApi ?? \"orchestration\";\n}\n\n/**\n * Validates that the API value is a valid SAPAIApiType.\n * @param api - API value to validate.\n */\nexport function validateApiInput(api: unknown): void {\n if (api === undefined) return;\n\n if (typeof api !== \"string\" || !VALID_API_TYPES.includes(api as SAPAIApiType)) {\n throw new Error(\n `Invalid API type: ${JSON.stringify(api)}. ` +\n `Valid values are: ${VALID_API_TYPES.map((t) => `\"${t}\"`).join(\", \")}`,\n );\n }\n}\n\n/**\n * Pushes a deprecation warning when `settings.masking` carries `masking_providers`\n * without a `providers` block.\n * @param modelSettings - Resolved model settings (LM or embedding) that may carry a `masking` module.\n * @param warnings - Sink that collects the deprecation warning when it applies.\n * @internal\n */\nexport function validateMaskingProvidersDeprecation(\n modelSettings: undefined | { masking?: unknown },\n warnings: SharedV3Warning[],\n): void {\n const masking = modelSettings?.masking;\n if (!masking || typeof masking !== \"object\") {\n return;\n }\n const maskingRecord = masking as Record<string, unknown>;\n const hasDeprecated = maskingRecord.masking_providers !== undefined;\n const hasPreferred = maskingRecord.providers !== undefined;\n if (hasDeprecated && !hasPreferred) {\n warnings.push({\n message:\n \"settings.masking.masking_providers is deprecated and will be removed by SAP on 2027-03-20. \" +\n \"Migrate to settings.masking.providers.\",\n type: \"other\",\n });\n }\n}\n\n/**\n * Main validation function that performs all API-specific validations.\n *\n * This function orchestrates all validation checks:\n * 1. Validates API type inputs\n * 2. Checks for API switching conflicts\n * 3. Validates API-specific feature usage\n * 4. Validates template placeholder escaping\n * @param options - Validation options.\n * @throws {Error} When an invalid API type is provided.\n * @throws {ApiSwitchError} When attempting to switch APIs with incompatible settings.\n * @throws {UnsupportedFeatureError} When using features not supported by the current API.\n * @see {@link ApiSwitchError}\n * @see {@link UnsupportedFeatureError}\n */\nexport function validateSettings(options: ValidateSettingsOptions): void {\n const { api, embeddingSettings, invocationSettings, modelApi, modelSettings } = options;\n\n validateApiInput(api);\n if (invocationSettings?.api !== undefined) {\n validateApiInput(invocationSettings.api);\n }\n\n if (invocationSettings?.api !== undefined) {\n const effectiveModelApi = modelApi ?? \"orchestration\";\n if (effectiveModelApi !== invocationSettings.api) {\n validateApiSwitch(effectiveModelApi, invocationSettings.api, modelSettings);\n }\n }\n\n if (api === \"foundation-models\") {\n validateOrchestrationOnlyOptions(modelSettings);\n validateOrchestrationOnlyInvocationOptions(invocationSettings);\n validateOrchestrationOnlyEmbeddingOptions(embeddingSettings);\n } else {\n validateFoundationModelsOnlyOptions(modelSettings);\n }\n\n const modelEscape = (modelSettings as OrchestrationModelSettings | undefined)\n ?.escapeTemplatePlaceholders;\n const invocationEscape = invocationSettings?.escapeTemplatePlaceholders;\n const effectiveEscape = invocationEscape ?? modelEscape;\n validateEscapeTemplatePlaceholders(api, effectiveEscape);\n}\n\n/**\n * Validates that Orchestration-only options are not passed at invocation level with Foundation Models API.\n * @param invocationSettings - Invocation-level settings to validate.\n * @throws {UnsupportedFeatureError} When any Orchestration-only feature is set at invocation level.\n * @internal\n */\nfunction validateOrchestrationOnlyInvocationOptions(\n invocationSettings: ValidateSettingsOptions[\"invocationSettings\"],\n): void {\n if (!invocationSettings) return;\n\n for (const feature of ORCHESTRATION_ONLY_INVOCATION_FEATURE_KEYS) {\n if (invocationSettings[feature] !== undefined) {\n throw new UnsupportedFeatureError(\n ORCHESTRATION_ONLY_FEATURES[feature],\n \"foundation-models\",\n \"orchestration\",\n );\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,13 +1,14 @@
1
1
  import {createRequire as __createRequire} from 'module';var require=__createRequire(import.meta.url);
2
2
  import {
3
3
  BaseEmbeddingModelStrategy
4
- } from "./chunk-X66RDDSB.js";
4
+ } from "./chunk-GMMX46AH.js";
5
5
  import {
6
6
  buildModelDeployment,
7
+ extractResponseMetadata,
7
8
  hasKeys,
8
9
  normalizeEmbedding
9
- } from "./chunk-M3AV2YUV.js";
10
- import "./chunk-7OGNFVGC.js";
10
+ } from "./chunk-36DFHUVQ.js";
11
+ import "./chunk-TVXWNZQT.js";
11
12
 
12
13
  // src/foundation-models-embedding-model-strategy.ts
13
14
  var FoundationModelsEmbeddingModelStrategy = class extends BaseEmbeddingModelStrategy {
@@ -35,6 +36,9 @@ var FoundationModelsEmbeddingModelStrategy = class extends BaseEmbeddingModelStr
35
36
  const sortedEmbeddings = embeddingData.slice().sort((a, b) => a.index - b.index);
36
37
  return sortedEmbeddings.map((item) => normalizeEmbedding(item.embedding));
37
38
  }
39
+ extractResponseMetadata(response) {
40
+ return extractResponseMetadata(response, "rawResponse");
41
+ }
38
42
  extractTokenCount(response) {
39
43
  return response._data.usage.total_tokens;
40
44
  }
@@ -51,4 +55,4 @@ var FoundationModelsEmbeddingModelStrategy = class extends BaseEmbeddingModelStr
51
55
  export {
52
56
  FoundationModelsEmbeddingModelStrategy
53
57
  };
54
- //# sourceMappingURL=foundation-models-embedding-model-strategy-GXJRGM4X.js.map
58
+ //# sourceMappingURL=foundation-models-embedding-model-strategy-YWPDIJEN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/foundation-models-embedding-model-strategy.ts"],"sourcesContent":["/** Foundation Models embedding model strategy using `@sap-ai-sdk/foundation-models`. */\nimport type { EmbeddingModelV3Embedding } from \"@ai-sdk/provider\";\nimport type {\n AzureOpenAiEmbeddingClient,\n AzureOpenAiEmbeddingParameters,\n AzureOpenAiEmbeddingResponse,\n} from \"@sap-ai-sdk/foundation-models\";\n\nimport type { SAPAIEmbeddingSettings } from \"./sap-ai-settings.js\";\nimport type { EmbeddingModelStrategyConfig } from \"./sap-ai-strategy.js\";\nimport type { EmbeddingProviderOptions, ResponseMetadata } from \"./strategy-utils.js\";\n\nimport { BaseEmbeddingModelStrategy } from \"./base-embedding-model-strategy.js\";\nimport {\n buildModelDeployment,\n extractResponseMetadata,\n hasKeys,\n normalizeEmbedding,\n} from \"./strategy-utils.js\";\n\n/**\n * Client with pre-merged params for thread-safe concurrent requests.\n * @internal\n */\ninterface FMEmbeddingClientWithContext {\n client: AzureOpenAiEmbeddingClient;\n mergedParams: Record<string, unknown> | undefined;\n}\n\n/** @internal */\ntype FoundationModelsEmbeddingClientClass = typeof AzureOpenAiEmbeddingClient;\n\n/**\n * Embedding model strategy for the Foundation Models API.\n *\n * Provides direct access to Azure OpenAI embedding models.\n * @internal\n */\nexport class FoundationModelsEmbeddingModelStrategy extends BaseEmbeddingModelStrategy<\n FMEmbeddingClientWithContext,\n AzureOpenAiEmbeddingResponse\n> {\n private readonly ClientClass: FoundationModelsEmbeddingClientClass;\n\n constructor(ClientClass: FoundationModelsEmbeddingClientClass) {\n super();\n this.ClientClass = ClientClass;\n }\n\n protected createClient(\n config: EmbeddingModelStrategyConfig,\n settings: SAPAIEmbeddingSettings,\n embeddingOptions: EmbeddingProviderOptions | undefined,\n ): FMEmbeddingClientWithContext {\n const mergedParams = this.mergeModelParams(settings, embeddingOptions);\n\n return {\n client: new this.ClientClass(\n buildModelDeployment(config, settings.modelVersion),\n config.destination,\n ),\n mergedParams: hasKeys(mergedParams) ? mergedParams : undefined,\n };\n }\n\n protected async executeCall(\n clientWithContext: FMEmbeddingClientWithContext,\n values: string[],\n _embeddingType: unknown,\n abortSignal: AbortSignal | undefined,\n ): Promise<AzureOpenAiEmbeddingResponse> {\n const request = this.buildRequest(values, clientWithContext.mergedParams);\n return clientWithContext.client.run(request, abortSignal ? { signal: abortSignal } : undefined);\n }\n\n protected extractEmbeddings(response: AzureOpenAiEmbeddingResponse): EmbeddingModelV3Embedding[] {\n // SDK types include `& Record<string, any>` which requires explicit extraction\n const embeddingData = response._data.data;\n const sortedEmbeddings = embeddingData.slice().sort((a, b) => a.index - b.index);\n return sortedEmbeddings.map((item) => normalizeEmbedding(item.embedding as number[]));\n }\n\n protected override extractResponseMetadata(\n response: AzureOpenAiEmbeddingResponse,\n ): ResponseMetadata {\n return extractResponseMetadata(response, \"rawResponse\");\n }\n\n protected extractTokenCount(response: AzureOpenAiEmbeddingResponse): number {\n return response._data.usage.total_tokens;\n }\n\n protected getUrl(): string {\n return \"sap-ai:foundation-models/embeddings\";\n }\n\n private buildRequest(\n values: string[],\n mergedParams: Record<string, unknown> | undefined,\n ): AzureOpenAiEmbeddingParameters {\n return {\n input: values,\n ...(mergedParams ?? {}),\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAsCO,IAAM,yCAAN,cAAqD,2BAG1D;AAAA,EACiB;AAAA,EAEjB,YAAY,aAAmD;AAC7D,UAAM;AACN,SAAK,cAAc;AAAA,EACrB;AAAA,EAEU,aACR,QACA,UACA,kBAC8B;AAC9B,UAAM,eAAe,KAAK,iBAAiB,UAAU,gBAAgB;AAErE,WAAO;AAAA,MACL,QAAQ,IAAI,KAAK;AAAA,QACf,qBAAqB,QAAQ,SAAS,YAAY;AAAA,QAClD,OAAO;AAAA,MACT;AAAA,MACA,cAAc,QAAQ,YAAY,IAAI,eAAe;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,MAAgB,YACd,mBACA,QACA,gBACA,aACuC;AACvC,UAAM,UAAU,KAAK,aAAa,QAAQ,kBAAkB,YAAY;AACxE,WAAO,kBAAkB,OAAO,IAAI,SAAS,cAAc,EAAE,QAAQ,YAAY,IAAI,MAAS;AAAA,EAChG;AAAA,EAEU,kBAAkB,UAAqE;AAE/F,UAAM,gBAAgB,SAAS,MAAM;AACrC,UAAM,mBAAmB,cAAc,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAC/E,WAAO,iBAAiB,IAAI,CAAC,SAAS,mBAAmB,KAAK,SAAqB,CAAC;AAAA,EACtF;AAAA,EAEmB,wBACjB,UACkB;AAClB,WAAO,wBAAwB,UAAU,aAAa;AAAA,EACxD;AAAA,EAEU,kBAAkB,UAAgD;AAC1E,WAAO,SAAS,MAAM,MAAM;AAAA,EAC9B;AAAA,EAEU,SAAiB;AACzB,WAAO;AAAA,EACT;AAAA,EAEQ,aACN,QACA,cACgC;AAChC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,GAAI,gBAAgB,CAAC;AAAA,IACvB;AAAA,EACF;AACF;","names":[]}
@@ -1,16 +1,14 @@
1
1
  import {createRequire as __createRequire} from 'module';var require=__createRequire(import.meta.url);
2
2
  import {
3
3
  BaseLanguageModelStrategy
4
- } from "./chunk-6BVUDEKZ.js";
5
- import "./chunk-IIBSUXGT.js";
4
+ } from "./chunk-BZZJKLDG.js";
5
+ import "./chunk-4JIMBRMV.js";
6
6
  import {
7
7
  buildModelDeployment,
8
8
  convertResponseFormat,
9
9
  convertToolsToSAPFormat
10
- } from "./chunk-M3AV2YUV.js";
11
- import {
12
- normalizeHeaders
13
- } from "./chunk-7OGNFVGC.js";
10
+ } from "./chunk-36DFHUVQ.js";
11
+ import "./chunk-TVXWNZQT.js";
14
12
 
15
13
  // src/foundation-models-language-model-strategy.ts
16
14
  var FOUNDATION_MODELS_PARAM_MAPPINGS = [
@@ -29,9 +27,7 @@ var FoundationModelsLanguageModelStrategy = class extends BaseLanguageModelStrat
29
27
  }
30
28
  buildRequest(_config, settings, options, commonParts) {
31
29
  const warnings = [];
32
- const toolsResult = convertToolsToSAPFormat(
33
- options.tools
34
- );
30
+ const toolsResult = convertToolsToSAPFormat(options.tools);
35
31
  warnings.push(...toolsResult.warnings);
36
32
  const { responseFormat, warning: responseFormatWarning } = convertResponseFormat(
37
33
  options.responseFormat,
@@ -59,8 +55,7 @@ var FoundationModelsLanguageModelStrategy = class extends BaseLanguageModelStrat
59
55
  }
60
56
  async executeApiCall(client, request, abortSignal) {
61
57
  const response = await client.run(request, abortSignal ? { signal: abortSignal } : void 0);
62
- const headers = normalizeHeaders(response.rawResponse.headers);
63
- const completionId = response._data?.id ?? headers?.["x-request-id"];
58
+ const { requestId, responseId } = this.extractMetadata(response);
64
59
  return {
65
60
  getContent: () => response.getContent(),
66
61
  getFinishReason: () => response.getFinishReason(),
@@ -68,17 +63,25 @@ var FoundationModelsLanguageModelStrategy = class extends BaseLanguageModelStrat
68
63
  getToolCalls: () => response.getToolCalls(),
69
64
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- SAP SDK types headers as any
70
65
  rawResponse: { headers: response.rawResponse.headers },
71
- responseId: completionId
66
+ requestId,
67
+ responseId
72
68
  };
73
69
  }
74
70
  async executeStreamCall(client, request, abortSignal, _settings) {
75
71
  const streamResponse = await client.stream(request, abortSignal);
72
+ const { requestId, responseHeaders, responseId } = this.extractMetadata(streamResponse);
76
73
  return {
77
74
  getFinishReason: () => streamResponse.getFinishReason(),
78
75
  getTokenUsage: () => streamResponse.getTokenUsage(),
76
+ requestId,
77
+ responseHeaders,
78
+ responseId,
79
79
  stream: streamResponse.stream
80
80
  };
81
81
  }
82
+ getCompletionIdPath() {
83
+ return ["id"];
84
+ }
82
85
  getParamMappings() {
83
86
  return FOUNDATION_MODELS_PARAM_MAPPINGS;
84
87
  }
@@ -89,4 +92,4 @@ var FoundationModelsLanguageModelStrategy = class extends BaseLanguageModelStrat
89
92
  export {
90
93
  FoundationModelsLanguageModelStrategy
91
94
  };
92
- //# sourceMappingURL=foundation-models-language-model-strategy-FGUGQPBL.js.map
95
+ //# sourceMappingURL=foundation-models-language-model-strategy-WDSQWU64.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/foundation-models-language-model-strategy.ts"],"sourcesContent":["/** Foundation Models language model strategy using `@sap-ai-sdk/foundation-models`. */\nimport type { LanguageModelV3CallOptions, SharedV3Warning } from \"@ai-sdk/provider\";\nimport type {\n AzureOpenAiChatClient,\n AzureOpenAiChatCompletionParameters,\n AzureOpenAiChatCompletionTool,\n} from \"@sap-ai-sdk/foundation-models\";\nimport type { ChatMessage } from \"@sap-ai-sdk/orchestration\";\n\nimport type { FoundationModelsModelSettings } from \"./sap-ai-settings.js\";\nimport type { LanguageModelStrategyConfig } from \"./sap-ai-strategy.js\";\n\nimport {\n BaseLanguageModelStrategy,\n type CommonBuildResult,\n type StreamCallResponse,\n} from \"./base-language-model-strategy.js\";\nimport {\n buildModelDeployment,\n convertResponseFormat,\n convertToolsToSAPFormat,\n type ParamMapping,\n type SAPToolChoice,\n type SDKResponse,\n type SDKStreamChunk,\n} from \"./strategy-utils.js\";\n\n/** @internal */\ntype FoundationModelsClient = InstanceType<typeof AzureOpenAiChatClient>;\n\n/**\n * Foundation Models API parameter mappings.\n * @internal\n */\nconst FOUNDATION_MODELS_PARAM_MAPPINGS: readonly ParamMapping[] = [\n ...BaseLanguageModelStrategy.COMMON_PARAM_MAPPINGS,\n { camelCaseKey: \"logprobs\", outputKey: \"logprobs\" },\n { camelCaseKey: \"topLogprobs\", outputKey: \"top_logprobs\" },\n { camelCaseKey: \"logitBias\", outputKey: \"logit_bias\" },\n { camelCaseKey: \"user\", outputKey: \"user\" },\n { camelCaseKey: \"n\", outputKey: \"n\" },\n] as const;\n\n/**\n * Language model strategy for the Foundation Models API.\n *\n * Provides direct access to Azure OpenAI models with parameters like:\n * - logprobs\n * - seed\n * - dataSources (On Your Data)\n * @internal\n */\nexport class FoundationModelsLanguageModelStrategy extends BaseLanguageModelStrategy<\n FoundationModelsClient,\n AzureOpenAiChatCompletionParameters,\n FoundationModelsModelSettings\n> {\n private readonly ClientClass: typeof AzureOpenAiChatClient;\n\n constructor(ClientClass: typeof AzureOpenAiChatClient) {\n super();\n this.ClientClass = ClientClass;\n }\n\n protected buildRequest(\n _config: LanguageModelStrategyConfig,\n settings: FoundationModelsModelSettings,\n options: LanguageModelV3CallOptions,\n commonParts: CommonBuildResult<ChatMessage[], SAPToolChoice | undefined>,\n ): {\n readonly request: AzureOpenAiChatCompletionParameters;\n readonly warnings: SharedV3Warning[];\n } {\n const warnings: SharedV3Warning[] = [];\n\n const toolsResult = convertToolsToSAPFormat<AzureOpenAiChatCompletionTool>(options.tools);\n warnings.push(...toolsResult.warnings);\n\n const { responseFormat, warning: responseFormatWarning } = convertResponseFormat(\n options.responseFormat,\n settings.responseFormat,\n );\n if (responseFormatWarning) {\n warnings.push(responseFormatWarning);\n }\n\n const { toolChoice } = commonParts;\n\n const request: AzureOpenAiChatCompletionParameters = {\n messages: commonParts.messages as AzureOpenAiChatCompletionParameters[\"messages\"],\n ...(commonParts.modelParams as Partial<AzureOpenAiChatCompletionParameters>),\n ...(toolsResult.tools?.length ? { tools: toolsResult.tools } : {}),\n ...(toolChoice ? { tool_choice: toolChoice } : {}),\n ...(responseFormat ? { response_format: responseFormat } : {}),\n ...(settings.dataSources?.length\n ? {\n data_sources: settings.dataSources,\n }\n : {}),\n };\n\n return { request, warnings };\n }\n\n protected createClient(\n config: LanguageModelStrategyConfig,\n settings: FoundationModelsModelSettings,\n _commonParts: CommonBuildResult<ChatMessage[], SAPToolChoice | undefined>,\n ): FoundationModelsClient {\n const modelDeployment = buildModelDeployment(config, settings.modelVersion);\n return new this.ClientClass(modelDeployment, config.destination);\n }\n\n protected async executeApiCall(\n client: FoundationModelsClient,\n request: AzureOpenAiChatCompletionParameters,\n abortSignal: AbortSignal | undefined,\n ): Promise<SDKResponse> {\n const response = await client.run(request, abortSignal ? { signal: abortSignal } : undefined);\n\n const { requestId, responseId } = this.extractMetadata(response);\n\n return {\n getContent: () => response.getContent(),\n getFinishReason: () => response.getFinishReason(),\n getTokenUsage: () => response.getTokenUsage(),\n getToolCalls: () => response.getToolCalls(),\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- SAP SDK types headers as any\n rawResponse: { headers: response.rawResponse.headers },\n requestId,\n responseId,\n };\n }\n\n protected async executeStreamCall(\n client: FoundationModelsClient,\n request: AzureOpenAiChatCompletionParameters,\n abortSignal: AbortSignal | undefined,\n _settings: FoundationModelsModelSettings,\n ): Promise<StreamCallResponse> {\n const streamResponse = await client.stream(request, abortSignal);\n\n const { requestId, responseHeaders, responseId } = this.extractMetadata(streamResponse);\n\n return {\n getFinishReason: () => streamResponse.getFinishReason(),\n getTokenUsage: () => streamResponse.getTokenUsage(),\n requestId,\n responseHeaders,\n responseId,\n stream: streamResponse.stream as AsyncIterable<SDKStreamChunk>,\n };\n }\n\n protected getCompletionIdPath(): readonly string[] {\n return [\"id\"];\n }\n\n protected getParamMappings(): readonly ParamMapping[] {\n return FOUNDATION_MODELS_PARAM_MAPPINGS;\n }\n\n protected getUrl(): string {\n return \"sap-ai:foundation-models\";\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAkCA,IAAM,mCAA4D;AAAA,EAChE,GAAG,0BAA0B;AAAA,EAC7B,EAAE,cAAc,YAAY,WAAW,WAAW;AAAA,EAClD,EAAE,cAAc,eAAe,WAAW,eAAe;AAAA,EACzD,EAAE,cAAc,aAAa,WAAW,aAAa;AAAA,EACrD,EAAE,cAAc,QAAQ,WAAW,OAAO;AAAA,EAC1C,EAAE,cAAc,KAAK,WAAW,IAAI;AACtC;AAWO,IAAM,wCAAN,cAAoD,0BAIzD;AAAA,EACiB;AAAA,EAEjB,YAAY,aAA2C;AACrD,UAAM;AACN,SAAK,cAAc;AAAA,EACrB;AAAA,EAEU,aACR,SACA,UACA,SACA,aAIA;AACA,UAAM,WAA8B,CAAC;AAErC,UAAM,cAAc,wBAAuD,QAAQ,KAAK;AACxF,aAAS,KAAK,GAAG,YAAY,QAAQ;AAErC,UAAM,EAAE,gBAAgB,SAAS,sBAAsB,IAAI;AAAA,MACzD,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AACA,QAAI,uBAAuB;AACzB,eAAS,KAAK,qBAAqB;AAAA,IACrC;AAEA,UAAM,EAAE,WAAW,IAAI;AAEvB,UAAM,UAA+C;AAAA,MACnD,UAAU,YAAY;AAAA,MACtB,GAAI,YAAY;AAAA,MAChB,GAAI,YAAY,OAAO,SAAS,EAAE,OAAO,YAAY,MAAM,IAAI,CAAC;AAAA,MAChE,GAAI,aAAa,EAAE,aAAa,WAAW,IAAI,CAAC;AAAA,MAChD,GAAI,iBAAiB,EAAE,iBAAiB,eAAe,IAAI,CAAC;AAAA,MAC5D,GAAI,SAAS,aAAa,SACtB;AAAA,QACE,cAAc,SAAS;AAAA,MACzB,IACA,CAAC;AAAA,IACP;AAEA,WAAO,EAAE,SAAS,SAAS;AAAA,EAC7B;AAAA,EAEU,aACR,QACA,UACA,cACwB;AACxB,UAAM,kBAAkB,qBAAqB,QAAQ,SAAS,YAAY;AAC1E,WAAO,IAAI,KAAK,YAAY,iBAAiB,OAAO,WAAW;AAAA,EACjE;AAAA,EAEA,MAAgB,eACd,QACA,SACA,aACsB;AACtB,UAAM,WAAW,MAAM,OAAO,IAAI,SAAS,cAAc,EAAE,QAAQ,YAAY,IAAI,MAAS;AAE5F,UAAM,EAAE,WAAW,WAAW,IAAI,KAAK,gBAAgB,QAAQ;AAE/D,WAAO;AAAA,MACL,YAAY,MAAM,SAAS,WAAW;AAAA,MACtC,iBAAiB,MAAM,SAAS,gBAAgB;AAAA,MAChD,eAAe,MAAM,SAAS,cAAc;AAAA,MAC5C,cAAc,MAAM,SAAS,aAAa;AAAA;AAAA,MAE1C,aAAa,EAAE,SAAS,SAAS,YAAY,QAAQ;AAAA,MACrD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAgB,kBACd,QACA,SACA,aACA,WAC6B;AAC7B,UAAM,iBAAiB,MAAM,OAAO,OAAO,SAAS,WAAW;AAE/D,UAAM,EAAE,WAAW,iBAAiB,WAAW,IAAI,KAAK,gBAAgB,cAAc;AAEtF,WAAO;AAAA,MACL,iBAAiB,MAAM,eAAe,gBAAgB;AAAA,MACtD,eAAe,MAAM,eAAe,cAAc;AAAA,MAClD;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,eAAe;AAAA,IACzB;AAAA,EACF;AAAA,EAEU,sBAAyC;AACjD,WAAO,CAAC,IAAI;AAAA,EACd;AAAA,EAEU,mBAA4C;AACpD,WAAO;AAAA,EACT;AAAA,EAEU,SAAiB;AACzB,WAAO;AAAA,EACT;AACF;","names":[]}