chatlab-cli 0.25.1 → 0.26.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/{chat-command-5XMRLXZM.mjs → chat-command-ZP4WJVWC.mjs} +144 -6
- package/dist/chat-command-ZP4WJVWC.mjs.map +1 -0
- package/dist/{chunk-YZYP5ST6.mjs → chunk-6G7AIF7I.mjs} +12 -11
- package/dist/chunk-6G7AIF7I.mjs.map +1 -0
- package/dist/{chunk-WYHGWTA4.mjs → chunk-ILGSSXOG.mjs} +92 -28
- package/dist/chunk-ILGSSXOG.mjs.map +1 -0
- package/dist/{chunk-JE3FOFF7.mjs → chunk-IRZRIHIT.mjs} +49 -12
- package/dist/chunk-IRZRIHIT.mjs.map +1 -0
- package/dist/{chunk-7VG6QGQ2.mjs → chunk-QY67NN65.mjs} +841 -79
- package/dist/chunk-QY67NN65.mjs.map +1 -0
- package/dist/{chunk-GTCTDD2Z.mjs → chunk-SJIOPSMM.mjs} +8 -8
- package/dist/{chunk-PDQFSQO6.mjs → chunk-TC74HESZ.mjs} +2 -2
- package/dist/{chunk-FDK6SPCG.mjs → chunk-UB4XBM4R.mjs} +2 -2
- package/dist/{chunk-CUCDRAY6.mjs → chunk-WXC6RZCX.mjs} +2 -2
- package/dist/cli.mjs +3 -3
- package/dist/{http-C3CGXUBU.mjs → http-J3IOFFIA.mjs} +8 -8
- package/dist/{import-VS7L5JDX.mjs → import-POYG5LOX.mjs} +4 -4
- package/dist/index.mjs +8 -8
- package/dist/{mcp-6VXDPUQK.mjs → mcp-7HH7UMXT.mjs} +4 -4
- package/dist/{stream-import-TFDBNVIW.mjs → stream-import-O3H3FGV2.mjs} +3 -3
- package/dist-web/assets/{DebugToolsPanel-vn-bnUxn.css → DebugToolsPanel-CrqULdXp.css} +1 -1
- package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-BTJxEma5.js +182 -0
- package/dist-web/assets/{EChartWordcloud-CzhfrEF_.js → EChartWordcloud-B_YisOW5.js} +1 -1
- package/dist-web/assets/{MessageExportModal-B79pPBL9.js → MessageExportModal-C7NgEL8T.js} +1 -1
- package/dist-web/assets/{electron-DRkrjeIl.js → electron-B3DFm1cC.js} +1 -1
- package/dist-web/assets/electron-BMM4Nfty.js +1 -0
- package/dist-web/assets/{fetch-DfgdagMN.js → fetch-ArMjdMcy.js} +1 -1
- package/dist-web/assets/{fetch-BqLy63aj.js → fetch-BFtuJaa1.js} +1 -1
- package/dist-web/assets/{fetch-CDamdvtb.js → fetch-BGfaAqO9.js} +1 -1
- package/dist-web/assets/{fetch-Drk9dLaF.js → fetch-BaJDB31c.js} +1 -1
- package/dist-web/assets/{fetch-BmZIm6mS.js → fetch-BjDJgdN0.js} +1 -1
- package/dist-web/assets/{fetch-DWg-2kOp.js → fetch-C5CLcpQW.js} +1 -1
- package/dist-web/assets/{fetch-ph2_d79v.js → fetch-DQZvdHnG.js} +1 -1
- package/dist-web/assets/{fetch-Y-_WsCuk.js → fetch-Dhfbt1BQ.js} +3 -3
- package/dist-web/assets/{fetch-BstX-wd4.js → fetch-DnEP0uyF.js} +1 -1
- package/dist-web/assets/{fetch-Bvcxe5PI.js → fetch-SYrb-sZe.js} +1 -1
- package/dist-web/assets/index-CWfkrx37.js +173 -0
- package/dist-web/assets/index-D3N4NDFx.css +1 -0
- package/dist-web/assets/{index-DMWf5On7.js → index-D7_ch4zf.js} +1 -1
- package/dist-web/assets/{index-9urfJP1r.js → index-DK9LEEzT.js} +1 -1
- package/dist-web/assets/index-DqDa_on9.js +9 -0
- package/dist-web/assets/{index-D_hHm7bQ.js → index-DrN1G9bl.js} +2 -2
- package/dist-web/assets/{index-deYDOVUa.js → index-MdYeovYo.js} +4 -4
- package/dist-web/assets/{vendor-nuxt-ui-C_8CsH6e.js → vendor-nuxt-ui-Zy8txNdC.js} +1 -1
- package/dist-web/assets/{vendor-reka-ui-CIMXwvEp.js → vendor-reka-ui-mMvma1EP.js} +1 -1
- package/dist-web/assets/{web-XJV6Vj5t.js → web-zEXsvoZW.js} +1 -1
- package/dist-web/index.html +4 -4
- package/package.json +1 -1
- package/dist/chat-command-5XMRLXZM.mjs.map +0 -1
- package/dist/chunk-7VG6QGQ2.mjs.map +0 -1
- package/dist/chunk-JE3FOFF7.mjs.map +0 -1
- package/dist/chunk-WYHGWTA4.mjs.map +0 -1
- package/dist/chunk-YZYP5ST6.mjs.map +0 -1
- package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-B1xZmp9r.js +0 -161
- package/dist-web/assets/electron-Dv8jdn_2.js +0 -1
- package/dist-web/assets/index-CfKjh0Jr.js +0 -9
- package/dist-web/assets/index-CprJOAB1.css +0 -1
- package/dist-web/assets/index-MCdpiX_O.js +0 -173
- /package/dist/{chunk-GTCTDD2Z.mjs.map → chunk-SJIOPSMM.mjs.map} +0 -0
- /package/dist/{chunk-PDQFSQO6.mjs.map → chunk-TC74HESZ.mjs.map} +0 -0
- /package/dist/{chunk-FDK6SPCG.mjs.map → chunk-UB4XBM4R.mjs.map} +0 -0
- /package/dist/{chunk-CUCDRAY6.mjs.map → chunk-WXC6RZCX.mjs.map} +0 -0
- /package/dist/{http-C3CGXUBU.mjs.map → http-J3IOFFIA.mjs.map} +0 -0
- /package/dist/{import-VS7L5JDX.mjs.map → import-POYG5LOX.mjs.map} +0 -0
- /package/dist/{mcp-6VXDPUQK.mjs.map → mcp-7HH7UMXT.mjs.map} +0 -0
- /package/dist/{stream-import-TFDBNVIW.mjs.map → stream-import-O3H3FGV2.mjs.map} +0 -0
|
@@ -2158,6 +2158,7 @@ function getChatOverview(db, topN = 10) {
|
|
|
2158
2158
|
if (!meta) return null;
|
|
2159
2159
|
const overview = getSessionOverview(db);
|
|
2160
2160
|
const members = getMemberActivity(db);
|
|
2161
|
+
const summaryCount = getSummaryCount(db);
|
|
2161
2162
|
const topMembers = members.slice(0, topN).map((m) => ({
|
|
2162
2163
|
id: m.memberId,
|
|
2163
2164
|
name: m.name,
|
|
@@ -2171,7 +2172,8 @@ function getChatOverview(db, topN = 10) {
|
|
|
2171
2172
|
totalMembers: overview.totalMembers,
|
|
2172
2173
|
firstMessageTs: overview.firstMessageTs,
|
|
2173
2174
|
lastMessageTs: overview.lastMessageTs,
|
|
2174
|
-
topMembers
|
|
2175
|
+
topMembers,
|
|
2176
|
+
summaryCount
|
|
2175
2177
|
};
|
|
2176
2178
|
}
|
|
2177
2179
|
function searchSegments(db, keywords, timeFilter, limit = 20, previewCount = 5, ftsMatchExpression) {
|
|
@@ -11779,6 +11781,10 @@ function isDuplicate(msg, existingPlatformMsgIds, existingKeys) {
|
|
|
11779
11781
|
existingKeys.add(key);
|
|
11780
11782
|
return false;
|
|
11781
11783
|
}
|
|
11784
|
+
function normalizeTimestamp(timestamp) {
|
|
11785
|
+
const value = typeof timestamp === "string" && timestamp.trim() !== "" ? Number(timestamp) : timestamp;
|
|
11786
|
+
return typeof value === "number" && value > 0 && Number.isFinite(value) ? value : null;
|
|
11787
|
+
}
|
|
11782
11788
|
async function analyzeIncrementalImport(sessionId, filePath, deps) {
|
|
11783
11789
|
const formatFeature = detectFormat(filePath);
|
|
11784
11790
|
if (!formatFeature) {
|
|
@@ -11806,7 +11812,9 @@ async function analyzeIncrementalImport(sessionId, filePath, deps) {
|
|
|
11806
11812
|
onMessageBatch: (batch) => {
|
|
11807
11813
|
for (const msg of batch) {
|
|
11808
11814
|
totalInFile++;
|
|
11809
|
-
|
|
11815
|
+
const timestamp = normalizeTimestamp(msg.timestamp);
|
|
11816
|
+
if (timestamp === null) continue;
|
|
11817
|
+
if (isDuplicate({ ...msg, timestamp }, existingPlatformMsgIds, existingKeys)) {
|
|
11810
11818
|
duplicateCount++;
|
|
11811
11819
|
} else {
|
|
11812
11820
|
newMessageCount++;
|
|
@@ -11929,11 +11937,12 @@ async function incrementalImport(sessionId, filePath, deps, options) {
|
|
|
11929
11937
|
trackError2(processedCount, "MISSING_TIMESTAMP", "timestamp field is missing");
|
|
11930
11938
|
continue;
|
|
11931
11939
|
}
|
|
11932
|
-
|
|
11940
|
+
const timestamp = normalizeTimestamp(msg.timestamp);
|
|
11941
|
+
if (timestamp === null) {
|
|
11933
11942
|
trackError2(processedCount, "INVALID_TIMESTAMP", `timestamp value: ${msg.timestamp}`);
|
|
11934
11943
|
continue;
|
|
11935
11944
|
}
|
|
11936
|
-
if (isDuplicate(msg, existingPlatformMsgIds, existingKeys)) {
|
|
11945
|
+
if (isDuplicate({ ...msg, timestamp }, existingPlatformMsgIds, existingKeys)) {
|
|
11937
11946
|
duplicateCount++;
|
|
11938
11947
|
continue;
|
|
11939
11948
|
}
|
|
@@ -11957,7 +11966,7 @@ async function incrementalImport(sessionId, filePath, deps, options) {
|
|
|
11957
11966
|
memberId,
|
|
11958
11967
|
msg.senderAccountName || null,
|
|
11959
11968
|
msg.senderGroupNickname || null,
|
|
11960
|
-
|
|
11969
|
+
timestamp,
|
|
11961
11970
|
msg.type,
|
|
11962
11971
|
msg.content || null,
|
|
11963
11972
|
msg.replyToMessageId || null,
|
|
@@ -12584,11 +12593,7 @@ var AIChatManager = class {
|
|
|
12584
12593
|
siblingGroupId,
|
|
12585
12594
|
branchIndex
|
|
12586
12595
|
);
|
|
12587
|
-
db.prepare("UPDATE ai_chat SET active_message_id = ?, updated_at = ? WHERE id = ?").run(
|
|
12588
|
-
id,
|
|
12589
|
-
now,
|
|
12590
|
-
aiChatId
|
|
12591
|
-
);
|
|
12596
|
+
db.prepare("UPDATE ai_chat SET active_message_id = ?, updated_at = ? WHERE id = ?").run(id, now, aiChatId);
|
|
12592
12597
|
return {
|
|
12593
12598
|
id,
|
|
12594
12599
|
aiChatId,
|
|
@@ -12626,11 +12631,7 @@ var AIChatManager = class {
|
|
|
12626
12631
|
db.prepare(`DELETE FROM ai_message WHERE id IN (${placeholders})`).run(...idsToDelete);
|
|
12627
12632
|
const newLeafId = targetIndex > 0 ? activePath[targetIndex - 1].id : null;
|
|
12628
12633
|
const now = Math.floor(Date.now() / 1e3);
|
|
12629
|
-
db.prepare("UPDATE ai_chat SET active_message_id = ?, updated_at = ? WHERE id = ?").run(
|
|
12630
|
-
newLeafId,
|
|
12631
|
-
now,
|
|
12632
|
-
aiChatId
|
|
12633
|
-
);
|
|
12634
|
+
db.prepare("UPDATE ai_chat SET active_message_id = ?, updated_at = ? WHERE id = ?").run(newLeafId, now, aiChatId);
|
|
12634
12635
|
}
|
|
12635
12636
|
forkAIChat(sourceAIChatId, upToMessageId, title) {
|
|
12636
12637
|
const db = this.getDb();
|
|
@@ -12749,11 +12750,7 @@ var AIChatManager = class {
|
|
|
12749
12750
|
db.prepare("UPDATE ai_message SET parent_id = ? WHERE id = ?").run(id, childRow.id);
|
|
12750
12751
|
db.prepare("UPDATE ai_chat SET updated_at = ? WHERE id = ?").run(now, aiChatId);
|
|
12751
12752
|
} else {
|
|
12752
|
-
db.prepare("UPDATE ai_chat SET active_message_id = ?, updated_at = ? WHERE id = ?").run(
|
|
12753
|
-
id,
|
|
12754
|
-
now,
|
|
12755
|
-
aiChatId
|
|
12756
|
-
);
|
|
12753
|
+
db.prepare("UPDATE ai_chat SET active_message_id = ?, updated_at = ? WHERE id = ?").run(id, now, aiChatId);
|
|
12757
12754
|
}
|
|
12758
12755
|
return {
|
|
12759
12756
|
id,
|
|
@@ -14034,10 +14031,38 @@ function shouldUseChartCapabilityForMessage(message) {
|
|
|
14034
14031
|
normalized
|
|
14035
14032
|
);
|
|
14036
14033
|
}
|
|
14034
|
+
function shouldOfferChartCapabilityForAnalyticalMessage(message) {
|
|
14035
|
+
const normalized = message.trim().toLowerCase();
|
|
14036
|
+
if (!normalized) return false;
|
|
14037
|
+
if (shouldUseChartCapabilityForMessage(normalized)) return true;
|
|
14038
|
+
return /(?:趋势|变化|走势|排名|排行|前\s*\d+|top\s*\d*|最多|最少|高频|分布|占比|比例|构成|份额|活跃度|热度|按.{0,8}统计|统计.{0,8}按|trend|ranking|rank|top\s*\d*|distribution|ratio|share|percentage|breakdown)/i.test(
|
|
14039
|
+
normalized
|
|
14040
|
+
);
|
|
14041
|
+
}
|
|
14042
|
+
function getChartPlannerCapabilityForMessage(options) {
|
|
14043
|
+
const availableToolSet = new Set(options.availableTools);
|
|
14044
|
+
if (!availableToolSet.has("get_schema") || !availableToolSet.has("render_chart")) {
|
|
14045
|
+
return null;
|
|
14046
|
+
}
|
|
14047
|
+
const chartAutoMode = options.chartAutoMode ?? "suggest";
|
|
14048
|
+
const shouldOffer = chartAutoMode === "explicit" ? shouldUseChartCapabilityForMessage(options.userMessage) : shouldOfferChartCapabilityForAnalyticalMessage(options.userMessage);
|
|
14049
|
+
if (!shouldOffer) {
|
|
14050
|
+
return null;
|
|
14051
|
+
}
|
|
14052
|
+
const isZh = (options.locale ?? "zh-CN").startsWith("zh");
|
|
14053
|
+
return {
|
|
14054
|
+
id: "chart_generation",
|
|
14055
|
+
label: isZh ? "\u56FE\u8868\u751F\u6210" : "Chart generation",
|
|
14056
|
+
tools: ["get_schema", "render_chart"],
|
|
14057
|
+
guidance: isZh ? "\u7528\u6237\u660E\u786E\u8981\u6C42\u56FE\u8868\uFF0C\u6216\u8D8B\u52BF\u3001\u6392\u540D\u3001\u5206\u5E03\u3001\u5360\u6BD4\u7B49\u5206\u6790\u7528\u56FE\u66F4\u6E05\u695A\u65F6\uFF0C\u53EF\u4EE5\u5728\u8BA1\u5212\u4E2D\u52A0\u5165\u6700\u591A\u4E00\u5F20\u56FE\u8868\u6B65\u9AA4\uFF1B\u5FC5\u987B\u5148\u7528 get_schema \u786E\u8BA4 schema\uFF0C\u518D\u7528 render_chart \u751F\u6210\u56FE\u8868\uFF1B\u4E0D\u8981\u8F93\u51FA\u7ED8\u56FE\u4EE3\u7801\u3002" : "When the user explicitly asks for charts, or when trends, rankings, distributions, or ratios are clearer visually, you may add at most one chart step to the plan; call get_schema before render_chart; do not output chart-rendering code."
|
|
14058
|
+
};
|
|
14059
|
+
}
|
|
14037
14060
|
function resolveChartRuntimeForRequest(options) {
|
|
14038
14061
|
const locale = options.locale ?? "zh-CN";
|
|
14039
14062
|
const isExplicitChartSkill = options.skillId === CHART_CAPABILITY_SKILL_ID;
|
|
14040
|
-
const
|
|
14063
|
+
const allowAnalyticalAutoDetection = options.chartAutoMode !== void 0 ? options.chartAutoMode === "aggressive" : options.enableAnalyticalAutoDetection === true;
|
|
14064
|
+
const shouldAutoDetectChart = shouldUseChartCapabilityForMessage(options.userMessage ?? "") || allowAnalyticalAutoDetection && shouldOfferChartCapabilityForAnalyticalMessage(options.userMessage ?? "");
|
|
14065
|
+
const isAutoChartSkill = options.enableAutoDetection === true && !options.skillId && shouldAutoDetectChart;
|
|
14041
14066
|
if (!isExplicitChartSkill && !isAutoChartSkill) {
|
|
14042
14067
|
return { isChartCapability: false };
|
|
14043
14068
|
}
|
|
@@ -14083,23 +14108,28 @@ function getSkillConfigWithBuiltinChart(id, locale = "zh-CN", getSkillConfig) {
|
|
|
14083
14108
|
}
|
|
14084
14109
|
var ZH_PROMPT = `\u4F60\u662F ChatLab \u7ED8\u56FE\u52A9\u624B\u3002\u672C\u8F6E\u7528\u6237\u5E0C\u671B\u4F60\u5728\u56DE\u7B54\u91CC\u81EA\u7136\u5D4C\u5165\u4E00\u5F20\u6216\u591A\u5F20\u56FE\u8868\u3002
|
|
14085
14110
|
|
|
14086
|
-
\u4F60\u5FC5\u987B\u901A\u8FC7 render_chart \u5DE5\u5177\u751F\u6210\u56FE\u8868\u3002\u4E0D\u8981\u8F93\u51FA HTML\u3001JavaScript\u3001SVG\u3001Canvas\u3001ECharts option \u6216\u4EFB\u4F55\u6E32\u67D3\u4EE3\u7801\u3002
|
|
14111
|
+
\u4F60\u5FC5\u987B\u901A\u8FC7 render_chart \u5DE5\u5177\u751F\u6210\u56FE\u8868\u3002\u4E0D\u8981\u8F93\u51FA HTML\u3001JavaScript\u3001SVG\u3001Canvas\u3001ECharts option\u3001Markdown \u56FE\u7247\u94FE\u63A5\uFF08\u5982 \uFF09\u6216\u4EFB\u4F55\u6E32\u67D3\u4EE3\u7801\u3002
|
|
14087
14112
|
|
|
14088
14113
|
\u786C\u6027\u89C4\u5219\uFF1A
|
|
14089
14114
|
1. \u7B2C\u4E00\u6B21\u5199 SQL \u524D\u5FC5\u987B\u5148\u8C03\u7528 get_schema\u3002\u7981\u6B62\u731C\u6D4B\u8868\u540D\u3001\u5B57\u6BB5\u540D\u6216\u65F6\u95F4\u5B57\u6BB5\u3002
|
|
14090
|
-
2. \u201C\u6700\u8FD1\u201D\u201C\
|
|
14115
|
+
2. \u201C\u6700\u8FD1\u201D\u201C\u8FC7\u53BB N \u5929/\u5E74\u201D\u7B49\u76F8\u5BF9\u65F6\u95F4\u4EE5\u7CFB\u7EDF\u63D0\u793A\u4E2D\u7684\u771F\u5B9E\u5F53\u524D\u65E5\u671F\u4E3A\u57FA\u51C6\uFF1B\u5982\u679C\u542F\u52A8\u4E0A\u4E0B\u6587\u663E\u793A\u6570\u636E\u5E93\u8986\u76D6\u4E0D\u8DB3\uFF0C\u53EA\u5206\u6790\u7528\u6237\u65F6\u95F4\u8303\u56F4\u4E0E\u6570\u636E\u5E93\u8986\u76D6\u8303\u56F4\u7684\u4EA4\u96C6\u5E76\u8BF4\u660E\u7F3A\u53E3\u3002
|
|
14091
14116
|
3. ChatLab \u7684 message.ts \u662F\u79D2\u7EA7 Unix \u65F6\u95F4\u6233\uFF0C\u4F7F\u7528 date(ts, 'unixepoch', 'localtime')\uFF1B\u7981\u6B62\u5199 ts/1000\u3002
|
|
14092
14117
|
4. \u201C\u6700\u8FD1\u7684 N \u4EBA/\u6210\u5458\u201D\u5FC5\u987B\u5148\u7528\u6570\u636E\u5B9A\u4E49\u5E76\u7B5B\u9009\u51FA N \u4E2A\u6210\u5458\uFF0C\u518D\u53EA\u7EDF\u8BA1\u8FD9\u4E9B\u6210\u5458\u3002
|
|
14093
14118
|
5. \u6298\u7EBF\u56FE\u6709\u591A\u6761\u7EBF\u65F6\uFF0C\u6BCF\u6761\u7EBF\u5FC5\u987B\u6709\u660E\u786E series \u5B57\u6BB5\u542B\u4E49\uFF1B\u6309\u65E5\u671F\u7EDF\u8BA1\u65F6\u5E94\u8865\u9F50\u65E5\u671F \xD7 series \u7684 0 \u503C\uFF0C\u907F\u514D\u7F3A\u5931\u65E5\u671F\u5BFC\u81F4\u6298\u7EBF\u65AD\u88C2\u6216\u8BEF\u8FDE\u3002
|
|
14094
|
-
6. \u5DE5\u5177\u5931\u8D25\u3001SQL \u4FEE\u6B63\u3001schema \u63A2\u7D22\u8FC7\u7A0B\u4E0D\u8981\u5199\u8FDB\u6700\u7EC8\u56DE\u7B54\uFF1B\u6700\u7EC8\u53EA\u4FDD\u7559\u56FE\u8868\u548C\u7B80\u77ED\u7ED3\u8BBA\u3002
|
|
14095
|
-
7. \
|
|
14119
|
+
6. \u5DE5\u5177\u5931\u8D25\u3001SQL \u4FEE\u6B63\u3001schema \u63A2\u7D22\u8FC7\u7A0B\u4E0D\u8981\u5199\u8FDB\u6700\u7EC8\u56DE\u7B54\uFF1B\u6700\u7EC8\u53EA\u4FDD\u7559\u539F\u751F\u56FE\u8868\u548C\u7B80\u77ED\u7ED3\u8BBA\uFF0C\u7981\u6B62\u7528 chart1.png\u3001chart2.png \u7B49\u6587\u4EF6\u540D\u5F15\u7528\u56FE\u8868\u3002
|
|
14120
|
+
7. \u8C03\u7528 render_chart \u65F6\uFF0CChatLab \u4F1A\u7ACB\u5373\u5728\u8BE5\u4F4D\u7F6E\u63D2\u5165\u539F\u751F\u56FE\u8868\uFF1B\u9700\u8981\u56FE\u8868\u5C31\u76F4\u63A5\u8C03\u7528\u5DE5\u5177\uFF0C\u4E0D\u8981\u5199 SQL \u6CE8\u91CA\u3001Markdown \u56FE\u7247\u6216\u201C\u5DF2\u751F\u6210\u56FE\u8868/\u89C1\u4E0A\u56FE\u201D\u8FD9\u7C7B\u6587\u672C\u5360\u4F4D\u3002
|
|
14121
|
+
8. \u7528\u6237\u8981\u6C42\u591A\u5F20\u56FE\u65F6\uFF0C\u56FE\u8868\u5E94\u5206\u6563\u51FA\u73B0\u5728\u76F8\u5173\u603B\u7ED3\u6216\u89E3\u91CA\u9644\u8FD1\uFF1B\u4E0D\u8981\u628A\u6240\u6709\u56FE\u96C6\u4E2D\u751F\u6210\u540E\u518D\u5728\u6700\u540E\u7528\u6587\u5B57\u5F15\u7528\u3002
|
|
14122
|
+
9. \u4E3A\u56FE\u8868\u51C6\u5907\u6570\u636E\u65F6\uFF0C\u4F18\u5148\u8C03\u7528\u9AD8\u5C42\u5DE5\u5177\uFF08\u5982 get_time_stats\u3001member_stats\uFF09\u800C\u975E\u81EA\u5DF1\u5199 SQL\uFF1B\u53EA\u6709\u9AD8\u5C42\u5DE5\u5177\u65E0\u6CD5\u8986\u76D6\u6240\u9700\u7B5B\u9009\u6216\u805A\u5408\u65F6\u624D\u7528 sql\u3002render_chart \u4E0D\u8981\u7528\u4E8E\u5143\u6570\u636E\u63A2\u6D4B\u3001\u6807\u91CF\u67E5\u8BE2\u3001\u5355\u884C\u65E5\u671F\u5B57\u7B26\u4E32\u6216\u7EAF\u8BF4\u660E\u6027\u7ED3\u679C\u3002
|
|
14123
|
+
10. render_chart \u7684\u5DE5\u5177\u7ED3\u679C\u4F1A\u5305\u542B\u6570\u636E\u9884\u89C8\uFF08Data preview\uFF09\uFF1B\u7528\u5B83\u5206\u6790\u5CF0\u503C\u3001\u4F4E\u8C37\u548C\u5DEE\u5F02\uFF0C\u4E0D\u8981\u4E3A\u4E86\u8BFB\u53D6\u6570\u503C\u91CD\u590D\u751F\u6210\u7B49\u4EF7\u56FE\u8868\u3002
|
|
14124
|
+
11. \u56FE\u8868\u89E3\u91CA\u53EA\u80FD\u63CF\u8FF0\u6570\u636E\u76F4\u63A5\u652F\u6301\u7684\u8D8B\u52BF\u3001\u5CF0\u503C\u3001\u4F4E\u8C37\u3001\u5DEE\u5F02\u548C\u540C\u6B65\u6027\uFF0C\u7981\u6B62\u5938\u5F20\u62DF\u4EBA\u5316\u6216\u65E0\u6CD5\u4ECE\u56FE\u4E2D\u9A8C\u8BC1\u7684\u5173\u7CFB\u5224\u65AD\u3002
|
|
14096
14125
|
|
|
14097
14126
|
\u5DE5\u4F5C\u6D41\u7A0B\uFF1A
|
|
14098
14127
|
1. \u8C03\u7528 get_schema\u3002
|
|
14099
|
-
2. \u6839\u636E schema
|
|
14100
|
-
3. \
|
|
14101
|
-
4. \
|
|
14102
|
-
5. \
|
|
14128
|
+
2. \u6839\u636E schema\u3001\u7528\u6237\u8981\u6C42\u3001\u7CFB\u7EDF\u5F53\u524D\u65E5\u671F\u548C\u542F\u52A8\u4E0A\u4E0B\u6587\u786E\u5B9A\u7EDF\u8BA1\u5BF9\u8C61\u3001\u65F6\u95F4\u8303\u56F4\u3001\u7EF4\u5EA6\u3001\u6307\u6807\u548C\u56FE\u8868\u7C7B\u578B\u3002
|
|
14129
|
+
3. \u5982\u9700\u8C03\u67E5\u4E8B\u5B9E\u3001\u5EFA\u7ACB\u8BDD\u9898\u5730\u56FE\u3001\u7B5B\u9009\u6210\u5458\u6216\u786E\u8BA4\u7EDF\u8BA1\u53E3\u5F84\uFF0C\u5148\u7528\u53EF\u7528\u7684\u666E\u901A\u5206\u6790\u5DE5\u5177\u5B8C\u6210\uFF1B\u4E0D\u8981\u4E3A\u4E86\u8C03\u67E5\u800C\u751F\u6210\u4E34\u65F6\u56FE\u8868\u3002
|
|
14130
|
+
4. \u51C6\u5907\u56FE\u8868\u6570\u636E\u2014\u2014\u5148\u95EE\u81EA\u5DF1\uFF1A\u54EA\u4E2A\u53EF\u7528\u7684\u9AD8\u5C42\u5DE5\u5177\u80FD\u76F4\u63A5\u63D0\u4F9B\u8FD9\u5F20\u56FE\u6240\u9700\u7684\u6570\u636E\uFF1Fget_time_stats \u80FD\u7ED9\u65F6\u95F4\u5206\u5E03\u3001member_stats \u80FD\u7ED9\u6210\u5458\u6392\u540D\uFF1B\u80FD\u7528\u5C31\u8C03\u7528\uFF0C\u5C06 data \u6570\u7EC4\u4F5C\u4E3A rows \u4F20\u5165 render_chart\u3002\u53EA\u6709\u5728\u9AD8\u5C42\u5DE5\u5177\u65E0\u6CD5\u8986\u76D6\u6240\u9700\u7B5B\u9009\u6216\u805A\u5408\u65F6\uFF0C\u624D\u7F16\u5199 SQL\u3002
|
|
14131
|
+
5. \u5728\u5E0C\u671B\u56FE\u8868\u51FA\u73B0\u7684\u4F4D\u7F6E\u8C03\u7528 render_chart\uFF0C\u63D0\u4EA4\u6570\u636E\uFF08rows \u6216 sql\uFF09\u548C ChartSpec v1\u3002
|
|
14132
|
+
6. \u56FE\u8868\u751F\u6210\u540E\uFF0C\u7528 1-3 \u53E5\u7B80\u6D01\u6587\u5B57\u89E3\u91CA\u7ED3\u8BBA\u3002\u7528\u6237\u8981\u6C42\u591A\u5F20\u56FE\u65F6\uFF0C\u53EF\u4EE5\u591A\u6B21\u8C03\u7528 render_chart\uFF0C\u5E76\u628A\u6BCF\u5F20\u56FE\u653E\u5728\u6700\u76F8\u5173\u7684\u6BB5\u843D\u9644\u8FD1\u3002
|
|
14103
14133
|
|
|
14104
14134
|
\u5E38\u7528\u8BED\u3001\u53E3\u5934\u7985\u3001\u9AD8\u9891\u77ED\u53E5\u7C7B\u56FE\u8868\u5FC5\u987B\u6392\u9664\u975E\u771F\u4EBA\u6587\u672C\uFF1A\u53D1\u9001\u8005\u4E3A\u7CFB\u7EDF\u6D88\u606F\u3001\u5A92\u4F53\u5360\u4F4D\uFF08\u5982 [\u8868\u60C5\u5305]\u3001[\u56FE\u7247]\u3001[\u8BED\u97F3]\u3001[\u89C6\u9891]\u3001[\u6587\u4EF6]\u3001[\u94FE\u63A5]\u3001[\u7EA2\u5305]\u3001[\u8F6C\u8D26]\uFF09\u4EE5\u53CA\u64A4\u56DE/\u5220\u9664\u63D0\u793A\u90FD\u4E0D\u80FD\u8FDB\u5165\u7EDF\u8BA1\u3002
|
|
14105
14135
|
|
|
@@ -14121,23 +14151,28 @@ ChartSpec \u793A\u4F8B\uFF1A
|
|
|
14121
14151
|
\u7528\u6237\u660E\u786E\u8981\u6C42\u56FE\u8868\u65F6\u5FC5\u987B\u5C1D\u8BD5\u751F\u6210\u3002\u7528\u6237\u6CA1\u6709\u660E\u786E\u8981\u6C42\u65F6\uFF0C\u53EA\u6709\u6392\u540D\u3001\u8D8B\u52BF\u3001\u5206\u5E03\u3001\u5360\u6BD4\u6216\u4E8C\u7EF4\u5BC6\u5EA6\u660E\u663E\u66F4\u6E05\u695A\u65F6\u624D\u4E3B\u52A8\u751F\u6210\uFF0C\u4E14\u9ED8\u8BA4\u6700\u591A\u4E00\u5F20\u3002`;
|
|
14122
14152
|
var EN_PROMPT = `You are the ChatLab Chart Assistant. In this turn, the user wants one or more charts embedded naturally in the answer.
|
|
14123
14153
|
|
|
14124
|
-
You must generate charts through the render_chart tool. Do not output HTML, JavaScript, SVG, Canvas, ECharts options, or rendering code.
|
|
14154
|
+
You must generate charts through the render_chart tool. Do not output HTML, JavaScript, SVG, Canvas, ECharts options, Markdown image links such as , or rendering code.
|
|
14125
14155
|
|
|
14126
14156
|
Hard rules:
|
|
14127
14157
|
1. Always call get_schema before writing the first SQL query. Do not guess table names, field names, or timestamp fields.
|
|
14128
|
-
2. For
|
|
14158
|
+
2. For relative ranges like "recent" or "past N days/years", use the real current date from the system prompt as the baseline. If startup context shows incomplete database coverage, analyze only the intersection between the requested range and database coverage, and state the gap.
|
|
14129
14159
|
3. ChatLab message.ts is a Unix timestamp in seconds. Use date(ts, 'unixepoch', 'localtime'); never write ts/1000.
|
|
14130
14160
|
4. For "latest N members" or "recent N people", first define and select those N members from the data, then count only those members.
|
|
14131
14161
|
5. For multi-series line charts, every line must have an explicit series field. For daily counts, fill the date x series grid with zero values so missing days do not break or mislead the line.
|
|
14132
|
-
6. Do not include failed SQL attempts, schema exploration, or retry reasoning in the final answer. Final answer should contain only
|
|
14133
|
-
7.
|
|
14162
|
+
6. Do not include failed SQL attempts, schema exploration, or retry reasoning in the final answer. Final answer should contain only native charts and a short conclusion; never reference charts with filenames like chart1.png or chart2.png.
|
|
14163
|
+
7. When you call render_chart, ChatLab immediately inserts the native chart at that position. If a chart is needed, call the tool directly; do not write SQL-comment placeholders, Markdown images, or text such as "generated chart" or "see chart above".
|
|
14164
|
+
8. If the user asks for multiple charts, place each chart near the relevant summary or explanation. Do not generate all charts together and then reference them later with text.
|
|
14165
|
+
9. When preparing chart data, prefer calling a high-level tool (such as get_time_stats, member_stats) over writing SQL; only use sql when no high-level tool can satisfy the required filters or aggregations. Do not use render_chart for metadata inspection, scalar queries, single-row date strings, or purely explanatory results.
|
|
14166
|
+
10. render_chart tool results include a Data preview; use it to identify peaks, lows, and differences. Do not generate equivalent charts again just to read values.
|
|
14167
|
+
11. Explain only trends, peaks, lows, differences, and synchrony directly supported by chart data. Do not make exaggerated personality or relationship claims.
|
|
14134
14168
|
|
|
14135
14169
|
Workflow:
|
|
14136
14170
|
1. Call get_schema.
|
|
14137
|
-
2. Derive the target members, time range, dimensions, metrics, and chart type from schema
|
|
14138
|
-
3.
|
|
14139
|
-
4.
|
|
14140
|
-
5.
|
|
14171
|
+
2. Derive the target members, time range, dimensions, metrics, and chart type from schema, the user request, system current date, and startup context.
|
|
14172
|
+
3. If you need to investigate facts, build a topic map, select members, or confirm statistical definitions, use available ordinary analysis tools first; do not generate temporary charts for investigation.
|
|
14173
|
+
4. Prepare chart data \u2014 ask yourself first: which available high-level tool can directly provide the data this chart needs? get_time_stats covers time distributions; member_stats covers member rankings. If one fits, call it and pass its data array as rows to render_chart. Only write SQL when no high-level tool can cover the required filters or aggregations.
|
|
14174
|
+
5. Call render_chart at the position where the chart should appear, with data (rows or sql) and ChartSpec v1.
|
|
14175
|
+
6. After the chart is generated, explain the key finding in 1-3 concise sentences. If the user asks for multiple charts, call render_chart multiple times and place each chart near its most relevant section.
|
|
14141
14176
|
|
|
14142
14177
|
For catchphrase, common phrase, or frequent short-text charts, exclude non-human text from the SQL: system-message senders, media placeholders such as [Sticker], [Image], [Photo], [Voice], [Video], [File], [Link], and recall/deletion notices must not be counted.
|
|
14143
14178
|
|
|
@@ -14964,7 +14999,7 @@ import {
|
|
|
14964
14999
|
} from "@earendil-works/pi-ai";
|
|
14965
15000
|
|
|
14966
15001
|
// ../../packages/node-runtime/src/ai/agent/constants.ts
|
|
14967
|
-
var DEFAULT_MAX_TOOL_ROUNDS =
|
|
15002
|
+
var DEFAULT_MAX_TOOL_ROUNDS = 20;
|
|
14968
15003
|
|
|
14969
15004
|
// ../../packages/node-runtime/src/ai/agent/core.ts
|
|
14970
15005
|
function createEmptyPiUsage() {
|
|
@@ -15045,14 +15080,6 @@ async function runAgentCore(options) {
|
|
|
15045
15080
|
return clampThinkingLevel(piModel, level);
|
|
15046
15081
|
})();
|
|
15047
15082
|
const finalThinkingLevel = resolvedThinkingLevel ?? (piModel.reasoning ? void 0 : "off");
|
|
15048
|
-
console.debug("[agent-core] thinkingLevel resolution:", {
|
|
15049
|
-
input: options.thinkingLevel,
|
|
15050
|
-
modelId: piModel.id,
|
|
15051
|
-
modelReasoning: effectiveModel.reasoning,
|
|
15052
|
-
isDefault,
|
|
15053
|
-
resolved: resolvedThinkingLevel,
|
|
15054
|
-
final: finalThinkingLevel
|
|
15055
|
-
});
|
|
15056
15083
|
const coreAgent = new PiAgentCore({
|
|
15057
15084
|
initialState: {
|
|
15058
15085
|
systemPrompt,
|
|
@@ -15182,6 +15209,584 @@ async function runAgentCore(options) {
|
|
|
15182
15209
|
}
|
|
15183
15210
|
}
|
|
15184
15211
|
|
|
15212
|
+
// ../../packages/node-runtime/src/ai/agent/data-snapshot.ts
|
|
15213
|
+
function roundShare(value) {
|
|
15214
|
+
if (!Number.isFinite(value)) return 0;
|
|
15215
|
+
return Math.round(value * 10) / 10;
|
|
15216
|
+
}
|
|
15217
|
+
function formatNullableTimestamp(timestamp) {
|
|
15218
|
+
return typeof timestamp === "number" && Number.isFinite(timestamp) ? String(timestamp) : "null";
|
|
15219
|
+
}
|
|
15220
|
+
function formatSharePercent(share) {
|
|
15221
|
+
if (!Number.isFinite(share)) return "0%";
|
|
15222
|
+
const rounded = Math.round(share * 10) / 10;
|
|
15223
|
+
return Number.isInteger(rounded) ? `${rounded}%` : `${rounded.toFixed(1)}%`;
|
|
15224
|
+
}
|
|
15225
|
+
function createDataSnapshotFromOverview(overview) {
|
|
15226
|
+
if (!overview) return void 0;
|
|
15227
|
+
const topMembers = overview.topMembers ?? [];
|
|
15228
|
+
return {
|
|
15229
|
+
version: 2,
|
|
15230
|
+
name: overview.name,
|
|
15231
|
+
platform: overview.platform,
|
|
15232
|
+
type: overview.type,
|
|
15233
|
+
totalMessages: overview.totalMessages,
|
|
15234
|
+
totalMembers: overview.totalMembers,
|
|
15235
|
+
firstMessageTs: overview.firstMessageTs,
|
|
15236
|
+
lastMessageTs: overview.lastMessageTs,
|
|
15237
|
+
activeMemberHints: topMembers.slice(0, 10).map((member) => ({
|
|
15238
|
+
memberId: member.id,
|
|
15239
|
+
displayName: member.name,
|
|
15240
|
+
messageCount: member.count,
|
|
15241
|
+
share: overview.totalMessages > 0 ? roundShare(member.count / overview.totalMessages * 100) : 0
|
|
15242
|
+
})),
|
|
15243
|
+
segmentSummaries: {
|
|
15244
|
+
availableCount: overview.summaryCount ?? 0
|
|
15245
|
+
}
|
|
15246
|
+
};
|
|
15247
|
+
}
|
|
15248
|
+
function formatDataSnapshotForRouter(dataSnapshot) {
|
|
15249
|
+
if (!dataSnapshot) return "(none)";
|
|
15250
|
+
return [
|
|
15251
|
+
`name: ${dataSnapshot.name}`,
|
|
15252
|
+
`platform: ${dataSnapshot.platform}`,
|
|
15253
|
+
`type: ${dataSnapshot.type}`,
|
|
15254
|
+
`total_messages: ${dataSnapshot.totalMessages}`,
|
|
15255
|
+
`total_members: ${dataSnapshot.totalMembers}`,
|
|
15256
|
+
`first_message_ts: ${formatNullableTimestamp(dataSnapshot.firstMessageTs)}`,
|
|
15257
|
+
`last_message_ts: ${formatNullableTimestamp(dataSnapshot.lastMessageTs)}`,
|
|
15258
|
+
`segment_summaries_available: ${dataSnapshot.segmentSummaries?.availableCount ?? 0}`,
|
|
15259
|
+
`active_member_hint_count: ${dataSnapshot.activeMemberHints?.length ?? 0}`
|
|
15260
|
+
].join("\n");
|
|
15261
|
+
}
|
|
15262
|
+
function formatDataSnapshotForPlanner(dataSnapshot) {
|
|
15263
|
+
if (!dataSnapshot) return "(none)";
|
|
15264
|
+
const memberHints = dataSnapshot.activeMemberHints ?? [];
|
|
15265
|
+
const memberHintLines = memberHints.length > 0 ? memberHints.map(
|
|
15266
|
+
(member, index) => `${index + 1}. member_id=${member.memberId} | display_name=${member.displayName} | messages=${member.messageCount} | share=${formatSharePercent(member.share)}`
|
|
15267
|
+
).join("\n") : "(none)";
|
|
15268
|
+
return `${formatDataSnapshotForRouter(dataSnapshot)}
|
|
15269
|
+
active_member_hints:
|
|
15270
|
+
${memberHintLines}
|
|
15271
|
+
notes:
|
|
15272
|
+
- member_id is a tool lookup hint; display_name may not be unique.
|
|
15273
|
+
- Active member hints reflect historical total message volume, not recent activity.
|
|
15274
|
+
- Use real current date for relative ranges; database bounds only describe data coverage.
|
|
15275
|
+
- Do not plan a tool call only to rediscover min/max timestamp.
|
|
15276
|
+
- When using default recent-day tools, choose a range that intersects database bounds instead of probing an empty real-current-date window first.`;
|
|
15277
|
+
}
|
|
15278
|
+
|
|
15279
|
+
// ../../packages/node-runtime/src/ai/agent/router.ts
|
|
15280
|
+
import {
|
|
15281
|
+
completeSimple as completeSimple2
|
|
15282
|
+
} from "@earendil-works/pi-ai";
|
|
15283
|
+
var DEFAULT_LLM_FALLBACK_CONFIDENCE_THRESHOLD = 0.6;
|
|
15284
|
+
function clampConfidence(value) {
|
|
15285
|
+
if (!Number.isFinite(value)) return 0;
|
|
15286
|
+
return Math.max(0, Math.min(1, value));
|
|
15287
|
+
}
|
|
15288
|
+
function normalizeText(text) {
|
|
15289
|
+
return text.trim().replace(/\s+/g, " ");
|
|
15290
|
+
}
|
|
15291
|
+
function matchAny(text, patterns) {
|
|
15292
|
+
return patterns.some((pattern) => pattern.test(text));
|
|
15293
|
+
}
|
|
15294
|
+
function isRoute(value) {
|
|
15295
|
+
return value === "direct_response" || value === "tool_assisted" || value === "planned_execution";
|
|
15296
|
+
}
|
|
15297
|
+
function resultToText(result) {
|
|
15298
|
+
return typeof result === "string" ? { text: result } : result;
|
|
15299
|
+
}
|
|
15300
|
+
function extractJsonObject3(text) {
|
|
15301
|
+
const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
15302
|
+
if (fenced?.[1]) return fenced[1].trim();
|
|
15303
|
+
const start = text.indexOf("{");
|
|
15304
|
+
const end = text.lastIndexOf("}");
|
|
15305
|
+
if (start >= 0 && end > start) return text.slice(start, end + 1);
|
|
15306
|
+
return text.trim();
|
|
15307
|
+
}
|
|
15308
|
+
function parseLlmDecision(rawText, usage) {
|
|
15309
|
+
try {
|
|
15310
|
+
const parsed = JSON.parse(extractJsonObject3(rawText));
|
|
15311
|
+
if (!isRoute(parsed.route)) return null;
|
|
15312
|
+
return {
|
|
15313
|
+
route: parsed.route,
|
|
15314
|
+
confidence: clampConfidence(typeof parsed.confidence === "number" ? parsed.confidence : 0.5),
|
|
15315
|
+
reason: typeof parsed.reason === "string" && parsed.reason.trim() ? parsed.reason.trim() : "LLM route decision.",
|
|
15316
|
+
source: "llm",
|
|
15317
|
+
usage
|
|
15318
|
+
};
|
|
15319
|
+
} catch {
|
|
15320
|
+
return null;
|
|
15321
|
+
}
|
|
15322
|
+
}
|
|
15323
|
+
function buildLlmRouterPrompt(input, ruleDecision2) {
|
|
15324
|
+
const toolNames = input.availableTools?.length ? input.availableTools.join(", ") : "(none)";
|
|
15325
|
+
const dataSnapshot = formatDataSnapshotForRouter(input.dataSnapshot);
|
|
15326
|
+
return `Classify the user's ChatLab request into exactly one route.
|
|
15327
|
+
|
|
15328
|
+
Routes:
|
|
15329
|
+
- direct_response: no local chat data/tools needed.
|
|
15330
|
+
- tool_assisted: local chat data/tools needed, but the task is simple.
|
|
15331
|
+
- planned_execution: complex analysis, multi-step evidence gathering, retries, long-range comparison, relationship analysis, or insufficient-evidence handling.
|
|
15332
|
+
|
|
15333
|
+
Return strict JSON only:
|
|
15334
|
+
{"route":"direct_response|tool_assisted|planned_execution","confidence":0.0,"reason":"short reason"}
|
|
15335
|
+
|
|
15336
|
+
Context:
|
|
15337
|
+
- locale: ${input.locale}
|
|
15338
|
+
- chatType: ${input.chatType}
|
|
15339
|
+
- availableTools: ${toolNames}
|
|
15340
|
+
- dataSnapshot: ${dataSnapshot}
|
|
15341
|
+
- assistantSummary: ${input.assistantSummary ?? "(none)"}
|
|
15342
|
+
- skillSummary: ${input.skillSummary ?? "(none)"}
|
|
15343
|
+
- recentIntentSummary: ${input.recentIntentSummary ?? "(none)"}
|
|
15344
|
+
- ruleDecision: ${ruleDecision2.route}, confidence=${ruleDecision2.confidence}, reason=${ruleDecision2.reason}
|
|
15345
|
+
|
|
15346
|
+
User request:
|
|
15347
|
+
${input.userMessage}`;
|
|
15348
|
+
}
|
|
15349
|
+
function directRuleDecision(text) {
|
|
15350
|
+
if (matchAny(text, [/不用查聊天记录|不用查询|不用查数据|不用看本地数据/i, /润色|改写|翻译|polish|rewrite|translate/i])) {
|
|
15351
|
+
return {
|
|
15352
|
+
route: "direct_response",
|
|
15353
|
+
confidence: 0.95,
|
|
15354
|
+
reason: "User explicitly asked for a non-data response.",
|
|
15355
|
+
source: "rule"
|
|
15356
|
+
};
|
|
15357
|
+
}
|
|
15358
|
+
if (matchAny(text, [/什么是|解释一下|概念|区别|explain|briefly explain|why .*function calling|react/i])) {
|
|
15359
|
+
return {
|
|
15360
|
+
route: "direct_response",
|
|
15361
|
+
confidence: 0.86,
|
|
15362
|
+
reason: "Conceptual explanation without local chat-data dependency.",
|
|
15363
|
+
source: "rule"
|
|
15364
|
+
};
|
|
15365
|
+
}
|
|
15366
|
+
if (matchAny(text, [/日志在哪里|怎么配置|设置|帮助|help|where .*log/i])) {
|
|
15367
|
+
return {
|
|
15368
|
+
route: "direct_response",
|
|
15369
|
+
confidence: 0.84,
|
|
15370
|
+
reason: "Help or configuration request does not require chat tools.",
|
|
15371
|
+
source: "rule"
|
|
15372
|
+
};
|
|
15373
|
+
}
|
|
15374
|
+
if (matchAny(text, [/你觉得|闲聊|随便聊聊|建议我|should i/i])) {
|
|
15375
|
+
return {
|
|
15376
|
+
route: "direct_response",
|
|
15377
|
+
confidence: 0.78,
|
|
15378
|
+
reason: "Conversational request without clear data dependency.",
|
|
15379
|
+
source: "rule"
|
|
15380
|
+
};
|
|
15381
|
+
}
|
|
15382
|
+
return null;
|
|
15383
|
+
}
|
|
15384
|
+
function plannedRuleDecision(text) {
|
|
15385
|
+
if (matchAny(text, [/如果.*找不到.*继续查|换几个相关|换几个.*继续|search.*if.*not.*found/i])) {
|
|
15386
|
+
return {
|
|
15387
|
+
route: "planned_execution",
|
|
15388
|
+
confidence: 0.88,
|
|
15389
|
+
reason: "Request asks for search failure recovery and retry strategy.",
|
|
15390
|
+
source: "rule"
|
|
15391
|
+
};
|
|
15392
|
+
}
|
|
15393
|
+
const dimensions = [
|
|
15394
|
+
matchAny(text, [/分析|复盘|总结.*规律|趋势|变化|演变|compare|comparison/i]),
|
|
15395
|
+
matchAny(text, [
|
|
15396
|
+
/过去一年|最近一年|近一年|过去.*年|最近半年|今年|去年|上半年|下半年|长期|按季度|按月份|first half|second half/i
|
|
15397
|
+
]),
|
|
15398
|
+
matchAny(text, [/关系|互动|影响力|核心成员|最强|最活跃|被忽略|主动|回应|turning point|转折点/i]),
|
|
15399
|
+
matchAny(text, [/证据|举出|例子|关键分歧|主要矛盾|evidence/i]),
|
|
15400
|
+
matchAny(text, [/并且|同时|以及|分别|每个阶段|按阶段|阶段|多条件|参与|回复|话题|主题|发言规律|topic|theme/i]),
|
|
15401
|
+
matchAny(text, [/证据不够|不足以|不够|uncertain|insufficient/i])
|
|
15402
|
+
];
|
|
15403
|
+
const score = dimensions.filter(Boolean).length;
|
|
15404
|
+
if (score >= 2) {
|
|
15405
|
+
return {
|
|
15406
|
+
route: "planned_execution",
|
|
15407
|
+
confidence: Math.min(0.95, 0.72 + score * 0.04),
|
|
15408
|
+
reason: `Rule matched ${score} complex-analysis signals.`,
|
|
15409
|
+
source: "rule"
|
|
15410
|
+
};
|
|
15411
|
+
}
|
|
15412
|
+
return null;
|
|
15413
|
+
}
|
|
15414
|
+
function toolRuleDecision(text) {
|
|
15415
|
+
if (matchAny(text, [
|
|
15416
|
+
/一共有多少|多少成员|多少条消息|谁发言最多|前\s*\d+\s*名|top\s*\d+/i,
|
|
15417
|
+
/异常活跃|活跃度|发言最多|message count|member count/i
|
|
15418
|
+
])) {
|
|
15419
|
+
return {
|
|
15420
|
+
route: "tool_assisted",
|
|
15421
|
+
confidence: 0.82,
|
|
15422
|
+
reason: "Simple statistics request can be answered by one or a few tools.",
|
|
15423
|
+
source: "rule"
|
|
15424
|
+
};
|
|
15425
|
+
}
|
|
15426
|
+
if (matchAny(text, [
|
|
15427
|
+
/找一下|查一下|有没有聊到|有没有提过|最近提到|昨天.*聊了什么|最近.*发言/i,
|
|
15428
|
+
/search|find|mentioned|talked about/i
|
|
15429
|
+
])) {
|
|
15430
|
+
return {
|
|
15431
|
+
route: "tool_assisted",
|
|
15432
|
+
confidence: 0.78,
|
|
15433
|
+
reason: "Simple search or lookup request with a single clear target.",
|
|
15434
|
+
source: "rule"
|
|
15435
|
+
};
|
|
15436
|
+
}
|
|
15437
|
+
return null;
|
|
15438
|
+
}
|
|
15439
|
+
function ruleDecision(input) {
|
|
15440
|
+
const text = normalizeText(input.userMessage);
|
|
15441
|
+
return plannedRuleDecision(text) ?? toolRuleDecision(text) ?? directRuleDecision(text) ?? {
|
|
15442
|
+
route: "tool_assisted",
|
|
15443
|
+
confidence: 0.45,
|
|
15444
|
+
reason: "Ambiguous request; conservatively keep the existing tool-assisted Agent path.",
|
|
15445
|
+
source: "rule"
|
|
15446
|
+
};
|
|
15447
|
+
}
|
|
15448
|
+
async function decideRequestRoute(input, options = {}) {
|
|
15449
|
+
const decision = ruleDecision(input);
|
|
15450
|
+
const threshold = options.llmFallbackConfidenceThreshold ?? DEFAULT_LLM_FALLBACK_CONFIDENCE_THRESHOLD;
|
|
15451
|
+
if (decision.confidence >= threshold || !options.llmRouter) {
|
|
15452
|
+
return { ...decision, confidence: clampConfidence(decision.confidence) };
|
|
15453
|
+
}
|
|
15454
|
+
const llmDecision = await options.llmRouter(input, decision);
|
|
15455
|
+
return {
|
|
15456
|
+
...llmDecision,
|
|
15457
|
+
confidence: clampConfidence(llmDecision.confidence)
|
|
15458
|
+
};
|
|
15459
|
+
}
|
|
15460
|
+
function createLlmRouteDecider(options) {
|
|
15461
|
+
return async (input, ruleDecision2) => {
|
|
15462
|
+
const prompt = buildLlmRouterPrompt(input, ruleDecision2);
|
|
15463
|
+
try {
|
|
15464
|
+
const rawResult = options.complete ? await options.complete(prompt, options.abortSignal) : await completeWithPiAi(prompt, options);
|
|
15465
|
+
const { text, usage } = resultToText(rawResult);
|
|
15466
|
+
const decision = parseLlmDecision(text, usage);
|
|
15467
|
+
if (decision) return decision;
|
|
15468
|
+
return {
|
|
15469
|
+
...ruleDecision2,
|
|
15470
|
+
reason: `${ruleDecision2.reason} LLM fallback returned invalid route JSON.`
|
|
15471
|
+
};
|
|
15472
|
+
} catch (error) {
|
|
15473
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
15474
|
+
return {
|
|
15475
|
+
...ruleDecision2,
|
|
15476
|
+
reason: `${ruleDecision2.reason} LLM fallback failed: ${message}`
|
|
15477
|
+
};
|
|
15478
|
+
}
|
|
15479
|
+
};
|
|
15480
|
+
}
|
|
15481
|
+
async function completeWithPiAi(prompt, options) {
|
|
15482
|
+
if (!options.piModel || !options.apiKey) {
|
|
15483
|
+
throw new Error("LLM router requires piModel and apiKey");
|
|
15484
|
+
}
|
|
15485
|
+
const result = await completeSimple2(
|
|
15486
|
+
options.piModel,
|
|
15487
|
+
{
|
|
15488
|
+
systemPrompt: "You are a strict JSON classifier for ChatLab AI routing. Return JSON only.",
|
|
15489
|
+
messages: [{ role: "user", content: [{ type: "text", text: prompt }], timestamp: Date.now() }]
|
|
15490
|
+
},
|
|
15491
|
+
{
|
|
15492
|
+
apiKey: options.apiKey,
|
|
15493
|
+
maxTokens: options.maxTokens ?? 180,
|
|
15494
|
+
temperature: options.temperature ?? 0,
|
|
15495
|
+
signal: options.abortSignal
|
|
15496
|
+
}
|
|
15497
|
+
);
|
|
15498
|
+
const text = result.content.filter((item) => item.type === "text").map((item) => item.text).join("");
|
|
15499
|
+
return {
|
|
15500
|
+
text,
|
|
15501
|
+
usage: {
|
|
15502
|
+
promptTokens: result.usage?.input,
|
|
15503
|
+
completionTokens: result.usage?.output,
|
|
15504
|
+
totalTokens: result.usage?.totalTokens
|
|
15505
|
+
}
|
|
15506
|
+
};
|
|
15507
|
+
}
|
|
15508
|
+
|
|
15509
|
+
// ../../packages/node-runtime/src/ai/agent/planner.ts
|
|
15510
|
+
import {
|
|
15511
|
+
completeSimple as completeSimple3,
|
|
15512
|
+
streamSimple
|
|
15513
|
+
} from "@earendil-works/pi-ai";
|
|
15514
|
+
var PLAN_INTENTS = [
|
|
15515
|
+
"summary",
|
|
15516
|
+
"trend",
|
|
15517
|
+
"relationship",
|
|
15518
|
+
"search",
|
|
15519
|
+
"comparison",
|
|
15520
|
+
"mixed"
|
|
15521
|
+
];
|
|
15522
|
+
var STREAM_MARKER_HOLDBACK_CHARS = Math.max("</draft>".length, "</plan>".length, "<json>".length) - 1;
|
|
15523
|
+
function isRecord2(value) {
|
|
15524
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15525
|
+
}
|
|
15526
|
+
function isIntent(value) {
|
|
15527
|
+
return typeof value === "string" && PLAN_INTENTS.includes(value);
|
|
15528
|
+
}
|
|
15529
|
+
function normalizeString(value) {
|
|
15530
|
+
if (typeof value !== "string") return null;
|
|
15531
|
+
const text = value.trim();
|
|
15532
|
+
return text.length > 0 ? text : null;
|
|
15533
|
+
}
|
|
15534
|
+
function extractJsonObject4(text) {
|
|
15535
|
+
const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
15536
|
+
if (fenced?.[1]) return fenced[1].trim();
|
|
15537
|
+
const start = text.indexOf("{");
|
|
15538
|
+
const end = text.lastIndexOf("}");
|
|
15539
|
+
if (start >= 0 && end > start) return text.slice(start, end + 1);
|
|
15540
|
+
return text.trim();
|
|
15541
|
+
}
|
|
15542
|
+
function parsePlanJson(rawText, availableTools) {
|
|
15543
|
+
try {
|
|
15544
|
+
const parsed = JSON.parse(extractJsonObject4(rawText));
|
|
15545
|
+
if (!isRecord2(parsed)) return null;
|
|
15546
|
+
const title = normalizeString(parsed.title);
|
|
15547
|
+
if (!title || !isIntent(parsed.intent) || !Array.isArray(parsed.steps)) return null;
|
|
15548
|
+
const steps = parsed.steps.filter(isRecord2).map((step) => {
|
|
15549
|
+
const goal = normalizeString(step.goal);
|
|
15550
|
+
const evidenceNeeded = normalizeString(step.evidenceNeeded);
|
|
15551
|
+
if (!goal || !evidenceNeeded) return null;
|
|
15552
|
+
const suggestedTools = Array.isArray(step.suggestedTools) ? step.suggestedTools.filter((tool) => typeof tool === "string" && availableTools.has(tool)) : [];
|
|
15553
|
+
return { goal, suggestedTools: Array.from(new Set(suggestedTools)), evidenceNeeded };
|
|
15554
|
+
}).filter((step) => step !== null).slice(0, 5);
|
|
15555
|
+
if (steps.length === 0) return null;
|
|
15556
|
+
const successCriteria = Array.isArray(parsed.successCriteria) ? parsed.successCriteria.map(normalizeString).filter((item) => item !== null).slice(0, 5) : [];
|
|
15557
|
+
if (successCriteria.length === 0) return null;
|
|
15558
|
+
return {
|
|
15559
|
+
version: 1,
|
|
15560
|
+
title,
|
|
15561
|
+
route: "planned_execution",
|
|
15562
|
+
intent: parsed.intent,
|
|
15563
|
+
steps,
|
|
15564
|
+
successCriteria
|
|
15565
|
+
};
|
|
15566
|
+
} catch {
|
|
15567
|
+
return null;
|
|
15568
|
+
}
|
|
15569
|
+
}
|
|
15570
|
+
function resultToText2(result) {
|
|
15571
|
+
return typeof result === "string" ? result : result.text;
|
|
15572
|
+
}
|
|
15573
|
+
function buildPlannerPrompt(input) {
|
|
15574
|
+
const dataSnapshot = formatDataSnapshotForPlanner(input.dataSnapshot);
|
|
15575
|
+
const availableCapabilities = input.availableCapabilities && input.availableCapabilities.length > 0 ? input.availableCapabilities.map((capability) => {
|
|
15576
|
+
const tools = capability.tools.join(", ") || "none";
|
|
15577
|
+
return ` - ${capability.id} (${capability.label}; tools: ${tools}): ${capability.guidance}`;
|
|
15578
|
+
}).join("\n") : "(none)";
|
|
15579
|
+
return `Create a concise user-visible analysis plan for a ChatLab planned_execution request.
|
|
15580
|
+
|
|
15581
|
+
Return exactly three blocks:
|
|
15582
|
+
<draft>
|
|
15583
|
+
A brief user-visible planning note in the user's locale. Keep it high-level; do not reveal hidden chain-of-thought.
|
|
15584
|
+
</draft>
|
|
15585
|
+
<plan>
|
|
15586
|
+
A concise user-facing analysis approach in the user's locale. Do not include suggested tools, evidence fields, or success criteria; those details belong in <json>.
|
|
15587
|
+
</plan>
|
|
15588
|
+
<json>
|
|
15589
|
+
{
|
|
15590
|
+
"title": "short title",
|
|
15591
|
+
"intent": "summary|trend|relationship|search|comparison|mixed",
|
|
15592
|
+
"steps": [
|
|
15593
|
+
{"goal": "what to investigate", "suggestedTools": ["tool_name"], "evidenceNeeded": "what evidence is needed"}
|
|
15594
|
+
],
|
|
15595
|
+
"successCriteria": ["criterion"]
|
|
15596
|
+
}
|
|
15597
|
+
</json>
|
|
15598
|
+
|
|
15599
|
+
Limits:
|
|
15600
|
+
- Max 5 steps.
|
|
15601
|
+
- Max 5 successCriteria.
|
|
15602
|
+
- suggestedTools must come only from availableTools.
|
|
15603
|
+
- If availableCapabilities are listed, you may plan steps that use their tools when the capability helps the user.
|
|
15604
|
+
- Do not reveal hidden chain-of-thought; draft and plan are user-readable summaries only.
|
|
15605
|
+
- The plan is soft guidance, not a mandatory execution script.
|
|
15606
|
+
|
|
15607
|
+
Planning strategy:
|
|
15608
|
+
- For open-ended topic, community profile, influence, interaction-pattern, or multi-dimensional retrospective analysis, first plan a lightweight reconnaissance step to build a topic/member activity map before drawing conclusions.
|
|
15609
|
+
- Prefer segment summaries, keyword frequency, time distribution, member activity, and representative message retrieval when available.
|
|
15610
|
+
- Do not create a dedicated step whose only purpose is finding max timestamp or confirming latest message time.
|
|
15611
|
+
|
|
15612
|
+
Context:
|
|
15613
|
+
- locale: ${input.locale}
|
|
15614
|
+
- chatType: ${input.chatType}
|
|
15615
|
+
- availableTools: ${input.availableTools.join(", ") || "(none)"}
|
|
15616
|
+
- availableCapabilities:
|
|
15617
|
+
${availableCapabilities}
|
|
15618
|
+
- dataSnapshot: ${dataSnapshot}
|
|
15619
|
+
- assistantSummary: ${input.assistantSummary ?? "(none)"}
|
|
15620
|
+
- skillSummary: ${input.skillSummary ?? "(none)"}
|
|
15621
|
+
- recentIntentSummary: ${input.recentIntentSummary ?? "(none)"}
|
|
15622
|
+
|
|
15623
|
+
User request:
|
|
15624
|
+
${input.userMessage}`;
|
|
15625
|
+
}
|
|
15626
|
+
function createAnalysisPlanner(options) {
|
|
15627
|
+
return async (input, signal) => {
|
|
15628
|
+
try {
|
|
15629
|
+
const prompt = buildPlannerPrompt(input);
|
|
15630
|
+
const callbacks = {
|
|
15631
|
+
onPlanDelta: options.onPlanDelta ?? (() => {
|
|
15632
|
+
}),
|
|
15633
|
+
onThinkingDelta: options.onThinkingDelta,
|
|
15634
|
+
onThinkingEnd: options.onThinkingEnd,
|
|
15635
|
+
onValidationDelta: options.onValidationDelta,
|
|
15636
|
+
onValidationEnd: options.onValidationEnd
|
|
15637
|
+
};
|
|
15638
|
+
const rawResult = options.stream ? await options.stream(prompt, callbacks, signal) : options.complete ? await options.complete(prompt, signal) : options.onPlanDelta ? await streamWithPiAi(prompt, options, signal) : await completeWithPiAi2(prompt, options, signal);
|
|
15639
|
+
return parsePlanJson(resultToText2(rawResult), new Set(input.availableTools));
|
|
15640
|
+
} catch {
|
|
15641
|
+
return null;
|
|
15642
|
+
}
|
|
15643
|
+
};
|
|
15644
|
+
}
|
|
15645
|
+
function createPlanContentBlock(plan, status = "created") {
|
|
15646
|
+
return {
|
|
15647
|
+
type: "plan",
|
|
15648
|
+
version: 1,
|
|
15649
|
+
status,
|
|
15650
|
+
plan
|
|
15651
|
+
};
|
|
15652
|
+
}
|
|
15653
|
+
function buildPlanGuidance(plan) {
|
|
15654
|
+
const steps = plan.steps.map((step, index) => {
|
|
15655
|
+
const tools = step.suggestedTools.length > 0 ? step.suggestedTools.join(", ") : "none";
|
|
15656
|
+
return `${index + 1}. ${step.goal}
|
|
15657
|
+
Evidence needed: ${step.evidenceNeeded}
|
|
15658
|
+
Suggested tools: ${tools}`;
|
|
15659
|
+
}).join("\n");
|
|
15660
|
+
const successCriteria = plan.successCriteria.map((item) => `- ${item}`).join("\n");
|
|
15661
|
+
return `A suggested analysis plan is available below. Use it as guidance when helpful, but do not follow it mechanically if the user's question can be answered more directly.
|
|
15662
|
+
|
|
15663
|
+
Plan title: ${plan.title}
|
|
15664
|
+
Intent: ${plan.intent}
|
|
15665
|
+
|
|
15666
|
+
Steps:
|
|
15667
|
+
${steps}
|
|
15668
|
+
|
|
15669
|
+
Success criteria:
|
|
15670
|
+
${successCriteria}`;
|
|
15671
|
+
}
|
|
15672
|
+
async function completeWithPiAi2(prompt, options, signal) {
|
|
15673
|
+
if (!options.piModel || !options.apiKey) {
|
|
15674
|
+
throw new Error("Planner requires piModel and apiKey");
|
|
15675
|
+
}
|
|
15676
|
+
const result = await completeSimple3(
|
|
15677
|
+
options.piModel,
|
|
15678
|
+
{
|
|
15679
|
+
systemPrompt: "You are a strict planner for ChatLab analysis. Return the requested blocks only.",
|
|
15680
|
+
messages: [{ role: "user", content: [{ type: "text", text: prompt }], timestamp: Date.now() }]
|
|
15681
|
+
},
|
|
15682
|
+
{
|
|
15683
|
+
apiKey: options.apiKey,
|
|
15684
|
+
maxTokens: options.maxTokens ?? 900,
|
|
15685
|
+
temperature: options.temperature ?? 0.2,
|
|
15686
|
+
signal
|
|
15687
|
+
}
|
|
15688
|
+
);
|
|
15689
|
+
return {
|
|
15690
|
+
text: result.content.filter((item) => item.type === "text").map((item) => item.text).join("")
|
|
15691
|
+
};
|
|
15692
|
+
}
|
|
15693
|
+
function extractTaggedBlockText(rawText, tag, nextTags) {
|
|
15694
|
+
const openTag = `<${tag}>`;
|
|
15695
|
+
const closeTag = `</${tag}>`;
|
|
15696
|
+
const blockStart = rawText.indexOf(openTag);
|
|
15697
|
+
if (blockStart < 0) return "";
|
|
15698
|
+
const bodyStart = blockStart + openTag.length;
|
|
15699
|
+
const closeStart = rawText.indexOf(closeTag, bodyStart);
|
|
15700
|
+
const nextStarts = nextTags.map((nextTag) => rawText.indexOf(nextTag, bodyStart)).filter((index) => index >= 0);
|
|
15701
|
+
const endCandidates = [closeStart, ...nextStarts].filter((index) => index >= 0);
|
|
15702
|
+
const bodyEnd = endCandidates.length > 0 ? Math.min(...endCandidates) : Math.max(bodyStart, rawText.length - STREAM_MARKER_HOLDBACK_CHARS);
|
|
15703
|
+
const text = rawText.slice(bodyStart, bodyEnd);
|
|
15704
|
+
return text.replace(/^\s+/, "");
|
|
15705
|
+
}
|
|
15706
|
+
async function streamWithPiAi(prompt, options, signal) {
|
|
15707
|
+
if (!options.piModel || !options.apiKey) {
|
|
15708
|
+
throw new Error("Planner requires piModel and apiKey");
|
|
15709
|
+
}
|
|
15710
|
+
const stream = streamSimple(
|
|
15711
|
+
options.piModel,
|
|
15712
|
+
{
|
|
15713
|
+
systemPrompt: "You are a strict planner for ChatLab analysis. Return the requested plan and JSON blocks only.",
|
|
15714
|
+
messages: [{ role: "user", content: [{ type: "text", text: prompt }], timestamp: Date.now() }]
|
|
15715
|
+
},
|
|
15716
|
+
{
|
|
15717
|
+
apiKey: options.apiKey,
|
|
15718
|
+
maxTokens: options.maxTokens ?? 900,
|
|
15719
|
+
temperature: options.temperature ?? 0.2,
|
|
15720
|
+
signal
|
|
15721
|
+
}
|
|
15722
|
+
);
|
|
15723
|
+
let text = "";
|
|
15724
|
+
let emittedDraftLength = 0;
|
|
15725
|
+
let emittedPlanLength = 0;
|
|
15726
|
+
let emittedJsonLength = 0;
|
|
15727
|
+
let thinkingStartedAt;
|
|
15728
|
+
let draftThinkingStartedAt;
|
|
15729
|
+
let draftThinkingEnded = false;
|
|
15730
|
+
let validationStartedAt;
|
|
15731
|
+
let validationEnded = false;
|
|
15732
|
+
for await (const event of stream) {
|
|
15733
|
+
if (signal?.aborted) break;
|
|
15734
|
+
if (event.type === "thinking_start") {
|
|
15735
|
+
thinkingStartedAt = Date.now();
|
|
15736
|
+
continue;
|
|
15737
|
+
}
|
|
15738
|
+
if (event.type === "thinking_delta") {
|
|
15739
|
+
options.onThinkingDelta?.(event.delta);
|
|
15740
|
+
continue;
|
|
15741
|
+
}
|
|
15742
|
+
if (event.type === "thinking_end") {
|
|
15743
|
+
const durationMs = thinkingStartedAt ? Date.now() - thinkingStartedAt : void 0;
|
|
15744
|
+
thinkingStartedAt = void 0;
|
|
15745
|
+
options.onThinkingEnd?.(durationMs);
|
|
15746
|
+
continue;
|
|
15747
|
+
}
|
|
15748
|
+
if (event.type !== "text_delta") continue;
|
|
15749
|
+
text += event.delta;
|
|
15750
|
+
const draftText = extractTaggedBlockText(text, "draft", ["<plan>", "<json>"]);
|
|
15751
|
+
if (draftText.length > emittedDraftLength) {
|
|
15752
|
+
if (!draftThinkingStartedAt) draftThinkingStartedAt = Date.now();
|
|
15753
|
+
const delta = draftText.slice(emittedDraftLength);
|
|
15754
|
+
emittedDraftLength = draftText.length;
|
|
15755
|
+
if (delta.trim().length > 0 || /\s/.test(delta)) {
|
|
15756
|
+
options.onThinkingDelta?.(delta);
|
|
15757
|
+
}
|
|
15758
|
+
}
|
|
15759
|
+
if (!draftThinkingEnded && emittedDraftLength > 0 && (text.includes("</draft>") || text.includes("<plan>"))) {
|
|
15760
|
+
draftThinkingEnded = true;
|
|
15761
|
+
const durationMs = draftThinkingStartedAt ? Date.now() - draftThinkingStartedAt : void 0;
|
|
15762
|
+
options.onThinkingEnd?.(durationMs);
|
|
15763
|
+
}
|
|
15764
|
+
const planText = extractTaggedBlockText(text, "plan", ["<json>"]);
|
|
15765
|
+
if (planText.length > emittedPlanLength) {
|
|
15766
|
+
const delta = planText.slice(emittedPlanLength);
|
|
15767
|
+
emittedPlanLength = planText.length;
|
|
15768
|
+
if (delta.trim().length > 0 || /\s/.test(delta)) {
|
|
15769
|
+
options.onPlanDelta?.(delta);
|
|
15770
|
+
}
|
|
15771
|
+
}
|
|
15772
|
+
const jsonText = extractTaggedBlockText(text, "json", []);
|
|
15773
|
+
if (jsonText.length > emittedJsonLength) {
|
|
15774
|
+
if (!validationStartedAt) validationStartedAt = Date.now();
|
|
15775
|
+
const delta = jsonText.slice(emittedJsonLength);
|
|
15776
|
+
emittedJsonLength = jsonText.length;
|
|
15777
|
+
if (delta.trim().length > 0 || /\s/.test(delta)) {
|
|
15778
|
+
options.onValidationDelta?.(delta);
|
|
15779
|
+
}
|
|
15780
|
+
}
|
|
15781
|
+
if (!validationEnded && emittedJsonLength > 0 && text.includes("</json>")) {
|
|
15782
|
+
validationEnded = true;
|
|
15783
|
+
const durationMs = validationStartedAt ? Date.now() - validationStartedAt : void 0;
|
|
15784
|
+
options.onValidationEnd?.(durationMs);
|
|
15785
|
+
}
|
|
15786
|
+
}
|
|
15787
|
+
return { text };
|
|
15788
|
+
}
|
|
15789
|
+
|
|
15185
15790
|
// ../../packages/node-runtime/src/ai/agent/event-handler.ts
|
|
15186
15791
|
function estimateTokensFromText(text) {
|
|
15187
15792
|
if (!text) return 0;
|
|
@@ -15318,6 +15923,39 @@ var AgentEventHandler = class {
|
|
|
15318
15923
|
function agentT(t2, key, locale, options) {
|
|
15319
15924
|
return t2(key, { lng: locale, ...options });
|
|
15320
15925
|
}
|
|
15926
|
+
function formatNullableTimestamp2(timestamp) {
|
|
15927
|
+
return typeof timestamp === "number" && Number.isFinite(timestamp) ? String(timestamp) : "null";
|
|
15928
|
+
}
|
|
15929
|
+
function formatSharePercent2(share) {
|
|
15930
|
+
if (!Number.isFinite(share)) return "0%";
|
|
15931
|
+
const rounded = Math.round(share * 10) / 10;
|
|
15932
|
+
return Number.isInteger(rounded) ? `${rounded}%` : `${rounded.toFixed(1)}%`;
|
|
15933
|
+
}
|
|
15934
|
+
function normalizeInlineText(text) {
|
|
15935
|
+
return text.replace(/\s+/g, " ").trim();
|
|
15936
|
+
}
|
|
15937
|
+
function formatDataSnapshotContext(t2, dataSnapshot, locale) {
|
|
15938
|
+
const memberHints = dataSnapshot.activeMemberHints ?? [];
|
|
15939
|
+
const memberHintTitle = memberHints.length === 0 ? agentT(t2, "ai.agent.dataSnapshotMemberHintsUnavailable", locale) : dataSnapshot.totalMembers <= 10 ? agentT(t2, "ai.agent.dataSnapshotMemberHintsAll", locale) : agentT(t2, "ai.agent.dataSnapshotMemberHintsTop", locale);
|
|
15940
|
+
const memberHintLines = memberHints.length > 0 ? memberHints.map((member, index) => {
|
|
15941
|
+
return `${index + 1}. member_id=${member.memberId} | display_name=${normalizeInlineText(member.displayName)} | messages=${member.messageCount} | share=${formatSharePercent2(member.share)}`;
|
|
15942
|
+
}).join("\n") : agentT(t2, "ai.agent.dataSnapshotMemberHintsEmpty", locale);
|
|
15943
|
+
return agentT(t2, "ai.agent.dataSnapshotContext", locale, {
|
|
15944
|
+
name: dataSnapshot.name,
|
|
15945
|
+
platform: dataSnapshot.platform,
|
|
15946
|
+
type: dataSnapshot.type,
|
|
15947
|
+
totalMessages: dataSnapshot.totalMessages,
|
|
15948
|
+
totalMembers: dataSnapshot.totalMembers,
|
|
15949
|
+
firstMessageTs: formatNullableTimestamp2(dataSnapshot.firstMessageTs),
|
|
15950
|
+
firstMessageTime: formatTimestamp(dataSnapshot.firstMessageTs, locale),
|
|
15951
|
+
lastMessageTs: formatNullableTimestamp2(dataSnapshot.lastMessageTs),
|
|
15952
|
+
lastMessageTime: formatTimestamp(dataSnapshot.lastMessageTs, locale),
|
|
15953
|
+
segmentSummaryCount: dataSnapshot.segmentSummaries?.availableCount ?? 0,
|
|
15954
|
+
memberHintTitle,
|
|
15955
|
+
memberHintLines,
|
|
15956
|
+
usageRules: agentT(t2, "ai.agent.dataSnapshotUsageRules", locale)
|
|
15957
|
+
});
|
|
15958
|
+
}
|
|
15321
15959
|
function getLockedPromptSection(t2, chatType, ownerInfo, locale, mentionedMembers, dataSnapshot) {
|
|
15322
15960
|
const now = /* @__PURE__ */ new Date();
|
|
15323
15961
|
const dateLocale = locale.startsWith("zh") ? "zh-CN" : "en-US";
|
|
@@ -15342,14 +15980,7 @@ ${mentionedMembers.map((member) => {
|
|
|
15342
15980
|
}).join("\n")}
|
|
15343
15981
|
` : "";
|
|
15344
15982
|
const year = now.getFullYear();
|
|
15345
|
-
const dataSnapshotNote = dataSnapshot ? `${
|
|
15346
|
-
name: dataSnapshot.name,
|
|
15347
|
-
platform: dataSnapshot.platform,
|
|
15348
|
-
totalMessages: dataSnapshot.totalMessages,
|
|
15349
|
-
totalMembers: dataSnapshot.totalMembers,
|
|
15350
|
-
firstMessageDate: formatTimestamp(dataSnapshot.firstMessageTs, locale),
|
|
15351
|
-
lastMessageDate: formatTimestamp(dataSnapshot.lastMessageTs, locale)
|
|
15352
|
-
})}
|
|
15983
|
+
const dataSnapshotNote = dataSnapshot ? `${formatDataSnapshotContext(t2, dataSnapshot, locale)}
|
|
15353
15984
|
` : "";
|
|
15354
15985
|
return `${agentT(t2, "ai.agent.currentDateIs", locale)} ${currentDate}\u3002
|
|
15355
15986
|
${ownerNote}
|
|
@@ -15463,7 +16094,7 @@ var zh_CN_default = {
|
|
|
15463
16094
|
}
|
|
15464
16095
|
},
|
|
15465
16096
|
get_time_stats: {
|
|
15466
|
-
desc: '\u83B7\u53D6\u7FA4\u804A\u7684\u65F6\u95F4\u5206\u5E03\u7EDF\u8BA1\u3002\u9002\u7528\u4E8E\u56DE\u7B54"\u4EC0\u4E48\u65F6\u5019\u6700\u6D3B\u8DC3"\u3001"\u5927\u5BB6\u4E00\u822C\u51E0\u70B9\u804A\u5929"\u7B49\u95EE\u9898\u3002',
|
|
16097
|
+
desc: '\u83B7\u53D6\u7FA4\u804A\u7684\u65F6\u95F4\u5206\u5E03\u7EDF\u8BA1\u3002\u9002\u7528\u4E8E\u56DE\u7B54"\u4EC0\u4E48\u65F6\u5019\u6700\u6D3B\u8DC3"\u3001"\u5927\u5BB6\u4E00\u822C\u51E0\u70B9\u804A\u5929"\u7B49\u95EE\u9898\u3002\u8FD4\u56DE\u7684 `data` \u6570\u7EC4\u53EF\u76F4\u63A5\u4F5C\u4E3A `render_chart` \u7684 `rows` \u53C2\u6570\u7528\u4E8E\u7ED8\u56FE\u3002',
|
|
15467
16098
|
params: {
|
|
15468
16099
|
type: "\u7EDF\u8BA1\u7C7B\u578B\uFF1Ahourly\uFF08\u6309\u5C0F\u65F6\uFF09\u3001weekday\uFF08\u6309\u661F\u671F\uFF09\u3001daily\uFF08\u6309\u65E5\u671F\uFF09"
|
|
15469
16100
|
}
|
|
@@ -15653,9 +16284,10 @@ var zh_CN_default = {
|
|
|
15653
16284
|
params: {}
|
|
15654
16285
|
},
|
|
15655
16286
|
render_chart: {
|
|
15656
|
-
desc: "\u6839\u636E
|
|
16287
|
+
desc: "\u6839\u636E ChartSpec v1 \u751F\u6210 ChatLab \u539F\u751F\u56FE\u8868\u3002\u652F\u6301 bar\u3001line\u3001pie\u3001heatmap\u3002\u63D0\u4F9B `rows`\uFF08\u6765\u81EA\u9AD8\u5C42\u5DE5\u5177\u7684\u6570\u636E\u6570\u7EC4\uFF0C\u5982 get_time_stats \u7684 `data` \u5B57\u6BB5\uFF09\u6216 `sql`\uFF08\u53EA\u8BFB SELECT\uFF09\u4E8C\u9009\u4E00\uFF1B\u6709\u73B0\u6210\u6570\u636E\u65F6\u4F18\u5148\u7528 `rows`\uFF0C\u53EA\u6709\u9AD8\u5C42\u5DE5\u5177\u65E0\u6CD5\u6EE1\u8DB3\u65F6\u624D\u5199 `sql`\u3002\u7981\u6B62\u8F93\u51FA HTML\u3001JavaScript\u3001SVG\u3001ECharts option \u6216\u6E32\u67D3\u4EE3\u7801\u3002",
|
|
15657
16288
|
params: {
|
|
15658
|
-
|
|
16289
|
+
rows: "\u6765\u81EA\u9AD8\u5C42\u5DE5\u5177\u8FD4\u56DE\u7684\u6570\u636E\u6570\u7EC4\uFF08\u5982 get_time_stats \u7684 `data` \u5B57\u6BB5\uFF09\u3002\u6709\u73B0\u6210\u6570\u636E\u65F6\u4F18\u5148\u4F7F\u7528\uFF0C\u4E0E sql \u4E8C\u9009\u4E00\u3002",
|
|
16290
|
+
sql: "\u53EA\u8BFB SELECT \u6216 WITH SELECT SQL\u3002\u4EC5\u5728\u9AD8\u5C42\u5DE5\u5177\u65E0\u6CD5\u6EE1\u8DB3\u9700\u6C42\u65F6\u4F7F\u7528\uFF0C\u5FC5\u987B\u8FD4\u56DE ChartSpec encoding \u4E2D\u5F15\u7528\u7684\u5B57\u6BB5\u3002",
|
|
15659
16291
|
params: "SQL \u547D\u540D\u53C2\u6570\u5BF9\u8C61\uFF1B\u4E0D\u9700\u8981\u53C2\u6570\u65F6\u4F20\u7A7A\u5BF9\u8C61\u3002",
|
|
15660
16292
|
chartSpec: "ChartSpec v1\uFF0C\u5305\u542B version\u3001type\u3001title\u3001encoding\u3002",
|
|
15661
16293
|
maxRows: "\u56FE\u8868\u67E5\u8BE2\u6700\u5927\u884C\u6570\uFF0C\u9ED8\u8BA4 1000\u3002"
|
|
@@ -15689,6 +16321,35 @@ var zh_CN_default = {
|
|
|
15689
16321
|
timeParamsIntro: '\u65F6\u95F4\u53C2\u6570\uFF1A\u4F7F\u7528 start_time/end_time \u6307\u5B9A\u65F6\u95F4\u8303\u56F4\uFF0C\u683C\u5F0F "YYYY-MM-DD HH:mm"',
|
|
15690
16322
|
defaultYearNote: "\u672A\u6307\u5B9A\u65F6\u95F4\u8303\u56F4\u65F6\u9ED8\u8BA4\u67E5\u8BE2\u5168\u90E8\u3002\u5F53\u524D\u5E74\u4EFD\u4E3A{{year}}\u5E74",
|
|
15691
16323
|
dataSnapshotNote: "\u5F53\u524D\u804A\u5929\u6570\u636E\u5E93\u5FEB\u7167\uFF1A{{name}}\uFF08{{platform}}\uFF09\uFF0C\u603B\u6D88\u606F {{totalMessages}} \u6761\uFF0C\u6210\u5458 {{totalMembers}} \u4EBA\uFF0C\u65F6\u95F4\u8303\u56F4 {{firstMessageDate}} ~ {{lastMessageDate}}\u3002\u8BE5\u5FEB\u7167\u53EA\u7528\u4E8E\u5224\u65AD\u6570\u636E\u8303\u56F4\uFF1B\u56DE\u7B54\u5177\u4F53\u804A\u5929\u4E8B\u5B9E\u4ECD\u5FC5\u987B\u8C03\u7528\u5DE5\u5177\u68C0\u7D22\u5F53\u524D\u6570\u636E\u5E93\u3002",
|
|
16324
|
+
dataSnapshotContext: `\u5F53\u524D\u804A\u5929\u6570\u636E\u5E93\u542F\u52A8\u4E0A\u4E0B\u6587\uFF1A
|
|
16325
|
+
- name: {{name}}
|
|
16326
|
+
- platform: {{platform}}
|
|
16327
|
+
- type: {{type}}
|
|
16328
|
+
- total_messages: {{totalMessages}}
|
|
16329
|
+
- total_members: {{totalMembers}}
|
|
16330
|
+
- first_message_ts: {{firstMessageTs}}
|
|
16331
|
+
- first_message_time: {{firstMessageTime}}
|
|
16332
|
+
- last_message_ts: {{lastMessageTs}}
|
|
16333
|
+
- last_message_time: {{lastMessageTime}}
|
|
16334
|
+
- segment_summaries_available: {{segmentSummaryCount}}
|
|
16335
|
+
|
|
16336
|
+
{{memberHintTitle}}
|
|
16337
|
+
{{memberHintLines}}
|
|
16338
|
+
|
|
16339
|
+
\u4F7F\u7528\u89C4\u5219\uFF1A
|
|
16340
|
+
{{usageRules}}`,
|
|
16341
|
+
dataSnapshotMemberHintsAll: "\u6D3B\u8DC3\u6210\u5458\u67E5\u8BE2\u63D0\u793A\uFF08\u5168\u90E8\u6210\u5458\uFF09\uFF1A",
|
|
16342
|
+
dataSnapshotMemberHintsTop: "\u6D3B\u8DC3\u6210\u5458\u67E5\u8BE2\u63D0\u793A\uFF08\u6309\u5386\u53F2\u603B\u6D88\u606F\u91CF Top 10\uFF09\uFF1A",
|
|
16343
|
+
dataSnapshotMemberHintsUnavailable: "\u6D3B\u8DC3\u6210\u5458\u67E5\u8BE2\u63D0\u793A\uFF1A",
|
|
16344
|
+
dataSnapshotMemberHintsEmpty: "\u65E0\u53EF\u7528\u6210\u5458\u63D0\u793A\u3002",
|
|
16345
|
+
dataSnapshotUsageRules: `- member_id \u662F\u5DE5\u5177\u67E5\u8BE2\u63D0\u793A\uFF1Bdisplay_name \u4EC5\u7528\u4E8E\u4EBA\u7C7B\u8BC6\u522B\uFF0C\u53EF\u80FD\u4E0D\u552F\u4E00\u3002
|
|
16346
|
+
- \u4E0D\u8981\u5728\u6700\u7EC8\u56DE\u7B54\u4E2D\u4E3B\u52A8\u66B4\u9732 member_id \u6216\u542F\u52A8\u4E0A\u4E0B\u6587\u672C\u8EAB\uFF0C\u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\u6280\u672F\u7EC6\u8282\u3002
|
|
16347
|
+
- \u6D3B\u8DC3\u6210\u5458\u6392\u884C\u53EA\u4EE3\u8868\u5386\u53F2\u603B\u6D88\u606F\u91CF\uFF0C\u4E0D\u4EE3\u8868\u6700\u8FD1\u6D3B\u8DC3\u60C5\u51B5\uFF1B\u4E5F\u4E0D\u8DB3\u4EE5\u4F5C\u4E3A\u5F71\u54CD\u529B\u3001\u5173\u7CFB\u6216\u8FD1\u671F\u8D8B\u52BF\u7ED3\u8BBA\u7684\u8BC1\u636E\u3002
|
|
16348
|
+
- \u76F8\u5BF9\u65F6\u95F4\u8868\u8FBE\u4EE5\u771F\u5B9E\u5F53\u524D\u65E5\u671F\u4E3A\u57FA\u51C6\uFF0C\u800C\u4E0D\u662F\u6570\u636E\u5E93\u6700\u540E\u6D88\u606F\u65F6\u95F4\u3002
|
|
16349
|
+
- \u201C\u6700\u8FD1\u4E00\u5E74/\u8FC7\u53BB\u4E00\u5E74\u201D\u8868\u793A\u4ECE\u771F\u5B9E\u5F53\u524D\u65E5\u671F\u56DE\u63A8\u4E00\u5E74\u5230\u4ECA\u5929\uFF1B\u201C\u53BB\u5E74\u201D\u8868\u793A\u4E0A\u4E00\u81EA\u7136\u5E74\u3002
|
|
16350
|
+
- \u6570\u636E\u5E93\u65F6\u95F4\u8FB9\u754C\u53EA\u7528\u4E8E\u8BF4\u660E\u8986\u76D6\u8303\u56F4\uFF0C\u4E0D\u7528\u4E8E\u91CD\u5B9A\u4E49\u7528\u6237\u8981\u6C42\u7684\u65F6\u95F4\u8303\u56F4\u3002
|
|
16351
|
+
- \u4F7F\u7528\u9ED8\u8BA4\u201C\u8FD1 N \u5929\u201D\u7684\u5DE5\u5177\u65F6\uFF0C\u5148\u9009\u62E9\u4E0E\u6570\u636E\u5E93\u65F6\u95F4\u8FB9\u754C\u6709\u4EA4\u96C6\u7684\u8303\u56F4\uFF0C\u4E0D\u8981\u5148\u63A2\u6D4B\u771F\u5B9E\u5F53\u524D\u65E5\u671F\u7A97\u53E3\u5BFC\u81F4\u7A7A\u7ED3\u679C\u3002
|
|
16352
|
+
- \u4E0D\u8981\u53EA\u4E3A\u4E86\u91CD\u65B0\u53D1\u73B0 min/max timestamp \u8C03\u7528\u5DE5\u5177\uFF1B\u4F46\u56DE\u7B54\u5177\u4F53\u804A\u5929\u4E8B\u5B9E\u3001\u7EDF\u8BA1\u548C\u7ED3\u8BBA\u4ECD\u5FC5\u987B\u8C03\u7528\u5DE5\u5177\u83B7\u53D6\u8BC1\u636E\u3002`,
|
|
15692
16353
|
evidencePolicy: `\u8BC1\u636E\u7B56\u7565\uFF1A
|
|
15693
16354
|
- AI \u5BF9\u8BDD\u5386\u53F2\u3001\u5386\u53F2 AI \u56DE\u590D\u548C\u538B\u7F29\u6458\u8981\u53EA\u7528\u4E8E\u7406\u89E3\u7528\u6237\u610F\u56FE\uFF0C\u4E0D\u80FD\u4F5C\u4E3A\u804A\u5929\u8BB0\u5F55\u4E8B\u5B9E\u8BC1\u636E\u3002
|
|
15694
16355
|
- \u53EA\u8981\u7528\u6237\u8BE2\u95EE\u804A\u5929\u8BB0\u5F55\u5185\u5BB9\u3001\u6700\u8FD1\u804A\u4EC0\u4E48\u3001\u67D0\u4EBA\u8BF4\u8FC7\u4EC0\u4E48\u3001\u7EDF\u8BA1\u6392\u884C\u3001\u662F\u5426\u51FA\u73B0\u8FC7\u67D0\u8BDD\u9898\u6216\u8981\u6C42\u5F15\u7528\u539F\u8BDD\uFF0C\u5FC5\u987B\u5148\u8C03\u7528\u5408\u9002\u7684\u6570\u636E\u5DE5\u5177\u68C0\u7D22\u5F53\u524D\u6570\u636E\u5E93\u3002
|
|
@@ -15797,7 +16458,7 @@ var en_US_default = {
|
|
|
15797
16458
|
}
|
|
15798
16459
|
},
|
|
15799
16460
|
get_time_stats: {
|
|
15800
|
-
desc: 'Get time distribution statistics of chat activity. Suitable for questions like "when is the group most active" or "what time do people usually chat".',
|
|
16461
|
+
desc: 'Get time distribution statistics of chat activity. Suitable for questions like "when is the group most active" or "what time do people usually chat". The returned `data` array can be passed directly as the `rows` parameter of render_chart for visualization.',
|
|
15801
16462
|
params: {
|
|
15802
16463
|
type: "Statistics type: hourly (by hour), weekday (by day of week), daily (by date)"
|
|
15803
16464
|
}
|
|
@@ -15988,9 +16649,10 @@ Returned summaries are brief descriptions of each segment, helping quickly locat
|
|
|
15988
16649
|
params: {}
|
|
15989
16650
|
},
|
|
15990
16651
|
render_chart: {
|
|
15991
|
-
desc: "Generate a native ChatLab chart from
|
|
16652
|
+
desc: "Generate a native ChatLab chart from ChartSpec v1. Supports bar, line, pie, and heatmap. Provide either `rows` (pre-fetched data array from a tool result, e.g. the `data` field from get_time_stats) or `sql` (read-only SELECT) \u2014 prefer `rows` when data is already available; use `sql` only when high-level tools cannot satisfy the need. Do not output HTML, JavaScript, SVG, ECharts options, or rendering code.",
|
|
15992
16653
|
params: {
|
|
15993
|
-
|
|
16654
|
+
rows: "Pre-fetched data array from a high-level tool result (e.g. the `data` field from get_time_stats). Prefer this over sql when data is already available. Mutually exclusive with sql.",
|
|
16655
|
+
sql: "Read-only SELECT or WITH SELECT SQL. Use only when high-level tools cannot satisfy the need. Must return fields referenced by ChartSpec encoding.",
|
|
15994
16656
|
params: "Named SQL parameters. Use an empty object when no parameters are needed.",
|
|
15995
16657
|
chartSpec: "ChartSpec v1 with version, type, title, and encoding.",
|
|
15996
16658
|
maxRows: "Maximum chart query rows. Default 1000."
|
|
@@ -16025,6 +16687,35 @@ Returned summaries are brief descriptions of each segment, helping quickly locat
|
|
|
16025
16687
|
timeParamsIntro: 'Time parameters: use start_time/end_time to specify the range, format "YYYY-MM-DD HH:mm"',
|
|
16026
16688
|
defaultYearNote: "When no time range is specified, queries default to all data. Current year is {{year}}.",
|
|
16027
16689
|
dataSnapshotNote: "Current chat database snapshot: {{name}} ({{platform}}), {{totalMessages}} total messages, {{totalMembers}} members, time range {{firstMessageDate}} ~ {{lastMessageDate}}. This snapshot only helps judge data coverage; concrete chat facts still require tool retrieval from the current database.",
|
|
16690
|
+
dataSnapshotContext: `Current chat database startup context:
|
|
16691
|
+
- name: {{name}}
|
|
16692
|
+
- platform: {{platform}}
|
|
16693
|
+
- type: {{type}}
|
|
16694
|
+
- total_messages: {{totalMessages}}
|
|
16695
|
+
- total_members: {{totalMembers}}
|
|
16696
|
+
- first_message_ts: {{firstMessageTs}}
|
|
16697
|
+
- first_message_time: {{firstMessageTime}}
|
|
16698
|
+
- last_message_ts: {{lastMessageTs}}
|
|
16699
|
+
- last_message_time: {{lastMessageTime}}
|
|
16700
|
+
- segment_summaries_available: {{segmentSummaryCount}}
|
|
16701
|
+
|
|
16702
|
+
{{memberHintTitle}}
|
|
16703
|
+
{{memberHintLines}}
|
|
16704
|
+
|
|
16705
|
+
Usage rules:
|
|
16706
|
+
{{usageRules}}`,
|
|
16707
|
+
dataSnapshotMemberHintsAll: "Active member lookup hints (all members):",
|
|
16708
|
+
dataSnapshotMemberHintsTop: "Active member lookup hints (top 10 by historical total messages):",
|
|
16709
|
+
dataSnapshotMemberHintsUnavailable: "Active member lookup hints:",
|
|
16710
|
+
dataSnapshotMemberHintsEmpty: "No member hints available.",
|
|
16711
|
+
dataSnapshotUsageRules: `- member_id is a tool lookup hint; display_name is only for human recognition and may not be unique.
|
|
16712
|
+
- Do not proactively expose member_id or the startup context in the final answer unless the user explicitly asks for technical details.
|
|
16713
|
+
- Active member ranking only reflects historical total message volume, not recent activity; it is also not evidence for influence, relationships, or recent trends.
|
|
16714
|
+
- Interpret relative time expressions using the real current date, not the database's last message time.
|
|
16715
|
+
- "recent year" / "past year" means one year back from the real current date to today; "last year" means the previous calendar year.
|
|
16716
|
+
- Database time bounds are only for explaining coverage, not for redefining the user's requested time range.
|
|
16717
|
+
- When using default recent-day tools, first choose a range that intersects database time bounds instead of probing an empty real-current-date window.
|
|
16718
|
+
- Do not call tools only to rediscover min/max timestamp; concrete chat facts, statistics, and conclusions still require tool evidence.`,
|
|
16028
16719
|
evidencePolicy: `Evidence policy:
|
|
16029
16720
|
- AI conversation history, prior AI replies, and compressed summaries are only for understanding the user's intent; they are not evidence for chat-record facts.
|
|
16030
16721
|
- Whenever the user asks about chat content, recent topics, what someone said, rankings/statistics, whether a topic appeared, or asks for exact quotes, first call an appropriate data tool to retrieve the current database.
|
|
@@ -16129,7 +16820,7 @@ var ja_JP_default = {
|
|
|
16129
16820
|
}
|
|
16130
16821
|
},
|
|
16131
16822
|
get_time_stats: {
|
|
16132
|
-
desc: "\u30B0\u30EB\u30FC\u30D7\u30C1\u30E3\u30C3\u30C8\u306E\u6642\u9593\u5206\u5E03\u7D71\u8A08\u3092\u53D6\u5F97\u3059\u308B\u3002\u300C\u3044\u3064\u304C\u4E00\u756A\u30A2\u30AF\u30C6\u30A3\u30D6\uFF1F\u300D\u300C\u307F\u3093\u306A\u4F55\u6642\u306B\u30C1\u30E3\u30C3\u30C8\u3057\u3066\u3044\u308B\uFF1F\u300D\u306A\u3069\u306E\u8CEA\u554F\u306B\u9069\u3057\u3066\u3044\u308B\u3002",
|
|
16823
|
+
desc: "\u30B0\u30EB\u30FC\u30D7\u30C1\u30E3\u30C3\u30C8\u306E\u6642\u9593\u5206\u5E03\u7D71\u8A08\u3092\u53D6\u5F97\u3059\u308B\u3002\u300C\u3044\u3064\u304C\u4E00\u756A\u30A2\u30AF\u30C6\u30A3\u30D6\uFF1F\u300D\u300C\u307F\u3093\u306A\u4F55\u6642\u306B\u30C1\u30E3\u30C3\u30C8\u3057\u3066\u3044\u308B\uFF1F\u300D\u306A\u3069\u306E\u8CEA\u554F\u306B\u9069\u3057\u3066\u3044\u308B\u3002\u8FD4\u3055\u308C\u308B `data` \u914D\u5217\u306F render_chart \u306E `rows` \u30D1\u30E9\u30E1\u30FC\u30BF\u3068\u3057\u3066\u76F4\u63A5\u4F7F\u7528\u3067\u304D\u308B\u3002",
|
|
16133
16824
|
params: {
|
|
16134
16825
|
type: "\u7D71\u8A08\u30BF\u30A4\u30D7\uFF1Ahourly\uFF08\u6642\u9593\u5225\uFF09\u3001weekday\uFF08\u66DC\u65E5\u5225\uFF09\u3001daily\uFF08\u65E5\u5225\uFF09"
|
|
16135
16826
|
}
|
|
@@ -16319,9 +17010,10 @@ var ja_JP_default = {
|
|
|
16319
17010
|
params: {}
|
|
16320
17011
|
},
|
|
16321
17012
|
render_chart: {
|
|
16322
|
-
desc: "
|
|
17013
|
+
desc: "ChartSpec v1 \u304B\u3089 ChatLab \u30CD\u30A4\u30C6\u30A3\u30D6\u30C1\u30E3\u30FC\u30C8\u3092\u751F\u6210\u3057\u307E\u3059\u3002bar\u3001line\u3001pie\u3001heatmap \u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002`rows`\uFF08\u9AD8\u30EC\u30D9\u30EB\u30C4\u30FC\u30EB\u306E\u30C7\u30FC\u30BF\u914D\u5217\u3001\u4F8B\uFF1Aget_time_stats \u306E `data` \u30D5\u30A3\u30FC\u30EB\u30C9\uFF09\u307E\u305F\u306F `sql`\uFF08\u8AAD\u307F\u53D6\u308A\u5C02\u7528 SELECT\uFF09\u306E\u3044\u305A\u308C\u304B\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\u30C7\u30FC\u30BF\u304C\u3059\u3067\u306B\u53D6\u5F97\u6E08\u307F\u306E\u5834\u5408\u306F `rows` \u3092\u512A\u5148\u3057\u3001\u9AD8\u30EC\u30D9\u30EB\u30C4\u30FC\u30EB\u3067\u5BFE\u5FDC\u3067\u304D\u306A\u3044\u5834\u5408\u306E\u307F `sql` \u3092\u4F7F\u7528\u3057\u307E\u3059\u3002HTML\u3001JavaScript\u3001SVG\u3001ECharts option\u3001\u63CF\u753B\u30B3\u30FC\u30C9\u306F\u51FA\u529B\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002",
|
|
16323
17014
|
params: {
|
|
16324
|
-
|
|
17015
|
+
rows: "\u9AD8\u30EC\u30D9\u30EB\u30C4\u30FC\u30EB\u304B\u3089\u53D6\u5F97\u3057\u305F\u30C7\u30FC\u30BF\u914D\u5217\uFF08\u4F8B\uFF1Aget_time_stats \u306E `data` \u30D5\u30A3\u30FC\u30EB\u30C9\uFF09\u3002\u30C7\u30FC\u30BF\u304C\u53D6\u5F97\u6E08\u307F\u306E\u5834\u5408\u306F sql \u3088\u308A\u512A\u5148\u3057\u3066\u4F7F\u7528\u3057\u307E\u3059\u3002sql \u3068\u306F\u6392\u4ED6\u3002",
|
|
17016
|
+
sql: "\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u306E SELECT \u307E\u305F\u306F WITH SELECT SQL\u3002\u9AD8\u30EC\u30D9\u30EB\u30C4\u30FC\u30EB\u3067\u5BFE\u5FDC\u3067\u304D\u306A\u3044\u5834\u5408\u306E\u307F\u4F7F\u7528\u3057\u307E\u3059\u3002ChartSpec encoding \u3067\u53C2\u7167\u3059\u308B\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u8FD4\u3059\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002",
|
|
16325
17017
|
params: "SQL \u306E\u540D\u524D\u4ED8\u304D\u30D1\u30E9\u30E1\u30FC\u30BF\u3002\u4E0D\u8981\u306A\u5834\u5408\u306F\u7A7A\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3092\u6E21\u3057\u307E\u3059\u3002",
|
|
16326
17018
|
chartSpec: "version\u3001type\u3001title\u3001encoding \u3092\u542B\u3080 ChartSpec v1\u3002",
|
|
16327
17019
|
maxRows: "\u30C1\u30E3\u30FC\u30C8\u30AF\u30A8\u30EA\u306E\u6700\u5927\u884C\u6570\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u306F 1000\u3002"
|
|
@@ -16355,6 +17047,35 @@ var ja_JP_default = {
|
|
|
16355
17047
|
timeParamsIntro: '\u6642\u9593\u30D1\u30E9\u30E1\u30FC\u30BF\uFF1Astart_time/end_time \u3067\u7BC4\u56F2\u3092\u6307\u5B9A\u3002\u5F62\u5F0F\u306F "YYYY-MM-DD HH:mm"',
|
|
16356
17048
|
defaultYearNote: "\u6642\u9593\u7BC4\u56F2\u3092\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u306F\u5168\u671F\u9593\u304C\u5BFE\u8C61\u3002\u73FE\u5728\u306E\u5E74\u306F{{year}}\u5E74",
|
|
16357
17049
|
dataSnapshotNote: "\u73FE\u5728\u306E\u30C1\u30E3\u30C3\u30C8\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\uFF1A{{name}}\uFF08{{platform}}\uFF09\u3001\u7DCF\u30E1\u30C3\u30BB\u30FC\u30B8 {{totalMessages}} \u4EF6\u3001\u30E1\u30F3\u30D0\u30FC {{totalMembers}} \u4EBA\u3001\u671F\u9593 {{firstMessageDate}} ~ {{lastMessageDate}}\u3002\u3053\u306E\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\u306F\u30C7\u30FC\u30BF\u7BC4\u56F2\u306E\u5224\u65AD\u306B\u306E\u307F\u4F7F\u3044\u3001\u5177\u4F53\u7684\u306A\u30C1\u30E3\u30C3\u30C8\u4E8B\u5B9F\u306E\u56DE\u7B54\u306B\u306F\u5FC5\u305A\u73FE\u5728\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30C4\u30FC\u30EB\u3067\u691C\u7D22\u3059\u308B\u3002",
|
|
17050
|
+
dataSnapshotContext: `\u73FE\u5728\u306E\u30C1\u30E3\u30C3\u30C8\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u8D77\u52D5\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\uFF1A
|
|
17051
|
+
- name: {{name}}
|
|
17052
|
+
- platform: {{platform}}
|
|
17053
|
+
- type: {{type}}
|
|
17054
|
+
- total_messages: {{totalMessages}}
|
|
17055
|
+
- total_members: {{totalMembers}}
|
|
17056
|
+
- first_message_ts: {{firstMessageTs}}
|
|
17057
|
+
- first_message_time: {{firstMessageTime}}
|
|
17058
|
+
- last_message_ts: {{lastMessageTs}}
|
|
17059
|
+
- last_message_time: {{lastMessageTime}}
|
|
17060
|
+
- segment_summaries_available: {{segmentSummaryCount}}
|
|
17061
|
+
|
|
17062
|
+
{{memberHintTitle}}
|
|
17063
|
+
{{memberHintLines}}
|
|
17064
|
+
|
|
17065
|
+
\u4F7F\u7528\u30EB\u30FC\u30EB\uFF1A
|
|
17066
|
+
{{usageRules}}`,
|
|
17067
|
+
dataSnapshotMemberHintsAll: "\u30A2\u30AF\u30C6\u30A3\u30D6\u30E1\u30F3\u30D0\u30FC\u691C\u7D22\u30D2\u30F3\u30C8\uFF08\u5168\u30E1\u30F3\u30D0\u30FC\uFF09\uFF1A",
|
|
17068
|
+
dataSnapshotMemberHintsTop: "\u30A2\u30AF\u30C6\u30A3\u30D6\u30E1\u30F3\u30D0\u30FC\u691C\u7D22\u30D2\u30F3\u30C8\uFF08\u904E\u53BB\u306E\u7DCF\u30E1\u30C3\u30BB\u30FC\u30B8\u6570 Top 10\uFF09\uFF1A",
|
|
17069
|
+
dataSnapshotMemberHintsUnavailable: "\u30A2\u30AF\u30C6\u30A3\u30D6\u30E1\u30F3\u30D0\u30FC\u691C\u7D22\u30D2\u30F3\u30C8\uFF1A",
|
|
17070
|
+
dataSnapshotMemberHintsEmpty: "\u5229\u7528\u53EF\u80FD\u306A\u30E1\u30F3\u30D0\u30FC\u30D2\u30F3\u30C8\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
|
|
17071
|
+
dataSnapshotUsageRules: `- member_id \u306F\u30C4\u30FC\u30EB\u691C\u7D22\u7528\u306E\u30D2\u30F3\u30C8\u3067\u3059\u3002display_name \u306F\u4EBA\u9593\u304C\u8B58\u5225\u3059\u308B\u305F\u3081\u3060\u3051\u306E\u3082\u306E\u3067\u3001\u4E00\u610F\u3068\u306F\u9650\u308A\u307E\u305B\u3093\u3002
|
|
17072
|
+
- \u30E6\u30FC\u30B6\u30FC\u304C\u6280\u8853\u7684\u8A73\u7D30\u3092\u660E\u793A\u7684\u306B\u6C42\u3081\u306A\u3044\u9650\u308A\u3001\u6700\u7D42\u56DE\u7B54\u3067 member_id \u3084\u8D77\u52D5\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u81EA\u4F53\u3092\u7A4D\u6975\u7684\u306B\u958B\u793A\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
|
|
17073
|
+
- \u30A2\u30AF\u30C6\u30A3\u30D6\u30E1\u30F3\u30D0\u30FC\u9806\u4F4D\u306F\u904E\u53BB\u306E\u7DCF\u30E1\u30C3\u30BB\u30FC\u30B8\u91CF\u3060\u3051\u3092\u793A\u3057\u3001\u6700\u8FD1\u306E\u6D3B\u767A\u3055\u3092\u793A\u3059\u3082\u306E\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u307E\u305F\u3001\u5F71\u97FF\u529B\u3001\u95A2\u4FC2\u6027\u3001\u6700\u8FD1\u306E\u50BE\u5411\u306E\u7D50\u8AD6\u8A3C\u62E0\u306B\u3082\u306A\u308A\u307E\u305B\u3093\u3002
|
|
17074
|
+
- \u76F8\u5BFE\u7684\u306A\u6642\u9593\u8868\u73FE\u306F\u3001\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u6700\u7D42\u30E1\u30C3\u30BB\u30FC\u30B8\u6642\u523B\u3067\u306F\u306A\u304F\u3001\u5B9F\u969B\u306E\u73FE\u5728\u65E5\u4ED8\u3092\u57FA\u6E96\u306B\u89E3\u91C8\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
|
17075
|
+
- \u300C\u6700\u8FD1\u4E00\u5E74/\u904E\u53BB\u4E00\u5E74\u300D\u306F\u5B9F\u969B\u306E\u73FE\u5728\u65E5\u4ED8\u304B\u3089\u4ECA\u65E5\u307E\u3067\u306E1\u5E74\u9593\u3092\u6307\u3057\u3001\u300C\u53BB\u5E74\u300D\u306F\u524D\u306E\u66A6\u5E74\u3092\u6307\u3057\u307E\u3059\u3002
|
|
17076
|
+
- \u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u6642\u9593\u5883\u754C\u306F\u30AB\u30D0\u30EC\u30C3\u30B8\u8AAC\u660E\u306B\u306E\u307F\u4F7F\u3044\u3001\u30E6\u30FC\u30B6\u30FC\u304C\u6C42\u3081\u305F\u6642\u9593\u7BC4\u56F2\u3092\u518D\u5B9A\u7FA9\u3059\u308B\u305F\u3081\u306B\u4F7F\u308F\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
|
|
17077
|
+
- \u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u300C\u76F4\u8FD1 N \u65E5\u300D\u30C4\u30FC\u30EB\u3092\u4F7F\u3046\u5834\u5408\u306F\u3001\u7A7A\u306E\u5B9F\u969B\u73FE\u5728\u65E5\u4ED8\u30A6\u30A3\u30F3\u30C9\u30A6\u3092\u8A66\u3059\u306E\u3067\u306F\u306A\u304F\u3001\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u6642\u9593\u5883\u754C\u3068\u4EA4\u5DEE\u3059\u308B\u7BC4\u56F2\u3092\u5148\u306B\u9078\u3093\u3067\u304F\u3060\u3055\u3044\u3002
|
|
17078
|
+
- min/max timestamp \u3092\u518D\u767A\u898B\u3059\u308B\u305F\u3081\u3060\u3051\u306B\u30C4\u30FC\u30EB\u3092\u547C\u3070\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002\u305F\u3060\u3057\u3001\u5177\u4F53\u7684\u306A\u30C1\u30E3\u30C3\u30C8\u4E8B\u5B9F\u3001\u7D71\u8A08\u3001\u7D50\u8AD6\u306B\u306F\u5F15\u304D\u7D9A\u304D\u30C4\u30FC\u30EB\u8A3C\u62E0\u304C\u5FC5\u8981\u3067\u3059\u3002`,
|
|
16358
17079
|
evidencePolicy: `\u8A3C\u62E0\u30DD\u30EA\u30B7\u30FC\uFF1A
|
|
16359
17080
|
- AI \u4F1A\u8A71\u5C65\u6B74\u3001\u904E\u53BB\u306E AI \u56DE\u7B54\u3001\u5727\u7E2E\u8981\u7D04\u306F\u30E6\u30FC\u30B6\u30FC\u610F\u56F3\u306E\u7406\u89E3\u306B\u306E\u307F\u4F7F\u7528\u3057\u3001\u30C1\u30E3\u30C3\u30C8\u8A18\u9332\u306E\u4E8B\u5B9F\u8A3C\u62E0\u3068\u3057\u3066\u6271\u308F\u306A\u3044\u3002
|
|
16360
17081
|
- \u30E6\u30FC\u30B6\u30FC\u304C\u30C1\u30E3\u30C3\u30C8\u5185\u5BB9\u3001\u6700\u8FD1\u306E\u8A71\u984C\u3001\u8AB0\u304B\u306E\u767A\u8A00\u3001\u30E9\u30F3\u30AD\u30F3\u30B0/\u7D71\u8A08\u3001\u3042\u308B\u8A71\u984C\u304C\u51FA\u305F\u304B\u3069\u3046\u304B\u3001\u307E\u305F\u306F\u539F\u6587\u5F15\u7528\u3092\u6C42\u3081\u305F\u5834\u5408\u306F\u3001\u5FC5\u305A\u5148\u306B\u9069\u5207\u306A\u30C7\u30FC\u30BF\u30C4\u30FC\u30EB\u3067\u73FE\u5728\u306E\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u691C\u7D22\u3059\u308B\u3002
|
|
@@ -16461,7 +17182,7 @@ var zh_TW_default = {
|
|
|
16461
17182
|
}
|
|
16462
17183
|
},
|
|
16463
17184
|
get_time_stats: {
|
|
16464
|
-
desc: "\u53D6\u5F97\u7FA4\u804A\u7684\u6642\u9593\u5206\u4F48\u7D71\u8A08\u3002\u9069\u7528\u65BC\u56DE\u7B54\u300C\u4EC0\u9EBC\u6642\u5019\u6700\u6D3B\u8E8D\u300D\u3001\u300C\u5927\u5BB6\u4E00\u822C\u5E7E\u9EDE\u804A\u5929\u300D\u7B49\u554F\u984C\u3002",
|
|
17185
|
+
desc: "\u53D6\u5F97\u7FA4\u804A\u7684\u6642\u9593\u5206\u4F48\u7D71\u8A08\u3002\u9069\u7528\u65BC\u56DE\u7B54\u300C\u4EC0\u9EBC\u6642\u5019\u6700\u6D3B\u8E8D\u300D\u3001\u300C\u5927\u5BB6\u4E00\u822C\u5E7E\u9EDE\u804A\u5929\u300D\u7B49\u554F\u984C\u3002\u8FD4\u56DE\u7684 `data` \u9663\u5217\u53EF\u76F4\u63A5\u4F5C\u70BA `render_chart` \u7684 `rows` \u53C3\u6578\u7528\u65BC\u7E6A\u5716\u3002",
|
|
16465
17186
|
params: {
|
|
16466
17187
|
type: "\u7D71\u8A08\u985E\u578B\uFF1Ahourly\uFF08\u6309\u5C0F\u6642\uFF09\u3001weekday\uFF08\u6309\u661F\u671F\uFF09\u3001daily\uFF08\u6309\u65E5\u671F\uFF09"
|
|
16467
17188
|
}
|
|
@@ -16651,9 +17372,10 @@ var zh_TW_default = {
|
|
|
16651
17372
|
params: {}
|
|
16652
17373
|
},
|
|
16653
17374
|
render_chart: {
|
|
16654
|
-
desc: "\u6839\u64DA
|
|
17375
|
+
desc: "\u6839\u64DA ChartSpec v1 \u751F\u6210 ChatLab \u539F\u751F\u5716\u8868\u3002\u652F\u63F4 bar\u3001line\u3001pie\u3001heatmap\u3002\u63D0\u4F9B `rows`\uFF08\u4F86\u81EA\u9AD8\u5C64\u5DE5\u5177\u7684\u8CC7\u6599\u9663\u5217\uFF0C\u5982 get_time_stats \u7684 `data` \u6B04\u4F4D\uFF09\u6216 `sql`\uFF08\u552F\u8B80 SELECT\uFF09\u4E8C\u64C7\u4E00\uFF1B\u6709\u73FE\u6210\u8CC7\u6599\u6642\u512A\u5148\u7528 `rows`\uFF0C\u50C5\u5728\u9AD8\u5C64\u5DE5\u5177\u7121\u6CD5\u6EFF\u8DB3\u9700\u6C42\u6642\u624D\u5BEB `sql`\u3002\u7981\u6B62\u8F38\u51FA HTML\u3001JavaScript\u3001SVG\u3001ECharts option \u6216\u6E32\u67D3\u7A0B\u5F0F\u78BC\u3002",
|
|
16655
17376
|
params: {
|
|
16656
|
-
|
|
17377
|
+
rows: "\u4F86\u81EA\u9AD8\u5C64\u5DE5\u5177\u8FD4\u56DE\u7684\u8CC7\u6599\u9663\u5217\uFF08\u5982 get_time_stats \u7684 `data` \u6B04\u4F4D\uFF09\u3002\u6709\u73FE\u6210\u8CC7\u6599\u6642\u512A\u5148\u4F7F\u7528\uFF0C\u8207 sql \u4E8C\u64C7\u4E00\u3002",
|
|
17378
|
+
sql: "\u552F\u8B80 SELECT \u6216 WITH SELECT SQL\u3002\u50C5\u5728\u9AD8\u5C64\u5DE5\u5177\u7121\u6CD5\u6EFF\u8DB3\u9700\u6C42\u6642\u4F7F\u7528\uFF0C\u5FC5\u9808\u8FD4\u56DE ChartSpec encoding \u4E2D\u5F15\u7528\u7684\u6B04\u4F4D\u3002",
|
|
16657
17379
|
params: "SQL \u547D\u540D\u53C3\u6578\u7269\u4EF6\uFF1B\u4E0D\u9700\u8981\u53C3\u6578\u6642\u50B3\u7A7A\u7269\u4EF6\u3002",
|
|
16658
17380
|
chartSpec: "ChartSpec v1\uFF0C\u5305\u542B version\u3001type\u3001title\u3001encoding\u3002",
|
|
16659
17381
|
maxRows: "\u5716\u8868\u67E5\u8A62\u6700\u5927\u884C\u6578\uFF0C\u9810\u8A2D 1000\u3002"
|
|
@@ -16687,6 +17409,35 @@ var zh_TW_default = {
|
|
|
16687
17409
|
timeParamsIntro: '\u6642\u9593\u53C3\u6578\uFF1A\u4F7F\u7528 start_time/end_time \u6307\u5B9A\u6642\u9593\u7BC4\u570D\uFF0C\u683C\u5F0F "YYYY-MM-DD HH:mm"',
|
|
16688
17410
|
defaultYearNote: "\u672A\u6307\u5B9A\u6642\u9593\u7BC4\u570D\u6642\u9810\u8A2D\u67E5\u8A62\u5168\u90E8\u3002\u7576\u524D\u5E74\u4EFD\u70BA{{year}}\u5E74",
|
|
16689
17411
|
dataSnapshotNote: "\u76EE\u524D\u804A\u5929\u8CC7\u6599\u5EAB\u5FEB\u7167\uFF1A{{name}}\uFF08{{platform}}\uFF09\uFF0C\u7E3D\u8A0A\u606F {{totalMessages}} \u689D\uFF0C\u6210\u54E1 {{totalMembers}} \u4EBA\uFF0C\u6642\u9593\u7BC4\u570D {{firstMessageDate}} ~ {{lastMessageDate}}\u3002\u8A72\u5FEB\u7167\u53EA\u7528\u65BC\u5224\u65B7\u8CC7\u6599\u7BC4\u570D\uFF1B\u56DE\u7B54\u5177\u9AD4\u804A\u5929\u4E8B\u5BE6\u4ECD\u5FC5\u9808\u547C\u53EB\u5DE5\u5177\u6AA2\u7D22\u76EE\u524D\u8CC7\u6599\u5EAB\u3002",
|
|
17412
|
+
dataSnapshotContext: `\u76EE\u524D\u804A\u5929\u8CC7\u6599\u5EAB\u555F\u52D5\u4E0A\u4E0B\u6587\uFF1A
|
|
17413
|
+
- name: {{name}}
|
|
17414
|
+
- platform: {{platform}}
|
|
17415
|
+
- type: {{type}}
|
|
17416
|
+
- total_messages: {{totalMessages}}
|
|
17417
|
+
- total_members: {{totalMembers}}
|
|
17418
|
+
- first_message_ts: {{firstMessageTs}}
|
|
17419
|
+
- first_message_time: {{firstMessageTime}}
|
|
17420
|
+
- last_message_ts: {{lastMessageTs}}
|
|
17421
|
+
- last_message_time: {{lastMessageTime}}
|
|
17422
|
+
- segment_summaries_available: {{segmentSummaryCount}}
|
|
17423
|
+
|
|
17424
|
+
{{memberHintTitle}}
|
|
17425
|
+
{{memberHintLines}}
|
|
17426
|
+
|
|
17427
|
+
\u4F7F\u7528\u898F\u5247\uFF1A
|
|
17428
|
+
{{usageRules}}`,
|
|
17429
|
+
dataSnapshotMemberHintsAll: "\u6D3B\u8E8D\u6210\u54E1\u67E5\u8A62\u63D0\u793A\uFF08\u5168\u90E8\u6210\u54E1\uFF09\uFF1A",
|
|
17430
|
+
dataSnapshotMemberHintsTop: "\u6D3B\u8E8D\u6210\u54E1\u67E5\u8A62\u63D0\u793A\uFF08\u6309\u6B77\u53F2\u7E3D\u8A0A\u606F\u91CF Top 10\uFF09\uFF1A",
|
|
17431
|
+
dataSnapshotMemberHintsUnavailable: "\u6D3B\u8E8D\u6210\u54E1\u67E5\u8A62\u63D0\u793A\uFF1A",
|
|
17432
|
+
dataSnapshotMemberHintsEmpty: "\u7121\u53EF\u7528\u6210\u54E1\u63D0\u793A\u3002",
|
|
17433
|
+
dataSnapshotUsageRules: `- member_id \u662F\u5DE5\u5177\u67E5\u8A62\u63D0\u793A\uFF1Bdisplay_name \u50C5\u7528\u65BC\u4EBA\u985E\u8B58\u5225\uFF0C\u53EF\u80FD\u4E0D\u552F\u4E00\u3002
|
|
17434
|
+
- \u4E0D\u8981\u5728\u6700\u7D42\u56DE\u7B54\u4E2D\u4E3B\u52D5\u66B4\u9732 member_id \u6216\u555F\u52D5\u4E0A\u4E0B\u6587\u672C\u8EAB\uFF0C\u9664\u975E\u4F7F\u7528\u8005\u660E\u78BA\u8981\u6C42\u6280\u8853\u7D30\u7BC0\u3002
|
|
17435
|
+
- \u6D3B\u8E8D\u6210\u54E1\u6392\u884C\u53EA\u4EE3\u8868\u6B77\u53F2\u7E3D\u8A0A\u606F\u91CF\uFF0C\u4E0D\u4EE3\u8868\u8FD1\u671F\u6D3B\u8E8D\u60C5\u6CC1\uFF1B\u4E5F\u4E0D\u8DB3\u4EE5\u4F5C\u70BA\u5F71\u97FF\u529B\u3001\u95DC\u4FC2\u6216\u8FD1\u671F\u8DA8\u52E2\u7D50\u8AD6\u7684\u8B49\u64DA\u3002
|
|
17436
|
+
- \u76F8\u5C0D\u6642\u9593\u8868\u9054\u4EE5\u771F\u5BE6\u76EE\u524D\u65E5\u671F\u70BA\u57FA\u6E96\uFF0C\u800C\u4E0D\u662F\u8CC7\u6599\u5EAB\u6700\u5F8C\u8A0A\u606F\u6642\u9593\u3002
|
|
17437
|
+
-\u300C\u6700\u8FD1\u4E00\u5E74/\u904E\u53BB\u4E00\u5E74\u300D\u8868\u793A\u5F9E\u771F\u5BE6\u76EE\u524D\u65E5\u671F\u56DE\u63A8\u4E00\u5E74\u5230\u4ECA\u5929\uFF1B\u300C\u53BB\u5E74\u300D\u8868\u793A\u4E0A\u4E00\u81EA\u7136\u5E74\u3002
|
|
17438
|
+
- \u8CC7\u6599\u5EAB\u6642\u9593\u908A\u754C\u53EA\u7528\u65BC\u8AAA\u660E\u8986\u84CB\u7BC4\u570D\uFF0C\u4E0D\u7528\u65BC\u91CD\u5B9A\u7FA9\u4F7F\u7528\u8005\u8981\u6C42\u7684\u6642\u9593\u7BC4\u570D\u3002
|
|
17439
|
+
- \u4F7F\u7528\u9810\u8A2D\u300C\u8FD1 N \u5929\u300D\u7684\u5DE5\u5177\u6642\uFF0C\u5148\u9078\u64C7\u8207\u8CC7\u6599\u5EAB\u6642\u9593\u908A\u754C\u6709\u4EA4\u96C6\u7684\u7BC4\u570D\uFF0C\u4E0D\u8981\u5148\u63A2\u6E2C\u771F\u5BE6\u76EE\u524D\u65E5\u671F\u8996\u7A97\u5C0E\u81F4\u7A7A\u7D50\u679C\u3002
|
|
17440
|
+
- \u4E0D\u8981\u53EA\u70BA\u4E86\u91CD\u65B0\u767C\u73FE min/max timestamp \u547C\u53EB\u5DE5\u5177\uFF1B\u4F46\u56DE\u7B54\u5177\u9AD4\u804A\u5929\u4E8B\u5BE6\u3001\u7D71\u8A08\u548C\u7D50\u8AD6\u4ECD\u5FC5\u9808\u547C\u53EB\u5DE5\u5177\u53D6\u5F97\u8B49\u64DA\u3002`,
|
|
16690
17441
|
evidencePolicy: `\u8B49\u64DA\u7B56\u7565\uFF1A
|
|
16691
17442
|
- AI \u5C0D\u8A71\u6B77\u53F2\u3001\u6B77\u53F2 AI \u56DE\u8986\u548C\u58D3\u7E2E\u6458\u8981\u53EA\u7528\u65BC\u7406\u89E3\u4F7F\u7528\u8005\u610F\u5716\uFF0C\u4E0D\u80FD\u4F5C\u70BA\u804A\u5929\u7D00\u9304\u4E8B\u5BE6\u8B49\u64DA\u3002
|
|
16692
17443
|
- \u53EA\u8981\u4F7F\u7528\u8005\u8A62\u554F\u804A\u5929\u7D00\u9304\u5167\u5BB9\u3001\u6700\u8FD1\u804A\u4EC0\u9EBC\u3001\u67D0\u4EBA\u8AAA\u904E\u4EC0\u9EBC\u3001\u7D71\u8A08\u6392\u884C\u3001\u662F\u5426\u51FA\u73FE\u904E\u67D0\u8A71\u984C\u6216\u8981\u6C42\u5F15\u7528\u539F\u8A71\uFF0C\u5FC5\u9808\u5148\u547C\u53EB\u5408\u9069\u7684\u8CC7\u6599\u5DE5\u5177\u6AA2\u7D22\u76EE\u524D\u8CC7\u6599\u5EAB\u3002
|
|
@@ -17127,7 +17878,7 @@ function buildPiModel(config, options) {
|
|
|
17127
17878
|
}
|
|
17128
17879
|
|
|
17129
17880
|
// ../../packages/node-runtime/src/ai/remote-api.ts
|
|
17130
|
-
import { completeSimple as
|
|
17881
|
+
import { completeSimple as completeSimple4 } from "@earendil-works/pi-ai";
|
|
17131
17882
|
async function fetchRemoteModels(provider, apiKey, baseUrl, apiFormat, options) {
|
|
17132
17883
|
const effectiveApiFormat = apiFormat || "openai-completions";
|
|
17133
17884
|
if (effectiveApiFormat === "anthropic-messages") {
|
|
@@ -17211,7 +17962,7 @@ async function validateApiKey(provider, apiKey, baseUrl, model, apiFormat, optio
|
|
|
17211
17962
|
const abortController = new AbortController();
|
|
17212
17963
|
const timeout = setTimeout(() => abortController.abort(), 15e3);
|
|
17213
17964
|
try {
|
|
17214
|
-
const result = await
|
|
17965
|
+
const result = await completeSimple4(
|
|
17215
17966
|
piModel,
|
|
17216
17967
|
{ messages: [{ role: "user", content: "Hi", timestamp: Date.now() }] },
|
|
17217
17968
|
{ apiKey, maxTokens: 1, signal: abortController.signal }
|
|
@@ -17232,7 +17983,7 @@ async function validateApiKey(provider, apiKey, baseUrl, model, apiFormat, optio
|
|
|
17232
17983
|
}
|
|
17233
17984
|
|
|
17234
17985
|
// ../../packages/node-runtime/src/ai/llm-stream.ts
|
|
17235
|
-
import { streamSimple } from "@earendil-works/pi-ai";
|
|
17986
|
+
import { streamSimple as streamSimple2 } from "@earendil-works/pi-ai";
|
|
17236
17987
|
function toPiMessages(messages, timestamp) {
|
|
17237
17988
|
return messages.map((m) => ({
|
|
17238
17989
|
role: m.role,
|
|
@@ -17245,7 +17996,7 @@ async function runSimpleLlmStream(options) {
|
|
|
17245
17996
|
const systemMsg = messages.find((m) => m.role === "system");
|
|
17246
17997
|
const nonSystemMsgs = messages.filter((m) => m.role !== "system");
|
|
17247
17998
|
const now = Date.now();
|
|
17248
|
-
const eventStream =
|
|
17999
|
+
const eventStream = streamSimple2(
|
|
17249
18000
|
piModel,
|
|
17250
18001
|
{
|
|
17251
18002
|
systemPrompt: systemMsg?.content,
|
|
@@ -17303,7 +18054,7 @@ async function runSimpleLlmStream(options) {
|
|
|
17303
18054
|
}
|
|
17304
18055
|
|
|
17305
18056
|
// ../../packages/node-runtime/src/ai/index.ts
|
|
17306
|
-
import { Type, completeSimple as
|
|
18057
|
+
import { Type, completeSimple as completeSimple6, streamSimple as streamSimple3 } from "@earendil-works/pi-ai";
|
|
17307
18058
|
|
|
17308
18059
|
// ../../packages/node-runtime/src/ai/rag/types.ts
|
|
17309
18060
|
var noopLogger = {
|
|
@@ -17342,7 +18093,7 @@ var _logger6 = getNoopLogger();
|
|
|
17342
18093
|
var _logger7 = getNoopLogger();
|
|
17343
18094
|
|
|
17344
18095
|
// ../../packages/node-runtime/src/ai/rag/pipeline/semantic.ts
|
|
17345
|
-
import { completeSimple as
|
|
18096
|
+
import { completeSimple as completeSimple5 } from "@earendil-works/pi-ai";
|
|
17346
18097
|
var _logger8 = getNoopLogger();
|
|
17347
18098
|
|
|
17348
18099
|
// ../../packages/node-runtime/src/migrations/electron-data-migration.ts
|
|
@@ -17967,7 +18718,7 @@ function getMetaPath(userDataDir) {
|
|
|
17967
18718
|
return path31.join(userDataDir, ".chatlab-meta.json");
|
|
17968
18719
|
}
|
|
17969
18720
|
function validateDataDirCompatibilityMeta(value, userDataDir, metaPath) {
|
|
17970
|
-
if (!
|
|
18721
|
+
if (!isRecord3(value)) {
|
|
17971
18722
|
throw createInvalidMetaError(userDataDir, metaPath, "Data directory compatibility meta must be an object.");
|
|
17972
18723
|
}
|
|
17973
18724
|
if (value.formatVersion !== 1) {
|
|
@@ -17978,7 +18729,7 @@ function validateDataDirCompatibilityMeta(value, userDataDir, metaPath) {
|
|
|
17978
18729
|
const reasons = value.reasons;
|
|
17979
18730
|
const updatedBy = value.updatedBy;
|
|
17980
18731
|
const updatedAt = value.updatedAt;
|
|
17981
|
-
if (!isStableSemver(minRuntimeVersion) || typeof dataCompatibilityVersion !== "number" || !Number.isInteger(dataCompatibilityVersion) || dataCompatibilityVersion < 0 || !Array.isArray(reasons) || !reasons.every(isNonEmptyString) || !
|
|
18732
|
+
if (!isStableSemver(minRuntimeVersion) || typeof dataCompatibilityVersion !== "number" || !Number.isInteger(dataCompatibilityVersion) || dataCompatibilityVersion < 0 || !Array.isArray(reasons) || !reasons.every(isNonEmptyString) || !isRecord3(updatedBy) || !isRuntimeKind(updatedBy.runtime) || !isNonEmptyString(updatedBy.module) || !isStableSemver(updatedBy.version) || typeof updatedAt !== "number" || !Number.isInteger(updatedAt) || updatedAt < 0) {
|
|
17982
18733
|
throw createInvalidMetaError(userDataDir, metaPath, "Invalid data directory compatibility meta fields.");
|
|
17983
18734
|
}
|
|
17984
18735
|
return {
|
|
@@ -18036,7 +18787,7 @@ function writeMetaAtomic(userDataDir, metaPath, meta) {
|
|
|
18036
18787
|
throw error;
|
|
18037
18788
|
}
|
|
18038
18789
|
}
|
|
18039
|
-
function
|
|
18790
|
+
function isRecord3(value) {
|
|
18040
18791
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18041
18792
|
}
|
|
18042
18793
|
function isNonEmptyString(value) {
|
|
@@ -18842,6 +19593,7 @@ var DEFAULTS = {
|
|
|
18842
19593
|
exportFormat: "markdown",
|
|
18843
19594
|
sqlExportFormat: "csv",
|
|
18844
19595
|
enableAutoSkill: true,
|
|
19596
|
+
chartAutoMode: "suggest",
|
|
18845
19597
|
searchContextBefore: 2,
|
|
18846
19598
|
searchContextAfter: 2,
|
|
18847
19599
|
contextCompression: {
|
|
@@ -18858,7 +19610,8 @@ var DEFAULTS = {
|
|
|
18858
19610
|
defaultSchemeId: null,
|
|
18859
19611
|
sessionSchemeOverrides: {}
|
|
18860
19612
|
},
|
|
18861
|
-
filterHistory: []
|
|
19613
|
+
filterHistory: [],
|
|
19614
|
+
thinkingLevels: {}
|
|
18862
19615
|
};
|
|
18863
19616
|
var PreferencesManager = class {
|
|
18864
19617
|
filePath;
|
|
@@ -18926,7 +19679,8 @@ var PreferencesManager = class {
|
|
|
18926
19679
|
customKeywordTemplates: partial.customKeywordTemplates ?? DEFAULTS.customKeywordTemplates,
|
|
18927
19680
|
deletedPresetTemplateIds: partial.deletedPresetTemplateIds ?? DEFAULTS.deletedPresetTemplateIds,
|
|
18928
19681
|
wordFilter: partial.wordFilter ? { ...DEFAULTS.wordFilter, ...partial.wordFilter } : { ...DEFAULTS.wordFilter },
|
|
18929
|
-
filterHistory: partial.filterHistory ?? DEFAULTS.filterHistory
|
|
19682
|
+
filterHistory: partial.filterHistory ?? DEFAULTS.filterHistory,
|
|
19683
|
+
thinkingLevels: partial.thinkingLevels ?? DEFAULTS.thinkingLevels
|
|
18930
19684
|
};
|
|
18931
19685
|
}
|
|
18932
19686
|
normalizeAiPreprocessConfig(partial) {
|
|
@@ -19549,7 +20303,7 @@ function buildSummaryDeps(db, llmConfig, deps) {
|
|
|
19549
20303
|
return getSegmentSummary(db, segmentId);
|
|
19550
20304
|
},
|
|
19551
20305
|
async llmComplete(systemPrompt, userPrompt, options) {
|
|
19552
|
-
const result = await
|
|
20306
|
+
const result = await completeSimple6(
|
|
19553
20307
|
piModel,
|
|
19554
20308
|
{
|
|
19555
20309
|
systemPrompt,
|
|
@@ -19836,6 +20590,8 @@ export {
|
|
|
19836
20590
|
createActivateSkillTool,
|
|
19837
20591
|
CHART_CAPABILITY_CORE_TOOLS,
|
|
19838
20592
|
getAllowedBuiltinToolsForChartAutoSkill,
|
|
20593
|
+
shouldUseChartCapabilityForMessage,
|
|
20594
|
+
getChartPlannerCapabilityForMessage,
|
|
19839
20595
|
resolveChartRuntimeForRequest,
|
|
19840
20596
|
getChartCapabilitySkill,
|
|
19841
20597
|
buildSkillMenuWithBuiltinChart,
|
|
@@ -19849,6 +20605,12 @@ export {
|
|
|
19849
20605
|
applyPreprocessingPipeline,
|
|
19850
20606
|
DEFAULT_MAX_TOOL_ROUNDS,
|
|
19851
20607
|
runAgentCore,
|
|
20608
|
+
createDataSnapshotFromOverview,
|
|
20609
|
+
decideRequestRoute,
|
|
20610
|
+
createLlmRouteDecider,
|
|
20611
|
+
createAnalysisPlanner,
|
|
20612
|
+
createPlanContentBlock,
|
|
20613
|
+
buildPlanGuidance,
|
|
19852
20614
|
AgentEventHandler,
|
|
19853
20615
|
buildSystemPrompt,
|
|
19854
20616
|
createAiTranslate,
|
|
@@ -19884,4 +20646,4 @@ export {
|
|
|
19884
20646
|
createDatabaseManagerAdapter,
|
|
19885
20647
|
MergeSessionCache
|
|
19886
20648
|
};
|
|
19887
|
-
//# sourceMappingURL=chunk-
|
|
20649
|
+
//# sourceMappingURL=chunk-QY67NN65.mjs.map
|