@vibe-lark/larkpal 0.1.73 → 0.1.74
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/main.mjs +150 -7
- package/package.json +1 -1
package/dist/main.mjs
CHANGED
|
@@ -782,7 +782,10 @@ function getToolDisplayName(toolName) {
|
|
|
782
782
|
* - parseError(error, rawLine) — 解析错误(不中断流)
|
|
783
783
|
*/
|
|
784
784
|
const log$36 = larkLogger("cc-runtime/stream-parser");
|
|
785
|
+
const MAX_TOOL_RESULT_CONTENT_CHARS = 8e3;
|
|
785
786
|
var CCStreamParser = class extends EventEmitter {
|
|
787
|
+
toolNamesById = /* @__PURE__ */ new Map();
|
|
788
|
+
declaredTools = null;
|
|
786
789
|
/**
|
|
787
790
|
* 解析一行 NDJSON 文本
|
|
788
791
|
*
|
|
@@ -830,6 +833,7 @@ var CCStreamParser = class extends EventEmitter {
|
|
|
830
833
|
subtype: msg.subtype,
|
|
831
834
|
detail: JSON.stringify(msg).slice(0, 500)
|
|
832
835
|
});
|
|
836
|
+
this.handleSystem(msg);
|
|
833
837
|
this.emit("system", msg);
|
|
834
838
|
break;
|
|
835
839
|
default:
|
|
@@ -858,6 +862,7 @@ var CCStreamParser = class extends EventEmitter {
|
|
|
858
862
|
toolUseId: block?.id
|
|
859
863
|
});
|
|
860
864
|
if (block?.type === "tool_use" && block.name) {
|
|
865
|
+
this.recordToolUse(block.name, block.id);
|
|
861
866
|
log$36.info("工具调用开始", {
|
|
862
867
|
toolName: block.name,
|
|
863
868
|
displayName: getToolDisplayName(block.name),
|
|
@@ -905,6 +910,7 @@ var CCStreamParser = class extends EventEmitter {
|
|
|
905
910
|
});
|
|
906
911
|
if (Array.isArray(content)) {
|
|
907
912
|
for (const block of content) if (block.type === "tool_use" && block.name) {
|
|
913
|
+
this.recordToolUse(block.name, block.id);
|
|
908
914
|
log$36.info("从 assistant 消息提取工具调用", {
|
|
909
915
|
toolName: block.name,
|
|
910
916
|
displayName: getToolDisplayName(block.name),
|
|
@@ -924,10 +930,46 @@ var CCStreamParser = class extends EventEmitter {
|
|
|
924
930
|
const content = msg.message?.content;
|
|
925
931
|
if (!Array.isArray(content)) return;
|
|
926
932
|
for (const item of content) if (item.type === "tool_result" && item.tool_use_id) {
|
|
927
|
-
|
|
928
|
-
|
|
933
|
+
const result = this.buildToolResultSummary(item, msg.toolUseResult);
|
|
934
|
+
log$36.debug("工具结果返回", {
|
|
935
|
+
toolUseId: item.tool_use_id,
|
|
936
|
+
toolName: result.toolName,
|
|
937
|
+
isError: result.isError,
|
|
938
|
+
truncated: result.truncated
|
|
939
|
+
});
|
|
940
|
+
this.emit("toolResult", item.tool_use_id, result);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
handleSystem(msg) {
|
|
944
|
+
if (msg.subtype !== "init" || !Array.isArray(msg.tools)) return;
|
|
945
|
+
this.declaredTools = new Set(msg.tools);
|
|
946
|
+
}
|
|
947
|
+
recordToolUse(toolName, toolUseId) {
|
|
948
|
+
if (toolUseId) this.toolNamesById.set(toolUseId, toolName);
|
|
949
|
+
if (this.declaredTools && !this.declaredTools.has(toolName)) {
|
|
950
|
+
log$36.warn("模型请求了未声明工具", {
|
|
951
|
+
toolName,
|
|
952
|
+
toolUseId
|
|
953
|
+
});
|
|
954
|
+
this.emit("unknownToolUse", toolName, toolUseId);
|
|
929
955
|
}
|
|
930
956
|
}
|
|
957
|
+
buildToolResultSummary(item, toolUseResult) {
|
|
958
|
+
const serializedContent = serializeToolResultContent(item.content);
|
|
959
|
+
const truncatedContent = truncateToolResultContent(serializedContent);
|
|
960
|
+
const toolUseResultSummary = summarizeToolUseResult(toolUseResult);
|
|
961
|
+
return {
|
|
962
|
+
toolCallId: item.tool_use_id,
|
|
963
|
+
toolName: this.toolNamesById.get(item.tool_use_id),
|
|
964
|
+
rawType: "tool_result",
|
|
965
|
+
isError: item.is_error,
|
|
966
|
+
content: truncatedContent.content,
|
|
967
|
+
resultSummary: extractToolResultSummary(serializedContent, toolUseResultSummary),
|
|
968
|
+
truncated: truncatedContent.truncated || toolUseResultSummary.truncated,
|
|
969
|
+
originalSize: Math.max(serializedContent.length, toolUseResultSummary.originalSize),
|
|
970
|
+
toolUseResult: toolUseResultSummary.summary
|
|
971
|
+
};
|
|
972
|
+
}
|
|
931
973
|
/**
|
|
932
974
|
* 处理 tool_progress 消息 — 工具执行进度
|
|
933
975
|
*/
|
|
@@ -959,6 +1001,52 @@ var CCStreamParser = class extends EventEmitter {
|
|
|
959
1001
|
});
|
|
960
1002
|
}
|
|
961
1003
|
};
|
|
1004
|
+
function serializeToolResultContent(content) {
|
|
1005
|
+
if (typeof content === "string") return content;
|
|
1006
|
+
return safeJsonStringify(content);
|
|
1007
|
+
}
|
|
1008
|
+
function summarizeToolUseResult(value) {
|
|
1009
|
+
if (value === void 0) return {
|
|
1010
|
+
originalSize: 0,
|
|
1011
|
+
truncated: false
|
|
1012
|
+
};
|
|
1013
|
+
const serialized = typeof value === "string" ? value : safeJsonStringify(value);
|
|
1014
|
+
const truncated = truncateToolResultContent(serialized);
|
|
1015
|
+
return {
|
|
1016
|
+
summary: typeof value === "string" ? truncated.content : tryParseJson$1(truncated.content) ?? truncated.content,
|
|
1017
|
+
originalSize: serialized.length,
|
|
1018
|
+
truncated: truncated.truncated
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
function truncateToolResultContent(content) {
|
|
1022
|
+
if (content.length <= MAX_TOOL_RESULT_CONTENT_CHARS) return {
|
|
1023
|
+
content,
|
|
1024
|
+
truncated: false
|
|
1025
|
+
};
|
|
1026
|
+
return {
|
|
1027
|
+
content: content.slice(0, MAX_TOOL_RESULT_CONTENT_CHARS),
|
|
1028
|
+
truncated: true
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
function extractToolResultSummary(content, toolUseResult) {
|
|
1032
|
+
const text = (typeof toolUseResult.summary === "string" ? toolUseResult.summary : toolUseResult.summary === void 0 ? void 0 : safeJsonStringify(toolUseResult.summary)) || content;
|
|
1033
|
+
const summary = (text.match(/<tool_use_error>([\s\S]*?)<\/tool_use_error>/)?.[1] || text).trim();
|
|
1034
|
+
return summary ? truncateToolResultContent(summary).content : void 0;
|
|
1035
|
+
}
|
|
1036
|
+
function safeJsonStringify(value) {
|
|
1037
|
+
try {
|
|
1038
|
+
return JSON.stringify(value);
|
|
1039
|
+
} catch {
|
|
1040
|
+
return String(value);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
function tryParseJson$1(value) {
|
|
1044
|
+
try {
|
|
1045
|
+
return JSON.parse(value);
|
|
1046
|
+
} catch {
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
962
1050
|
//#endregion
|
|
963
1051
|
//#region src/cc-runtime/process-manager.ts
|
|
964
1052
|
/**
|
|
@@ -1416,8 +1504,11 @@ var SessionProcessManager = class {
|
|
|
1416
1504
|
parser.on("toolUseStart", (toolName, toolInput) => {
|
|
1417
1505
|
getCallbacks()?.onToolUseStart?.(toolName, toolInput);
|
|
1418
1506
|
});
|
|
1419
|
-
parser.on("toolResult", (toolUseId) => {
|
|
1420
|
-
getCallbacks()?.onToolResult?.(toolUseId);
|
|
1507
|
+
parser.on("toolResult", (toolUseId, result) => {
|
|
1508
|
+
getCallbacks()?.onToolResult?.(toolUseId, result);
|
|
1509
|
+
});
|
|
1510
|
+
parser.on("unknownToolUse", (toolName, toolUseId) => {
|
|
1511
|
+
getCallbacks()?.onUnknownToolUse?.(toolName, toolUseId);
|
|
1421
1512
|
});
|
|
1422
1513
|
parser.on("toolProgress", (toolName, elapsedSeconds) => {
|
|
1423
1514
|
getCallbacks()?.onToolProgress?.(toolName, elapsedSeconds);
|
|
@@ -3732,6 +3823,9 @@ function serializeChatRun(run) {
|
|
|
3732
3823
|
lastEventAt: run.lastEventAt,
|
|
3733
3824
|
lastEventType: run.lastEventType,
|
|
3734
3825
|
lastToolName: run.lastToolName,
|
|
3826
|
+
lastToolError: run.lastToolError,
|
|
3827
|
+
unknownToolCallCount: run.unknownToolCallCount,
|
|
3828
|
+
lastUnknownToolName: run.lastUnknownToolName,
|
|
3735
3829
|
idleSeconds,
|
|
3736
3830
|
adapterBusy: run.status === "running" ? run.adapterBusy : false,
|
|
3737
3831
|
processStatus,
|
|
@@ -4244,6 +4338,29 @@ function isPathInside(parent, child) {
|
|
|
4244
4338
|
const path = relative(parent, child);
|
|
4245
4339
|
return path !== "" && !path.startsWith("..") && !isAbsolute(path);
|
|
4246
4340
|
}
|
|
4341
|
+
function buildToolResultPayload(result, resultSummary) {
|
|
4342
|
+
if (!result || typeof result !== "object" || Array.isArray(result)) return { result: resultSummary };
|
|
4343
|
+
const record = result;
|
|
4344
|
+
return {
|
|
4345
|
+
rawType: record.rawType,
|
|
4346
|
+
isError: record.isError,
|
|
4347
|
+
content: record.content,
|
|
4348
|
+
resultSummary: record.resultSummary ?? resultSummary,
|
|
4349
|
+
truncated: record.truncated,
|
|
4350
|
+
originalSize: record.originalSize,
|
|
4351
|
+
result: resultSummary
|
|
4352
|
+
};
|
|
4353
|
+
}
|
|
4354
|
+
function readStringField(value, key) {
|
|
4355
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
4356
|
+
const field = value[key];
|
|
4357
|
+
return typeof field === "string" ? field : void 0;
|
|
4358
|
+
}
|
|
4359
|
+
function readBooleanField(value, key) {
|
|
4360
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
4361
|
+
const field = value[key];
|
|
4362
|
+
return typeof field === "boolean" ? field : void 0;
|
|
4363
|
+
}
|
|
4247
4364
|
/**
|
|
4248
4365
|
* 创建 Chat 流式对话 + 历史查询路由
|
|
4249
4366
|
*
|
|
@@ -4594,8 +4711,12 @@ function createChatRouter(config) {
|
|
|
4594
4711
|
if (run.status !== "running") return;
|
|
4595
4712
|
recordRunEvent(run, "tool-result");
|
|
4596
4713
|
const resultSummary = summarizeForAudit(result);
|
|
4714
|
+
const toolName = readStringField(result, "toolName") || run.lastToolName;
|
|
4715
|
+
const isError = readBooleanField(result, "isError");
|
|
4716
|
+
if (isError) run.lastToolError = resultSummary;
|
|
4597
4717
|
if (runtimeConfig.requestContext) logChatAudit(buildAuditEvent(runtimeConfig.requestContext, "tool_call_finished", {
|
|
4598
4718
|
toolCallId: toolUseId,
|
|
4719
|
+
toolName,
|
|
4599
4720
|
resultSummary,
|
|
4600
4721
|
metadata: buildToolResultAuditMetadata(result)
|
|
4601
4722
|
}));
|
|
@@ -4604,7 +4725,8 @@ function createChatRouter(config) {
|
|
|
4604
4725
|
role: "tool",
|
|
4605
4726
|
content: JSON.stringify({
|
|
4606
4727
|
toolUseId,
|
|
4607
|
-
|
|
4728
|
+
toolName,
|
|
4729
|
+
...buildToolResultPayload(result, resultSummary)
|
|
4608
4730
|
}),
|
|
4609
4731
|
channel: "web",
|
|
4610
4732
|
metadata: {
|
|
@@ -4614,12 +4736,33 @@ function createChatRouter(config) {
|
|
|
4614
4736
|
scenarioId,
|
|
4615
4737
|
runtimeEventType: "tool-result",
|
|
4616
4738
|
toolCallId: toolUseId,
|
|
4617
|
-
|
|
4739
|
+
toolName,
|
|
4740
|
+
toolResult: resultSummary,
|
|
4741
|
+
isError
|
|
4618
4742
|
}
|
|
4619
4743
|
}, "[stream] 保存 tool result 消息失败");
|
|
4620
4744
|
broadcastRunEvent(run, "tool-result", {
|
|
4621
4745
|
toolUseId,
|
|
4622
|
-
|
|
4746
|
+
toolName,
|
|
4747
|
+
...buildToolResultPayload(result, resultSummary)
|
|
4748
|
+
});
|
|
4749
|
+
},
|
|
4750
|
+
onUnknownToolUse: (toolName, toolUseId) => {
|
|
4751
|
+
if (run.status !== "running") return;
|
|
4752
|
+
run.unknownToolCallCount = (run.unknownToolCallCount ?? 0) + 1;
|
|
4753
|
+
run.lastUnknownToolName = toolName;
|
|
4754
|
+
run.lastToolError = {
|
|
4755
|
+
isError: true,
|
|
4756
|
+
reasonCode: "UNKNOWN_TOOL_CALL",
|
|
4757
|
+
toolName,
|
|
4758
|
+
toolCallId: toolUseId
|
|
4759
|
+
};
|
|
4760
|
+
recordRunEvent(run, "unknown-tool-use", { toolName });
|
|
4761
|
+
broadcastRunEvent(run, "runtime-event", {
|
|
4762
|
+
type: "unknown-tool-use",
|
|
4763
|
+
toolName,
|
|
4764
|
+
toolUseId,
|
|
4765
|
+
unknownToolCallCount: run.unknownToolCallCount
|
|
4623
4766
|
});
|
|
4624
4767
|
},
|
|
4625
4768
|
onToolProgress: (toolName, elapsedSeconds) => {
|