chatlab-cli 0.22.1 → 0.23.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.
Files changed (76) hide show
  1. package/dist/{chunk-OC2W5Q5T.mjs → chunk-3MX7VF2B.mjs} +2 -2
  2. package/dist/chunk-5ADKYYNA.mjs +28 -0
  3. package/dist/chunk-5ADKYYNA.mjs.map +1 -0
  4. package/dist/{chunk-QRC3RSER.mjs → chunk-643S2N2U.mjs} +2 -2
  5. package/dist/{chunk-XPBPKH6B.mjs → chunk-D2BR3MFN.mjs} +107 -37
  6. package/dist/chunk-D2BR3MFN.mjs.map +1 -0
  7. package/dist/{chunk-6NB475AA.mjs → chunk-FJ35V3TE.mjs} +2 -17
  8. package/dist/chunk-FJ35V3TE.mjs.map +1 -0
  9. package/dist/{chunk-SQKT45MM.mjs → chunk-G7Q7EQ3V.mjs} +546 -84
  10. package/dist/chunk-G7Q7EQ3V.mjs.map +1 -0
  11. package/dist/{chunk-LZ3W6NS5.mjs → chunk-NTWDG52H.mjs} +66 -68
  12. package/dist/chunk-NTWDG52H.mjs.map +1 -0
  13. package/dist/{chunk-Z2LYMKCC.mjs → chunk-WTQ7LAZR.mjs} +2 -2
  14. package/dist/cli.mjs +4 -3
  15. package/dist/{http-O5P4BYXU.mjs → http-2DN3XOXO.mjs} +8 -7
  16. package/dist/{import-BDLL3DG7.mjs → import-LCBSBLYF.mjs} +4 -4
  17. package/dist/index.mjs +10 -9
  18. package/dist/{mcp-L2TPZFE7.mjs → mcp-AR7HBIK4.mjs} +8 -6
  19. package/dist/{mcp-L2TPZFE7.mjs.map → mcp-AR7HBIK4.mjs.map} +1 -1
  20. package/dist/service-WNEVPQ4N.mjs +258 -0
  21. package/dist/service-WNEVPQ4N.mjs.map +1 -0
  22. package/dist/{src-FVJL5ENA.mjs → src-EGXULYFQ.mjs} +2 -2
  23. package/dist/{stream-import-ZTEW3YVL.mjs → stream-import-QM5R5FDG.mjs} +3 -3
  24. package/dist/{update-checker-MQMQ6A4B.mjs → update-checker-JG5K67O2.mjs} +3 -2
  25. package/dist/{update-checker-MQMQ6A4B.mjs.map → update-checker-JG5K67O2.mjs.map} +1 -1
  26. package/dist-web/assets/{DebugToolsPanel-DkbsB6lr.css → DebugToolsPanel-D9O_4J04.css} +1 -1
  27. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-hp9Mjpub.js +161 -0
  28. package/dist-web/assets/{EChartWordcloud-Ubal_aYg.js → EChartWordcloud-Cenbzcyj.js} +1 -1
  29. package/dist-web/assets/MessageExportModal-CvocO88D.js +1 -0
  30. package/dist-web/assets/electron-DpE69lO4.js +1 -0
  31. package/dist-web/assets/electron-SyPZX9OU.js +1 -0
  32. package/dist-web/assets/{fetch-BS4SlQjA.js → fetch-B7OBmANJ.js} +1 -1
  33. package/dist-web/assets/{fetch-o5NJ2uWE.js → fetch-BikSxuED.js} +1 -1
  34. package/dist-web/assets/fetch-BwMZFwbF.js +1 -0
  35. package/dist-web/assets/fetch-CfTcWxqG.js +1 -0
  36. package/dist-web/assets/fetch-DTP8Q782.js +17 -0
  37. package/dist-web/assets/{fetch-W43zfemj.js → fetch-LBHcBBkv.js} +1 -1
  38. package/dist-web/assets/http-C741fIwb.js +1 -0
  39. package/dist-web/assets/index-B6dkyIiA.js +2 -0
  40. package/dist-web/assets/index-CALU1QPF.js +163 -0
  41. package/dist-web/assets/{index-DOwQB7In.js → index-CHkXbqMb.js} +1 -1
  42. package/dist-web/assets/{index-DSpvXged.css → index-CvuHOeoU.css} +1 -1
  43. package/dist-web/assets/{index-BE64tUWq.css → index-CxMP0DNd.css} +1 -1
  44. package/dist-web/assets/index-DOS5o2_H.js +7 -0
  45. package/dist-web/assets/{index-CbQMfheg.css → index-DuepdDzz.css} +1 -1
  46. package/dist-web/assets/index-niwrSprs.js +173 -0
  47. package/dist-web/assets/model-catalog-DUuKjIVU.js +1 -0
  48. package/dist-web/assets/{vendor-nuxt-ui-7OAuiz_i.js → vendor-nuxt-ui-CuCZ1aRl.js} +2 -2
  49. package/dist-web/assets/vendor-reka-ui-BrTYuIfH.js +11 -0
  50. package/dist-web/assets/{web-Cx5APyCN.js → web-DGd63PrV.js} +1 -1
  51. package/dist-web/index.html +4 -4
  52. package/package.json +1 -1
  53. package/dist/chunk-6NB475AA.mjs.map +0 -1
  54. package/dist/chunk-LZ3W6NS5.mjs.map +0 -1
  55. package/dist/chunk-SQKT45MM.mjs.map +0 -1
  56. package/dist/chunk-XPBPKH6B.mjs.map +0 -1
  57. package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-CqacsKDU.js +0 -147
  58. package/dist-web/assets/MessageExportModal-D1GY6WSV.js +0 -1
  59. package/dist-web/assets/electron-8qi0d92j.js +0 -1
  60. package/dist-web/assets/electron-CsUM2O_Y.js +0 -1
  61. package/dist-web/assets/fetch-BOogCPfg.js +0 -1
  62. package/dist-web/assets/fetch-CclRWOHf.js +0 -1
  63. package/dist-web/assets/fetch-CxwnEEqk.js +0 -17
  64. package/dist-web/assets/http-CeXMt-Fv.js +0 -1
  65. package/dist-web/assets/index-CM29Kc4p.js +0 -173
  66. package/dist-web/assets/index-D183wYuz.js +0 -7
  67. package/dist-web/assets/index-DTxRy2FH.js +0 -163
  68. package/dist-web/assets/index-grds3iG-.js +0 -2
  69. package/dist-web/assets/vendor-reka-ui-CW2cIgMu.js +0 -11
  70. /package/dist/{chunk-OC2W5Q5T.mjs.map → chunk-3MX7VF2B.mjs.map} +0 -0
  71. /package/dist/{chunk-QRC3RSER.mjs.map → chunk-643S2N2U.mjs.map} +0 -0
  72. /package/dist/{chunk-Z2LYMKCC.mjs.map → chunk-WTQ7LAZR.mjs.map} +0 -0
  73. /package/dist/{http-O5P4BYXU.mjs.map → http-2DN3XOXO.mjs.map} +0 -0
  74. /package/dist/{import-BDLL3DG7.mjs.map → import-LCBSBLYF.mjs.map} +0 -0
  75. /package/dist/{src-FVJL5ENA.mjs.map → src-EGXULYFQ.mjs.map} +0 -0
  76. /package/dist/{stream-import-ZTEW3YVL.mjs.map → stream-import-QM5R5FDG.mjs.map} +0 -0
