@clawos-dev/clawd 0.2.328 → 0.2.330

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/cli.cjs CHANGED
@@ -6714,6 +6714,10 @@ var init_persona_schemas = __esm({
6714
6714
  personaId: external_exports.string(),
6715
6715
  label: external_exports.string(),
6716
6716
  model: external_exports.string().optional(),
6717
+ // 与 model 平行的第二个 session 默认值:reasoning effort。值域跟着 tool 走
6718
+ // (claude 是 '' | low | medium | high | xhigh | max,codex 是 per-model 档位),
6719
+ // 协议层保持 string,由消费侧按 capabilities 收窄。
6720
+ effort: external_exports.string().optional(),
6717
6721
  public: external_exports.boolean(),
6718
6722
  // 8-key set defined UI-side in `lib/session-icons.ts`; protocol stays plain string
6719
6723
  // for forward compatibility, consumer fallbacks to default when key not found.
@@ -6779,6 +6783,7 @@ var init_persona_schemas = __esm({
6779
6783
  label: external_exports.string().min(1),
6780
6784
  personality: external_exports.string(),
6781
6785
  model: external_exports.string().optional(),
6786
+ effort: external_exports.string().optional(),
6782
6787
  tool: external_exports.string().optional(),
6783
6788
  public: external_exports.boolean().optional(),
6784
6789
  iconKey: external_exports.string().optional()
@@ -6791,6 +6796,7 @@ var init_persona_schemas = __esm({
6791
6796
  patch: external_exports.object({
6792
6797
  label: external_exports.string().min(1).optional(),
6793
6798
  model: external_exports.string().optional(),
6799
+ effort: external_exports.string().optional(),
6794
6800
  tool: external_exports.string().optional(),
6795
6801
  personality: external_exports.string().optional(),
6796
6802
  public: external_exports.boolean().optional(),
@@ -15023,17 +15029,12 @@ var init_claude = __esm({
15023
15029
  };
15024
15030
  CLAUDE_MODEL_IDS = ["opus", "fable", "sonnet", "haiku"];
15025
15031
  CLAUDE_MODELS = [
15026
- // label 不写 'Default':那个词没告诉用户任何事。这一项的语义是「不传 --model」,
15027
- // 说清楚谁来决定即可(真实落到哪个模型由 UI 用 session.resolvedModel 补充显示)。
15028
- { id: "", label: "\u7531 CC \u51B3\u5B9A", description: "\u4E0D\u6307\u5B9A\u6A21\u578B\uFF0C\u7528 Claude Code \u81EA\u8EAB\u914D\u7F6E\u7684\u90A3\u4E2A", contextWindowSize: 1e6, default: true },
15029
- { id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6 },
15032
+ { id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6, default: true },
15030
15033
  { id: "fable", label: "Fable", contextWindowSize: 1e6 },
15031
15034
  { id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize: 1e6 },
15032
15035
  { id: "haiku", label: "Haiku", description: "Fastest, lightest", contextWindowSize: 1e6 }
15033
15036
  ];
15034
- _assertModelIdsAligned = CLAUDE_MODELS.filter(
15035
- (m2) => m2.id !== ""
15036
- ).map((m2) => m2.id);
15037
+ _assertModelIdsAligned = CLAUDE_MODELS.map((m2) => m2.id);
15037
15038
  CLAUDE_PERMISSION_MODES = [
15038
15039
  // 与 codex 的 'Ask for approval' 同义同名——同一个概念两个 tool 别叫两个名字
15039
15040
  { id: "", label: "Ask for approval", description: "\u6BCF\u4E2A\u5DE5\u5177\u8C03\u7528\u90FD\u8981\u4F60\u70B9\u540C\u610F" },
@@ -15053,7 +15054,7 @@ var init_claude = __esm({
15053
15054
  label: "Model",
15054
15055
  scope: "core",
15055
15056
  options: CLAUDE_MODELS.map((m2) => ({ value: m2.id, label: m2.label, description: m2.description })),
15056
- default: ""
15057
+ default: "opus"
15057
15058
  },
15058
15059
  {
15059
15060
  name: "permissionMode",
@@ -15070,16 +15071,17 @@ var init_claude = __esm({
15070
15071
  description: "Reasoning effort level",
15071
15072
  scope: "tool-specific",
15072
15073
  // CC `--effort` 值域(claude --help, 2.1.187):low / medium / high / xhigh / max。
15073
- // '' = 不传 --effort,用 CLI 默认。
15074
+ // 2026-08-12:删掉 '' 项(理由同 CLAUDE_MODELS)。default high —— CC 出厂默认虽是
15075
+ // xhigh,但不传 --effort 时实际生效的是 ~/.claude/settings.json 的 effortLevel,
15076
+ // 而它的常见值就是 high;用 high 作 persona 补齐值对既有会话行为最中性。
15074
15077
  options: [
15075
- { value: "", label: "\u7531 CC \u51B3\u5B9A", description: "\u4E0D\u6307\u5B9A\u5F3A\u5EA6\uFF0C\u7528 Claude Code \u81EA\u8EAB\u7684\u9ED8\u8BA4\u6863" },
15076
15078
  { value: "low", label: "Low" },
15077
15079
  { value: "medium", label: "Medium" },
15078
15080
  { value: "high", label: "High" },
15079
15081
  { value: "xhigh", label: "Extra high" },
15080
15082
  { value: "max", label: "Max" }
15081
15083
  ],
15082
- default: ""
15084
+ default: "high"
15083
15085
  }
15084
15086
  ]
15085
15087
  };
@@ -45736,6 +45738,13 @@ function compressFrameForWire(frame) {
45736
45738
  status: compressed
45737
45739
  };
45738
45740
  }
45741
+ function personaDefaultFields(defaults, modelOverride) {
45742
+ const model = modelOverride ?? defaults?.model;
45743
+ return {
45744
+ ...model ? { model } : {},
45745
+ ...defaults?.effort ? { effort: defaults.effort } : {}
45746
+ };
45747
+ }
45739
45748
  function nowIso2(deps) {
45740
45749
  return new Date((deps.now ?? Date.now)()).toISOString();
45741
45750
  }
@@ -47210,12 +47219,13 @@ var SessionManager = class {
47210
47219
  };
47211
47220
  const cwd = import_node_path9.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
47212
47221
  const now = (/* @__PURE__ */ new Date()).toISOString();
47222
+ const personaDefaults = this.deps.getPersonaDefaults?.(args.targetPersona);
47213
47223
  const file = {
47214
47224
  sessionId,
47215
47225
  cwd,
47216
47226
  // dispatch B session 跟随 persona 绑定的 tool(codex persona 用 codex spawn),
47217
47227
  // 与 UI 手建路径(handlers/session.ts create 的 persona.tool 优先)同语义
47218
- tool: this.deps.getPersonaTool?.(args.targetPersona) ?? "claude",
47228
+ tool: personaDefaults?.tool ?? "claude",
47219
47229
  ownerPersonaId: args.targetPersona,
47220
47230
  dispatchedFromSessionId: args.sourceSessionId,
47221
47231
  // 跨设备显示关键(spec §8):creatorPrincipalId = A 的 deviceId,让 A 的
@@ -47227,8 +47237,9 @@ var SessionManager = class {
47227
47237
  // T-31: A 的飞书 union_id stamp 到 B 的 SessionFile;guest meta 由 newRunner 派生
47228
47238
  ...args.guestFeishuUnionId ? { creatorFeishuUnionId: args.guestFeishuUnionId } : {}
47229
47239
  } : {},
47230
- // T-20dispatch model override 落盘(reducer spawn 路径读 SessionFile.model 生成 --model flag)
47231
- ...args.model ? { model: args.model } : {},
47240
+ // T-20dispatch model override 优先;缺省回落 persona 默认值(spec 2026-08-12)。
47241
+ // effort 没有 override 参数(续派也不允许改),直接取 persona 默认值。
47242
+ ...personaDefaultFields(personaDefaults, args.model),
47232
47243
  // butler 顶部入口:dispatch 传下来的 label 落盘,sidebar 显示(否则兜底 cwd-basename)
47233
47244
  ...args.label ? { label: args.label } : {},
47234
47245
  createdAt: now,
@@ -47304,12 +47315,15 @@ var SessionManager = class {
47304
47315
  };
47305
47316
  const cwd = import_node_path9.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
47306
47317
  const now = (/* @__PURE__ */ new Date()).toISOString();
47318
+ const personaDefaults = this.deps.getPersonaDefaults?.(args.targetPersona);
47307
47319
  const file = {
47308
47320
  sessionId,
47309
47321
  cwd,
47310
47322
  // shift 定时 spawn 同样跟随 persona 绑定 tool(对齐 dispatch B session)
47311
- tool: this.deps.getPersonaTool?.(args.targetPersona) ?? "claude",
47323
+ tool: personaDefaults?.tool ?? "claude",
47312
47324
  ownerPersonaId: args.targetPersona,
47325
+ // persona 绑定的 model / effort 快照进 SessionFile(spec 2026-08-12)
47326
+ ...personaDefaultFields(personaDefaults),
47313
47327
  ...args.sourceSessionId ? { shiftFiredFromSessionId: args.sourceSessionId } : {},
47314
47328
  createdAt: now,
47315
47329
  updatedAt: now
@@ -47400,11 +47414,15 @@ var SessionManager = class {
47400
47414
  let file = store.list().find((f) => f.larkChatId === args.chatId);
47401
47415
  if (!file) {
47402
47416
  const now = (/* @__PURE__ */ new Date()).toISOString();
47417
+ const personaDefaults = this.deps.getPersonaDefaults?.(args.personaId);
47403
47418
  file = {
47404
47419
  sessionId: newSessionId(),
47405
47420
  cwd: import_node_path9.default.join(this.deps.personaRoot, safeFileName(args.personaId)),
47406
- tool: this.deps.getPersonaTool?.(args.personaId) ?? "claude",
47421
+ tool: personaDefaults?.tool ?? "claude",
47407
47422
  ownerPersonaId: args.personaId,
47423
+ // persona 绑定的 model / effort 快照进 SessionFile(spec 2026-08-12)——
47424
+ // 飞书里跟 persona 聊天用的模型,与 UI 里给它配的一致
47425
+ ...personaDefaultFields(personaDefaults),
47408
47426
  // guest 三件套:creatorPrincipalId=capId(scopeForFile 回落防线)、
47409
47427
  // creatorDisplayName(reducer guest 分支硬性要求,缺则 spawn 抛)
47410
47428
  creatorPrincipalId: capId,
@@ -48460,6 +48478,11 @@ var PersonaManager = class {
48460
48478
  personaId: personaId2,
48461
48479
  label: args.label,
48462
48480
  model: args.model,
48481
+ // effort 兜底 high:persona 一律持有具体档位(spec 2026-08-12),UI 会带界面上高亮的
48482
+ // 那一档,但 persona:create 也可能来自 butler 的 persona-authoring skill 这类不带该
48483
+ // 字段的调用方——不兜的话要等下次 daemon 启动 backfill 才补上,中间建的 session 就漏了。
48484
+ // 取值理由与 backfillPersonaSessionDefaults 一致(见那里的注释)。
48485
+ effort: args.effort ?? "high",
48463
48486
  tool: args.tool,
48464
48487
  public: args.public ?? false,
48465
48488
  iconKey: args.iconKey,
@@ -48479,6 +48502,11 @@ var PersonaManager = class {
48479
48502
  ...restPatch,
48480
48503
  updatedAt: Date.now()
48481
48504
  };
48505
+ const toolChanged = patch.tool !== void 0 && (patch.tool ?? "claude") !== (existing.tool ?? "claude");
48506
+ if (toolChanged) {
48507
+ if (patch.model === void 0) delete updated.model;
48508
+ if (patch.effort === void 0) delete updated.effort;
48509
+ }
48482
48510
  if (iconKeyPatch === null) {
48483
48511
  delete updated.iconKey;
48484
48512
  } else if (iconKeyPatch !== void 0) {
@@ -48535,6 +48563,7 @@ var DEFAULT_PERSONAS = [
48535
48563
  personaId: "persona-researcher",
48536
48564
  label: "\u8C03\u7814\u5458",
48537
48565
  model: "opus",
48566
+ effort: "high",
48538
48567
  iconKey: "research",
48539
48568
  public: false,
48540
48569
  sandboxProfile: DEFAULT_BYPASS_PROFILE
@@ -48543,6 +48572,7 @@ var DEFAULT_PERSONAS = [
48543
48572
  personaId: "persona-knowledge-base",
48544
48573
  label: "\u77E5\u8BC6\u5E93\u7BA1\u7406\u5458",
48545
48574
  model: "opus",
48575
+ effort: "high",
48546
48576
  iconKey: "reading",
48547
48577
  public: false,
48548
48578
  sandboxProfile: DEFAULT_BYPASS_PROFILE
@@ -48558,6 +48588,7 @@ var DEFAULT_PERSONAS = [
48558
48588
  personaId: "persona-clawd-butler",
48559
48589
  label: "clawd \u7BA1\u5BB6",
48560
48590
  model: "opus",
48591
+ effort: "high",
48561
48592
  iconKey: "assist",
48562
48593
  public: false,
48563
48594
  sandboxProfile: DEFAULT_BYPASS_PROFILE
@@ -48566,6 +48597,7 @@ var DEFAULT_PERSONAS = [
48566
48597
  personaId: "persona-feishu-assistant",
48567
48598
  label: "\u98DE\u4E66\u52A9\u7406",
48568
48599
  model: "opus",
48600
+ effort: "high",
48569
48601
  iconKey: "assist",
48570
48602
  public: false,
48571
48603
  sandboxProfile: DEFAULT_BYPASS_PROFILE
@@ -48577,6 +48609,7 @@ var DEFAULT_PERSONAS = [
48577
48609
  personaId: "persona-app-builder",
48578
48610
  label: "App Builder",
48579
48611
  model: "opus",
48612
+ effort: "high",
48580
48613
  iconKey: "assist",
48581
48614
  public: false,
48582
48615
  // 开发型 profile:在最严格 base(已含 Bash+文件工具)上追加 web 工具 + node/pnpm 工具链精确路径
@@ -48620,6 +48653,7 @@ var DEFAULT_PERSONAS = [
48620
48653
  personaId: "persona-dataclaw-builder",
48621
48654
  label: "\u6570\u636E\u67E5\u8BE2\u642D\u5EFA\u5E08",
48622
48655
  model: "opus",
48656
+ effort: "high",
48623
48657
  iconKey: "assist",
48624
48658
  public: false,
48625
48659
  // 同 app-builder 的开发型 profile(逐字段照抄):web 工具 + node/pnpm 工具链精确路径
@@ -48653,6 +48687,7 @@ var DEFAULT_PERSONAS = [
48653
48687
  personaId: "persona-html-slides",
48654
48688
  label: "HTML PPT \u5236\u4F5C\u5E08",
48655
48689
  model: "opus",
48690
+ effort: "high",
48656
48691
  iconKey: "doc",
48657
48692
  public: false,
48658
48693
  // 与 app-builder 对齐"调用阿里云的工作方式"(owner 2026-06-17 要求):开发型 profile —— 放开文件/web
@@ -48751,6 +48786,7 @@ function seedDefaultPersonas(args) {
48751
48786
  personaId: entry.personaId,
48752
48787
  label: entry.label,
48753
48788
  model: entry.model,
48789
+ effort: entry.effort,
48754
48790
  public: entry.public,
48755
48791
  iconKey: entry.iconKey,
48756
48792
  createdAt: now,
@@ -48873,6 +48909,43 @@ function migrateCodexSandbox(args) {
48873
48909
  }
48874
48910
  if (n > 0) args.logger.info("persona.codex-sandbox.done", { migrated: n });
48875
48911
  }
48912
+ function backfillPersonaSessionDefaults(args) {
48913
+ let n = 0;
48914
+ let codexDefault;
48915
+ let codexResolved = false;
48916
+ for (const personaId2 of args.store.list()) {
48917
+ try {
48918
+ const persona = args.store.read(personaId2);
48919
+ if (!persona) continue;
48920
+ const patch = {};
48921
+ const isClaude = (persona.tool ?? "claude") === "claude";
48922
+ if (!persona.model) {
48923
+ if (isClaude) {
48924
+ patch.model = "opus";
48925
+ } else {
48926
+ if (!codexResolved) {
48927
+ codexDefault = args.resolveCodexDefaultModel?.();
48928
+ codexResolved = true;
48929
+ }
48930
+ if (codexDefault) patch.model = codexDefault;
48931
+ }
48932
+ }
48933
+ if (!persona.effort) patch.effort = "high";
48934
+ if (Object.keys(patch).length === 0) continue;
48935
+ const updated = { ...persona, ...patch };
48936
+ args.store.writeMeta(updated);
48937
+ args.registry?.set(updated);
48938
+ n++;
48939
+ args.logger.info("persona.session-defaults.backfilled", { personaId: personaId2, ...patch });
48940
+ } catch (err) {
48941
+ args.logger.warn("persona.session-defaults.backfill-failed", {
48942
+ personaId: personaId2,
48943
+ error: err instanceof Error ? err.message : String(err)
48944
+ });
48945
+ }
48946
+ }
48947
+ if (n > 0) args.logger.info("persona.session-defaults.done", { backfilled: n });
48948
+ }
48876
48949
  function migrateSandboxAllowRead(args) {
48877
48950
  let n = 0;
48878
48951
  for (const personaId2 of args.store.list()) {
@@ -49834,7 +49907,7 @@ function mapModelList(raw) {
49834
49907
  if (!raw || typeof raw !== "object") throw new Error("model/list: response is not an object");
49835
49908
  const data = raw.data;
49836
49909
  if (!Array.isArray(data)) throw new Error("model/list: `data` is not an array");
49837
- const models = [CODEX_DEFAULT_MODEL_ENTRY];
49910
+ const models = [];
49838
49911
  for (const item of data) {
49839
49912
  if (!item || typeof item !== "object") throw new Error("model/list: entry is not an object");
49840
49913
  const e = item;
@@ -49854,6 +49927,10 @@ function mapModelList(raw) {
49854
49927
  ...typeof e.description === "string" ? { description: e.description } : {},
49855
49928
  contextWindowSize: CODEX_CONTEXT_WINDOW,
49856
49929
  ...efforts && efforts.length > 0 ? { efforts } : {},
49930
+ // codex 自己标的默认型号。以前空项占着 default:true,这个字段一直没人读;
49931
+ // 空项删掉后它是「哪个是默认」的唯一权威来源——新建 persona 的预选、
49932
+ // backfill 补 codex model 都依赖它。
49933
+ ...e.isDefault === true ? { default: true } : {},
49857
49934
  ...typeof e.defaultReasoningEffort === "string" ? { defaultEffort: e.defaultReasoningEffort } : {}
49858
49935
  });
49859
49936
  }
@@ -52932,7 +53009,7 @@ function buildPersonaDispatchHandlers(deps) {
52932
53009
  const args = DispatchRunArgsSchema.parse(rest);
52933
53010
  if (args.model !== void 0) {
52934
53011
  const targetPersona2 = args.targetPersona ?? (args.dispatchId ? deps.store.get(args.dispatchId)?.targetPersonaId : void 0);
52935
- const targetTool = (targetPersona2 ? deps.getPersonaTool?.(targetPersona2) : void 0) ?? "claude";
53012
+ const targetTool = (targetPersona2 ? deps.getPersonaDefaults?.(targetPersona2)?.tool : void 0) ?? "claude";
52936
53013
  const allowed = targetTool === "codex" ? ((await deps.getCapabilities?.("codex"))?.models ?? []).map((m2) => m2.id).filter((id) => id !== "") : CLAUDE_MODEL_IDS;
52937
53014
  if (!allowed.includes(args.model)) {
52938
53015
  throw new ClawdError(
@@ -58266,19 +58343,23 @@ function buildSessionHandlers(deps) {
58266
58343
  const create = async (frame, _client, ctx) => {
58267
58344
  const args = SessionCreateArgs.parse(frame);
58268
58345
  let tool = args.tool;
58346
+ let model = args.model;
58347
+ let effort = args.effort;
58269
58348
  if (args.ownerPersonaId) {
58270
58349
  const persona = deps.personaRegistry.get(args.ownerPersonaId);
58271
58350
  if (!persona) {
58272
58351
  throw new Error(`persona not found: ${args.ownerPersonaId}`);
58273
58352
  }
58274
58353
  tool = persona.tool ?? args.tool;
58354
+ model = args.model ?? persona.model;
58355
+ effort = args.effort ?? persona.effort;
58275
58356
  }
58276
58357
  ensurePersonaAccess(ctx, args.ownerPersonaId, "send");
58277
58358
  const creatorPrincipalId = ctx?.principal.id ?? ownerPrincipalId;
58278
58359
  const creatorDisplayName = ctx?.principal.displayName ?? "Owner";
58279
58360
  const creatorFeishuUnionId = ctx?.principal.feishuUnionId;
58280
58361
  const { response, broadcast } = manager.create(
58281
- { ...args, tool },
58362
+ { ...args, tool, model, effort },
58282
58363
  creatorPrincipalId,
58283
58364
  creatorDisplayName,
58284
58365
  creatorFeishuUnionId
@@ -59990,7 +60071,7 @@ function computeMethodAccess(args) {
59990
60071
  }
59991
60072
 
59992
60073
  // src/version.ts
59993
- var version = "0.2.328".length > 0 ? "0.2.328" : "dev";
60074
+ var version = "0.2.330".length > 0 ? "0.2.330" : "dev";
59994
60075
 
59995
60076
  // src/cli-probe/probe.ts
59996
60077
  var fs59 = __toESM(require("fs"), 1);
@@ -63628,6 +63709,7 @@ async function startDaemon(config) {
63628
63709
  migrateAgentsMirror({ store: personaStore, logger });
63629
63710
  migrateCodexSandbox({ store: personaStore, logger });
63630
63711
  migrateSandboxAllowRead({ store: personaStore, logger });
63712
+ backfillPersonaSessionDefaults({ store: personaStore, logger });
63631
63713
  retirePersonaBuilder({ store: personaStore, logger });
63632
63714
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
63633
63715
  const dispatchStore = createDispatchStore({
@@ -63830,7 +63912,7 @@ async function startDaemon(config) {
63830
63912
  personaRoot: import_node_path67.default.join(config.dataDir, "personas"),
63831
63913
  // dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
63832
63914
  // personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
63833
- getPersonaTool: (personaId2) => personaRegistry.get(personaId2)?.tool,
63915
+ getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
63834
63916
  usersRoot,
63835
63917
  personaStore,
63836
63918
  ownerDisplayName,
@@ -63966,6 +64048,18 @@ async function startDaemon(config) {
63966
64048
  registerAdapter("codex", new CodexAdapter({ logger, historyReader: new CodexHistoryReader() }));
63967
64049
  warmCodexFeatureCache();
63968
64050
  const personaRegistry = new PersonaRegistry(personaStore);
64051
+ void getAdapter("codex").capabilities().then((caps) => {
64052
+ const defaultModel = caps.models.find((m2) => m2.default)?.id;
64053
+ if (!defaultModel) return;
64054
+ backfillPersonaSessionDefaults({
64055
+ store: personaStore,
64056
+ registry: personaRegistry,
64057
+ logger,
64058
+ resolveCodexDefaultModel: () => defaultModel
64059
+ });
64060
+ }).catch((err) => {
64061
+ logger.debug("codex persona model backfill skipped", { error: err.message });
64062
+ });
63969
64063
  const personaManager = new PersonaManager({
63970
64064
  store: personaStore,
63971
64065
  registry: personaRegistry,
@@ -64357,7 +64451,7 @@ async function startDaemon(config) {
64357
64451
  // B 角色:判断 targetPersona 是否 public(跨设备授权边界,private 拒)。
64358
64452
  getPersonaPublic: (personaId2) => personaRegistry.get(personaId2)?.public ?? false,
64359
64453
  // model 校验按 target persona 绑定 tool 选来源(claude / codex 模型集不同)
64360
- getPersonaTool: (personaId2) => personaRegistry.get(personaId2)?.tool,
64454
+ getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
64361
64455
  // codex 模型表是运行时查 model/list 来的,校验必须问 capabilities(manager 侧有进程级缓存)
64362
64456
  getCapabilities: (tool) => manager.getCapabilities(tool)
64363
64457
  });
@@ -21892,6 +21892,10 @@ var PersonaFileSchema = external_exports.object({
21892
21892
  personaId: external_exports.string(),
21893
21893
  label: external_exports.string(),
21894
21894
  model: external_exports.string().optional(),
21895
+ // 与 model 平行的第二个 session 默认值:reasoning effort。值域跟着 tool 走
21896
+ // (claude 是 '' | low | medium | high | xhigh | max,codex 是 per-model 档位),
21897
+ // 协议层保持 string,由消费侧按 capabilities 收窄。
21898
+ effort: external_exports.string().optional(),
21895
21899
  public: external_exports.boolean(),
21896
21900
  // 8-key set defined UI-side in `lib/session-icons.ts`; protocol stays plain string
21897
21901
  // for forward compatibility, consumer fallbacks to default when key not found.
@@ -21957,6 +21961,7 @@ var PersonaCreateArgsSchema = external_exports.object({
21957
21961
  label: external_exports.string().min(1),
21958
21962
  personality: external_exports.string(),
21959
21963
  model: external_exports.string().optional(),
21964
+ effort: external_exports.string().optional(),
21960
21965
  tool: external_exports.string().optional(),
21961
21966
  public: external_exports.boolean().optional(),
21962
21967
  iconKey: external_exports.string().optional()
@@ -21969,6 +21974,7 @@ var PersonaUpdateArgsSchema = external_exports.object({
21969
21974
  patch: external_exports.object({
21970
21975
  label: external_exports.string().min(1).optional(),
21971
21976
  model: external_exports.string().optional(),
21977
+ effort: external_exports.string().optional(),
21972
21978
  tool: external_exports.string().optional(),
21973
21979
  personality: external_exports.string().optional(),
21974
21980
  public: external_exports.boolean().optional(),
@@ -24184,17 +24190,12 @@ arrayDiff.join = arrayDiff.removeEmpty = function(value) {
24184
24190
  // src/tools/claude.ts
24185
24191
  var CLAUDE_MODEL_IDS = ["opus", "fable", "sonnet", "haiku"];
24186
24192
  var CLAUDE_MODELS = [
24187
- // label 不写 'Default':那个词没告诉用户任何事。这一项的语义是「不传 --model」,
24188
- // 说清楚谁来决定即可(真实落到哪个模型由 UI 用 session.resolvedModel 补充显示)。
24189
- { id: "", label: "\u7531 CC \u51B3\u5B9A", description: "\u4E0D\u6307\u5B9A\u6A21\u578B\uFF0C\u7528 Claude Code \u81EA\u8EAB\u914D\u7F6E\u7684\u90A3\u4E2A", contextWindowSize: 1e6, default: true },
24190
- { id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6 },
24193
+ { id: "opus", label: "Opus", description: "Most capable", contextWindowSize: 1e6, default: true },
24191
24194
  { id: "fable", label: "Fable", contextWindowSize: 1e6 },
24192
24195
  { id: "sonnet", label: "Sonnet", description: "Fast, balanced", contextWindowSize: 1e6 },
24193
24196
  { id: "haiku", label: "Haiku", description: "Fastest, lightest", contextWindowSize: 1e6 }
24194
24197
  ];
24195
- var _assertModelIdsAligned = CLAUDE_MODELS.filter(
24196
- (m) => m.id !== ""
24197
- ).map((m) => m.id);
24198
+ var _assertModelIdsAligned = CLAUDE_MODELS.map((m) => m.id);
24198
24199
  var CLAUDE_PERMISSION_MODES = [
24199
24200
  // 与 codex 的 'Ask for approval' 同义同名——同一个概念两个 tool 别叫两个名字
24200
24201
  { id: "", label: "Ask for approval", description: "\u6BCF\u4E2A\u5DE5\u5177\u8C03\u7528\u90FD\u8981\u4F60\u70B9\u540C\u610F" },
@@ -24214,7 +24215,7 @@ var CLAUDE_CAPABILITIES = {
24214
24215
  label: "Model",
24215
24216
  scope: "core",
24216
24217
  options: CLAUDE_MODELS.map((m) => ({ value: m.id, label: m.label, description: m.description })),
24217
- default: ""
24218
+ default: "opus"
24218
24219
  },
24219
24220
  {
24220
24221
  name: "permissionMode",
@@ -24231,16 +24232,17 @@ var CLAUDE_CAPABILITIES = {
24231
24232
  description: "Reasoning effort level",
24232
24233
  scope: "tool-specific",
24233
24234
  // CC `--effort` 值域(claude --help, 2.1.187):low / medium / high / xhigh / max。
24234
- // '' = 不传 --effort,用 CLI 默认。
24235
+ // 2026-08-12:删掉 '' 项(理由同 CLAUDE_MODELS)。default high —— CC 出厂默认虽是
24236
+ // xhigh,但不传 --effort 时实际生效的是 ~/.claude/settings.json 的 effortLevel,
24237
+ // 而它的常见值就是 high;用 high 作 persona 补齐值对既有会话行为最中性。
24235
24238
  options: [
24236
- { value: "", label: "\u7531 CC \u51B3\u5B9A", description: "\u4E0D\u6307\u5B9A\u5F3A\u5EA6\uFF0C\u7528 Claude Code \u81EA\u8EAB\u7684\u9ED8\u8BA4\u6863" },
24237
24239
  { value: "low", label: "Low" },
24238
24240
  { value: "medium", label: "Medium" },
24239
24241
  { value: "high", label: "High" },
24240
24242
  { value: "xhigh", label: "Extra high" },
24241
24243
  { value: "max", label: "Max" }
24242
24244
  ],
24243
- default: ""
24245
+ default: "high"
24244
24246
  }
24245
24247
  ]
24246
24248
  };