atomix-cli 1.1.0 → 1.2.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.
package/dist/session.js CHANGED
@@ -62,8 +62,14 @@ var require_adapter = __commonJS({
62
62
  "../atomix-core/dist/util/adapter.js"(exports2) {
63
63
  "use strict";
64
64
  Object.defineProperty(exports2, "__esModule", { value: true });
65
- exports2.TEMPERATURE_ONE_MODELS = void 0;
65
+ exports2.TEMPERATURE_MAX = exports2.TEMPERATURE_MIN = exports2.DEFAULT_ANTHROPIC_TEMPERATURE = exports2.TEMPERATURE_ONE_MODELS = void 0;
66
66
  exports2.resolveAdapter = resolveAdapter;
67
+ exports2.openaiTemperatureCapability = openaiTemperatureCapability;
68
+ exports2.modelForcesTemperatureOne = modelForcesTemperatureOne2;
69
+ exports2.modelRejectsTemperature = modelRejectsTemperature2;
70
+ exports2.modelTemperatureGatedByThinking = modelTemperatureGatedByThinking2;
71
+ exports2.isValidTemperature = isValidTemperature2;
72
+ exports2.assertTemperature = assertTemperature;
67
73
  exports2.useMaxCompletionTokens = useMaxCompletionTokens;
68
74
  exports2.modelForcesThinking = modelForcesThinking;
69
75
  exports2.forcedThinkingEffort = forcedThinkingEffort;
@@ -112,6 +118,60 @@ var require_adapter = __commonJS({
112
118
  "kimi-k2.5",
113
119
  "moonshotai/kimi-k2.5"
114
120
  ];
121
+ var OPENAI_TEMPERATURE_NORMAL_PREFIXES = ["gpt-5-chat", "gpt-5.1-chat", "gpt-5.2-chat"];
122
+ var OPENAI_TEMPERATURE_REJECT_EXACT = ["gpt-5"];
123
+ var OPENAI_TEMPERATURE_REJECT_PREFIXES = [
124
+ "o1",
125
+ "o3",
126
+ "o4",
127
+ "gpt-5-mini",
128
+ "gpt-5-nano",
129
+ "gpt-5-20",
130
+ // 初代及其日期快照(gpt-5-2025-08-07)
131
+ "gpt-5-pro",
132
+ "gpt-5.1-pro",
133
+ "gpt-5.2-pro",
134
+ "gpt-5-codex",
135
+ "gpt-5.1-codex",
136
+ "gpt-5.2-codex"
137
+ ];
138
+ var OPENAI_TEMPERATURE_GATED_PREFIXES = ["gpt-5.1", "gpt-5.2"];
139
+ function bareModelName(modelName) {
140
+ const lower = modelName.toLowerCase();
141
+ return lower.split("/").pop() ?? lower;
142
+ }
143
+ function openaiTemperatureCapability(modelName) {
144
+ const bare = bareModelName(modelName);
145
+ if (OPENAI_TEMPERATURE_NORMAL_PREFIXES.some((p) => bare.startsWith(p)))
146
+ return "normal";
147
+ if (OPENAI_TEMPERATURE_REJECT_EXACT.includes(bare) || OPENAI_TEMPERATURE_REJECT_PREFIXES.some((p) => bare.startsWith(p)))
148
+ return "reject";
149
+ if (OPENAI_TEMPERATURE_GATED_PREFIXES.some((p) => bare.startsWith(p)))
150
+ return "gated";
151
+ if (bare.startsWith("gpt-5"))
152
+ return "reject";
153
+ return null;
154
+ }
155
+ function modelForcesTemperatureOne2(modelName) {
156
+ return exports2.TEMPERATURE_ONE_MODELS.includes(modelName);
157
+ }
158
+ function modelRejectsTemperature2(modelName) {
159
+ return openaiTemperatureCapability(modelName) === "reject";
160
+ }
161
+ function modelTemperatureGatedByThinking2(modelName) {
162
+ return openaiTemperatureCapability(modelName) === "gated";
163
+ }
164
+ function isValidTemperature2(t) {
165
+ return typeof t === "number" && Number.isFinite(t) && t >= exports2.TEMPERATURE_MIN && t <= exports2.TEMPERATURE_MAX;
166
+ }
167
+ exports2.DEFAULT_ANTHROPIC_TEMPERATURE = 0.7;
168
+ exports2.TEMPERATURE_MIN = 0;
169
+ exports2.TEMPERATURE_MAX = 2;
170
+ function assertTemperature(t) {
171
+ if (!isValidTemperature2(t)) {
172
+ throw new Error(`temperature \u987B\u4E3A ${exports2.TEMPERATURE_MIN}\u2013${exports2.TEMPERATURE_MAX} \u7684\u6570\u5B57,\u6536\u5230 ${JSON.stringify(t)}`);
173
+ }
174
+ }
115
175
  var MAX_COMPLETION_TOKENS_PREFIXES = [
116
176
  "o1",
117
177
  "o3",
@@ -305,7 +365,8 @@ var require_apiUtil = __commonJS({
305
365
  model: modelName,
306
366
  messages: [{ role: "user", content: 'Please respond with exactly "YES" (in capital letters) to confirm this connection is working.' }],
307
367
  ...(0, adapter_1.useMaxCompletionTokens)(modelName) ? { max_completion_tokens: 200 } : { max_tokens: 200 },
308
- temperature: adapter_1.TEMPERATURE_ONE_MODELS.includes(modelName) ? 1 : 0,
368
+ // 不发 temperature:与正式请求(adapt/openai.ts)一致,交给服务端默认。之前固定发 0.0,
369
+ // gpt-5 / o 系列等只接受默认值 1 的模型直接 400("does not support 0.0 with this model"),把可用模型挡在添加阶段
309
370
  stream: false
310
371
  }),
311
372
  extractContent: (response) => response.choices?.[0]?.message?.content || "",
@@ -17390,7 +17451,8 @@ var require_model = __commonJS({
17390
17451
  apiKey: config.apiKey,
17391
17452
  maxTokens: config.maxTokens || fallback.maxTokens,
17392
17453
  contextLength: config.contextLength || fallback.contextLength,
17393
- adapt: config.adapt ?? (0, adapter_1.resolveAdapter)(config.provider, config.modelName)
17454
+ adapt: config.adapt ?? (0, adapter_1.resolveAdapter)(config.provider, config.modelName),
17455
+ ...config.temperature !== void 0 ? { temperature: config.temperature } : {}
17394
17456
  };
17395
17457
  }
17396
17458
  }
@@ -17441,10 +17503,12 @@ var require_ModelManager = __commonJS({
17441
17503
  exports2.getModelManager = exports2.ModelManager = void 0;
17442
17504
  var fs11 = __importStar(require("fs"));
17443
17505
  var path11 = __importStar(require("path"));
17506
+ var adapter_1 = require_adapter();
17444
17507
  var apiUtil_1 = require_apiUtil();
17445
17508
  var savePath_1 = require_savePath();
17446
17509
  var model_1 = require_model();
17447
17510
  var log_1 = require_log();
17511
+ var EngineContext_1 = require_EngineContext();
17448
17512
  var ModelManager = class {
17449
17513
  constructor(initialConfig) {
17450
17514
  this.configPath = (0, savePath_1.getModelConfigFilePath)();
@@ -17472,6 +17536,8 @@ var require_ModelManager = __commonJS({
17472
17536
  * @param skipValidation 是否跳过API校验,默认为false
17473
17537
  */
17474
17538
  async addNewModel(config, skipValidation = false) {
17539
+ if (config.temperature !== void 0)
17540
+ this.assertProfileTemperature(config.modelName, config.temperature);
17475
17541
  const profile = (0, model_1.convertToModelProfile)(config);
17476
17542
  const existingModelIndex = this.config.modelProfiles.findIndex((p) => p.name === profile.name);
17477
17543
  if (!skipValidation) {
@@ -17500,7 +17566,7 @@ ${testResult.curlCommand}` : testResult.message;
17500
17566
  }
17501
17567
  }
17502
17568
  if (existingModelIndex !== -1) {
17503
- this.config.modelProfiles[existingModelIndex] = profile;
17569
+ this.config.modelProfiles[existingModelIndex] = { ...this.config.modelProfiles[existingModelIndex], ...profile };
17504
17570
  } else {
17505
17571
  this.config.modelProfiles.push(profile);
17506
17572
  if (this.config.modelProfiles.length === 1) {
@@ -17599,16 +17665,36 @@ ${testResult.curlCommand}` : testResult.message;
17599
17665
  };
17600
17666
  }
17601
17667
  /**
17602
- * 获取指定类型的模型配置
17668
+ * 解析指针槽位实际指向的模型标识(harness-model-v1 §2):
17669
+ * 当前会话(EngineStore.coreConfig.modelOverrides)有覆盖则用覆盖,否则用 model.conf 指针。
17670
+ * ALS 之外(无 EngineStore)读不到覆盖 = base。
17671
+ */
17672
+ resolvePointer(pointer) {
17673
+ const override = (0, EngineContext_1.getEngineStore)()?.coreConfig?.modelOverrides?.[pointer];
17674
+ if (typeof override === "string" && override)
17675
+ return { id: override, overridden: true };
17676
+ return { id: this.config.modelPointers?.[pointer] || null, overridden: false };
17677
+ }
17678
+ /**
17679
+ * 获取指定类型的模型配置(会话覆盖优先)。
17680
+ * 覆盖指向的 profile 已不存在(会话中被删)时返回 null,由调用方报错——不静默回落 base。
17603
17681
  */
17604
17682
  getModel(pointer) {
17605
- const pointerId = this.config.modelPointers?.[pointer];
17606
- if (!pointerId) {
17683
+ const { id } = this.resolvePointer(pointer);
17684
+ if (!id) {
17607
17685
  return null;
17608
17686
  }
17609
- const profile = (0, model_1.findModelProfile)(pointerId, this.config.modelProfiles);
17687
+ const profile = (0, model_1.findModelProfile)(id, this.config.modelProfiles);
17610
17688
  return profile || null;
17611
17689
  }
17690
+ /** 已配置的模型标识列表(同步;harness 解析是同步纯函数,不能等异步 getModelData)。 */
17691
+ getModelNames() {
17692
+ return this.config.modelProfiles.map((p) => p.name);
17693
+ }
17694
+ /** model.conf 的指针值(base,不含会话覆盖;同步)。 */
17695
+ getModelPointers() {
17696
+ return { main: this.config.modelPointers?.main ?? "", quick: this.config.modelPointers?.quick ?? "" };
17697
+ }
17612
17698
  /**
17613
17699
  * 获取指定类型的模型名称
17614
17700
  */
@@ -17616,6 +17702,89 @@ ${testResult.curlCommand}` : testResult.message;
17616
17702
  const profile = this.getModel(pointer);
17617
17703
  return profile ? profile.modelName : null;
17618
17704
  }
17705
+ // ===================== 温度 / profile 字段编辑(model-temperature-v1) =====================
17706
+ /** 去 apiKey 的只读视图;adapt 补齐(缺省按 provider/modelName 推断),cli 展示"协议默认"时不必再算 */
17707
+ getModelProfiles() {
17708
+ return this.config.modelProfiles.map((p) => {
17709
+ const { apiKey: _k, ...rest2 } = p;
17710
+ return { ...rest2, adapt: p.adapt ?? (0, adapter_1.resolveAdapter)(p.provider, p.modelName) };
17711
+ });
17712
+ }
17713
+ /**
17714
+ * 改单个 profile 的字段,不重跑连通性测试。`'temperature' in patch && patch.temperature === undefined` = 清除。
17715
+ * 硬约束模型(TEMPERATURE_ONE_MODELS)拒绝设温度:覆盖只会换来 4xx。
17716
+ */
17717
+ async updateModelProfile(name, patch) {
17718
+ const idx = this.config.modelProfiles.findIndex((p) => p.name === name);
17719
+ if (idx === -1)
17720
+ throw new Error(`\u6A21\u578B\u4E0D\u5B58\u5728: ${name}`);
17721
+ const next = { ...this.config.modelProfiles[idx] };
17722
+ if ("temperature" in patch) {
17723
+ if (patch.temperature === void 0)
17724
+ delete next.temperature;
17725
+ else {
17726
+ this.assertProfileTemperature(next.modelName, patch.temperature);
17727
+ next.temperature = patch.temperature;
17728
+ }
17729
+ }
17730
+ for (const k of ["maxTokens", "contextLength"]) {
17731
+ if (k in patch) {
17732
+ const v = patch[k];
17733
+ if (!Number.isInteger(v) || v <= 0)
17734
+ throw new Error(`${k} \u987B\u4E3A\u6B63\u6574\u6570,\u6536\u5230 ${JSON.stringify(v)}`);
17735
+ next[k] = v;
17736
+ }
17737
+ }
17738
+ if ("vision" in patch) {
17739
+ if (patch.vision === void 0)
17740
+ delete next.vision;
17741
+ else if (typeof patch.vision !== "boolean")
17742
+ throw new Error(`vision \u987B\u4E3A\u5E03\u5C14\u503C`);
17743
+ else
17744
+ next.vision = patch.vision;
17745
+ }
17746
+ this.config.modelProfiles[idx] = next;
17747
+ await this.saveConfig();
17748
+ const { apiKey: _k, ...rest2 } = next;
17749
+ return { ...rest2, adapt: next.adapt ?? (0, adapter_1.resolveAdapter)(next.provider, next.modelName) };
17750
+ }
17751
+ /** 范围校验 + 模型侧约束拒绝;addNewModel / updateModelProfile 共用。gpt-5 系列允许配置(thinking 关时生效),这里不挡 */
17752
+ assertProfileTemperature(modelName, t) {
17753
+ (0, adapter_1.assertTemperature)(t);
17754
+ if ((0, adapter_1.modelForcesTemperatureOne)(modelName))
17755
+ throw new Error(`\u6A21\u578B ${modelName} \u53EA\u63A5\u53D7\u9ED8\u8BA4\u6E29\u5EA6 1,\u4E0D\u80FD\u8BBE\u7F6E temperature`);
17756
+ if ((0, adapter_1.modelRejectsTemperature)(modelName))
17757
+ throw new Error(`\u6A21\u578B ${modelName} \u4E0D\u652F\u6301 temperature \u53C2\u6570(\u63A8\u7406\u6A21\u578B),\u4E0D\u80FD\u8BBE\u7F6E`);
17758
+ }
17759
+ /**
17760
+ * 请求时的温度解析(model-temperature-v1 §1.1),高者胜:
17761
+ * 1 模型侧约束:kimi 恒 1;o 系列永不发;gpt-5 系列 thinking 开(发 reasoning_effort)时不发;anthropic 协议开 thinking 不发;
17762
+ * 2 会话级覆盖(harness,经 EngineStore);3 profile.temperature;4 协议默认(anthropic 0.7,openai 不发)。
17763
+ * 返回 undefined = 请求体不带该字段。
17764
+ */
17765
+ resolveTemperature(pointer, profile, opts) {
17766
+ if ((0, adapter_1.modelForcesTemperatureOne)(profile.modelName))
17767
+ return 1;
17768
+ if ((0, adapter_1.modelRejectsTemperature)(profile.modelName))
17769
+ return void 0;
17770
+ if (opts.enableThinking && (0, adapter_1.modelTemperatureGatedByThinking)(profile.modelName))
17771
+ return void 0;
17772
+ if (opts.adapter === "anthropic" && opts.enableThinking)
17773
+ return void 0;
17774
+ const over2 = (0, EngineContext_1.getEngineStore)()?.coreConfig?.temperatureOverrides?.[pointer];
17775
+ if (over2 !== void 0 && !(0, adapter_1.isValidTemperature)(over2))
17776
+ (0, log_1.logWarn)(`temperatureOverrides.${pointer} \u975E\u6CD5(${JSON.stringify(over2)}),\u5FFD\u7565,\u6539\u7528 profile / \u9ED8\u8BA4`);
17777
+ if (profile.temperature !== void 0 && !(0, adapter_1.isValidTemperature)(profile.temperature))
17778
+ (0, log_1.logWarn)(`\u6A21\u578B ${profile.name} \u7684 temperature \u975E\u6CD5(${JSON.stringify(profile.temperature)}),\u5FFD\u7565,\u6539\u7528\u534F\u8BAE\u9ED8\u8BA4`);
17779
+ let t = (0, adapter_1.isValidTemperature)(over2) ? over2 : (0, adapter_1.isValidTemperature)(profile.temperature) ? profile.temperature : void 0;
17780
+ if (t === void 0)
17781
+ return opts.adapter === "anthropic" ? adapter_1.DEFAULT_ANTHROPIC_TEMPERATURE : void 0;
17782
+ if (opts.adapter === "anthropic" && t > 1) {
17783
+ (0, log_1.logWarn)(`temperature ${t} \u8D85\u51FA anthropic \u534F\u8BAE\u4E0A\u9650,\u6309 1 \u53D1\u9001(${profile.name})`);
17784
+ t = 1;
17785
+ }
17786
+ return t;
17787
+ }
17619
17788
  /**
17620
17789
  * 获取当前模型数据
17621
17790
  * @param showModelProfiles 是否包含详细的模型配置信息,默认为false
@@ -47739,13 +47908,15 @@ var require_cacheLLM = __commonJS({
47739
47908
  /**
47740
47909
  * 生成缓存键 - 基于消息内容生成简单hash
47741
47910
  */
47742
- generateKey(messages, systemPrompt, modelName, enableThinking = false) {
47911
+ generateKey(messages, systemPrompt, modelName, enableThinking = false, temperature) {
47743
47912
  const normalizedSystemPrompt = Array.isArray(systemPrompt) && systemPrompt.length > 0 && typeof systemPrompt[0] === "object" && "type" in systemPrompt[0] ? systemPrompt.map((item) => item.text) : systemPrompt;
47744
47913
  const content = JSON.stringify({
47745
47914
  messages: messages.map((msg) => msg.message.content),
47746
47915
  systemPrompt: normalizedSystemPrompt,
47747
47916
  modelName,
47748
- enableThinking
47917
+ enableThinking,
47918
+ temperature: temperature ?? null
47919
+ // 不同温度不共享缓存(model-temperature-v1)
47749
47920
  });
47750
47921
  return crypto_1.default.createHash("md5").update(content).digest("hex");
47751
47922
  }
@@ -47775,8 +47946,8 @@ var require_cacheLLM = __commonJS({
47775
47946
  /**
47776
47947
  * 获取缓存
47777
47948
  */
47778
- get(messages, systemPrompt, modelName, enableThinking = false) {
47779
- const key = this.generateKey(messages, systemPrompt, modelName, enableThinking);
47949
+ get(messages, systemPrompt, modelName, enableThinking = false, temperature) {
47950
+ const key = this.generateKey(messages, systemPrompt, modelName, enableThinking, temperature);
47780
47951
  const entries = this.readCacheFile();
47781
47952
  const entry = entries.find((e) => e.key === key);
47782
47953
  return entry ? entry.response : null;
@@ -47784,8 +47955,8 @@ var require_cacheLLM = __commonJS({
47784
47955
  /**
47785
47956
  * 设置缓存
47786
47957
  */
47787
- set(messages, systemPrompt, modelName, response, enableThinking = false) {
47788
- const key = this.generateKey(messages, systemPrompt, modelName, enableThinking);
47958
+ set(messages, systemPrompt, modelName, response, enableThinking = false, temperature) {
47959
+ const key = this.generateKey(messages, systemPrompt, modelName, enableThinking, temperature);
47789
47960
  let entries = this.readCacheFile();
47790
47961
  entries = entries.filter((e) => e.key !== key);
47791
47962
  entries.unshift({
@@ -47834,8 +48005,8 @@ var require_cache = __commonJS({
47834
48005
  var log_1 = require_log();
47835
48006
  var CACHE_STREAM_CHUNK_SIZE = 20;
47836
48007
  var CACHE_STREAM_DELAY = 100;
47837
- async function tryGetCachedResponse(messages, systemPromptContent, modelName, shouldStream, enableThinking, emitChunkEvents, signal) {
47838
- const cachedResponse = cacheLLM_1.llmCache.get(messages, systemPromptContent, modelName, enableThinking);
48008
+ async function tryGetCachedResponse(messages, systemPromptContent, modelName, shouldStream, enableThinking, emitChunkEvents, signal, temperature) {
48009
+ const cachedResponse = cacheLLM_1.llmCache.get(messages, systemPromptContent, modelName, enableThinking, temperature);
47839
48010
  if (!cachedResponse) {
47840
48011
  return null;
47841
48012
  }
@@ -47908,8 +48079,8 @@ var require_cache = __commonJS({
47908
48079
  function calcSimulatedDelay(contentLength, maxDelay) {
47909
48080
  return Math.min(Math.ceil(contentLength / CACHE_STREAM_CHUNK_SIZE) * CACHE_STREAM_DELAY, maxDelay);
47910
48081
  }
47911
- function setCachedResponse(messages, systemPromptContent, modelName, response, enableThinking = false) {
47912
- cacheLLM_1.llmCache.set(messages, systemPromptContent, modelName, response, enableThinking);
48082
+ function setCachedResponse(messages, systemPromptContent, modelName, response, enableThinking = false, temperature) {
48083
+ cacheLLM_1.llmCache.set(messages, systemPromptContent, modelName, response, enableThinking, temperature);
47913
48084
  }
47914
48085
  function getCacheSize() {
47915
48086
  return cacheLLM_1.llmCache.size();
@@ -61176,7 +61347,7 @@ var require_openai2 = __commonJS({
61176
61347
  }
61177
61348
  };
61178
61349
  }
61179
- async function queryOpenAI(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents) {
61350
+ async function queryOpenAI(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents) {
61180
61351
  const start = Date.now();
61181
61352
  let baseURL = modelProfile.baseURL || "https://api.openai.com/v1";
61182
61353
  const providerEndpoints = (0, providerEndpoint_1.getProviderEndpoints)(modelProfile.provider, baseURL);
@@ -61201,6 +61372,7 @@ var require_openai2 = __commonJS({
61201
61372
  stream: true,
61202
61373
  ...openaiTools && { tools: openaiTools },
61203
61374
  ...(0, adapter_1.useMaxCompletionTokens)(modelProfile.modelName) ? { max_completion_tokens: modelProfile.maxTokens || 8e3 } : { max_tokens: modelProfile.maxTokens || 8e3 },
61375
+ ...temperature !== void 0 && { temperature },
61204
61376
  // thinking 参数按 provider profile 统一构造(openai/openrouter/qwen/compat 等)
61205
61377
  ...(0, providerProfile_1.buildThinkingParams)(modelProfile, enableThinking)
61206
61378
  };
@@ -72410,7 +72582,7 @@ var require_anthropic = __commonJS({
72410
72582
  usage
72411
72583
  };
72412
72584
  }
72413
- async function queryAnthropic(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents) {
72585
+ async function queryAnthropic(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents) {
72414
72586
  const start = Date.now();
72415
72587
  const rawBaseURL = modelProfile.baseURL || "https://api.anthropic.com";
72416
72588
  const providerEndpoints = (0, providerEndpoint_1.getProviderEndpoints)(modelProfile.provider, rawBaseURL);
@@ -72431,7 +72603,7 @@ var require_anthropic = __commonJS({
72431
72603
  messages: anthropicMessages,
72432
72604
  system: systemPromptContent,
72433
72605
  max_tokens: modelProfile.maxTokens,
72434
- temperature: util_1.MAIN_QUERY_TEMPERATURE,
72606
+ ...temperature !== void 0 && { temperature },
72435
72607
  stream: true,
72436
72608
  ...anthropicTools && { tools: anthropicTools }
72437
72609
  };
@@ -72512,7 +72684,8 @@ var require_queryLLM = __commonJS({
72512
72684
  async function queryLLM(messages, systemPromptContent, signal, tools, modelPointer = "main", disableChunkEvents = false, suppressErrorEvent = false) {
72513
72685
  const modelProfile = (0, ModelManager_1.getModelManager)().getModel(modelPointer);
72514
72686
  if (!modelProfile) {
72515
- throw new Error(`\u89E3\u6790\u6A21\u578B\u5931\u8D25: ${modelPointer}`);
72687
+ const { id, overridden } = (0, ModelManager_1.getModelManager)().resolvePointer(modelPointer);
72688
+ throw new Error(id ? `\u89E3\u6790\u6A21\u578B\u5931\u8D25: ${modelPointer} \u2192 ${id} \u4E0D\u5728\u6A21\u578B\u914D\u7F6E\u4E2D${overridden ? "(\u4F1A\u8BDD\u7EA7\u8986\u76D6,\u6765\u81EA harness)" : ""}` : `\u89E3\u6790\u6A21\u578B\u5931\u8D25: ${modelPointer}`);
72516
72689
  }
72517
72690
  try {
72518
72691
  const coreConfig = (0, ConfManager_1.getConfManager)().getCoreConfig();
@@ -72520,30 +72693,31 @@ var require_queryLLM = __commonJS({
72520
72693
  const shouldStream = coreConfig?.stream !== false;
72521
72694
  const enableThinking = modelPointer !== "quick" && coreConfig?.thinking === true;
72522
72695
  const emitChunkEvents = !disableChunkEvents && shouldStream !== false;
72696
+ const adapt = modelProfile.adapt || (0, adapter_1.resolveAdapter)(modelProfile.provider, modelProfile.modelName);
72697
+ const temperature = (0, ModelManager_1.getModelManager)().resolveTemperature(modelPointer, modelProfile, { adapter: adapt, enableThinking });
72523
72698
  if (shouldUseCache) {
72524
- const cachedResponse = await (0, cache_1.tryGetCachedResponse)(messages, systemPromptContent, modelProfile.modelName, shouldStream, enableThinking, emitChunkEvents, signal);
72699
+ const cachedResponse = await (0, cache_1.tryGetCachedResponse)(messages, systemPromptContent, modelProfile.modelName, shouldStream, enableThinking, emitChunkEvents, signal, temperature);
72525
72700
  if (cachedResponse) {
72526
72701
  (0, logLLM_1.logLLMRequest)({ cached: true, model: modelProfile.modelName, messages });
72527
72702
  (0, logLLM_1.logLLMResponse)(cachedResponse);
72528
72703
  return cachedResponse;
72529
72704
  }
72530
72705
  }
72531
- const adapt = modelProfile.adapt || (0, adapter_1.resolveAdapter)(modelProfile.provider, modelProfile.modelName);
72532
72706
  let result2;
72533
72707
  switch (adapt) {
72534
72708
  case "anthropic":
72535
- result2 = await (0, anthropic_1.queryAnthropic)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents);
72709
+ result2 = await (0, anthropic_1.queryAnthropic)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents);
72536
72710
  break;
72537
72711
  case "openai":
72538
72712
  default:
72539
- result2 = await (0, openai_1.queryOpenAI)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents);
72713
+ result2 = await (0, openai_1.queryOpenAI)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents);
72540
72714
  break;
72541
72715
  }
72542
72716
  (0, logLLM_1.logLLMResponse)(result2);
72543
72717
  if (shouldUseCache && !signal.aborted) {
72544
72718
  const hasContent = result2.message.content.some((block) => block.type === "text" && block.text.trim().length > 0 || block.type === "tool_use");
72545
72719
  if (hasContent) {
72546
- (0, cache_1.setCachedResponse)(messages, systemPromptContent, modelProfile.modelName, result2, enableThinking);
72720
+ (0, cache_1.setCachedResponse)(messages, systemPromptContent, modelProfile.modelName, result2, enableThinking, temperature);
72547
72721
  (0, log_1.logDebug)(`LLM\u54CD\u5E94\u5DF2\u7F13\u5B58\uFF0C\u5F53\u524D\u7F13\u5B58\u6761\u76EE\u6570: ${(0, cache_1.getCacheSize)()}`);
72548
72722
  }
72549
72723
  }
@@ -109421,6 +109595,12 @@ var require_SemaEngine = __commonJS({
109421
109595
  cfg.memoryFiles = partial2.memoryFiles ?? null;
109422
109596
  if ("personaFile" in partial2)
109423
109597
  cfg.personaFile = partial2.personaFile ?? null;
109598
+ if ("modelOverrides" in partial2)
109599
+ cfg.modelOverrides = partial2.modelOverrides ?? null;
109600
+ if ("temperatureOverrides" in partial2)
109601
+ cfg.temperatureOverrides = partial2.temperatureOverrides ?? null;
109602
+ if ("thinking" in partial2)
109603
+ cfg.thinking = partial2.thinking === true;
109424
109604
  }
109425
109605
  /**
109426
109606
  * 当前 session 的 coreConfig 只读快照(= initialConfig,含运行时 mutation 结果)。
@@ -110305,6 +110485,10 @@ var require_AtomixCore = __commonJS({
110305
110485
  this.switchModel = (ModelName) => this.kernel.models.switchCurrentModel(ModelName);
110306
110486
  this.applyTaskModel = (config2) => this.kernel.models.applyTaskModelConfig(config2);
110307
110487
  this.getModelData = () => this.kernel.models.getModelData();
110488
+ this.getModelNames = () => this.kernel.models.getModelNames();
110489
+ this.getModelPointers = () => this.kernel.models.getModelPointers();
110490
+ this.getModelProfiles = () => this.kernel.models.getModelProfiles();
110491
+ this.updateModel = (name, patch) => this.kernel.models.updateModelProfile(name, patch);
110308
110492
  this.updateCoreConfByKey = (key, value) => {
110309
110493
  if (key === "customRules") {
110310
110494
  this.session.updateAssemblyConfig({ customRules: value ?? "" });
@@ -116928,7 +117112,7 @@ var require_dist4 = __commonJS({
116928
117112
  "../atomix-core/dist/index.js"(exports2) {
116929
117113
  "use strict";
116930
117114
  Object.defineProperty(exports2, "__esModule", { value: true });
116931
- exports2.fetchModels = exports2.testApiConnection = exports2.inferVision = exports2.modelHasVision = exports2.ImageLoadError = exports2.preprocessImage = exports2.imageBlockToPlaceholder = exports2.loadImagesAsBlocks = exports2.loadImageAsBlock = exports2.HOOK_EVENTS = exports2.executeHooks = exports2.HookManager = exports2.projectPathToDirName = exports2.getHistoryFilePath = exports2.getProjectHistoryDir = exports2.getHistoryDir = exports2.setModelConfigPathOverride = exports2.setLogLevel = exports2.getModelManager = exports2.SemaSession = exports2.SemaKernel = exports2.getAgentOwnedFilePaths = exports2.renderContextReminder = exports2.readContextSections = exports2.normalizeMemoryFiles = exports2.resolveContextFiles = exports2.isReadOnlyBashCommand = exports2.DEFAULT_PERMISSION_MODE = exports2.PERMISSION_MODES = exports2.assemblePromptSections = exports2.PROMPT_SECTION_CATALOG = exports2.AtomixCore = void 0;
117115
+ exports2.fetchModels = exports2.testApiConnection = exports2.inferVision = exports2.modelHasVision = exports2.ImageLoadError = exports2.preprocessImage = exports2.imageBlockToPlaceholder = exports2.loadImagesAsBlocks = exports2.loadImageAsBlock = exports2.HOOK_EVENTS = exports2.executeHooks = exports2.HookManager = exports2.projectPathToDirName = exports2.getHistoryFilePath = exports2.getProjectHistoryDir = exports2.getHistoryDir = exports2.setModelConfigPathOverride = exports2.setLogLevel = exports2.TEMPERATURE_MAX = exports2.TEMPERATURE_MIN = exports2.DEFAULT_ANTHROPIC_TEMPERATURE = exports2.isValidTemperature = exports2.openaiTemperatureCapability = exports2.modelTemperatureGatedByThinking = exports2.modelRejectsTemperature = exports2.modelForcesTemperatureOne = exports2.getModelManager = exports2.SemaSession = exports2.SemaKernel = exports2.getAgentOwnedFilePaths = exports2.renderContextReminder = exports2.readContextSections = exports2.normalizeMemoryFiles = exports2.resolveContextFiles = exports2.isReadOnlyBashCommand = exports2.DEFAULT_PERMISSION_MODE = exports2.PERMISSION_MODES = exports2.assemblePromptSections = exports2.PROMPT_SECTION_CATALOG = exports2.AtomixCore = void 0;
116932
117116
  var AtomixCore_1 = require_AtomixCore();
116933
117117
  Object.defineProperty(exports2, "AtomixCore", { enumerable: true, get: function() {
116934
117118
  return AtomixCore_1.AtomixCore;
@@ -116979,6 +117163,31 @@ var require_dist4 = __commonJS({
116979
117163
  Object.defineProperty(exports2, "getModelManager", { enumerable: true, get: function() {
116980
117164
  return ModelManager_1.getModelManager;
116981
117165
  } });
117166
+ var adapter_1 = require_adapter();
117167
+ Object.defineProperty(exports2, "modelForcesTemperatureOne", { enumerable: true, get: function() {
117168
+ return adapter_1.modelForcesTemperatureOne;
117169
+ } });
117170
+ Object.defineProperty(exports2, "modelRejectsTemperature", { enumerable: true, get: function() {
117171
+ return adapter_1.modelRejectsTemperature;
117172
+ } });
117173
+ Object.defineProperty(exports2, "modelTemperatureGatedByThinking", { enumerable: true, get: function() {
117174
+ return adapter_1.modelTemperatureGatedByThinking;
117175
+ } });
117176
+ Object.defineProperty(exports2, "openaiTemperatureCapability", { enumerable: true, get: function() {
117177
+ return adapter_1.openaiTemperatureCapability;
117178
+ } });
117179
+ Object.defineProperty(exports2, "isValidTemperature", { enumerable: true, get: function() {
117180
+ return adapter_1.isValidTemperature;
117181
+ } });
117182
+ Object.defineProperty(exports2, "DEFAULT_ANTHROPIC_TEMPERATURE", { enumerable: true, get: function() {
117183
+ return adapter_1.DEFAULT_ANTHROPIC_TEMPERATURE;
117184
+ } });
117185
+ Object.defineProperty(exports2, "TEMPERATURE_MIN", { enumerable: true, get: function() {
117186
+ return adapter_1.TEMPERATURE_MIN;
117187
+ } });
117188
+ Object.defineProperty(exports2, "TEMPERATURE_MAX", { enumerable: true, get: function() {
117189
+ return adapter_1.TEMPERATURE_MAX;
117190
+ } });
116982
117191
  var log_1 = require_log();
116983
117192
  Object.defineProperty(exports2, "setLogLevel", { enumerable: true, get: function() {
116984
117193
  return log_1.setLogLevel;
@@ -124383,6 +124592,63 @@ function requireRuntime(core) {
124383
124592
  function getActiveHarnessName(core) {
124384
124593
  return runtimeOf(core)?.active?.name ?? BASE_HARNESS;
124385
124594
  }
124595
+ function harnessTemperatureOverride(core) {
124596
+ return runtimeOf(core)?.active?.temperatureOverrides ?? null;
124597
+ }
124598
+ function effectiveTemperatures(core) {
124599
+ const models = effectiveModels(core);
124600
+ const profiles = core.getModelProfiles();
124601
+ const over2 = harnessTemperatureOverride(core);
124602
+ const one = (slot) => {
124603
+ const prof = profiles.find((p) => p.name === models[slot]);
124604
+ const mn = prof?.modelName;
124605
+ if (mn && (0, import_atomix_core2.modelForcesTemperatureOne)(mn)) return { value: 1, from: "fixed" };
124606
+ if (mn && (0, import_atomix_core2.modelRejectsTemperature)(mn)) return { value: null, from: "unsupported" };
124607
+ const anthropic = prof?.adapt === "anthropic";
124608
+ const gatedByThinking = anthropic || (mn ? (0, import_atomix_core2.modelTemperatureGatedByThinking)(mn) : false);
124609
+ const notes = [];
124610
+ let from = "default";
124611
+ let raw;
124612
+ const o = over2?.[slot];
124613
+ if (o !== void 0) {
124614
+ if ((0, import_atomix_core2.isValidTemperature)(o)) {
124615
+ raw = o;
124616
+ from = "harness";
124617
+ } else notes.push(`harness \u503C ${JSON.stringify(o)} \u975E\u6CD5(\u987B 0\u20132),\u5DF2\u5FFD\u7565`);
124618
+ }
124619
+ if (raw === void 0 && prof?.temperature !== void 0) {
124620
+ if ((0, import_atomix_core2.isValidTemperature)(prof.temperature)) {
124621
+ raw = prof.temperature;
124622
+ from = "profile";
124623
+ } else notes.push(`profile \u503C ${JSON.stringify(prof.temperature)} \u975E\u6CD5(\u987B 0\u20132),\u5DF2\u5FFD\u7565`);
124624
+ }
124625
+ if (raw === void 0) {
124626
+ return { value: anthropic ? import_atomix_core2.DEFAULT_ANTHROPIC_TEMPERATURE : null, from: "default", ...gatedByThinking ? { gatedByThinking } : {}, ...notes.length ? { notes } : {} };
124627
+ }
124628
+ let value = raw;
124629
+ if (anthropic && value > 1) {
124630
+ value = 1;
124631
+ notes.push(`\u58F0\u660E ${raw} \u8D85 anthropic \u534F\u8BAE\u4E0A\u9650,\u5B9E\u9645\u6309 1 \u53D1`);
124632
+ }
124633
+ return { value, from, configured: raw, ...gatedByThinking ? { gatedByThinking } : {}, ...notes.length ? { notes } : {} };
124634
+ };
124635
+ return { main: one("main"), quick: one("quick") };
124636
+ }
124637
+ function harnessModelOverride(core) {
124638
+ return runtimeOf(core)?.active?.modelOverrides ?? null;
124639
+ }
124640
+ function harnessModelFallback(core) {
124641
+ return runtimeOf(core)?.active?.modelFallback ?? null;
124642
+ }
124643
+ function effectiveModels(core) {
124644
+ const base = core.getModelPointers();
124645
+ const over2 = harnessModelOverride(core);
124646
+ const fb = harnessModelFallback(core);
124647
+ const pick2 = (slot) => over2?.[slot] ? [over2[slot], "harness"] : [base[slot], fb?.[slot] ? "fallback" : "base"];
124648
+ const [main, mainFrom] = pick2("main");
124649
+ const [quick, quickFrom] = pick2("quick");
124650
+ return { main, quick, mainFrom, quickFrom, ...fb ? { fallback: fb } : {} };
124651
+ }
124386
124652
  function recordSkillUniverse(core, names) {
124387
124653
  const rt = runtimeOf(core);
124388
124654
  if (rt) rt.fullSkillNames = names.slice();
@@ -124553,6 +124819,67 @@ function loadHarnessDoc(name) {
124553
124819
  };
124554
124820
  const memory = parseToggle(raw.memory, "memory");
124555
124821
  const persona = parseToggle(raw.persona, "persona");
124822
+ const parseModel = (v) => {
124823
+ if (v === void 0 || v === null) return null;
124824
+ if (typeof v === "string") {
124825
+ const id = v.trim();
124826
+ if (id) return { main: id, quick: id };
124827
+ toggleWarnings.push("model \u4E3A\u7A7A\u5B57\u7B26\u4E32,\u5FFD\u7565(\u89C6\u4E3A\u672A\u58F0\u660E,\u8DDF\u968F base)");
124828
+ return null;
124829
+ }
124830
+ if (typeof v === "object" && !Array.isArray(v)) {
124831
+ const o = v;
124832
+ const out = {};
124833
+ for (const slot of MODEL_SLOTS) {
124834
+ const x = o[slot];
124835
+ if (x === void 0 || x === null) continue;
124836
+ if (typeof x === "string" && x.trim()) out[slot] = x.trim();
124837
+ else toggleWarnings.push(`model.${slot} \u987B\u4E3A\u6A21\u578B\u6807\u8BC6\u5B57\u7B26\u4E32(modelName[provider]),\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(x)}`);
124838
+ }
124839
+ for (const k of Object.keys(o)) if (!MODEL_SLOTS.includes(k)) toggleWarnings.push(`model \u672A\u77E5\u69FD\u4F4D ${k}(\u53EA\u8BA4 main / quick),\u5FFD\u7565`);
124840
+ if (!out.main && !out.quick) {
124841
+ toggleWarnings.push("model \u672A\u58F0\u660E\u4EFB\u4F55\u6709\u6548\u69FD\u4F4D,\u89C6\u4E3A\u672A\u58F0\u660E(\u8DDF\u968F base)");
124842
+ return null;
124843
+ }
124844
+ return out;
124845
+ }
124846
+ toggleWarnings.push(`model \u53EA\u8BA4\u5B57\u7B26\u4E32\u6216 { main, quick },\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(v)}`);
124847
+ return null;
124848
+ };
124849
+ const model = parseModel(raw.model);
124850
+ const thinkingToggle = parseToggle(raw.thinking, "thinking");
124851
+ const thinking = thinkingToggle === null ? null : thinkingToggle === "on";
124852
+ const parseTemperature = (v) => {
124853
+ if (v === void 0 || v === null) return null;
124854
+ const num = (x, label) => {
124855
+ if ((0, import_atomix_core2.isValidTemperature)(x)) return x;
124856
+ toggleWarnings.push(`${label} \u987B\u4E3A 0\u20132 \u7684\u6570\u5B57,\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(x)}`);
124857
+ return void 0;
124858
+ };
124859
+ if (typeof v === "number") {
124860
+ const t2 = num(v, "temperature");
124861
+ return t2 === void 0 ? null : { main: t2 };
124862
+ }
124863
+ if (typeof v === "object" && !Array.isArray(v)) {
124864
+ const o = v;
124865
+ const out = {};
124866
+ for (const slot of MODEL_SLOTS) {
124867
+ const x = o[slot];
124868
+ if (x === void 0 || x === null) continue;
124869
+ const t2 = num(x, `temperature.${slot}`);
124870
+ if (t2 !== void 0) out[slot] = t2;
124871
+ }
124872
+ for (const k of Object.keys(o)) if (!MODEL_SLOTS.includes(k)) toggleWarnings.push(`temperature \u672A\u77E5\u69FD\u4F4D ${k}(\u53EA\u8BA4 main / quick),\u5FFD\u7565`);
124873
+ if (out.main === void 0 && out.quick === void 0) {
124874
+ toggleWarnings.push("temperature \u672A\u58F0\u660E\u4EFB\u4F55\u6709\u6548\u69FD\u4F4D,\u89C6\u4E3A\u672A\u58F0\u660E");
124875
+ return null;
124876
+ }
124877
+ return out;
124878
+ }
124879
+ toggleWarnings.push(`temperature \u53EA\u8BA4\u6570\u5B57\u6216 { main, quick },\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(v)}`);
124880
+ return null;
124881
+ };
124882
+ const temperature = parseTemperature(raw.temperature);
124556
124883
  return {
124557
124884
  name: typeof raw.name === "string" && raw.name ? raw.name : name,
124558
124885
  description: typeof raw.description === "string" ? raw.description : void 0,
@@ -124573,6 +124900,9 @@ function loadHarnessDoc(name) {
124573
124900
  memory,
124574
124901
  persona,
124575
124902
  soulPath,
124903
+ model,
124904
+ thinking,
124905
+ temperature,
124576
124906
  toggleWarnings,
124577
124907
  dir
124578
124908
  };
@@ -124588,6 +124918,14 @@ function resolveBase(ctx) {
124588
124918
  memoryFiles: ctx.baseline.memoryFiles,
124589
124919
  personaFile: ctx.baseline.personaFile,
124590
124920
  warnings: [],
124921
+ dirName: BASE_HARNESS,
124922
+ modelOverrides: null,
124923
+ modelDeclared: null,
124924
+ modelFallback: null,
124925
+ thinkingDeclared: null,
124926
+ temperatureOverrides: null,
124927
+ temperatureDeclared: null,
124928
+ thinking: ctx.baseline.thinking,
124591
124929
  skillsSpec: null,
124592
124930
  agentsSpec: null,
124593
124931
  skillsDisabled: /* @__PURE__ */ new Set(),
@@ -124638,8 +124976,49 @@ function resolveHarness(doc, ctx) {
124638
124976
  if (doc.persona === "on") warnings.push("persona: on \u65E0\u6548:\u672C harness \u672A\u5E26\u4E13\u5C5E SOUL.md(\u4E25\u683C\u9694\u79BB,\u4E0D\u501F base \u4EBA\u8BBE;\u653E\u4E00\u4EFD SOUL.md \u8FDB harness \u76EE\u5F55\u5373\u751F\u6548)");
124639
124977
  personaFile = null;
124640
124978
  }
124979
+ const dirName = path2.basename(doc.dir);
124980
+ const modelOverrides = {};
124981
+ const modelFallback = {};
124982
+ if (doc.model) {
124983
+ for (const slot of MODEL_SLOTS) {
124984
+ const want = doc.model[slot];
124985
+ if (!want) continue;
124986
+ if (ctx.modelNames.includes(want)) modelOverrides[slot] = want;
124987
+ else {
124988
+ modelFallback[slot] = want;
124989
+ warnings.push(`\u6A21\u578B\u56DE\u843D:harness.yaml \u58F0\u660E ${slot}=${want},model.conf \u4E2D\u4E0D\u5B58\u5728,\u5F53\u524D ${slot} \u4F7F\u7528 base \u7684 ${ctx.baseModels[slot] || "-"}(/model add \u6DFB\u52A0\u540E /harness use ${dirName} \u91CD\u65B0\u5E94\u7528)`);
124990
+ }
124991
+ }
124992
+ }
124993
+ const temperatureOverrides = {};
124994
+ if (doc.temperature) {
124995
+ for (const slot of MODEL_SLOTS) {
124996
+ const t = doc.temperature[slot];
124997
+ if (t === void 0) continue;
124998
+ const effModel = modelOverrides[slot] ?? ctx.baseModels[slot];
124999
+ const mn = ctx.modelProfiles?.find((p) => p.name === effModel)?.modelName;
125000
+ if (mn && (0, import_atomix_core2.modelForcesTemperatureOne)(mn)) {
125001
+ warnings.push(`\u6E29\u5EA6\u5FFD\u7565:harness.yaml \u58F0\u660E ${slot} temperature=${t},\u4F46\u6A21\u578B ${effModel} \u53EA\u63A5\u53D7\u9ED8\u8BA4\u6E29\u5EA6 1`);
125002
+ continue;
125003
+ }
125004
+ if (mn && (0, import_atomix_core2.modelRejectsTemperature)(mn)) {
125005
+ warnings.push(`\u6E29\u5EA6\u5FFD\u7565:harness.yaml \u58F0\u660E ${slot} temperature=${t},\u4F46\u6A21\u578B ${effModel} \u4E0D\u652F\u6301 temperature \u53C2\u6570`);
125006
+ continue;
125007
+ }
125008
+ temperatureOverrides[slot] = t;
125009
+ }
125010
+ }
124641
125011
  return {
124642
125012
  name: doc.name,
125013
+ dirName,
125014
+ temperatureOverrides: Object.keys(temperatureOverrides).length ? temperatureOverrides : null,
125015
+ temperatureDeclared: doc.temperature,
125016
+ modelOverrides: Object.keys(modelOverrides).length ? modelOverrides : null,
125017
+ modelDeclared: doc.model,
125018
+ modelFallback: Object.keys(modelFallback).length ? modelFallback : null,
125019
+ // thinking:声明即下发;未声明跟随基线(基线未知则不下发该键,与 memoryFiles 同规则)
125020
+ thinkingDeclared: doc.thinking,
125021
+ thinking: doc.thinking ?? ctx.baseline.thinking,
124643
125022
  useTools,
124644
125023
  deferBuiltinTools: doc.tools.defer.length ? doc.tools.defer : ctx.baseline.deferBuiltinTools ?? [],
124645
125024
  pinnedTools: doc.tools.pin,
@@ -124664,10 +125043,13 @@ function buildContext(core) {
124664
125043
  // 缓存为空只在启动初始化时(此刻尚未过滤,直读即全集)
124665
125044
  allToolNames: core.getToolInfos().map((t) => t.name),
124666
125045
  allSkillNames: rt.fullSkillNames ?? core.getSkillsInfo({ includeDisabled: true }).map((s) => s.name),
124667
- allAgentNames: rt.fullAgentNames ?? core.getAgentsInfo().map((a) => a.name)
125046
+ allAgentNames: rt.fullAgentNames ?? core.getAgentsInfo().map((a) => a.name),
125047
+ modelNames: core.getModelNames(),
125048
+ baseModels: core.getModelPointers(),
125049
+ modelProfiles: core.getModelProfiles()
124668
125050
  };
124669
125051
  }
124670
- function applyAssembly(core, rt, r) {
125052
+ function applyAssembly(core, rt, r, opts = {}) {
124671
125053
  core.updateAssemblyConfig({
124672
125054
  useTools: r.useTools,
124673
125055
  deferBuiltinTools: r.deferBuiltinTools,
@@ -124677,11 +125059,18 @@ function applyAssembly(core, rt, r) {
124677
125059
  // null = 回默认组装(base 清场)
124678
125060
  // 基线未知(宿主没给快照)时不下发该键:传 undefined 会被 core 当 null 落,把供给层开着的注入误关
124679
125061
  ...r.memoryFiles !== void 0 ? { memoryFiles: r.memoryFiles } : {},
124680
- ...r.personaFile !== void 0 ? { personaFile: r.personaFile } : {}
125062
+ ...r.personaFile !== void 0 ? { personaFile: r.personaFile } : {},
125063
+ modelOverrides: r.modelOverrides,
125064
+ // null = 回 model.conf 指针(base 清场)
125065
+ temperatureOverrides: r.temperatureOverrides,
125066
+ // null = 回 profile / 协议默认(base 清场)
125067
+ ...!opts.preserveThinking && r.thinking !== void 0 ? { thinking: r.thinking } : {}
125068
+ // 声明 ?? 基线;只在 use/reset/启动 下发,不做热切换
124681
125069
  });
124682
125070
  rt.activeMemoryFiles = r.memoryFiles;
124683
125071
  rt.activePersonaFile = r.personaFile;
124684
- rt.active = r.name === BASE_HARNESS ? null : r;
125072
+ if (!opts.preserveThinking) rt.activeThinking = r.thinking;
125073
+ rt.active = r.dirName === BASE_HARNESS ? null : r;
124685
125074
  }
124686
125075
  function initHarness(core, cwd, base, opts = {}) {
124687
125076
  const rt = {
@@ -124690,10 +125079,12 @@ function initHarness(core, cwd, base, opts = {}) {
124690
125079
  deferBuiltinTools: base.deferBuiltinTools?.slice(),
124691
125080
  memoryFiles: base.memoryFiles,
124692
125081
  personaFile: base.personaFile,
124693
- potentialMemoryFiles: base.potentialMemoryFiles
125082
+ potentialMemoryFiles: base.potentialMemoryFiles,
125083
+ thinking: base.thinking
124694
125084
  },
124695
125085
  activeMemoryFiles: base.memoryFiles,
124696
125086
  activePersonaFile: base.personaFile,
125087
+ activeThinking: base.thinking,
124697
125088
  projectDir: cwd,
124698
125089
  active: null,
124699
125090
  overridden: opts.harness !== void 0,
@@ -124715,7 +125106,7 @@ function initHarness(core, cwd, base, opts = {}) {
124715
125106
  return `harness "${name}"(${source})\u52A0\u8F7D\u5931\u8D25,\u5DF2\u56DE\u843D base:${e instanceof Error ? e.message : e}`;
124716
125107
  }
124717
125108
  }
124718
- var fs2, path2, import_yaml, import_atomix_core, BASE_HARNESS, runtimes;
125109
+ var fs2, path2, import_yaml, import_atomix_core, import_atomix_core2, MODEL_SLOTS, BASE_HARNESS, runtimes;
124719
125110
  var init_harness = __esm({
124720
125111
  "src/harness.ts"() {
124721
125112
  "use strict";
@@ -124723,7 +125114,9 @@ var init_harness = __esm({
124723
125114
  path2 = __toESM(require("path"));
124724
125115
  import_yaml = __toESM(require_dist5());
124725
125116
  import_atomix_core = __toESM(require_dist4());
125117
+ import_atomix_core2 = __toESM(require_dist4());
124726
125118
  init_paths();
125119
+ MODEL_SLOTS = ["main", "quick"];
124727
125120
  BASE_HARNESS = "base";
124728
125121
  runtimes = /* @__PURE__ */ new WeakMap();
124729
125122
  }
@@ -124732,7 +125125,7 @@ var init_harness = __esm({
124732
125125
  // src/memoryPaths.ts
124733
125126
  function getMemoryPaths(cwd) {
124734
125127
  const root3 = realpathOrSelf(getAtomixRoot());
124735
- const slug = (0, import_atomix_core2.projectPathToDirName)(cwd);
125128
+ const slug = (0, import_atomix_core3.projectPathToDirName)(cwd);
124736
125129
  const projectDir = path3.join(root3, "projects", slug);
124737
125130
  return {
124738
125131
  root: root3,
@@ -124750,13 +125143,13 @@ function realpathOrSelf(p) {
124750
125143
  return p;
124751
125144
  }
124752
125145
  }
124753
- var fs3, path3, import_atomix_core2;
125146
+ var fs3, path3, import_atomix_core3;
124754
125147
  var init_memoryPaths = __esm({
124755
125148
  "src/memoryPaths.ts"() {
124756
125149
  "use strict";
124757
125150
  fs3 = __toESM(require("fs"));
124758
125151
  path3 = __toESM(require("path"));
124759
- import_atomix_core2 = __toESM(require_dist4());
125152
+ import_atomix_core3 = __toESM(require_dist4());
124760
125153
  init_paths();
124761
125154
  }
124762
125155
  });
@@ -125468,7 +125861,7 @@ if (!process.env.ATOMIX_LLM_LOG_ROOT) {
125468
125861
  }
125469
125862
 
125470
125863
  // src/session.ts
125471
- var import_atomix_core5 = __toESM(require_dist4());
125864
+ var import_atomix_core6 = __toESM(require_dist4());
125472
125865
 
125473
125866
  // src/sessionTypes.ts
125474
125867
  var SESSION_HANDLE_BRAND = /* @__PURE__ */ Symbol.for("atomix-cli.sessionHandle");
@@ -125592,10 +125985,10 @@ async function applyMcpHotUpdates(core) {
125592
125985
  // src/hooksLoader.ts
125593
125986
  var fs9 = __toESM(require("fs"));
125594
125987
  var path9 = __toESM(require("path"));
125595
- var import_atomix_core3 = __toESM(require_dist4());
125988
+ var import_atomix_core4 = __toESM(require_dist4());
125596
125989
  init_paths();
125597
125990
  init_marketplace();
125598
- var VALID_EVENTS = new Set(import_atomix_core3.HOOK_EVENTS);
125991
+ var VALID_EVENTS = new Set(import_atomix_core4.HOOK_EVENTS);
125599
125992
  function readHookFile(p) {
125600
125993
  if (!fs9.existsSync(p)) return null;
125601
125994
  try {
@@ -125657,7 +126050,7 @@ function loadHooks(cwd) {
125657
126050
  }
125658
126051
 
125659
126052
  // src/quiet.ts
125660
- var import_atomix_core4 = __toESM(require_dist4());
126053
+ var import_atomix_core5 = __toESM(require_dist4());
125661
126054
  var VALID = ["none", "debug", "info", "warn", "error"];
125662
126055
  function atomixLogLevel() {
125663
126056
  const env = process.env.ATOMIX_LOG;
@@ -125697,7 +126090,7 @@ function prepareProcess(cwd) {
125697
126090
  }
125698
126091
  function createSessionCore(opts) {
125699
126092
  const interactive = opts.interactive ?? false;
125700
- const permissionMode = opts.permissionMode ?? (interactive ? import_atomix_core5.DEFAULT_PERMISSION_MODE : "free-style");
126093
+ const permissionMode = opts.permissionMode ?? (interactive ? import_atomix_core6.DEFAULT_PERMISSION_MODE : "free-style");
125701
126094
  const notes = [];
125702
126095
  const prepNote = prepareProcess(opts.cwd);
125703
126096
  if (prepNote) notes.push(prepNote);
@@ -125705,7 +126098,7 @@ function createSessionCore(opts) {
125705
126098
  const contextFiles = buildContextFilesConfig(opts.cwd, appConfig);
125706
126099
  const hookCfg = opts.hooks ?? interactive ? loadHooks(opts.cwd) : {};
125707
126100
  const dirs = { skills: buildSkillsExtraDirs(), agents: buildAgentsExtraDirs(), commands: buildCommandsExtraDirs() };
125708
- const core = new import_atomix_core5.AtomixCore({
126101
+ const core = new import_atomix_core6.AtomixCore({
125709
126102
  workingDir: opts.cwd,
125710
126103
  logLevel: opts.logLevel ?? atomixLogLevel(),
125711
126104
  stream: opts.stream ?? interactive,
@@ -125729,7 +126122,9 @@ function createSessionCore(opts) {
125729
126122
  deferBuiltinTools: ATOMIX_DEFER_TOOLS,
125730
126123
  memoryFiles: contextFiles.memoryFiles,
125731
126124
  personaFile: contextFiles.personaFile,
125732
- potentialMemoryFiles: potential.memoryFiles
126125
+ potentialMemoryFiles: potential.memoryFiles,
126126
+ thinking: false
126127
+ // cli 构造 core 时 thinking 关;harness 未声明即回到这里
125733
126128
  };
125734
126129
  return { [SESSION_HANDLE_BRAND]: true, core, cwd: opts.cwd, interactive, permissionMode, appConfig, contextFiles, baseline, notes };
125735
126130
  }
@@ -125836,6 +126231,16 @@ var SessionImpl = class {
125836
126231
  get harness() {
125837
126232
  return getActiveHarnessName(this.core);
125838
126233
  }
126234
+ get model() {
126235
+ const m = effectiveModels(this.core);
126236
+ const t = effectiveTemperatures(this.core);
126237
+ const temperature = {};
126238
+ for (const slot of ["main", "quick"]) {
126239
+ const e = t[slot];
126240
+ if ((e.from === "harness" || e.from === "profile") && e.value !== null) temperature[slot] = e.value;
126241
+ }
126242
+ return { main: m.main, quick: m.quick, ...m.fallback ? { fallback: m.fallback } : {}, ...Object.keys(temperature).length ? { temperature } : {} };
126243
+ }
125839
126244
  on(event, listener) {
125840
126245
  this.core.on(event, listener);
125841
126246
  }
@@ -125954,7 +126359,7 @@ function attachStreamEvents(core, emit) {
125954
126359
  // src/resume.ts
125955
126360
  var fs10 = __toESM(require("fs"));
125956
126361
  var path10 = __toESM(require("path"));
125957
- var import_atomix_core6 = __toESM(require_dist4());
126362
+ var import_atomix_core7 = __toESM(require_dist4());
125958
126363
  function extractText(content) {
125959
126364
  if (typeof content === "string") return content.trim().startsWith("<") ? "" : content;
125960
126365
  if (Array.isArray(content)) {
@@ -125971,7 +126376,7 @@ function readMessages(file) {
125971
126376
  }
125972
126377
  }
125973
126378
  function listSessions(cwd) {
125974
- const dir = (0, import_atomix_core6.getProjectHistoryDir)(cwd);
126379
+ const dir = (0, import_atomix_core7.getProjectHistoryDir)(cwd);
125975
126380
  if (!fs10.existsSync(dir)) return [];
125976
126381
  const entries = [];
125977
126382
  for (const f of fs10.readdirSync(dir)) {
@@ -125996,8 +126401,8 @@ function listSessions(cwd) {
125996
126401
  init_harness();
125997
126402
 
125998
126403
  // src/permissionMode.ts
125999
- var import_atomix_core7 = __toESM(require_dist4());
126000
- var PERMISSION_MODE_ORDER = import_atomix_core7.PERMISSION_MODES;
126404
+ var import_atomix_core8 = __toESM(require_dist4());
126405
+ var PERMISSION_MODE_ORDER = import_atomix_core8.PERMISSION_MODES;
126001
126406
  function parsePermissionMode(arg) {
126002
126407
  if (!arg) return null;
126003
126408
  const norm = arg.trim().toLowerCase().replace(/[\s_-]+/g, "");
@@ -126028,7 +126433,7 @@ var listSessions2 = listSessions;
126028
126433
  var listHarnesses2 = listHarnesses;
126029
126434
  var BASE_HARNESS2 = BASE_HARNESS;
126030
126435
  var PERMISSION_MODE_ORDER2 = PERMISSION_MODE_ORDER;
126031
- var DEFAULT_PERMISSION_MODE3 = import_atomix_core7.DEFAULT_PERMISSION_MODE;
126436
+ var DEFAULT_PERMISSION_MODE3 = import_atomix_core8.DEFAULT_PERMISSION_MODE;
126032
126437
  var parsePermissionMode2 = parsePermissionMode;
126033
126438
  var getAtomixRoot2 = getAtomixRoot;
126034
126439
  // Annotate the CommonJS export names for ESM import in node: