duclaw-cli 2.0.0 → 3.0.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.
Files changed (41) hide show
  1. package/dist/agent/coreHooks.d.ts +38 -0
  2. package/dist/agent/coreHooks.d.ts.map +1 -0
  3. package/dist/agent/createAgentCore.d.ts.map +1 -1
  4. package/dist/agent/duclawAgentConfig.d.ts.map +1 -1
  5. package/dist/agent/duclawCoreHooks.d.ts +5 -0
  6. package/dist/agent/duclawCoreHooks.d.ts.map +1 -0
  7. package/dist/agent/types.d.ts +2 -0
  8. package/dist/agent/types.d.ts.map +1 -1
  9. package/dist/bundle.js +1246 -1190
  10. package/dist/files/fileType.d.ts +2 -0
  11. package/dist/files/fileType.d.ts.map +1 -0
  12. package/dist/main.js +1 -1
  13. package/dist/sdk/core.d.ts +40 -0
  14. package/dist/sdk/core.d.ts.map +1 -0
  15. package/dist/sdk/core.js +40900 -0
  16. package/dist/sdk/createSdkAgent.d.ts +5 -0
  17. package/dist/sdk/createSdkAgent.d.ts.map +1 -0
  18. package/dist/sdk/duclaw.d.ts +15 -0
  19. package/dist/sdk/duclaw.d.ts.map +1 -1
  20. package/dist/sdk/duclaw.js +899 -488
  21. package/dist/sdk/duclawPreset.d.ts +21 -0
  22. package/dist/sdk/duclawPreset.d.ts.map +1 -0
  23. package/dist/sdk/index.d.ts +7 -24
  24. package/dist/sdk/index.d.ts.map +1 -1
  25. package/dist/sdk/index.js +6411 -40161
  26. package/dist/sdk/models/anthropic.d.ts +2 -0
  27. package/dist/sdk/models/anthropic.d.ts.map +1 -0
  28. package/dist/sdk/publicTypes.d.ts +33 -0
  29. package/dist/sdk/publicTypes.d.ts.map +1 -0
  30. package/dist/sdk/storage/memoryStorage.d.ts +3 -0
  31. package/dist/sdk/storage/memoryStorage.d.ts.map +1 -0
  32. package/dist/sdk/tool.d.ts +12 -0
  33. package/dist/sdk/tool.d.ts.map +1 -0
  34. package/dist/tools/Tool.d.ts +13 -7
  35. package/dist/tools/Tool.d.ts.map +1 -1
  36. package/dist/tools/tools/SendFile.d.ts +1 -1
  37. package/dist/tools/tools/SendFile.d.ts.map +1 -1
  38. package/dist/types/context.d.ts +1 -1
  39. package/dist/types/context.d.ts.map +1 -1
  40. package/dist/worker-main.js +1 -1
  41. package/package.json +11 -2
package/dist/bundle.js CHANGED
@@ -30129,39 +30129,39 @@ var require_timezone = __commonJS({
30129
30129
  }
30130
30130
  });
30131
30131
 
30132
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/max.js
30132
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/max.js
30133
30133
  var init_max = __esm({
30134
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/max.js"() {
30134
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/max.js"() {
30135
30135
  }
30136
30136
  });
30137
30137
 
30138
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/nil.js
30138
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/nil.js
30139
30139
  var init_nil = __esm({
30140
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/nil.js"() {
30140
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/nil.js"() {
30141
30141
  }
30142
30142
  });
30143
30143
 
30144
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/regex.js
30144
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/regex.js
30145
30145
  var regex_default;
30146
30146
  var init_regex = __esm({
30147
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/regex.js"() {
30147
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/regex.js"() {
30148
30148
  regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
30149
30149
  }
30150
30150
  });
30151
30151
 
30152
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/validate.js
30152
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/validate.js
30153
30153
  function validate(uuid) {
30154
30154
  return typeof uuid === "string" && regex_default.test(uuid);
30155
30155
  }
30156
30156
  var validate_default;
30157
30157
  var init_validate = __esm({
30158
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/validate.js"() {
30158
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/validate.js"() {
30159
30159
  init_regex();
30160
30160
  validate_default = validate;
30161
30161
  }
30162
30162
  });
30163
30163
 
