@vibe-lark/larkpal 0.1.75 → 0.1.76
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/bin/larkpal.js +0 -0
- package/dist/main.mjs +125 -6
- package/package.json +15 -14
package/bin/larkpal.js
CHANGED
|
File without changes
|
package/dist/main.mjs
CHANGED
|
@@ -3961,6 +3961,7 @@ function serializeChatRun(run) {
|
|
|
3961
3961
|
completedAt: run.completedAt,
|
|
3962
3962
|
finalStatus: run.finalStatus,
|
|
3963
3963
|
error: run.error,
|
|
3964
|
+
runtimeError: run.runtimeError,
|
|
3964
3965
|
textLength: run.text.length,
|
|
3965
3966
|
finalText: run.status === "running" ? void 0 : run.text || void 0,
|
|
3966
3967
|
lastEventAt: run.lastEventAt,
|
|
@@ -4128,6 +4129,7 @@ function appendRunStatusMessage(run, messageStore) {
|
|
|
4128
4129
|
runtimeEventType: "run-status",
|
|
4129
4130
|
finalStatus: run.finalStatus,
|
|
4130
4131
|
errorMessage: run.error,
|
|
4132
|
+
runtimeError: run.runtimeError,
|
|
4131
4133
|
staleReason: run.staleReason
|
|
4132
4134
|
}
|
|
4133
4135
|
}, "[stream] 保存 run status 消息失败");
|
|
@@ -4494,6 +4496,107 @@ function buildToolResultPayload(result, resultSummary) {
|
|
|
4494
4496
|
result: resultSummary
|
|
4495
4497
|
};
|
|
4496
4498
|
}
|
|
4499
|
+
function normalizeRuntimeResult(result) {
|
|
4500
|
+
if (!result.isError) return {
|
|
4501
|
+
status: "completed",
|
|
4502
|
+
finalStatus: result.subtype,
|
|
4503
|
+
isError: false,
|
|
4504
|
+
finalText: result.result
|
|
4505
|
+
};
|
|
4506
|
+
const error = buildRuntimeErrorSummary(result.subtype, result.result);
|
|
4507
|
+
return {
|
|
4508
|
+
status: "failed",
|
|
4509
|
+
finalStatus: error.code,
|
|
4510
|
+
isError: true,
|
|
4511
|
+
finalText: result.result || error.message,
|
|
4512
|
+
error
|
|
4513
|
+
};
|
|
4514
|
+
}
|
|
4515
|
+
function buildRuntimeErrorSummary(subtype, result) {
|
|
4516
|
+
const message = normalizeWhitespace(result || `Runtime execution failed: ${subtype}`);
|
|
4517
|
+
const httpStatus = extractHttpStatus(message);
|
|
4518
|
+
const requestId = extractRequestId(message);
|
|
4519
|
+
const providerMessage = extractProviderMessage(message);
|
|
4520
|
+
return {
|
|
4521
|
+
isError: true,
|
|
4522
|
+
code: detectRuntimeErrorCode(subtype, message),
|
|
4523
|
+
subtype,
|
|
4524
|
+
httpStatus,
|
|
4525
|
+
message: truncateRuntimeErrorMessage(message),
|
|
4526
|
+
providerMessage: providerMessage ? truncateRuntimeErrorMessage(providerMessage) : void 0,
|
|
4527
|
+
requestId
|
|
4528
|
+
};
|
|
4529
|
+
}
|
|
4530
|
+
function detectRuntimeErrorCode(subtype, message) {
|
|
4531
|
+
if (/\bprovider_response_error\b/i.test(message)) return "provider_response_error";
|
|
4532
|
+
if (/\bapi_error\b/i.test(message) || /^API Error:/i.test(message)) return "api_error";
|
|
4533
|
+
if (subtype && subtype !== "success") return subtype;
|
|
4534
|
+
return "error_during_execution";
|
|
4535
|
+
}
|
|
4536
|
+
function extractHttpStatus(message) {
|
|
4537
|
+
const match = message.match(/\b(?:API Error:|provider[^:]*:)?\s*(\d{3})\b/i);
|
|
4538
|
+
if (!match?.[1]) return void 0;
|
|
4539
|
+
const status = Number.parseInt(match[1], 10);
|
|
4540
|
+
return Number.isFinite(status) ? status : void 0;
|
|
4541
|
+
}
|
|
4542
|
+
function extractRequestId(message) {
|
|
4543
|
+
return message.match(/\bRequest id:\s*([A-Za-z0-9._:-]+)/i)?.[1];
|
|
4544
|
+
}
|
|
4545
|
+
function extractProviderMessage(message) {
|
|
4546
|
+
const parsedMessage = extractJsonErrorMessage(message);
|
|
4547
|
+
if (parsedMessage) return parsedMessage;
|
|
4548
|
+
const jsonMessage = message.match(/"message"\s*:\s*"([^"]+)"/);
|
|
4549
|
+
if (jsonMessage?.[1]) return unescapeJsonFragment(jsonMessage[1]);
|
|
4550
|
+
const requestIdIndex = message.search(/\bRequest id:/i);
|
|
4551
|
+
if (requestIdIndex > 0) {
|
|
4552
|
+
const prefix = message.slice(0, requestIdIndex).trim();
|
|
4553
|
+
const sentenceStart = Math.max(prefix.lastIndexOf("}"), prefix.lastIndexOf(":"));
|
|
4554
|
+
return prefix.slice(sentenceStart + 1).trim() || void 0;
|
|
4555
|
+
}
|
|
4556
|
+
}
|
|
4557
|
+
function extractJsonErrorMessage(message) {
|
|
4558
|
+
const start = message.indexOf("{");
|
|
4559
|
+
const end = message.lastIndexOf("}");
|
|
4560
|
+
if (start < 0 || end <= start) return void 0;
|
|
4561
|
+
try {
|
|
4562
|
+
const topMessage = readNestedString(JSON.parse(message.slice(start, end + 1)), ["error", "message"]);
|
|
4563
|
+
if (!topMessage) return void 0;
|
|
4564
|
+
return extractNestedJsonErrorMessage(topMessage) || topMessage;
|
|
4565
|
+
} catch {
|
|
4566
|
+
return;
|
|
4567
|
+
}
|
|
4568
|
+
}
|
|
4569
|
+
function extractNestedJsonErrorMessage(message) {
|
|
4570
|
+
const start = message.indexOf("{");
|
|
4571
|
+
const end = message.lastIndexOf("}");
|
|
4572
|
+
if (start < 0 || end <= start) return void 0;
|
|
4573
|
+
try {
|
|
4574
|
+
return readNestedString(JSON.parse(message.slice(start, end + 1)), ["error", "message"]);
|
|
4575
|
+
} catch {
|
|
4576
|
+
return;
|
|
4577
|
+
}
|
|
4578
|
+
}
|
|
4579
|
+
function readNestedString(value, path) {
|
|
4580
|
+
let current = value;
|
|
4581
|
+
for (const key of path) {
|
|
4582
|
+
if (!current || typeof current !== "object" || Array.isArray(current)) return void 0;
|
|
4583
|
+
current = current[key];
|
|
4584
|
+
}
|
|
4585
|
+
return typeof current === "string" ? current : void 0;
|
|
4586
|
+
}
|
|
4587
|
+
function unescapeJsonFragment(value) {
|
|
4588
|
+
try {
|
|
4589
|
+
return JSON.parse(`"${value.replace(/"/g, "\\\"")}"`);
|
|
4590
|
+
} catch {
|
|
4591
|
+
return value.replace(/\\"/g, "\"").replace(/\\\\/g, "\\");
|
|
4592
|
+
}
|
|
4593
|
+
}
|
|
4594
|
+
function normalizeWhitespace(value) {
|
|
4595
|
+
return value.replace(/\s+/g, " ").trim();
|
|
4596
|
+
}
|
|
4597
|
+
function truncateRuntimeErrorMessage(value) {
|
|
4598
|
+
return value.length > 2e3 ? `${value.slice(0, 2e3)}...` : value;
|
|
4599
|
+
}
|
|
4497
4600
|
function readStringField(value, key) {
|
|
4498
4601
|
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
4499
4602
|
const field = value[key];
|
|
@@ -4928,9 +5031,15 @@ function createChatRouter(config) {
|
|
|
4928
5031
|
onResult: async (result) => {
|
|
4929
5032
|
if (run.status !== "running") return;
|
|
4930
5033
|
recordRunEvent(run, "result");
|
|
4931
|
-
const
|
|
5034
|
+
const normalizedResult = normalizeRuntimeResult(result);
|
|
5035
|
+
const partialText = run.text.trim() ? run.text : void 0;
|
|
5036
|
+
const finalText = normalizedResult.isError ? normalizedResult.finalText || partialText || "" : partialText || normalizedResult.finalText || "";
|
|
4932
5037
|
run.text = finalText;
|
|
4933
|
-
|
|
5038
|
+
run.runtimeError = normalizedResult.error;
|
|
5039
|
+
await markRunTerminal(run, messageStore, normalizedResult.status, {
|
|
5040
|
+
finalStatus: normalizedResult.finalStatus,
|
|
5041
|
+
error: normalizedResult.error?.message
|
|
5042
|
+
});
|
|
4934
5043
|
await cleanupTerminalRunProcess(run, processManager, "result");
|
|
4935
5044
|
await queueRunMessage(run, messageStore, {
|
|
4936
5045
|
sessionId,
|
|
@@ -4945,15 +5054,21 @@ function createChatRouter(config) {
|
|
|
4945
5054
|
traceId,
|
|
4946
5055
|
requestId,
|
|
4947
5056
|
scenarioId,
|
|
4948
|
-
finalStatus:
|
|
4949
|
-
isError:
|
|
5057
|
+
finalStatus: normalizedResult.finalStatus,
|
|
5058
|
+
isError: normalizedResult.isError,
|
|
5059
|
+
runtimeError: normalizedResult.error,
|
|
5060
|
+
partialText
|
|
4950
5061
|
}
|
|
4951
5062
|
}, "[stream] 保存 assistant 消息失败");
|
|
4952
5063
|
broadcastRunEvent(run, "done", {
|
|
4953
5064
|
sessionId,
|
|
4954
5065
|
runId: run.runId,
|
|
4955
|
-
result:
|
|
5066
|
+
result: normalizedResult.finalStatus,
|
|
5067
|
+
finalStatus: normalizedResult.finalStatus,
|
|
5068
|
+
isError: normalizedResult.isError,
|
|
5069
|
+
error: normalizedResult.error,
|
|
4956
5070
|
text: finalText,
|
|
5071
|
+
partialText,
|
|
4957
5072
|
durationMs: result.durationMs,
|
|
4958
5073
|
totalCostUsd: result.totalCostUsd,
|
|
4959
5074
|
numTurns: result.numTurns
|
|
@@ -4963,7 +5078,8 @@ function createChatRouter(config) {
|
|
|
4963
5078
|
log$30.info("[stream] 对话完成", {
|
|
4964
5079
|
sessionId,
|
|
4965
5080
|
runId: run.runId,
|
|
4966
|
-
result:
|
|
5081
|
+
result: normalizedResult.finalStatus,
|
|
5082
|
+
isError: normalizedResult.isError,
|
|
4967
5083
|
textLength: finalText.length,
|
|
4968
5084
|
durationMs: result.durationMs
|
|
4969
5085
|
});
|
|
@@ -4972,6 +5088,9 @@ function createChatRouter(config) {
|
|
|
4972
5088
|
metadata: {
|
|
4973
5089
|
runId: run.runId,
|
|
4974
5090
|
subtype: result.subtype,
|
|
5091
|
+
finalStatus: normalizedResult.finalStatus,
|
|
5092
|
+
isError: normalizedResult.isError,
|
|
5093
|
+
runtimeError: normalizedResult.error,
|
|
4975
5094
|
totalCostUsd: result.totalCostUsd,
|
|
4976
5095
|
numTurns: result.numTurns,
|
|
4977
5096
|
traceId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibe-lark/larkpal",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.76",
|
|
4
4
|
"description": "LarkPal - Lark/Feishu bot service",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/main.mjs",
|
|
@@ -21,9 +21,22 @@
|
|
|
21
21
|
"registry": "https://registry.npmjs.org",
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
|
+
"packageManager": "pnpm@10.32.1",
|
|
24
25
|
"engines": {
|
|
25
26
|
"node": ">=22"
|
|
26
27
|
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"start": "node --env-file=.env bin/larkpal.js",
|
|
30
|
+
"build": "tsdown",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"test:watch": "vitest",
|
|
33
|
+
"lint": "eslint src/",
|
|
34
|
+
"lint:fix": "eslint src/ --fix",
|
|
35
|
+
"sit:larkpal-agent": "node scripts/sit/larkpal-agent-0.1.9-sit.mjs",
|
|
36
|
+
"typecheck": "tsc --noEmit",
|
|
37
|
+
"format": "prettier --write src/**/*.ts",
|
|
38
|
+
"format:check": "prettier --check src/**/*.ts"
|
|
39
|
+
},
|
|
27
40
|
"dependencies": {
|
|
28
41
|
"@larksuiteoapi/node-sdk": "^1.60.0",
|
|
29
42
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
@@ -56,17 +69,5 @@
|
|
|
56
69
|
"typescript": "^5.9.3",
|
|
57
70
|
"typescript-eslint": "^8.32.1",
|
|
58
71
|
"vitest": "^4.1.1"
|
|
59
|
-
},
|
|
60
|
-
"scripts": {
|
|
61
|
-
"start": "node --env-file=.env bin/larkpal.js",
|
|
62
|
-
"build": "tsdown",
|
|
63
|
-
"test": "vitest run",
|
|
64
|
-
"test:watch": "vitest",
|
|
65
|
-
"lint": "eslint src/",
|
|
66
|
-
"lint:fix": "eslint src/ --fix",
|
|
67
|
-
"sit:larkpal-agent": "node scripts/sit/larkpal-agent-0.1.9-sit.mjs",
|
|
68
|
-
"typecheck": "tsc --noEmit",
|
|
69
|
-
"format": "prettier --write src/**/*.ts",
|
|
70
|
-
"format:check": "prettier --check src/**/*.ts"
|
|
71
72
|
}
|
|
72
|
-
}
|
|
73
|
+
}
|