@@ -2022,6 +2022,25 @@ function getSessionSummaries(db, options) {
2022
2022
  });
2023
2023
  }
2024
2024
  var DEFAULT_SESSION_GAP_THRESHOLD = 1800;
2025
+ function getSessionIndexStats(db) {
2026
+ let sessionCount = 0;
2027
+ if (hasTable(db, "chat_session")) {
2028
+ try {
2029
+ const row = db.prepare("SELECT COUNT(*) as count FROM chat_session").get();
2030
+ sessionCount = row?.count ?? 0;
2031
+ } catch {
2032
+ }
2033
+ }
2034
+ let gapThreshold = DEFAULT_SESSION_GAP_THRESHOLD;
2035
+ try {
2036
+ const meta = db.prepare("SELECT session_gap_threshold FROM meta LIMIT 1").get();
2037
+ if (meta?.session_gap_threshold) {
2038
+ gapThreshold = meta.session_gap_threshold;
2039
+ }
2040
+ } catch {
2041
+ }
2042
+ return { sessionCount, hasIndex: sessionCount > 0, gapThreshold };
2043
+ }
2025
2044
  function getChatSessionList(db) {
2026
2045
  if (!hasTable(db, "chat_session")) return [];
2027
2046
  try {
@@ -5774,6 +5793,138 @@ function needsStreamingThinkParsing(provider, _modelId) {
5774
5793
  return provider === "minimax";
5775
5794
  }
5776
5795
 
5796
+ // ../../packages/core/src/ai/thinking.ts
5797
+ var TYPE_LEVEL_MAP = {
5798
+ gpt5: {
5799
+ minimal: "minimal",
5800
+ low: "low",
5801
+ medium: "medium",
5802
+ high: "high"
5803
+ },
5804
+ gpt5_1: {
5805
+ off: "none",
5806
+ low: "low",
5807
+ medium: "medium",
5808
+ high: "high",
5809
+ xhigh: null
5810
+ },
5811
+ gpt5_2plus: {
5812
+ off: "none",
5813
+ minimal: "minimal",
5814
+ low: "low",
5815
+ medium: "medium",
5816
+ high: "high",
5817
+ xhigh: "xhigh"
5818
+ },
5819
+ grok: {
5820
+ minimal: null,
5821
+ low: "low",
5822
+ medium: null,
5823
+ high: "high",
5824
+ xhigh: null
5825
+ },
5826
+ kimi: {
5827
+ off: "none",
5828
+ auto: "auto",
5829
+ minimal: null,
5830
+ low: "low",
5831
+ medium: "medium",
5832
+ high: "high",
5833
+ xhigh: null
5834
+ },
5835
+ doubao: {
5836
+ off: null,
5837
+ auto: "auto",
5838
+ high: "high"
5839
+ },
5840
+ deepseek_hybrid: {
5841
+ off: null,
5842
+ auto: "auto",
5843
+ high: "high"
5844
+ }
5845
+ };
5846
+ var REASONING_FALLBACK_REGEX = /^(?!.*-non-reasoning\b)(o\d+(?:-[\w-]+)?|.*\b(?:reasoning|reasoner|thinking|think)\b.*|.*-[rR]\d+.*|.*\bqwq(?:-[\w-]+)?\b.*|.*\bhunyuan-t1(?:-[\w-]+)?\b.*|.*\bgrok-(?:3-mini|4|4-fast|build)(?:-[\w-]+)?\b.*)$/i;
5847
+ function classifyThinkingType(provider, modelId) {
5848
+ const id = modelId.toLowerCase();
5849
+ const prov = provider.toLowerCase();
5850
+ if (id.includes("-non-reasoning")) return "none";
5851
+ if (prov === "anthropic") return "none";
5852
+ if (prov === "gemini") {
5853
+ if (/gemini-(?:2\.5|3(?:\.\d+)?-(?:flash|pro)|flash-latest|pro-latest)/i.test(id)) return "gemini";
5854
+ return "none";
5855
+ }
5856
+ if (prov === "qwen" || /\bqwen|qwq/i.test(id)) return "qwen";
5857
+ if (/deepseek[_-]v([4-9]|\d{2,})/i.test(id) || /deepseek-ai\/deepseek-r1/i.test(id)) return "deepseek_v4";
5858
+ if (/deepseek[_-]chat|deepseek[_-]v3/i.test(id)) return "deepseek_hybrid";
5859
+ if (prov === "openai" || prov === "openai-compatible") {
5860
+ if (/gpt-5\.[2-9]|gpt-5\.[1-9]\d/.test(id)) return "gpt5_2plus";
5861
+ if (/gpt-5\.1/.test(id)) return "gpt5_1";
5862
+ if (/gpt-5/.test(id)) return "gpt5";
5863
+ if (/^o\d/.test(id)) return "o_series";
5864
+ }
5865
+ if (/^o\d/.test(id)) return "o_series";
5866
+ if (/\bgrok-(?:3-mini|4|4-fast|build)\b/i.test(id)) return "grok";
5867
+ if (/\bkimi-k(?:2-thinking|2\.[5-9]|[3-9])/i.test(id)) return "kimi";
5868
+ if (prov === "kimi" && /thinking/i.test(id)) return "kimi";
5869
+ if (/\bdoubao-.*seed/i.test(id) || prov === "doubao" && /seed/i.test(id)) return "doubao";
5870
+ if (/\bhunyuan-(?:t1|a13b)/i.test(id)) return "hunyuan";
5871
+ if (prov === "glm" || /\bglm-?(?:5|4\.[5-7]|z1|zero)/i.test(id)) return "qwen";
5872
+ if (prov === "siliconflow" && /r[1-9]/i.test(id)) return "deepseek_v4";
5873
+ if (prov === "openrouter") {
5874
+ if (/deepseek.*(v[4-9]|r\d)/i.test(id)) return "deepseek_v4";
5875
+ if (/deepseek[_-]?(chat|v3)/i.test(id)) return "deepseek_hybrid";
5876
+ if (/\bgrok-(?:3-mini|4|4-fast|build)\b/i.test(id)) return "grok";
5877
+ if (/\bkimi-k(?:2-thinking|2\.[5-9]|[3-9])/i.test(id)) return "kimi";
5878
+ if (REASONING_FALLBACK_REGEX.test(id)) return "default";
5879
+ return "none";
5880
+ }
5881
+ if (/\bmimo-v2/i.test(id)) return "deepseek_hybrid";
5882
+ if (/\bminimax-m[123]/i.test(id)) return "deepseek_hybrid";
5883
+ if (/\bseed-oss/i.test(id)) return "deepseek_hybrid";
5884
+ if (/\bbaichuan-m[23]/i.test(id)) return "default";
5885
+ if (/\bmagistral/i.test(id)) return "default";
5886
+ if (/\bmistral-small-2603/i.test(id)) return "default";
5887
+ if (/\bstep-(?:3|r1-v-mini)/i.test(id)) return "default";
5888
+ if (/\bgemma-?4/i.test(id)) return "default";
5889
+ if (/\bpangu-pro-moe/i.test(id)) return "default";
5890
+ if (/\bsonar-deep-research/i.test(id)) return "default";
5891
+ if (/\bring-(?:1t|mini|flash)/i.test(id)) return "default";
5892
+ if (/\bqwen|qwq/i.test(id)) return "qwen";
5893
+ if (/deepseek[_-]?r\d|deepseek[_-]?v[4-9]/i.test(id)) return "deepseek_v4";
5894
+ if (/^o\d/i.test(id)) return "o_series";
5895
+ if (REASONING_FALLBACK_REGEX.test(id)) return "default";
5896
+ return "none";
5897
+ }
5898
+ function isReasoningModel(provider, modelId) {
5899
+ return classifyThinkingType(provider, modelId) !== "none";
5900
+ }
5901
+ function getThinkingCompat(provider, modelId) {
5902
+ const type = classifyThinkingType(provider, modelId);
5903
+ if (type === "none") return {};
5904
+ if (type === "gemini") return {};
5905
+ if (type === "qwen" || type === "hunyuan") {
5906
+ return { thinkingFormat: "qwen" };
5907
+ }
5908
+ if (type === "deepseek_v4") {
5909
+ return {
5910
+ thinkingFormat: "deepseek",
5911
+ thinkingLevelMap: { high: "high", xhigh: "max", minimal: null, low: null, medium: null }
5912
+ };
5913
+ }
5914
+ if (type === "deepseek_hybrid") {
5915
+ return {
5916
+ thinkingFormat: "deepseek",
5917
+ thinkingLevelMap: { auto: "auto", high: "high", minimal: null, low: null, medium: null, xhigh: null }
5918
+ };
5919
+ }
5920
+ const compat = { supportsReasoningEffort: true };
5921
+ const levelMap = TYPE_LEVEL_MAP[type];
5922
+ if (levelMap) {
5923
+ compat.thinkingLevelMap = levelMap;
5924
+ }
5925
+ return compat;
5926
+ }
5927
+
5777
5928
  // ../../packages/core/src/import/dedup.ts
5778
5929
  function fnv1a64(input) {
5779
5930
  let h0 = 2166136261;
@@ -11657,6 +11808,7 @@ var AIConversationManager = class {
11657
11808
  id TEXT PRIMARY KEY,
11658
11809
  session_id TEXT NOT NULL,
11659
11810
  title TEXT,
11811
+ active_message_id TEXT,
11660
11812
  created_at INTEGER NOT NULL,
11661
11813
  updated_at INTEGER NOT NULL
11662
11814
  );
@@ -11670,6 +11822,9 @@ var AIConversationManager = class {
11670
11822
  data_keywords TEXT,
11671
11823
  data_message_count INTEGER,
11672
11824
  content_blocks TEXT,
11825
+ parent_id TEXT,
11826
+ sibling_group_id TEXT,
11827
+ branch_index INTEGER DEFAULT 0,
11673
11828
  FOREIGN KEY(conversation_id) REFERENCES ai_conversation(id) ON DELETE CASCADE
11674
11829
  );
11675
11830
 
@@ -11683,6 +11838,7 @@ var AIConversationManager = class {
11683
11838
  try {
11684
11839
  const messageTableInfo = db.pragma("table_info(ai_message)");
11685
11840
  const messageColumns = messageTableInfo.map((col) => col.name);
11841
+ const needsMessageTreeBackfill = !messageColumns.includes("parent_id") || !messageColumns.includes("sibling_group_id") || !messageColumns.includes("branch_index");
11686
11842
  if (!messageColumns.includes("content_blocks")) {
11687
11843
  db.exec("ALTER TABLE ai_message ADD COLUMN content_blocks TEXT");
11688
11844
  }
@@ -11692,18 +11848,149 @@ var AIConversationManager = class {
11692
11848
  if (!messageColumns.includes("debug_context")) {
11693
11849
  db.exec("ALTER TABLE ai_message ADD COLUMN debug_context TEXT");
11694
11850
  }
11851
+ if (!messageColumns.includes("parent_id")) {
11852
+ db.exec("ALTER TABLE ai_message ADD COLUMN parent_id TEXT");
11853
+ }
11854
+ if (!messageColumns.includes("sibling_group_id")) {
11855
+ db.exec("ALTER TABLE ai_message ADD COLUMN sibling_group_id TEXT");
11856
+ }
11857
+ if (!messageColumns.includes("branch_index")) {
11858
+ db.exec("ALTER TABLE ai_message ADD COLUMN branch_index INTEGER DEFAULT 0");
11859
+ }
11695
11860
  const convTableInfo = db.pragma("table_info(ai_conversation)");
11696
11861
  const convColumns = convTableInfo.map((col) => col.name);
11862
+ const needsConversationBackfill = !convColumns.includes("active_message_id");
11697
11863
  if (!convColumns.includes("assistant_id")) {
11698
11864
  db.exec(`ALTER TABLE ai_conversation ADD COLUMN assistant_id TEXT DEFAULT '${DEFAULT_GENERAL_ID}'`);
11699
11865
  }
11866
+ if (!convColumns.includes("active_message_id")) {
11867
+ db.exec("ALTER TABLE ai_conversation ADD COLUMN active_message_id TEXT");
11868
+ }
11869
+ if (needsMessageTreeBackfill || needsConversationBackfill || this.hasUnbackfilledMessageTree(db)) {
11870
+ this.backfillMessageTree(db);
11871
+ }
11872
+ db.exec(`
11873
+ CREATE INDEX IF NOT EXISTS idx_ai_message_parent ON ai_message(parent_id);
11874
+ CREATE INDEX IF NOT EXISTS idx_ai_message_sibling ON ai_message(sibling_group_id);
11875
+ `);
11700
11876
  } catch (error) {
11701
11877
  console.error("[AI DB Migration] Migration failed:", error);
11702
11878
  }
11703
11879
  }
11880
+ hasUnbackfilledMessageTree(db) {
11881
+ const row = db.prepare(
11882
+ `SELECT 1
11883
+ FROM ai_conversation c
11884
+ WHERE EXISTS (
11885
+ SELECT 1 FROM ai_message m
11886
+ WHERE m.conversation_id = c.id
11887
+ )
11888
+ AND (
11889
+ c.active_message_id IS NULL
11890
+ OR EXISTS (
11891
+ SELECT 1 FROM ai_message m
11892
+ WHERE m.conversation_id = c.id
11893
+ AND (m.sibling_group_id IS NULL OR m.branch_index IS NULL)
11894
+ )
11895
+ )
11896
+ LIMIT 1`
11897
+ ).get();
11898
+ return !!row;
11899
+ }
11900
+ backfillMessageTree(db) {
11901
+ const conversations = db.prepare("SELECT id FROM ai_conversation").all();
11902
+ const updateMessage = db.prepare(
11903
+ "UPDATE ai_message SET parent_id = ?, sibling_group_id = COALESCE(sibling_group_id, ?), branch_index = COALESCE(branch_index, 0) WHERE id = ?"
11904
+ );
11905
+ const updateConversation = db.prepare("UPDATE ai_conversation SET active_message_id = ? WHERE id = ?");
11906
+ const tx = db.transaction(() => {
11907
+ for (const conversation of conversations) {
11908
+ const messages = db.prepare(
11909
+ `SELECT id, parent_id as parentId, sibling_group_id as siblingGroupId
11910
+ FROM ai_message WHERE conversation_id = ? ORDER BY timestamp ASC, id ASC`
11911
+ ).all(conversation.id);
11912
+ let previousId = null;
11913
+ for (const message of messages) {
11914
+ const parentId = message.parentId === void 0 ? previousId : message.parentId ?? previousId;
11915
+ updateMessage.run(parentId, message.siblingGroupId ?? message.id, message.id);
11916
+ previousId = message.id;
11917
+ }
11918
+ const conversationRow = db.prepare("SELECT active_message_id as activeMessageId FROM ai_conversation WHERE id = ?").get(conversation.id);
11919
+ if (!conversationRow?.activeMessageId && previousId) {
11920
+ updateConversation.run(previousId, conversation.id);
11921
+ }
11922
+ }
11923
+ });
11924
+ tx();
11925
+ }
11704
11926
  generateId(prefix) {
11705
11927
  return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
11706
11928
  }
11929
+ parseMessageRow(row) {
11930
+ return {
11931
+ id: row.id,
11932
+ conversationId: row.conversationId,
11933
+ role: row.role,
11934
+ content: row.content,
11935
+ timestamp: row.timestamp,
11936
+ parentId: row.parentId ?? null,
11937
+ dataKeywords: row.dataKeywords ? JSON.parse(row.dataKeywords) : void 0,
11938
+ dataMessageCount: row.dataMessageCount ?? void 0,
11939
+ contentBlocks: row.contentBlocks ? JSON.parse(row.contentBlocks) : void 0,
11940
+ tokenUsage: row.tokenUsage ? JSON.parse(row.tokenUsage) : void 0
11941
+ };
11942
+ }
11943
+ getMessageRow(messageId) {
11944
+ const db = this.getDb();
11945
+ const row = db.prepare(
11946
+ `SELECT id, conversation_id as conversationId, role, content, timestamp,
11947
+ parent_id as parentId, sibling_group_id as siblingGroupId, branch_index as branchIndex,
11948
+ data_keywords as dataKeywords, data_message_count as dataMessageCount,
11949
+ content_blocks as contentBlocks, token_usage as tokenUsage
11950
+ FROM ai_message WHERE id = ?`
11951
+ ).get(messageId);
11952
+ return row ?? null;
11953
+ }
11954
+ getActiveMessageId(conversationId) {
11955
+ const db = this.getDb();
11956
+ const row = db.prepare("SELECT active_message_id as activeMessageId FROM ai_conversation WHERE id = ?").get(conversationId);
11957
+ if (row?.activeMessageId) {
11958
+ const activeExists = db.prepare("SELECT 1 FROM ai_message WHERE id = ?").get(row.activeMessageId);
11959
+ if (activeExists) return row.activeMessageId;
11960
+ }
11961
+ const fallback = db.prepare("SELECT id FROM ai_message WHERE conversation_id = ? ORDER BY timestamp DESC, id DESC LIMIT 1").get(conversationId);
11962
+ if (fallback?.id) {
11963
+ db.prepare("UPDATE ai_conversation SET active_message_id = ? WHERE id = ?").run(fallback.id, conversationId);
11964
+ return fallback.id;
11965
+ }
11966
+ return null;
11967
+ }
11968
+ getAllMessageRows(conversationId) {
11969
+ return this.getDb().prepare(
11970
+ `SELECT id, conversation_id as conversationId, role, content, timestamp,
11971
+ parent_id as parentId, sibling_group_id as siblingGroupId, branch_index as branchIndex,
11972
+ data_keywords as dataKeywords, data_message_count as dataMessageCount,
11973
+ content_blocks as contentBlocks, token_usage as tokenUsage
11974
+ FROM ai_message WHERE conversation_id = ? ORDER BY timestamp ASC, id ASC`
11975
+ ).all(conversationId);
11976
+ }
11977
+ getActivePathRows(conversationId, leafMessageId) {
11978
+ if (leafMessageId === null) return [];
11979
+ const allRows = this.getAllMessageRows(conversationId);
11980
+ if (allRows.length === 0) return [];
11981
+ const rowMap = new Map(allRows.map((row) => [row.id, row]));
11982
+ let currentId = leafMessageId ?? this.getActiveMessageId(conversationId);
11983
+ const path37 = [];
11984
+ const seen = /* @__PURE__ */ new Set();
11985
+ while (currentId && !seen.has(currentId)) {
11986
+ seen.add(currentId);
11987
+ const row = rowMap.get(currentId);
11988
+ if (!row) break;
11989
+ path37.push(row);
11990
+ currentId = row.parentId;
11991
+ }
11992
+ return path37.length > 0 ? path37.reverse() : allRows;
11993
+ }
11707
11994
  // ==================== 生命周期 ====================
11708
11995
  close() {
11709
11996
  if (this.db) {
@@ -11766,7 +12053,7 @@ var AIConversationManager = class {
11766
12053
  `INSERT INTO ai_conversation (id, session_id, title, assistant_id, created_at, updated_at)
11767
12054
  VALUES (?, ?, ?, ?, ?, ?)`
11768
12055
  ).run(id, sessionId, title || null, assistantId, now, now);
11769
- return { id, sessionId, title: title || null, assistantId, createdAt: now, updatedAt: now };
12056
+ return { id, sessionId, title: title || null, assistantId, activeMessageId: null, createdAt: now, updatedAt: now };
11770
12057
  }
11771
12058
  getConversationCountsBySession() {
11772
12059
  const result = /* @__PURE__ */ new Map();
@@ -11784,6 +12071,7 @@ var AIConversationManager = class {
11784
12071
  const db = this.getDb();
11785
12072
  return db.prepare(
11786
12073
  `SELECT id, session_id as sessionId, title, assistant_id as assistantId,
12074
+ active_message_id as activeMessageId,
11787
12075
  created_at as createdAt, updated_at as updatedAt
11788
12076
  FROM ai_conversation WHERE session_id = ? ORDER BY updated_at DESC`
11789
12077
  ).all(sessionId);
@@ -11792,6 +12080,7 @@ var AIConversationManager = class {
11792
12080
  const db = this.getDb();
11793
12081
  const row = db.prepare(
11794
12082
  `SELECT id, session_id as sessionId, title, assistant_id as assistantId,
12083
+ active_message_id as activeMessageId,
11795
12084
  created_at as createdAt, updated_at as updatedAt
11796
12085
  FROM ai_conversation WHERE id = ?`
11797
12086
  ).get(conversationId);
@@ -11814,13 +12103,19 @@ var AIConversationManager = class {
11814
12103
  const db = this.getDb();
11815
12104
  const now = Math.floor(Date.now() / 1e3);
11816
12105
  const id = this.generateId("msg");
12106
+ const parentId = this.getActiveMessageId(conversationId);
12107
+ const siblingGroupId = id;
12108
+ const branchIndex = 0;
11817
12109
  const pendingDebug = role === "assistant" ? this.pendingDebugContextMap.get(conversationId) : void 0;
11818
12110
  if (pendingDebug) {
11819
12111
  this.pendingDebugContextMap.delete(conversationId);
11820
12112
  }
11821
12113
  db.prepare(
11822
- `INSERT INTO ai_message (id, conversation_id, role, content, timestamp, data_keywords, data_message_count, content_blocks, token_usage, debug_context)
11823
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
12114
+ `INSERT INTO ai_message (
12115
+ id, conversation_id, role, content, timestamp, data_keywords, data_message_count,
12116
+ content_blocks, token_usage, debug_context, parent_id, sibling_group_id, branch_index
12117
+ )
12118
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
11824
12119
  ).run(
11825
12120
  id,
11826
12121
  conversationId,
@@ -11831,15 +12126,23 @@ var AIConversationManager = class {
11831
12126
  dataMessageCount ?? null,
11832
12127
  contentBlocks ? JSON.stringify(contentBlocks) : null,
11833
12128
  tokenUsage ? JSON.stringify(tokenUsage) : null,
11834
- pendingDebug ?? null
12129
+ pendingDebug ?? null,
12130
+ parentId,
12131
+ siblingGroupId,
12132
+ branchIndex
12133
+ );
12134
+ db.prepare("UPDATE ai_conversation SET active_message_id = ?, updated_at = ? WHERE id = ?").run(
12135
+ id,
12136
+ now,
12137
+ conversationId
11835
12138
  );
11836
- db.prepare("UPDATE ai_conversation SET updated_at = ? WHERE id = ?").run(now, conversationId);
11837
12139
  return {
11838
12140
  id,
11839
12141
  conversationId,
11840
12142
  role,
11841
12143
  content,
11842
12144
  timestamp: now,
12145
+ parentId,
11843
12146
  dataKeywords,
11844
12147
  dataMessageCount,
11845
12148
  contentBlocks,
@@ -11847,40 +12150,181 @@ var AIConversationManager = class {
11847
12150
  };
11848
12151
  }
11849
12152
  getMessages(conversationId) {
11850
- const db = this.getDb();
11851
- const rows = db.prepare(
11852
- `SELECT id, conversation_id as conversationId, role, content, timestamp,
11853
- data_keywords as dataKeywords, data_message_count as dataMessageCount,
11854
- content_blocks as contentBlocks, token_usage as tokenUsage
11855
- FROM ai_message WHERE conversation_id = ? ORDER BY timestamp ASC`
11856
- ).all(conversationId);
11857
- return rows.map((row) => ({
11858
- id: row.id,
11859
- conversationId: row.conversationId,
11860
- role: row.role,
11861
- content: row.content,
11862
- timestamp: row.timestamp,
11863
- dataKeywords: row.dataKeywords ? JSON.parse(row.dataKeywords) : void 0,
11864
- dataMessageCount: row.dataMessageCount ?? void 0,
11865
- contentBlocks: row.contentBlocks ? JSON.parse(row.contentBlocks) : void 0,
11866
- tokenUsage: row.tokenUsage ? JSON.parse(row.tokenUsage) : void 0
11867
- }));
12153
+ return this.getActivePathRows(conversationId).map((row) => this.parseMessageRow(row));
11868
12154
  }
11869
12155
  deleteMessage(messageId) {
11870
12156
  const db = this.getDb();
11871
12157
  const result = db.prepare("DELETE FROM ai_message WHERE id = ?").run(messageId);
11872
12158
  return result.changes > 0;
11873
12159
  }
11874
- getConversationTokenUsage(conversationId) {
12160
+ deleteMessagesFrom(conversationId, messageId) {
11875
12161
  const db = this.getDb();
11876
- const row = db.prepare(
11877
- `SELECT
11878
- COALESCE(SUM(json_extract(token_usage, '$.promptTokens')), 0) as promptTokens,
11879
- COALESCE(SUM(json_extract(token_usage, '$.completionTokens')), 0) as completionTokens,
11880
- COALESCE(SUM(json_extract(token_usage, '$.totalTokens')), 0) as totalTokens
11881
- FROM ai_message WHERE conversation_id = ? AND token_usage IS NOT NULL`
11882
- ).get(conversationId);
11883
- return { promptTokens: row.promptTokens, completionTokens: row.completionTokens, totalTokens: row.totalTokens };
12162
+ const target = this.getMessageRow(messageId);
12163
+ if (!target || target.conversationId !== conversationId) {
12164
+ throw new Error("Message not found in conversation");
12165
+ }
12166
+ const activePath = this.getActivePathRows(conversationId);
12167
+ const targetIndex = activePath.findIndex((row) => row.id === messageId);
12168
+ if (targetIndex < 0) {
12169
+ throw new Error("Message not on active path");
12170
+ }
12171
+ const idsToDelete = activePath.slice(targetIndex).map((row) => row.id);
12172
+ const placeholders = idsToDelete.map(() => "?").join(", ");
12173
+ db.prepare(`DELETE FROM ai_message WHERE id IN (${placeholders})`).run(...idsToDelete);
12174
+ const newLeafId = targetIndex > 0 ? activePath[targetIndex - 1].id : null;
12175
+ const now = Math.floor(Date.now() / 1e3);
12176
+ db.prepare("UPDATE ai_conversation SET active_message_id = ?, updated_at = ? WHERE id = ?").run(
12177
+ newLeafId,
12178
+ now,
12179
+ conversationId
12180
+ );
12181
+ }
12182
+ forkConversation(sourceConversationId, upToMessageId, title) {
12183
+ const db = this.getDb();
12184
+ const source = this.getConversation(sourceConversationId);
12185
+ if (!source) {
12186
+ throw new Error("Source conversation not found");
12187
+ }
12188
+ const activePath = this.getActivePathRows(sourceConversationId);
12189
+ const cutIndex = activePath.findIndex((row) => row.id === upToMessageId);
12190
+ if (cutIndex < 0) {
12191
+ throw new Error("Message not on active path");
12192
+ }
12193
+ const messagesToCopy = activePath.slice(0, cutIndex + 1);
12194
+ const now = Math.floor(Date.now() / 1e3);
12195
+ const newConvId = this.generateId("conv");
12196
+ const forkTitle = title || `${source.title || "Untitled"} (fork)`;
12197
+ db.prepare(
12198
+ `INSERT INTO ai_conversation (id, session_id, title, assistant_id, active_message_id, created_at, updated_at)
12199
+ VALUES (?, ?, ?, ?, NULL, ?, ?)`
12200
+ ).run(newConvId, source.sessionId, forkTitle, source.assistantId, now, now);
12201
+ const idMap = /* @__PURE__ */ new Map();
12202
+ let lastNewId = null;
12203
+ for (const row of messagesToCopy) {
12204
+ const newMsgId = this.generateId("msg");
12205
+ idMap.set(row.id, newMsgId);
12206
+ const newParentId = row.parentId ? idMap.get(row.parentId) ?? null : null;
12207
+ db.prepare(
12208
+ `INSERT INTO ai_message (
12209
+ id, conversation_id, role, content, timestamp, data_keywords, data_message_count,
12210
+ content_blocks, token_usage, debug_context, parent_id, sibling_group_id, branch_index
12211
+ )
12212
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, 0)`
12213
+ ).run(
12214
+ newMsgId,
12215
+ newConvId,
12216
+ row.role,
12217
+ row.content,
12218
+ row.timestamp,
12219
+ row.dataKeywords,
12220
+ row.dataMessageCount,
12221
+ row.contentBlocks,
12222
+ row.tokenUsage,
12223
+ newParentId,
12224
+ newMsgId
12225
+ );
12226
+ lastNewId = newMsgId;
12227
+ }
12228
+ if (lastNewId) {
12229
+ db.prepare("UPDATE ai_conversation SET active_message_id = ? WHERE id = ?").run(lastNewId, newConvId);
12230
+ }
12231
+ return {
12232
+ id: newConvId,
12233
+ sessionId: source.sessionId,
12234
+ title: forkTitle,
12235
+ assistantId: source.assistantId,
12236
+ activeMessageId: lastNewId,
12237
+ createdAt: now,
12238
+ updatedAt: now
12239
+ };
12240
+ }
12241
+ updateMessageContent(messageId, newContent) {
12242
+ const db = this.getDb();
12243
+ const result = db.prepare("UPDATE ai_message SET content = ? WHERE id = ?").run(newContent, messageId);
12244
+ if (result.changes === 0) throw new Error("Message not found");
12245
+ }
12246
+ deleteAndRelinkMessage(conversationId, messageId) {
12247
+ const db = this.getDb();
12248
+ const target = this.getMessageRow(messageId);
12249
+ if (!target || target.conversationId !== conversationId) {
12250
+ throw new Error("Message not found in conversation");
12251
+ }
12252
+ db.prepare("UPDATE ai_message SET parent_id = ? WHERE parent_id = ? AND conversation_id = ?").run(
12253
+ target.parentId,
12254
+ messageId,
12255
+ conversationId
12256
+ );
12257
+ const conv = this.getConversation(conversationId);
12258
+ if (conv?.activeMessageId === messageId) {
12259
+ const now = Math.floor(Date.now() / 1e3);
12260
+ db.prepare("UPDATE ai_conversation SET active_message_id = ?, updated_at = ? WHERE id = ?").run(
12261
+ target.parentId,
12262
+ now,
12263
+ conversationId
12264
+ );
12265
+ }
12266
+ db.prepare("DELETE FROM ai_message WHERE id = ?").run(messageId);
12267
+ }
12268
+ insertMessageAfter(conversationId, afterMessageId, role, content, contentBlocks, tokenUsage) {
12269
+ const db = this.getDb();
12270
+ const now = Math.floor(Date.now() / 1e3);
12271
+ const id = this.generateId("msg");
12272
+ const pendingDebug = role === "assistant" ? this.pendingDebugContextMap.get(conversationId) : void 0;
12273
+ if (pendingDebug) {
12274
+ this.pendingDebugContextMap.delete(conversationId);
12275
+ }
12276
+ const childRow = db.prepare("SELECT id FROM ai_message WHERE parent_id = ? AND conversation_id = ? LIMIT 1").get(afterMessageId, conversationId);
12277
+ db.prepare(
12278
+ `INSERT INTO ai_message (
12279
+ id, conversation_id, role, content, timestamp, data_keywords, data_message_count,
12280
+ content_blocks, token_usage, debug_context, parent_id, sibling_group_id, branch_index
12281
+ )
12282
+ VALUES (?, ?, ?, ?, ?, NULL, NULL, ?, ?, ?, ?, ?, 0)`
12283
+ ).run(
12284
+ id,
12285
+ conversationId,
12286
+ role,
12287
+ content,
12288
+ now,
12289
+ contentBlocks ? JSON.stringify(contentBlocks) : null,
12290
+ tokenUsage ? JSON.stringify(tokenUsage) : null,
12291
+ pendingDebug ?? null,
12292
+ afterMessageId,
12293
+ id
12294
+ );
12295
+ if (childRow) {
12296
+ db.prepare("UPDATE ai_message SET parent_id = ? WHERE id = ?").run(id, childRow.id);
12297
+ db.prepare("UPDATE ai_conversation SET updated_at = ? WHERE id = ?").run(now, conversationId);
12298
+ } else {
12299
+ db.prepare("UPDATE ai_conversation SET active_message_id = ?, updated_at = ? WHERE id = ?").run(
12300
+ id,
12301
+ now,
12302
+ conversationId
12303
+ );
12304
+ }
12305
+ return {
12306
+ id,
12307
+ conversationId,
12308
+ role,
12309
+ content,
12310
+ timestamp: now,
12311
+ parentId: afterMessageId,
12312
+ contentBlocks,
12313
+ tokenUsage
12314
+ };
12315
+ }
12316
+ getConversationTokenUsage(conversationId) {
12317
+ const rows = this.getActivePathRows(conversationId);
12318
+ const result = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
12319
+ for (const row of rows) {
12320
+ if (row.tokenUsage) {
12321
+ const usage = JSON.parse(row.tokenUsage);
12322
+ result.promptTokens += usage.promptTokens;
12323
+ result.completionTokens += usage.completionTokens;
12324
+ result.totalTokens += usage.totalTokens;
12325
+ }
12326
+ }
12327
+ return result;
11884
12328
  }
11885
12329
  // ==================== Debug context ====================
11886
12330
  setPendingDebugContext(conversationId, debugContext) {
@@ -11896,8 +12340,8 @@ var AIConversationManager = class {
11896
12340
  return result.changes;
11897
12341
  }
11898
12342
  // ==================== Agent 专用 ====================
11899
- getHistoryForAgent(conversationId, maxMessages) {
11900
- const messages = this.getMessages(conversationId);
12343
+ getHistoryForAgent(conversationId, maxMessages, leafMessageId) {
12344
+ const messages = this.getActivePathRows(conversationId, leafMessageId).map((row) => this.parseMessageRow(row));
11901
12345
  const validMessages = messages.filter(
11902
12346
  (m) => (m.role === "user" || m.role === "assistant" || m.role === "summary") && m.content?.trim()
11903
12347
  );
@@ -11940,8 +12384,6 @@ var AIConversationManager = class {
11940
12384
  }
11941
12385
  // ==================== Summary / 压缩专用 ====================
11942
12386
  addSummaryMessage(conversationId, content, meta) {
11943
- const db = this.getDb();
11944
- db.prepare("DELETE FROM ai_message WHERE conversation_id = ? AND role = 'summary'").run(conversationId);
11945
12387
  const contentBlocks = [
11946
12388
  {
11947
12389
  type: "summary_meta",
@@ -11952,60 +12394,27 @@ var AIConversationManager = class {
11952
12394
  return this.addMessage(conversationId, "summary", content, void 0, void 0, contentBlocks);
11953
12395
  }
11954
12396
  getLatestSummary(conversationId) {
11955
- const db = this.getDb();
11956
- const row = db.prepare(
11957
- `SELECT id, conversation_id as conversationId, role, content, timestamp,
11958
- data_keywords as dataKeywords, data_message_count as dataMessageCount,
11959
- content_blocks as contentBlocks
11960
- FROM ai_message WHERE conversation_id = ? AND role = 'summary'
11961
- ORDER BY timestamp DESC LIMIT 1`
11962
- ).get(conversationId);
11963
- if (!row) return null;
11964
- return {
11965
- id: row.id,
11966
- conversationId: row.conversationId,
11967
- role: row.role,
11968
- content: row.content,
11969
- timestamp: row.timestamp,
11970
- dataKeywords: row.dataKeywords ? JSON.parse(row.dataKeywords) : void 0,
11971
- dataMessageCount: row.dataMessageCount ?? void 0,
11972
- contentBlocks: row.contentBlocks ? JSON.parse(row.contentBlocks) : void 0
11973
- };
12397
+ const row = [...this.getActivePathRows(conversationId)].reverse().find((message) => message.role === "summary");
12398
+ return row ? this.parseMessageRow(row) : null;
11974
12399
  }
11975
12400
  getMessagesAfterSummary(conversationId, summaryTimestamp) {
11976
- const db = this.getDb();
11977
- const rows = db.prepare(
11978
- `SELECT role, content, timestamp FROM ai_message
11979
- WHERE conversation_id = ? AND timestamp > ? AND role IN ('user', 'assistant')
11980
- ORDER BY timestamp ASC`
11981
- ).all(conversationId, summaryTimestamp);
11982
- return rows.map((r) => ({ role: r.role, content: r.content, timestamp: r.timestamp }));
12401
+ return this.getActivePathRows(conversationId).filter((row) => row.timestamp > summaryTimestamp && (row.role === "user" || row.role === "assistant")).map((row) => ({ role: row.role, content: row.content, timestamp: row.timestamp }));
11983
12402
  }
11984
12403
  getAllUserAssistantMessages(conversationId) {
11985
- const db = this.getDb();
11986
- const rows = db.prepare(
11987
- `SELECT role, content, timestamp FROM ai_message
11988
- WHERE conversation_id = ? AND role IN ('user', 'assistant')
11989
- ORDER BY timestamp ASC`
11990
- ).all(conversationId);
11991
- return rows.map((r) => ({ role: r.role, content: r.content, timestamp: r.timestamp }));
12404
+ return this.getActivePathRows(conversationId).filter((row) => row.role === "user" || row.role === "assistant").map((row) => ({ role: row.role, content: row.content, timestamp: row.timestamp }));
11992
12405
  }
11993
12406
  getMessageCountAfterSummary(conversationId) {
11994
12407
  const summary = this.getLatestSummary(conversationId);
11995
12408
  if (!summary) {
11996
- const db2 = this.getDb();
11997
- const row2 = db2.prepare("SELECT COUNT(*) as count FROM ai_message WHERE conversation_id = ? AND role IN ('user', 'assistant')").get(conversationId);
11998
- return row2.count;
12409
+ return this.getActivePathRows(conversationId).filter((row) => row.role === "user" || row.role === "assistant").length;
11999
12410
  }
12000
12411
  const metaBlock = summary.contentBlocks?.find(
12001
12412
  (b) => b.type === "summary_meta"
12002
12413
  );
12003
12414
  const boundary = metaBlock?.bufferBoundaryTimestamp ?? summary.timestamp;
12004
- const db = this.getDb();
12005
- const row = db.prepare(
12006
- "SELECT COUNT(*) as count FROM ai_message WHERE conversation_id = ? AND timestamp >= ? AND role IN ('user', 'assistant')"
12007
- ).get(conversationId, boundary);
12008
- return row.count;
12415
+ return this.getActivePathRows(conversationId).filter(
12416
+ (row) => row.timestamp >= boundary && (row.role === "user" || row.role === "assistant")
12417
+ ).length;
12009
12418
  }
12010
12419
  };
12011
12420
 
@@ -13177,7 +13586,8 @@ function applyPreprocessingPipeline(options) {
13177
13586
  // ../../packages/node-runtime/src/ai/agent/core.ts
13178
13587
  import { Agent as PiAgentCore } from "@earendil-works/pi-agent-core";
13179
13588
  import {
13180
- streamSimple as defaultStreamSimple
13589
+ streamSimple as defaultStreamSimple,
13590
+ clampThinkingLevel
13181
13591
  } from "@earendil-works/pi-ai";
13182
13592
  function createEmptyPiUsage() {
13183
13593
  return {
@@ -13241,11 +13651,34 @@ async function runAgentCore(options) {
13241
13651
  if (abortSignal?.aborted) {
13242
13652
  return { usage: totalUsage, finalMessages: [], toolsUsed: [], toolRounds: 0 };
13243
13653
  }
13654
+ const isDefault = !options.thinkingLevel || options.thinkingLevel === "default";
13655
+ const effectiveModel = isDefault ? { ...piModel, reasoning: false, compat: void 0, thinkingLevelMap: void 0 } : piModel;
13656
+ const resolvedThinkingLevel = (() => {
13657
+ if (isDefault) return "off";
13658
+ const level = options.thinkingLevel;
13659
+ if (level === "auto") {
13660
+ if (!piModel.reasoning) return "off";
13661
+ const compat = piModel.compat;
13662
+ if (compat?.thinkingFormat) return "high";
13663
+ if (piModel.thinkingLevelMap) return "high";
13664
+ return void 0;
13665
+ }
13666
+ return clampThinkingLevel(piModel, level);
13667
+ })();
13668
+ const finalThinkingLevel = resolvedThinkingLevel ?? (piModel.reasoning ? void 0 : "off");
13669
+ console.debug("[agent-core] thinkingLevel resolution:", {
13670
+ input: options.thinkingLevel,
13671
+ modelId: piModel.id,
13672
+ modelReasoning: effectiveModel.reasoning,
13673
+ isDefault,
13674
+ resolved: resolvedThinkingLevel,
13675
+ final: finalThinkingLevel
13676
+ });
13244
13677
  const coreAgent = new PiAgentCore({
13245
13678
  initialState: {
13246
13679
  systemPrompt,
13247
- model: piModel,
13248
- thinkingLevel: piModel.reasoning ? "medium" : "off",
13680
+ model: effectiveModel,
13681
+ thinkingLevel: finalThinkingLevel,
13249
13682
  tools: maxToolRounds > 0 ? tools : [],
13250
13683
  messages: toPiHistoryMessages(history)
13251
13684
  },
@@ -15388,6 +15821,20 @@ var BUILTIN_PROVIDER_API = {
15388
15821
  gemini: "google-generative-ai",
15389
15822
  anthropic: "anthropic-messages"
15390
15823
  };
15824
+ function inferReasoning(provider, modelId, modelDef) {
15825
+ const reasoning = modelDef?.capabilities.includes("reasoning") || !modelDef?.builtin && isReasoningModel(provider, modelId);
15826
+ if (!reasoning) return { reasoning: false, compat: void 0 };
15827
+ const thinkingCompat = getThinkingCompat(provider, modelId);
15828
+ if (Object.keys(thinkingCompat).length === 0) {
15829
+ return { reasoning: true, compat: void 0 };
15830
+ }
15831
+ const { thinkingLevelMap, ...compatFields } = thinkingCompat;
15832
+ return {
15833
+ reasoning: true,
15834
+ compat: Object.keys(compatFields).length > 0 ? compatFields : void 0,
15835
+ thinkingLevelMap
15836
+ };
15837
+ }
15391
15838
  function buildPiModel(config, options) {
15392
15839
  const providerDef = BUILTIN_PROVIDERS.find((p) => p.id === config.provider);
15393
15840
  const baseUrl = config.baseUrl || providerDef?.defaultBaseUrl || "";
@@ -15403,7 +15850,7 @@ function buildPiModel(config, options) {
15403
15850
  api: "google-generative-ai",
15404
15851
  provider: "google",
15405
15852
  baseUrl,
15406
- reasoning: false,
15853
+ reasoning: isReasoningModel(config.provider, modelId),
15407
15854
  input: ["text"],
15408
15855
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
15409
15856
  contextWindow,
@@ -15425,6 +15872,7 @@ function buildPiModel(config, options) {
15425
15872
  };
15426
15873
  }
15427
15874
  const resolvedBaseUrl = config.provider === "openai-compatible" && (apiFormat === "openai-completions" || apiFormat === "openai-responses") ? normalizeOpenAICompatibleBaseUrl(baseUrl) : baseUrl;
15875
+ const { reasoning, compat, thinkingLevelMap } = inferReasoning(config.provider, modelId, modelDef);
15428
15876
  return {
15429
15877
  id: modelId,
15430
15878
  name: modelId,
@@ -15432,12 +15880,13 @@ function buildPiModel(config, options) {
15432
15880
  provider: config.provider,
15433
15881
  baseUrl: resolvedBaseUrl,
15434
15882
  headers: options?.headers,
15435
- reasoning: config.isReasoningModel ?? false,
15883
+ reasoning,
15884
+ thinkingLevelMap,
15436
15885
  input: ["text"],
15437
15886
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
15438
15887
  contextWindow,
15439
15888
  maxTokens: config.maxTokens ?? 4096,
15440
- compat: config.disableThinking ? { thinkingFormat: "qwen" } : void 0
15889
+ compat
15441
15890
  };
15442
15891
  }
15443
15892
 
@@ -18804,6 +19253,7 @@ __export(session_index_service_exports, {
18804
19253
  clearIndex: () => clearIndex,
18805
19254
  generateIncrementalIndex: () => generateIncrementalIndex,
18806
19255
  generateIndex: () => generateIndex,
19256
+ getAllIndexStats: () => getAllIndexStats,
18807
19257
  getFtsStatus: () => getFtsStatus,
18808
19258
  rebuildFts: () => rebuildFts,
18809
19259
  searchFts: () => searchFts
@@ -18832,6 +19282,18 @@ function rebuildFts(adapter, sessionId) {
18832
19282
  const db = adapter.ensureWritable(sessionId);
18833
19283
  return rebuildFtsIndex(db);
18834
19284
  }
19285
+ function getAllIndexStats(adapter) {
19286
+ const ids = adapter.listSessionIds();
19287
+ return ids.map((sessionId) => {
19288
+ try {
19289
+ const db = adapter.ensureReadonly(sessionId);
19290
+ const stats = getSessionIndexStats(db);
19291
+ return { sessionId, hasIndex: stats.hasIndex, sessionCount: stats.sessionCount };
19292
+ } catch {
19293
+ return { sessionId, hasIndex: false, sessionCount: 0 };
19294
+ }
19295
+ });
19296
+ }
18835
19297
 
18836
19298
  // ../../packages/node-runtime/src/services/summary-service.ts
18837
19299
  var summary_service_exports = {};
@@ -19201,4 +19663,4 @@ export {
19201
19663
  export_service_exports,
19202
19664
  createDatabaseManagerAdapter
19203
19665
  };
19204
- //# sourceMappingURL=chunk-SQKT45MM.mjs.map
19666
+ //# sourceMappingURL=chunk-G7Q7EQ3V.mjs.map