mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-11-08 08:55:22 +00:00
feat(openai): allow none as reasoning mapping source
This commit is contained in:
1 parent
b1748c4ea9
commit
7969751f1f
6 files changed
+144
-8
No files matched your search
@@ -23,6 +23,13 @@ const (
|
|||||||
|
|
||||||
var openAIReasoningEffortValues = []string{"minimal", "low", "medium", "high", "xhigh", "max"}
|
var openAIReasoningEffortValues = []string{"minimal", "low", "medium", "high", "xhigh", "max"}
|
||||||
|
|
||||||
|
func normalizeReasoningEffortMappingSource(raw string) string {
|
||||||
|
if strings.EqualFold(strings.TrimSpace(raw), "none") {
|
||||||
|
return "none"
|
||||||
|
}
|
||||||
|
return NormalizeMaxReasoningEffort(raw)
|
||||||
|
}
|
||||||
|
|
||||||
type openAIReasoningEffortPolicyContextKey struct{}
|
type openAIReasoningEffortPolicyContextKey struct{}
|
||||||
type requestedReasoningEffortContextKey struct{}
|
type requestedReasoningEffortContextKey struct{}
|
||||||
|
|
||||||
@@ -220,7 +227,7 @@ func selectReasoningEffortMapping(mappings []ReasoningEffortMapping, from, reque
|
|||||||
}
|
}
|
||||||
candidates := make([]candidate, 0, len(mappings))
|
candidates := make([]candidate, 0, len(mappings))
|
||||||
for i, mapping := range mappings {
|
for i, mapping := range mappings {
|
||||||
if NormalizeMaxReasoningEffort(mapping.From) != from {
|
if normalizeReasoningEffortMappingSource(mapping.From) != from {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
model := strings.TrimSpace(mapping.Model)
|
model := strings.TrimSpace(mapping.Model)
|
||||||
@@ -283,7 +290,7 @@ func NormalizeReasoningEffortMappings(platform string, raw []ReasoningEffortMapp
|
|||||||
normalized := make([]ReasoningEffortMapping, 0, len(raw))
|
normalized := make([]ReasoningEffortMapping, 0, len(raw))
|
||||||
seen := make(map[string]struct{}, len(raw))
|
seen := make(map[string]struct{}, len(raw))
|
||||||
for i, mapping := range raw {
|
for i, mapping := range raw {
|
||||||
from := NormalizeMaxReasoningEffort(mapping.From)
|
from := normalizeReasoningEffortMappingSource(mapping.From)
|
||||||
to := NormalizeMaxReasoningEffort(mapping.To)
|
to := NormalizeMaxReasoningEffort(mapping.To)
|
||||||
if from == "" || to == "" {
|
if from == "" || to == "" {
|
||||||
return nil, fmt.Errorf("reasoning effort mapping %d contains an empty or unknown value", i+1)
|
return nil, fmt.Errorf("reasoning effort mapping %d contains an empty or unknown value", i+1)
|
||||||
@@ -291,9 +298,16 @@ func NormalizeReasoningEffortMappings(platform string, raw []ReasoningEffortMapp
|
|||||||
if len(from) > maxReasoningEffortValueLen || len(to) > maxReasoningEffortValueLen {
|
if len(from) > maxReasoningEffortValueLen || len(to) > maxReasoningEffortValueLen {
|
||||||
return nil, fmt.Errorf("reasoning effort mapping %d values cannot exceed %d characters", i+1, maxReasoningEffortValueLen)
|
return nil, fmt.Errorf("reasoning effort mapping %d values cannot exceed %d characters", i+1, maxReasoningEffortValueLen)
|
||||||
}
|
}
|
||||||
|
if from != "none" {
|
||||||
if _, err := normalizeMaxReasoningEffortForPlatform(platform, from); err != nil {
|
if _, err := normalizeMaxReasoningEffortForPlatform(platform, from); err != nil {
|
||||||
return nil, fmt.Errorf("reasoning effort mapping %d source: %w", i+1, err)
|
return nil, fmt.Errorf("reasoning effort mapping %d source: %w", i+1, err)
|
||||||
}
|
}
|
||||||
|
} else if len(reasoningEffortValuesForPlatform(platform)) == 0 {
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"reasoning effort mapping %d source: reasoning effort policy is only supported for platforms %q and %q",
|
||||||
|
i+1, PlatformOpenAI, PlatformComposite,
|
||||||
|
)
|
||||||
|
}
|
||||||
if _, err := normalizeMaxReasoningEffortForPlatform(platform, to); err != nil {
|
if _, err := normalizeMaxReasoningEffortForPlatform(platform, to); err != nil {
|
||||||
return nil, fmt.Errorf("reasoning effort mapping %d target: %w", i+1, err)
|
return nil, fmt.Errorf("reasoning effort mapping %d target: %w", i+1, err)
|
||||||
}
|
}
|
||||||
@@ -383,7 +397,7 @@ func ApplyOpenAIReasoningEffortPolicyFromContext(ctx context.Context, body []byt
|
|||||||
|
|
||||||
func mapReasoningEffort(raw string, mappings []ReasoningEffortMapping, requestModel string) (string, bool) {
|
func mapReasoningEffort(raw string, mappings []ReasoningEffortMapping, requestModel string) (string, bool) {
|
||||||
value := strings.TrimSpace(raw)
|
value := strings.TrimSpace(raw)
|
||||||
canonical := NormalizeMaxReasoningEffort(value)
|
canonical := normalizeReasoningEffortMappingSource(value)
|
||||||
if canonical == "" {
|
if canonical == "" {
|
||||||
return value, false
|
return value, false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,10 +152,18 @@ func TestNormalizeReasoningEffortMappings(t *testing.T) {
|
|||||||
require.ErrorContains(t, err, "only supported for platforms \"openai\" and \"composite\"")
|
require.ErrorContains(t, err, "only supported for platforms \"openai\" and \"composite\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := NormalizeReasoningEffortMappings(PlatformOpenAI, []ReasoningEffortMapping{{From: "none", To: "low"}})
|
_, err := NormalizeReasoningEffortMappings(PlatformOpenAI, []ReasoningEffortMapping{{From: "ultra", To: "high"}})
|
||||||
require.ErrorContains(t, err, "empty or unknown")
|
require.ErrorContains(t, err, "empty or unknown")
|
||||||
|
})
|
||||||
|
|
||||||
_, err = NormalizeReasoningEffortMappings(PlatformOpenAI, []ReasoningEffortMapping{{From: "ultra", To: "high"}})
|
t.Run("allows none only as a source for OpenAI routes", func(t *testing.T) {
|
||||||
|
for _, platform := range []string{PlatformOpenAI, PlatformComposite} {
|
||||||
|
got, err := NormalizeReasoningEffortMappings(platform, []ReasoningEffortMapping{{From: " NONE ", To: "low"}})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, []ReasoningEffortMapping{{From: "none", To: "low"}}, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := NormalizeReasoningEffortMappings(PlatformOpenAI, []ReasoningEffortMapping{{From: "low", To: "none"}})
|
||||||
require.ErrorContains(t, err, "empty or unknown")
|
require.ErrorContains(t, err, "empty or unknown")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -252,6 +260,15 @@ func TestApplyOpenAIReasoningEffortPolicy(t *testing.T) {
|
|||||||
{name: "caps both shapes", body: `{"reasoning":{"effort":"high"},"reasoning_effort":"xhigh"}`, max: "low", path: "reasoning.effort", want: "low", changed: true},
|
{name: "caps both shapes", body: `{"reasoning":{"effort":"high"},"reasoning_effort":"xhigh"}`, max: "low", path: "reasoning.effort", want: "low", changed: true},
|
||||||
{name: "maps before cap", body: `{"reasoning":{"effort":"MAX"}}`, max: "medium", mappings: []ReasoningEffortMapping{{From: "max", To: "xhigh"}}, path: "reasoning.effort", want: "medium", changed: true},
|
{name: "maps before cap", body: `{"reasoning":{"effort":"MAX"}}`, max: "medium", mappings: []ReasoningEffortMapping{{From: "max", To: "xhigh"}}, path: "reasoning.effort", want: "medium", changed: true},
|
||||||
{name: "does not chain mappings", body: `{"reasoning_effort":"max"}`, mappings: []ReasoningEffortMapping{{From: "max", To: "xhigh"}, {From: "xhigh", To: "low"}}, path: "reasoning_effort", want: "xhigh", changed: true},
|
{name: "does not chain mappings", body: `{"reasoning_effort":"max"}`, mappings: []ReasoningEffortMapping{{From: "max", To: "xhigh"}, {From: "xhigh", To: "low"}}, path: "reasoning_effort", want: "xhigh", changed: true},
|
||||||
|
{name: "maps nested none", body: `{"reasoning":{"effort":"none"}}`, mappings: []ReasoningEffortMapping{{From: "none", To: "low"}}, path: "reasoning.effort", want: "low", changed: true},
|
||||||
|
{name: "maps flat none", body: `{"reasoning_effort":"none"}`, mappings: []ReasoningEffortMapping{{From: "none", To: "low"}}, path: "reasoning_effort", want: "low", changed: true},
|
||||||
|
{name: "none mapping runs before cap", body: `{"reasoning_effort":"none"}`, max: "low", mappings: []ReasoningEffortMapping{{From: "none", To: "high"}}, path: "reasoning_effort", want: "low", changed: true},
|
||||||
|
{name: "keeps none byte for byte without mappings", body: `{ "reasoning_effort": " none " }`, max: "low", path: "reasoning_effort", want: " none ", changed: false},
|
||||||
|
{name: "keeps none byte for byte when scope does not match", body: `{ "model":"o3", "reasoning_effort":"none" }`, mappings: []ReasoningEffortMapping{{From: "none", To: "low", MatchType: domain.ReasoningEffortMatchExact, Model: "gpt-5"}}, path: "reasoning_effort", want: "none", changed: false},
|
||||||
|
{name: "exact scope maps none", body: `{"model":"gpt-5","reasoning_effort":"none"}`, mappings: []ReasoningEffortMapping{{From: "none", To: "low", MatchType: domain.ReasoningEffortMatchExact, Model: "gpt-5"}}, path: "reasoning_effort", want: "low", changed: true},
|
||||||
|
{name: "prefix scope maps none", body: `{"model":"gpt-5-mini","reasoning_effort":"none"}`, mappings: []ReasoningEffortMapping{{From: "none", To: "low", MatchType: domain.ReasoningEffortMatchPrefix, Model: "gpt-5"}}, path: "reasoning_effort", want: "low", changed: true},
|
||||||
|
{name: "suffix scope maps none", body: `{"model":"gpt-5-mini","reasoning_effort":"none"}`, mappings: []ReasoningEffortMapping{{From: "none", To: "low", MatchType: domain.ReasoningEffortMatchSuffix, Model: "mini"}}, path: "reasoning_effort", want: "low", changed: true},
|
||||||
|
{name: "global scope maps none", body: `{"model":"o3","reasoning_effort":"none"}`, mappings: []ReasoningEffortMapping{{From: "none", To: "low"}}, path: "reasoning_effort", want: "low", changed: true},
|
||||||
{name: "keeps unknown without mapping", body: `{"reasoning_effort":"future"}`, max: "low", path: "reasoning_effort", want: "future", changed: false},
|
{name: "keeps unknown without mapping", body: `{"reasoning_effort":"future"}`, max: "low", path: "reasoning_effort", want: "future", changed: false},
|
||||||
{name: "keeps non string value", body: `{"reasoning_effort":{"level":"high"}}`, max: "low", path: "reasoning_effort.level", want: "high", changed: false},
|
{name: "keeps non string value", body: `{"reasoning_effort":{"level":"high"}}`, max: "low", path: "reasoning_effort.level", want: "high", changed: false},
|
||||||
{
|
{
|
||||||
@@ -398,6 +415,9 @@ func TestApplyOpenAIReasoningEffortPolicy(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tt.changed, changed)
|
require.Equal(t, tt.changed, changed)
|
||||||
|
if !tt.changed {
|
||||||
|
require.Equal(t, tt.body, string(got))
|
||||||
|
}
|
||||||
if tt.path != "" {
|
if tt.path != "" {
|
||||||
require.Equal(t, tt.want, gjson.GetBytes(got, tt.path).String())
|
require.Equal(t, tt.want, gjson.GetBytes(got, tt.path).String())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,7 +136,7 @@
|
|||||||
<Select
|
<Select
|
||||||
:id="`${idPrefix}-${pair.id}-from`"
|
:id="`${idPrefix}-${pair.id}-from`"
|
||||||
:model-value="pair.from"
|
:model-value="pair.from"
|
||||||
:options="reasoningEffortOptions"
|
:options="reasoningEffortSourceOptions"
|
||||||
:placeholder="t('admin.groups.form.reasoningEffortFromPlaceholder')"
|
:placeholder="t('admin.groups.form.reasoningEffortFromPlaceholder')"
|
||||||
:error="showValidation && !!pairErrors(pair.id).from"
|
:error="showValidation && !!pairErrors(pair.id).from"
|
||||||
:aria-label="t('admin.groups.form.reasoningEffortFrom')"
|
:aria-label="t('admin.groups.form.reasoningEffortFrom')"
|
||||||
@@ -217,6 +217,7 @@ import {
|
|||||||
createReasoningEffortMappingRow,
|
createReasoningEffortMappingRow,
|
||||||
normalizeReasoningEffortMatchType,
|
normalizeReasoningEffortMatchType,
|
||||||
reasoningEffortOptionsForPlatform,
|
reasoningEffortOptionsForPlatform,
|
||||||
|
reasoningEffortSourceOptionsForPlatform,
|
||||||
reasoningEffortOverLimitDeny,
|
reasoningEffortOverLimitDeny,
|
||||||
reasoningEffortOverLimitDowngrade,
|
reasoningEffortOverLimitDowngrade,
|
||||||
validateReasoningEffortMappings,
|
validateReasoningEffortMappings,
|
||||||
@@ -243,6 +244,9 @@ const showValidation = ref(false);
|
|||||||
const reasoningEffortOptions = computed(() =>
|
const reasoningEffortOptions = computed(() =>
|
||||||
reasoningEffortOptionsForPlatform(props.platform),
|
reasoningEffortOptionsForPlatform(props.platform),
|
||||||
);
|
);
|
||||||
|
const reasoningEffortSourceOptions = computed(() =>
|
||||||
|
reasoningEffortSourceOptionsForPlatform(props.platform),
|
||||||
|
);
|
||||||
const matchTypeOptions = computed(() => [
|
const matchTypeOptions = computed(() => [
|
||||||
{
|
{
|
||||||
value: "exact",
|
value: "exact",
|
||||||
|
|||||||
@@ -13,6 +13,48 @@ vi.mock("vue-i18n", async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("ReasoningEffortPolicyFields", () => {
|
describe("ReasoningEffortPolicyFields", () => {
|
||||||
|
it("offers none only in the mapping source selector", () => {
|
||||||
|
const mapping = createReasoningEffortMappingRow({
|
||||||
|
from: "none",
|
||||||
|
to: "low",
|
||||||
|
});
|
||||||
|
const wrapper = mount(ReasoningEffortPolicyFields, {
|
||||||
|
props: {
|
||||||
|
idPrefix: "edit-group-reasoning",
|
||||||
|
platform: "openai",
|
||||||
|
maxEffort: "",
|
||||||
|
overLimit: "downgrade",
|
||||||
|
mappings: [mapping],
|
||||||
|
},
|
||||||
|
global: {
|
||||||
|
stubs: {
|
||||||
|
Icon: true,
|
||||||
|
Select: {
|
||||||
|
props: ["id", "options"],
|
||||||
|
template:
|
||||||
|
'<div :id="id"><span v-for="option in options" :key="option.value" :data-value="option.value" /></div>',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const optionValues = (id: string) =>
|
||||||
|
wrapper
|
||||||
|
.get(`#${id}`)
|
||||||
|
.findAll("[data-value]")
|
||||||
|
.map((option) => option.attributes("data-value"));
|
||||||
|
|
||||||
|
expect(optionValues("edit-group-reasoning-max-effort")).not.toContain(
|
||||||
|
"none",
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
optionValues(`edit-group-reasoning-${mapping.pairs[0].id}-from`),
|
||||||
|
).toContain("none");
|
||||||
|
expect(
|
||||||
|
optionValues(`edit-group-reasoning-${mapping.pairs[0].id}-to`),
|
||||||
|
).not.toContain("none");
|
||||||
|
});
|
||||||
|
|
||||||
it("renders model scope fields for each mapping", () => {
|
it("renders model scope fields for each mapping", () => {
|
||||||
const mapping = createReasoningEffortMappingRow({
|
const mapping = createReasoningEffortMappingRow({
|
||||||
from: "max",
|
from: "max",
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import {
|
|||||||
createReasoningEffortMappingPair,
|
createReasoningEffortMappingPair,
|
||||||
createReasoningEffortMappingRow,
|
createReasoningEffortMappingRow,
|
||||||
normalizeReasoningEffortForPlatform,
|
normalizeReasoningEffortForPlatform,
|
||||||
|
normalizeReasoningEffortSourceForPlatform,
|
||||||
normalizeReasoningEffortMatchType,
|
normalizeReasoningEffortMatchType,
|
||||||
normalizeReasoningEffortOverLimit,
|
normalizeReasoningEffortOverLimit,
|
||||||
reasoningEffortMappingsToAPI,
|
reasoningEffortMappingsToAPI,
|
||||||
reasoningEffortMappingsToRows,
|
reasoningEffortMappingsToRows,
|
||||||
reasoningEffortOptionsForPlatform,
|
reasoningEffortOptionsForPlatform,
|
||||||
|
reasoningEffortSourceOptionsForPlatform,
|
||||||
reasoningEffortOverLimitDeny,
|
reasoningEffortOverLimitDeny,
|
||||||
reasoningEffortOverLimitDowngrade,
|
reasoningEffortOverLimitDowngrade,
|
||||||
supportsReasoningEffortPolicyPlatform,
|
supportsReasoningEffortPolicyPlatform,
|
||||||
@@ -31,6 +33,11 @@ describe("groupsReasoningEffort", () => {
|
|||||||
(option) => option.value,
|
(option) => option.value,
|
||||||
),
|
),
|
||||||
).toEqual(expected);
|
).toEqual(expected);
|
||||||
|
expect(
|
||||||
|
reasoningEffortSourceOptionsForPlatform(platform).map(
|
||||||
|
(option) => option.value,
|
||||||
|
),
|
||||||
|
).toEqual(["none", ...expected]);
|
||||||
expect(supportsReasoningEffortPolicyPlatform(platform)).toBe(true);
|
expect(supportsReasoningEffortPolicyPlatform(platform)).toBe(true);
|
||||||
}
|
}
|
||||||
for (const platform of [
|
for (const platform of [
|
||||||
@@ -40,6 +47,7 @@ describe("groupsReasoningEffort", () => {
|
|||||||
"grok",
|
"grok",
|
||||||
] as const) {
|
] as const) {
|
||||||
expect(reasoningEffortOptionsForPlatform(platform)).toEqual([]);
|
expect(reasoningEffortOptionsForPlatform(platform)).toEqual([]);
|
||||||
|
expect(reasoningEffortSourceOptionsForPlatform(platform)).toEqual([]);
|
||||||
expect(supportsReasoningEffortPolicyPlatform(platform)).toBe(false);
|
expect(supportsReasoningEffortPolicyPlatform(platform)).toBe(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -59,6 +67,27 @@ describe("groupsReasoningEffort", () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("hydrates and validates none only as a mapping source", () => {
|
||||||
|
const rows = reasoningEffortMappingsToRows(
|
||||||
|
[{ from: " NONE ", to: "low" }],
|
||||||
|
"openai",
|
||||||
|
);
|
||||||
|
expect(reasoningEffortMappingsToAPI(rows)).toEqual([
|
||||||
|
{ from: "none", to: "low" },
|
||||||
|
]);
|
||||||
|
expect(validateReasoningEffortMappings(rows, "openai")).toEqual({});
|
||||||
|
expect(normalizeReasoningEffortSourceForPlatform("composite", " NONE ")).toBe("none");
|
||||||
|
|
||||||
|
const invalidTarget = createReasoningEffortMappingRow({
|
||||||
|
from: "low",
|
||||||
|
to: "none",
|
||||||
|
});
|
||||||
|
expect(validateReasoningEffortMappings([invalidTarget], "openai")).toEqual({
|
||||||
|
[invalidTarget.pairs[0].id]: { to: "unsupportedTo" },
|
||||||
|
});
|
||||||
|
expect(normalizeReasoningEffortForPlatform("openai", "none")).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
it("hydrates model scoped mappings", () => {
|
it("hydrates model scoped mappings", () => {
|
||||||
const rows = reasoningEffortMappingsToRows(
|
const rows = reasoningEffortMappingsToRows(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ const openAIReasoningEffortValues = [
|
|||||||
"xhigh",
|
"xhigh",
|
||||||
"max",
|
"max",
|
||||||
] as const;
|
] as const;
|
||||||
|
const openAIReasoningEffortSourceValues = [
|
||||||
|
"none",
|
||||||
|
...openAIReasoningEffortValues,
|
||||||
|
] as const;
|
||||||
|
|
||||||
const reasoningEffortMatchTypes: readonly ReasoningEffortMatchType[] = [
|
const reasoningEffortMatchTypes: readonly ReasoningEffortMatchType[] = [
|
||||||
"exact",
|
"exact",
|
||||||
@@ -42,6 +46,15 @@ export function reasoningEffortOptionsForPlatform(platform: GroupPlatform) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function reasoningEffortSourceOptionsForPlatform(
|
||||||
|
platform: GroupPlatform,
|
||||||
|
) {
|
||||||
|
return (supportsReasoningEffortPolicyPlatform(platform)
|
||||||
|
? openAIReasoningEffortSourceValues
|
||||||
|
: []
|
||||||
|
).map((value) => ({ value, label: value }));
|
||||||
|
}
|
||||||
|
|
||||||
export function normalizeReasoningEffortForPlatform(
|
export function normalizeReasoningEffortForPlatform(
|
||||||
platform: GroupPlatform,
|
platform: GroupPlatform,
|
||||||
value: string | null | undefined,
|
value: string | null | undefined,
|
||||||
@@ -54,6 +67,17 @@ export function normalizeReasoningEffortForPlatform(
|
|||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function normalizeReasoningEffortSourceForPlatform(
|
||||||
|
platform: GroupPlatform,
|
||||||
|
value: string | null | undefined,
|
||||||
|
): string {
|
||||||
|
const normalized = value?.trim().toLowerCase() ?? "";
|
||||||
|
return supportsReasoningEffortPolicyPlatform(platform) &&
|
||||||
|
normalized === "none"
|
||||||
|
? "none"
|
||||||
|
: normalizeReasoningEffortForPlatform(platform, value);
|
||||||
|
}
|
||||||
|
|
||||||
export function normalizeReasoningEffortMatchType(
|
export function normalizeReasoningEffortMatchType(
|
||||||
value: string | null | undefined,
|
value: string | null | undefined,
|
||||||
): ReasoningEffortMatchType | "" {
|
): ReasoningEffortMatchType | "" {
|
||||||
@@ -154,7 +178,10 @@ export function reasoningEffortMappingsToRows(
|
|||||||
const indexByScope = new Map<string, number>();
|
const indexByScope = new Map<string, number>();
|
||||||
|
|
||||||
(mappings ?? []).forEach((mapping) => {
|
(mappings ?? []).forEach((mapping) => {
|
||||||
const from = normalizeReasoningEffortForPlatform(platform, mapping.from);
|
const from = normalizeReasoningEffortSourceForPlatform(
|
||||||
|
platform,
|
||||||
|
mapping.from,
|
||||||
|
);
|
||||||
const to = normalizeReasoningEffortForPlatform(platform, mapping.to);
|
const to = normalizeReasoningEffortForPlatform(platform, mapping.to);
|
||||||
if (!from || !to) return;
|
if (!from || !to) return;
|
||||||
|
|
||||||
@@ -225,7 +252,7 @@ export function validateReasoningEffortMappings(
|
|||||||
const to = pair.to.trim();
|
const to = pair.to.trim();
|
||||||
if (!from) {
|
if (!from) {
|
||||||
errors[pair.id] = { ...errors[pair.id], from: "fromRequired" };
|
errors[pair.id] = { ...errors[pair.id], from: "fromRequired" };
|
||||||
} else if (!normalizeReasoningEffortForPlatform(platform, from)) {
|
} else if (!normalizeReasoningEffortSourceForPlatform(platform, from)) {
|
||||||
errors[pair.id] = { ...errors[pair.id], from: "unsupportedFrom" };
|
errors[pair.id] = { ...errors[pair.id], from: "unsupportedFrom" };
|
||||||
} else {
|
} else {
|
||||||
const key = `${scope}\0${from.toLowerCase()}`;
|
const key = `${scope}\0${from.toLowerCase()}`;
|
||||||
|
|||||||
Reference in new issue
Block a user