@litfamily/lithermes 1.0.19 → 1.0.20

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.
@@ -10,30 +10,36 @@ const LEGACY_SOL_MODEL = "gpt-5.6-sol";
10
10
  const LEGACY_CHILD_MODEL = "gpt-5.6-luna";
11
11
  const CHILD_EFFORT = "max";
12
12
  const GPT6_LUNA_EFFORTS = new Set(["low", "medium", "high", "xhigh", "max"]);
13
- const LEGACY_LUNA_EFFORTS = new Set(["high", "max"]);
13
+ const LEGACY_LUNA_EFFORTS = GPT6_LUNA_EFFORTS;
14
14
  const LUNA_EFFORTS = LEGACY_LUNA_EFFORTS;
15
15
  const LUNA_MODELS = new Set([CHILD_MODEL, LEGACY_CHILD_MODEL]);
16
16
  const TERRA_MODEL = "gpt-5.6-terra";
17
- const TERRA_EFFORTS = new Set(["high", "xhigh", "max"]);
18
- const LEGACY_SOL_EFFORTS = new Set(["high", "xhigh"]);
19
17
  const MODEL_EFFORTS = new Map([
20
18
  [ASTRA_MODEL, GPT6_LEAD_EFFORTS],
21
19
  [SOL_MODEL, GPT6_LEAD_EFFORTS],
22
20
  [PREVIOUS_SOL_MODEL, GPT6_LEAD_EFFORTS],
23
21
  [CHILD_MODEL, GPT6_LUNA_EFFORTS],
24
- [LEGACY_SOL_MODEL, LEGACY_SOL_EFFORTS],
22
+ [LEGACY_SOL_MODEL, GPT6_LEAD_EFFORTS],
25
23
  [LEGACY_CHILD_MODEL, LEGACY_LUNA_EFFORTS],
26
24
  ["gpt-5.6", new Set(["high"])],
27
- [TERRA_MODEL, TERRA_EFFORTS],
25
+ [TERRA_MODEL, GPT6_LEAD_EFFORTS],
28
26
  ]);
27
+ // When only a model is given, these keep the effort they resolved to before their
28
+ // full effort sets were listed, so widening a menu never moves a default.
29
+ const MODEL_ONLY_EFFORTS = {
30
+ lead: new Map([[LEGACY_CHILD_MODEL, CHILD_EFFORT]]),
31
+ child: new Map([[LEGACY_SOL_MODEL, "high"]]),
32
+ };
29
33
  const CHILD_TRANSPORT_KEYS = ["provider", "base_url", "api_mode"];
30
34
  const { OPENAI_PROVIDER: OPENAI_PROVIDER_ID } = require("./modelConfigBoundary");
31
35
  const XAI_PROVIDER_ID = "xai";
32
36
  // Installer choice catalog (plans/references/installer-choice-contract.md, LitHermes row).
33
- // OpenAI rows follow each model's listed effort set, including selectable legacy
34
- // GPT-5.6 routes. xAI rows use the reasoning-capable models of the Hermes 0.19 catalog
35
- // (hermes_cli/models.py `_XAI_STATIC_FALLBACK`), newest first, with the Hermes
36
- // reasoning_effort vocabulary (hermes_cli/config.py delegation.reasoning_effort).
37
+ // OpenAI rows offer every effort the live model catalog lists for each model
38
+ // (supported_reasoning_levels), including the selectable legacy GPT-5.6 routes. Hermes
39
+ // accepts each of them in config but may send a lower level (ultra as max; max and ultra
40
+ // as xhigh on gpt-6.1-sol, gpt-6-sol and gpt-6-luna). xAI rows use the reasoning-capable models
41
+ // of the Hermes 0.19 catalog (hermes_cli/models.py `_XAI_STATIC_FALLBACK`), newest first,
42
+ // with the efforts Hermes sends to Grok before 4.6 (agent/reasoning_effort.py XAI_LEGACY_EFFORTS).
37
43
  const ROUTE_CATALOG = {
38
44
  [OPENAI_PROVIDER_ID]: {
39
45
  credentialEnv: null,
@@ -67,18 +73,25 @@ const ROUTE_CATALOG = {
67
73
  ? "balanced, lighter effort"
68
74
  : "Luna Responses effort",
69
75
  })),
