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.mjs CHANGED
@@ -67,8 +67,14 @@ var require_adapter = __commonJS({
67
67
  "../atomix-core/dist/util/adapter.js"(exports2) {
68
68
  "use strict";
69
69
  Object.defineProperty(exports2, "__esModule", { value: true });
70
- exports2.TEMPERATURE_ONE_MODELS = void 0;
70
+ exports2.TEMPERATURE_MAX = exports2.TEMPERATURE_MIN = exports2.DEFAULT_ANTHROPIC_TEMPERATURE = exports2.TEMPERATURE_ONE_MODELS = void 0;
71
71
  exports2.resolveAdapter = resolveAdapter;
72
+ exports2.openaiTemperatureCapability = openaiTemperatureCapability;
73
+ exports2.modelForcesTemperatureOne = modelForcesTemperatureOne2;
74
+ exports2.modelRejectsTemperature = modelRejectsTemperature2;
75
+ exports2.modelTemperatureGatedByThinking = modelTemperatureGatedByThinking2;
76
+ exports2.isValidTemperature = isValidTemperature2;
77
+ exports2.assertTemperature = assertTemperature;
72
78
  exports2.useMaxCompletionTokens = useMaxCompletionTokens;
73
79
  exports2.modelForcesThinking = modelForcesThinking;
74
80
  exports2.forcedThinkingEffort = forcedThinkingEffort;
@@ -117,6 +123,60 @@ var require_adapter = __commonJS({
117
123
  "kimi-k2.5",
118
124
  "moonshotai/kimi-k2.5"
119
125
  ];
126
+ var OPENAI_TEMPERATURE_NORMAL_PREFIXES = ["gpt-5-chat", "gpt-5.1-chat", "gpt-5.2-chat"];
127
+ var OPENAI_TEMPERATURE_REJECT_EXACT = ["gpt-5"];
128
+ var OPENAI_TEMPERATURE_REJECT_PREFIXES = [
129
+ "o1",
130
+ "o3",
131
+ "o4",
132
+ "gpt-5-mini",
133
+ "gpt-5-nano",
134
+ "gpt-5-20",
135
+ // 初代及其日期快照(gpt-5-2025-08-07)
136
+ "gpt-5-pro",
137
+ "gpt-5.1-pro",
138
+ "gpt-5.2-pro",
139
+ "gpt-5-codex",
140
+ "gpt-5.1-codex",
141
+ "gpt-5.2-codex"
142
+ ];
143
+ var OPENAI_TEMPERATURE_GATED_PREFIXES = ["gpt-5.1", "gpt-5.2"];
144
+ function bareModelName(modelName) {
145
+ const lower = modelName.toLowerCase();
146
+ return lower.split("/").pop() ?? lower;
147
+ }
148
+ function openaiTemperatureCapability(modelName) {
149
+ const bare = bareModelName(modelName);
150
+ if (OPENAI_TEMPERATURE_NORMAL_PREFIXES.some((p) => bare.startsWith(p)))
151
+ return "normal";
152
+ if (OPENAI_TEMPERATURE_REJECT_EXACT.includes(bare) || OPENAI_TEMPERATURE_REJECT_PREFIXES.some((p) => bare.startsWith(p)))
153
+ return "reject";
154
+ if (OPENAI_TEMPERATURE_GATED_PREFIXES.some((p) => bare.startsWith(p)))
155
+ return "gated";
156
+ if (bare.startsWith("gpt-5"))
157
+ return "reject";
158
+ return null;
159
+ }
160
+ function modelForcesTemperatureOne2(modelName) {
161
+ return exports2.TEMPERATURE_ONE_MODELS.includes(modelName);
162
+ }
163
+ function modelRejectsTemperature2(modelName) {
164
+ return openaiTemperatureCapability(modelName) === "reject";
165
+ }
166
+ function modelTemperatureGatedByThinking2(modelName) {
167
+ return openaiTemperatureCapability(modelName) === "gated";
168
+ }
169
+ function isValidTemperature2(t) {
170
+ return typeof t === "number" && Number.isFinite(t) && t >= exports2.TEMPERATURE_MIN && t <= exports2.TEMPERATURE_MAX;
171
+ }
172
+ exports2.DEFAULT_ANTHROPIC_TEMPERATURE = 0.7;
173
+ exports2.TEMPERATURE_MIN = 0;
174
+ exports2.TEMPERATURE_MAX = 2;
175
+ function assertTemperature(t) {
176
+ if (!isValidTemperature2(t)) {
177
+ throw new Error(`temperature \u987B\u4E3A ${exports2.TEMPERATURE_MIN}\u2013${exports2.TEMPERATURE_MAX} \u7684\u6570\u5B57,\u6536\u5230 ${JSON.stringify(t)}`);
178
+ }
179
+ }
120
180
  var MAX_COMPLETION_TOKENS_PREFIXES = [
121
181
  "o1",
122
182
  "o3",
@@ -310,7 +370,8 @@ var require_apiUtil = __commonJS({
310
370
  model: modelName,
311
371
  messages: [{ role: "user", content: 'Please respond with exactly "YES" (in capital letters) to confirm this connection is working.' }],
312
372
  ...(0, adapter_1.useMaxCompletionTokens)(modelName) ? { max_completion_tokens: 200 } : { max_tokens: 200 },
313
- temperature: adapter_1.TEMPERATURE_ONE_MODELS.includes(modelName) ? 1 : 0,
373
+ // 不发 temperature:与正式请求(adapt/openai.ts)一致,交给服务端默认。之前固定发 0.0,
374
+ // gpt-5 / o 系列等只接受默认值 1 的模型直接 400("does not support 0.0 with this model"),把可用模型挡在添加阶段
314
375
  stream: false
315
376
  }),
316
377
  extractContent: (response) => response.choices?.[0]?.message?.content || "",
@@ -17395,7 +17456,8 @@ var require_model = __commonJS({
17395
17456
  apiKey: config.apiKey,
17396
17457
  maxTokens: config.maxTokens || fallback.maxTokens,
17397
17458
  contextLength: config.contextLength || fallback.contextLength,
17398
- adapt: config.adapt ?? (0, adapter_1.resolveAdapter)(config.provider, config.modelName)
17459
+ adapt: config.adapt ?? (0, adapter_1.resolveAdapter)(config.provider, config.modelName),
17460
+ ...config.temperature !== void 0 ? { temperature: config.temperature } : {}
17399
17461
  };
17400
17462
  }
17401
17463
  }
@@ -17446,10 +17508,12 @@ var require_ModelManager = __commonJS({
17446
17508
  exports2.getModelManager = exports2.ModelManager = void 0;
17447
17509
  var fs11 = __importStar(__require("fs"));
17448
17510
  var path11 = __importStar(__require("path"));
17511
+ var adapter_1 = require_adapter();
17449
17512
  var apiUtil_1 = require_apiUtil();
17450
17513
  var savePath_1 = require_savePath();
17451
17514
  var model_1 = require_model();
17452
17515
  var log_1 = require_log();
17516
+ var EngineContext_1 = require_EngineContext();
17453
17517
  var ModelManager = class {
17454
17518
  constructor(initialConfig) {
17455
17519
  this.configPath = (0, savePath_1.getModelConfigFilePath)();
@@ -17477,6 +17541,8 @@ var require_ModelManager = __commonJS({
17477
17541
  * @param skipValidation 是否跳过API校验,默认为false
17478
17542
  */
17479
17543
  async addNewModel(config, skipValidation = false) {
17544
+ if (config.temperature !== void 0)
17545
+ this.assertProfileTemperature(config.modelName, config.temperature);
17480
17546
  const profile = (0, model_1.convertToModelProfile)(config);
17481
17547
  const existingModelIndex = this.config.modelProfiles.findIndex((p) => p.name === profile.name);
17482
17548
  if (!skipValidation) {
@@ -17505,7 +17571,7 @@ ${testResult.curlCommand}` : testResult.message;
17505
17571
  }
17506
17572
  }
17507
17573
  if (existingModelIndex !== -1) {
17508
- this.config.modelProfiles[existingModelIndex] = profile;
17574
+ this.config.modelProfiles[existingModelIndex] = { ...this.config.modelProfiles[existingModelIndex], ...profile };
17509
17575
  } else {
17510
17576
  this.config.modelProfiles.push(profile);
17511
17577
  if (this.config.modelProfiles.length === 1) {
@@ -17604,16 +17670,36 @@ ${testResult.curlCommand}` : testResult.message;
17604
17670
  };
17605
17671
  }
17606
17672
  /**
17607
- * 获取指定类型的模型配置
17673
+ * 解析指针槽位实际指向的模型标识(harness-model-v1 §2):
17674
+ * 当前会话(EngineStore.coreConfig.modelOverrides)有覆盖则用覆盖,否则用 model.conf 指针。
17675
+ * ALS 之外(无 EngineStore)读不到覆盖 = base。
17676
+ */
17677
+ resolvePointer(pointer) {
17678
+ const override = (0, EngineContext_1.getEngineStore)()?.coreConfig?.modelOverrides?.[pointer];
17679
+ if (typeof override === "string" && override)
17680
+ return { id: override, overridden: true };
17681
+ return { id: this.config.modelPointers?.[pointer] || null, overridden: false };
17682
+ }
17683
+ /**
17684
+ * 获取指定类型的模型配置(会话覆盖优先)。
17685
+ * 覆盖指向的 profile 已不存在(会话中被删)时返回 null,由调用方报错——不静默回落 base。
17608
17686
  */
17609
17687
  getModel(pointer) {
17610
- const pointerId = this.config.modelPointers?.[pointer];
17611
- if (!pointerId) {
17688
+ const { id } = this.resolvePointer(pointer);
17689
+ if (!id) {
17612
17690
  return null;
17613
17691
  }
17614
- const profile = (0, model_1.findModelProfile)(pointerId, this.config.modelProfiles);
17692
+ const profile = (0, model_1.findModelProfile)(id, this.config.modelProfiles);
17615
17693
  return profile || null;
17616
17694
  }
17695
+ /** 已配置的模型标识列表(同步;harness 解析是同步纯函数,不能等异步 getModelData)。 */
17696
+ getModelNames() {
17697
+ return this.config.modelProfiles.map((p) => p.name);
17698
+ }
17699
+ /** model.conf 的指针值(base,不含会话覆盖;同步)。 */
17700
+ getModelPointers() {
17701
+ return { main: this.config.modelPointers?.main ?? "", quick: this.config.modelPointers?.quick ?? "" };
17702
+ }
17617
17703
  /**
17618
17704
  * 获取指定类型的模型名称
17619
17705
  */
@@ -17621,6 +17707,89 @@ ${testResult.curlCommand}` : testResult.message;
17621
17707
  const profile = this.getModel(pointer);
17622
17708
  return profile ? profile.modelName : null;
17623
17709
  }
17710
+ // ===================== 温度 / profile 字段编辑(model-temperature-v1) =====================
17711
+ /** 去 apiKey 的只读视图;adapt 补齐(缺省按 provider/modelName 推断),cli 展示"协议默认"时不必再算 */
17712
+ getModelProfiles() {
17713
+ return this.config.modelProfiles.map((p) => {
17714
+ const { apiKey: _k, ...rest2 } = p;
17715
+ return { ...rest2, adapt: p.adapt ?? (0, adapter_1.resolveAdapter)(p.provider, p.modelName) };
17716
+ });
17717
+ }
17718
+ /**
17719
+ * 改单个 profile 的字段,不重跑连通性测试。`'temperature' in patch && patch.temperature === undefined` = 清除。
17720
+ * 硬约束模型(TEMPERATURE_ONE_MODELS)拒绝设温度:覆盖只会换来 4xx。
17721
+ */
17722
+ async updateModelProfile(name, patch) {
17723
+ const idx = this.config.modelProfiles.findIndex((p) => p.name === name);
17724
+ if (idx === -1)
17725
+ throw new Error(`\u6A21\u578B\u4E0D\u5B58\u5728: ${name}`);
17726
+ const next = { ...this.config.modelProfiles[idx] };
17727
+ if ("temperature" in patch) {
17728
+ if (patch.temperature === void 0)
17729
+ delete next.temperature;
17730
+ else {
17731
+ this.assertProfileTemperature(next.modelName, patch.temperature);
17732
+ next.temperature = patch.temperature;
17733
+ }
17734
+ }
17735
+ for (const k of ["maxTokens", "contextLength"]) {
17736
+ if (k in patch) {
17737
+ const v = patch[k];
17738
+ if (!Number.isInteger(v) || v <= 0)
17739
+ throw new Error(`${k} \u987B\u4E3A\u6B63\u6574\u6570,\u6536\u5230 ${JSON.stringify(v)}`);
17740
+ next[k] = v;
17741
+ }
17742
+ }
17743
+ if ("vision" in patch) {
17744
+ if (patch.vision === void 0)
17745
+ delete next.vision;
17746
+ else if (typeof patch.vision !== "boolean")
17747
+ throw new Error(`vision \u987B\u4E3A\u5E03\u5C14\u503C`);
17748
+ else
17749
+ next.vision = patch.vision;
17750
+ }
17751
+ this.config.modelProfiles[idx] = next;
17752
+ await this.saveConfig();
17753
+ const { apiKey: _k, ...rest2 } = next;
17754
+ return { ...rest2, adapt: next.adapt ?? (0, adapter_1.resolveAdapter)(next.provider, next.modelName) };
17755
+ }
17756
+ /** 范围校验 + 模型侧约束拒绝;addNewModel / updateModelProfile 共用。gpt-5 系列允许配置(thinking 关时生效),这里不挡 */
17757
+ assertProfileTemperature(modelName, t) {
17758
+ (0, adapter_1.assertTemperature)(t);
17759
+ if ((0, adapter_1.modelForcesTemperatureOne)(modelName))
17760
+ throw new Error(`\u6A21\u578B ${modelName} \u53EA\u63A5\u53D7\u9ED8\u8BA4\u6E29\u5EA6 1,\u4E0D\u80FD\u8BBE\u7F6E temperature`);
17761
+ if ((0, adapter_1.modelRejectsTemperature)(modelName))
17762
+ throw new Error(`\u6A21\u578B ${modelName} \u4E0D\u652F\u6301 temperature \u53C2\u6570(\u63A8\u7406\u6A21\u578B),\u4E0D\u80FD\u8BBE\u7F6E`);
17763
+ }
17764
+ /**
17765
+ * 请求时的温度解析(model-temperature-v1 §1.1),高者胜:
17766
+ * 1 模型侧约束:kimi 恒 1;o 系列永不发;gpt-5 系列 thinking 开(发 reasoning_effort)时不发;anthropic 协议开 thinking 不发;
17767
+ * 2 会话级覆盖(harness,经 EngineStore);3 profile.temperature;4 协议默认(anthropic 0.7,openai 不发)。
17768
+ * 返回 undefined = 请求体不带该字段。
17769
+ */
17770
+ resolveTemperature(pointer, profile, opts) {
17771
+ if ((0, adapter_1.modelForcesTemperatureOne)(profile.modelName))
17772
+ return 1;
17773
+ if ((0, adapter_1.modelRejectsTemperature)(profile.modelName))
17774
+ return void 0;
17775
+ if (opts.enableThinking && (0, adapter_1.modelTemperatureGatedByThinking)(profile.modelName))
17776
+ return void 0;
17777
+ if (opts.adapter === "anthropic" && opts.enableThinking)
17778
+ return void 0;
17779
+ const over2 = (0, EngineContext_1.getEngineStore)()?.coreConfig?.temperatureOverrides?.[pointer];
17780
+ if (over2 !== void 0 && !(0, adapter_1.isValidTemperature)(over2))
17781
+ (0, log_1.logWarn)(`temperatureOverrides.${pointer} \u975E\u6CD5(${JSON.stringify(over2)}),\u5FFD\u7565,\u6539\u7528 profile / \u9ED8\u8BA4`);
17782
+ if (profile.temperature !== void 0 && !(0, adapter_1.isValidTemperature)(profile.temperature))
17783
+ (0, log_1.logWarn)(`\u6A21\u578B ${profile.name} \u7684 temperature \u975E\u6CD5(${JSON.stringify(profile.temperature)}),\u5FFD\u7565,\u6539\u7528\u534F\u8BAE\u9ED8\u8BA4`);
17784
+ let t = (0, adapter_1.isValidTemperature)(over2) ? over2 : (0, adapter_1.isValidTemperature)(profile.temperature) ? profile.temperature : void 0;
17785
+ if (t === void 0)
17786
+ return opts.adapter === "anthropic" ? adapter_1.DEFAULT_ANTHROPIC_TEMPERATURE : void 0;
17787
+ if (opts.adapter === "anthropic" && t > 1) {
17788
+ (0, log_1.logWarn)(`temperature ${t} \u8D85\u51FA anthropic \u534F\u8BAE\u4E0A\u9650,\u6309 1 \u53D1\u9001(${profile.name})`);
17789
+ t = 1;
17790
+ }
17791
+ return t;
17792
+ }
17624
17793
  /**
17625
17794
  * 获取当前模型数据
17626
17795
  * @param showModelProfiles 是否包含详细的模型配置信息,默认为false
@@ -47744,13 +47913,15 @@ var require_cacheLLM = __commonJS({
47744
47913
  /**
47745
47914
  * 生成缓存键 - 基于消息内容生成简单hash
47746
47915
  */
47747
- generateKey(messages, systemPrompt, modelName, enableThinking = false) {
47916
+ generateKey(messages, systemPrompt, modelName, enableThinking = false, temperature) {
47748
47917
  const normalizedSystemPrompt = Array.isArray(systemPrompt) && systemPrompt.length > 0 && typeof systemPrompt[0] === "object" && "type" in systemPrompt[0] ? systemPrompt.map((item) => item.text) : systemPrompt;
47749
47918
  const content = JSON.stringify({
47750
47919
  messages: messages.map((msg) => msg.message.content),
47751
47920
  systemPrompt: normalizedSystemPrompt,
47752
47921
  modelName,
47753
- enableThinking
47922
+ enableThinking,
47923
+ temperature: temperature ?? null
47924
+ // 不同温度不共享缓存(model-temperature-v1)
47754
47925
  });
47755
47926
  return crypto_1.default.createHash("md5").update(content).digest("hex");
47756
47927
  }
@@ -47780,8 +47951,8 @@ var require_cacheLLM = __commonJS({
47780
47951
  /**
47781
47952
  * 获取缓存
47782
47953
  */
47783
- get(messages, systemPrompt, modelName, enableThinking = false) {
47784
- const key = this.generateKey(messages, systemPrompt, modelName, enableThinking);
47954
+ get(messages, systemPrompt, modelName, enableThinking = false, temperature) {
47955
+ const key = this.generateKey(messages, systemPrompt, modelName, enableThinking, temperature);
47785
47956
  const entries = this.readCacheFile();
47786
47957
  const entry = entries.find((e) => e.key === key);
47787
47958
  return entry ? entry.response : null;
@@ -47789,8 +47960,8 @@ var require_cacheLLM = __commonJS({
47789
47960
  /**
47790
47961
  * 设置缓存
47791
47962
  */
47792
- set(messages, systemPrompt, modelName, response, enableThinking = false) {
47793
- const key = this.generateKey(messages, systemPrompt, modelName, enableThinking);
47963
+ set(messages, systemPrompt, modelName, response, enableThinking = false, temperature) {
47964
+ const key = this.generateKey(messages, systemPrompt, modelName, enableThinking, temperature);
47794
47965
  let entries = this.readCacheFile();
47795
47966
  entries = entries.filter((e) => e.key !== key);
47796
47967
  entries.unshift({
@@ -47839,8 +48010,8 @@ var require_cache = __commonJS({
47839
48010
  var log_1 = require_log();
47840
48011
  var CACHE_STREAM_CHUNK_SIZE = 20;
47841
48012
  var CACHE_STREAM_DELAY = 100;
47842
- async function tryGetCachedResponse(messages, systemPromptContent, modelName, shouldStream, enableThinking, emitChunkEvents, signal) {
47843
- const cachedResponse = cacheLLM_1.llmCache.get(messages, systemPromptContent, modelName, enableThinking);
48013
+ async function tryGetCachedResponse(messages, systemPromptContent, modelName, shouldStream, enableThinking, emitChunkEvents, signal, temperature) {
48014
+ const cachedResponse = cacheLLM_1.llmCache.get(messages, systemPromptContent, modelName, enableThinking, temperature);
47844
48015
  if (!cachedResponse) {
47845
48016
  return null;
47846
48017
  }
@@ -47913,8 +48084,8 @@ var require_cache = __commonJS({
47913
48084
  function calcSimulatedDelay(contentLength, maxDelay) {
47914
48085
  return Math.min(Math.ceil(contentLength / CACHE_STREAM_CHUNK_SIZE) * CACHE_STREAM_DELAY, maxDelay);
47915
48086
  }
47916
- function setCachedResponse(messages, systemPromptContent, modelName, response, enableThinking = false) {
47917
- cacheLLM_1.llmCache.set(messages, systemPromptContent, modelName, response, enableThinking);
48087
+ function setCachedResponse(messages, systemPromptContent, modelName, response, enableThinking = false, temperature) {
48088
+ cacheLLM_1.llmCache.set(messages, systemPromptContent, modelName, response, enableThinking, temperature);
47918
48089
  }
47919
48090
  function getCacheSize() {
47920
48091
  return cacheLLM_1.llmCache.size();
@@ -61181,7 +61352,7 @@ var require_openai2 = __commonJS({
61181
61352
  }
61182
61353
  };
61183
61354
  }
61184
- async function queryOpenAI(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents) {
61355
+ async function queryOpenAI(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents) {
61185
61356
  const start = Date.now();
61186
61357
  let baseURL = modelProfile.baseURL || "https://api.openai.com/v1";
61187
61358
  const providerEndpoints = (0, providerEndpoint_1.getProviderEndpoints)(modelProfile.provider, baseURL);
@@ -61206,6 +61377,7 @@ var require_openai2 = __commonJS({
61206
61377
  stream: true,
61207
61378
  ...openaiTools && { tools: openaiTools },
61208
61379
  ...(0, adapter_1.useMaxCompletionTokens)(modelProfile.modelName) ? { max_completion_tokens: modelProfile.maxTokens || 8e3 } : { max_tokens: modelProfile.maxTokens || 8e3 },
61380
+ ...temperature !== void 0 && { temperature },
61209
61381
  // thinking 参数按 provider profile 统一构造(openai/openrouter/qwen/compat 等)
61210
61382
  ...(0, providerProfile_1.buildThinkingParams)(modelProfile, enableThinking)
61211
61383
  };
@@ -72415,7 +72587,7 @@ var require_anthropic = __commonJS({
72415
72587
  usage
72416
72588
  };
72417
72589
  }
72418
- async function queryAnthropic(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents) {
72590
+ async function queryAnthropic(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents) {
72419
72591
  const start = Date.now();
72420
72592
  const rawBaseURL = modelProfile.baseURL || "https://api.anthropic.com";
72421
72593
  const providerEndpoints = (0, providerEndpoint_1.getProviderEndpoints)(modelProfile.provider, rawBaseURL);
@@ -72436,7 +72608,7 @@ var require_anthropic = __commonJS({
72436
72608
  messages: anthropicMessages,
72437
72609
  system: systemPromptContent,
72438
72610
  max_tokens: modelProfile.maxTokens,
72439
- temperature: util_1.MAIN_QUERY_TEMPERATURE,
72611
+ ...temperature !== void 0 && { temperature },
72440
72612
  stream: true,
72441
72613
  ...anthropicTools && { tools: anthropicTools }
72442
72614
  };
@@ -72517,7 +72689,8 @@ var require_queryLLM = __commonJS({
72517
72689
  async function queryLLM(messages, systemPromptContent, signal, tools, modelPointer = "main", disableChunkEvents = false, suppressErrorEvent = false) {
72518
72690
  const modelProfile = (0, ModelManager_1.getModelManager)().getModel(modelPointer);
72519
72691
  if (!modelProfile) {
72520
- throw new Error(`\u89E3\u6790\u6A21\u578B\u5931\u8D25: ${modelPointer}`);
72692
+ const { id, overridden } = (0, ModelManager_1.getModelManager)().resolvePointer(modelPointer);
72693
+ 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}`);
72521
72694
  }
72522
72695
  try {
72523
72696
  const coreConfig = (0, ConfManager_1.getConfManager)().getCoreConfig();
@@ -72525,30 +72698,31 @@ var require_queryLLM = __commonJS({
72525
72698
  const shouldStream = coreConfig?.stream !== false;
72526
72699
  const enableThinking = modelPointer !== "quick" && coreConfig?.thinking === true;
72527
72700
  const emitChunkEvents = !disableChunkEvents && shouldStream !== false;
72701
+ const adapt = modelProfile.adapt || (0, adapter_1.resolveAdapter)(modelProfile.provider, modelProfile.modelName);
72702
+ const temperature = (0, ModelManager_1.getModelManager)().resolveTemperature(modelPointer, modelProfile, { adapter: adapt, enableThinking });
72528
72703
  if (shouldUseCache) {
72529
- const cachedResponse = await (0, cache_1.tryGetCachedResponse)(messages, systemPromptContent, modelProfile.modelName, shouldStream, enableThinking, emitChunkEvents, signal);
72704
+ const cachedResponse = await (0, cache_1.tryGetCachedResponse)(messages, systemPromptContent, modelProfile.modelName, shouldStream, enableThinking, emitChunkEvents, signal, temperature);
72530
72705
  if (cachedResponse) {
72531
72706
  (0, logLLM_1.logLLMRequest)({ cached: true, model: modelProfile.modelName, messages });
72532
72707
  (0, logLLM_1.logLLMResponse)(cachedResponse);
72533
72708
  return cachedResponse;
72534
72709
  }
72535
72710
  }
72536
- const adapt = modelProfile.adapt || (0, adapter_1.resolveAdapter)(modelProfile.provider, modelProfile.modelName);
72537
72711
  let result2;
72538
72712
  switch (adapt) {
72539
72713
  case "anthropic":
72540
- result2 = await (0, anthropic_1.queryAnthropic)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents);
72714
+ result2 = await (0, anthropic_1.queryAnthropic)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents);
72541
72715
  break;
72542
72716
  case "openai":
72543
72717
  default:
72544
- result2 = await (0, openai_1.queryOpenAI)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents);
72718
+ result2 = await (0, openai_1.queryOpenAI)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents);
72545
72719
  break;
72546
72720
  }
72547
72721
  (0, logLLM_1.logLLMResponse)(result2);
72548
72722
  if (shouldUseCache && !signal.aborted) {
72549
72723
  const hasContent = result2.message.content.some((block) => block.type === "text" && block.text.trim().length > 0 || block.type === "tool_use");
72550
72724
  if (hasContent) {
72551
- (0, cache_1.setCachedResponse)(messages, systemPromptContent, modelProfile.modelName, result2, enableThinking);
72725
+ (0, cache_1.setCachedResponse)(messages, systemPromptContent, modelProfile.modelName, result2, enableThinking, temperature);
72552
72726
  (0, log_1.logDebug)(`LLM\u54CD\u5E94\u5DF2\u7F13\u5B58\uFF0C\u5F53\u524D\u7F13\u5B58\u6761\u76EE\u6570: ${(0, cache_1.getCacheSize)()}`);
72553
72727
  }
72554
72728
  }
@@ -109426,6 +109600,12 @@ var require_SemaEngine = __commonJS({
109426
109600
  cfg.memoryFiles = partial2.memoryFiles ?? null;
109427
109601
  if ("personaFile" in partial2)
109428
109602
  cfg.personaFile = partial2.personaFile ?? null;
109603
+ if ("modelOverrides" in partial2)
109604
+ cfg.modelOverrides = partial2.modelOverrides ?? null;
109605
+ if ("temperatureOverrides" in partial2)
109606
+ cfg.temperatureOverrides = partial2.temperatureOverrides ?? null;
109607
+ if ("thinking" in partial2)
109608
+ cfg.thinking = partial2.thinking === true;
109429
109609
  }
109430
109610
  /**
109431
109611
  * 当前 session 的 coreConfig 只读快照(= initialConfig,含运行时 mutation 结果)。
@@ -110310,6 +110490,10 @@ var require_AtomixCore = __commonJS({
110310
110490
  this.switchModel = (ModelName) => this.kernel.models.switchCurrentModel(ModelName);
110311
110491
  this.applyTaskModel = (config2) => this.kernel.models.applyTaskModelConfig(config2);
110312
110492
  this.getModelData = () => this.kernel.models.getModelData();
110493
+ this.getModelNames = () => this.kernel.models.getModelNames();
110494
+ this.getModelPointers = () => this.kernel.models.getModelPointers();
110495
+ this.getModelProfiles = () => this.kernel.models.getModelProfiles();
110496
+ this.updateModel = (name, patch) => this.kernel.models.updateModelProfile(name, patch);
110313
110497
  this.updateCoreConfByKey = (key, value) => {
110314
110498
  if (key === "customRules") {
110315
110499
  this.session.updateAssemblyConfig({ customRules: value ?? "" });
@@ -116933,7 +117117,7 @@ var require_dist4 = __commonJS({
116933
117117
  "../atomix-core/dist/index.js"(exports2) {
116934
117118
  "use strict";
116935
117119
  Object.defineProperty(exports2, "__esModule", { value: true });
116936
- 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;
117120
+ 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;
116937
117121
  var AtomixCore_1 = require_AtomixCore();
116938
117122
  Object.defineProperty(exports2, "AtomixCore", { enumerable: true, get: function() {
116939
117123
  return AtomixCore_1.AtomixCore;
@@ -116984,6 +117168,31 @@ var require_dist4 = __commonJS({
116984
117168
  Object.defineProperty(exports2, "getModelManager", { enumerable: true, get: function() {
116985
117169
  return ModelManager_1.getModelManager;
116986
117170
  } });
117171
+ var adapter_1 = require_adapter();
117172
+ Object.defineProperty(exports2, "modelForcesTemperatureOne", { enumerable: true, get: function() {
117173
+ return adapter_1.modelForcesTemperatureOne;
117174
+ } });
117175
+ Object.defineProperty(exports2, "modelRejectsTemperature", { enumerable: true, get: function() {
117176
+ return adapter_1.modelRejectsTemperature;
117177
+ } });
117178
+ Object.defineProperty(exports2, "modelTemperatureGatedByThinking", { enumerable: true, get: function() {
117179
+ return adapter_1.modelTemperatureGatedByThinking;
117180
+ } });
117181
+ Object.defineProperty(exports2, "openaiTemperatureCapability", { enumerable: true, get: function() {
117182
+ return adapter_1.openaiTemperatureCapability;
117183
+ } });
117184
+ Object.defineProperty(exports2, "isValidTemperature", { enumerable: true, get: function() {
117185
+ return adapter_1.isValidTemperature;
117186
+ } });
117187
+ Object.defineProperty(exports2, "DEFAULT_ANTHROPIC_TEMPERATURE", { enumerable: true, get: function() {
117188
+ return adapter_1.DEFAULT_ANTHROPIC_TEMPERATURE;
117189
+ } });
117190
+ Object.defineProperty(exports2, "TEMPERATURE_MIN", { enumerable: true, get: function() {
117191
+ return adapter_1.TEMPERATURE_MIN;
117192
+ } });
117193
+ Object.defineProperty(exports2, "TEMPERATURE_MAX", { enumerable: true, get: function() {
117194
+ return adapter_1.TEMPERATURE_MAX;
117195
+ } });
116987
117196
  var log_1 = require_log();
116988
117197
  Object.defineProperty(exports2, "setLogLevel", { enumerable: true, get: function() {
116989
117198
  return log_1.setLogLevel;
@@ -124390,6 +124599,63 @@ function requireRuntime(core) {
124390
124599
  function getActiveHarnessName(core) {
124391
124600
  return runtimeOf(core)?.active?.name ?? BASE_HARNESS;
124392
124601
  }
124602
+ function harnessTemperatureOverride(core) {
124603
+ return runtimeOf(core)?.active?.temperatureOverrides ?? null;
124604
+ }
124605
+ function effectiveTemperatures(core) {
124606
+ const models = effectiveModels(core);
124607
+ const profiles = core.getModelProfiles();
124608
+ const over2 = harnessTemperatureOverride(core);
124609
+ const one = (slot) => {
124610
+ const prof = profiles.find((p) => p.name === models[slot]);
124611
+ const mn = prof?.modelName;
124612
+ if (mn && (0, import_atomix_core2.modelForcesTemperatureOne)(mn)) return { value: 1, from: "fixed" };
124613
+ if (mn && (0, import_atomix_core2.modelRejectsTemperature)(mn)) return { value: null, from: "unsupported" };
124614
+ const anthropic = prof?.adapt === "anthropic";
124615
+ const gatedByThinking = anthropic || (mn ? (0, import_atomix_core2.modelTemperatureGatedByThinking)(mn) : false);
124616
+ const notes = [];
124617
+ let from = "default";
124618
+ let raw;
124619
+ const o = over2?.[slot];
124620
+ if (o !== void 0) {
124621
+ if ((0, import_atomix_core2.isValidTemperature)(o)) {
124622
+ raw = o;
124623
+ from = "harness";
124624
+ } else notes.push(`harness \u503C ${JSON.stringify(o)} \u975E\u6CD5(\u987B 0\u20132),\u5DF2\u5FFD\u7565`);
124625
+ }
124626
+ if (raw === void 0 && prof?.temperature !== void 0) {
124627
+ if ((0, import_atomix_core2.isValidTemperature)(prof.temperature)) {
124628
+ raw = prof.temperature;
124629
+ from = "profile";
124630
+ } else notes.push(`profile \u503C ${JSON.stringify(prof.temperature)} \u975E\u6CD5(\u987B 0\u20132),\u5DF2\u5FFD\u7565`);
124631
+ }
124632
+ if (raw === void 0) {
124633
+ return { value: anthropic ? import_atomix_core2.DEFAULT_ANTHROPIC_TEMPERATURE : null, from: "default", ...gatedByThinking ? { gatedByThinking } : {}, ...notes.length ? { notes } : {} };
124634
+ }
124635
+ let value = raw;
124636
+ if (anthropic && value > 1) {
124637
+ value = 1;
124638
+ notes.push(`\u58F0\u660E ${raw} \u8D85 anthropic \u534F\u8BAE\u4E0A\u9650,\u5B9E\u9645\u6309 1 \u53D1`);
124639
+ }
124640
+ return { value, from, configured: raw, ...gatedByThinking ? { gatedByThinking } : {}, ...notes.length ? { notes } : {} };
124641
+ };
124642
+ return { main: one("main"), quick: one("quick") };
124643
+ }
124644
+ function harnessModelOverride(core) {
124645
+ return runtimeOf(core)?.active?.modelOverrides ?? null;
124646
+ }
124647
+ function harnessModelFallback(core) {
124648
+ return runtimeOf(core)?.active?.modelFallback ?? null;
124649
+ }
124650
+ function effectiveModels(core) {
124651
+ const base = core.getModelPointers();
124652
+ const over2 = harnessModelOverride(core);
124653
+ const fb = harnessModelFallback(core);
124654
+ const pick2 = (slot) => over2?.[slot] ? [over2[slot], "harness"] : [base[slot], fb?.[slot] ? "fallback" : "base"];
124655
+ const [main, mainFrom] = pick2("main");
124656
+ const [quick, quickFrom] = pick2("quick");
124657
+ return { main, quick, mainFrom, quickFrom, ...fb ? { fallback: fb } : {} };
124658
+ }
124393
124659
  function recordSkillUniverse(core, names) {
124394
124660
  const rt = runtimeOf(core);
124395
124661
  if (rt) rt.fullSkillNames = names.slice();
@@ -124560,6 +124826,67 @@ function loadHarnessDoc(name) {
124560
124826
  };
124561
124827
  const memory = parseToggle(raw.memory, "memory");
124562
124828
  const persona = parseToggle(raw.persona, "persona");
124829
+ const parseModel = (v) => {
124830
+ if (v === void 0 || v === null) return null;
124831
+ if (typeof v === "string") {
124832
+ const id = v.trim();
124833
+ if (id) return { main: id, quick: id };
124834
+ toggleWarnings.push("model \u4E3A\u7A7A\u5B57\u7B26\u4E32,\u5FFD\u7565(\u89C6\u4E3A\u672A\u58F0\u660E,\u8DDF\u968F base)");
124835
+ return null;
124836
+ }
124837
+ if (typeof v === "object" && !Array.isArray(v)) {
124838
+ const o = v;
124839
+ const out = {};
124840
+ for (const slot of MODEL_SLOTS) {
124841
+ const x = o[slot];
124842
+ if (x === void 0 || x === null) continue;
124843
+ if (typeof x === "string" && x.trim()) out[slot] = x.trim();
124844
+ else toggleWarnings.push(`model.${slot} \u987B\u4E3A\u6A21\u578B\u6807\u8BC6\u5B57\u7B26\u4E32(modelName[provider]),\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(x)}`);
124845
+ }
124846
+ 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`);
124847
+ if (!out.main && !out.quick) {
124848
+ toggleWarnings.push("model \u672A\u58F0\u660E\u4EFB\u4F55\u6709\u6548\u69FD\u4F4D,\u89C6\u4E3A\u672A\u58F0\u660E(\u8DDF\u968F base)");
124849
+ return null;
124850
+ }
124851
+ return out;
124852
+ }
124853
+ toggleWarnings.push(`model \u53EA\u8BA4\u5B57\u7B26\u4E32\u6216 { main, quick },\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(v)}`);
124854
+ return null;
124855
+ };
124856
+ const model = parseModel(raw.model);
124857
+ const thinkingToggle = parseToggle(raw.thinking, "thinking");
124858
+ const thinking = thinkingToggle === null ? null : thinkingToggle === "on";
124859
+ const parseTemperature = (v) => {
124860
+ if (v === void 0 || v === null) return null;
124861
+ const num = (x, label) => {
124862
+ if ((0, import_atomix_core2.isValidTemperature)(x)) return x;
124863
+ toggleWarnings.push(`${label} \u987B\u4E3A 0\u20132 \u7684\u6570\u5B57,\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(x)}`);
124864
+ return void 0;
124865
+ };
124866
+ if (typeof v === "number") {
124867
+ const t2 = num(v, "temperature");
124868
+ return t2 === void 0 ? null : { main: t2 };
124869
+ }
124870
+ if (typeof v === "object" && !Array.isArray(v)) {
124871
+ const o = v;
124872
+ const out = {};
124873
+ for (const slot of MODEL_SLOTS) {
124874
+ const x = o[slot];
124875
+ if (x === void 0 || x === null) continue;
124876
+ const t2 = num(x, `temperature.${slot}`);
124877
+ if (t2 !== void 0) out[slot] = t2;
124878
+ }
124879
+ 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`);
124880
+ if (out.main === void 0 && out.quick === void 0) {
124881
+ toggleWarnings.push("temperature \u672A\u58F0\u660E\u4EFB\u4F55\u6709\u6548\u69FD\u4F4D,\u89C6\u4E3A\u672A\u58F0\u660E");
124882
+ return null;
124883
+ }
124884
+ return out;
124885
+ }
124886
+ toggleWarnings.push(`temperature \u53EA\u8BA4\u6570\u5B57\u6216 { main, quick },\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(v)}`);
124887
+ return null;
124888
+ };
124889
+ const temperature = parseTemperature(raw.temperature);
124563
124890
  return {
124564
124891
  name: typeof raw.name === "string" && raw.name ? raw.name : name,
124565
124892
  description: typeof raw.description === "string" ? raw.description : void 0,
@@ -124580,6 +124907,9 @@ function loadHarnessDoc(name) {
124580
124907
  memory,
124581
124908
  persona,
124582
124909
  soulPath,
124910
+ model,
124911
+ thinking,
124912
+ temperature,
124583
124913
  toggleWarnings,
124584
124914
  dir
124585
124915
  };
@@ -124595,6 +124925,14 @@ function resolveBase(ctx) {
124595
124925
  memoryFiles: ctx.baseline.memoryFiles,
124596
124926
  personaFile: ctx.baseline.personaFile,
124597
124927
  warnings: [],
124928
+ dirName: BASE_HARNESS,
124929
+ modelOverrides: null,
124930
+ modelDeclared: null,
124931
+ modelFallback: null,
124932
+ thinkingDeclared: null,
124933
+ temperatureOverrides: null,
124934
+ temperatureDeclared: null,
124935
+ thinking: ctx.baseline.thinking,
124598
124936
  skillsSpec: null,
124599
124937
  agentsSpec: null,
124600
124938
  skillsDisabled: /* @__PURE__ */ new Set(),
@@ -124645,8 +124983,49 @@ function resolveHarness(doc, ctx) {
124645
124983
  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)");
124646
124984
  personaFile = null;
124647
124985
  }
124986
+ const dirName = path2.basename(doc.dir);
124987
+ const modelOverrides = {};
124988
+ const modelFallback = {};
124989
+ if (doc.model) {
124990
+ for (const slot of MODEL_SLOTS) {
124991
+ const want = doc.model[slot];
124992
+ if (!want) continue;
124993
+ if (ctx.modelNames.includes(want)) modelOverrides[slot] = want;
124994
+ else {
124995
+ modelFallback[slot] = want;
124996
+ 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)`);
124997
+ }
124998
+ }
124999
+ }
125000
+ const temperatureOverrides = {};
125001
+ if (doc.temperature) {
125002
+ for (const slot of MODEL_SLOTS) {
125003
+ const t = doc.temperature[slot];
125004
+ if (t === void 0) continue;
125005
+ const effModel = modelOverrides[slot] ?? ctx.baseModels[slot];
125006
+ const mn = ctx.modelProfiles?.find((p) => p.name === effModel)?.modelName;
125007
+ if (mn && (0, import_atomix_core2.modelForcesTemperatureOne)(mn)) {
125008
+ 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`);
125009
+ continue;
125010
+ }
125011
+ if (mn && (0, import_atomix_core2.modelRejectsTemperature)(mn)) {
125012
+ warnings.push(`\u6E29\u5EA6\u5FFD\u7565:harness.yaml \u58F0\u660E ${slot} temperature=${t},\u4F46\u6A21\u578B ${effModel} \u4E0D\u652F\u6301 temperature \u53C2\u6570`);
125013
+ continue;
125014
+ }
125015
+ temperatureOverrides[slot] = t;
125016
+ }
125017
+ }
124648
125018
  return {
124649
125019
  name: doc.name,
125020
+ dirName,
125021
+ temperatureOverrides: Object.keys(temperatureOverrides).length ? temperatureOverrides : null,
125022
+ temperatureDeclared: doc.temperature,
125023
+ modelOverrides: Object.keys(modelOverrides).length ? modelOverrides : null,
125024
+ modelDeclared: doc.model,
125025
+ modelFallback: Object.keys(modelFallback).length ? modelFallback : null,
125026
+ // thinking:声明即下发;未声明跟随基线(基线未知则不下发该键,与 memoryFiles 同规则)
125027
+ thinkingDeclared: doc.thinking,
125028
+ thinking: doc.thinking ?? ctx.baseline.thinking,
124650
125029
  useTools,
124651
125030
  deferBuiltinTools: doc.tools.defer.length ? doc.tools.defer : ctx.baseline.deferBuiltinTools ?? [],
124652
125031
  pinnedTools: doc.tools.pin,
@@ -124671,10 +125050,13 @@ function buildContext(core) {
124671
125050
  // 缓存为空只在启动初始化时(此刻尚未过滤,直读即全集)
124672
125051
  allToolNames: core.getToolInfos().map((t) => t.name),
124673
125052
  allSkillNames: rt.fullSkillNames ?? core.getSkillsInfo({ includeDisabled: true }).map((s) => s.name),
124674
- allAgentNames: rt.fullAgentNames ?? core.getAgentsInfo().map((a) => a.name)
125053
+ allAgentNames: rt.fullAgentNames ?? core.getAgentsInfo().map((a) => a.name),
125054
+ modelNames: core.getModelNames(),
125055
+ baseModels: core.getModelPointers(),
125056
+ modelProfiles: core.getModelProfiles()
124675
125057
  };
124676
125058
  }
124677
- function applyAssembly(core, rt, r) {
125059
+ function applyAssembly(core, rt, r, opts = {}) {
124678
125060
  core.updateAssemblyConfig({
124679
125061
  useTools: r.useTools,
124680
125062
  deferBuiltinTools: r.deferBuiltinTools,
@@ -124684,11 +125066,18 @@ function applyAssembly(core, rt, r) {
124684
125066
  // null = 回默认组装(base 清场)
124685
125067
  // 基线未知(宿主没给快照)时不下发该键:传 undefined 会被 core 当 null 落,把供给层开着的注入误关
124686
125068
  ...r.memoryFiles !== void 0 ? { memoryFiles: r.memoryFiles } : {},
124687
- ...r.personaFile !== void 0 ? { personaFile: r.personaFile } : {}
125069
+ ...r.personaFile !== void 0 ? { personaFile: r.personaFile } : {},
125070
+ modelOverrides: r.modelOverrides,
125071
+ // null = 回 model.conf 指针(base 清场)
125072
+ temperatureOverrides: r.temperatureOverrides,
125073
+ // null = 回 profile / 协议默认(base 清场)
125074
+ ...!opts.preserveThinking && r.thinking !== void 0 ? { thinking: r.thinking } : {}
125075
+ // 声明 ?? 基线;只在 use/reset/启动 下发,不做热切换
124688
125076
  });
124689
125077
  rt.activeMemoryFiles = r.memoryFiles;
124690
125078
  rt.activePersonaFile = r.personaFile;
124691
- rt.active = r.name === BASE_HARNESS ? null : r;
125079
+ if (!opts.preserveThinking) rt.activeThinking = r.thinking;
125080
+ rt.active = r.dirName === BASE_HARNESS ? null : r;
124692
125081
  }
124693
125082
  function initHarness(core, cwd, base, opts = {}) {
124694
125083
  const rt = {
@@ -124697,10 +125086,12 @@ function initHarness(core, cwd, base, opts = {}) {
124697
125086
  deferBuiltinTools: base.deferBuiltinTools?.slice(),
124698
125087
  memoryFiles: base.memoryFiles,
124699
125088
  personaFile: base.personaFile,
124700
- potentialMemoryFiles: base.potentialMemoryFiles
125089
+ potentialMemoryFiles: base.potentialMemoryFiles,
125090
+ thinking: base.thinking
124701
125091
  },
124702
125092
  activeMemoryFiles: base.memoryFiles,
124703
125093
  activePersonaFile: base.personaFile,
125094
+ activeThinking: base.thinking,
124704
125095
  projectDir: cwd,
124705
125096
  active: null,
124706
125097
  overridden: opts.harness !== void 0,
@@ -124722,13 +125113,15 @@ function initHarness(core, cwd, base, opts = {}) {
124722
125113
  return `harness "${name}"(${source})\u52A0\u8F7D\u5931\u8D25,\u5DF2\u56DE\u843D base:${e instanceof Error ? e.message : e}`;
124723
125114
  }
124724
125115
  }
124725
- var import_yaml, import_atomix_core, BASE_HARNESS, runtimes;
125116
+ var import_yaml, import_atomix_core, import_atomix_core2, MODEL_SLOTS, BASE_HARNESS, runtimes;
124726
125117
  var init_harness = __esm({
124727
125118
  "src/harness.ts"() {
124728
125119
  "use strict";
124729
125120
  import_yaml = __toESM(require_dist5());
124730
125121
  import_atomix_core = __toESM(require_dist4());
125122
+ import_atomix_core2 = __toESM(require_dist4());
124731
125123
  init_paths();
125124
+ MODEL_SLOTS = ["main", "quick"];
124732
125125
  BASE_HARNESS = "base";
124733
125126
  runtimes = /* @__PURE__ */ new WeakMap();
124734
125127
  }
@@ -124739,7 +125132,7 @@ import * as fs3 from "fs";
124739
125132
  import * as path3 from "path";
124740
125133
  function getMemoryPaths(cwd) {
124741
125134
  const root3 = realpathOrSelf(getAtomixRoot());
124742
- const slug = (0, import_atomix_core2.projectPathToDirName)(cwd);
125135
+ const slug = (0, import_atomix_core3.projectPathToDirName)(cwd);
124743
125136
  const projectDir = path3.join(root3, "projects", slug);
124744
125137
  return {
124745
125138
  root: root3,
@@ -124757,11 +125150,11 @@ function realpathOrSelf(p) {
124757
125150
  return p;
124758
125151
  }
124759
125152
  }
124760
- var import_atomix_core2;
125153
+ var import_atomix_core3;
124761
125154
  var init_memoryPaths = __esm({
124762
125155
  "src/memoryPaths.ts"() {
124763
125156
  "use strict";
124764
- import_atomix_core2 = __toESM(require_dist4());
125157
+ import_atomix_core3 = __toESM(require_dist4());
124765
125158
  init_paths();
124766
125159
  }
124767
125160
  });
@@ -125446,7 +125839,7 @@ if (!process.env.ATOMIX_LLM_LOG_ROOT) {
125446
125839
  }
125447
125840
 
125448
125841
  // src/session.ts
125449
- var import_atomix_core5 = __toESM(require_dist4());
125842
+ var import_atomix_core6 = __toESM(require_dist4());
125450
125843
 
125451
125844
  // src/sessionTypes.ts
125452
125845
  var SESSION_HANDLE_BRAND = /* @__PURE__ */ Symbol.for("atomix-cli.sessionHandle");
@@ -125568,12 +125961,12 @@ async function applyMcpHotUpdates(core) {
125568
125961
  }
125569
125962
 
125570
125963
  // src/hooksLoader.ts
125571
- var import_atomix_core3 = __toESM(require_dist4());
125964
+ var import_atomix_core4 = __toESM(require_dist4());
125572
125965
  init_paths();
125573
125966
  init_marketplace();
125574
125967
  import * as fs9 from "fs";
125575
125968
  import * as path9 from "path";
125576
- var VALID_EVENTS = new Set(import_atomix_core3.HOOK_EVENTS);
125969
+ var VALID_EVENTS = new Set(import_atomix_core4.HOOK_EVENTS);
125577
125970
  function readHookFile(p) {
125578
125971
  if (!fs9.existsSync(p)) return null;
125579
125972
  try {
@@ -125635,7 +126028,7 @@ function loadHooks(cwd) {
125635
126028
  }
125636
126029
 
125637
126030
  // src/quiet.ts
125638
- var import_atomix_core4 = __toESM(require_dist4());
126031
+ var import_atomix_core5 = __toESM(require_dist4());
125639
126032
  var VALID = ["none", "debug", "info", "warn", "error"];
125640
126033
  function atomixLogLevel() {
125641
126034
  const env = process.env.ATOMIX_LOG;
@@ -125675,7 +126068,7 @@ function prepareProcess(cwd) {
125675
126068
  }
125676
126069
  function createSessionCore(opts) {
125677
126070
  const interactive = opts.interactive ?? false;
125678
- const permissionMode = opts.permissionMode ?? (interactive ? import_atomix_core5.DEFAULT_PERMISSION_MODE : "free-style");
126071
+ const permissionMode = opts.permissionMode ?? (interactive ? import_atomix_core6.DEFAULT_PERMISSION_MODE : "free-style");
125679
126072
  const notes = [];
125680
126073
  const prepNote = prepareProcess(opts.cwd);
125681
126074
  if (prepNote) notes.push(prepNote);
@@ -125683,7 +126076,7 @@ function createSessionCore(opts) {
125683
126076
  const contextFiles = buildContextFilesConfig(opts.cwd, appConfig);
125684
126077
  const hookCfg = opts.hooks ?? interactive ? loadHooks(opts.cwd) : {};
125685
126078
  const dirs = { skills: buildSkillsExtraDirs(), agents: buildAgentsExtraDirs(), commands: buildCommandsExtraDirs() };
125686
- const core = new import_atomix_core5.AtomixCore({
126079
+ const core = new import_atomix_core6.AtomixCore({
125687
126080
  workingDir: opts.cwd,
125688
126081
  logLevel: opts.logLevel ?? atomixLogLevel(),
125689
126082
  stream: opts.stream ?? interactive,
@@ -125707,7 +126100,9 @@ function createSessionCore(opts) {
125707
126100
  deferBuiltinTools: ATOMIX_DEFER_TOOLS,
125708
126101
  memoryFiles: contextFiles.memoryFiles,
125709
126102
  personaFile: contextFiles.personaFile,
125710
- potentialMemoryFiles: potential.memoryFiles
126103
+ potentialMemoryFiles: potential.memoryFiles,
126104
+ thinking: false
126105
+ // cli 构造 core 时 thinking 关;harness 未声明即回到这里
125711
126106
  };
125712
126107
  return { [SESSION_HANDLE_BRAND]: true, core, cwd: opts.cwd, interactive, permissionMode, appConfig, contextFiles, baseline, notes };
125713
126108
  }
@@ -125814,6 +126209,16 @@ var SessionImpl = class {
125814
126209
  get harness() {
125815
126210
  return getActiveHarnessName(this.core);
125816
126211
  }
126212
+ get model() {
126213
+ const m = effectiveModels(this.core);
126214
+ const t = effectiveTemperatures(this.core);
126215
+ const temperature = {};
126216
+ for (const slot of ["main", "quick"]) {
126217
+ const e = t[slot];
126218
+ if ((e.from === "harness" || e.from === "profile") && e.value !== null) temperature[slot] = e.value;
126219
+ }
126220
+ return { main: m.main, quick: m.quick, ...m.fallback ? { fallback: m.fallback } : {}, ...Object.keys(temperature).length ? { temperature } : {} };
126221
+ }
125817
126222
  on(event, listener) {
125818
126223
  this.core.on(event, listener);
125819
126224
  }
@@ -125930,7 +126335,7 @@ function attachStreamEvents(core, emit) {
125930
126335
  }
125931
126336
 
125932
126337
  // src/resume.ts
125933
- var import_atomix_core6 = __toESM(require_dist4());
126338
+ var import_atomix_core7 = __toESM(require_dist4());
125934
126339
  import * as fs10 from "fs";
125935
126340
  import * as path10 from "path";
125936
126341
  function extractText(content) {
@@ -125949,7 +126354,7 @@ function readMessages(file) {
125949
126354
  }
125950
126355
  }
125951
126356
  function listSessions(cwd) {
125952
- const dir = (0, import_atomix_core6.getProjectHistoryDir)(cwd);
126357
+ const dir = (0, import_atomix_core7.getProjectHistoryDir)(cwd);
125953
126358
  if (!fs10.existsSync(dir)) return [];
125954
126359
  const entries = [];
125955
126360
  for (const f of fs10.readdirSync(dir)) {
@@ -125974,8 +126379,8 @@ function listSessions(cwd) {
125974
126379
  init_harness();
125975
126380
 
125976
126381
  // src/permissionMode.ts
125977
- var import_atomix_core7 = __toESM(require_dist4());
125978
- var PERMISSION_MODE_ORDER = import_atomix_core7.PERMISSION_MODES;
126382
+ var import_atomix_core8 = __toESM(require_dist4());
126383
+ var PERMISSION_MODE_ORDER = import_atomix_core8.PERMISSION_MODES;
125979
126384
  function parsePermissionMode(arg) {
125980
126385
  if (!arg) return null;
125981
126386
  const norm = arg.trim().toLowerCase().replace(/[\s_-]+/g, "");
@@ -126006,7 +126411,7 @@ var listSessions2 = listSessions;
126006
126411
  var listHarnesses2 = listHarnesses;
126007
126412
  var BASE_HARNESS2 = BASE_HARNESS;
126008
126413
  var PERMISSION_MODE_ORDER2 = PERMISSION_MODE_ORDER;
126009
- var DEFAULT_PERMISSION_MODE3 = import_atomix_core7.DEFAULT_PERMISSION_MODE;
126414
+ var DEFAULT_PERMISSION_MODE3 = import_atomix_core8.DEFAULT_PERMISSION_MODE;
126010
126415
  var parsePermissionMode2 = parsePermissionMode;
126011
126416
  var getAtomixRoot2 = getAtomixRoot;
126012
126417
  export {