File size: 3,768 Bytes
4e23b01
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import type {
  KimiConfig,
  ModelAlias,
  ModelAliasOverrides,
  SecondaryModelConfig,
} from './schema';

export const SECONDARY_DERIVED_MODEL_ALIAS = '__secondary__';
export const SECONDARY_MODEL_ENV = 'KIMI_SECONDARY_MODEL';
export const SECONDARY_MODEL_EFFORT_ENV = 'KIMI_SECONDARY_EFFORT';

type Env = Readonly<Record<string, string | undefined>>;

function trimmed(value: string | undefined): string | undefined {
  const t = value?.trim();
  return t === undefined || t.length === 0 ? undefined : t;
}

export function secondaryModelPatch(
  secondary: SecondaryModelConfig | undefined,
): ModelAliasOverrides | undefined {
  if (secondary === undefined) return undefined;
  const {
    model: _model,
    defaultModel: _defaultModel,
    models: _models,
    force: _force,
    ...rawPatch
  } = secondary;
  const patch = Object.fromEntries(
    Object.entries(rawPatch).filter(([, value]) => value !== undefined),
  ) as ModelAliasOverrides;
  return Object.keys(patch).length > 0 ? patch : undefined;
}

export function applySecondaryModelConfig(config: KimiConfig, env: Env = process.env): KimiConfig {
  let secondary = config.secondaryModel;
  const envModel = trimmed(env[SECONDARY_MODEL_ENV]);
  const envEffort = trimmed(env[SECONDARY_MODEL_EFFORT_ENV]);
  if (envModel !== undefined || envEffort !== undefined) {
    secondary = {
      ...secondary,
      model: envModel ?? secondary?.model,
      defaultEffort: envEffort ?? secondary?.defaultEffort,
    };
  }

  let next = secondary === config.secondaryModel ? config : { ...config, secondaryModel: secondary };

  const patch = secondaryModelPatch(secondary);
  const baseId = secondary?.model;
  if (patch === undefined || baseId === undefined || baseId === SECONDARY_DERIVED_MODEL_ALIAS) {
    return next;
  }
  const base = next.models?.[baseId];
  if (base === undefined) return next;

  const { overrides: baseOverrides, ...baseFields } = base;
  const derived: ModelAlias = {
    ...baseFields,
    overrides: { ...baseOverrides, ...patch },
  };
  return {
    ...next,
    models: { ...next.models, [SECONDARY_DERIVED_MODEL_ALIAS]: derived },
  };
}

export function stripSecondaryModelConfig(
  config: KimiConfig,
  env: Env = process.env,
): KimiConfig {
  let next = config;

  if (next.models !== undefined && SECONDARY_DERIVED_MODEL_ALIAS in next.models) {
    const models = { ...next.models };
    delete models[SECONDARY_DERIVED_MODEL_ALIAS];
    next = { ...next, models };
  }

  if (next.defaultModel === SECONDARY_DERIVED_MODEL_ALIAS) {
    const rawDefault = config.raw?.['default_model'];
    next = {
      ...next,
      defaultModel: typeof rawDefault === 'string' ? rawDefault : undefined,
    };
  }

  const envModel = trimmed(env[SECONDARY_MODEL_ENV]);
  const envEffort = trimmed(env[SECONDARY_MODEL_EFFORT_ENV]);
  if ((envModel !== undefined || envEffort !== undefined) && next.secondaryModel !== undefined) {
    const raw = isPlainObject(config.raw?.['secondary_model']) ? config.raw['secondary_model'] : {};
    const restored = { ...next.secondaryModel };
    if (envModel !== undefined && restored.model === envModel) {
      if (typeof raw['model'] === 'string') restored.model = raw['model'];
      else delete restored.model;
    }
    if (envEffort !== undefined && restored.defaultEffort === envEffort) {
      if (typeof raw['default_effort'] === 'string') restored.defaultEffort = raw['default_effort'];
      else delete restored.defaultEffort;
    }
    next = {
      ...next,
      secondaryModel: Object.keys(restored).length > 0 ? restored : undefined,
    };
  }

  return next;
}

function isPlainObject(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}