@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 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 finalText = run.text.trim() ? run.text : result.result || "";
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
- await markRunTerminal(run, messageStore, result.isError ? "failed" : "completed", { finalStatus: result.subtype });
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: result.subtype,
4949
- isError: result.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: result.subtype,
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: result.subtype,
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.75",
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
+ }