duclaw-cli 1.8.13 → 1.8.15

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/bundle.js CHANGED
@@ -30242,7 +30242,7 @@ function printHelp() {
30242
30242
  `);
30243
30243
  }
30244
30244
  function printVersion() {
30245
- console.log(`duclaw-cli v${true ? "1.8.13" : "unknown"}`);
30245
+ console.log(`duclaw-cli v${true ? "1.8.15" : "unknown"}`);
30246
30246
  }
30247
30247
  function getDuclawTemplate() {
30248
30248
  return {
@@ -30589,6 +30589,19 @@ var enqueueSpoolMessage = async (input) => {
30589
30589
  };
30590
30590
 
30591
30591
  // src/channels/feishu/feishuChannelsPlugin.ts
30592
+ var buildFeishuMarkdownPostContent = (text2) => JSON.stringify({
30593
+ zh_cn: {
30594
+ title: "",
30595
+ content: [
30596
+ [
30597
+ {
30598
+ tag: "md",
30599
+ text: text2
30600
+ }
30601
+ ]
30602
+ ]
30603
+ }
30604
+ });
30592
30605
  var feishuChannelPlugin = {
30593
30606
  id: `feishu-channel`,
30594
30607
  meta: {
@@ -30612,8 +30625,8 @@ var feishuChannelPlugin = {
30612
30625
  },
30613
30626
  data: {
30614
30627
  receive_id: ctx.to,
30615
- content: JSON.stringify({ text: ctx.text }),
30616
- msg_type: "text"
30628
+ content: buildFeishuMarkdownPostContent(ctx.text),
30629
+ msg_type: "post"
30617
30630
  }
30618
30631
  });
30619
30632
  },
@@ -32616,7 +32629,7 @@ var chokidar_default = { watch, FSWatcher };
32616
32629
  var import_node_cron = __toESM(require_node_cron());
32617
32630
 
32618
32631
  // src/agent/createAgent.ts
32619
- var import_node_crypto10 = require("node:crypto");
32632
+ var import_node_crypto11 = require("node:crypto");
32620
32633
  var import_node_fs6 = require("node:fs");
32621
32634
 
32622
32635
  // src/background/BackgroundManager.ts
@@ -39463,13 +39476,13 @@ var Diff = class {
39463
39476
  editLength++;
39464
39477
  };
39465
39478
  if (callback) {
39466
- (function exec2() {
39479
+ (function exec() {
39467
39480
  setTimeout(function() {
39468
39481
  if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
39469
39482
  return callback(void 0);
39470
39483
  }
39471
39484
  if (!execEditLength()) {
39472
- exec2();
39485
+ exec();
39473
39486
  }
39474
39487
  }, 0);
39475
39488
  })();
@@ -40423,7 +40436,7 @@ var DESCRIPTION9 = `
40423
40436
  - MUST be called at least once in every user interaction to provide a response
40424
40437
  - Without calling this tool, users receive NO feedback or results whatsoever
40425
40438
  - Always call this tool to acknowledge user requests, report progress, and deliver final results
40426
- - \u4E0D\u8981\u7528markdown\u683C\u5F0F\u56DE\u590D\uFF0C\u7528\u6237\u63A5\u6536\u7AEF\u4E0D\u652F\u6301markdown\u683C\u5F0F\u6E32\u67D3
40439
+ - \u53EF\u4EE5\u4F7F\u7528\u57FA\u7840 Markdown \u63D0\u5347\u53EF\u8BFB\u6027\uFF0C\u4F8B\u5982\u52A0\u7C97\u3001\u5217\u8868\u3001\u94FE\u63A5\u548C\u4EE3\u7801\u5757\uFF1B\u907F\u514D\u590D\u6742\u8868\u683C\u7B49\u98DE\u4E66\u53EF\u80FD\u4E0D\u5B8C\u6574\u652F\u6301\u7684\u683C\u5F0F
40427
40440
  `;
40428
40441
  var sendMessage = {
40429
40442
  name: `send_message`,
@@ -42860,6 +42873,7 @@ var mailboxFollowup = {
42860
42873
 
42861
42874
  // src/tools/tools/Bash.ts
42862
42875
  var import_node_child_process = require("node:child_process");
42876
+ var import_node_crypto7 = require("node:crypto");
42863
42877
  var import_node_fs4 = require("node:fs");
42864
42878
  var DESCRIPTION29 = `\u5728\u7CFB\u7EDF shell \u4E2D\u6267\u884C\u547D\u4EE4\u3002
42865
42879
 
@@ -42875,17 +42889,24 @@ var DESCRIPTION29 = `\u5728\u7CFB\u7EDF shell \u4E2D\u6267\u884C\u547D\u4EE4\u30
42875
42889
  - Bash \u53EF\u4EE5\u7528\u6765\u8FD0\u884C\u6D4B\u8BD5\u3001\u683C\u5F0F\u5316\u3001\u8BAD\u7EC3\u3001\u63A8\u7406\u3001\u67E5\u770B\u76EE\u5F55\u3001\u6267\u884C\u5DF2\u7ECF\u5199\u597D\u7684\u811A\u672C\u3002
42876
42890
 
42877
42891
  \u53C2\u6570\uFF1A
42892
+ - action: \u64CD\u4F5C\u7C7B\u578B\uFF08\u53EF\u9009\uFF0Crun/check/write/stop\uFF0C\u9ED8\u8BA4 run\uFF09
42878
42893
  - command: \u8981\u6267\u884C\u7684 shell \u547D\u4EE4
42879
42894
  - cwd: \u547D\u4EE4\u6267\u884C\u7684\u5DE5\u4F5C\u76EE\u5F55\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u76EE\u5F55\uFF09
42880
- - timeout: \u8D85\u65F6\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF0C\u53EF\u9009\uFF0C\u9ED8\u8BA4 30000ms\uFF09
42895
+ - timeout: \u7B49\u5F85\u547D\u4EE4\u5B8C\u6210\u7684\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF0C\u53EF\u9009\uFF0C\u9ED8\u8BA4 30000ms\uFF09\u3002\u8D85\u8FC7\u540E\u547D\u4EE4\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C\uFF0C\u5E76\u8FD4\u56DE session_id
42896
+ - session_id: \u540E\u53F0\u8FD0\u884C\u4E2D\u7684 Bash \u4F1A\u8BDD ID\uFF08check/write/stop \u65F6\u4F7F\u7528\uFF09
42897
+ - input: \u5199\u5165\u540E\u53F0\u4F1A\u8BDD stdin \u7684\u5185\u5BB9\uFF08write \u65F6\u4F7F\u7528\uFF09
42881
42898
 
42882
42899
  \u6CE8\u610F\u4E8B\u9879\uFF1A
42883
42900
  - \u4E0D\u8981\u6267\u884C\u7834\u574F\u6027\u547D\u4EE4\uFF08\u5982 rm -rf /\uFF09
42884
- - \u957F\u65F6\u95F4\u8FD0\u884C\u7684\u547D\u4EE4\uFF08\u5982\u542F\u52A8\u670D\u52A1\u5668\uFF09\u4F1A\u5728\u8D85\u65F6\u540E\u88AB\u7EC8\u6B62
42901
+ - \u957F\u65F6\u95F4\u8FD0\u884C\u7684\u547D\u4EE4\uFF08\u5982\u542F\u52A8\u670D\u52A1\u5668\uFF09\u8D85\u8FC7\u7B49\u5F85\u65F6\u95F4\u540E\u4F1A\u4FDD\u7559\u4F1A\u8BDD\uFF0C\u53EF\u7528 session_id \u67E5\u8BE2\u589E\u91CF\u8F93\u51FA
42885
42902
  - \u5982\u679C\u4F60\u5904\u4E8E\u90E8\u95E8\u5DE5\u4F5C\u533A\u6A21\u5F0F\uFF0Ccwd \u5FC5\u987B\u5728\u5DE5\u4F5C\u533A\u8303\u56F4\u5185
42886
42903
  `;
42887
42904
  var MAX_OUTPUT_LENGTH = 1e4;
42905
+ var MAX_SESSION_OUTPUT_LENGTH = 5e4;
42906
+ var DEFAULT_TIMEOUT_MS = 3e4;
42907
+ var DEFAULT_SESSION_TTL_MS = 30 * 60 * 1e3;
42888
42908
  var SHELL_CANDIDATES2 = ["/bin/sh", "/usr/bin/sh", "/bin/bash"];
42909
+ var sessions = /* @__PURE__ */ new Map();
42889
42910
  function findExecutableShell2() {
42890
42911
  for (const shell of SHELL_CANDIDATES2) {
42891
42912
  try {
@@ -42915,12 +42936,70 @@ function validateCwd(cwd) {
42915
42936
  return `[bash] \u9519\u8BEF: cwd \u4E0D\u53EF\u7528: ${cwd} (${err.message})`;
42916
42937
  }
42917
42938
  }
42939
+ function truncateOutput(output, limit = MAX_OUTPUT_LENGTH) {
42940
+ if (output.length <= limit) return output;
42941
+ return output.slice(0, limit) + `
42942
+ ... (\u8F93\u51FA\u622A\u65AD\uFF0C\u5171 ${output.length} \u5B57\u7B26)`;
42943
+ }
42944
+ function appendSessionOutput(session, chunk, source) {
42945
+ const text2 = chunk.toString();
42946
+ session.output += source === "stderr" ? `[stderr]
42947
+ ${text2}` : text2;
42948
+ if (session.output.length > MAX_SESSION_OUTPUT_LENGTH) {
42949
+ const removed = session.output.length - MAX_SESSION_OUTPUT_LENGTH;
42950
+ session.output = session.output.slice(removed);
42951
+ session.readOffset = Math.max(0, session.readOffset - removed);
42952
+ }
42953
+ }
42954
+ function finishSession(session, status, exitCode, signal) {
42955
+ if (session.status !== "running") return;
42956
+ session.status = status;
42957
+ session.exitCode = exitCode;
42958
+ session.signal = signal;
42959
+ session.finishedAt = (/* @__PURE__ */ new Date()).toISOString();
42960
+ if (status === "failed") {
42961
+ const prefix = session.output ? "\n" : "";
42962
+ session.output += `${prefix}[bash] \u547D\u4EE4\u9000\u51FA\u7801: ${exitCode ?? "unknown"}${signal ? `, signal: ${signal}` : ""}`;
42963
+ }
42964
+ }
42965
+ function renderSessionDelta(session, prefix) {
42966
+ const delta = session.output.slice(session.readOffset);
42967
+ session.readOffset = session.output.length;
42968
+ const body = delta ? truncateOutput(delta) : "[bash] \u6682\u65E0\u65B0\u8F93\u51FA";
42969
+ const state = session.status === "running" ? `\u4ECD\u5728\u8FD0\u884C` : `\u5DF2\u7ED3\u675F\uFF08status=${session.status}${session.exitCode === void 0 ? "" : `, exitCode=${session.exitCode}`}\uFF09`;
42970
+ return `${prefix}
42971
+ [bash] session_id=${session.id} ${state}
42972
+ ${body}`;
42973
+ }
42974
+ function waitForClose(session, waitMs) {
42975
+ if (session.status !== "running") return Promise.resolve("closed");
42976
+ return new Promise((resolve11) => {
42977
+ const timer = setTimeout(() => {
42978
+ cleanup();
42979
+ resolve11("timeout");
42980
+ }, waitMs);
42981
+ const onClose = () => {
42982
+ cleanup();
42983
+ resolve11("closed");
42984
+ };
42985
+ const cleanup = () => {
42986
+ clearTimeout(timer);
42987
+ session.child.off("close", onClose);
42988
+ };
42989
+ session.child.once("close", onClose);
42990
+ });
42991
+ }
42918
42992
  var bashTool = {
42919
42993
  name: `bash`,
42920
42994
  description: DESCRIPTION29,
42921
42995
  input_schema: {
42922
42996
  type: `object`,
42923
42997
  properties: {
42998
+ action: {
42999
+ type: `string`,
43000
+ enum: [`run`, `check`, `write`, `stop`],
43001
+ description: `\u64CD\u4F5C\u7C7B\u578B\uFF1Arun \u6267\u884C\u547D\u4EE4\uFF1Bcheck \u8BFB\u53D6\u540E\u53F0\u4F1A\u8BDD\u589E\u91CF\u8F93\u51FA\uFF1Bwrite \u5411\u540E\u53F0\u4F1A\u8BDD stdin \u5199\u5165\u5185\u5BB9\uFF1Bstop \u505C\u6B62\u540E\u53F0\u4F1A\u8BDD\u3002\u9ED8\u8BA4 run`
43002
+ },
42924
43003
  command: {
42925
43004
  type: `string`,
42926
43005
  description: `\u8981\u6267\u884C\u7684 shell \u547D\u4EE4`
@@ -42931,15 +43010,50 @@ var bashTool = {
42931
43010
  },
42932
43011
  timeout: {
42933
43012
  type: `number`,
42934
- description: `\u8D85\u65F6\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09\uFF0C\u9ED8\u8BA4 30000`
43013
+ description: `run \u65F6\u7B49\u5F85\u547D\u4EE4\u5B8C\u6210\u7684\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09\uFF0C\u9ED8\u8BA4 30000\u3002\u8D85\u8FC7\u540E\u8FD4\u56DE session_id\uFF0C\u547D\u4EE4\u7EE7\u7EED\u8FD0\u884C`
43014
+ },
43015
+ session_id: {
43016
+ type: `string`,
43017
+ description: `\u540E\u53F0 Bash \u4F1A\u8BDD ID\uFF0C\u7528\u4E8E check/write/stop`
43018
+ },
43019
+ input: {
43020
+ type: `string`,
43021
+ description: `write \u65F6\u5199\u5165 stdin \u7684\u5185\u5BB9`
42935
43022
  }
42936
43023
  },
42937
- required: [`command`]
43024
+ required: []
42938
43025
  },
42939
43026
  async execute(input, userRequest) {
43027
+ const action = input.action || "run";
43028
+ const sessionId = input.session_id;
43029
+ if (action === "check" || action === "write" || action === "stop") {
43030
+ if (!sessionId) return `[bash] \u9519\u8BEF: ${action} \u9700\u8981 session_id`;
43031
+ const session = sessions.get(sessionId);
43032
+ if (!session) return `[bash] \u9519\u8BEF: \u672A\u627E\u5230 session_id: ${sessionId}`;
43033
+ if (action === "write") {
43034
+ if (session.status !== "running") {
43035
+ return renderSessionDelta(session, `[bash] session ${session.id} \u5DF2\u4E0D\u5728\u8FD0\u884C\uFF0C\u65E0\u6CD5\u5199\u5165 stdin`);
43036
+ }
43037
+ const stdin = input.input;
43038
+ if (stdin === void 0) return `[bash] \u9519\u8BEF: write \u9700\u8981 input`;
43039
+ session.child.stdin.write(stdin);
43040
+ return renderSessionDelta(session, `[bash] \u5DF2\u5199\u5165 session ${session.id} stdin`);
43041
+ }
43042
+ if (action === "stop") {
43043
+ if (session.status === "running") {
43044
+ session.child.kill("SIGTERM");
43045
+ finishSession(session, "stopped", null, "SIGTERM");
43046
+ }
43047
+ return renderSessionDelta(session, `[bash] \u5DF2\u505C\u6B62 session ${session.id}`);
43048
+ }
43049
+ return renderSessionDelta(session, `[bash] \u5DF2\u68C0\u67E5 session ${session.id}`);
43050
+ }
43051
+ if (action !== "run") {
43052
+ return `[bash] \u9519\u8BEF: \u4E0D\u652F\u6301\u7684 action: ${action}`;
43053
+ }
42940
43054
  const command = input.command;
42941
43055
  const explicitCwd = input.cwd || void 0;
42942
- const timeout = input.timeout || 3e4;
43056
+ const timeout = input.timeout || DEFAULT_TIMEOUT_MS;
42943
43057
  if (!command || command.trim() === "") {
42944
43058
  return `[bash] \u9519\u8BEF: command \u4E0D\u80FD\u4E3A\u7A7A`;
42945
43059
  }
@@ -42954,41 +43068,56 @@ var bashTool = {
42954
43068
  if (!shell) {
42955
43069
  return `[bash] \u9519\u8BEF: \u6267\u884C\u73AF\u5883\u7F3A\u5C11\u53EF\u7528 shell\uFF08\u5DF2\u68C0\u67E5 ${SHELL_CANDIDATES2.join(", ")}\uFF09\u3002\u8BF7\u5148\u68C0\u67E5\u5BB9\u5668\u955C\u50CF/rootfs/\u6302\u8F7D\u662F\u5426\u521D\u59CB\u5316\u5B8C\u6210\u3002`;
42956
43070
  }
42957
- return new Promise((resolve11) => {
43071
+ return new Promise(async (resolve11) => {
42958
43072
  const options = {
42959
- timeout,
42960
- maxBuffer: 1024 * 1024,
42961
- // 1MB
42962
- env: { ...process.env, PAGER: "cat" },
42963
- shell
43073
+ env: { ...process.env, PAGER: "cat" }
42964
43074
  };
42965
43075
  if (cwd) options.cwd = cwd;
42966
- (0, import_node_child_process.exec)(command, options, (error, stdout, stderr) => {
42967
- let output = "";
42968
- if (stdout) {
42969
- const trimmed = stdout.length > MAX_OUTPUT_LENGTH ? stdout.slice(0, MAX_OUTPUT_LENGTH) + `
42970
- ... (\u8F93\u51FA\u622A\u65AD\uFF0C\u5171 ${stdout.length} \u5B57\u7B26)` : stdout;
42971
- output += trimmed;
42972
- }
42973
- if (stderr) {
42974
- const trimmed = stderr.length > MAX_OUTPUT_LENGTH ? stderr.slice(0, MAX_OUTPUT_LENGTH) + `
42975
- ... (stderr \u622A\u65AD\uFF0C\u5171 ${stderr.length} \u5B57\u7B26)` : stderr;
42976
- output += (output ? "\n" : "") + `[stderr]
42977
- ${trimmed}`;
42978
- }
42979
- if (error) {
42980
- if (error.killed) {
42981
- output += `
42982
- [bash] \u547D\u4EE4\u8D85\u65F6\uFF08${timeout}ms\uFF09\uFF0C\u5DF2\u7EC8\u6B62`;
42983
- } else if (!stderr) {
42984
- output += (output ? "\n" : "") + `[bash] \u9519\u8BEF: ${error.message}`;
42985
- }
42986
- }
42987
- if (!output) {
42988
- output = "[bash] \u547D\u4EE4\u6267\u884C\u6210\u529F\uFF08\u65E0\u8F93\u51FA\uFF09";
42989
- }
42990
- resolve11(output);
43076
+ const child = (0, import_node_child_process.spawn)(shell, ["-c", command], {
43077
+ ...options,
43078
+ stdio: ["pipe", "pipe", "pipe"]
43079
+ });
43080
+ const id = (0, import_node_crypto7.randomUUID)().slice(0, 8);
43081
+ const session = {
43082
+ id,
43083
+ command,
43084
+ child,
43085
+ output: "",
43086
+ readOffset: 0,
43087
+ status: "running",
43088
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
43089
+ cleanupTimer: setTimeout(() => {
43090
+ const current = sessions.get(id);
43091
+ if (!current) return;
43092
+ if (current.status === "running") {
43093
+ current.child.kill("SIGTERM");
43094
+ finishSession(current, "stopped", null, "SIGTERM");
43095
+ }
43096
+ sessions.delete(id);
43097
+ }, DEFAULT_SESSION_TTL_MS)
43098
+ };
43099
+ sessions.set(id, session);
43100
+ child.stdout.on("data", (chunk) => appendSessionOutput(session, chunk, "stdout"));
43101
+ child.stderr.on("data", (chunk) => appendSessionOutput(session, chunk, "stderr"));
43102
+ child.on("error", (err) => {
43103
+ session.output += `[bash] \u9519\u8BEF: ${err.message}`;
43104
+ finishSession(session, "failed");
43105
+ });
43106
+ child.on("close", (code, signal) => {
43107
+ finishSession(session, code === 0 ? "completed" : "failed", code, signal);
42991
43108
  });
43109
+ const waitResult = await waitForClose(session, Math.max(0, timeout));
43110
+ if (waitResult === "timeout" && session.status === "running") {
43111
+ resolve11(renderSessionDelta(session, `[bash] \u547D\u4EE4\u4ECD\u5728\u8FD0\u884C\uFF0C\u5DF2\u4FDD\u7559\u540E\u53F0\u4F1A\u8BDD\u3002\u540E\u7EED\u4F7F\u7528 action=check \u548C session_id=${session.id} \u8BFB\u53D6\u8FDB\u5C55\uFF1B\u4F7F\u7528 action=stop \u53EF\u505C\u6B62\u3002`));
43112
+ return;
43113
+ }
43114
+ clearTimeout(session.cleanupTimer);
43115
+ sessions.delete(id);
43116
+ let output = session.output;
43117
+ if (!output) {
43118
+ output = session.status === "completed" ? "[bash] \u547D\u4EE4\u6267\u884C\u6210\u529F\uFF08\u65E0\u8F93\u51FA\uFF09" : "[bash] \u547D\u4EE4\u6267\u884C\u5931\u8D25\uFF08\u65E0\u8F93\u51FA\uFF09";
43119
+ }
43120
+ resolve11(truncateOutput(output));
42992
43121
  });
42993
43122
  }
42994
43123
  };
@@ -43562,7 +43691,7 @@ var readDreamHistoryLimit = () => {
43562
43691
  var import_node_fs5 = require("node:fs");
43563
43692
  var import_node_os2 = require("node:os");
43564
43693
  var import_node_path12 = require("node:path");
43565
- var import_node_crypto7 = require("node:crypto");
43694
+ var import_node_crypto8 = require("node:crypto");
43566
43695
  var SkillForgeEngine = class {
43567
43696
  proposalStorage;
43568
43697
  draftRoot;
@@ -43591,7 +43720,7 @@ var SkillForgeEngine = class {
43591
43720
  if (pending.some((p) => p.skillName === skillName)) {
43592
43721
  return null;
43593
43722
  }
43594
- const id = (0, import_node_crypto7.randomBytes)(4).toString("hex");
43723
+ const id = (0, import_node_crypto8.randomBytes)(4).toString("hex");
43595
43724
  const draftDir = (0, import_node_path12.join)(this.draftRoot, userId, id);
43596
43725
  (0, import_node_fs5.mkdirSync)(draftDir, { recursive: true });
43597
43726
  (0, import_node_fs5.writeFileSync)((0, import_node_path12.join)(draftDir, "SKILL.md"), skillMd, "utf-8");
@@ -43839,7 +43968,7 @@ var skillForgeDrop = (engine) => ({
43839
43968
  });
43840
43969
 
43841
43970
  // src/memory/MemoryEngine.ts
43842
- var import_node_crypto8 = require("node:crypto");
43971
+ var import_node_crypto9 = require("node:crypto");
43843
43972
  var MemoryEngine = class {
43844
43973
  storage;
43845
43974
  recallIndexStorage;
@@ -43867,7 +43996,7 @@ var MemoryEngine = class {
43867
43996
  }
43868
43997
  const now = Date.now();
43869
43998
  const memory = {
43870
- id: (0, import_node_crypto8.randomBytes)(4).toString("hex"),
43999
+ id: (0, import_node_crypto9.randomBytes)(4).toString("hex"),
43871
44000
  userId,
43872
44001
  title,
43873
44002
  content,
@@ -44520,7 +44649,7 @@ var microCompactMessages = (messages, config2) => {
44520
44649
  };
44521
44650
 
44522
44651
  // src/agent/events.ts
44523
- var import_node_crypto9 = require("node:crypto");
44652
+ var import_node_crypto10 = require("node:crypto");
44524
44653
  var rowToEvent = (row) => ({
44525
44654
  id: row.id,
44526
44655
  userId: row.userId,
@@ -44537,7 +44666,7 @@ var rowToEvent = (row) => ({
44537
44666
  var recordAgentEvent = (input) => {
44538
44667
  const db3 = createSqliteDB();
44539
44668
  const now = Date.now();
44540
- const id = `evt_${(0, import_node_crypto9.randomUUID)().slice(0, 12)}`;
44669
+ const id = `evt_${(0, import_node_crypto10.randomUUID)().slice(0, 12)}`;
44541
44670
  const payloadJson = JSON.stringify(input.payload);
44542
44671
  db3.prepare(`
44543
44672
  INSERT INTO agent_events (
@@ -44669,7 +44798,7 @@ var assistantMessageFromResponse = (response) => ({
44669
44798
  ...response.model ? { model: response.model } : {}
44670
44799
  });
44671
44800
  var llmRequestIdForTurn = (request, messages, system, tools) => {
44672
- const hash = (0, import_node_crypto10.createHash)("sha256").update(request.requestId).update("\0").update(system).update("\0").update(JSON.stringify(messages)).update("\0").update(JSON.stringify(tools.map((tool) => tool.name).sort())).digest("hex").slice(0, 40);
44801
+ const hash = (0, import_node_crypto11.createHash)("sha256").update(request.requestId).update("\0").update(system).update("\0").update(JSON.stringify(messages)).update("\0").update(JSON.stringify(tools.map((tool) => tool.name).sort())).digest("hex").slice(0, 40);
44673
44802
  return `dreq_${hash}`;
44674
44803
  };
44675
44804
  var getDefaultAgentConfig = (tools, systemPrompt) => {
@@ -44775,7 +44904,7 @@ The user will primarily request you perform software engineering tasks. This inc
44775
44904
  - Use specialized tools instead of bash commands when possible, as this provides a better user experience. For file operations, use dedicated tools: Read for reading files instead of cat/head/tail, Edit for editing instead of sed/awk, and Write for creating files instead of cat with heredoc or echo redirection. Reserve bash tools exclusively for actual system commands and terminal operations that require shell execution. NEVER use bash echo or other command-line tools to communicate thoughts, explanations, or instructions to the user. Output all communication directly in your response text instead.
44776
44905
  - VERY IMPORTANT: When exploring the codebase to gather context or to answer a question that is not a needle query for a specific file/class/function, it is CRITICAL that you use the Task tool instead of running search commands directly.
44777
44906
  - \u5F53\u7528\u6237\u63D0\u5230"\u4E4B\u524D"\u3001"\u4E0A\u6B21"\u3001"\u4EE5\u524D\u804A\u8FC7"\u7B49\u6D89\u53CA\u5386\u53F2\u5BF9\u8BDD\u7684\u5185\u5BB9\u65F6\uFF0C\u4F7F\u7528 recall_chat_history \u5DE5\u5177\u68C0\u7D22\u3002query \u5FC5\u987B\u5305\u542B\u5177\u4F53\u5173\u952E\u8BCD\uFF0C\u901A\u5E38\u53EA\u9700 1 \u6B21\u8C03\u7528\u5373\u53EF\uFF0C\u907F\u514D\u53CD\u590D\u68C0\u7D22\u6D6A\u8D39\u4E0A\u4E0B\u6587\u3002
44778
- - send_message \u5DE5\u5177\u662F\u4F60\u552F\u4E00\u548C\u7528\u6237\u901A\u4FE1\u7684\u5DE5\u5177\uFF0C\u6BCF\u6B21\u4EA4\u4E92\u90FD\u81F3\u5C11\u8981\u8C03\u7528\u4E00\u6B21\uFF0C\u5426\u5219\uFF0C\u7528\u6237\u5C06\u6536\u4E0D\u5230\u4F60\u7684\u5904\u7406\u7ED3\u679C\uFF0C\u8FD9\u662F\u4E0D\u53EF\u63A5\u53D7\u7684\u3002\u56DE\u590D\u5C3D\u91CF\u4E0D\u8981\u7528markdown\u683C\u5F0F\uFF0C\u65E0\u6CD5\u4FDD\u8BC1\u7528\u6237\u7AEF\u8BBE\u5907\u662F\u5426\u652F\u6301markdown\u6E32\u67D3\u3002
44907
+ - send_message \u5DE5\u5177\u662F\u4F60\u552F\u4E00\u548C\u7528\u6237\u901A\u4FE1\u7684\u5DE5\u5177\uFF0C\u6BCF\u6B21\u4EA4\u4E92\u90FD\u81F3\u5C11\u8981\u8C03\u7528\u4E00\u6B21\uFF0C\u5426\u5219\uFF0C\u7528\u6237\u5C06\u6536\u4E0D\u5230\u4F60\u7684\u5904\u7406\u7ED3\u679C\uFF0C\u8FD9\u662F\u4E0D\u53EF\u63A5\u53D7\u7684\u3002\u53EF\u4F7F\u7528\u57FA\u7840 Markdown \u63D0\u5347\u53EF\u8BFB\u6027\uFF0C\u4F8B\u5982\u52A0\u7C97\u3001\u5217\u8868\u3001\u94FE\u63A5\u548C\u4EE3\u7801\u5757\uFF1B\u907F\u514D\u590D\u6742\u8868\u683C\u7B49\u98DE\u4E66\u53EF\u80FD\u4E0D\u5B8C\u6574\u652F\u6301\u7684\u683C\u5F0F\u3002
44779
44908
  - /<skill-name> (e.g., /commit) is shorthand for users to invoke a user-invocable skill. When executed, the skill gets expanded to a full prompt. Use the Skill tool to execute them. IMPORTANT: Only use Skill for skills listed in its user-invocable skills section - do not guess or use built-in CLI commands.
44780
44909
  </Tool usage policy>
44781
44910
 
@@ -45503,7 +45632,7 @@ var getCronSystemPrompt = () => {
45503
45632
 
45504
45633
  <\u5173\u952E\u89C4\u5219>
45505
45634
  - send_message \u662F\u4F60\u552F\u4E00\u5C06\u7ED3\u679C\u9001\u8FBE\u7528\u6237\u7684\u65B9\u5F0F\uFF0C\u6BCF\u6B21\u6267\u884C\u5FC5\u987B\u81F3\u5C11\u8C03\u7528\u4E00\u6B21\uFF0C\u5426\u5219\u7528\u6237\u5C06\u6536\u4E0D\u5230\u4EFB\u4F55\u7ED3\u679C\u3002
45506
- - \u56DE\u590D\u5185\u5BB9\u4F7F\u7528\u7EAF\u6587\u672C\u683C\u5F0F\uFF0C\u4E0D\u8981\u4F7F\u7528 markdown\uFF0C\u7528\u6237\u63A5\u6536\u7AEF\u53EF\u80FD\u4E0D\u652F\u6301 markdown \u6E32\u67D3\u3002
45635
+ - \u53EF\u4F7F\u7528\u57FA\u7840 Markdown \u63D0\u5347\u56DE\u590D\u53EF\u8BFB\u6027\uFF0C\u4F8B\u5982\u52A0\u7C97\u3001\u5217\u8868\u3001\u94FE\u63A5\u548C\u4EE3\u7801\u5757\uFF1B\u907F\u514D\u590D\u6742\u8868\u683C\u7B49\u98DE\u4E66\u53EF\u80FD\u4E0D\u5B8C\u6574\u652F\u6301\u7684\u683C\u5F0F\u3002
45507
45636
  - \u56DE\u590D\u5185\u5BB9\u5E94\u7B80\u6D01\u3001\u6709\u4FE1\u606F\u91CF\uFF0C\u76F4\u63A5\u5448\u73B0\u7528\u6237\u5173\u5FC3\u7684\u7ED3\u679C\u3002
45508
45637
  - \u5982\u679C\u4EFB\u52A1\u6267\u884C\u8FC7\u7A0B\u4E2D\u9047\u5230\u9519\u8BEF\uFF0C\u4E5F\u8981\u901A\u8FC7 send_message \u544A\u77E5\u7528\u6237\u6267\u884C\u5931\u8D25\u53CA\u539F\u56E0\u3002
45509
45638
  - \u4F18\u5148\u4F7F\u7528\u4E13\u7528\u5DE5\u5177\u800C\u975E\u901A\u7528\u65B9\u6CD5\uFF1A\u7528 web_search \u641C\u7D22\u4FE1\u606F\uFF0C\u7528 read \u8BFB\u53D6\u6587\u4EF6\uFF0C\u4E0D\u8981\u731C\u6D4B\u6216\u7F16\u9020\u6570\u636E\u3002
@@ -50638,6 +50767,13 @@ var dateKeyInShanghai = (timestamp) => new Date(timestamp).toLocaleString("sv-SE
50638
50767
  month: "2-digit",
50639
50768
  day: "2-digit"
50640
50769
  }).replace(/-/g, "");
50770
+ var recentDateKeysInShanghaiForTest = (now, days = 7) => {
50771
+ const keys = [];
50772
+ for (let i = days - 1; i >= 0; i--) {
50773
+ keys.push(dateKeyInShanghai(now - i * 864e5));
50774
+ }
50775
+ return keys;
50776
+ };
50641
50777
  var messageToAgentLogEntry = (message, index) => ({
50642
50778
  index,
50643
50779
  role: message.role,
@@ -50666,8 +50802,7 @@ var collectConversationMessages = async (userId, limit = 300) => {
50666
50802
  const storage = createRuntimeStorage(storageConf);
50667
50803
  const now = Date.now();
50668
50804
  const byDate = [];
50669
- for (let i = 0; i < 7; i++) {
50670
- const dateStr = dateKeyInShanghai(now - i * 864e5);
50805
+ for (const dateStr of recentDateKeysInShanghaiForTest(now, 7)) {
50671
50806
  const messages = await getMessages(storage, userId, limit, dateStr);
50672
50807
  if (messages.length > 0) {
50673
50808
  byDate.push(...messages.map((message) => ({ message, sourceKey: dateStr })));
@@ -50960,7 +51095,7 @@ var systemRoutes = new Hono2();
50960
51095
  var startTime = Date.now();
50961
51096
  systemRoutes.get("/system/info", (c) => {
50962
51097
  return c.json({
50963
- version: true ? "1.8.13" : "unknown",
51098
+ version: true ? "1.8.15" : "unknown",
50964
51099
  uptime: Math.floor((Date.now() - startTime) / 1e3),
50965
51100
  env: process.env.NODE_ENV || "development",
50966
51101
  nodeVersion: process.version