@remnic/core 9.3.636 → 9.3.637

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.
package/src/config.ts CHANGED
@@ -774,10 +774,31 @@ export function parseConfig(raw: unknown): PluginConfig {
774
774
  // API key is optional at load time — retrieval works without it.
775
775
  // Extraction will log a warning if called without a key.
776
776
 
777
- const model =
778
- typeof cfg.model === "string" && cfg.model.length > 0
779
- ? cfg.model
777
+ const taskModelChain = parseModelChainConfig(cfg.taskModelChain, "taskModelChain");
778
+ // Gateway-routed background tasks (flush plan, hourly summary cron, recall
779
+ // planner) default to the configured task-model primary, or empty so the
780
+ // Gateway default wins — never a bare reasoning id that resolves to an
781
+ // unroutable `<provider>/gpt-5.5` (issue #1469).
782
+ const taskModelFallback =
783
+ modelSource === "gateway"
784
+ ? (taskModelChain?.primary ?? "")
780
785
  : DEFAULT_REASONING_MODEL;
786
+ const explicitModel =
787
+ typeof cfg.model === "string" && cfg.model.length > 0 ? cfg.model : "";
788
+ // Base reasoning/extraction model. Kept DIRECT-compatible: direct-key call
789
+ // sites (e.g. briefing follow-ups when `openaiApiKey` is set) pass this
790
+ // straight to the OpenAI Responses API, so it must stay a bare/direct model
791
+ // id and never a provider-qualified gateway route string. The gateway task
792
+ // chain is applied at gateway-routed call sites (summaryModel, recall planner)
793
+ // instead, not here (issue #1469 / codex review on PR #1470).
794
+ const model = explicitModel || DEFAULT_REASONING_MODEL;
795
+ // In gateway mode a usable task route must be provider-qualified (`provider/model`).
796
+ // A bare id — including the `"gpt-5.5"` schema default OpenClaw injects when the
797
+ // operator only configured `modelSource` + `taskModelChain` — resolves to an
798
+ // unroutable `<provider>/gpt-5.5`, so it is treated as ABSENT and the configured
799
+ // task chain wins. Direct (non-gateway) mode keeps bare ids as-is (#1469).
800
+ const gatewayTaskModel = (value: string): string =>
801
+ modelSource === "gateway" && !value.includes("/") ? "" : value;
781
802
  const captureMode =
782
803
  cfg.captureMode === "explicit" || cfg.captureMode === "hybrid"
783
804
  ? cfg.captureMode
@@ -2049,10 +2070,19 @@ export function parseConfig(raw: unknown): PluginConfig {
2049
2070
  typeof cfg.summaryRecallHours === "number" ? cfg.summaryRecallHours : 24,
2050
2071
  maxSummaryCount:
2051
2072
  typeof cfg.maxSummaryCount === "number" ? cfg.maxSummaryCount : 6,
2073
+ // Gateway-routed (memory flush plan + hourly summary cron). Precedence:
2074
+ // explicit summaryModel → explicit base model → gateway task-chain primary →
2075
+ // "" (omit, so the Gateway default wins). In gateway mode bare ids (incl. the
2076
+ // injected `model` schema default) are dropped via `gatewayTaskModel`, so the
2077
+ // Gateway is never sent an unroutable `<provider>/gpt-5.5` (issue #1469).
2052
2078
  summaryModel:
2053
- typeof cfg.summaryModel === "string" && cfg.summaryModel.length > 0
2054
- ? cfg.summaryModel
2055
- : model, // default: same as extraction model
2079
+ gatewayTaskModel(
2080
+ typeof cfg.summaryModel === "string" && cfg.summaryModel.length > 0
2081
+ ? cfg.summaryModel
2082
+ : "",
2083
+ ) ||
2084
+ gatewayTaskModel(explicitModel) ||
2085
+ taskModelFallback,
2056
2086
  // v2.4 Extended hourly summaries (default off)
2057
2087
  hourlySummariesExtendedEnabled: cfg.hourlySummariesExtendedEnabled === true,
2058
2088
  hourlySummariesIncludeToolStats: cfg.hourlySummariesIncludeToolStats === true,
@@ -2540,7 +2570,7 @@ export function parseConfig(raw: unknown): PluginConfig {
2540
2570
  typeof cfg.fastGatewayAgentId === "string" && cfg.fastGatewayAgentId.length > 0
2541
2571
  ? cfg.fastGatewayAgentId
2542
2572
  : "",
2543
- taskModelChain: parseModelChainConfig(cfg.taskModelChain, "taskModelChain"),
2573
+ taskModelChain,
2544
2574
 
2545
2575
  // v3.0 namespaces (default off)
2546
2576
  namespacesEnabled: cfg.namespacesEnabled === true,
@@ -2896,10 +2926,15 @@ export function parseConfig(raw: unknown): PluginConfig {
2896
2926
  // CLI/env surfaces (`--config recallPlannerLlmEnabled=true`) actually
2897
2927
  // enable it (gotcha #36); defaults off.
2898
2928
  recallPlannerLlmEnabled: coerceBooleanLike(cfg.recallPlannerLlmEnabled) ?? false,
2929
+ // Gateway-routed via FallbackLlmClient (qualifiedPlannerModel drops bare ids).
2930
+ // Drop the bare schema-default model in gateway mode too so the resolved value
2931
+ // reflects the actual gateway route (task-chain primary) instead of "gpt-5.5".
2899
2932
  recallPlannerModel:
2900
- typeof cfg.recallPlannerModel === "string" && cfg.recallPlannerModel.trim().length > 0
2901
- ? cfg.recallPlannerModel.trim()
2902
- : DEFAULT_REASONING_MODEL,
2933
+ gatewayTaskModel(
2934
+ typeof cfg.recallPlannerModel === "string" && cfg.recallPlannerModel.trim().length > 0
2935
+ ? cfg.recallPlannerModel.trim()
2936
+ : "",
2937
+ ) || taskModelFallback,
2903
2938
  recallPlannerTimeoutMs:
2904
2939
  typeof cfg.recallPlannerTimeoutMs === "number" ? cfg.recallPlannerTimeoutMs : 1500,
2905
2940
  recallPlannerUseResponsesApi: coerceBooleanLike(cfg.recallPlannerUseResponsesApi) ?? true,