30164
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/parse.js
30164
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/parse.js
30165
30165
  function parse(uuid) {
30166
30166
  if (!validate_default(uuid)) {
30167
30167
  throw TypeError("Invalid UUID");
@@ -30193,19 +30193,19 @@ function parse(uuid) {
30193
30193
  }
30194
30194
  var parse_default;
30195
30195
  var init_parse = __esm({
30196
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/parse.js"() {
30196
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/parse.js"() {
30197
30197
  init_validate();
30198
30198
  parse_default = parse;
30199
30199
  }
30200
30200
  });
30201
30201
 
30202
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/stringify.js
30202
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/stringify.js
30203
30203
  function unsafeStringify(arr2, offset = 0) {
30204
30204
  return (byteToHex[arr2[offset + 0]] + byteToHex[arr2[offset + 1]] + byteToHex[arr2[offset + 2]] + byteToHex[arr2[offset + 3]] + "-" + byteToHex[arr2[offset + 4]] + byteToHex[arr2[offset + 5]] + "-" + byteToHex[arr2[offset + 6]] + byteToHex[arr2[offset + 7]] + "-" + byteToHex[arr2[offset + 8]] + byteToHex[arr2[offset + 9]] + "-" + byteToHex[arr2[offset + 10]] + byteToHex[arr2[offset + 11]] + byteToHex[arr2[offset + 12]] + byteToHex[arr2[offset + 13]] + byteToHex[arr2[offset + 14]] + byteToHex[arr2[offset + 15]]).toLowerCase();
30205
30205
  }
30206
30206
  var byteToHex;
30207
30207
  var init_stringify = __esm({
30208
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/stringify.js"() {
30208
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/stringify.js"() {
30209
30209
  init_validate();
30210
30210
  byteToHex = [];
30211
30211
  for (let i = 0; i < 256; ++i) {
@@ -30214,18 +30214,18 @@ var init_stringify = __esm({
30214
30214
  }
30215
30215
  });
30216
30216
 
30217
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/rng.js
30217
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/rng.js
30218
30218
  function rng() {
30219
30219
  return crypto.getRandomValues(rnds8);
30220
30220
  }
30221
30221
  var rnds8;
30222
30222
  var init_rng = __esm({
30223
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/rng.js"() {
30223
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/rng.js"() {
30224
30224
  rnds8 = new Uint8Array(16);
30225
30225
  }
30226
30226
  });
30227
30227
 
30228
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/v4.js
30228
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/v4.js
30229
30229
  function v4(options, buf, offset) {
30230
30230
  if (!buf && !options && crypto.randomUUID) {
30231
30231
  return crypto.randomUUID();
@@ -30254,14 +30254,14 @@ function _v4(options, buf, offset) {
30254
30254
  }
30255
30255
  var v4_default;
30256
30256
  var init_v4 = __esm({
30257
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/v4.js"() {
30257
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/v4.js"() {
30258
30258
  init_rng();
30259
30259
  init_stringify();
30260
30260
  v4_default = v4;
30261
30261
  }
30262
30262
  });
30263
30263
 
30264
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/sha1.js
30264
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/sha1.js
30265
30265
  function f(s, x, y, z) {
30266
30266
  switch (s) {
30267
30267
  case 0:
@@ -30329,12 +30329,12 @@ function sha1(bytes) {
30329
30329
  }
30330
30330
  var sha1_default;
30331
30331
  var init_sha1 = __esm({
30332
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/sha1.js"() {
30332
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/sha1.js"() {
30333
30333
  sha1_default = sha1;
30334
30334
  }
30335
30335
  });
30336
30336
 
30337
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/v35.js
30337
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/v35.js
30338
30338
  function stringToBytes(str) {
30339
30339
  str = unescape(encodeURIComponent(str));
30340
30340
  const bytes = new Uint8Array(str.length);
@@ -30372,7 +30372,7 @@ function v35(version, hash, value, namespace, buf, offset) {
30372
30372
  }
30373
30373
  var DNS, URL2;
30374
30374
  var init_v35 = __esm({
30375
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/v35.js"() {
30375
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/v35.js"() {
30376
30376
  init_parse();
30377
30377
  init_stringify();
30378
30378
  DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
@@ -30380,13 +30380,13 @@ var init_v35 = __esm({
30380
30380
  }
30381
30381
  });
30382
30382
 
30383
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/v5.js
30383
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/v5.js
30384
30384
  function v5(value, namespace, buf, offset) {
30385
30385
  return v35(80, sha1_default, value, namespace, buf, offset);
30386
30386
  }
30387
30387
  var v5_default;
30388
30388
  var init_v5 = __esm({
30389
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/v5.js"() {
30389
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/v5.js"() {
30390
30390
  init_sha1();
30391
30391
  init_v35();
30392
30392
  init_v35();
@@ -30396,7 +30396,7 @@ var init_v5 = __esm({
30396
30396
  }
30397
30397
  });
30398
30398
 
30399
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/v7.js
30399
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/v7.js
30400
30400
  function v7(options, buf, offset) {
30401
30401
  let bytes;
30402
30402
  if (options) {
@@ -30457,7 +30457,7 @@ function v7Bytes(rnds, msecs, seq, buf, offset = 0) {
30457
30457
  }
30458
30458
  var _state, v7_default;
30459
30459
  var init_v7 = __esm({
30460
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/v7.js"() {
30460
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/v7.js"() {
30461
30461
  init_rng();
30462
30462
  init_stringify();
30463
30463
  _state = {};
@@ -30465,16 +30465,16 @@ var init_v7 = __esm({
30465
30465
  }
30466
30466
  });
30467
30467
 
30468
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/version.js
30468
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/version.js
30469
30469
  var init_version = __esm({
30470
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/version.js"() {
30470
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/version.js"() {
30471
30471
  init_validate();
30472
30472
  }
30473
30473
  });
30474
30474
 
30475
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/index.js
30475
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/index.js
30476
30476
  var init_src = __esm({
30477
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/uuid/src/index.js"() {
30477
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/uuid/src/index.js"() {
30478
30478
  init_max();
30479
30479
  init_nil();
30480
30480
  init_parse();
@@ -30487,10 +30487,10 @@ var init_src = __esm({
30487
30487
  }
30488
30488
  });
30489
30489
 
30490
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/experimental/otel/constants.js
30490
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/experimental/otel/constants.js
30491
30491
  var GEN_AI_OPERATION_NAME, GEN_AI_SYSTEM, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, GEN_AI_USAGE_TOTAL_TOKENS, GEN_AI_REQUEST_MAX_TOKENS, GEN_AI_REQUEST_TEMPERATURE, GEN_AI_REQUEST_TOP_P, GEN_AI_REQUEST_FREQUENCY_PENALTY, GEN_AI_REQUEST_PRESENCE_PENALTY, GEN_AI_RESPONSE_FINISH_REASONS, GENAI_PROMPT, GENAI_COMPLETION, GEN_AI_REQUEST_EXTRA_QUERY, GEN_AI_REQUEST_EXTRA_BODY, GEN_AI_SERIALIZED_NAME, GEN_AI_SERIALIZED_SIGNATURE, GEN_AI_SERIALIZED_DOC, GEN_AI_RESPONSE_ID, GEN_AI_RESPONSE_SERVICE_TIER, GEN_AI_RESPONSE_SYSTEM_FINGERPRINT, GEN_AI_USAGE_INPUT_TOKEN_DETAILS, GEN_AI_USAGE_OUTPUT_TOKEN_DETAILS, LANGSMITH_SESSION_ID, LANGSMITH_SESSION_NAME, LANGSMITH_RUN_TYPE, LANGSMITH_NAME, LANGSMITH_METADATA, LANGSMITH_TAGS, LANGSMITH_REQUEST_STREAMING, LANGSMITH_REQUEST_HEADERS, LANGSMITH_USAGE_METADATA;
30492
30492
  var init_constants = __esm({
30493
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/experimental/otel/constants.js"() {
30493
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/experimental/otel/constants.js"() {
30494
30494
  GEN_AI_OPERATION_NAME = "gen_ai.operation.name";
30495
30495
  GEN_AI_SYSTEM = "gen_ai.system";
30496
30496
  GEN_AI_REQUEST_MODEL = "gen_ai.request.model";
@@ -30528,7 +30528,7 @@ var init_constants = __esm({
30528
30528
  }
30529
30529
  });
30530
30530
 
30531
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/env.js
30531
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/env.js
30532
30532
  function getRuntimeEnvironment() {
30533
30533
  if (runtimeEnvironment === void 0) {
30534
30534
  const env = getEnv();
@@ -30661,7 +30661,7 @@ function resolveTracingMode(configValue) {
30661
30661
  }
30662
30662
  var globalEnv, isBrowser, isWebWorker, isJsDom, isDeno, isNode, getEnv, runtimeEnvironment, cachedCommitSHAs, _VALID_TRACING_MODES;
30663
30663
  var init_env = __esm({
30664
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/env.js"() {
30664
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/env.js"() {
30665
30665
  init_dist();
30666
30666
  isBrowser = () => typeof window !== "undefined" && typeof window.document !== "undefined";
30667
30667
  isWebWorker = () => typeof globalThis === "object" && globalThis.constructor && globalThis.constructor.name === "DedicatedWorkerGlobalScope";
@@ -30693,7 +30693,7 @@ var init_env = __esm({
30693
30693
  }
30694
30694
  });
30695
30695
 
30696
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/singletons/otel.js
30696
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/singletons/otel.js
30697
30697
  function getOTELTrace() {
30698
30698
  return OTELProviderSingleton.getTraceInstance();
30699
30699
  }
@@ -30705,7 +30705,7 @@ function getDefaultOTLPTracerComponents() {
30705
30705
  }
30706
30706
  var MockTracer, MockOTELTrace, MockOTELContext, OTEL_TRACE_KEY, OTEL_CONTEXT_KEY, OTEL_GET_DEFAULT_OTLP_TRACER_PROVIDER_KEY, mockOTELTrace, mockOTELContext, OTELProvider, OTELProviderSingleton;
30707
30707
  var init_otel = __esm({
30708
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/singletons/otel.js"() {
30708
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/singletons/otel.js"() {
30709
30709
  init_env();
30710
30710
  MockTracer = class {
30711
30711
  constructor() {
@@ -30805,7 +30805,7 @@ var init_otel = __esm({
30805
30805
  }
30806
30806
  });
30807
30807
 
30808
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/experimental/otel/translator.js
30808
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/experimental/otel/translator.js
30809
30809
  function getOperationName(runType) {
30810
30810
  return WELL_KNOWN_OPERATION_NAMES[runType] || runType;
30811
30811
  }
@@ -30814,7 +30814,7 @@ function isPrimitive(value) {
30814
30814
  }
30815
30815
  var WELL_KNOWN_OPERATION_NAMES, LangSmithToOTELTranslator;
30816
30816
  var init_translator = __esm({
30817
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/experimental/otel/translator.js"() {
30817
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/experimental/otel/translator.js"() {
30818
30818
  init_constants();
30819
30819
  init_otel();
30820
30820
  WELL_KNOWN_OPERATION_NAMES = {
@@ -31160,7 +31160,7 @@ var init_translator = __esm({
31160
31160
  }
31161
31161
  });
31162
31162
 
31163
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/is-network-error/index.js
31163
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/is-network-error/index.js
31164
31164
  function isNetworkError(error) {
31165
31165
  const isValid = error && isError(error) && error.name === "TypeError" && typeof error.message === "string";
31166
31166
  if (!isValid) {
@@ -31178,7 +31178,7 @@ function isNetworkError(error) {
31178
31178
  }
31179
31179
  var objectToString, isError, errorMessages;
31180
31180
  var init_is_network_error = __esm({
31181
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/is-network-error/index.js"() {
31181
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/is-network-error/index.js"() {
31182
31182
  objectToString = Object.prototype.toString;
31183
31183
  isError = (value) => objectToString.call(value) === "[object Error]";
31184
31184
  errorMessages = /* @__PURE__ */ new Set([
@@ -31204,7 +31204,7 @@ var init_is_network_error = __esm({
31204
31204
  }
31205
31205
  });
31206
31206
 
31207
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/p-retry/index.js
31207
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/p-retry/index.js
31208
31208
  function validateRetries(retries) {
31209
31209
  if (typeof retries === "number") {
31210
31210
  if (retries < 0) {
@@ -31364,7 +31364,7 @@ async function pRetry(input, options = {}) {
31364
31364
  }
31365
31365
  var AbortError;
31366
31366
  var init_p_retry = __esm({
31367
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/p-retry/index.js"() {
31367
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/p-retry/index.js"() {
31368
31368
  init_is_network_error();
31369
31369
  AbortError = class extends Error {
31370
31370
  constructor(message) {
@@ -31948,19 +31948,19 @@ var require_dist3 = __commonJS({
31948
31948
  }
31949
31949
  });
31950
31950
 
31951
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/p-queue.js
31951
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/p-queue.js
31952
31952
  var import_p_queue, PQueue;
31953
31953
  var init_p_queue = __esm({
31954
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/p-queue.js"() {
31954
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/p-queue.js"() {
31955
31955
  import_p_queue = __toESM(require_dist3(), 1);
31956
31956
  PQueue = "default" in import_p_queue.default ? import_p_queue.default.default : import_p_queue.default;
31957
31957
  }
31958
31958
  });
31959
31959
 
31960
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/async_caller.js
31960
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/async_caller.js
31961
31961
  var STATUS_RETRYABLE, AsyncCaller;
31962
31962
  var init_async_caller = __esm({
31963
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/async_caller.js"() {
31963
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/async_caller.js"() {
31964
31964
  init_p_retry();
31965
31965
  init_p_queue();
31966
31966
  STATUS_RETRYABLE = [
@@ -32092,7 +32092,7 @@ var init_async_caller = __esm({
32092
32092
  }
32093
32093
  });
32094
32094
 
32095
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/messages.js
32095
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/messages.js
32096
32096
  function isLangChainMessage(message) {
32097
32097
  return typeof message?._getType === "function";
32098
32098
  }
@@ -32107,11 +32107,11 @@ function convertLangChainMessageToExample(message) {
32107
32107
  return converted;
32108
32108
  }
32109
32109
  var init_messages = __esm({
32110
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/messages.js"() {
32110
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/messages.js"() {
32111
32111
  }
32112
32112
  });
32113
32113
 
32114
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/warn.js
32114
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/warn.js
32115
32115
  function warnOnce(message) {
32116
32116
  if (!warnedMessages[message]) {
32117
32117
  console.warn(message);
@@ -32120,12 +32120,12 @@ function warnOnce(message) {
32120
32120
  }
32121
32121
  var warnedMessages;
32122
32122
  var init_warn = __esm({
32123
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/warn.js"() {
32123
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/warn.js"() {
32124
32124
  warnedMessages = {};
32125
32125
  }
32126
32126
  });
32127
32127
 
32128
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/xxhash/xxhash.js
32128
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/xxhash/xxhash.js
32129
32129
  function hexToBytes(hex) {
32130
32130
  const bytes = new Uint8Array(hex.length / 2);
32131
32131
  for (let i = 0; i < hex.length; i += 2) {
@@ -32374,7 +32374,7 @@ function xxh128ToBytes(hash128) {
32374
32374
  }
32375
32375
  var n, PRIME32_1, PRIME32_2, PRIME32_3, PRIME64_1, PRIME64_2, PRIME64_3, PRIME64_4, PRIME64_5, PRIME_MX1, PRIME_MX2, kkey, mask128, mask64, mask32, STRIPE_LEN, ACC_NB, _U64, _U32, bswap64, bswap32, XXH_mult32to64, assert;
32376
32376
  var init_xxhash = __esm({
32377
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/xxhash/xxhash.js"() {
32377
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/xxhash/xxhash.js"() {
32378
32378
  n = (n2) => BigInt(n2);
32379
32379
  PRIME32_1 = n("0x9E3779B1");
32380
32380
  PRIME32_2 = n("0x85EBCA77");
@@ -32410,7 +32410,7 @@ var init_xxhash = __esm({
32410
32410
  }
32411
32411
  });
32412
32412
 
32413
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/_uuid.js
32413
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/_uuid.js
32414
32414
  function assertUuid(str, which) {
32415
32415
  if (!UUID_REGEX.test(str)) {
32416
32416
  const msg = which !== void 0 ? `Invalid UUID for ${which}: ${str}` : `Invalid UUID: ${str}`;
@@ -32471,7 +32471,7 @@ function nonCryptographicUuid7Deterministic(originalId, key) {
32471
32471
  }
32472
32472
  var UUID_REGEX, _textEncoder;
32473
32473
  var init_uuid = __esm({
32474
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/_uuid.js"() {
32474
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/_uuid.js"() {
32475
32475
  init_src();
32476
32476
  init_warn();
32477
32477
  init_xxhash();
@@ -32480,7 +32480,7 @@ var init_uuid = __esm({
32480
32480
  }
32481
32481
  });
32482
32482
 
32483
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/error.js
32483
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/error.js
32484
32484
  function getInvalidPromptIdentifierMsg(identifier) {
32485
32485
  return `Invalid prompt identifier format: "${identifier}". Expected one of:
32486
32486
  - "prompt-name" (for private prompts)
@@ -32538,7 +32538,7 @@ function isConflictingEndpointsError(err) {
32538
32538
  }
32539
32539
  var LangSmithConflictError, LangSmithNotFoundError, ERR_CONFLICTING_ENDPOINTS, ConflictingEndpointsError;
32540
32540
  var init_error = __esm({
32541
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/error.js"() {
32541
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/error.js"() {
32542
32542
  LangSmithConflictError = class extends Error {
32543
32543
  constructor(message) {
32544
32544
  super(message);
@@ -32581,7 +32581,7 @@ var init_error = __esm({
32581
32581
  }
32582
32582
  });
32583
32583
 
32584
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/prompts.js
32584
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/prompts.js
32585
32585
  function parseHubIdentifier(identifier) {
32586
32586
  if (!identifier || identifier.split("/").length > 2 || identifier.startsWith("/") || identifier.endsWith("/") || identifier.split(":").length > 2) {
32587
32587
  throw new Error(getInvalidPromptIdentifierMsg(identifier));
@@ -32602,12 +32602,12 @@ function parseHubIdentifier(identifier) {
32602
32602
  }
32603
32603
  }
32604
32604
  var init_prompts = __esm({
32605
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/prompts.js"() {
32605
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/prompts.js"() {
32606
32606
  init_error();
32607
32607
  }
32608
32608
  });
32609
32609
 
32610
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/fs.js
32610
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/fs.js
32611
32611
  async function mkdir7(dir) {
32612
32612
  await nodeFsPromises.mkdir(dir, { recursive: true });
32613
32613
  }
@@ -32658,7 +32658,7 @@ async function rmRecursive(filePath) {
32658
32658
  }
32659
32659
  var nodeFs, nodeFsPromises, nodePath, path17;
32660
32660
  var init_fs = __esm({
32661
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/fs.js"() {
32661
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/fs.js"() {
32662
32662
  nodeFs = __toESM(require("node:fs"), 1);
32663
32663
  nodeFsPromises = __toESM(require("node:fs/promises"), 1);
32664
32664
  nodePath = __toESM(require("node:path"), 1);
@@ -32666,7 +32666,7 @@ var init_fs = __esm({
32666
32666
  }
32667
32667
  });
32668
32668
 
32669
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/prompt_cache/index.js
32669
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/prompt_cache/index.js
32670
32670
  function isStale(entry, ttlSeconds) {
32671
32671
  if (ttlSeconds === null) {
32672
32672
  return false;
@@ -32679,7 +32679,7 @@ function configureGlobalPromptCache(config2) {
32679
32679
  }
32680
32680
  var PromptCache, promptCacheSingleton, Cache;
32681
32681
  var init_prompt_cache = __esm({
32682
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/prompt_cache/index.js"() {
32682
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/prompt_cache/index.js"() {
32683
32683
  init_fs();
32684
32684
  PromptCache = class {
32685
32685
  constructor(config2 = {}) {
@@ -32955,10 +32955,10 @@ var init_prompt_cache = __esm({
32955
32955
  }
32956
32956
  });
32957
32957
 
32958
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/singletons/fetch.js
32958
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/singletons/fetch.js
32959
32959
  var DEFAULT_FETCH_IMPLEMENTATION, globalFetchSupportsWebStreaming, LANGSMITH_FETCH_IMPLEMENTATION_KEY, overrideFetchImplementation, _shouldStreamForGlobalFetchImplementation, _getFetchImplementation;
32960
32960
  var init_fetch = __esm({
32961
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/singletons/fetch.js"() {
32961
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/singletons/fetch.js"() {
32962
32962
  init_env();
32963
32963
  DEFAULT_FETCH_IMPLEMENTATION = (...args) => fetch(...args);
32964
32964
  globalFetchSupportsWebStreaming = void 0;
@@ -32990,7 +32990,7 @@ var init_fetch = __esm({
32990
32990
  }
32991
32991
  });
32992
32992
 
32993
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/profile-lock.js
32993
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/profile-lock.js
32994
32994
  function sleep3(ms) {
32995
32995
  return new Promise((resolve10) => setTimeout(resolve10, ms));
32996
32996
  }
@@ -33071,7 +33071,7 @@ ${owner}
33071
33071
  }
33072
33072
  var LOCK_POLL_INTERVAL_MS, LOCK_STALE_AFTER_MS, LOCK_METADATA_FILE;
33073
33073
  var init_profile_lock = __esm({
33074
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/profile-lock.js"() {
33074
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/profile-lock.js"() {
33075
33075
  init_fs();
33076
33076
  LOCK_POLL_INTERVAL_MS = 10;
33077
33077
  LOCK_STALE_AFTER_MS = 1e4;
@@ -33079,7 +33079,7 @@ var init_profile_lock = __esm({
33079
33079
  }
33080
33080
  });
33081
33081
 
33082
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/profiles.js
33082
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/profiles.js
33083
33083
  function isBrowserLikeRuntime() {
33084
33084
  const env = getEnv();
33085
33085
  return env === "browser" || env === "webworker";
@@ -33238,7 +33238,7 @@ function authHeaderFromProfile(profile) {
33238
33238
  }
33239
33239
  var DEFAULT_API_URL, OAUTH_CLIENT_ID, TOKEN_REFRESH_LEEWAY_MS, TOKEN_REFRESH_TIMEOUT_MS, ProfileAuth;
33240
33240
  var init_profiles = __esm({
33241
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/profiles.js"() {
33241
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/profiles.js"() {
33242
33242
  init_env();
33243
33243
  init_fs();
33244
33244
  init_profile_lock();
@@ -33355,7 +33355,7 @@ var init_profiles = __esm({
33355
33355
  }
33356
33356
  });
33357
33357
 
33358
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/fast-safe-stringify/index.js
33358
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/fast-safe-stringify/index.js
33359
33359
  function defaultOptions2() {
33360
33360
  return {
33361
33361
  depthLimit: Number.MAX_SAFE_INTEGER,
@@ -33641,7 +33641,7 @@ function replaceGetterValues(replacer) {
33641
33641
  }
33642
33642
  var LIMIT_REPLACE_NODE, CIRCULAR_REPLACE_NODE, arr, replacerStack, encoder;
33643
33643
  var init_fast_safe_stringify = __esm({
33644
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/fast-safe-stringify/index.js"() {
33644
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/fast-safe-stringify/index.js"() {
33645
33645
  init_env();
33646
33646
  LIMIT_REPLACE_NODE = "[...]";
33647
33647
  CIRCULAR_REPLACE_NODE = { result: "[Circular]" };
@@ -33651,17 +33651,17 @@ var init_fast_safe_stringify = __esm({
33651
33651
  }
33652
33652
  });
33653
33653
 
33654
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/worker_threads.js
33654
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/worker_threads.js
33655
33655
  var import_node_worker_threads, Worker, WORKER_THREADS_AVAILABLE;
33656
33656
  var init_worker_threads = __esm({
33657
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/worker_threads.js"() {
33657
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/worker_threads.js"() {
33658
33658
  import_node_worker_threads = require("node:worker_threads");
33659
33659
  Worker = import_node_worker_threads.Worker;
33660
33660
  WORKER_THREADS_AVAILABLE = true;
33661
33661
  }
33662
33662
  });
33663
33663
 
33664
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/serialize_worker.js
33664
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/serialize_worker.js
33665
33665
  function getSharedSerializeWorker() {
33666
33666
  if (sharedWorker === null)
33667
33667
  sharedWorker = new SerializeWorker();
@@ -33719,7 +33719,7 @@ function hasLargeString(value, threshold = LARGE_STRING_THRESHOLD, nodeBudget =
33719
33719
  }
33720
33720
  var WORKER_SOURCE, SerializeWorker, sharedWorker, LARGE_STRING_THRESHOLD, NODE_BUDGET;
33721
33721
  var init_serialize_worker = __esm({
33722
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/serialize_worker.js"() {
33722
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/serialize_worker.js"() {
33723
33723
  init_worker_threads();
33724
33724
  WORKER_SOURCE = /* js */
33725
33725
  `
@@ -33950,7 +33950,7 @@ parentPort.on("message", (msg) => {
33950
33950
  }
33951
33951
  });
33952
33952
 
33953
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/client.js
33953
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/client.js
33954
33954
  function assertPullPublicPromptAllowed(promptIdentifier, dangerouslyPullPublicPrompt) {
33955
33955
  const [owner] = parseHubIdentifier(promptIdentifier);
33956
33956
  if (owner !== "-" && !dangerouslyPullPublicPrompt) {
@@ -34018,7 +34018,7 @@ function isExampleCreate(input) {
34018
34018
  }
34019
34019
  var getTracingSamplingRate, isLocalhost, handle429, DEFAULT_UNCOMPRESSED_BATCH_SIZE_LIMIT_BYTES, DEFAULT_MAX_SIZE_BYTES, SERVER_INFO_REQUEST_TIMEOUT_MS, DEFAULT_BATCH_SIZE_LIMIT, AutoBatchQueue, Client2;
34020
34020
  var init_client = __esm({
34021
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/client.js"() {
34021
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/client.js"() {
34022
34022
  init_src();
34023
34023
  init_translator();
34024
34024
  init_otel();
@@ -38812,10 +38812,10 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
38812
38812
  }
38813
38813
  });
38814
38814
 
38815
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/env.js
38815
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/env.js
38816
38816
  var isTracingEnabled;
38817
38817
  var init_env2 = __esm({
38818
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/env.js"() {
38818
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/env.js"() {
38819
38819
  init_env();
38820
38820
  isTracingEnabled = (tracingEnabled) => {
38821
38821
  if (tracingEnabled !== void 0) {
@@ -38827,16 +38827,16 @@ var init_env2 = __esm({
38827
38827
  }
38828
38828
  });
38829
38829
 
38830
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/singletons/constants.js
38830
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/singletons/constants.js
38831
38831
  var _LC_CONTEXT_VARIABLES_KEY, _REPLICA_TRACE_ROOTS_KEY;
38832
38832
  var init_constants2 = __esm({
38833
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/singletons/constants.js"() {
38833
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/singletons/constants.js"() {
38834
38834
  _LC_CONTEXT_VARIABLES_KEY = /* @__PURE__ */ Symbol.for("lc:context_variables");
38835
38835
  _REPLICA_TRACE_ROOTS_KEY = /* @__PURE__ */ Symbol.for("langsmith:replica_trace_roots");
38836
38836
  }
38837
38837
  });
38838
38838
 
38839
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/context_vars.js
38839
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/context_vars.js
38840
38840
  function getContextVar(runTree, key) {
38841
38841
  if (_LC_CONTEXT_VARIABLES_KEY in runTree) {
38842
38842
  const contextVars = runTree[_LC_CONTEXT_VARIABLES_KEY];
@@ -38853,15 +38853,15 @@ function setContextVar(runTree, key, value) {
38853
38853
  runTree[_LC_CONTEXT_VARIABLES_KEY] = contextVars;
38854
38854
  }
38855
38855
  var init_context_vars = __esm({
38856
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/context_vars.js"() {
38856
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/context_vars.js"() {
38857
38857
  init_constants2();
38858
38858
  }
38859
38859
  });
38860
38860
 
38861
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/project.js
38861
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/project.js
38862
38862
  var getDefaultProjectName;
38863
38863
  var init_project = __esm({
38864
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/utils/project.js"() {
38864
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/utils/project.js"() {
38865
38865
  init_env();
38866
38866
  getDefaultProjectName = () => {
38867
38867
  return getLangSmithEnvironmentVariable("PROJECT") ?? getEnvironmentVariable("LANGCHAIN_SESSION") ?? // TODO: Deprecate
@@ -38870,7 +38870,7 @@ var init_project = __esm({
38870
38870
  }
38871
38871
  });
38872
38872
 
38873
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/run_trees.js
38873
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/run_trees.js
38874
38874
  function getReplicaKey(replica) {
38875
38875
  const sortedKeys = Object.keys(replica).sort();
38876
38876
  const keyData = sortedKeys.map((key) => `${key}:${replica[key] ?? ""}`).join("|");
@@ -38994,7 +38994,7 @@ function _checkEndpointEnvUnset(parsed) {
38994
38994
  }
38995
38995
  var TIMESTAMP_LENGTH, UUID_NAMESPACE_DNS, HEADER_SAFE_REPLICA_FIELDS, Baggage, RunTree;
38996
38996
  var init_run_trees = __esm({
38997
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/run_trees.js"() {
38997
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/run_trees.js"() {
38998
38998
  init_client();
38999
38999
  init_env2();
39000
39000
  init_error();
@@ -39789,21 +39789,21 @@ var init_run_trees = __esm({
39789
39789
  }
39790
39790
  });
39791
39791
 
39792
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/uuid.js
39792
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/uuid.js
39793
39793
  function uuid7() {
39794
39794
  return v7_default();
39795
39795
  }
39796
39796
  var init_uuid2 = __esm({
39797
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/uuid.js"() {
39797
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/uuid.js"() {
39798
39798
  init_src();
39799
39799
  init_uuid();
39800
39800
  }
39801
39801
  });
39802
39802
 
39803
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/index.js
39803
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/index.js
39804
39804
  var __version__, LS_MESSAGE_VIEW_EXCLUDE;
39805
39805
  var init_dist = __esm({
39806
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/dist/index.js"() {
39806
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/dist/index.js"() {
39807
39807
  init_client();
39808
39808
  init_run_trees();
39809
39809
  init_fetch();
@@ -39815,7 +39815,7 @@ var init_dist = __esm({
39815
39815
  }
39816
39816
  });
39817
39817
 
39818
- // node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/index.js
39818
+ // node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/index.js
39819
39819
  var langsmith_exports = {};
39820
39820
  __export(langsmith_exports, {
39821
39821
  Cache: () => Cache,
@@ -39832,7 +39832,7 @@ __export(langsmith_exports, {
39832
39832
  uuid7FromTime: () => uuid7FromTime
39833
39833
  });
39834
39834
  var init_langsmith = __esm({
39835
- "node_modules/.pnpm/langsmith@0.7.7_ws@8.20.0/node_modules/langsmith/index.js"() {
39835
+ "node_modules/.pnpm/langsmith@0.7.7_ws@8.21.0/node_modules/langsmith/index.js"() {
39836
39836
  init_dist();
39837
39837
  }
39838
39838
  });
@@ -39957,7 +39957,7 @@ function printHelp() {
39957
39957
  `);
39958
39958
  }
39959
39959
  function printVersion() {
39960
- console.log(`duclaw-cli v${true ? "2.0.0" : "unknown"}`);
39960
+ console.log(`duclaw-cli v${true ? "3.0.0" : "unknown"}`);
39961
39961
  }
39962
39962
  function getDuclawTemplate() {
39963
39963
  return {
@@ -43085,7 +43085,7 @@ var chokidar_default = { watch, FSWatcher };
43085
43085
  var import_node_cron = __toESM(require_node_cron());
43086
43086
 
43087
43087
  // src/agent/createAgentCore.ts
43088
- var import_node_crypto6 = require("node:crypto");
43088
+ var import_node_crypto3 = require("node:crypto");
43089
43089
 
43090
43090
  // src/storage/utils.ts
43091
43091
  var buildMessageKey = (userId, date, cronTitle) => {
@@ -43432,15 +43432,7 @@ var isTextBlock = (block) => block.type === `text`;
43432
43432
  var isToolUseBlock = (block) => block.type === "tool_use";
43433
43433
  var extractText = (blocks) => blocks.filter(isTextBlock).map((b) => b.text).join("\n");
43434
43434
 
43435
- // src/tools/tools/SendFile.ts
43436
- var DESCRIPTION = `
43437
- \u53D1\u9001\u6587\u4EF6\u7ED9\u7528\u6237\u3002\u652F\u6301\u4E24\u79CD\u65B9\u5F0F\uFF1A
43438
- 1. \u672C\u5730\u6587\u4EF6\u8DEF\u5F84\uFF08filePath\uFF09\uFF1A\u9002\u7528\u4E8E\u4F60\u901A\u8FC7 Write \u5DE5\u5177\u751F\u6210\u7684\u6587\u4EF6
43439
- 2. \u8FDC\u7A0B URL\uFF08url\uFF09\uFF1A\u9002\u7528\u4E8E\u4ECE\u7F51\u7EDC\u83B7\u53D6\u7684\u6587\u4EF6
43440
-
43441
- \u4E24\u8005\u4E8C\u9009\u4E00\uFF0C\u4F18\u5148\u4F7F\u7528 filePath\u3002\u5982\u679C\u540C\u65F6\u63D0\u4F9B\uFF0C\u4F18\u5148\u4F7F\u7528 filePath\u3002
43442
- \u652F\u6301\u53D1\u9001\u4EFB\u610F\u7C7B\u578B\u7684\u6587\u4EF6\uFF08pdf\u3001doc\u3001xls\u3001ppt\u3001mp4\u3001opus\u3001\u56FE\u7247\u3001\u538B\u7F29\u5305\u7B49\uFF09\uFF0C\u7CFB\u7EDF\u4F1A\u6839\u636E\u6587\u4EF6\u540D\u540E\u7F00\u81EA\u52A8\u8BC6\u522B\u7C7B\u578B\u3002
43443
- `;
43435
+ // src/files/fileType.ts
43444
43436
  var EXT_TO_FILE_TYPE = {
43445
43437
  ".opus": "opus",
43446
43438
  ".mp4": "mp4",
@@ -43453,37 +43445,11 @@ var EXT_TO_FILE_TYPE = {
43453
43445
  ".pptx": "ppt"
43454
43446
  };
43455
43447
  var inferFileType = (fileName) => {
43456
- const ext = fileName.slice(fileName.lastIndexOf(".")).toLowerCase();
43448
+ const dotIndex = fileName.lastIndexOf(".");
43449
+ if (dotIndex < 0) return "stream";
43450
+ const ext = fileName.slice(dotIndex).toLowerCase();
43457
43451
  return EXT_TO_FILE_TYPE[ext] || "stream";
43458
43452
  };
43459
- var sendFile = {
43460
- name: `send_file`,
43461
- description: DESCRIPTION,
43462
- input_schema: {
43463
- type: `object`,
43464
- properties: {
43465
- filePath: {
43466
- type: `string`,
43467
- description: `\u672C\u5730\u6587\u4EF6\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u4F8B\u5982 /tmp/report.pdf`
43468
- },
43469
- url: {
43470
- type: `string`,
43471
- description: `\u8FDC\u7A0B\u6587\u4EF6\u7684 URL\uFF0C\u4F8B\u5982 https://example.com/report.pdf`
43472
- },
43473
- fileName: {
43474
- type: `string`,
43475
- description: `\u53D1\u9001\u7ED9\u7528\u6237\u65F6\u663E\u793A\u7684\u6587\u4EF6\u540D\uFF08\u5E26\u540E\u7F00\uFF09\uFF0C\u4F8B\u5982 report.pdf`
43476
- }
43477
- },
43478
- required: [`fileName`]
43479
- },
43480
- async execute(input, userRequest) {
43481
- if (!input.filePath && !input.url) {
43482
- return `\u9519\u8BEF\uFF1AfilePath \u548C url \u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A`;
43483
- }
43484
- return `\u6587\u4EF6\u5DF2\u53D1\u9001: ${input.fileName}`;
43485
- }
43486
- };
43487
43453
 
43488
43454
  // src/agent/interruptRegistry.ts
43489
43455
  var registry = /* @__PURE__ */ new Map();
@@ -44232,254 +44198,6 @@ ${managerMailboxInstruction}
44232
44198
  </system-reminder>`;
44233
44199
  };
44234
44200
 
44235
- // src/department/mailbox/ceoFollowup.ts
44236
- var import_node_crypto3 = require("node:crypto");
44237
- var rowToFollowup = (row) => ({
44238
- id: row.id,
44239
- sourceMessageId: row.sourceMessageId,
44240
- status: row.status,
44241
- originUserId: row.originUserId,
44242
- originPlatform: row.originPlatform,
44243
- fromMailboxId: row.fromMailboxId,
44244
- threadId: row.threadId ?? void 0,
44245
- parentMessageId: row.parentMessageId ?? void 0,
44246
- workItemId: row.workItemId ?? void 0,
44247
- content: row.content,
44248
- attempts: row.attempts,
44249
- lastError: row.lastError ?? void 0,
44250
- createdAt: row.createdAt,
44251
- updatedAt: row.updatedAt,
44252
- completedAt: row.completedAt ?? void 0
44253
- });
44254
- var selectById = (id) => {
44255
- const db3 = createSqliteDB();
44256
- const row = db3.prepare(`
44257
- SELECT
44258
- id,
44259
- source_message_id as sourceMessageId,
44260
- status,
44261
- origin_user_id as originUserId,
44262
- origin_platform as originPlatform,
44263
- from_mailbox_id as fromMailboxId,
44264
- thread_id as threadId,
44265
- parent_message_id as parentMessageId,
44266
- work_item_id as workItemId,
44267
- content,
44268
- attempts,
44269
- last_error as lastError,
44270
- created_at as createdAt,
44271
- updated_at as updatedAt,
44272
- completed_at as completedAt
44273
- FROM ceo_followups
44274
- WHERE id = ?
44275
- `).get(id);
44276
- return row ? rowToFollowup(row) : null;
44277
- };
44278
- var enqueueCeoFollowupFromMailbox = (message) => {
44279
- if (message.toMailboxId !== "manager") return null;
44280
- if (message.workItemRole === "followup") return null;
44281
- if (!message.originUserId || !message.originPlatform) return null;
44282
- const db3 = createSqliteDB();
44283
- const now = Date.now();
44284
- const id = `cfu_${(0, import_node_crypto3.randomUUID)().slice(0, 12)}`;
44285
- db3.prepare(`
44286
- INSERT INTO ceo_followups (
44287
- id,
44288
- source_message_id,
44289
- status,
44290
- origin_user_id,
44291
- origin_platform,
44292
- from_mailbox_id,
44293
- thread_id,
44294
- parent_message_id,
44295
- work_item_id,
44296
- content,
44297
- created_at,
44298
- updated_at
44299
- ) VALUES (?, ?, 'pending', ?, ?, ?, ?, ?, ?, ?, ?, ?)
44300
- ON CONFLICT(source_message_id) DO UPDATE SET
44301
- status = CASE
44302
- WHEN ceo_followups.status = 'completed' THEN ceo_followups.status
44303
- ELSE 'pending'
44304
- END,
44305
- origin_user_id = excluded.origin_user_id,
44306
- origin_platform = excluded.origin_platform,
44307
- from_mailbox_id = excluded.from_mailbox_id,
44308
- thread_id = excluded.thread_id,
44309
- parent_message_id = excluded.parent_message_id,
44310
- work_item_id = excluded.work_item_id,
44311
- content = excluded.content,
44312
- updated_at = excluded.updated_at
44313
- `).run(
44314
- id,
44315
- message.id,
44316
- message.originUserId,
44317
- message.originPlatform,
44318
- message.fromMailboxId,
44319
- message.threadId ?? message.id,
44320
- message.parentMessageId ?? null,
44321
- message.workItemId ?? null,
44322
- message.content,
44323
- now,
44324
- now
44325
- );
44326
- const row = db3.prepare(`
44327
- SELECT id FROM ceo_followups WHERE source_message_id = ?
44328
- `).get(message.id);
44329
- return row ? selectById(row.id) : null;
44330
- };
44331
- var listPendingCeoFollowups = (limit = 10) => {
44332
- const db3 = createSqliteDB();
44333
- const rows = db3.prepare(`
44334
- SELECT
44335
- id,
44336
- source_message_id as sourceMessageId,
44337
- status,
44338
- origin_user_id as originUserId,
44339
- origin_platform as originPlatform,
44340
- from_mailbox_id as fromMailboxId,
44341
- thread_id as threadId,
44342
- parent_message_id as parentMessageId,
44343
- work_item_id as workItemId,
44344
- content,
44345
- attempts,
44346
- last_error as lastError,
44347
- created_at as createdAt,
44348
- updated_at as updatedAt,
44349
- completed_at as completedAt
44350
- FROM ceo_followups
44351
- WHERE status IN ('pending', 'failed')
44352
- ORDER BY created_at ASC
44353
- LIMIT ?
44354
- `).all(limit);
44355
- return rows.map(rowToFollowup);
44356
- };
44357
- var claimCeoFollowup = (id) => {
44358
- const db3 = createSqliteDB();
44359
- const now = Date.now();
44360
- const result = db3.prepare(`
44361
- UPDATE ceo_followups
44362
- SET status = 'processing',
44363
- attempts = attempts + 1,
44364
- updated_at = ?
44365
- WHERE id = ?
44366
- AND status IN ('pending', 'failed')
44367
- `).run(now, id);
44368
- if (result.changes === 0) return null;
44369
- return selectById(id);
44370
- };
44371
- var completeCeoFollowup = (id) => {
44372
- const db3 = createSqliteDB();
44373
- const now = Date.now();
44374
- db3.prepare(`
44375
- UPDATE ceo_followups
44376
- SET status = 'completed',
44377
- completed_at = COALESCE(completed_at, ?),
44378
- updated_at = ?,
44379
- last_error = NULL
44380
- WHERE id = ?
44381
- AND status IN ('pending', 'processing', 'failed')
44382
- `).run(now, now, id);
44383
- db3.prepare(`
44384
- UPDATE mailbox
44385
- SET status = 'done',
44386
- updated_at = ?
44387
- WHERE id = (SELECT source_message_id FROM ceo_followups WHERE id = ?)
44388
- AND status IN ('pending', 'processing', 'read')
44389
- `).run(now, id);
44390
- };
44391
- var failCeoFollowup = (id, error) => {
44392
- const db3 = createSqliteDB();
44393
- const now = Date.now();
44394
- db3.prepare(`
44395
- UPDATE ceo_followups
44396
- SET status = 'failed',
44397
- last_error = ?,
44398
- updated_at = ?
44399
- WHERE id = ?
44400
- AND status IN ('pending', 'processing', 'failed')
44401
- `).run(error.slice(0, 1e3), now, id);
44402
- };
44403
- var recoverStaleProcessingCeoFollowups = (staleBefore) => {
44404
- const db3 = createSqliteDB();
44405
- const now = Date.now();
44406
- const result = db3.prepare(`
44407
- UPDATE ceo_followups
44408
- SET status = 'failed',
44409
- last_error = 'stale_processing_recovered',
44410
- updated_at = ?
44411
- WHERE status = 'processing'
44412
- AND updated_at < ?
44413
- `).run(now, staleBefore);
44414
- return result.changes;
44415
- };
44416
- var completePendingCeoFollowupsForUser = (originUserId) => {
44417
- const db3 = createSqliteDB();
44418
- const now = Date.now();
44419
- const rows = db3.prepare(`
44420
- SELECT id, source_message_id as sourceMessageId
44421
- FROM ceo_followups
44422
- WHERE origin_user_id = ?
44423
- AND status IN ('pending', 'processing', 'failed')
44424
- `).all(originUserId);
44425
- const tx = db3.transaction((items) => {
44426
- const completeStmt = db3.prepare(`
44427
- UPDATE ceo_followups
44428
- SET status = 'completed',
44429
- completed_at = COALESCE(completed_at, ?),
44430
- updated_at = ?,
44431
- last_error = NULL
44432
- WHERE id = ?
44433
- AND status IN ('pending', 'processing', 'failed')
44434
- `);
44435
- const doneStmt = db3.prepare(`
44436
- UPDATE mailbox
44437
- SET status = 'done',
44438
- updated_at = ?
44439
- WHERE id = ?
44440
- AND status IN ('pending', 'processing', 'read')
44441
- `);
44442
- for (const item of items) {
44443
- completeStmt.run(now, now, item.id);
44444
- doneStmt.run(now, item.sourceMessageId);
44445
- }
44446
- });
44447
- tx(rows);
44448
- return rows.length;
44449
- };
44450
-
44451
- // src/agent/outboundDedup.ts
44452
- var import_node_crypto4 = require("node:crypto");
44453
- var DEFAULT_WINDOW_MS = 15e3;
44454
- var recentSends = /* @__PURE__ */ new Map();
44455
- var lastSweepAt = 0;
44456
- var normalize3 = (text2) => text2.replace(/\s+/g, " ").trim();
44457
- var keyFor = (userId, normalized) => {
44458
- const hash = (0, import_node_crypto4.createHash)("sha1").update(normalized).digest("hex");
44459
- return `${userId}::${hash}`;
44460
- };
44461
- var sweep = (now, windowMs) => {
44462
- if (now - lastSweepAt < windowMs) return;
44463
- lastSweepAt = now;
44464
- for (const [k, ts] of recentSends) {
44465
- if (now - ts > windowMs) recentSends.delete(k);
44466
- }
44467
- };
44468
- var claimOutboundSend = (userId, text2, windowMs = DEFAULT_WINDOW_MS) => {
44469
- const normalized = normalize3(text2);
44470
- if (!normalized) return true;
44471
- const now = Date.now();
44472
- sweep(now, windowMs);
44473
- const key = keyFor(userId, normalized);
44474
- const last = recentSends.get(key);
44475
- if (last !== void 0 && now - last < windowMs) {
44476
- return false;
44477
- }
44478
- recentSends.set(key, now);
44479
- return true;
44480
- };
44481
- var claimOutboundFileSend = (userId, fileName, fileRef, windowMs = DEFAULT_WINDOW_MS) => claimOutboundSend(userId, `file:${fileName}:${fileRef}`, windowMs);
44482
-
44483
44201
  // src/tools/UserRecoverableToolError.ts
44484
44202
  var UserRecoverableToolError = class extends Error {
44485
44203
  userMessage;
@@ -44493,466 +44211,6 @@ var UserRecoverableToolError = class extends Error {
44493
44211
  };
44494
44212
  var isUserRecoverableToolError = (error) => error instanceof UserRecoverableToolError || typeof error === "object" && error !== null && error.name === "UserRecoverableToolError" && typeof error.userMessage === "string";
44495
44213
 
44496
- // src/attachments/attachmentContext.ts
44497
- var import_node_crypto5 = require("node:crypto");
44498
- var import_node_fs3 = require("node:fs");
44499
- var import_node_path5 = require("node:path");
44500
- var MAX_ATTACHMENT_RECORDS = 100;
44501
- var RECENT_ATTACHMENT_LIMIT = 5;
44502
- function makeAttachmentId(input) {
44503
- const raw2 = [
44504
- input.userId,
44505
- input.platform,
44506
- input.messageId,
44507
- input.resourceKey,
44508
- input.kind
44509
- ].join(":");
44510
- const digest = (0, import_node_crypto5.createHash)("sha256").update(raw2).digest("hex").slice(0, 16);
44511
- return `att_${input.kind === "image" ? "img" : "file"}_${digest}`;
44512
- }
44513
- function indexPath(userId) {
44514
- return (0, import_node_path5.join)(getDuclawWorkspaceDir(), userId, "attachments", "index.json");
44515
- }
44516
- function readIndex(userId) {
44517
- const filePath = indexPath(userId);
44518
- if (!(0, import_node_fs3.existsSync)(filePath)) return [];
44519
- try {
44520
- const parsed = JSON.parse((0, import_node_fs3.readFileSync)(filePath, "utf8"));
44521
- return Array.isArray(parsed) ? parsed.filter(isAttachmentRecord) : [];
44522
- } catch (error) {
44523
- console.warn(`[attachments] failed to read attachment index: ${error.message}`);
44524
- return [];
44525
- }
44526
- }
44527
- function writeIndex(userId, records) {
44528
- const filePath = indexPath(userId);
44529
- (0, import_node_fs3.mkdirSync)((0, import_node_path5.dirname)(filePath), { recursive: true });
44530
- (0, import_node_fs3.writeFileSync)(filePath, JSON.stringify(records.slice(0, MAX_ATTACHMENT_RECORDS), null, 2));
44531
- }
44532
- function isAttachmentRecord(value) {
44533
- const record2 = value;
44534
- return Boolean(record2) && typeof record2.id === "string" && (record2.kind === "image" || record2.kind === "file") && typeof record2.userId === "string" && typeof record2.pathOrUrl === "string";
44535
- }
44536
- function stringValue(value) {
44537
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
44538
- }
44539
- function attachmentKind(value) {
44540
- const type = stringValue(value.type);
44541
- const mimeType = stringValue(value.mimeType);
44542
- const name = stringValue(value.name) ?? stringValue(value.path) ?? stringValue(value.url) ?? "";
44543
- if (type === "image" || mimeType?.startsWith("image/") || /\.(png|jpe?g|gif|webp)$/i.test(name)) {
44544
- return "image";
44545
- }
44546
- return "file";
44547
- }
44548
- function xmlEscape(value) {
44549
- return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
44550
- }
44551
- function upsertAttachments(userId, records) {
44552
- if (records.length === 0) return;
44553
- const existing = readIndex(userId);
44554
- const byId = /* @__PURE__ */ new Map();
44555
- for (const record2 of [...records, ...existing]) {
44556
- if (!byId.has(record2.id)) byId.set(record2.id, record2);
44557
- }
44558
- writeIndex(userId, Array.from(byId.values()).sort((a, b) => b.receivedAt.localeCompare(a.receivedAt)));
44559
- }
44560
- function listRecentAttachments(userId, limit = RECENT_ATTACHMENT_LIMIT) {
44561
- return readIndex(userId).sort((a, b) => b.receivedAt.localeCompare(a.receivedAt)).slice(0, limit);
44562
- }
44563
- function resolveAttachmentPathOrUrl(userId, attachmentId) {
44564
- return readIndex(userId).find((record2) => record2.id === attachmentId)?.pathOrUrl;
44565
- }
44566
- function collectAttachmentsFromRequest(request) {
44567
- const metadata = request.metadata ?? {};
44568
- const platform = request.platform || "unknown";
44569
- const messageId = request.requestId;
44570
- const receivedAt = (/* @__PURE__ */ new Date()).toISOString();
44571
- const records = [];
44572
- const seen = /* @__PURE__ */ new Set();
44573
- const addRecord = (input) => {
44574
- if (!input.pathOrUrl) return;
44575
- const id = makeAttachmentId({
44576
- userId: request.userId,
44577
- platform,
44578
- messageId,
44579
- resourceKey: input.resourceKey,
44580
- kind: input.kind
44581
- });
44582
- if (seen.has(id)) return;
44583
- seen.add(id);
44584
- records.push({
44585
- id,
44586
- kind: input.kind,
44587
- platform,
44588
- userId: request.userId,
44589
- messageId,
44590
- resourceKey: input.resourceKey,
44591
- pathOrUrl: input.pathOrUrl,
44592
- name: input.name,
44593
- mimeType: input.mimeType,
44594
- source: input.source,
44595
- receivedAt
44596
- });
44597
- };
44598
- const imageUrl = stringValue(metadata.imageUrl);
44599
- const imageKey = stringValue(metadata.imageKey);
44600
- if (imageUrl && imageKey) {
44601
- addRecord({
44602
- kind: "image",
44603
- resourceKey: imageKey,
44604
- pathOrUrl: imageUrl,
44605
- source: `${platform}_metadata`
44606
- });
44607
- }
44608
- const fileUrl = stringValue(metadata.fileUrl);
44609
- const fileName = stringValue(metadata.fileName);
44610
- if (fileUrl && fileName) {
44611
- addRecord({
44612
- kind: "file",
44613
- resourceKey: fileName,
44614
- pathOrUrl: fileUrl,
44615
- name: fileName,
44616
- source: `${platform}_metadata`
44617
- });
44618
- }
44619
- const attachments = Array.isArray(metadata.attachments) ? metadata.attachments : [];
44620
- for (const attachment of attachments) {
44621
- const resourceKey = stringValue(attachment.id) ?? stringValue(attachment.name);
44622
- const pathOrUrl = stringValue(attachment.url) ?? stringValue(attachment.path);
44623
- if (!resourceKey || !pathOrUrl) continue;
44624
- addRecord({
44625
- kind: attachmentKind(attachment),
44626
- resourceKey,
44627
- pathOrUrl,
44628
- name: stringValue(attachment.name),
44629
- mimeType: stringValue(attachment.mimeType),
44630
- source: `${platform}_attachment`
44631
- });
44632
- }
44633
- return records;
44634
- }
44635
- function buildAttachmentContextXml(records) {
44636
- if (records.length === 0) return "";
44637
- const lines = [
44638
- `<recent-attachments>`,
44639
- ` <system-note>Recent attachments are available assets, not automatic task inputs. Use attachment_id only when the current user message explicitly refers to an attachment/image/file, asks to use previous assets, or says \u56FE\u4E00/\u56FE\u4E8C/\u7B2C\u4E00\u5F20/\u7B2C\u4E8C\u5F20. If the current request is unrelated pure text, Do not call image_understand or image_generate just because recent attachments are listed. Do not invent or reproduce long URLs; tools can resolve the real file source from attachment_id. \u56FE\u4E00/\u7B2C\u4E00\u5F20\u56FE\u7247 maps to image number 1, \u56FE\u4E8C/\u7B2C\u4E8C\u5F20\u56FE\u7247 maps to image number 2, following the order below. For image_generate edits, put the destination/base image in target_attachment_id or attachment_id, and put source/reference/material images in reference_attachment_id(s).</system-note>`
44640
- ];
44641
- for (const [index, record2] of records.entries()) {
44642
- lines.push(` <${record2.kind} id="${xmlEscape(record2.id)}">`);
44643
- lines.push(` <number>${index + 1}</number>`);
44644
- lines.push(` <source>${xmlEscape(record2.source ?? record2.platform)}</source>`);
44645
- lines.push(` <message_id>${xmlEscape(record2.messageId)}</message_id>`);
44646
- lines.push(` <resource_key>${xmlEscape(record2.resourceKey)}</resource_key>`);
44647
- if (record2.name) lines.push(` <name>${xmlEscape(record2.name)}</name>`);
44648
- if (record2.mimeType) lines.push(` <mime_type>${xmlEscape(record2.mimeType)}</mime_type>`);
44649
- lines.push(` <received_at>${xmlEscape(record2.receivedAt)}</received_at>`);
44650
- lines.push(` </${record2.kind}>`);
44651
- }
44652
- lines.push(`</recent-attachments>`);
44653
- return lines.join("\n");
44654
- }
44655
- function attachRecentAttachmentContext(request, content) {
44656
- const current = collectAttachmentsFromRequest(request);
44657
- if (current.length > 0) {
44658
- upsertAttachments(request.userId, current);
44659
- request.metadata = {
44660
- ...request.metadata ?? {},
44661
- attachmentIds: current.map((record2) => record2.id),
44662
- attachmentId: current[0]?.id
44663
- };
44664
- }
44665
- const context = buildAttachmentContextXml(listRecentAttachments(request.userId));
44666
- if (!context) return content;
44667
- return `${content}
44668
-
44669
- <system-reminder>
44670
- ${context}
44671
- </system-reminder>`;
44672
- }
44673
-
44674
- // src/agent/workDossier.ts
44675
- var textPreview = (value, max = 240) => value.length <= max ? value : `${value.slice(0, max)}...`;
44676
- var stringArray = (value) => {
44677
- if (typeof value === `string` && value.trim()) return [value];
44678
- if (!Array.isArray(value)) return [];
44679
- return value.filter((item) => typeof item === `string` && item.trim().length > 0);
44680
- };
44681
- var findWorkItemIdFromCeoFollowups = (ids) => {
44682
- if (ids.length === 0) return null;
44683
- const db3 = createSqliteDB();
44684
- const placeholders = ids.map(() => `?`).join(`,`);
44685
- const row = db3.prepare(`
44686
- SELECT work_item_id as workItemId
44687
- FROM ceo_followups
44688
- WHERE id IN (${placeholders})
44689
- AND work_item_id IS NOT NULL
44690
- ORDER BY created_at DESC
44691
- LIMIT 1
44692
- `).get(...ids);
44693
- return row?.workItemId ?? null;
44694
- };
44695
- var findWorkItemIdFromMailbox = (messageId) => {
44696
- const db3 = createSqliteDB();
44697
- const row = db3.prepare(`
44698
- SELECT work_item_id as workItemId
44699
- FROM mailbox
44700
- WHERE id = ?
44701
- AND work_item_id IS NOT NULL
44702
- `).get(messageId);
44703
- return row?.workItemId ?? null;
44704
- };
44705
- var workItemIdFromRequest = (request) => {
44706
- const fromMetadata = request.metadata?.workItemId;
44707
- if (typeof fromMetadata === `string` && fromMetadata.trim()) return fromMetadata;
44708
- const followupIds = [
44709
- ...stringArray(request.metadata?.ceoFollowupId),
44710
- ...stringArray(request.metadata?.ceoFollowupIds)
44711
- ];
44712
- const fromFollowups = findWorkItemIdFromCeoFollowups(followupIds);
44713
- if (fromFollowups) return fromFollowups;
44714
- return findWorkItemIdFromMailbox(request.requestId);
44715
- };
44716
- var rowsForWorkItem = (workItemId) => {
44717
- const db3 = createSqliteDB();
44718
- return db3.prepare(`
44719
- SELECT
44720
- id,
44721
- from_mailbox_id as fromMailboxId,
44722
- to_mailbox_id as toMailboxId,
44723
- content,
44724
- status,
44725
- work_item_role as workItemRole,
44726
- send_time as sendTime
44727
- FROM mailbox
44728
- WHERE work_item_id = ?
44729
- ORDER BY send_time ASC
44730
- LIMIT 12
44731
- `).all(workItemId);
44732
- };
44733
- var buildWorkDossier = (request) => {
44734
- const role = request.departmentAgentId ? `Department Agent` : `Main Manager/CEO`;
44735
- const workItemId = workItemIdFromRequest(request);
44736
- const rows = workItemId ? rowsForWorkItem(workItemId) : [];
44737
- const progressRows = rows.filter((row) => row.workItemRole === `followup`);
44738
- const finalRows = rows.filter((row) => row.workItemRole === `upstream_report`);
44739
- const lines = [
44740
- `<work-dossier>`,
44741
- `\u4F60\u7684\u89D2\u8272\uFF1A${role}`,
44742
- request.departmentAgentId ? `\u5F53\u524D\u90AE\u7BB1\uFF1A${request.departmentAgentId}` : `\u5F53\u524D\u7528\u6237\uFF1A${request.userId}`,
44743
- workItemId ? `work_item_id\uFF1A${workItemId}` : ``,
44744
- finalRows.length > 0 ? `\u7528\u6237\u662F\u5426\u5DF2\u6536\u5230\u6700\u7EC8\u7ED3\u679C\uFF1A\u7B49\u5F85 CEO \u7528\u6237\u53EF\u89C1\u6C47\u62A5` : `\u7528\u6237\u662F\u5426\u5DF2\u6536\u5230\u6700\u7EC8\u7ED3\u679C\uFF1A\u5426\u6216\u672A\u77E5`,
44745
- progressRows.length > 0 ? `\u5185\u90E8\u5F53\u524D\u8FDB\u5C55\uFF1A` : ``,
44746
- ...progressRows.map((row) => `- ${row.fromMailboxId} -> ${row.toMailboxId}: ${textPreview(row.content)}`),
44747
- finalRows.length === 0 ? `\u5F53\u524D\u7F3A\u53E3\uFF1A\u8FD8\u6CA1\u6709\u6700\u7EC8\u62A5\u544A` : `\u5F53\u524D\u7F3A\u53E3\uFF1ACEO \u9700\u8981\u6C47\u603B\u6700\u7EC8\u62A5\u544A\u5E76\u5411\u7528\u6237\u4EA4\u4ED8`,
44748
- finalRows.length === 0 ? `\u5EFA\u8BAE\u52A8\u4F5C\uFF1A\u4E0D\u8981\u91CD\u590D\u5411\u7528\u6237\u64AD\u62A5\u5185\u90E8\u8FDB\u5C55\uFF1B\u7B49\u5F85\u6700\u7EC8\u62A5\u544A\uFF0C\u6216\u5728\u5408\u7406\u7B49\u5F85\u65F6\u95F4\u540E\u5411\u8D1F\u8D23\u4EBA\u8BE2\u95EE\u4E00\u6B21\u3002` : `\u5EFA\u8BAE\u52A8\u4F5C\uFF1A\u6C47\u603B\u6700\u7EC8\u62A5\u544A\uFF0C\u5411\u7528\u6237\u53D1\u9001\u4E00\u6B21\u6E05\u6670\u7B54\u590D\uFF0C\u7136\u540E\u7ED3\u675F\u672C\u8F6E\u3002`,
44749
- `</work-dossier>`
44750
- ].filter(Boolean);
44751
- return lines.join(`
44752
- `);
44753
- };
44754
-
44755
- // src/department/DepartmentMember.ts
44756
- var import_fs7 = require("fs");
44757
- var import_path7 = __toESM(require("path"));
44758
-
44759
- // src/department/Department.ts
44760
- var import_path6 = __toESM(require("path"));
44761
- var import_fs6 = require("fs");
44762
- var legacyMigrationChecked = false;
44763
- var getDepartmentBaseDir = () => {
44764
- return import_path6.default.join(getDuclawHomeDir(), "department");
44765
- };
44766
- var getLegacyTeamBaseDir = () => {
44767
- return import_path6.default.join(getDuclawHomeDir(), "team");
44768
- };
44769
- var getDepartmentWorkSpaceDir = (departmentName) => {
44770
- return import_path6.default.join(getDepartmentBaseDir(), "workspace", departmentName);
44771
- };
44772
- var getLegacyTeamWorkSpaceDir = (teamName) => {
44773
- return import_path6.default.join(getLegacyTeamBaseDir(), "workspace", teamName);
44774
- };
44775
- var getDepartmentJsonPath = (departmentName) => {
44776
- return import_path6.default.join(getDepartmentWorkSpaceDir(departmentName), "department.json");
44777
- };
44778
- var getLegacyTeamJsonPath = (teamName) => {
44779
- return import_path6.default.join(getLegacyTeamWorkSpaceDir(teamName), "team.json");
44780
- };
44781
- var mapLegacyRole = (role) => {
44782
- return role === "team_manager" ? "department_head" : "executor";
44783
- };
44784
- var mapLegacyDepartment = (legacy) => {
44785
- const departmentMembers = (legacy.teamMembers ?? []).map((member) => ({
44786
- id: member.id,
44787
- name: member.name,
44788
- departmentId: legacy.id,
44789
- mailBoxId: member.mailBoxId,
44790
- workspaceId: member.workspaceId,
44791
- role: mapLegacyRole(member.role),
44792
- focusOn: member.focusOn
44793
- }));
44794
- const headMemberId = legacy.managerMemberId ?? departmentMembers.find((member) => member.role === "department_head")?.id;
44795
- return {
44796
- id: legacy.id,
44797
- name: legacy.name,
44798
- sourceGoalId: legacy.goalId,
44799
- charter: legacy.goalId ? `Legacy department migrated from team goal ${legacy.goalId}.` : "Legacy department migrated from team data.",
44800
- workpath: legacy.workpath,
44801
- headMemberId,
44802
- departmentMembers
44803
- };
44804
- };
44805
- var migrateLegacyTeamsToDepartments = () => {
44806
- if (legacyMigrationChecked) return;
44807
- legacyMigrationChecked = true;
44808
- const legacyWorkspaceDir = import_path6.default.join(getLegacyTeamBaseDir(), "workspace");
44809
- if (!(0, import_fs6.existsSync)(legacyWorkspaceDir)) return;
44810
- for (const legacyName of (0, import_fs6.readdirSync)(legacyWorkspaceDir)) {
44811
- const legacyJsonPath = getLegacyTeamJsonPath(legacyName);
44812
- if (!(0, import_fs6.existsSync)(legacyJsonPath)) continue;
44813
- const departmentJsonPath = getDepartmentJsonPath(legacyName);
44814
- if ((0, import_fs6.existsSync)(departmentJsonPath)) continue;
44815
- try {
44816
- const legacy = JSON.parse((0, import_fs6.readFileSync)(legacyJsonPath, "utf-8"));
44817
- const department = mapLegacyDepartment(legacy);
44818
- (0, import_fs6.mkdirSync)(getDepartmentWorkSpaceDir(department.name), { recursive: true });
44819
- (0, import_fs6.writeFileSync)(departmentJsonPath, JSON.stringify(department, null, " "), "utf-8");
44820
- } catch (err) {
44821
- console.warn(`[department] Failed to migrate legacy team ${legacyName}: ${err.message}`);
44822
- }
44823
- }
44824
- };
44825
- var createDepartment = (departmentDefinition) => {
44826
- if (!departmentDefinition) throw new Error(`[createDepartment] departmentDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
44827
- const departmentPath = getDepartmentWorkSpaceDir(departmentDefinition.name);
44828
- (0, import_fs6.mkdirSync)(departmentPath, { recursive: true });
44829
- (0, import_fs6.writeFileSync)(getDepartmentJsonPath(departmentDefinition.name), JSON.stringify(departmentDefinition, null, " "), "utf-8");
44830
- return departmentDefinition;
44831
- };
44832
- var getDepartment = (name) => {
44833
- migrateLegacyTeamsToDepartments();
44834
- const departmentJsonPath = getDepartmentJsonPath(name);
44835
- if (!(0, import_fs6.existsSync)(departmentJsonPath)) return null;
44836
- const text2 = (0, import_fs6.readFileSync)(departmentJsonPath, "utf-8");
44837
- return JSON.parse(text2);
44838
- };
44839
- var listDepartments = () => {
44840
- migrateLegacyTeamsToDepartments();
44841
- const workspaceDir = import_path6.default.join(getDepartmentBaseDir(), "workspace");
44842
- if (!(0, import_fs6.existsSync)(workspaceDir)) return [];
44843
- const departments = [];
44844
- for (const departmentName of (0, import_fs6.readdirSync)(workspaceDir)) {
44845
- const department = getDepartment(departmentName);
44846
- if (department) departments.push(department);
44847
- }
44848
- return departments;
44849
- };
44850
- var getDepartmentById = (id) => {
44851
- const department = listDepartments().find((item) => item.id === id);
44852
- return department ?? null;
44853
- };
44854
- var deleteDepartment = (name) => {
44855
- if (!(0, import_fs6.existsSync)(getDepartmentJsonPath(name))) {
44856
- throw new Error(`[deleteDepartment] \u4E0D\u5B58\u5728\u5BF9\u5E94\u7684\u90E8\u95E8 ${name} \u7684 department.json \u6587\u4EF6`);
44857
- }
44858
- (0, import_fs6.rmSync)(getDepartmentJsonPath(name));
44859
- };
44860
-
44861
- // src/department/workspace/workspace.ts
44862
- var db = createSqliteDB();
44863
- var getWorkspaceId = (departmentName, memberName) => {
44864
- return `${departmentName}::${memberName}`;
44865
- };
44866
- var createWorkspace = (workspace) => {
44867
- const stmt = db.prepare(`INSERT INTO workspace (id, team_name, teammate_name, team_workpath) VALUES (?, ?, ?, ?) `);
44868
- stmt.run(
44869
- workspace.id,
44870
- workspace.departmentName,
44871
- workspace.memberName,
44872
- workspace.departmentWorkPath
44873
- );
44874
- };
44875
- var deleteWorkspace = (workspaceId) => {
44876
- const stmt = db.prepare(`delete from workspace where id = ?`);
44877
- stmt.run(workspaceId);
44878
- };
44879
-
44880
- // src/department/DepartmentMember.ts
44881
- var createDepartmentMember = (departmentMemberDefinition) => {
44882
- if (!departmentMemberDefinition) throw new Error(`[createDepartmentMember] departmentMemberDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
44883
- const { name, departmentId, workspaceId } = departmentMemberDefinition;
44884
- const department = getDepartmentById(departmentId);
44885
- if (!department) throw new Error(`[createDepartmentMember] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentId}`);
44886
- const memberPath = import_path7.default.join(getDepartmentWorkSpaceDir(department.name), name);
44887
- (0, import_fs7.mkdirSync)(memberPath, { recursive: true });
44888
- const workspace = {
44889
- id: getWorkspaceId(department.name, departmentMemberDefinition.name),
44890
- departmentName: department.name,
44891
- memberName: name,
44892
- departmentWorkPath: memberPath
44893
- };
44894
- createWorkspace(workspace);
44895
- if (!department.departmentMembers) {
44896
- department.departmentMembers = [];
44897
- }
44898
- if (department.departmentMembers.some((member) => member.id === departmentMemberDefinition.id || member.name === departmentMemberDefinition.name)) {
44899
- throw new Error(`[createDepartmentMember] \u90E8\u95E8 ${department.name} \u5DF2\u5B58\u5728\u540C\u540D\u6216\u540C id \u6210\u5458: ${departmentMemberDefinition.name}/${departmentMemberDefinition.id}`);
44900
- }
44901
- if (departmentMemberDefinition.role === "department_head") {
44902
- const existingHead = department.headMemberId ? department.departmentMembers.find((member) => member.id === department.headMemberId) : department.departmentMembers.find((member) => member.role === "department_head");
44903
- if (existingHead) {
44904
- throw new Error(`[createDepartmentMember] \u90E8\u95E8 ${department.name} \u5DF2\u5B58\u5728 Department Head: ${existingHead.name}`);
44905
- }
44906
- department.headMemberId = departmentMemberDefinition.id;
44907
- }
44908
- department.departmentMembers.push(departmentMemberDefinition);
44909
- (0, import_fs7.writeFileSync)(getDepartmentJsonPath(department.name), JSON.stringify(department, null, " "), "utf-8");
44910
- return departmentMemberDefinition;
44911
- };
44912
- var listDepartmentMembers = (departmentName) => {
44913
- const departmentJsonPath = getDepartmentJsonPath(departmentName);
44914
- if (!(0, import_fs7.existsSync)(departmentJsonPath)) return [];
44915
- const text2 = (0, import_fs7.readFileSync)(departmentJsonPath, "utf-8");
44916
- const department = JSON.parse(text2);
44917
- if (!department) throw new Error(`[listDepartmentMembers] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentName}`);
44918
- return department.departmentMembers ?? [];
44919
- };
44920
- var getDepartmentMember = (departmentName, departmentMemberId) => {
44921
- const members = listDepartmentMembers(departmentName);
44922
- return members.find((member) => member.id === departmentMemberId) || null;
44923
- };
44924
- var getDepartmentMemberByName = (departmentName, departmentMemberName) => {
44925
- const members = listDepartmentMembers(departmentName);
44926
- return members.find((member) => member.name === departmentMemberName) || null;
44927
- };
44928
- var getDepartmentMemberByMailboxId = (mailboxId) => {
44929
- const [departmentName, memberName] = mailboxId.split("::");
44930
- if (!departmentName || !memberName) return null;
44931
- return getDepartmentMemberByName(departmentName, memberName);
44932
- };
44933
- var getDepartmentMemberById = (memberId) => {
44934
- for (const department of listDepartments()) {
44935
- const targetMember = department.departmentMembers.find((member) => member.id === memberId);
44936
- if (targetMember) return targetMember;
44937
- }
44938
- return null;
44939
- };
44940
- var deleteDepartmentMemberById = (departmentName, memberId) => {
44941
- const department = getDepartment(departmentName);
44942
- if (!department) throw new Error(`[deleteDepartmentMemberById] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentName}`);
44943
- const memberIdx = department.departmentMembers.findIndex((member) => member.id === memberId);
44944
- if (memberIdx === -1) {
44945
- throw new Error(`[deleteDepartmentMemberById] \u627E\u4E0D\u5230\u5BF9\u5E94 id \u7684 department member: ${memberId}`);
44946
- }
44947
- const workspaceId = department.departmentMembers[memberIdx].workspaceId;
44948
- if (department.headMemberId === memberId) {
44949
- delete department.headMemberId;
44950
- }
44951
- department.departmentMembers = department.departmentMembers.filter((_, index) => index !== memberIdx);
44952
- (0, import_fs7.writeFileSync)(getDepartmentJsonPath(departmentName), JSON.stringify(department, null, " "), "utf-8");
44953
- deleteWorkspace(workspaceId);
44954
- };
44955
-
44956
44214
  // src/agent/createAgentCore.ts
44957
44215
  var assistantMessageFromResponse = (response) => ({
44958
44216
  role: "assistant",
@@ -44966,7 +44224,7 @@ var isAbortError = (error) => {
44966
44224
  return error.name === "AbortError" || error.message.includes("aborted") || error.message.includes("AbortError");
44967
44225
  };
44968
44226
  var llmRequestIdForTurn = (request, messages, system, tools) => {
44969
- const hash = (0, import_node_crypto6.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);
44227
+ const hash = (0, import_node_crypto3.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);
44970
44228
  return `dreq_${hash}`;
44971
44229
  };
44972
44230
  var LLM_CREDIT_EXHAUSTED_MESSAGE = "Credit \u4F59\u989D\u4E0D\u8DB3\uFF0C\u6682\u65F6\u65E0\u6CD5\u7EE7\u7EED\u8C03\u7528\u4E3B\u6A21\u578B\u5904\u7406\u8FD9\u6761\u6D88\u606F\u3002\u8BF7\u5148\u5145\u503C\u6216\u4F7F\u7528\u6FC0\u6D3B\u7801\u589E\u52A0 Credit \u540E\u518D\u8BD5\u3002";
@@ -44996,42 +44254,27 @@ var traceMetadataFromRequest = (request, internalOnly) => ({
44996
44254
  parentMessageId: request.metadata?.parentMessageId,
44997
44255
  workItemId: request.metadata?.workItemId
44998
44256
  });
44999
- var agentTraceIdentity = (request) => {
45000
- if (!request.departmentAgentId) {
45001
- return { name: `CEO turn`, role: `ceo` };
45002
- }
45003
- const member = getDepartmentMemberByMailboxId(request.departmentAgentId);
45004
- if (member?.role === `department_head`) {
45005
- return {
45006
- name: `Department Head turn: ${request.departmentAgentId}`,
45007
- role: `department_head`,
45008
- memberName: member.name,
45009
- mailboxId: request.departmentAgentId
45010
- };
45011
- }
45012
- if (member?.role === `executor`) {
45013
- return {
45014
- name: `Executor turn: ${request.departmentAgentId}`,
45015
- role: `executor`,
45016
- memberName: member.name,
45017
- mailboxId: request.departmentAgentId
45018
- };
45019
- }
44257
+ var genericTraceIdentity = (request) => {
45020
44258
  return {
45021
- name: `Department Agent turn: ${request.departmentAgentId}`,
45022
- role: `department_agent`,
45023
- mailboxId: request.departmentAgentId
44259
+ name: `Agent turn`,
44260
+ role: `agent`,
44261
+ mailboxId: request.departmentAgentId || void 0
45024
44262
  };
45025
44263
  };
45026
44264
  var createAgent = (config2) => {
45027
44265
  const { systemPrompt, llm, storage, topicStorage, compactSummaryStorage, recallIndexStorage, toolExecutor, tools, backgroundManager, maxIterations = 50, dreamEngine, skillForgeEngine, memoryEngine, onLlmRequestId, tracer } = config2;
45028
44266
  const signals = /* @__PURE__ */ new Map();
45029
- return async (request) => {
44267
+ return async (initialRequest) => {
44268
+ let request = initialRequest;
45030
44269
  if (config2.workspacePath && !request.defaultWorkDir) {
45031
44270
  request.defaultWorkDir = config2.workspacePath;
45032
44271
  }
44272
+ request = await config2.hooks?.beforeRun?.(request) ?? request;
45033
44273
  const { userId, job } = request;
45034
- const content = attachRecentAttachmentContext(request, request.content);
44274
+ const content = await config2.hooks?.augmentUserContent?.({
44275
+ request,
44276
+ content: request.content
44277
+ }) ?? request.content;
45035
44278
  const internalOnly = request.metadata?.internalOnly === true;
45036
44279
  let rootTrace;
45037
44280
  let agentTrace;
@@ -45043,6 +44286,7 @@ var createAgent = (config2) => {
45043
44286
  const finish = async (result) => {
45044
44287
  await agentTrace?.end({ outputs: result });
45045
44288
  await rootTrace?.end({ outputs: result });
44289
+ await config2.hooks?.afterRun?.({ request, result });
45046
44290
  return result;
45047
44291
  };
45048
44292
  const traceOutboundText = async (to, message, send) => {
@@ -45104,7 +44348,7 @@ var createAgent = (config2) => {
45104
44348
  if (userVisibleSent) return ids;
45105
44349
  return ids.filter((id) => !managerMailboxEventIds.has(id));
45106
44350
  };
45107
- const ceoFollowupIdsFromMetadata = (metadata) => {
44351
+ const ceoFollowupIdsFromMetadata2 = (metadata) => {
45108
44352
  const ids = /* @__PURE__ */ new Set();
45109
44353
  if (typeof metadata?.ceoFollowupId === "string") ids.add(metadata.ceoFollowupId);
45110
44354
  if (Array.isArray(metadata?.ceoFollowupIds)) {
@@ -45116,19 +44360,20 @@ var createAgent = (config2) => {
45116
44360
  };
45117
44361
  const rememberCeoFollowupIds = (ids) => {
45118
44362
  if (ids.length === 0) return;
45119
- const current = ceoFollowupIdsFromMetadata(request.metadata);
44363
+ const current = ceoFollowupIdsFromMetadata2(request.metadata);
45120
44364
  request.metadata = {
45121
44365
  ...request.metadata ?? {},
45122
44366
  ceoFollowupIds: Array.from(/* @__PURE__ */ new Set([...current, ...ids]))
45123
44367
  };
45124
44368
  };
45125
- const completeUserVisibleCeoFollowups = () => {
45126
- const ids = ceoFollowupIdsFromMetadata(request.metadata);
45127
- if (ids.length > 0) {
45128
- for (const id of ids) completeCeoFollowup(id);
45129
- return;
45130
- }
45131
- completePendingCeoFollowupsForUser(request.userId);
44369
+ const completeUserVisibleCeoFollowups = async () => {
44370
+ await config2.hooks?.completeUserVisibleDelivery?.({ request });
44371
+ };
44372
+ const claimOutboundText = async (text2, reason) => {
44373
+ return await config2.hooks?.claimOutboundText?.({ request, text: text2, reason }) ?? true;
44374
+ };
44375
+ const claimOutboundFile = async (fileName, file) => {
44376
+ return await config2.hooks?.claimOutboundFile?.({ request, fileName, file }) ?? true;
45132
44377
  };
45133
44378
  const queuePendingDurableEvents = () => {
45134
44379
  try {
@@ -45176,7 +44421,7 @@ var createAgent = (config2) => {
45176
44421
  metadata: traceMetadataFromRequest(request, internalOnly)
45177
44422
  };
45178
44423
  rootTrace = request.traceRun ? await request.traceRun.child(sessionTraceInput) : await tracer?.startRun(sessionTraceInput);
45179
- const traceIdentity = agentTraceIdentity(request);
44424
+ const traceIdentity = await config2.hooks?.traceIdentity?.(request) ?? genericTraceIdentity(request);
45180
44425
  agentTrace = await rootTrace?.child({
45181
44426
  name: traceIdentity.name,
45182
44427
  runType: `chain`,
@@ -45303,10 +44548,10 @@ ${content}`;
45303
44548
  }
45304
44549
  }
45305
44550
  const dreamInjection = dreamEngine ? await dreamEngine.injectDream(userId) : "";
45306
- const workDossier = buildWorkDossier(request);
45307
- return systemPrompt + `
44551
+ const systemContext = await config2.hooks?.buildSystemContext?.({ request }) ?? "";
44552
+ return systemPrompt + (systemContext ? `
45308
44553
 
45309
- ${workDossier}` + (memoryInjection ? `
44554
+ ${systemContext}` : "") + (memoryInjection ? `
45310
44555
 
45311
44556
  ${memoryInjection}` : "") + dreamInjection;
45312
44557
  };
@@ -45355,7 +44600,7 @@ ${notifText}
45355
44600
  if (interrupts.length > 0) {
45356
44601
  for (const interrupt of interrupts) {
45357
44602
  markInterruptEventIdsInjected(interrupt.metadata);
45358
- rememberCeoFollowupIds(ceoFollowupIdsFromMetadata(interrupt.metadata));
44603
+ rememberCeoFollowupIds(ceoFollowupIdsFromMetadata2(interrupt.metadata));
45359
44604
  const msg = interrupt.content;
45360
44605
  console.log(`[agent] \u6536\u5230\u4E2D\u65AD\u6D88\u606F\uFF0C\u6CE8\u5165\u5BF9\u8BDD: ${msg.slice(0, 80)}...`);
45361
44606
  if (interrupt.metadata) {
@@ -45413,7 +44658,7 @@ ${content}`
45413
44658
  messages = [...messages, userMessage(text(eventReminder))];
45414
44659
  }
45415
44660
  }
45416
- const workDossier = buildWorkDossier(request);
44661
+ const systemContext = await config2.hooks?.buildSystemContext?.({ request }) ?? "";
45417
44662
  const effectiveSystemPrompt = await buildEffectiveSystemPrompt();
45418
44663
  if (compactConfig.enabled) {
45419
44664
  let tokenCount = tokenCountWithEstimation(messages, effectiveSystemPrompt);
@@ -45455,7 +44700,7 @@ ${content}`
45455
44700
  inputs: {
45456
44701
  llmRequestId,
45457
44702
  systemPrompt: effectiveSystemPrompt,
45458
- workDossier,
44703
+ systemContext,
45459
44704
  messages,
45460
44705
  tools: tools.map((tool) => ({
45461
44706
  name: tool.name,
@@ -45507,7 +44752,7 @@ ${content}`
45507
44752
  if (isLlmCreditExhaustedError(error)) {
45508
44753
  let alreadySent = false;
45509
44754
  if (config2.channelPlugin && !internalOnly) {
45510
- if (claimOutboundSend(request.userId, LLM_CREDIT_EXHAUSTED_MESSAGE)) {
44755
+ if (await claimOutboundText(LLM_CREDIT_EXHAUSTED_MESSAGE, "llm_credit_exhausted")) {
45511
44756
  await traceOutboundText(
45512
44757
  request.userId,
45513
44758
  LLM_CREDIT_EXHAUSTED_MESSAGE,
@@ -45570,7 +44815,7 @@ ${content}`
45570
44815
  console.log(`channelPlugin: ${JSON.stringify(config2.channelPlugin)}`);
45571
44816
  const { userId: userId2 } = request;
45572
44817
  console.log(`request: ${JSON.stringify(request)}`);
45573
- if (claimOutboundSend(userId2, answer)) {
44818
+ if (await claimOutboundText(answer, "send_message_tool")) {
45574
44819
  await traceOutboundText(
45575
44820
  userId2,
45576
44821
  answer,
@@ -45588,7 +44833,7 @@ ${content}`
45588
44833
  }
45589
44834
  hasSentMessage = true;
45590
44835
  sentMessageContent = answer;
45591
- completeUserVisibleCeoFollowups();
44836
+ await completeUserVisibleCeoFollowups();
45592
44837
  }
45593
44838
  }
45594
44839
  if (useBlock.name === `send_file`) {
@@ -45598,7 +44843,7 @@ ${content}`
45598
44843
  if (file) {
45599
44844
  const fileType = inferFileType(fileName);
45600
44845
  const sentFileMessage = `\u6587\u4EF6\u5DF2\u53D1\u9001: ${fileName}`;
45601
- if (claimOutboundFileSend(request.userId, fileName, file)) {
44846
+ if (await claimOutboundFile(fileName, file)) {
45602
44847
  await traceOutboundFile(
45603
44848
  request.userId,
45604
44849
  fileName,
@@ -45618,7 +44863,7 @@ ${content}`
45618
44863
  }
45619
44864
  hasSentMessage = true;
45620
44865
  sentMessageContent ||= sentFileMessage;
45621
- completeUserVisibleCeoFollowups();
44866
+ await completeUserVisibleCeoFollowups();
45622
44867
  }
45623
44868
  }
45624
44869
  }
@@ -45649,7 +44894,7 @@ ${content}`
45649
44894
  if (userRecoverableMessage) {
45650
44895
  let recoverableMessageSent = false;
45651
44896
  if (config2.channelPlugin && !internalOnly) {
45652
- if (claimOutboundSend(request.userId, userRecoverableMessage)) {
44897
+ if (await claimOutboundText(userRecoverableMessage, "user_recoverable_tool_error")) {
45653
44898
  await traceOutboundText(
45654
44899
  request.userId,
45655
44900
  userRecoverableMessage,
@@ -45673,7 +44918,7 @@ ${content}`
45673
44918
  alreadySent: recoverableMessageSent
45674
44919
  });
45675
44920
  }
45676
- const visibleCeoFollowupIdsAfterTools = ceoFollowupIdsFromMetadata(request.metadata);
44921
+ const visibleCeoFollowupIdsAfterTools = ceoFollowupIdsFromMetadata2(request.metadata);
45677
44922
  if (hasSentMessage && visibleCeoFollowupIdsAfterTools.length > 0) {
45678
44923
  if (topicStorage) {
45679
44924
  await updateTopicSummary(topicStorage, userId, beijingTime, sentMessageContent, job?.title);
@@ -45712,7 +44957,7 @@ ${content}`
45712
44957
  console.log(`[agent] \u9000\u51FA\u524D\u53D1\u73B0 ${lateInterrupts.length} \u6761\u8FDF\u5230\u7684\u4E2D\u65AD\u6D88\u606F\uFF0C\u7EE7\u7EED\u5904\u7406`);
45713
44958
  for (const interrupt of lateInterrupts) {
45714
44959
  markInterruptEventIdsInjected(interrupt.metadata);
45715
- rememberCeoFollowupIds(ceoFollowupIdsFromMetadata(interrupt.metadata));
44960
+ rememberCeoFollowupIds(ceoFollowupIdsFromMetadata2(interrupt.metadata));
45716
44961
  const msg = interrupt.content;
45717
44962
  if (interrupt.metadata) {
45718
44963
  request.metadata = {
@@ -45730,9 +44975,9 @@ ${msg}</user-interrupt>`
45730
44975
  }
45731
44976
  continue;
45732
44977
  }
45733
- const visibleCeoFollowupIds = ceoFollowupIdsFromMetadata(request.metadata);
44978
+ const visibleCeoFollowupIds = ceoFollowupIdsFromMetadata2(request.metadata);
45734
44979
  if (!hasSentMessage && visibleCeoFollowupIds.length > 0 && config2.channelPlugin) {
45735
- if (claimOutboundSend(request.userId, textContent2)) {
44980
+ if (await claimOutboundText(textContent2, "followup_fallback_text")) {
45736
44981
  await traceOutboundText(
45737
44982
  request.userId,
45738
44983
  textContent2,
@@ -45749,7 +44994,7 @@ ${msg}</user-interrupt>`
45749
44994
  }
45750
44995
  hasSentMessage = true;
45751
44996
  sentMessageContent = textContent2;
45752
- completeUserVisibleCeoFollowups();
44997
+ await completeUserVisibleCeoFollowups();
45753
44998
  }
45754
44999
  if (topicStorage) {
45755
45000
  const topicSummary = hasSentMessage ? sentMessageContent : textContent2;
@@ -45767,7 +45012,7 @@ ${msg}</user-interrupt>`
45767
45012
  console.log(`[agent] \u9000\u51FA\u524D\u53D1\u73B0 ${lateInterrupts.length} \u6761\u8FDF\u5230\u7684\u4E2D\u65AD\u6D88\u606F\uFF0C\u7EE7\u7EED\u5904\u7406`);
45768
45013
  for (const interrupt of lateInterrupts) {
45769
45014
  markInterruptEventIdsInjected(interrupt.metadata);
45770
- rememberCeoFollowupIds(ceoFollowupIdsFromMetadata(interrupt.metadata));
45015
+ rememberCeoFollowupIds(ceoFollowupIdsFromMetadata2(interrupt.metadata));
45771
45016
  const msg = interrupt.content;
45772
45017
  if (interrupt.metadata) {
45773
45018
  request.metadata = {
@@ -45831,7 +45076,7 @@ var import_node_fs12 = require("node:fs");
45831
45076
  // src/background/BackgroundManager.ts
45832
45077
  var import_child_process = require("child_process");
45833
45078
  var import_crypto2 = require("crypto");
45834
- var import_fs8 = require("fs");
45079
+ var import_fs6 = require("fs");
45835
45080
  var MAX_OUTPUT = 5e4;
45836
45081
  var NOTIFY_LIMIT = 500;
45837
45082
  var TIMEOUT_MS = 3e5;
@@ -45839,7 +45084,7 @@ var SHELL_CANDIDATES = ["/bin/sh", "/usr/bin/sh", "/bin/bash"];
45839
45084
  function findExecutableShell() {
45840
45085
  for (const shell of SHELL_CANDIDATES) {
45841
45086
  try {
45842
- (0, import_fs8.accessSync)(shell, import_fs8.constants.X_OK);
45087
+ (0, import_fs6.accessSync)(shell, import_fs6.constants.X_OK);
45843
45088
  return shell;
45844
45089
  } catch {
45845
45090
  }
@@ -47304,7 +46549,7 @@ ${underline}`);
47304
46549
  }
47305
46550
  return path26;
47306
46551
  };
47307
- var path7 = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
46552
+ var path5 = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
47308
46553
 
47309
46554
  // node_modules/.pnpm/@anthropic-ai+sdk@0.78.0_zod@4.3.6/node_modules/@anthropic-ai/sdk/resources/beta/files.mjs
47310
46555
  var Files = class extends APIResource {
@@ -47342,7 +46587,7 @@ var Files = class extends APIResource {
47342
46587
  */
47343
46588
  delete(fileID, params = {}, options) {
47344
46589
  const { betas } = params ?? {};
47345
- return this._client.delete(path7`/v1/files/${fileID}`, {
46590
+ return this._client.delete(path5`/v1/files/${fileID}`, {
47346
46591
  ...options,
47347
46592
  headers: buildHeaders([
47348
46593
  { "anthropic-beta": [...betas ?? [], "files-api-2025-04-14"].toString() },
@@ -47365,7 +46610,7 @@ var Files = class extends APIResource {
47365
46610
  */
47366
46611
  download(fileID, params = {}, options) {
47367
46612
  const { betas } = params ?? {};
47368
- return this._client.get(path7`/v1/files/${fileID}/content`, {
46613
+ return this._client.get(path5`/v1/files/${fileID}/content`, {
47369
46614
  ...options,
47370
46615
  headers: buildHeaders([
47371
46616
  {
@@ -47388,7 +46633,7 @@ var Files = class extends APIResource {
47388
46633
  */
47389
46634
  retrieveMetadata(fileID, params = {}, options) {
47390
46635
  const { betas } = params ?? {};
47391
- return this._client.get(path7`/v1/files/${fileID}`, {
46636
+ return this._client.get(path5`/v1/files/${fileID}`, {
47392
46637
  ...options,
47393
46638
  headers: buildHeaders([
47394
46639
  { "anthropic-beta": [...betas ?? [], "files-api-2025-04-14"].toString() },
@@ -47437,7 +46682,7 @@ var Models = class extends APIResource {
47437
46682
  */
47438
46683
  retrieve(modelID, params = {}, options) {
47439
46684
  const { betas } = params ?? {};
47440
- return this._client.get(path7`/v1/models/${modelID}?beta=true`, {
46685
+ return this._client.get(path5`/v1/models/${modelID}?beta=true`, {
47441
46686
  ...options,
47442
46687
  headers: buildHeaders([
47443
46688
  { ...betas?.toString() != null ? { "anthropic-beta": betas?.toString() } : void 0 },
@@ -48859,7 +48104,7 @@ var Batches = class extends APIResource {
48859
48104
  */
48860
48105
  retrieve(messageBatchID, params = {}, options) {
48861
48106
  const { betas } = params ?? {};
48862
- return this._client.get(path7`/v1/messages/batches/${messageBatchID}?beta=true`, {
48107
+ return this._client.get(path5`/v1/messages/batches/${messageBatchID}?beta=true`, {
48863
48108
  ...options,
48864
48109
  headers: buildHeaders([
48865
48110
  { "anthropic-beta": [...betas ?? [], "message-batches-2024-09-24"].toString() },
@@ -48912,7 +48157,7 @@ var Batches = class extends APIResource {
48912
48157
  */
48913
48158
  delete(messageBatchID, params = {}, options) {
48914
48159
  const { betas } = params ?? {};
48915
- return this._client.delete(path7`/v1/messages/batches/${messageBatchID}?beta=true`, {
48160
+ return this._client.delete(path5`/v1/messages/batches/${messageBatchID}?beta=true`, {
48916
48161
  ...options,
48917
48162
  headers: buildHeaders([
48918
48163
  { "anthropic-beta": [...betas ?? [], "message-batches-2024-09-24"].toString() },
@@ -48944,7 +48189,7 @@ var Batches = class extends APIResource {
48944
48189
  */
48945
48190
  cancel(messageBatchID, params = {}, options) {
48946
48191
  const { betas } = params ?? {};
48947
- return this._client.post(path7`/v1/messages/batches/${messageBatchID}/cancel?beta=true`, {
48192
+ return this._client.post(path5`/v1/messages/batches/${messageBatchID}/cancel?beta=true`, {
48948
48193
  ...options,
48949
48194
  headers: buildHeaders([
48950
48195
  { "anthropic-beta": [...betas ?? [], "message-batches-2024-09-24"].toString() },
@@ -49139,7 +48384,7 @@ var Versions = class extends APIResource {
49139
48384
  */
49140
48385
  create(skillID, params = {}, options) {
49141
48386
  const { betas, ...body } = params ?? {};
49142
- return this._client.post(path7`/v1/skills/${skillID}/versions?beta=true`, multipartFormRequestOptions({
48387
+ return this._client.post(path5`/v1/skills/${skillID}/versions?beta=true`, multipartFormRequestOptions({
49143
48388
  body,
49144
48389
  ...options,
49145
48390
  headers: buildHeaders([
@@ -49161,7 +48406,7 @@ var Versions = class extends APIResource {
49161
48406
  */
49162
48407
  retrieve(version, params, options) {
49163
48408
  const { skill_id, betas } = params;
49164
- return this._client.get(path7`/v1/skills/${skill_id}/versions/${version}?beta=true`, {
48409
+ return this._client.get(path5`/v1/skills/${skill_id}/versions/${version}?beta=true`, {
49165
48410
  ...options,
49166
48411
  headers: buildHeaders([
49167
48412
  { "anthropic-beta": [...betas ?? [], "skills-2025-10-02"].toString() },
@@ -49184,7 +48429,7 @@ var Versions = class extends APIResource {
49184
48429
  */
49185
48430
  list(skillID, params = {}, options) {
49186
48431
  const { betas, ...query } = params ?? {};
49187
- return this._client.getAPIList(path7`/v1/skills/${skillID}/versions?beta=true`, PageCursor, {
48432
+ return this._client.getAPIList(path5`/v1/skills/${skillID}/versions?beta=true`, PageCursor, {
49188
48433
  query,
49189
48434
  ...options,
49190
48435
  headers: buildHeaders([
@@ -49206,7 +48451,7 @@ var Versions = class extends APIResource {
49206
48451
  */
49207
48452
  delete(version, params, options) {
49208
48453
  const { skill_id, betas } = params;
49209
- return this._client.delete(path7`/v1/skills/${skill_id}/versions/${version}?beta=true`, {
48454
+ return this._client.delete(path5`/v1/skills/${skill_id}/versions/${version}?beta=true`, {
49210
48455
  ...options,
49211
48456
  headers: buildHeaders([
49212
48457
  { "anthropic-beta": [...betas ?? [], "skills-2025-10-02"].toString() },
@@ -49251,7 +48496,7 @@ var Skills = class extends APIResource {
49251
48496
  */
49252
48497
  retrieve(skillID, params = {}, options) {
49253
48498
  const { betas } = params ?? {};
49254
- return this._client.get(path7`/v1/skills/${skillID}?beta=true`, {
48499
+ return this._client.get(path5`/v1/skills/${skillID}?beta=true`, {
49255
48500
  ...options,
49256
48501
  headers: buildHeaders([
49257
48502
  { "anthropic-beta": [...betas ?? [], "skills-2025-10-02"].toString() },
@@ -49291,7 +48536,7 @@ var Skills = class extends APIResource {
49291
48536
  */
49292
48537
  delete(skillID, params = {}, options) {
49293
48538
  const { betas } = params ?? {};
49294
- return this._client.delete(path7`/v1/skills/${skillID}?beta=true`, {
48539
+ return this._client.delete(path5`/v1/skills/${skillID}?beta=true`, {
49295
48540
  ...options,
49296
48541
  headers: buildHeaders([
49297
48542
  { "anthropic-beta": [...betas ?? [], "skills-2025-10-02"].toString() },
@@ -50034,7 +49279,7 @@ var Batches2 = class extends APIResource {
50034
49279
  * ```
50035
49280
  */
50036
49281
  retrieve(messageBatchID, options) {
50037
- return this._client.get(path7`/v1/messages/batches/${messageBatchID}`, options);
49282
+ return this._client.get(path5`/v1/messages/batches/${messageBatchID}`, options);
50038
49283
  }
50039
49284
  /**
50040
49285
  * List all Message Batches within a Workspace. Most recently created batches are
@@ -50070,7 +49315,7 @@ var Batches2 = class extends APIResource {
50070
49315
  * ```
50071
49316
  */
50072
49317
  delete(messageBatchID, options) {
50073
- return this._client.delete(path7`/v1/messages/batches/${messageBatchID}`, options);
49318
+ return this._client.delete(path5`/v1/messages/batches/${messageBatchID}`, options);
50074
49319
  }
50075
49320
  /**
50076
49321
  * Batches may be canceled any time before processing ends. Once cancellation is
@@ -50094,7 +49339,7 @@ var Batches2 = class extends APIResource {
50094
49339
  * ```
50095
49340
  */
50096
49341
  cancel(messageBatchID, options) {
50097
- return this._client.post(path7`/v1/messages/batches/${messageBatchID}/cancel`, options);
49342
+ return this._client.post(path5`/v1/messages/batches/${messageBatchID}/cancel`, options);
50098
49343
  }
50099
49344
  /**
50100
49345
  * Streams the results of a Message Batch as a `.jsonl` file.
@@ -50249,7 +49494,7 @@ var Models2 = class extends APIResource {
50249
49494
  */
50250
49495
  retrieve(modelID, params = {}, options) {
50251
49496
  const { betas } = params ?? {};
50252
- return this._client.get(path7`/v1/models/${modelID}`, {
49497
+ return this._client.get(path5`/v1/models/${modelID}`, {
50253
49498
  ...options,
50254
49499
  headers: buildHeaders([
50255
49500
  { ...betas?.toString() != null ? { "anthropic-beta": betas?.toString() } : void 0 },
@@ -51026,12 +50271,12 @@ var toInternalContent = (sdkContent) => {
51026
50271
 
51027
50272
  // src/storage/FileStorage.ts
51028
50273
  var import_promises6 = require("node:fs/promises");
51029
- var import_node_path6 = __toESM(require("node:path"));
50274
+ var import_node_path5 = __toESM(require("node:path"));
51030
50275
  var encodeKey = (key) => Buffer.from(key).toString("base64url");
51031
50276
  var normalizePrefix = (prefix) => prefix.replace(/[:/\\]+$/g, "") || "agent";
51032
50277
  var createFileStorage = (options = {}) => {
51033
- const rootDir = import_node_path6.default.join(options.rootDir || getDuclawDataDir(), "kv", normalizePrefix(options.prefix || "agent"));
51034
- const fileForKey = (key) => import_node_path6.default.join(rootDir, `${encodeKey(key)}.json`);
50278
+ const rootDir = import_node_path5.default.join(options.rootDir || getDuclawDataDir(), "kv", normalizePrefix(options.prefix || "agent"));
50279
+ const fileForKey = (key) => import_node_path5.default.join(rootDir, `${encodeKey(key)}.json`);
51035
50280
  return {
51036
50281
  async get(key) {
51037
50282
  try {
@@ -51511,7 +50756,7 @@ function createDefaultToolHookPlugins(extra = []) {
51511
50756
  }
51512
50757
 
51513
50758
  // src/tools/ToolExecutor.ts
51514
- var import_node_crypto7 = require("node:crypto");
50759
+ var import_node_crypto4 = require("node:crypto");
51515
50760
 
51516
50761
  // src/runtime/toolHooks.ts
51517
50762
  function sortToolHookPlugins(plugins = []) {
@@ -51676,8 +50921,8 @@ function summarizeText3(value, maxChars = 1e3) {
51676
50921
  return value.length <= maxChars ? value : `${value.slice(0, maxChars)}...`;
51677
50922
  }
51678
50923
  function runtimeEventId(type, toolName, toolCallId, startedAt) {
51679
- if (typeof import_node_crypto7.randomUUID === "function") return (0, import_node_crypto7.randomUUID)();
51680
- return (0, import_node_crypto7.createHash)("sha256").update(type).update("\0").update(toolName).update("\0").update(toolCallId ?? "").update("\0").update(startedAt.toISOString()).digest("hex");
50924
+ if (typeof import_node_crypto4.randomUUID === "function") return (0, import_node_crypto4.randomUUID)();
50925
+ return (0, import_node_crypto4.createHash)("sha256").update(type).update("\0").update(toolName).update("\0").update(toolCallId ?? "").update("\0").update(startedAt.toISOString()).digest("hex");
51681
50926
  }
51682
50927
 
51683
50928
  // src/tools/ToolRegistry.ts
@@ -51696,42 +50941,42 @@ var getAllTools = (registry2) => {
51696
50941
 
51697
50942
  // src/tools/tools/Bash.ts
51698
50943
  var import_node_child_process2 = require("node:child_process");
51699
- var import_node_crypto10 = require("node:crypto");
51700
- var import_node_fs8 = require("node:fs");
50944
+ var import_node_crypto7 = require("node:crypto");
50945
+ var import_node_fs7 = require("node:fs");
51701
50946
 
51702
50947
  // src/tools/utils/workspaceGuard.ts
51703
- var import_node_fs5 = require("node:fs");
51704
- var import_node_path8 = require("node:path");
51705
-
51706
- // src/runtime/sandbox/WorkspaceBroker.ts
51707
50948
  var import_node_fs4 = require("node:fs");
51708
50949
  var import_node_path7 = require("node:path");
50950
+
50951
+ // src/runtime/sandbox/WorkspaceBroker.ts
50952
+ var import_node_fs3 = require("node:fs");
50953
+ var import_node_path6 = require("node:path");
51709
50954
  var SANDBOX_WORKSPACE_PATH = "/workspace";
51710
50955
  var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
51711
50956
  var isInsidePath = (parentPath, childPath) => {
51712
- const rel = (0, import_node_path7.relative)(parentPath, childPath);
51713
- return rel === "" || !rel.startsWith("..") && !(0, import_node_path7.isAbsolute)(rel);
50957
+ const rel = (0, import_node_path6.relative)(parentPath, childPath);
50958
+ return rel === "" || !rel.startsWith("..") && !(0, import_node_path6.isAbsolute)(rel);
51714
50959
  };
51715
50960
  function createWorkspaceBroker(options) {
51716
- const hostWorkspacePath = (0, import_node_path7.resolve)(options.hostWorkspacePath);
51717
- const realHostWorkspacePath = import_node_fs4.realpathSync.native(hostWorkspacePath);
50961
+ const hostWorkspacePath = (0, import_node_path6.resolve)(options.hostWorkspacePath);
50962
+ const realHostWorkspacePath = import_node_fs3.realpathSync.native(hostWorkspacePath);
51718
50963
  const sandboxWorkspacePath = options.sandboxWorkspacePath ?? SANDBOX_WORKSPACE_PATH;
51719
50964
  const sandboxWorkspacePrefix = `${sandboxWorkspacePath}/`;
51720
50965
  const resolveForContainment = (path25) => {
51721
- const resolved = (0, import_node_path7.resolve)(path25);
50966
+ const resolved = (0, import_node_path6.resolve)(path25);
51722
50967
  let existingPath = resolved;
51723
- while (!(0, import_node_fs4.existsSync)(existingPath)) {
51724
- const parentPath = (0, import_node_path7.dirname)(existingPath);
50968
+ while (!(0, import_node_fs3.existsSync)(existingPath)) {
50969
+ const parentPath = (0, import_node_path6.dirname)(existingPath);
51725
50970
  if (parentPath === existingPath) {
51726
50971
  return null;
51727
50972
  }
51728
50973
  existingPath = parentPath;
51729
50974
  }
51730
- const realExistingPath = import_node_fs4.realpathSync.native(existingPath);
50975
+ const realExistingPath = import_node_fs3.realpathSync.native(existingPath);
51731
50976
  if (existingPath === resolved) {
51732
50977
  return realExistingPath;
51733
50978
  }
51734
- return (0, import_node_path7.resolve)(realExistingPath, (0, import_node_path7.relative)(existingPath, resolved));
50979
+ return (0, import_node_path6.resolve)(realExistingPath, (0, import_node_path6.relative)(existingPath, resolved));
51735
50980
  };
51736
50981
  const containsHostPath = (path25) => {
51737
50982
  const realPath = resolveForContainment(path25);
@@ -51745,28 +50990,28 @@ function createWorkspaceBroker(options) {
51745
50990
  if (realPath === null || !isInsidePath(realHostWorkspacePath, realPath)) {
51746
50991
  throw new Error(`\u8DEF\u5F84 ${path25} \u4E0D\u5728\u5F53\u524D workspace \u8303\u56F4\u5185`);
51747
50992
  }
51748
- const rel = (0, import_node_path7.relative)(realHostWorkspacePath, realPath);
51749
- if (rel.startsWith("..") || (0, import_node_path7.isAbsolute)(rel)) {
50993
+ const rel = (0, import_node_path6.relative)(realHostWorkspacePath, realPath);
50994
+ if (rel.startsWith("..") || (0, import_node_path6.isAbsolute)(rel)) {
51750
50995
  throw new Error(`\u8DEF\u5F84 ${path25} \u4E0D\u5728\u5F53\u524D workspace \u8303\u56F4\u5185`);
51751
50996
  }
51752
- return rel ? `${sandboxWorkspacePath}/${rel.split(import_node_path7.sep).join("/")}` : sandboxWorkspacePath;
50997
+ return rel ? `${sandboxWorkspacePath}/${rel.split(import_node_path6.sep).join("/")}` : sandboxWorkspacePath;
51753
50998
  };
51754
50999
  const toHostPath = (path25) => {
51755
51000
  if (path25 === sandboxWorkspacePath || path25.startsWith(sandboxWorkspacePrefix)) {
51756
51001
  const rel = path25 === sandboxWorkspacePath ? "" : path25.slice(sandboxWorkspacePrefix.length);
51757
- const hostPath2 = rel ? (0, import_node_path7.resolve)(hostWorkspacePath, rel) : hostWorkspacePath;
51002
+ const hostPath2 = rel ? (0, import_node_path6.resolve)(hostWorkspacePath, rel) : hostWorkspacePath;
51758
51003
  if (!containsHostPath(hostPath2)) {
51759
51004
  throw new Error(`\u8DEF\u5F84 ${path25} \u4E0D\u5728\u5F53\u524D workspace \u8303\u56F4\u5185`);
51760
51005
  }
51761
51006
  return hostPath2;
51762
51007
  }
51763
- if ((0, import_node_path7.isAbsolute)(path25)) {
51008
+ if ((0, import_node_path6.isAbsolute)(path25)) {
51764
51009
  if (!containsHostPath(path25)) {
51765
51010
  throw new Error(`\u8DEF\u5F84 ${path25} \u4E0D\u5728\u5F53\u524D workspace \u8303\u56F4\u5185`);
51766
51011
  }
51767
- return (0, import_node_path7.resolve)(path25);
51012
+ return (0, import_node_path6.resolve)(path25);
51768
51013
  }
51769
- const hostPath = (0, import_node_path7.resolve)(hostWorkspacePath, path25);
51014
+ const hostPath = (0, import_node_path6.resolve)(hostWorkspacePath, path25);
51770
51015
  if (!containsHostPath(hostPath)) {
51771
51016
  throw new Error(`\u8DEF\u5F84 ${path25} \u4E0D\u5728\u5F53\u524D workspace \u8303\u56F4\u5185`);
51772
51017
  }
@@ -51787,7 +51032,7 @@ function createWorkspaceBroker(options) {
51787
51032
  }
51788
51033
  };
51789
51034
  const redactHostPaths = (text2) => {
51790
- const normalizedHost = hostWorkspacePath.split(import_node_path7.sep).join("/");
51035
+ const normalizedHost = hostWorkspacePath.split(import_node_path6.sep).join("/");
51791
51036
  const escapedHost = escapeRegExp(normalizedHost);
51792
51037
  return text2.replace(new RegExp(`${escapedHost}(?=$|[\\s"',:;!?<>)]|/)(/[^\\s"',:;!?<>)]*)?`, "g"), (match2) => {
51793
51038
  const suffix = match2.slice(normalizedHost.length);
@@ -51836,15 +51081,15 @@ var redactWorkspaceToolOutput = (text2, workspacePath) => {
51836
51081
  }
51837
51082
  let output = text2;
51838
51083
  try {
51839
- output = redactWorkspacePath(output, import_node_fs5.realpathSync.native(workspacePath));
51084
+ output = redactWorkspacePath(output, import_node_fs4.realpathSync.native(workspacePath));
51840
51085
  } catch {
51841
51086
  }
51842
51087
  return redactWorkspacePath(output, workspacePath);
51843
51088
  };
51844
51089
  var normalizeToolPathForWorkspace = (toolPath, userRequest, access = "write") => {
51845
51090
  let resolvedPath = toolPath;
51846
- if (!(0, import_node_path8.isAbsolute)(resolvedPath)) {
51847
- resolvedPath = (0, import_node_path8.resolve)(getEffectiveCwd(userRequest), resolvedPath);
51091
+ if (!(0, import_node_path7.isAbsolute)(resolvedPath)) {
51092
+ resolvedPath = (0, import_node_path7.resolve)(getEffectiveCwd(userRequest), resolvedPath);
51848
51093
  }
51849
51094
  if (access === "read" && isReadAnyWriteReviewPolicy(userRequest)) {
51850
51095
  return resolvedPath;
@@ -51855,10 +51100,10 @@ var normalizeToolPathForWorkspace = (toolPath, userRequest, access = "write") =>
51855
51100
  return normalizeWorkspaceToolPath(resolvedPath, userRequest.workspacePath);
51856
51101
  };
51857
51102
  var normalizeHostToolPath = (toolPath, userRequest) => {
51858
- if ((0, import_node_path8.isAbsolute)(toolPath)) {
51103
+ if ((0, import_node_path7.isAbsolute)(toolPath)) {
51859
51104
  return toolPath;
51860
51105
  }
51861
- return (0, import_node_path8.resolve)(getEffectiveCwd(userRequest), toolPath);
51106
+ return (0, import_node_path7.resolve)(getEffectiveCwd(userRequest), toolPath);
51862
51107
  };
51863
51108
  var formatFileChangeSummary = (summary, workspacePath) => {
51864
51109
  const redactedSummary = {
@@ -52218,8 +51463,8 @@ var ToolPolicyEngine = class {
52218
51463
 
52219
51464
  // src/runtime/sandbox/DockerSandboxRuntime.ts
52220
51465
  var import_node_child_process = require("node:child_process");
52221
- var import_node_crypto8 = require("node:crypto");
52222
- var import_node_fs6 = require("node:fs");
51466
+ var import_node_crypto5 = require("node:crypto");
51467
+ var import_node_fs5 = require("node:fs");
52223
51468
  var DEFAULT_IMAGE = "duclaw-sandbox-runtime:phase2";
52224
51469
  var DEFAULT_CONTAINER_PREFIX = "duclaw-sandbox";
52225
51470
  var defaultCommandRunner = {
@@ -52232,7 +51477,7 @@ function createDockerSandboxRuntime(options = {}) {
52232
51477
  const commandRunner = options.commandRunner ?? defaultCommandRunner;
52233
51478
  return {
52234
51479
  async prepare(input) {
52235
- const hostWorkspacePath = import_node_fs6.realpathSync.native(input.hostWorkspacePath);
51480
+ const hostWorkspacePath = import_node_fs5.realpathSync.native(input.hostWorkspacePath);
52236
51481
  const id = containerName(containerNamePrefix, hostWorkspacePath);
52237
51482
  const session = {
52238
51483
  id,
@@ -52284,7 +51529,7 @@ function createDockerSandboxRuntime(options = {}) {
52284
51529
  };
52285
51530
  }
52286
51531
  function containerName(prefix, hostWorkspacePath) {
52287
- const hash = (0, import_node_crypto8.createHash)("sha256").update(hostWorkspacePath).digest("hex").slice(0, 16);
51532
+ const hash = (0, import_node_crypto5.createHash)("sha256").update(hostWorkspacePath).digest("hex").slice(0, 16);
52288
51533
  return `${prefix}-${hash}`;
52289
51534
  }
52290
51535
  function inspectContainer(commandRunner, containerId) {
@@ -52302,9 +51547,9 @@ function inspectContainer(commandRunner, containerId) {
52302
51547
  }
52303
51548
 
52304
51549
  // src/runtime/sandbox/SandboxReviewStore.ts
52305
- var import_node_crypto9 = require("node:crypto");
52306
- var import_node_fs7 = require("node:fs");
52307
- var import_node_path9 = require("node:path");
51550
+ var import_node_crypto6 = require("node:crypto");
51551
+ var import_node_fs6 = require("node:fs");
51552
+ var import_node_path8 = require("node:path");
52308
51553
  var import_node_os2 = require("node:os");
52309
51554
 
52310
51555
  // node_modules/.pnpm/diff@8.0.3/node_modules/diff/libesm/diff/base.js
@@ -52738,7 +51983,7 @@ function splitLines(text2) {
52738
51983
  }
52739
51984
 
52740
51985
  // src/runtime/sandbox/SandboxReviewStore.ts
52741
- var DEFAULT_ROOT = (0, import_node_path9.join)((0, import_node_os2.tmpdir)(), "duclaw-sandbox-reviews");
51986
+ var DEFAULT_ROOT = (0, import_node_path8.join)((0, import_node_os2.tmpdir)(), "duclaw-sandbox-reviews");
52742
51987
  var defaultStore = null;
52743
51988
  function getDefaultSandboxReviewStore() {
52744
51989
  if (defaultStore === null) {
@@ -52747,23 +51992,23 @@ function getDefaultSandboxReviewStore() {
52747
51992
  return defaultStore;
52748
51993
  }
52749
51994
  function createSandboxReviewStore(options = {}) {
52750
- const rootDir = (0, import_node_path9.resolve)(options.rootDir ?? DEFAULT_ROOT);
51995
+ const rootDir = (0, import_node_path8.resolve)(options.rootDir ?? DEFAULT_ROOT);
52751
51996
  const reviews = /* @__PURE__ */ new Map();
52752
51997
  const createReview = async (input) => {
52753
- const id = (0, import_node_crypto9.randomUUID)();
52754
- const hostWorkspacePath = (0, import_node_path9.resolve)(input.hostWorkspacePath ?? rootDir);
52755
- const overlayWorkspacePath = (0, import_node_path9.join)(rootDir, id, "workspace");
51998
+ const id = (0, import_node_crypto6.randomUUID)();
51999
+ const hostWorkspacePath = (0, import_node_path8.resolve)(input.hostWorkspacePath ?? rootDir);
52000
+ const overlayWorkspacePath = (0, import_node_path8.join)(rootDir, id, "workspace");
52756
52001
  const includedRelativePaths = input.includedRelativePaths?.map(normalizeRelativePath);
52757
- (0, import_node_fs7.mkdirSync)((0, import_node_path9.dirname)(overlayWorkspacePath), { recursive: true });
52758
- (0, import_node_fs7.mkdirSync)(overlayWorkspacePath, { recursive: true });
52002
+ (0, import_node_fs6.mkdirSync)((0, import_node_path8.dirname)(overlayWorkspacePath), { recursive: true });
52003
+ (0, import_node_fs6.mkdirSync)(overlayWorkspacePath, { recursive: true });
52759
52004
  if (input.hostWorkspacePath === void 0) {
52760
52005
  } else if (includedRelativePaths && includedRelativePaths.length > 0) {
52761
52006
  for (const relativePath of includedRelativePaths) {
52762
- const sourcePath = (0, import_node_path9.join)(hostWorkspacePath, relativePath);
52763
- const targetPath = (0, import_node_path9.join)(overlayWorkspacePath, relativePath);
52764
- if (!(0, import_node_fs7.existsSync)(sourcePath)) continue;
52765
- (0, import_node_fs7.mkdirSync)((0, import_node_path9.dirname)(targetPath), { recursive: true });
52766
- (0, import_node_fs7.cpSync)(sourcePath, targetPath, {
52007
+ const sourcePath = (0, import_node_path8.join)(hostWorkspacePath, relativePath);
52008
+ const targetPath = (0, import_node_path8.join)(overlayWorkspacePath, relativePath);
52009
+ if (!(0, import_node_fs6.existsSync)(sourcePath)) continue;
52010
+ (0, import_node_fs6.mkdirSync)((0, import_node_path8.dirname)(targetPath), { recursive: true });
52011
+ (0, import_node_fs6.cpSync)(sourcePath, targetPath, {
52767
52012
  recursive: true,
52768
52013
  dereference: false,
52769
52014
  force: true,
@@ -52771,7 +52016,7 @@ function createSandboxReviewStore(options = {}) {
52771
52016
  });
52772
52017
  }
52773
52018
  } else {
52774
- (0, import_node_fs7.cpSync)(hostWorkspacePath, overlayWorkspacePath, {
52019
+ (0, import_node_fs6.cpSync)(hostWorkspacePath, overlayWorkspacePath, {
52775
52020
  recursive: true,
52776
52021
  dereference: false,
52777
52022
  force: true,
@@ -52820,15 +52065,15 @@ function createSandboxReviewStore(options = {}) {
52820
52065
  }
52821
52066
  for (const change of review.changes) {
52822
52067
  if (change.action === "deleted") {
52823
- (0, import_node_fs7.rmSync)(change.hostPath, { recursive: true, force: true });
52068
+ (0, import_node_fs6.rmSync)(change.hostPath, { recursive: true, force: true });
52824
52069
  continue;
52825
52070
  }
52826
- (0, import_node_fs7.mkdirSync)((0, import_node_path9.dirname)(change.hostPath), { recursive: true });
52827
- (0, import_node_fs7.copyFileSync)(change.overlayPath, change.hostPath);
52071
+ (0, import_node_fs6.mkdirSync)((0, import_node_path8.dirname)(change.hostPath), { recursive: true });
52072
+ (0, import_node_fs6.copyFileSync)(change.overlayPath, change.hostPath);
52828
52073
  }
52829
52074
  review.status = "approved";
52830
52075
  review.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
52831
- (0, import_node_fs7.rmSync)((0, import_node_path9.dirname)(review.overlayWorkspacePath), { recursive: true, force: true });
52076
+ (0, import_node_fs6.rmSync)((0, import_node_path8.dirname)(review.overlayWorkspacePath), { recursive: true, force: true });
52832
52077
  return review;
52833
52078
  },
52834
52079
  async rejectReview(id) {
@@ -52836,7 +52081,7 @@ function createSandboxReviewStore(options = {}) {
52836
52081
  if (review.status !== "pending") return review;
52837
52082
  review.status = "rejected";
52838
52083
  review.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
52839
- (0, import_node_fs7.rmSync)((0, import_node_path9.dirname)(review.overlayWorkspacePath), { recursive: true, force: true });
52084
+ (0, import_node_fs6.rmSync)((0, import_node_path8.dirname)(review.overlayWorkspacePath), { recursive: true, force: true });
52840
52085
  return review;
52841
52086
  }
52842
52087
  };
@@ -52846,7 +52091,7 @@ function hasConflict(change) {
52846
52091
  return currentHash !== change.baseHash;
52847
52092
  }
52848
52093
  function normalizeRelativePath(relativePath) {
52849
- return relativePath.split(import_node_path9.sep).join("/");
52094
+ return relativePath.split(import_node_path8.sep).join("/");
52850
52095
  }
52851
52096
  function diffWorkspaces(hostWorkspacePath, overlayWorkspacePath, includedRelativePaths) {
52852
52097
  const broker = createWorkspaceBroker({ hostWorkspacePath });
@@ -52854,8 +52099,8 @@ function diffWorkspaces(hostWorkspacePath, overlayWorkspacePath, includedRelativ
52854
52099
  const overlayFiles = includedRelativePaths ?? listFiles(overlayWorkspacePath);
52855
52100
  const allRelativePaths = [.../* @__PURE__ */ new Set([...hostFiles, ...overlayFiles])].sort();
52856
52101
  return allRelativePaths.flatMap((relativePath) => {
52857
- const hostPath = (0, import_node_path9.join)(hostWorkspacePath, relativePath);
52858
- const overlayPath = (0, import_node_path9.join)(overlayWorkspacePath, relativePath);
52102
+ const hostPath = (0, import_node_path8.join)(hostWorkspacePath, relativePath);
52103
+ const overlayPath = (0, import_node_path8.join)(overlayWorkspacePath, relativePath);
52859
52104
  const baseHash = fileHash(hostPath);
52860
52105
  const overlayHash = fileHash(overlayPath);
52861
52106
  if (baseHash === overlayHash) {
@@ -52875,17 +52120,17 @@ function diffWorkspaces(hostWorkspacePath, overlayWorkspacePath, includedRelativ
52875
52120
  });
52876
52121
  }
52877
52122
  function listFiles(root) {
52878
- if (!(0, import_node_fs7.existsSync)(root)) return [];
52123
+ if (!(0, import_node_fs6.existsSync)(root)) return [];
52879
52124
  const result = [];
52880
52125
  const visit = (dir) => {
52881
- for (const entry of (0, import_node_fs7.readdirSync)(dir, { withFileTypes: true })) {
52882
- const fullPath = (0, import_node_path9.join)(dir, entry.name);
52126
+ for (const entry of (0, import_node_fs6.readdirSync)(dir, { withFileTypes: true })) {
52127
+ const fullPath = (0, import_node_path8.join)(dir, entry.name);
52883
52128
  if (entry.isDirectory()) {
52884
52129
  visit(fullPath);
52885
52130
  continue;
52886
52131
  }
52887
52132
  if (entry.isFile()) {
52888
- result.push((0, import_node_path9.relative)(root, fullPath).split(import_node_path9.sep).join("/"));
52133
+ result.push((0, import_node_path8.relative)(root, fullPath).split(import_node_path8.sep).join("/"));
52889
52134
  }
52890
52135
  }
52891
52136
  };
@@ -52893,14 +52138,14 @@ function listFiles(root) {
52893
52138
  return result.sort();
52894
52139
  }
52895
52140
  function fileHash(filePath) {
52896
- if (!(0, import_node_fs7.existsSync)(filePath)) return null;
52897
- const stat15 = (0, import_node_fs7.statSync)(filePath);
52141
+ if (!(0, import_node_fs6.existsSync)(filePath)) return null;
52142
+ const stat15 = (0, import_node_fs6.statSync)(filePath);
52898
52143
  if (!stat15.isFile()) return null;
52899
- return (0, import_node_crypto9.createHash)("sha256").update((0, import_node_fs7.readFileSync)(filePath)).digest("hex");
52144
+ return (0, import_node_crypto6.createHash)("sha256").update((0, import_node_fs6.readFileSync)(filePath)).digest("hex");
52900
52145
  }
52901
52146
  function readText(filePath) {
52902
- if (!(0, import_node_fs7.existsSync)(filePath)) return "";
52903
- return (0, import_node_fs7.readFileSync)(filePath, "utf-8");
52147
+ if (!(0, import_node_fs6.existsSync)(filePath)) return "";
52148
+ return (0, import_node_fs6.readFileSync)(filePath, "utf-8");
52904
52149
  }
52905
52150
  function createRedactedPatch(action, sandboxPath, hostPath, overlayPath) {
52906
52151
  const oldText = action === "created" ? "" : readText(hostPath);
@@ -52909,10 +52154,10 @@ function createRedactedPatch(action, sandboxPath, hostPath, overlayPath) {
52909
52154
  }
52910
52155
 
52911
52156
  // src/tools/tools/Bash.ts
52912
- var import_node_path11 = require("node:path");
52157
+ var import_node_path10 = require("node:path");
52913
52158
 
52914
52159
  // src/tools/utils/localSandboxReview.ts
52915
- var import_node_path10 = require("node:path");
52160
+ var import_node_path9 = require("node:path");
52916
52161
  var shouldStageWriteReview = (userRequest) => {
52917
52162
  return shouldAskLocalSandboxPermission(userRequest);
52918
52163
  };
@@ -52924,15 +52169,15 @@ var resolveReviewHostPath = (filePath, userRequest) => {
52924
52169
  };
52925
52170
  async function stageSingleFileSandboxReview(input) {
52926
52171
  const hostPath = resolveReviewHostPath(input.filePath, input.userRequest);
52927
- const relativePath = (0, import_node_path10.basename)(hostPath);
52172
+ const relativePath = (0, import_node_path9.basename)(hostPath);
52928
52173
  return getDefaultSandboxReviewStore().createReview({
52929
- hostWorkspacePath: (0, import_node_path10.dirname)(hostPath),
52174
+ hostWorkspacePath: (0, import_node_path9.dirname)(hostPath),
52930
52175
  includedRelativePaths: [relativePath],
52931
52176
  toolName: input.toolName,
52932
52177
  command: input.command,
52933
52178
  reason: input.reason ?? "host_write",
52934
52179
  mutateOverlay: async ({ overlayWorkspacePath }) => {
52935
- await input.mutateOverlayFile((0, import_node_path10.join)(overlayWorkspacePath, relativePath));
52180
+ await input.mutateOverlayFile((0, import_node_path9.join)(overlayWorkspacePath, relativePath));
52936
52181
  }
52937
52182
  });
52938
52183
  }
@@ -52973,7 +52218,7 @@ function formatPendingReviewMessage(review) {
52973
52218
  }
52974
52219
 
52975
52220
  // src/tools/tools/Bash.ts
52976
- var DESCRIPTION2 = `\u5728\u7CFB\u7EDF shell \u4E2D\u6267\u884C\u547D\u4EE4\u3002
52221
+ var DESCRIPTION = `\u5728\u7CFB\u7EDF shell \u4E2D\u6267\u884C\u547D\u4EE4\u3002
52977
52222
 
52978
52223
  \u7528\u9014\uFF1A
52979
52224
  - \u8FD0\u884C shell \u547D\u4EE4\uFF08\u5982 ls\u3001mkdir\u3001npm\u3001git\u3001rg \u7B49\uFF09
@@ -53025,7 +52270,7 @@ var sandboxRuntimeFactory = null;
53025
52270
  function findExecutableShell2() {
53026
52271
  for (const shell of SHELL_CANDIDATES2) {
53027
52272
  try {
53028
- (0, import_node_fs8.accessSync)(shell, import_node_fs8.constants.X_OK);
52273
+ (0, import_node_fs7.accessSync)(shell, import_node_fs7.constants.X_OK);
53029
52274
  return shell;
53030
52275
  } catch {
53031
52276
  }
@@ -53034,11 +52279,11 @@ function findExecutableShell2() {
53034
52279
  }
53035
52280
  function validateCwd(cwd) {
53036
52281
  try {
53037
- const stat15 = (0, import_node_fs8.statSync)(cwd);
52282
+ const stat15 = (0, import_node_fs7.statSync)(cwd);
53038
52283
  if (!stat15.isDirectory()) {
53039
52284
  return `[bash] \u9519\u8BEF: cwd \u4E0D\u662F\u76EE\u5F55: ${cwd}`;
53040
52285
  }
53041
- (0, import_node_fs8.accessSync)(cwd, import_node_fs8.constants.R_OK | import_node_fs8.constants.X_OK);
52286
+ (0, import_node_fs7.accessSync)(cwd, import_node_fs7.constants.R_OK | import_node_fs7.constants.X_OK);
53042
52287
  return null;
53043
52288
  } catch (err) {
53044
52289
  const code = err.code;
@@ -53197,15 +52442,15 @@ function redactBashOutput(text2, workspacePath) {
53197
52442
  if (!workspacePath) return text2;
53198
52443
  let output = text2;
53199
52444
  try {
53200
- output = redactWorkspacePath(output, import_node_fs8.realpathSync.native(workspacePath));
52445
+ output = redactWorkspacePath(output, import_node_fs7.realpathSync.native(workspacePath));
53201
52446
  } catch {
53202
52447
  }
53203
52448
  return redactWorkspacePath(output, workspacePath);
53204
52449
  }
53205
52450
  function toOverlayCwd(hostCwd, hostWorkspacePath, overlayWorkspacePath) {
53206
- const rel = (0, import_node_path11.relative)(import_node_fs8.realpathSync.native(hostWorkspacePath), import_node_fs8.realpathSync.native(hostCwd));
52451
+ const rel = (0, import_node_path10.relative)(import_node_fs7.realpathSync.native(hostWorkspacePath), import_node_fs7.realpathSync.native(hostCwd));
53207
52452
  if (!rel || rel === "") return overlayWorkspacePath;
53208
- return (0, import_node_path11.join)(overlayWorkspacePath, rel.split(import_node_path11.sep).join("/"));
52453
+ return (0, import_node_path10.join)(overlayWorkspacePath, rel.split(import_node_path10.sep).join("/"));
53209
52454
  }
53210
52455
  function commandForOverlay(command, overlayWorkspacePath) {
53211
52456
  return command.replaceAll("/workspace", overlayWorkspacePath);
@@ -53287,7 +52532,7 @@ function waitForClose(session, waitMs) {
53287
52532
  }
53288
52533
  var bashTool = {
53289
52534
  name: `bash`,
53290
- description: DESCRIPTION2,
52535
+ description: DESCRIPTION,
53291
52536
  input_schema: {
53292
52537
  type: `object`,
53293
52538
  properties: {
@@ -53461,7 +52706,7 @@ ${reviewStdout}</command-output>` : "";
53461
52706
  detached: process.platform !== "win32"
53462
52707
  });
53463
52708
  }
53464
- const id = (0, import_node_crypto10.randomUUID)().slice(0, 8);
52709
+ const id = (0, import_node_crypto7.randomUUID)().slice(0, 8);
53465
52710
  const session = {
53466
52711
  id,
53467
52712
  command,
@@ -53508,7 +52753,7 @@ ${reviewStdout}</command-output>` : "";
53508
52753
  };
53509
52754
 
53510
52755
  // src/tools/tools/CodeSearch.ts
53511
- var DESCRIPTION3 = `
52756
+ var DESCRIPTION2 = `
53512
52757
  - Search and get relevant context for any programming task using Exa Code API
53513
52758
  - Provides the highest quality and freshest context for libraries, SDKs, and APIs
53514
52759
  - Use this tool for ANY question or task related to programming
@@ -53530,7 +52775,7 @@ var API_CONFIG = {
53530
52775
  };
53531
52776
  var codeSearchTool = {
53532
52777
  name: "codesearch",
53533
- description: DESCRIPTION3,
52778
+ description: DESCRIPTION2,
53534
52779
  input_schema: {
53535
52780
  type: "object",
53536
52781
  properties: {
@@ -53632,7 +52877,7 @@ var dateTool = {
53632
52877
 
53633
52878
  // src/tools/tools/Edit.ts
53634
52879
  var import_promises7 = require("node:fs/promises");
53635
- var DESCRIPTION4 = `Performs exact string replacements in files.
52880
+ var DESCRIPTION3 = `Performs exact string replacements in files.
53636
52881
 
53637
52882
  Usage:
53638
52883
  - You MUST use the Read tool first to read the file's contents before editing.
@@ -53995,7 +53240,7 @@ function trimDiff(diff) {
53995
53240
  }
53996
53241
  var editTool = {
53997
53242
  name: "edit",
53998
- description: DESCRIPTION4,
53243
+ description: DESCRIPTION3,
53999
53244
  input_schema: {
54000
53245
  type: "object",
54001
53246
  properties: {
@@ -54130,9 +53375,9 @@ ${changeSummary}`, userRequest?.workspacePath);
54130
53375
  };
54131
53376
 
54132
53377
  // src/tools/tools/Glob.ts
54133
- var import_node_path12 = require("node:path");
53378
+ var import_node_path11 = require("node:path");
54134
53379
  var import_promises8 = require("node:fs/promises");
54135
- var DESCRIPTION5 = `\u5FEB\u901F\u6587\u4EF6\u6A21\u5F0F\u5339\u914D\u5DE5\u5177\uFF0C\u652F\u6301 glob \u6A21\u5F0F\uFF08\u5982 "**/*.ts"\u3001"src/**/*.js"\uFF09\u3002
53380
+ var DESCRIPTION4 = `\u5FEB\u901F\u6587\u4EF6\u6A21\u5F0F\u5339\u914D\u5DE5\u5177\uFF0C\u652F\u6301 glob \u6A21\u5F0F\uFF08\u5982 "**/*.ts"\u3001"src/**/*.js"\uFF09\u3002
54136
53381
  \u8FD4\u56DE\u5339\u914D\u7684\u6587\u4EF6\u8DEF\u5F84\u5217\u8868\uFF0C\u6309\u4FEE\u6539\u65F6\u95F4\u5012\u5E8F\u6392\u5217\u3002\u9002\u7528\u4E8E\u6309\u540D\u79F0\u6A21\u5F0F\u67E5\u627E\u6587\u4EF6\u7684\u573A\u666F\u3002`;
54137
53382
  function globToRegex(pattern) {
54138
53383
  let regex = "";
@@ -54160,7 +53405,7 @@ function globToRegex(pattern) {
54160
53405
  }
54161
53406
  var globTool = {
54162
53407
  name: "glob",
54163
- description: DESCRIPTION5,
53408
+ description: DESCRIPTION4,
54164
53409
  input_schema: {
54165
53410
  type: "object",
54166
53411
  properties: {
@@ -54199,7 +53444,7 @@ var globTool = {
54199
53444
  for (const entry of entries) {
54200
53445
  const normalized = entry.replace(/\\/g, "/");
54201
53446
  if (!regex.test(normalized)) continue;
54202
- const fullPath = (0, import_node_path12.resolve)(resolvedDir, entry);
53447
+ const fullPath = (0, import_node_path11.resolve)(resolvedDir, entry);
54203
53448
  try {
54204
53449
  const s = await (0, import_promises8.stat)(fullPath);
54205
53450
  if (!s.isFile()) continue;
@@ -54222,10 +53467,10 @@ var globTool = {
54222
53467
  };
54223
53468
 
54224
53469
  // src/tools/tools/Grep.ts
54225
- var import_node_path13 = require("node:path");
53470
+ var import_node_path12 = require("node:path");
54226
53471
  var import_promises9 = require("node:fs/promises");
54227
53472
  var MAX_LINE_LENGTH = 2e3;
54228
- var DESCRIPTION6 = `
53473
+ var DESCRIPTION5 = `
54229
53474
  - Fast content search tool that works with any codebase size
54230
53475
  - Searches file contents using regular expressions
54231
53476
  - Supports full regex syntax (eg. "log.*Error", "functions+w+", etc.)
@@ -54270,7 +53515,7 @@ function includeToRegex(pattern) {
54270
53515
  }
54271
53516
  var grepTool = {
54272
53517
  name: "grep",
54273
- description: DESCRIPTION6,
53518
+ description: DESCRIPTION5,
54274
53519
  input_schema: {
54275
53520
  type: "object",
54276
53521
  properties: {
@@ -54325,7 +53570,7 @@ var grepTool = {
54325
53570
  const fileName = normalized.split("/").pop() || normalized;
54326
53571
  if (!includeRegex.test(fileName)) continue;
54327
53572
  }
54328
- const fullPath = (0, import_node_path13.resolve)(resolvedDir, entry);
53573
+ const fullPath = (0, import_node_path12.resolve)(resolvedDir, entry);
54329
53574
  let s;
54330
53575
  try {
54331
53576
  s = await (0, import_promises9.stat)(fullPath);
@@ -54380,12 +53625,192 @@ var grepTool = {
54380
53625
  var import_promises10 = require("node:fs/promises");
54381
53626
  var import_node_path14 = __toESM(require("node:path"));
54382
53627
  var import_node_zlib = require("node:zlib");
53628
+
53629
+ // src/attachments/attachmentContext.ts
53630
+ var import_node_crypto8 = require("node:crypto");
53631
+ var import_node_fs8 = require("node:fs");
53632
+ var import_node_path13 = require("node:path");
53633
+ var MAX_ATTACHMENT_RECORDS = 100;
53634
+ var RECENT_ATTACHMENT_LIMIT = 5;
53635
+ function makeAttachmentId(input) {
53636
+ const raw2 = [
53637
+ input.userId,
53638
+ input.platform,
53639
+ input.messageId,
53640
+ input.resourceKey,
53641
+ input.kind
53642
+ ].join(":");
53643
+ const digest = (0, import_node_crypto8.createHash)("sha256").update(raw2).digest("hex").slice(0, 16);
53644
+ return `att_${input.kind === "image" ? "img" : "file"}_${digest}`;
53645
+ }
53646
+ function indexPath(userId) {
53647
+ return (0, import_node_path13.join)(getDuclawWorkspaceDir(), userId, "attachments", "index.json");
53648
+ }
53649
+ function readIndex(userId) {
53650
+ const filePath = indexPath(userId);
53651
+ if (!(0, import_node_fs8.existsSync)(filePath)) return [];
53652
+ try {
53653
+ const parsed = JSON.parse((0, import_node_fs8.readFileSync)(filePath, "utf8"));
53654
+ return Array.isArray(parsed) ? parsed.filter(isAttachmentRecord) : [];
53655
+ } catch (error) {
53656
+ console.warn(`[attachments] failed to read attachment index: ${error.message}`);
53657
+ return [];
53658
+ }
53659
+ }
53660
+ function writeIndex(userId, records) {
53661
+ const filePath = indexPath(userId);
53662
+ (0, import_node_fs8.mkdirSync)((0, import_node_path13.dirname)(filePath), { recursive: true });
53663
+ (0, import_node_fs8.writeFileSync)(filePath, JSON.stringify(records.slice(0, MAX_ATTACHMENT_RECORDS), null, 2));
53664
+ }
53665
+ function isAttachmentRecord(value) {
53666
+ const record2 = value;
53667
+ return Boolean(record2) && typeof record2.id === "string" && (record2.kind === "image" || record2.kind === "file") && typeof record2.userId === "string" && typeof record2.pathOrUrl === "string";
53668
+ }
53669
+ function stringValue(value) {
53670
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
53671
+ }
53672
+ function attachmentKind(value) {
53673
+ const type = stringValue(value.type);
53674
+ const mimeType = stringValue(value.mimeType);
53675
+ const name = stringValue(value.name) ?? stringValue(value.path) ?? stringValue(value.url) ?? "";
53676
+ if (type === "image" || mimeType?.startsWith("image/") || /\.(png|jpe?g|gif|webp)$/i.test(name)) {
53677
+ return "image";
53678
+ }
53679
+ return "file";
53680
+ }
53681
+ function xmlEscape(value) {
53682
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
53683
+ }
53684
+ function upsertAttachments(userId, records) {
53685
+ if (records.length === 0) return;
53686
+ const existing = readIndex(userId);
53687
+ const byId = /* @__PURE__ */ new Map();
53688
+ for (const record2 of [...records, ...existing]) {
53689
+ if (!byId.has(record2.id)) byId.set(record2.id, record2);
53690
+ }
53691
+ writeIndex(userId, Array.from(byId.values()).sort((a, b) => b.receivedAt.localeCompare(a.receivedAt)));
53692
+ }
53693
+ function listRecentAttachments(userId, limit = RECENT_ATTACHMENT_LIMIT) {
53694
+ return readIndex(userId).sort((a, b) => b.receivedAt.localeCompare(a.receivedAt)).slice(0, limit);
53695
+ }
53696
+ function resolveAttachmentPathOrUrl(userId, attachmentId) {
53697
+ return readIndex(userId).find((record2) => record2.id === attachmentId)?.pathOrUrl;
53698
+ }
53699
+ function collectAttachmentsFromRequest(request) {
53700
+ const metadata = request.metadata ?? {};
53701
+ const platform = request.platform || "unknown";
53702
+ const messageId = request.requestId;
53703
+ const receivedAt = (/* @__PURE__ */ new Date()).toISOString();
53704
+ const records = [];
53705
+ const seen = /* @__PURE__ */ new Set();
53706
+ const addRecord = (input) => {
53707
+ if (!input.pathOrUrl) return;
53708
+ const id = makeAttachmentId({
53709
+ userId: request.userId,
53710
+ platform,
53711
+ messageId,
53712
+ resourceKey: input.resourceKey,
53713
+ kind: input.kind
53714
+ });
53715
+ if (seen.has(id)) return;
53716
+ seen.add(id);
53717
+ records.push({
53718
+ id,
53719
+ kind: input.kind,
53720
+ platform,
53721
+ userId: request.userId,
53722
+ messageId,
53723
+ resourceKey: input.resourceKey,
53724
+ pathOrUrl: input.pathOrUrl,
53725
+ name: input.name,
53726
+ mimeType: input.mimeType,
53727
+ source: input.source,
53728
+ receivedAt
53729
+ });
53730
+ };
53731
+ const imageUrl = stringValue(metadata.imageUrl);
53732
+ const imageKey = stringValue(metadata.imageKey);
53733
+ if (imageUrl && imageKey) {
53734
+ addRecord({
53735
+ kind: "image",
53736
+ resourceKey: imageKey,
53737
+ pathOrUrl: imageUrl,
53738
+ source: `${platform}_metadata`
53739
+ });
53740
+ }
53741
+ const fileUrl = stringValue(metadata.fileUrl);
53742
+ const fileName = stringValue(metadata.fileName);
53743
+ if (fileUrl && fileName) {
53744
+ addRecord({
53745
+ kind: "file",
53746
+ resourceKey: fileName,
53747
+ pathOrUrl: fileUrl,
53748
+ name: fileName,
53749
+ source: `${platform}_metadata`
53750
+ });
53751
+ }
53752
+ const attachments = Array.isArray(metadata.attachments) ? metadata.attachments : [];
53753
+ for (const attachment of attachments) {
53754
+ const resourceKey = stringValue(attachment.id) ?? stringValue(attachment.name);
53755
+ const pathOrUrl = stringValue(attachment.url) ?? stringValue(attachment.path);
53756
+ if (!resourceKey || !pathOrUrl) continue;
53757
+ addRecord({
53758
+ kind: attachmentKind(attachment),
53759
+ resourceKey,
53760
+ pathOrUrl,
53761
+ name: stringValue(attachment.name),
53762
+ mimeType: stringValue(attachment.mimeType),
53763
+ source: `${platform}_attachment`
53764
+ });
53765
+ }
53766
+ return records;
53767
+ }
53768
+ function buildAttachmentContextXml(records) {
53769
+ if (records.length === 0) return "";
53770
+ const lines = [
53771
+ `<recent-attachments>`,
53772
+ ` <system-note>Recent attachments are available assets, not automatic task inputs. Use attachment_id only when the current user message explicitly refers to an attachment/image/file, asks to use previous assets, or says \u56FE\u4E00/\u56FE\u4E8C/\u7B2C\u4E00\u5F20/\u7B2C\u4E8C\u5F20. If the current request is unrelated pure text, Do not call image_understand or image_generate just because recent attachments are listed. Do not invent or reproduce long URLs; tools can resolve the real file source from attachment_id. \u56FE\u4E00/\u7B2C\u4E00\u5F20\u56FE\u7247 maps to image number 1, \u56FE\u4E8C/\u7B2C\u4E8C\u5F20\u56FE\u7247 maps to image number 2, following the order below. For image_generate edits, put the destination/base image in target_attachment_id or attachment_id, and put source/reference/material images in reference_attachment_id(s).</system-note>`
53773
+ ];
53774
+ for (const [index, record2] of records.entries()) {
53775
+ lines.push(` <${record2.kind} id="${xmlEscape(record2.id)}">`);
53776
+ lines.push(` <number>${index + 1}</number>`);
53777
+ lines.push(` <source>${xmlEscape(record2.source ?? record2.platform)}</source>`);
53778
+ lines.push(` <message_id>${xmlEscape(record2.messageId)}</message_id>`);
53779
+ lines.push(` <resource_key>${xmlEscape(record2.resourceKey)}</resource_key>`);
53780
+ if (record2.name) lines.push(` <name>${xmlEscape(record2.name)}</name>`);
53781
+ if (record2.mimeType) lines.push(` <mime_type>${xmlEscape(record2.mimeType)}</mime_type>`);
53782
+ lines.push(` <received_at>${xmlEscape(record2.receivedAt)}</received_at>`);
53783
+ lines.push(` </${record2.kind}>`);
53784
+ }
53785
+ lines.push(`</recent-attachments>`);
53786
+ return lines.join("\n");
53787
+ }
53788
+ function attachRecentAttachmentContext(request, content) {
53789
+ const current = collectAttachmentsFromRequest(request);
53790
+ if (current.length > 0) {
53791
+ upsertAttachments(request.userId, current);
53792
+ request.metadata = {
53793
+ ...request.metadata ?? {},
53794
+ attachmentIds: current.map((record2) => record2.id),
53795
+ attachmentId: current[0]?.id
53796
+ };
53797
+ }
53798
+ const context = buildAttachmentContextXml(listRecentAttachments(request.userId));
53799
+ if (!context) return content;
53800
+ return `${content}
53801
+
53802
+ <system-reminder>
53803
+ ${context}
53804
+ </system-reminder>`;
53805
+ }
53806
+
53807
+ // src/tools/tools/ImageGenerate.ts
54383
53808
  var DEFAULT_BASE_URL = "https://direct.shanyiapi.com";
54384
53809
  var DEFAULT_MODEL = "gpt-image-2";
54385
53810
  var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([403, 429, 500, 502, 503, 504, 524]);
54386
53811
  var MAX_RETRIES = 3;
54387
53812
  var RETRY_BACKOFF_BASE_MS = 5e3;
54388
- var DESCRIPTION7 = `
53813
+ var DESCRIPTION6 = `
54389
53814
  Generate images with the platform-configured Shanyi/NewAPI image provider.
54390
53815
 
54391
53816
  Use this when the user asks to create, draw, render, or generate a new image, and when they ask to edit, composite, transform, or preserve an existing image with GPT Image edits. Use this for image tasks where original image assets, pixels, layout, identity, object placement, or visual references matter.
@@ -54780,7 +54205,7 @@ function appendImageFile(form, field, source) {
54780
54205
  }
54781
54206
  var imageGenerate = {
54782
54207
  name: "image_generate",
54783
- description: DESCRIPTION7,
54208
+ description: DESCRIPTION6,
54784
54209
  input_schema: {
54785
54210
  type: "object",
54786
54211
  properties: {
@@ -55047,10 +54472,10 @@ var imageGenerate = {
55047
54472
  };
55048
54473
 
55049
54474
  // src/tools/tools/ImageUnderstand.ts
55050
- var import_fs9 = __toESM(require("fs"));
54475
+ var import_fs7 = __toESM(require("fs"));
55051
54476
 
55052
54477
  // src/tools/tools/ImageUnderstandMetering.ts
55053
- var import_node_crypto11 = require("node:crypto");
54478
+ var import_node_crypto9 = require("node:crypto");
55054
54479
  var ImageUnderstandMeteringError = class extends Error {
55055
54480
  constructor(message, statusCode, meteringStatus) {
55056
54481
  super(message);
@@ -55140,7 +54565,7 @@ function inferImageProvider(baseUrl) {
55140
54565
  }
55141
54566
  }
55142
54567
  function fingerprintImageSource(imageSource) {
55143
- return (0, import_node_crypto11.createHash)("sha256").update(imageSource).digest("hex");
54568
+ return (0, import_node_crypto9.createHash)("sha256").update(imageSource).digest("hex");
55144
54569
  }
55145
54570
  function imageSourceKind(imageSource) {
55146
54571
  if (imageSource.startsWith("http://") || imageSource.startsWith("https://")) return "url";
@@ -55243,9 +54668,9 @@ var resolveImageBlock = async (input) => {
55243
54668
  return imageBlockFromBuffer(buffer, contentType, remoteUrl);
55244
54669
  }
55245
54670
  if (input.startsWith("/") || input.startsWith(".") || /^[A-Za-z]:[\\/]/.test(input)) {
55246
- if (!import_fs9.default.existsSync(input)) throw new Error(`[ImageUnderstand] \u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728: ${input}`);
54671
+ if (!import_fs7.default.existsSync(input)) throw new Error(`[ImageUnderstand] \u672C\u5730\u6587\u4EF6\u4E0D\u5B58\u5728: ${input}`);
55247
54672
  console.log(`[ImageUnderstand] \u8BFB\u53D6\u672C\u5730\u6587\u4EF6: ${input}`);
55248
- const buffer = import_fs9.default.readFileSync(input);
54673
+ const buffer = import_fs7.default.readFileSync(input);
55249
54674
  const mediaType2 = guessMediaTypeFromData(buffer.toString("base64"));
55250
54675
  if (!mediaType2) {
55251
54676
  throw unsupportedImageFormatError(input);
@@ -55348,7 +54773,7 @@ var import_promises11 = require("node:fs/promises");
55348
54773
  var DEFAULT_READ_LIMIT = 2e3;
55349
54774
  var MAX_LINE_LENGTH2 = 2e3;
55350
54775
  var MAX_BYTES = 50 * 1024;
55351
- var DESCRIPTION8 = `Reads a file from the local filesystem. You can access any file directly by using this tool.
54776
+ var DESCRIPTION7 = `Reads a file from the local filesystem. You can access any file directly by using this tool.
55352
54777
  Assume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.
55353
54778
 
55354
54779
  Usage:
@@ -55425,7 +54850,7 @@ async function isBinaryFile(filePath) {
55425
54850
  }
55426
54851
  var readTool = {
55427
54852
  name: "read",
55428
- description: DESCRIPTION8,
54853
+ description: DESCRIPTION7,
55429
54854
  input_schema: {
55430
54855
  type: "object",
55431
54856
  properties: {
@@ -55540,7 +54965,7 @@ var import_promises12 = require("node:fs/promises");
55540
54965
  var DEFAULT_READ_LIMIT2 = 2e3;
55541
54966
  var MAX_LINE_LENGTH3 = 2e3;
55542
54967
  var MAX_BYTES2 = 50 * 1024;
55543
- var DESCRIPTION9 = `Reads a user-provided attachment by attachment_id from the local Duclaw attachment index.
54968
+ var DESCRIPTION8 = `Reads a user-provided attachment by attachment_id from the local Duclaw attachment index.
55544
54969
  Use this when the user attached a local macOS/iOS/Feishu file and the conversation context contains an attachment_id or file_id such as att_file_xxx.
55545
54970
 
55546
54971
  Usage:
@@ -55616,7 +55041,7 @@ async function isBinaryFile2(filePath) {
55616
55041
  }
55617
55042
  var readAttachmentTool = {
55618
55043
  name: "read_attachment",
55619
- description: DESCRIPTION9,
55044
+ description: DESCRIPTION8,
55620
55045
  input_schema: {
55621
55046
  type: "object",
55622
55047
  properties: {
@@ -55730,20 +55155,20 @@ ${suggestions.join("\n")}`;
55730
55155
  };
55731
55156
 
55732
55157
  // src/skill/SkillRegistry.ts
55733
- var import_fs11 = require("fs");
55158
+ var import_fs9 = require("fs");
55734
55159
  var import_os3 = require("os");
55735
- var import_path16 = __toESM(require("path"));
55160
+ var import_path14 = __toESM(require("path"));
55736
55161
 
55737
55162
  // src/runtime/paths.ts
55738
- var import_fs10 = require("fs");
55739
- var import_path15 = __toESM(require("path"));
55163
+ var import_fs8 = require("fs");
55164
+ var import_path13 = __toESM(require("path"));
55740
55165
  var findProjectRoot = (filename = "duclaw.json", startDir = process.cwd()) => {
55741
55166
  let currentDir = startDir;
55742
55167
  while (true) {
55743
- if ((0, import_fs10.existsSync)((0, import_path15.join)(currentDir, filename))) {
55168
+ if ((0, import_fs8.existsSync)((0, import_path13.join)(currentDir, filename))) {
55744
55169
  return currentDir;
55745
55170
  }
55746
- const parentDir = (0, import_path15.dirname)(currentDir);
55171
+ const parentDir = (0, import_path13.dirname)(currentDir);
55747
55172
  if (parentDir === currentDir) {
55748
55173
  return null;
55749
55174
  }
@@ -55752,12 +55177,12 @@ var findProjectRoot = (filename = "duclaw.json", startDir = process.cwd()) => {
55752
55177
  };
55753
55178
  var resolveCoreRoot = () => {
55754
55179
  const candidates = [
55755
- import_path15.default.resolve(__dirname_m, ".."),
55756
- import_path15.default.resolve(__dirname_m, "..", ".."),
55180
+ import_path13.default.resolve(__dirname_m, ".."),
55181
+ import_path13.default.resolve(__dirname_m, "..", ".."),
55757
55182
  process.cwd()
55758
55183
  ];
55759
55184
  for (const candidate of candidates) {
55760
- if ((0, import_fs10.existsSync)(import_path15.default.join(candidate, "web", "dist", "index.html"))) {
55185
+ if ((0, import_fs8.existsSync)(import_path13.default.join(candidate, "web", "dist", "index.html"))) {
55761
55186
  return candidate;
55762
55187
  }
55763
55188
  }
@@ -55766,11 +55191,11 @@ var resolveCoreRoot = () => {
55766
55191
  var resolveWebDistRoot = () => {
55767
55192
  const coreRoot = resolveCoreRoot();
55768
55193
  const candidates = [
55769
- import_path15.default.join(coreRoot, "dist", "web"),
55770
- import_path15.default.join(coreRoot, "web", "dist")
55194
+ import_path13.default.join(coreRoot, "dist", "web"),
55195
+ import_path13.default.join(coreRoot, "web", "dist")
55771
55196
  ];
55772
55197
  for (const candidate of candidates) {
55773
- if ((0, import_fs10.existsSync)(import_path15.default.join(candidate, "index.html"))) {
55198
+ if ((0, import_fs8.existsSync)(import_path13.default.join(candidate, "index.html"))) {
55774
55199
  return candidate;
55775
55200
  }
55776
55201
  }
@@ -55780,14 +55205,14 @@ var resolveWebDistRoot = () => {
55780
55205
  // src/skill/SkillRegistry.ts
55781
55206
  var getProjectSkillsPath = () => {
55782
55207
  const projectRoot = findProjectRoot();
55783
- return projectRoot ? (0, import_path16.join)(projectRoot, "skills") : null;
55208
+ return projectRoot ? (0, import_path14.join)(projectRoot, "skills") : null;
55784
55209
  };
55785
55210
  var getSkillPaths = () => {
55786
55211
  const paths = [];
55787
55212
  const seenPaths = /* @__PURE__ */ new Set();
55788
55213
  const pushPath = (candidate) => {
55789
- if (!(0, import_fs11.existsSync)(candidate) || !(0, import_fs11.statSync)(candidate).isDirectory()) return;
55790
- const normalized = import_path16.default.resolve(candidate);
55214
+ if (!(0, import_fs9.existsSync)(candidate) || !(0, import_fs9.statSync)(candidate).isDirectory()) return;
55215
+ const normalized = import_path14.default.resolve(candidate);
55791
55216
  if (seenPaths.has(normalized)) return;
55792
55217
  seenPaths.add(normalized);
55793
55218
  paths.push(normalized);
@@ -55796,16 +55221,16 @@ var getSkillPaths = () => {
55796
55221
  if (projectSkillsPath) {
55797
55222
  pushPath(projectSkillsPath);
55798
55223
  }
55799
- pushPath((0, import_path16.join)((0, import_os3.homedir)(), ".duclaw", "skills"));
55800
- pushPath((0, import_path16.join)((0, import_os3.homedir)(), ".agents", "skills"));
55224
+ pushPath((0, import_path14.join)((0, import_os3.homedir)(), ".duclaw", "skills"));
55225
+ pushPath((0, import_path14.join)((0, import_os3.homedir)(), ".agents", "skills"));
55801
55226
  return paths;
55802
55227
  };
55803
55228
  var getDirectories = (dirPath) => {
55804
- return (0, import_fs11.readdirSync)(dirPath).filter((name) => (0, import_fs11.statSync)((0, import_path16.join)(dirPath, name)).isDirectory());
55229
+ return (0, import_fs9.readdirSync)(dirPath).filter((name) => (0, import_fs9.statSync)((0, import_path14.join)(dirPath, name)).isDirectory());
55805
55230
  };
55806
55231
  var parseSkill = (mdPath, skillDir, options = {}) => {
55807
- if (!(0, import_fs11.existsSync)(mdPath)) return null;
55808
- const raw2 = (0, import_fs11.readFileSync)(mdPath, "utf-8");
55232
+ if (!(0, import_fs9.existsSync)(mdPath)) return null;
55233
+ const raw2 = (0, import_fs9.readFileSync)(mdPath, "utf-8");
55809
55234
  let name = "";
55810
55235
  let description = "";
55811
55236
  let body = raw2;
@@ -55821,14 +55246,14 @@ var parseSkill = (mdPath, skillDir, options = {}) => {
55821
55246
  }
55822
55247
  }
55823
55248
  if (!name) {
55824
- name = import_path16.default.basename(import_path16.default.dirname(mdPath));
55249
+ name = import_path14.default.basename(import_path14.default.dirname(mdPath));
55825
55250
  }
55826
55251
  if (!description && body) {
55827
55252
  description = body.split("\n")[0].replace(/^#+\s*/, "").trim();
55828
55253
  }
55829
- const normalizedSkillDir = import_path16.default.resolve(skillDir);
55254
+ const normalizedSkillDir = import_path14.default.resolve(skillDir);
55830
55255
  const projectSkillsPath = getProjectSkillsPath();
55831
- const isProjectSkill = projectSkillsPath ? normalizedSkillDir === import_path16.default.resolve(projectSkillsPath, import_path16.default.basename(normalizedSkillDir)) && normalizedSkillDir.startsWith(import_path16.default.resolve(projectSkillsPath) + import_path16.default.sep) : false;
55256
+ const isProjectSkill = projectSkillsPath ? normalizedSkillDir === import_path14.default.resolve(projectSkillsPath, import_path14.default.basename(normalizedSkillDir)) && normalizedSkillDir.startsWith(import_path14.default.resolve(projectSkillsPath) + import_path14.default.sep) : false;
55832
55257
  const scope = options.scope ?? (isProjectSkill ? "project" : "global");
55833
55258
  const deletable = options.deletable ?? (scope === "project" && isProjectSkill);
55834
55259
  return {
@@ -55853,8 +55278,8 @@ var loadSkill = () => {
55853
55278
  for (const skillPath of skillPaths) {
55854
55279
  const dirs = getDirectories(skillPath);
55855
55280
  for (const skillName of dirs) {
55856
- const eachSkillPath = (0, import_path16.join)(skillPath, skillName);
55857
- const eachSkillMdPath = (0, import_path16.join)(eachSkillPath, "SKILL.md");
55281
+ const eachSkillPath = (0, import_path14.join)(skillPath, skillName);
55282
+ const eachSkillMdPath = (0, import_path14.join)(eachSkillPath, "SKILL.md");
55858
55283
  const skill = parseSkill(eachSkillMdPath, eachSkillPath);
55859
55284
  if (skill && !seen.has(skill.name)) {
55860
55285
  seen.add(skill.name);
@@ -55868,7 +55293,7 @@ var deleteSkill = (name) => {
55868
55293
  const skills = loadSkill();
55869
55294
  const skill = skills.find((s) => s.name === name);
55870
55295
  if (!skill || !skill.deletable) return false;
55871
- (0, import_fs11.rmSync)(skill.baseDir, { recursive: true, force: false });
55296
+ (0, import_fs9.rmSync)(skill.baseDir, { recursive: true, force: false });
55872
55297
  return true;
55873
55298
  };
55874
55299
  var SkillRegistry_default = loadSkill;
@@ -55905,7 +55330,7 @@ var getSkillDetail = (skillName) => {
55905
55330
  };
55906
55331
 
55907
55332
  // src/tools/tools/Skill.ts
55908
- var DESCRIPTION10 = `
55333
+ var DESCRIPTION9 = `
55909
55334
  Execute a skill within the main conversation
55910
55335
 
55911
55336
  <skills_instructions>
@@ -55932,7 +55357,7 @@ ${getSkillMeta()}
55932
55357
  `;
55933
55358
  var skillTool = {
55934
55359
  name: `skill`,
55935
- description: DESCRIPTION10,
55360
+ description: DESCRIPTION9,
55936
55361
  input_schema: {
55937
55362
  type: `object`,
55938
55363
  properties: {
@@ -55961,7 +55386,7 @@ var skillTool = {
55961
55386
  };
55962
55387
 
55963
55388
  // src/tools/tools/WebFetch.ts
55964
- var DESCRIPTION11 = `Fetches the content of a web page given its URL.
55389
+ var DESCRIPTION10 = `Fetches the content of a web page given its URL.
55965
55390
 
55966
55391
  Usage:
55967
55392
  - Use this tool to retrieve the text content of a specific web page when you already know the URL.
@@ -55979,7 +55404,7 @@ function extractTextFromHtml(html) {
55979
55404
  }
55980
55405
  var webFetchTool = {
55981
55406
  name: "webfetch",
55982
- description: DESCRIPTION11,
55407
+ description: DESCRIPTION10,
55983
55408
  input_schema: {
55984
55409
  type: "object",
55985
55410
  properties: {
@@ -56050,7 +55475,7 @@ ${result}${suffix}
56050
55475
  };
56051
55476
 
56052
55477
  // src/tools/tools/WebSearch.ts
56053
- var DESCRIPTION12 = `
55478
+ var DESCRIPTION11 = `
56054
55479
  - Web search tool powered by Exa AI
56055
55480
  - Search the internet for up-to-date information, documentation, articles, and more
56056
55481
  - Today's date is {{date}}
@@ -56069,7 +55494,7 @@ var API_CONFIG2 = {
56069
55494
  var webSearchTool = {
56070
55495
  name: "websearch",
56071
55496
  get description() {
56072
- return DESCRIPTION12.replace("{{date}}", (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
55497
+ return DESCRIPTION11.replace("{{date}}", (/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
56073
55498
  },
56074
55499
  input_schema: {
56075
55500
  type: "object",
@@ -56170,7 +55595,7 @@ var webSearchTool = {
56170
55595
  // src/tools/tools/Write.ts
56171
55596
  var import_node_path17 = require("node:path");
56172
55597
  var import_promises13 = require("node:fs/promises");
56173
- var DESCRIPTION13 = `Writes a file to the local filesystem.
55598
+ var DESCRIPTION12 = `Writes a file to the local filesystem.
56174
55599
 
56175
55600
  Usage:
56176
55601
  - This tool will overwrite the existing file if there is one at the provided path.
@@ -56183,7 +55608,7 @@ Usage:
56183
55608
  `;
56184
55609
  var writeTool = {
56185
55610
  name: "write",
56186
- description: DESCRIPTION13,
55611
+ description: DESCRIPTION12,
56187
55612
  input_schema: {
56188
55613
  type: "object",
56189
55614
  properties: {
@@ -56296,7 +55721,7 @@ var createBaseTools = (options = []) => {
56296
55721
  };
56297
55722
 
56298
55723
  // src/tools/tools/InternalEventDecision.ts
56299
- var DESCRIPTION14 = `
55724
+ var DESCRIPTION13 = `
56300
55725
  \u7528\u4E8E\u5173\u95ED CEO \u5DF2\u7ECF\u770B\u8FC7\u7684\u5185\u90E8\u4E8B\u4EF6\uFF0C\u800C\u4E0D\u628A\u5B83\u8F6C\u53D1\u7ED9\u7528\u6237\u3002
56301
55726
 
56302
55727
  \u53EA\u5728\u4F60\u660E\u786E\u5224\u65AD\u67D0\u6761 manager.mailbox_message \u4E0D\u9700\u8981\u5BF9\u7528\u6237\u53EF\u89C1\u53D1\u9001\u65F6\u4F7F\u7528\u3002\u6BD4\u5982\uFF1A
@@ -56307,7 +55732,7 @@ var DESCRIPTION14 = `
56307
55732
  `;
56308
55733
  var internalEventDecision = {
56309
55734
  name: `internal_event_decision`,
56310
- description: DESCRIPTION14,
55735
+ description: DESCRIPTION13,
56311
55736
  input_schema: {
56312
55737
  type: `object`,
56313
55738
  properties: {
@@ -56354,6 +55779,44 @@ var internalEventDecision = {
56354
55779
  }
56355
55780
  };
56356
55781
 
55782
+ // src/tools/tools/SendFile.ts
55783
+ var DESCRIPTION14 = `
55784
+ \u53D1\u9001\u6587\u4EF6\u7ED9\u7528\u6237\u3002\u652F\u6301\u4E24\u79CD\u65B9\u5F0F\uFF1A
55785
+ 1. \u672C\u5730\u6587\u4EF6\u8DEF\u5F84\uFF08filePath\uFF09\uFF1A\u9002\u7528\u4E8E\u4F60\u901A\u8FC7 Write \u5DE5\u5177\u751F\u6210\u7684\u6587\u4EF6
55786
+ 2. \u8FDC\u7A0B URL\uFF08url\uFF09\uFF1A\u9002\u7528\u4E8E\u4ECE\u7F51\u7EDC\u83B7\u53D6\u7684\u6587\u4EF6
55787
+
55788
+ \u4E24\u8005\u4E8C\u9009\u4E00\uFF0C\u4F18\u5148\u4F7F\u7528 filePath\u3002\u5982\u679C\u540C\u65F6\u63D0\u4F9B\uFF0C\u4F18\u5148\u4F7F\u7528 filePath\u3002
55789
+ \u652F\u6301\u53D1\u9001\u4EFB\u610F\u7C7B\u578B\u7684\u6587\u4EF6\uFF08pdf\u3001doc\u3001xls\u3001ppt\u3001mp4\u3001opus\u3001\u56FE\u7247\u3001\u538B\u7F29\u5305\u7B49\uFF09\uFF0C\u7CFB\u7EDF\u4F1A\u6839\u636E\u6587\u4EF6\u540D\u540E\u7F00\u81EA\u52A8\u8BC6\u522B\u7C7B\u578B\u3002
55790
+ `;
55791
+ var sendFile = {
55792
+ name: `send_file`,
55793
+ description: DESCRIPTION14,
55794
+ input_schema: {
55795
+ type: `object`,
55796
+ properties: {
55797
+ filePath: {
55798
+ type: `string`,
55799
+ description: `\u672C\u5730\u6587\u4EF6\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u4F8B\u5982 /tmp/report.pdf`
55800
+ },
55801
+ url: {
55802
+ type: `string`,
55803
+ description: `\u8FDC\u7A0B\u6587\u4EF6\u7684 URL\uFF0C\u4F8B\u5982 https://example.com/report.pdf`
55804
+ },
55805
+ fileName: {
55806
+ type: `string`,
55807
+ description: `\u53D1\u9001\u7ED9\u7528\u6237\u65F6\u663E\u793A\u7684\u6587\u4EF6\u540D\uFF08\u5E26\u540E\u7F00\uFF09\uFF0C\u4F8B\u5982 report.pdf`
55808
+ }
55809
+ },
55810
+ required: [`fileName`]
55811
+ },
55812
+ async execute(input, userRequest) {
55813
+ if (!input.filePath && !input.url) {
55814
+ return `\u9519\u8BEF\uFF1AfilePath \u548C url \u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A`;
55815
+ }
55816
+ return `\u6587\u4EF6\u5DF2\u53D1\u9001: ${input.fileName}`;
55817
+ }
55818
+ };
55819
+
56357
55820
  // src/tools/tools/SendMessage.ts
56358
55821
  var DESCRIPTION15 = `
56359
55822
  \u8FD9\u4E2A\u5DE5\u5177\u662F\u548C\u7528\u6237\u6C9F\u901A\u7684\u552F\u4E00\u6E20\u9053\uFF0C\u5C3D\u53EF\u80FD\u8BA9\u7528\u6237\u77E5\u9053\u4F60\u5F53\u524D\u5728\u5E72\u4EC0\u4E48\uFF0C\u5982\u679C\u4E0D\u8C03\u7528\u8FD9\u4E2A\u5DE5\u5177\uFF0C\u7528\u6237\u5C06\u5BF9\u4F60\u4E00\u65E0\u6240\u77E5\u3002
@@ -56634,132 +56097,549 @@ ${msg.content}`;
56634
56097
  ${replies}`;
56635
56098
  }
56636
56099
  };
56637
-
56638
- // src/department/mailbox/mailbox.ts
56639
- var import_node_crypto13 = require("node:crypto");
56640
-
56641
- // src/department/mailbox/events.ts
56642
- var import_node_crypto12 = require("node:crypto");
56643
- var parseDetail = (detailJson) => {
56644
- if (!detailJson) return void 0;
56645
- try {
56646
- const parsed = JSON.parse(detailJson);
56647
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
56648
- return parsed;
56649
- }
56650
- } catch {
56651
- return void 0;
56100
+
56101
+ // src/department/mailbox/mailbox.ts
56102
+ var import_node_crypto12 = require("node:crypto");
56103
+
56104
+ // src/department/mailbox/events.ts
56105
+ var import_node_crypto10 = require("node:crypto");
56106
+ var parseDetail = (detailJson) => {
56107
+ if (!detailJson) return void 0;
56108
+ try {
56109
+ const parsed = JSON.parse(detailJson);
56110
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
56111
+ return parsed;
56112
+ }
56113
+ } catch {
56114
+ return void 0;
56115
+ }
56116
+ return void 0;
56117
+ };
56118
+ var mapMailboxEventRow = (row) => {
56119
+ const hasMessage = typeof row.toMailboxId === "string" && typeof row.fromMailboxId === "string" && typeof row.content === "string" && typeof row.sendTime === "number" && typeof row.status === "string";
56120
+ return {
56121
+ id: row.id,
56122
+ messageId: row.messageId || void 0,
56123
+ mailboxId: row.mailboxId,
56124
+ actorMailboxId: row.actorMailboxId || void 0,
56125
+ counterpartMailboxId: row.counterpartMailboxId || void 0,
56126
+ eventType: row.eventType,
56127
+ detail: parseDetail(row.detailJson),
56128
+ createdAt: row.createdAt,
56129
+ message: hasMessage ? {
56130
+ id: row.messageId || "",
56131
+ toMailboxId: row.toMailboxId,
56132
+ fromMailboxId: row.fromMailboxId,
56133
+ content: row.content,
56134
+ sendTime: row.sendTime,
56135
+ status: row.status,
56136
+ originUserId: row.originUserId || void 0,
56137
+ originPlatform: row.originPlatform || void 0,
56138
+ threadId: row.threadId || void 0,
56139
+ parentMessageId: row.parentMessageId || void 0
56140
+ } : null
56141
+ };
56142
+ };
56143
+ var recordMailboxEvent = (input) => {
56144
+ const db3 = createSqliteDB();
56145
+ const event = {
56146
+ id: (0, import_node_crypto10.randomUUID)().slice(0, 12),
56147
+ messageId: input.messageId,
56148
+ mailboxId: input.mailboxId,
56149
+ actorMailboxId: input.actorMailboxId,
56150
+ counterpartMailboxId: input.counterpartMailboxId,
56151
+ eventType: input.eventType,
56152
+ detail: input.detail,
56153
+ createdAt: input.createdAt ?? Date.now()
56154
+ };
56155
+ const stmt = db3.prepare(
56156
+ `INSERT INTO mailbox_events (
56157
+ id,
56158
+ message_id,
56159
+ mailbox_id,
56160
+ actor_mailbox_id,
56161
+ counterpart_mailbox_id,
56162
+ event_type,
56163
+ detail_json,
56164
+ created_at
56165
+ ) VALUES (?,?,?,?,?,?,?,?)`
56166
+ );
56167
+ stmt.run(
56168
+ event.id,
56169
+ event.messageId || null,
56170
+ event.mailboxId,
56171
+ event.actorMailboxId || null,
56172
+ event.counterpartMailboxId || null,
56173
+ event.eventType,
56174
+ event.detail ? JSON.stringify(event.detail) : null,
56175
+ event.createdAt
56176
+ );
56177
+ return event;
56178
+ };
56179
+ var recordMailboxStatusChange = (params) => {
56180
+ if (params.previousStatus === params.nextStatus) {
56181
+ return null;
56182
+ }
56183
+ return recordMailboxEvent({
56184
+ messageId: params.messageId,
56185
+ mailboxId: params.mailboxId,
56186
+ actorMailboxId: params.actorMailboxId,
56187
+ counterpartMailboxId: params.counterpartMailboxId,
56188
+ eventType: "message_status_changed",
56189
+ detail: {
56190
+ previousStatus: params.previousStatus,
56191
+ nextStatus: params.nextStatus,
56192
+ reason: params.reason
56193
+ }
56194
+ });
56195
+ };
56196
+ var listMailboxEvents = (params) => {
56197
+ const db3 = createSqliteDB();
56198
+ const limit = Math.max(1, Math.min(params.limit ?? 100, 500));
56199
+ const stmt = db3.prepare(
56200
+ `SELECT
56201
+ e.id as id,
56202
+ e.message_id as messageId,
56203
+ e.mailbox_id as mailboxId,
56204
+ e.actor_mailbox_id as actorMailboxId,
56205
+ e.counterpart_mailbox_id as counterpartMailboxId,
56206
+ e.event_type as eventType,
56207
+ e.detail_json as detailJson,
56208
+ e.created_at as createdAt,
56209
+ m.to_mailbox_id as toMailboxId,
56210
+ m.from_mailbox_id as fromMailboxId,
56211
+ m.content as content,
56212
+ m.send_time as sendTime,
56213
+ m.status as status,
56214
+ m.origin_user_id as originUserId,
56215
+ m.origin_platform as originPlatform,
56216
+ m.thread_id as threadId,
56217
+ m.parent_message_id as parentMessageId
56218
+ FROM mailbox_events e
56219
+ LEFT JOIN mailbox m ON m.id = e.message_id
56220
+ WHERE e.mailbox_id = ? OR e.actor_mailbox_id = ? OR e.counterpart_mailbox_id = ?
56221
+ ORDER BY e.created_at DESC
56222
+ LIMIT ?`
56223
+ );
56224
+ const rows = stmt.all(params.mailboxId, params.mailboxId, params.mailboxId, limit);
56225
+ return rows.map(mapMailboxEventRow);
56226
+ };
56227
+
56228
+ // src/department/DepartmentMember.ts
56229
+ var import_fs11 = require("fs");
56230
+ var import_path16 = __toESM(require("path"));
56231
+
56232
+ // src/department/Department.ts
56233
+ var import_path15 = __toESM(require("path"));
56234
+ var import_fs10 = require("fs");
56235
+ var legacyMigrationChecked = false;
56236
+ var getDepartmentBaseDir = () => {
56237
+ return import_path15.default.join(getDuclawHomeDir(), "department");
56238
+ };
56239
+ var getLegacyTeamBaseDir = () => {
56240
+ return import_path15.default.join(getDuclawHomeDir(), "team");
56241
+ };
56242
+ var getDepartmentWorkSpaceDir = (departmentName) => {
56243
+ return import_path15.default.join(getDepartmentBaseDir(), "workspace", departmentName);
56244
+ };
56245
+ var getLegacyTeamWorkSpaceDir = (teamName) => {
56246
+ return import_path15.default.join(getLegacyTeamBaseDir(), "workspace", teamName);
56247
+ };
56248
+ var getDepartmentJsonPath = (departmentName) => {
56249
+ return import_path15.default.join(getDepartmentWorkSpaceDir(departmentName), "department.json");
56250
+ };
56251
+ var getLegacyTeamJsonPath = (teamName) => {
56252
+ return import_path15.default.join(getLegacyTeamWorkSpaceDir(teamName), "team.json");
56253
+ };
56254
+ var mapLegacyRole = (role) => {
56255
+ return role === "team_manager" ? "department_head" : "executor";
56256
+ };
56257
+ var mapLegacyDepartment = (legacy) => {
56258
+ const departmentMembers = (legacy.teamMembers ?? []).map((member) => ({
56259
+ id: member.id,
56260
+ name: member.name,
56261
+ departmentId: legacy.id,
56262
+ mailBoxId: member.mailBoxId,
56263
+ workspaceId: member.workspaceId,
56264
+ role: mapLegacyRole(member.role),
56265
+ focusOn: member.focusOn
56266
+ }));
56267
+ const headMemberId = legacy.managerMemberId ?? departmentMembers.find((member) => member.role === "department_head")?.id;
56268
+ return {
56269
+ id: legacy.id,
56270
+ name: legacy.name,
56271
+ sourceGoalId: legacy.goalId,
56272
+ charter: legacy.goalId ? `Legacy department migrated from team goal ${legacy.goalId}.` : "Legacy department migrated from team data.",
56273
+ workpath: legacy.workpath,
56274
+ headMemberId,
56275
+ departmentMembers
56276
+ };
56277
+ };
56278
+ var migrateLegacyTeamsToDepartments = () => {
56279
+ if (legacyMigrationChecked) return;
56280
+ legacyMigrationChecked = true;
56281
+ const legacyWorkspaceDir = import_path15.default.join(getLegacyTeamBaseDir(), "workspace");
56282
+ if (!(0, import_fs10.existsSync)(legacyWorkspaceDir)) return;
56283
+ for (const legacyName of (0, import_fs10.readdirSync)(legacyWorkspaceDir)) {
56284
+ const legacyJsonPath = getLegacyTeamJsonPath(legacyName);
56285
+ if (!(0, import_fs10.existsSync)(legacyJsonPath)) continue;
56286
+ const departmentJsonPath = getDepartmentJsonPath(legacyName);
56287
+ if ((0, import_fs10.existsSync)(departmentJsonPath)) continue;
56288
+ try {
56289
+ const legacy = JSON.parse((0, import_fs10.readFileSync)(legacyJsonPath, "utf-8"));
56290
+ const department = mapLegacyDepartment(legacy);
56291
+ (0, import_fs10.mkdirSync)(getDepartmentWorkSpaceDir(department.name), { recursive: true });
56292
+ (0, import_fs10.writeFileSync)(departmentJsonPath, JSON.stringify(department, null, " "), "utf-8");
56293
+ } catch (err) {
56294
+ console.warn(`[department] Failed to migrate legacy team ${legacyName}: ${err.message}`);
56295
+ }
56296
+ }
56297
+ };
56298
+ var createDepartment = (departmentDefinition) => {
56299
+ if (!departmentDefinition) throw new Error(`[createDepartment] departmentDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
56300
+ const departmentPath = getDepartmentWorkSpaceDir(departmentDefinition.name);
56301
+ (0, import_fs10.mkdirSync)(departmentPath, { recursive: true });
56302
+ (0, import_fs10.writeFileSync)(getDepartmentJsonPath(departmentDefinition.name), JSON.stringify(departmentDefinition, null, " "), "utf-8");
56303
+ return departmentDefinition;
56304
+ };
56305
+ var getDepartment = (name) => {
56306
+ migrateLegacyTeamsToDepartments();
56307
+ const departmentJsonPath = getDepartmentJsonPath(name);
56308
+ if (!(0, import_fs10.existsSync)(departmentJsonPath)) return null;
56309
+ const text2 = (0, import_fs10.readFileSync)(departmentJsonPath, "utf-8");
56310
+ return JSON.parse(text2);
56311
+ };
56312
+ var listDepartments = () => {
56313
+ migrateLegacyTeamsToDepartments();
56314
+ const workspaceDir = import_path15.default.join(getDepartmentBaseDir(), "workspace");
56315
+ if (!(0, import_fs10.existsSync)(workspaceDir)) return [];
56316
+ const departments = [];
56317
+ for (const departmentName of (0, import_fs10.readdirSync)(workspaceDir)) {
56318
+ const department = getDepartment(departmentName);
56319
+ if (department) departments.push(department);
56320
+ }
56321
+ return departments;
56322
+ };
56323
+ var getDepartmentById = (id) => {
56324
+ const department = listDepartments().find((item) => item.id === id);
56325
+ return department ?? null;
56326
+ };
56327
+ var deleteDepartment = (name) => {
56328
+ if (!(0, import_fs10.existsSync)(getDepartmentJsonPath(name))) {
56329
+ throw new Error(`[deleteDepartment] \u4E0D\u5B58\u5728\u5BF9\u5E94\u7684\u90E8\u95E8 ${name} \u7684 department.json \u6587\u4EF6`);
56330
+ }
56331
+ (0, import_fs10.rmSync)(getDepartmentJsonPath(name));
56332
+ };
56333
+
56334
+ // src/department/workspace/workspace.ts
56335
+ var db = createSqliteDB();
56336
+ var getWorkspaceId = (departmentName, memberName) => {
56337
+ return `${departmentName}::${memberName}`;
56338
+ };
56339
+ var createWorkspace = (workspace) => {
56340
+ const stmt = db.prepare(`INSERT INTO workspace (id, team_name, teammate_name, team_workpath) VALUES (?, ?, ?, ?) `);
56341
+ stmt.run(
56342
+ workspace.id,
56343
+ workspace.departmentName,
56344
+ workspace.memberName,
56345
+ workspace.departmentWorkPath
56346
+ );
56347
+ };
56348
+ var deleteWorkspace = (workspaceId) => {
56349
+ const stmt = db.prepare(`delete from workspace where id = ?`);
56350
+ stmt.run(workspaceId);
56351
+ };
56352
+
56353
+ // src/department/DepartmentMember.ts
56354
+ var createDepartmentMember = (departmentMemberDefinition) => {
56355
+ if (!departmentMemberDefinition) throw new Error(`[createDepartmentMember] departmentMemberDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
56356
+ const { name, departmentId, workspaceId } = departmentMemberDefinition;
56357
+ const department = getDepartmentById(departmentId);
56358
+ if (!department) throw new Error(`[createDepartmentMember] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentId}`);
56359
+ const memberPath = import_path16.default.join(getDepartmentWorkSpaceDir(department.name), name);
56360
+ (0, import_fs11.mkdirSync)(memberPath, { recursive: true });
56361
+ const workspace = {
56362
+ id: getWorkspaceId(department.name, departmentMemberDefinition.name),
56363
+ departmentName: department.name,
56364
+ memberName: name,
56365
+ departmentWorkPath: memberPath
56366
+ };
56367
+ createWorkspace(workspace);
56368
+ if (!department.departmentMembers) {
56369
+ department.departmentMembers = [];
56370
+ }
56371
+ if (department.departmentMembers.some((member) => member.id === departmentMemberDefinition.id || member.name === departmentMemberDefinition.name)) {
56372
+ throw new Error(`[createDepartmentMember] \u90E8\u95E8 ${department.name} \u5DF2\u5B58\u5728\u540C\u540D\u6216\u540C id \u6210\u5458: ${departmentMemberDefinition.name}/${departmentMemberDefinition.id}`);
56373
+ }
56374
+ if (departmentMemberDefinition.role === "department_head") {
56375
+ const existingHead = department.headMemberId ? department.departmentMembers.find((member) => member.id === department.headMemberId) : department.departmentMembers.find((member) => member.role === "department_head");
56376
+ if (existingHead) {
56377
+ throw new Error(`[createDepartmentMember] \u90E8\u95E8 ${department.name} \u5DF2\u5B58\u5728 Department Head: ${existingHead.name}`);
56378
+ }
56379
+ department.headMemberId = departmentMemberDefinition.id;
56380
+ }
56381
+ department.departmentMembers.push(departmentMemberDefinition);
56382
+ (0, import_fs11.writeFileSync)(getDepartmentJsonPath(department.name), JSON.stringify(department, null, " "), "utf-8");
56383
+ return departmentMemberDefinition;
56384
+ };
56385
+ var listDepartmentMembers = (departmentName) => {
56386
+ const departmentJsonPath = getDepartmentJsonPath(departmentName);
56387
+ if (!(0, import_fs11.existsSync)(departmentJsonPath)) return [];
56388
+ const text2 = (0, import_fs11.readFileSync)(departmentJsonPath, "utf-8");
56389
+ const department = JSON.parse(text2);
56390
+ if (!department) throw new Error(`[listDepartmentMembers] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentName}`);
56391
+ return department.departmentMembers ?? [];
56392
+ };
56393
+ var getDepartmentMember = (departmentName, departmentMemberId) => {
56394
+ const members = listDepartmentMembers(departmentName);
56395
+ return members.find((member) => member.id === departmentMemberId) || null;
56396
+ };
56397
+ var getDepartmentMemberByName = (departmentName, departmentMemberName) => {
56398
+ const members = listDepartmentMembers(departmentName);
56399
+ return members.find((member) => member.name === departmentMemberName) || null;
56400
+ };
56401
+ var getDepartmentMemberByMailboxId = (mailboxId) => {
56402
+ const [departmentName, memberName] = mailboxId.split("::");
56403
+ if (!departmentName || !memberName) return null;
56404
+ return getDepartmentMemberByName(departmentName, memberName);
56405
+ };
56406
+ var getDepartmentMemberById = (memberId) => {
56407
+ for (const department of listDepartments()) {
56408
+ const targetMember = department.departmentMembers.find((member) => member.id === memberId);
56409
+ if (targetMember) return targetMember;
56410
+ }
56411
+ return null;
56412
+ };
56413
+ var deleteDepartmentMemberById = (departmentName, memberId) => {
56414
+ const department = getDepartment(departmentName);
56415
+ if (!department) throw new Error(`[deleteDepartmentMemberById] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentName}`);
56416
+ const memberIdx = department.departmentMembers.findIndex((member) => member.id === memberId);
56417
+ if (memberIdx === -1) {
56418
+ throw new Error(`[deleteDepartmentMemberById] \u627E\u4E0D\u5230\u5BF9\u5E94 id \u7684 department member: ${memberId}`);
56652
56419
  }
56653
- return void 0;
56420
+ const workspaceId = department.departmentMembers[memberIdx].workspaceId;
56421
+ if (department.headMemberId === memberId) {
56422
+ delete department.headMemberId;
56423
+ }
56424
+ department.departmentMembers = department.departmentMembers.filter((_, index) => index !== memberIdx);
56425
+ (0, import_fs11.writeFileSync)(getDepartmentJsonPath(departmentName), JSON.stringify(department, null, " "), "utf-8");
56426
+ deleteWorkspace(workspaceId);
56654
56427
  };
56655
- var mapMailboxEventRow = (row) => {
56656
- const hasMessage = typeof row.toMailboxId === "string" && typeof row.fromMailboxId === "string" && typeof row.content === "string" && typeof row.sendTime === "number" && typeof row.status === "string";
56657
- return {
56658
- id: row.id,
56659
- messageId: row.messageId || void 0,
56660
- mailboxId: row.mailboxId,
56661
- actorMailboxId: row.actorMailboxId || void 0,
56662
- counterpartMailboxId: row.counterpartMailboxId || void 0,
56663
- eventType: row.eventType,
56664
- detail: parseDetail(row.detailJson),
56665
- createdAt: row.createdAt,
56666
- message: hasMessage ? {
56667
- id: row.messageId || "",
56668
- toMailboxId: row.toMailboxId,
56669
- fromMailboxId: row.fromMailboxId,
56670
- content: row.content,
56671
- sendTime: row.sendTime,
56672
- status: row.status,
56673
- originUserId: row.originUserId || void 0,
56674
- originPlatform: row.originPlatform || void 0,
56675
- threadId: row.threadId || void 0,
56676
- parentMessageId: row.parentMessageId || void 0
56677
- } : null
56678
- };
56428
+
56429
+ // src/department/mailbox/ceoFollowup.ts
56430
+ var import_node_crypto11 = require("node:crypto");
56431
+ var rowToFollowup = (row) => ({
56432
+ id: row.id,
56433
+ sourceMessageId: row.sourceMessageId,
56434
+ status: row.status,
56435
+ originUserId: row.originUserId,
56436
+ originPlatform: row.originPlatform,
56437
+ fromMailboxId: row.fromMailboxId,
56438
+ threadId: row.threadId ?? void 0,
56439
+ parentMessageId: row.parentMessageId ?? void 0,
56440
+ workItemId: row.workItemId ?? void 0,
56441
+ content: row.content,
56442
+ attempts: row.attempts,
56443
+ lastError: row.lastError ?? void 0,
56444
+ createdAt: row.createdAt,
56445
+ updatedAt: row.updatedAt,
56446
+ completedAt: row.completedAt ?? void 0
56447
+ });
56448
+ var selectById = (id) => {
56449
+ const db3 = createSqliteDB();
56450
+ const row = db3.prepare(`
56451
+ SELECT
56452
+ id,
56453
+ source_message_id as sourceMessageId,
56454
+ status,
56455
+ origin_user_id as originUserId,
56456
+ origin_platform as originPlatform,
56457
+ from_mailbox_id as fromMailboxId,
56458
+ thread_id as threadId,
56459
+ parent_message_id as parentMessageId,
56460
+ work_item_id as workItemId,
56461
+ content,
56462
+ attempts,
56463
+ last_error as lastError,
56464
+ created_at as createdAt,
56465
+ updated_at as updatedAt,
56466
+ completed_at as completedAt
56467
+ FROM ceo_followups
56468
+ WHERE id = ?
56469
+ `).get(id);
56470
+ return row ? rowToFollowup(row) : null;
56679
56471
  };
56680
- var recordMailboxEvent = (input) => {
56472
+ var enqueueCeoFollowupFromMailbox = (message) => {
56473
+ if (message.toMailboxId !== "manager") return null;
56474
+ if (message.workItemRole === "followup") return null;
56475
+ if (!message.originUserId || !message.originPlatform) return null;
56681
56476
  const db3 = createSqliteDB();
56682
- const event = {
56683
- id: (0, import_node_crypto12.randomUUID)().slice(0, 12),
56684
- messageId: input.messageId,
56685
- mailboxId: input.mailboxId,
56686
- actorMailboxId: input.actorMailboxId,
56687
- counterpartMailboxId: input.counterpartMailboxId,
56688
- eventType: input.eventType,
56689
- detail: input.detail,
56690
- createdAt: input.createdAt ?? Date.now()
56691
- };
56692
- const stmt = db3.prepare(
56693
- `INSERT INTO mailbox_events (
56477
+ const now = Date.now();
56478
+ const id = `cfu_${(0, import_node_crypto11.randomUUID)().slice(0, 12)}`;
56479
+ db3.prepare(`
56480
+ INSERT INTO ceo_followups (
56694
56481
  id,
56695
- message_id,
56696
- mailbox_id,
56697
- actor_mailbox_id,
56698
- counterpart_mailbox_id,
56699
- event_type,
56700
- detail_json,
56701
- created_at
56702
- ) VALUES (?,?,?,?,?,?,?,?)`
56703
- );
56704
- stmt.run(
56705
- event.id,
56706
- event.messageId || null,
56707
- event.mailboxId,
56708
- event.actorMailboxId || null,
56709
- event.counterpartMailboxId || null,
56710
- event.eventType,
56711
- event.detail ? JSON.stringify(event.detail) : null,
56712
- event.createdAt
56482
+ source_message_id,
56483
+ status,
56484
+ origin_user_id,
56485
+ origin_platform,
56486
+ from_mailbox_id,
56487
+ thread_id,
56488
+ parent_message_id,
56489
+ work_item_id,
56490
+ content,
56491
+ created_at,
56492
+ updated_at
56493
+ ) VALUES (?, ?, 'pending', ?, ?, ?, ?, ?, ?, ?, ?, ?)
56494
+ ON CONFLICT(source_message_id) DO UPDATE SET
56495
+ status = CASE
56496
+ WHEN ceo_followups.status = 'completed' THEN ceo_followups.status
56497
+ ELSE 'pending'
56498
+ END,
56499
+ origin_user_id = excluded.origin_user_id,
56500
+ origin_platform = excluded.origin_platform,
56501
+ from_mailbox_id = excluded.from_mailbox_id,
56502
+ thread_id = excluded.thread_id,
56503
+ parent_message_id = excluded.parent_message_id,
56504
+ work_item_id = excluded.work_item_id,
56505
+ content = excluded.content,
56506
+ updated_at = excluded.updated_at
56507
+ `).run(
56508
+ id,
56509
+ message.id,
56510
+ message.originUserId,
56511
+ message.originPlatform,
56512
+ message.fromMailboxId,
56513
+ message.threadId ?? message.id,
56514
+ message.parentMessageId ?? null,
56515
+ message.workItemId ?? null,
56516
+ message.content,
56517
+ now,
56518
+ now
56713
56519
  );
56714
- return event;
56520
+ const row = db3.prepare(`
56521
+ SELECT id FROM ceo_followups WHERE source_message_id = ?
56522
+ `).get(message.id);
56523
+ return row ? selectById(row.id) : null;
56715
56524
  };
56716
- var recordMailboxStatusChange = (params) => {
56717
- if (params.previousStatus === params.nextStatus) {
56718
- return null;
56719
- }
56720
- return recordMailboxEvent({
56721
- messageId: params.messageId,
56722
- mailboxId: params.mailboxId,
56723
- actorMailboxId: params.actorMailboxId,
56724
- counterpartMailboxId: params.counterpartMailboxId,
56725
- eventType: "message_status_changed",
56726
- detail: {
56727
- previousStatus: params.previousStatus,
56728
- nextStatus: params.nextStatus,
56729
- reason: params.reason
56730
- }
56731
- });
56525
+ var listPendingCeoFollowups = (limit = 10) => {
56526
+ const db3 = createSqliteDB();
56527
+ const rows = db3.prepare(`
56528
+ SELECT
56529
+ id,
56530
+ source_message_id as sourceMessageId,
56531
+ status,
56532
+ origin_user_id as originUserId,
56533
+ origin_platform as originPlatform,
56534
+ from_mailbox_id as fromMailboxId,
56535
+ thread_id as threadId,
56536
+ parent_message_id as parentMessageId,
56537
+ work_item_id as workItemId,
56538
+ content,
56539
+ attempts,
56540
+ last_error as lastError,
56541
+ created_at as createdAt,
56542
+ updated_at as updatedAt,
56543
+ completed_at as completedAt
56544
+ FROM ceo_followups
56545
+ WHERE status IN ('pending', 'failed')
56546
+ ORDER BY created_at ASC
56547
+ LIMIT ?
56548
+ `).all(limit);
56549
+ return rows.map(rowToFollowup);
56732
56550
  };
56733
- var listMailboxEvents = (params) => {
56551
+ var claimCeoFollowup = (id) => {
56734
56552
  const db3 = createSqliteDB();
56735
- const limit = Math.max(1, Math.min(params.limit ?? 100, 500));
56736
- const stmt = db3.prepare(
56737
- `SELECT
56738
- e.id as id,
56739
- e.message_id as messageId,
56740
- e.mailbox_id as mailboxId,
56741
- e.actor_mailbox_id as actorMailboxId,
56742
- e.counterpart_mailbox_id as counterpartMailboxId,
56743
- e.event_type as eventType,
56744
- e.detail_json as detailJson,
56745
- e.created_at as createdAt,
56746
- m.to_mailbox_id as toMailboxId,
56747
- m.from_mailbox_id as fromMailboxId,
56748
- m.content as content,
56749
- m.send_time as sendTime,
56750
- m.status as status,
56751
- m.origin_user_id as originUserId,
56752
- m.origin_platform as originPlatform,
56753
- m.thread_id as threadId,
56754
- m.parent_message_id as parentMessageId
56755
- FROM mailbox_events e
56756
- LEFT JOIN mailbox m ON m.id = e.message_id
56757
- WHERE e.mailbox_id = ? OR e.actor_mailbox_id = ? OR e.counterpart_mailbox_id = ?
56758
- ORDER BY e.created_at DESC
56759
- LIMIT ?`
56760
- );
56761
- const rows = stmt.all(params.mailboxId, params.mailboxId, params.mailboxId, limit);
56762
- return rows.map(mapMailboxEventRow);
56553
+ const now = Date.now();
56554
+ const result = db3.prepare(`
56555
+ UPDATE ceo_followups
56556
+ SET status = 'processing',
56557
+ attempts = attempts + 1,
56558
+ updated_at = ?
56559
+ WHERE id = ?
56560
+ AND status IN ('pending', 'failed')
56561
+ `).run(now, id);
56562
+ if (result.changes === 0) return null;
56563
+ return selectById(id);
56564
+ };
56565
+ var completeCeoFollowup = (id) => {
56566
+ const db3 = createSqliteDB();
56567
+ const now = Date.now();
56568
+ db3.prepare(`
56569
+ UPDATE ceo_followups
56570
+ SET status = 'completed',
56571
+ completed_at = COALESCE(completed_at, ?),
56572
+ updated_at = ?,
56573
+ last_error = NULL
56574
+ WHERE id = ?
56575
+ AND status IN ('pending', 'processing', 'failed')
56576
+ `).run(now, now, id);
56577
+ db3.prepare(`
56578
+ UPDATE mailbox
56579
+ SET status = 'done',
56580
+ updated_at = ?
56581
+ WHERE id = (SELECT source_message_id FROM ceo_followups WHERE id = ?)
56582
+ AND status IN ('pending', 'processing', 'read')
56583
+ `).run(now, id);
56584
+ };
56585
+ var failCeoFollowup = (id, error) => {
56586
+ const db3 = createSqliteDB();
56587
+ const now = Date.now();
56588
+ db3.prepare(`
56589
+ UPDATE ceo_followups
56590
+ SET status = 'failed',
56591
+ last_error = ?,
56592
+ updated_at = ?
56593
+ WHERE id = ?
56594
+ AND status IN ('pending', 'processing', 'failed')
56595
+ `).run(error.slice(0, 1e3), now, id);
56596
+ };
56597
+ var recoverStaleProcessingCeoFollowups = (staleBefore) => {
56598
+ const db3 = createSqliteDB();
56599
+ const now = Date.now();
56600
+ const result = db3.prepare(`
56601
+ UPDATE ceo_followups
56602
+ SET status = 'failed',
56603
+ last_error = 'stale_processing_recovered',
56604
+ updated_at = ?
56605
+ WHERE status = 'processing'
56606
+ AND updated_at < ?
56607
+ `).run(now, staleBefore);
56608
+ return result.changes;
56609
+ };
56610
+ var completePendingCeoFollowupsForUser = (originUserId) => {
56611
+ const db3 = createSqliteDB();
56612
+ const now = Date.now();
56613
+ const rows = db3.prepare(`
56614
+ SELECT id, source_message_id as sourceMessageId
56615
+ FROM ceo_followups
56616
+ WHERE origin_user_id = ?
56617
+ AND status IN ('pending', 'processing', 'failed')
56618
+ `).all(originUserId);
56619
+ const tx = db3.transaction((items) => {
56620
+ const completeStmt = db3.prepare(`
56621
+ UPDATE ceo_followups
56622
+ SET status = 'completed',
56623
+ completed_at = COALESCE(completed_at, ?),
56624
+ updated_at = ?,
56625
+ last_error = NULL
56626
+ WHERE id = ?
56627
+ AND status IN ('pending', 'processing', 'failed')
56628
+ `);
56629
+ const doneStmt = db3.prepare(`
56630
+ UPDATE mailbox
56631
+ SET status = 'done',
56632
+ updated_at = ?
56633
+ WHERE id = ?
56634
+ AND status IN ('pending', 'processing', 'read')
56635
+ `);
56636
+ for (const item of items) {
56637
+ completeStmt.run(now, now, item.id);
56638
+ doneStmt.run(now, item.sourceMessageId);
56639
+ }
56640
+ });
56641
+ tx(rows);
56642
+ return rows.length;
56763
56643
  };
56764
56644
 
56765
56645
  // src/department/mailbox/mailbox.ts
@@ -56957,7 +56837,7 @@ var recordMailboxReceivedAgentEvent = (msg) => {
56957
56837
  };
56958
56838
  var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
56959
56839
  const db3 = createSqliteDB();
56960
- const id = (0, import_node_crypto13.randomUUID)().slice(0, 8);
56840
+ const id = (0, import_node_crypto12.randomUUID)().slice(0, 8);
56961
56841
  const threadId = options?.threadId || id;
56962
56842
  const workItemContext = resolveWorkItemContext(fromMailboxId, toMailboxId, id, options);
56963
56843
  const stmt = db3.prepare(`insert into mailbox (
@@ -57273,7 +57153,7 @@ var departmentCommunicate = {
57273
57153
  };
57274
57154
 
57275
57155
  // src/tools/tools/department/DepartmentCreate.ts
57276
- var import_node_crypto14 = require("node:crypto");
57156
+ var import_node_crypto13 = require("node:crypto");
57277
57157
 
57278
57158
  // src/tasks/goal.ts
57279
57159
  var import_dayjs2 = __toESM(require_dayjs_min());
@@ -57607,7 +57487,7 @@ var departmentCreate = {
57607
57487
  return `[departmentCreate] \u4E0D\u5B58\u5728 id=${sourceGoalId} \u7684\u76EE\u6807`;
57608
57488
  }
57609
57489
  let departmentDefinition = {
57610
- id: (0, import_node_crypto14.randomUUID)().slice(0, 8),
57490
+ id: (0, import_node_crypto13.randomUUID)().slice(0, 8),
57611
57491
  name,
57612
57492
  charter,
57613
57493
  sourceGoalId,
@@ -57676,7 +57556,7 @@ var departmentDelete = {
57676
57556
  // src/department/learning.ts
57677
57557
  var import_node_fs10 = require("node:fs");
57678
57558
  var import_node_path19 = __toESM(require("node:path"));
57679
- var import_node_crypto15 = require("node:crypto");
57559
+ var import_node_crypto14 = require("node:crypto");
57680
57560
 
57681
57561
  // src/skill/SkillValidator.ts
57682
57562
  var import_node_fs9 = require("node:fs");
@@ -57914,7 +57794,7 @@ var listDepartmentMemories = (departmentName) => {
57914
57794
  var createDepartmentMemory = (departmentName, input) => {
57915
57795
  const now = Date.now();
57916
57796
  const memory = {
57917
- id: (0, import_node_crypto15.randomUUID)().slice(0, 8),
57797
+ id: (0, import_node_crypto14.randomUUID)().slice(0, 8),
57918
57798
  departmentName,
57919
57799
  title: input.title,
57920
57800
  content: input.content,
@@ -57965,7 +57845,7 @@ ${formatSkillValidationIssues(validation)}`);
57965
57845
  }
57966
57846
  const now = Date.now();
57967
57847
  const skill = {
57968
- id: (0, import_node_crypto15.randomUUID)().slice(0, 8),
57848
+ id: (0, import_node_crypto14.randomUUID)().slice(0, 8),
57969
57849
  departmentName,
57970
57850
  skillName: input.skillName,
57971
57851
  description: input.description,
@@ -58017,7 +57897,7 @@ var createDepartmentProposal = (input) => {
58017
57897
  const records = readJsonArray(proposalsPath());
58018
57898
  const proposal = {
58019
57899
  ...input,
58020
- id: (0, import_node_crypto15.randomUUID)().slice(0, 8),
57900
+ id: (0, import_node_crypto14.randomUUID)().slice(0, 8),
58021
57901
  status: "pending",
58022
57902
  createdAt: Date.now()
58023
57903
  };
@@ -58295,7 +58175,7 @@ var departmentList = {
58295
58175
  };
58296
58176
 
58297
58177
  // src/tools/tools/department/DepartmentMemberCreate.ts
58298
- var import_node_crypto16 = require("node:crypto");
58178
+ var import_node_crypto15 = require("node:crypto");
58299
58179
  var DESCRIPTION26 = `
58300
58180
  \u521B\u5EFA\u90E8\u95E8\u6210\u5458\u3002
58301
58181
 
@@ -58361,7 +58241,7 @@ var departmentMemberCreate = {
58361
58241
  }
58362
58242
  }
58363
58243
  let departmentMember = {
58364
- id: (0, import_node_crypto16.randomUUID)().slice(0, 8),
58244
+ id: (0, import_node_crypto15.randomUUID)().slice(0, 8),
58365
58245
  name,
58366
58246
  departmentId: department.id,
58367
58247
  mailBoxId: getMailBoxId(department.name, name),
@@ -59367,7 +59247,7 @@ var readDreamHistoryLimit = () => {
59367
59247
  var import_node_fs11 = require("node:fs");
59368
59248
  var import_node_os3 = require("node:os");
59369
59249
  var import_node_path20 = require("node:path");
59370
- var import_node_crypto17 = require("node:crypto");
59250
+ var import_node_crypto16 = require("node:crypto");
59371
59251
  var SkillForgeEngine = class {
59372
59252
  proposalStorage;
59373
59253
  draftRoot;
@@ -59401,7 +59281,7 @@ ${formatSkillValidationIssues(validation)}`);
59401
59281
  if (pending.some((p) => p.skillName === skillName)) {
59402
59282
  return null;
59403
59283
  }
59404
- const id = (0, import_node_crypto17.randomBytes)(4).toString("hex");
59284
+ const id = (0, import_node_crypto16.randomBytes)(4).toString("hex");
59405
59285
  const draftDir = (0, import_node_path20.join)(this.draftRoot, userId, id);
59406
59286
  (0, import_node_fs11.mkdirSync)(draftDir, { recursive: true });
59407
59287
  (0, import_node_fs11.writeFileSync)((0, import_node_path20.join)(draftDir, "SKILL.md"), skillMd, "utf-8");
@@ -60338,7 +60218,7 @@ var RUNTIME_PROCESS_SAFETY_PROMPT = `
60338
60218
  `.trim();
60339
60219
 
60340
60220
  // src/tracing/runtimeTracer.ts
60341
- var import_node_crypto18 = require("node:crypto");
60221
+ var import_node_crypto17 = require("node:crypto");
60342
60222
 
60343
60223
  // src/tracing/redact.ts
60344
60224
  var SECRET_KEY_PATTERN = /(api[-_]?key|token|secret|password|authorization|cookie|private[-_]?key)/i;
@@ -60400,7 +60280,7 @@ var LangSmithRun = class _LangSmithRun {
60400
60280
  extra: { metadata: redactForTrace(input.metadata) }
60401
60281
  });
60402
60282
  await child.postRun();
60403
- return new _LangSmithRun(child.id ?? (0, import_node_crypto18.randomUUID)(), child);
60283
+ return new _LangSmithRun(child.id ?? (0, import_node_crypto17.randomUUID)(), child);
60404
60284
  }
60405
60285
  async end(result) {
60406
60286
  await this.run.end(redactForTrace(result.outputs), result.error);
@@ -60432,11 +60312,186 @@ var createRuntimeTracer = () => {
60432
60312
  })
60433
60313
  });
60434
60314
  await run.postRun();
60435
- return new LangSmithRun(run.id ?? (0, import_node_crypto18.randomUUID)(), run);
60315
+ return new LangSmithRun(run.id ?? (0, import_node_crypto17.randomUUID)(), run);
60436
60316
  }
60437
60317
  };
60438
60318
  };
60439
60319
 
60320
+ // src/agent/outboundDedup.ts
60321
+ var import_node_crypto18 = require("node:crypto");
60322
+ var DEFAULT_WINDOW_MS = 15e3;
60323
+ var recentSends = /* @__PURE__ */ new Map();
60324
+ var lastSweepAt = 0;
60325
+ var normalize3 = (text2) => text2.replace(/\s+/g, " ").trim();
60326
+ var keyFor = (userId, normalized) => {
60327
+ const hash = (0, import_node_crypto18.createHash)("sha1").update(normalized).digest("hex");
60328
+ return `${userId}::${hash}`;
60329
+ };
60330
+ var sweep = (now, windowMs) => {
60331
+ if (now - lastSweepAt < windowMs) return;
60332
+ lastSweepAt = now;
60333
+ for (const [k, ts] of recentSends) {
60334
+ if (now - ts > windowMs) recentSends.delete(k);
60335
+ }
60336
+ };
60337
+ var claimOutboundSend = (userId, text2, windowMs = DEFAULT_WINDOW_MS) => {
60338
+ const normalized = normalize3(text2);
60339
+ if (!normalized) return true;
60340
+ const now = Date.now();
60341
+ sweep(now, windowMs);
60342
+ const key = keyFor(userId, normalized);
60343
+ const last = recentSends.get(key);
60344
+ if (last !== void 0 && now - last < windowMs) {
60345
+ return false;
60346
+ }
60347
+ recentSends.set(key, now);
60348
+ return true;
60349
+ };
60350
+ var claimOutboundFileSend = (userId, fileName, fileRef, windowMs = DEFAULT_WINDOW_MS) => claimOutboundSend(userId, `file:${fileName}:${fileRef}`, windowMs);
60351
+
60352
+ // src/agent/workDossier.ts
60353
+ var textPreview = (value, max = 240) => value.length <= max ? value : `${value.slice(0, max)}...`;
60354
+ var stringArray = (value) => {
60355
+ if (typeof value === `string` && value.trim()) return [value];
60356
+ if (!Array.isArray(value)) return [];
60357
+ return value.filter((item) => typeof item === `string` && item.trim().length > 0);
60358
+ };
60359
+ var findWorkItemIdFromCeoFollowups = (ids) => {
60360
+ if (ids.length === 0) return null;
60361
+ const db3 = createSqliteDB();
60362
+ const placeholders = ids.map(() => `?`).join(`,`);
60363
+ const row = db3.prepare(`
60364
+ SELECT work_item_id as workItemId
60365
+ FROM ceo_followups
60366
+ WHERE id IN (${placeholders})
60367
+ AND work_item_id IS NOT NULL
60368
+ ORDER BY created_at DESC
60369
+ LIMIT 1
60370
+ `).get(...ids);
60371
+ return row?.workItemId ?? null;
60372
+ };
60373
+ var findWorkItemIdFromMailbox = (messageId) => {
60374
+ const db3 = createSqliteDB();
60375
+ const row = db3.prepare(`
60376
+ SELECT work_item_id as workItemId
60377
+ FROM mailbox
60378
+ WHERE id = ?
60379
+ AND work_item_id IS NOT NULL
60380
+ `).get(messageId);
60381
+ return row?.workItemId ?? null;
60382
+ };
60383
+ var workItemIdFromRequest = (request) => {
60384
+ const fromMetadata = request.metadata?.workItemId;
60385
+ if (typeof fromMetadata === `string` && fromMetadata.trim()) return fromMetadata;
60386
+ const followupIds = [
60387
+ ...stringArray(request.metadata?.ceoFollowupId),
60388
+ ...stringArray(request.metadata?.ceoFollowupIds)
60389
+ ];
60390
+ const fromFollowups = findWorkItemIdFromCeoFollowups(followupIds);
60391
+ if (fromFollowups) return fromFollowups;
60392
+ return findWorkItemIdFromMailbox(request.requestId);
60393
+ };
60394
+ var rowsForWorkItem = (workItemId) => {
60395
+ const db3 = createSqliteDB();
60396
+ return db3.prepare(`
60397
+ SELECT
60398
+ id,
60399
+ from_mailbox_id as fromMailboxId,
60400
+ to_mailbox_id as toMailboxId,
60401
+ content,
60402
+ status,
60403
+ work_item_role as workItemRole,
60404
+ send_time as sendTime
60405
+ FROM mailbox
60406
+ WHERE work_item_id = ?
60407
+ ORDER BY send_time ASC
60408
+ LIMIT 12
60409
+ `).all(workItemId);
60410
+ };
60411
+ var buildWorkDossier = (request) => {
60412
+ const role = request.departmentAgentId ? `Department Agent` : `Main Manager/CEO`;
60413
+ const workItemId = workItemIdFromRequest(request);
60414
+ const rows = workItemId ? rowsForWorkItem(workItemId) : [];
60415
+ const progressRows = rows.filter((row) => row.workItemRole === `followup`);
60416
+ const finalRows = rows.filter((row) => row.workItemRole === `upstream_report`);
60417
+ const lines = [
60418
+ `<work-dossier>`,
60419
+ `\u4F60\u7684\u89D2\u8272\uFF1A${role}`,
60420
+ request.departmentAgentId ? `\u5F53\u524D\u90AE\u7BB1\uFF1A${request.departmentAgentId}` : `\u5F53\u524D\u7528\u6237\uFF1A${request.userId}`,
60421
+ workItemId ? `work_item_id\uFF1A${workItemId}` : ``,
60422
+ finalRows.length > 0 ? `\u7528\u6237\u662F\u5426\u5DF2\u6536\u5230\u6700\u7EC8\u7ED3\u679C\uFF1A\u7B49\u5F85 CEO \u7528\u6237\u53EF\u89C1\u6C47\u62A5` : `\u7528\u6237\u662F\u5426\u5DF2\u6536\u5230\u6700\u7EC8\u7ED3\u679C\uFF1A\u5426\u6216\u672A\u77E5`,
60423
+ progressRows.length > 0 ? `\u5185\u90E8\u5F53\u524D\u8FDB\u5C55\uFF1A` : ``,
60424
+ ...progressRows.map((row) => `- ${row.fromMailboxId} -> ${row.toMailboxId}: ${textPreview(row.content)}`),
60425
+ finalRows.length === 0 ? `\u5F53\u524D\u7F3A\u53E3\uFF1A\u8FD8\u6CA1\u6709\u6700\u7EC8\u62A5\u544A` : `\u5F53\u524D\u7F3A\u53E3\uFF1ACEO \u9700\u8981\u6C47\u603B\u6700\u7EC8\u62A5\u544A\u5E76\u5411\u7528\u6237\u4EA4\u4ED8`,
60426
+ finalRows.length === 0 ? `\u5EFA\u8BAE\u52A8\u4F5C\uFF1A\u4E0D\u8981\u91CD\u590D\u5411\u7528\u6237\u64AD\u62A5\u5185\u90E8\u8FDB\u5C55\uFF1B\u7B49\u5F85\u6700\u7EC8\u62A5\u544A\uFF0C\u6216\u5728\u5408\u7406\u7B49\u5F85\u65F6\u95F4\u540E\u5411\u8D1F\u8D23\u4EBA\u8BE2\u95EE\u4E00\u6B21\u3002` : `\u5EFA\u8BAE\u52A8\u4F5C\uFF1A\u6C47\u603B\u6700\u7EC8\u62A5\u544A\uFF0C\u5411\u7528\u6237\u53D1\u9001\u4E00\u6B21\u6E05\u6670\u7B54\u590D\uFF0C\u7136\u540E\u7ED3\u675F\u672C\u8F6E\u3002`,
60427
+ `</work-dossier>`
60428
+ ].filter(Boolean);
60429
+ return lines.join(`
60430
+ `);
60431
+ };
60432
+
60433
+ // src/agent/duclawCoreHooks.ts
60434
+ var duclawTraceIdentity = (request) => {
60435
+ if (!request.departmentAgentId) {
60436
+ return { name: `CEO turn`, role: `ceo` };
60437
+ }
60438
+ const member = getDepartmentMemberByMailboxId(request.departmentAgentId);
60439
+ if (member?.role === `department_head`) {
60440
+ return {
60441
+ name: `Department Head turn: ${request.departmentAgentId}`,
60442
+ role: `department_head`,
60443
+ memberName: member.name,
60444
+ mailboxId: request.departmentAgentId
60445
+ };
60446
+ }
60447
+ if (member?.role === `executor`) {
60448
+ return {
60449
+ name: `Executor turn: ${request.departmentAgentId}`,
60450
+ role: `executor`,
60451
+ memberName: member.name,
60452
+ mailboxId: request.departmentAgentId
60453
+ };
60454
+ }
60455
+ return {
60456
+ name: `Department Agent turn: ${request.departmentAgentId}`,
60457
+ role: `department_agent`,
60458
+ mailboxId: request.departmentAgentId
60459
+ };
60460
+ };
60461
+ var createDuclawCoreHooks = () => ({
60462
+ augmentUserContent({ request, content }) {
60463
+ return attachRecentAttachmentContext(request, content);
60464
+ },
60465
+ completeUserVisibleDelivery({ request }) {
60466
+ const ids = ceoFollowupIdsFromMetadata(request.metadata);
60467
+ if (ids.length > 0) {
60468
+ for (const id of ids) completeCeoFollowup(id);
60469
+ return;
60470
+ }
60471
+ completePendingCeoFollowupsForUser(request.userId);
60472
+ },
60473
+ buildSystemContext({ request }) {
60474
+ return buildWorkDossier(request);
60475
+ },
60476
+ claimOutboundText({ request, text: text2 }) {
60477
+ return claimOutboundSend(request.userId, text2);
60478
+ },
60479
+ claimOutboundFile({ request, fileName, file }) {
60480
+ return claimOutboundFileSend(request.userId, fileName, file);
60481
+ },
60482
+ traceIdentity: duclawTraceIdentity
60483
+ });
60484
+ var ceoFollowupIdsFromMetadata = (metadata) => {
60485
+ const ids = /* @__PURE__ */ new Set();
60486
+ if (typeof metadata?.ceoFollowupId === "string") ids.add(metadata.ceoFollowupId);
60487
+ if (Array.isArray(metadata?.ceoFollowupIds)) {
60488
+ for (const id of metadata.ceoFollowupIds) {
60489
+ if (typeof id === "string") ids.add(id);
60490
+ }
60491
+ }
60492
+ return Array.from(ids);
60493
+ };
60494
+
60440
60495
  // src/agent/duclawAgentConfig.ts
60441
60496
  var DEFAULT_WORKSPACE_PATH = getDuclawWorkspaceDir();
60442
60497
  var getDefaultAgentConfig = (tools, systemPrompt, options = {}) => {
@@ -60676,7 +60731,8 @@ ${getSkillMeta()}
60676
60731
  dreamEngine,
60677
60732
  skillForgeEngine,
60678
60733
  memoryEngine,
60679
- tracer: createRuntimeTracer()
60734
+ tracer: createRuntimeTracer(),
60735
+ hooks: createDuclawCoreHooks()
60680
60736
  };
60681
60737
  return agentConfig;
60682
60738
  };
@@ -67388,7 +67444,7 @@ var systemRoutes = new Hono2();
67388
67444
  var startTime = Date.now();
67389
67445
  systemRoutes.get("/system/info", (c) => {
67390
67446
  return c.json({
67391
- version: true ? "2.0.0" : "unknown",
67447
+ version: true ? "3.0.0" : "unknown",
67392
67448
  uptime: Math.floor((Date.now() - startTime) / 1e3),
67393
67449
  env: process.env.NODE_ENV || "development",
67394
67450
  nodeVersion: process.version