70
- ...["high", "xhigh"].map((effort) => ({
76
+ ...[...GPT6_LEAD_EFFORTS].map((effort) => ({
71
77
  effort,
72
78
  model: LEGACY_SOL_MODEL,
73
79
  note: "previous-generation Sol lead route",
74
80
  })),
75
- ...["high", "xhigh", "max"].map((effort) => ({
81
+ ...[...GPT6_LEAD_EFFORTS].map((effort) => ({
76
82
  effort,
77
83
  model: TERRA_MODEL,
78
84
  note: "previous-generation Terra route",
79
85
  })),
80
- { effort: CHILD_EFFORT, model: LEGACY_CHILD_MODEL, note: "previous-generation balanced helper" },
81
- { effort: "high", model: LEGACY_CHILD_MODEL, note: "previous-generation lighter helper" },
86
+ ...[...GPT6_LUNA_EFFORTS].map((effort) => ({
87
+ effort,
88
+ model: LEGACY_CHILD_MODEL,
89
+ note: effort === CHILD_EFFORT
90
+ ? "previous-generation balanced helper"
91
+ : effort === "high"
92
+ ? "previous-generation lighter helper"
93
+ : "previous-generation Luna effort",
94
+ })),
82
95
  { effort: "high", model: "gpt-5.6", note: "general model" },
83
96
  ],
84
97
  lead: { effort: PARENT_EFFORT, model: PARENT_MODEL },
@@ -88,11 +101,15 @@ const ROUTE_CATALOG = {
88
101
  credentialEnv: "XAI_API_KEY",
89
102
  label: "xAI Grok",
90
103
  rows: [
91
- { effort: "high", model: "grok-build-0.1", note: "newest coding model (recommended lead)" },
92
- { effort: "high", model: "grok-4.5", note: "flagship reasoning" },
93
- { effort: "high", model: "grok-4.3", note: "fast reasoning (recommended helper)" },
94
- { effort: "high", model: "grok-4.20-0309-reasoning", note: "previous reasoning generation" },
95
- ],
104
+ ["grok-build-0.1", "newest coding model (recommended lead)"],
105
+ ["grok-4.5", "flagship reasoning"],
106
+ ["grok-4.3", "fast reasoning (recommended helper)"],
107
+ ["grok-4.20-0309-reasoning", "previous reasoning generation"],
108
+ ].flatMap(([model, note]) => ["low", "medium", "high"].map((effort) => ({
109
+ effort,
110
+ model,
111
+ note: effort === "high" ? note : "Grok reasoning effort",
112
+ }))),
96
113
  lead: { effort: "high", model: "grok-build-0.1" },
97
114
  helper: { effort: "high", model: "grok-4.3" },
98
115
  },
@@ -137,28 +154,19 @@ function inspectEffectiveRouteSafety(document, expectedProvider) {
137
154
  if (modelEfforts && !modelEfforts.has(route.effort)) {
138
155
  const isAstra = route.model === ASTRA_MODEL;
139
156
  const isLuna = LUNA_MODELS.has(route.model);
140
- const isLegacyLunaXhigh = route.model === LEGACY_CHILD_MODEL && route.effort === "xhigh";
141
157
  return {
142
158
  classificationClass: isAstra
143
159
  ? "astra_effort_unsupported"
144
- : isLegacyLunaXhigh
145
- ? "conflicting_luna_xhigh"
146
- : isLuna
147
- ? "luna_effort_below_high"
148
- : route.model === TERRA_MODEL
149
- ? "terra_effort_below_high"
150
- : "model_effort_unsupported",
160
+ : isLuna
161
+ ? "luna_effort_unsupported"
162
+ : "model_effort_unsupported",
151
163
  code: UNSAFE_ROUTE_CODE,
152
164
  observedSource: `${route.route} model, effort, and provider config`,
153
165
  reason: isAstra
154
166
  ? `${route.route} Astra effort is unsupported or missing; choose one of: ${[...modelEfforts].join(", ")}`
155
- : isLegacyLunaXhigh
156
- ? `${route.route} Luna xhigh is a forbidden pair (legacy Luna runs at high or max)`
157
- : isLuna
158
- ? `${route.route} Luna effort is unsupported; choose one of: ${[...modelEfforts].join(", ")}`
159
- : route.model === TERRA_MODEL
160
- ? `${route.route} TERRA effort is below high or missing`
161
- : `${route.route} ${route.model} effort is unsupported or missing; choose one of: ${[...modelEfforts].join(", ")}`,
167
+ : isLuna
168
+ ? `${route.route} Luna effort is unsupported; choose one of: ${[...modelEfforts].join(", ")}`
169
+ : `${route.route} ${route.model} effort is unsupported or missing; choose one of: ${[...modelEfforts].join(", ")}`,
162
170
  route: route.route,
163
171
  status: "blocked",
164
172
  };
@@ -202,9 +210,6 @@ function resolveRow(provider, role, model, effort) {
202
210
  const hasModel = model !== undefined;
203
211
  const hasEffort = effort !== undefined;
204
212
  const resolvedModel = hasModel ? String(model) : preset.model;
205
- if (resolvedModel === LEGACY_CHILD_MODEL && hasEffort && effort === "xhigh") {
206
- throw new Error(`${role} route ${resolvedModel} xhigh is a forbidden pair; legacy Luna runs at high or max`);
207
- }
208
213
  const rowsForModel = catalog.rows.filter((row) => row.model === resolvedModel);
209
214
  if (!rowsForModel.length) {
210
215
  const known = PROVIDER_IDS.some((id) => ROUTE_CATALOG[id].rows.some((row) => row.model === resolvedModel));
@@ -215,7 +220,9 @@ function resolveRow(provider, role, model, effort) {
215
220
  // An explicitly selected model keeps that model's cataloged preset effort
216
221
  // when no effort flag is supplied. This matters for Astra: its recommended
217
222
  // lead row is xhigh, while its catalog is intentionally listed low-first.
218
- const modelDefault = rowsForModel.find((row) => row.effort === preset.effort)?.effort ?? rowsForModel[0].effort;
223
+ const modelDefault = MODEL_ONLY_EFFORTS[role]?.get(resolvedModel)
224
+ ?? rowsForModel.find((row) => row.effort === preset.effort)?.effort
225
+ ?? rowsForModel[0].effort;
219
226
  const resolvedEffort = hasEffort ? String(effort) : (hasModel ? modelDefault : preset.effort);
220
227
  if (!rowsForModel.some((row) => row.effort === resolvedEffort)) {
221
228
  throw new Error(`${role} effort ${resolvedEffort} is not offered for ${resolvedModel}; choose one of: ${rowsForModel.map((row) => row.effort).join(", ")}`);