@rei-standard/amsg-server 2.6.0-next.20 → 2.6.0-next.21

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.
@@ -24,10 +24,10 @@
24
24
 
25
25
 
26
26
 
27
- var _chunkWOXSQBAMcjs = require('./chunk-WOXSQBAM.cjs');
28
- require('./chunk-V6NZQ22S.cjs');
29
27
 
30
28
 
29
+ var _chunkQHVID3V2cjs = require('./chunk-QHVID3V2.cjs');
30
+ require('./chunk-7NMQFTDJ.cjs');
31
31
 
32
32
 
33
33
 
@@ -52,4 +52,8 @@ require('./chunk-V6NZQ22S.cjs');
52
52
 
53
53
 
54
54
 
55
- exports.MAX_PUSH_PAYLOAD_BYTES = _chunkWOXSQBAMcjs.MAX_PUSH_PAYLOAD_BYTES; exports.NonRetryableError = _chunkWOXSQBAMcjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunkWOXSQBAMcjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunkWOXSQBAMcjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunkWOXSQBAMcjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunkWOXSQBAMcjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunkWOXSQBAMcjs.advanceOccurrence; exports.createD1Adapter = _chunkWOXSQBAMcjs.createD1Adapter; exports.createSingleUserCloudflareWorker = _chunkWOXSQBAMcjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunkWOXSQBAMcjs.createSingleUserServer; exports.createWebCryptoWebPush = _chunkWOXSQBAMcjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunkWOXSQBAMcjs.decryptFromStorage; exports.decryptPayload = _chunkWOXSQBAMcjs.decryptPayload; exports.deriveUserEncryptionKey = _chunkWOXSQBAMcjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunkWOXSQBAMcjs.encryptForStorage; exports.ensureSchema = _chunkWOXSQBAMcjs.ensureSchema; exports.getSchemaVersion = _chunkWOXSQBAMcjs.getSchemaVersion; exports.isNonRetryableError = _chunkWOXSQBAMcjs.isNonRetryableError; exports.isValidTimeZoneId = _chunkWOXSQBAMcjs.isValidTimeZoneId; exports.measurePushPayload = _chunkWOXSQBAMcjs.measurePushPayload; exports.nextFutureOccurrence = _chunkWOXSQBAMcjs.nextFutureOccurrence; exports.planNextOccurrence = _chunkWOXSQBAMcjs.planNextOccurrence; exports.runScheduledTick = _chunkWOXSQBAMcjs.runScheduledTick; exports.runTask = _chunkWOXSQBAMcjs.runTask; exports.summarizeErrorCause = _chunkWOXSQBAMcjs.summarizeErrorCause;
55
+
56
+
57
+
58
+
59
+ exports.DEFAULT_MAX_REQUEST_BODY_BYTES = _chunkQHVID3V2cjs.DEFAULT_MAX_REQUEST_BODY_BYTES; exports.MAX_PUSH_PAYLOAD_BYTES = _chunkQHVID3V2cjs.MAX_PUSH_PAYLOAD_BYTES; exports.NonRetryableError = _chunkQHVID3V2cjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunkQHVID3V2cjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunkQHVID3V2cjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunkQHVID3V2cjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunkQHVID3V2cjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunkQHVID3V2cjs.advanceOccurrence; exports.createD1Adapter = _chunkQHVID3V2cjs.createD1Adapter; exports.createSingleUserCloudflareWorker = _chunkQHVID3V2cjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunkQHVID3V2cjs.createSingleUserServer; exports.createWebCryptoWebPush = _chunkQHVID3V2cjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunkQHVID3V2cjs.decryptFromStorage; exports.decryptPayload = _chunkQHVID3V2cjs.decryptPayload; exports.deriveUserEncryptionKey = _chunkQHVID3V2cjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunkQHVID3V2cjs.encryptForStorage; exports.ensureSchema = _chunkQHVID3V2cjs.ensureSchema; exports.getSchemaVersion = _chunkQHVID3V2cjs.getSchemaVersion; exports.isNonRetryableError = _chunkQHVID3V2cjs.isNonRetryableError; exports.isValidTimeZoneId = _chunkQHVID3V2cjs.isValidTimeZoneId; exports.measurePushPayload = _chunkQHVID3V2cjs.measurePushPayload; exports.nextFutureOccurrence = _chunkQHVID3V2cjs.nextFutureOccurrence; exports.planNextOccurrence = _chunkQHVID3V2cjs.planNextOccurrence; exports.readRequestBody = _chunkQHVID3V2cjs.readRequestBody; exports.runScheduledTick = _chunkQHVID3V2cjs.runScheduledTick; exports.runTask = _chunkQHVID3V2cjs.runTask; exports.summarizeErrorCause = _chunkQHVID3V2cjs.summarizeErrorCause;
@@ -6,4 +6,5 @@ export { runScheduledTick, runTask } from "./lib/run-tick.js";
6
6
  export { getSchemaVersion, ensureSchema, SCHEMA_VERSION } from "./lib/schema-version.js";
7
7
  export { summarizeErrorCause, NonRetryableError, isNonRetryableError } from "./lib/errors.js";
8
8
  export { isValidTimeZoneId, advanceOccurrence, nextFutureOccurrence, planNextOccurrence } from "./lib/recurrence.js";
9
+ export { readRequestBody, DEFAULT_MAX_REQUEST_BODY_BYTES } from "./lib/request.js";
9
10
  export { deriveUserEncryptionKey, decryptPayload, encryptForStorage, decryptFromStorage } from "./lib/encryption.js";
@@ -1,4 +1,5 @@
1
1
  import {
2
+ DEFAULT_MAX_REQUEST_BODY_BYTES,
2
3
  MAX_PUSH_PAYLOAD_BYTES,
3
4
  NonRetryableError,
4
5
  PUSH_ENVELOPE_RESERVED_BYTES,
@@ -21,12 +22,14 @@ import {
21
22
  measurePushPayload,
22
23
  nextFutureOccurrence,
23
24
  planNextOccurrence,
25
+ readRequestBody,
24
26
  runScheduledTick,
25
27
  runTask,
26
28
  summarizeErrorCause
27
- } from "./chunk-HTGYGGUH.mjs";
28
- import "./chunk-5FXVSC5O.mjs";
29
+ } from "./chunk-KOJQVOYS.mjs";
30
+ import "./chunk-GN44PST5.mjs";
29
31
  export {
32
+ DEFAULT_MAX_REQUEST_BODY_BYTES,
30
33
  MAX_PUSH_PAYLOAD_BYTES,
31
34
  NonRetryableError,
32
35
  PUSH_ENVELOPE_RESERVED_BYTES,
@@ -49,6 +52,7 @@ export {
49
52
  measurePushPayload,
50
53
  nextFutureOccurrence,
51
54
  planNextOccurrence,
55
+ readRequestBody,
52
56
  runScheduledTick,
53
57
  runTask,
54
58
  summarizeErrorCause
package/dist/index.cjs CHANGED
@@ -67,8 +67,12 @@
67
67
 
68
68
 
69
69
 
70
- var _chunkWOXSQBAMcjs = require('./chunk-WOXSQBAM.cjs');
71
- require('./chunk-V6NZQ22S.cjs');
70
+
71
+
72
+
73
+
74
+ var _chunkQHVID3V2cjs = require('./chunk-QHVID3V2.cjs');
75
+ require('./chunk-7NMQFTDJ.cjs');
72
76
 
73
77
  // src/server/adapters/factory.js
74
78
  async function createAdapter(config) {
@@ -84,11 +88,11 @@ async function createAdapter(config) {
84
88
  }
85
89
  switch (config.driver) {
86
90
  case "neon": {
87
- const { NeonAdapter } = await Promise.resolve().then(() => _interopRequireWildcard(require("./neon-U6TQFKMJ.cjs")));
91
+ const { NeonAdapter } = await Promise.resolve().then(() => _interopRequireWildcard(require("./neon-KP2CPA57.cjs")));
88
92
  return new NeonAdapter(config.connectionString);
89
93
  }
90
94
  case "pg": {
91
- const { PgAdapter } = await Promise.resolve().then(() => _interopRequireWildcard(require("./pg-B324Q2R4.cjs")));
95
+ const { PgAdapter } = await Promise.resolve().then(() => _interopRequireWildcard(require("./pg-RZPQGXR3.cjs")));
92
96
  return new PgAdapter(config.connectionString);
93
97
  }
94
98
  default:
@@ -101,7 +105,7 @@ async function createAdapter(config) {
101
105
  // src/server/handlers/init-tenant.js
102
106
  function createInitTenantHandler(ctx) {
103
107
  async function POST(headers, body) {
104
- const initSecret = _chunkWOXSQBAMcjs.getHeader.call(void 0, headers, "x-init-secret");
108
+ const initSecret = _chunkQHVID3V2cjs.getHeader.call(void 0, headers, "x-init-secret");
105
109
  if (ctx.tenant.initSecret && initSecret !== ctx.tenant.initSecret) {
106
110
  return {
107
111
  status: 401,
@@ -114,7 +118,7 @@ function createInitTenantHandler(ctx) {
114
118
  }
115
119
  };
116
120
  }
117
- const parsed = _chunkWOXSQBAMcjs.parseJsonBody.call(void 0, body);
121
+ const parsed = _chunkQHVID3V2cjs.parseJsonBody.call(void 0, body);
118
122
  if (!parsed.ok) {
119
123
  return {
120
124
  status: 400,
@@ -128,7 +132,7 @@ function createInitTenantHandler(ctx) {
128
132
  const tenantId = payload.tenantId || void 0;
129
133
  const driver = payload.driver;
130
134
  const databaseUrl = payload.databaseUrl || payload.connectionString;
131
- if (tenantId && !_chunkWOXSQBAMcjs.isValidUUIDv4.call(void 0, tenantId)) {
135
+ if (tenantId && !_chunkQHVID3V2cjs.isValidUUIDv4.call(void 0, tenantId)) {
132
136
  return {
133
137
  status: 400,
134
138
  body: {
@@ -248,7 +252,7 @@ function createSendNotificationsHandler(ctx) {
248
252
  }
249
253
  };
250
254
  }
251
- const data = await _chunkWOXSQBAMcjs.runScheduledTick.call(void 0, { ...ctx, db, masterKey });
255
+ const data = await _chunkQHVID3V2cjs.runScheduledTick.call(void 0, { ...ctx, db, masterKey });
252
256
  return { status: 200, body: { success: true, data } };
253
257
  }
254
258
  return { POST };
@@ -270,16 +274,16 @@ function encryptConfig(config, kekBuffer) {
270
274
  const plaintext = Buffer.from(JSON.stringify(config), "utf8");
271
275
  const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
272
276
  const authTag = cipher.getAuthTag();
273
- return `v1.${_chunkWOXSQBAMcjs.bytesToBase64Url.call(void 0, iv)}.${_chunkWOXSQBAMcjs.bytesToBase64Url.call(void 0, authTag)}.${_chunkWOXSQBAMcjs.bytesToBase64Url.call(void 0, ciphertext)}`;
277
+ return `v1.${_chunkQHVID3V2cjs.bytesToBase64Url.call(void 0, iv)}.${_chunkQHVID3V2cjs.bytesToBase64Url.call(void 0, authTag)}.${_chunkQHVID3V2cjs.bytesToBase64Url.call(void 0, ciphertext)}`;
274
278
  }
275
279
  function decryptConfig(encrypted, kekBuffer) {
276
280
  const parts = String(encrypted || "").split(".");
277
281
  if (parts.length !== 4 || parts[0] !== "v1") {
278
282
  throw new Error("INVALID_TENANT_CONFIG");
279
283
  }
280
- const iv = _chunkWOXSQBAMcjs.base64UrlToBytes.call(void 0, parts[1]);
281
- const authTag = _chunkWOXSQBAMcjs.base64UrlToBytes.call(void 0, parts[2]);
282
- const ciphertext = _chunkWOXSQBAMcjs.base64UrlToBytes.call(void 0, parts[3]);
284
+ const iv = _chunkQHVID3V2cjs.base64UrlToBytes.call(void 0, parts[1]);
285
+ const authTag = _chunkQHVID3V2cjs.base64UrlToBytes.call(void 0, parts[2]);
286
+ const ciphertext = _chunkQHVID3V2cjs.base64UrlToBytes.call(void 0, parts[3]);
283
287
  const decipher = _crypto.createDecipheriv.call(void 0, "aes-256-gcm", kekBuffer, iv);
284
288
  decipher.setAuthTag(authTag);
285
289
  const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
@@ -347,7 +351,7 @@ function createTenantBlobStore(options) {
347
351
  // src/server/tenant/token.js
348
352
 
349
353
  function sign(input, secret) {
350
- return _chunkWOXSQBAMcjs.bytesToBase64Url.call(void 0, _crypto.createHmac.call(void 0, "sha256", secret).update(input).digest());
354
+ return _chunkQHVID3V2cjs.bytesToBase64Url.call(void 0, _crypto.createHmac.call(void 0, "sha256", secret).update(input).digest());
351
355
  }
352
356
  function nowEpochSeconds() {
353
357
  return Math.floor(Date.now() / 1e3);
@@ -363,8 +367,8 @@ function createTenantToken(params, secret) {
363
367
  v: 1
364
368
  };
365
369
  const header = { alg: "HS256", typ: "JWT" };
366
- const encodedHeader = _chunkWOXSQBAMcjs.bytesToBase64Url.call(void 0, _chunkWOXSQBAMcjs.utf8.call(void 0, JSON.stringify(header)));
367
- const encodedPayload = _chunkWOXSQBAMcjs.bytesToBase64Url.call(void 0, _chunkWOXSQBAMcjs.utf8.call(void 0, JSON.stringify(payload)));
370
+ const encodedHeader = _chunkQHVID3V2cjs.bytesToBase64Url.call(void 0, _chunkQHVID3V2cjs.utf8.call(void 0, JSON.stringify(header)));
371
+ const encodedPayload = _chunkQHVID3V2cjs.bytesToBase64Url.call(void 0, _chunkQHVID3V2cjs.utf8.call(void 0, JSON.stringify(payload)));
368
372
  const signingInput = `${encodedHeader}.${encodedPayload}`;
369
373
  const signature = sign(signingInput, secret);
370
374
  return `${signingInput}.${signature}`;
@@ -383,17 +387,17 @@ function verifyTenantToken(token, secret, options = {}) {
383
387
  let receivedBytes;
384
388
  let expectedBytes;
385
389
  try {
386
- receivedBytes = _chunkWOXSQBAMcjs.base64UrlToBytes.call(void 0, receivedSignature);
387
- expectedBytes = _chunkWOXSQBAMcjs.base64UrlToBytes.call(void 0, expectedSignature);
390
+ receivedBytes = _chunkQHVID3V2cjs.base64UrlToBytes.call(void 0, receivedSignature);
391
+ expectedBytes = _chunkQHVID3V2cjs.base64UrlToBytes.call(void 0, expectedSignature);
388
392
  } catch (e) {
389
393
  throw new Error("INVALID_TENANT_AUTH");
390
394
  }
391
- if (!_chunkWOXSQBAMcjs.timingSafeEqualBytes.call(void 0, receivedBytes, expectedBytes)) {
395
+ if (!_chunkQHVID3V2cjs.timingSafeEqualBytes.call(void 0, receivedBytes, expectedBytes)) {
392
396
  throw new Error("INVALID_TENANT_AUTH");
393
397
  }
394
398
  let payload;
395
399
  try {
396
- payload = JSON.parse(_chunkWOXSQBAMcjs.utf8Decode.call(void 0, _chunkWOXSQBAMcjs.base64UrlToBytes.call(void 0, encodedPayload)));
400
+ payload = JSON.parse(_chunkQHVID3V2cjs.utf8Decode.call(void 0, _chunkQHVID3V2cjs.base64UrlToBytes.call(void 0, encodedPayload)));
397
401
  } catch (e2) {
398
402
  throw new Error("INVALID_TENANT_AUTH");
399
403
  }
@@ -605,6 +609,10 @@ async function createReiServer(config) {
605
609
  privateKey: vapid.privateKey || ""
606
610
  },
607
611
  webpush: webpushModule,
612
+ // 分片传输的限额(与 installReiSW 的 multipart 同一份)。instant 消息在
613
+ // schedule-message 里就地投递、定时消息走 send-notifications 的 tick,两条路
614
+ // 都从这个 ctx 展开,所以配一次两边都认。
615
+ multipart: config.multipart || null,
608
616
  tenant: {
609
617
  initSecret
610
618
  },
@@ -613,15 +621,15 @@ async function createReiServer(config) {
613
621
  return {
614
622
  handlers: {
615
623
  initTenant: createInitTenantHandler(ctx),
616
- getUserKey: _chunkWOXSQBAMcjs.createGetUserKeyHandler.call(void 0, ctx),
617
- scheduleMessage: _chunkWOXSQBAMcjs.createScheduleMessageHandler.call(void 0, ctx),
624
+ getUserKey: _chunkQHVID3V2cjs.createGetUserKeyHandler.call(void 0, ctx),
625
+ scheduleMessage: _chunkQHVID3V2cjs.createScheduleMessageHandler.call(void 0, ctx),
618
626
  sendNotifications: createSendNotificationsHandler(ctx),
619
- updateMessage: _chunkWOXSQBAMcjs.createUpdateMessageHandler.call(void 0, ctx),
620
- cancelMessage: _chunkWOXSQBAMcjs.createCancelMessageHandler.call(void 0, ctx),
621
- messages: _chunkWOXSQBAMcjs.createMessagesHandler.call(void 0, ctx),
622
- getMessage: _chunkWOXSQBAMcjs.createGetMessageHandler.call(void 0, ctx),
623
- pushSubscription: _chunkWOXSQBAMcjs.createPushSubscriptionHandler.call(void 0, ctx),
624
- llmCredentials: _chunkWOXSQBAMcjs.createLlmCredentialsHandler.call(void 0, ctx)
627
+ updateMessage: _chunkQHVID3V2cjs.createUpdateMessageHandler.call(void 0, ctx),
628
+ cancelMessage: _chunkQHVID3V2cjs.createCancelMessageHandler.call(void 0, ctx),
629
+ messages: _chunkQHVID3V2cjs.createMessagesHandler.call(void 0, ctx),
630
+ getMessage: _chunkQHVID3V2cjs.createGetMessageHandler.call(void 0, ctx),
631
+ pushSubscription: _chunkQHVID3V2cjs.createPushSubscriptionHandler.call(void 0, ctx),
632
+ llmCredentials: _chunkQHVID3V2cjs.createLlmCredentialsHandler.call(void 0, ctx)
625
633
  }
626
634
  };
627
635
  }
@@ -683,4 +691,8 @@ async function createReiServer(config) {
683
691
 
684
692
 
685
693
 
686
- exports.CORS_ALLOW_HEADERS = _chunkWOXSQBAMcjs.CORS_ALLOW_HEADERS; exports.CORS_ALLOW_METHODS = _chunkWOXSQBAMcjs.CORS_ALLOW_METHODS; exports.CRED_ID_MAX_LENGTH = _chunkWOXSQBAMcjs.CRED_ID_MAX_LENGTH; exports.CRED_PUT_BATCH_MAX = _chunkWOXSQBAMcjs.CRED_PUT_BATCH_MAX; exports.CRED_REFS_MAX_ENTRIES = _chunkWOXSQBAMcjs.CRED_REFS_MAX_ENTRIES; exports.CRED_ROWS_PER_USER_MAX = _chunkWOXSQBAMcjs.CRED_ROWS_PER_USER_MAX; exports.DEFAULT_CLAIM_LEASE_MS = _chunkWOXSQBAMcjs.DEFAULT_CLAIM_LEASE_MS; exports.DEFAULT_HEARTBEAT_LEASE_TTL_MS = _chunkWOXSQBAMcjs.DEFAULT_HEARTBEAT_LEASE_TTL_MS; exports.DEFAULT_LEASE_HEARTBEAT_MS = _chunkWOXSQBAMcjs.DEFAULT_LEASE_HEARTBEAT_MS; exports.DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE = _chunkWOXSQBAMcjs.DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE; exports.DEFAULT_MAX_TOOL_ITERATIONS = _chunkWOXSQBAMcjs.DEFAULT_MAX_TOOL_ITERATIONS; exports.DEFAULT_TOTAL_TIMEOUT_MS = _chunkWOXSQBAMcjs.DEFAULT_TOTAL_TIMEOUT_MS; exports.MAX_PUSH_PAYLOAD_BYTES = _chunkWOXSQBAMcjs.MAX_PUSH_PAYLOAD_BYTES; exports.MIN_SCHEDULE_LEAD_MS = _chunkWOXSQBAMcjs.MIN_SCHEDULE_LEAD_MS; exports.NonRetryableError = _chunkWOXSQBAMcjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunkWOXSQBAMcjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunkWOXSQBAMcjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunkWOXSQBAMcjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunkWOXSQBAMcjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunkWOXSQBAMcjs.advanceOccurrence; exports.createAdapter = createAdapter; exports.createD1Adapter = _chunkWOXSQBAMcjs.createD1Adapter; exports.createReiServer = createReiServer; exports.createSingleUserCloudflareWorker = _chunkWOXSQBAMcjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunkWOXSQBAMcjs.createSingleUserServer; exports.createTenantToken = createTenantToken; exports.createWebCryptoWebPush = _chunkWOXSQBAMcjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunkWOXSQBAMcjs.decryptFromStorage; exports.decryptPayload = _chunkWOXSQBAMcjs.decryptPayload; exports.deriveUserEncryptionKey = _chunkWOXSQBAMcjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunkWOXSQBAMcjs.encryptForStorage; exports.ensureSchema = _chunkWOXSQBAMcjs.ensureSchema; exports.getSchemaVersion = _chunkWOXSQBAMcjs.getSchemaVersion; exports.hasChatCredRef = _chunkWOXSQBAMcjs.hasChatCredRef; exports.isNonRetryableError = _chunkWOXSQBAMcjs.isNonRetryableError; exports.isValidCredId = _chunkWOXSQBAMcjs.isValidCredId; exports.isValidISO8601 = _chunkWOXSQBAMcjs.isValidISO8601; exports.isValidTimeZoneId = _chunkWOXSQBAMcjs.isValidTimeZoneId; exports.isValidUUID = _chunkWOXSQBAMcjs.isValidUUID; exports.isValidUUIDv4 = _chunkWOXSQBAMcjs.isValidUUIDv4; exports.isValidUrl = _chunkWOXSQBAMcjs.isValidUrl; exports.measurePushPayload = _chunkWOXSQBAMcjs.measurePushPayload; exports.nextFutureOccurrence = _chunkWOXSQBAMcjs.nextFutureOccurrence; exports.planNextOccurrence = _chunkWOXSQBAMcjs.planNextOccurrence; exports.resolveLlmCredential = _chunkWOXSQBAMcjs.resolveLlmCredential; exports.runScheduledTick = _chunkWOXSQBAMcjs.runScheduledTick; exports.runTask = _chunkWOXSQBAMcjs.runTask; exports.sanitizeErrorSummary = _chunkWOXSQBAMcjs.sanitizeErrorSummary; exports.summarizeErrorCause = _chunkWOXSQBAMcjs.summarizeErrorCause; exports.supportsLlmCredentialsStore = _chunkWOXSQBAMcjs.supportsLlmCredentialsStore; exports.validateAvatarUrl = _chunkWOXSQBAMcjs.validateAvatarUrl; exports.validateCredRefs = _chunkWOXSQBAMcjs.validateCredRefs; exports.validateCredValue = _chunkWOXSQBAMcjs.validateCredValue; exports.validateLlmMessagesArray = _chunkWOXSQBAMcjs.validateLlmMessagesArray; exports.validateScheduleMessagePayload = _chunkWOXSQBAMcjs.validateScheduleMessagePayload; exports.validateSplitPattern = _chunkWOXSQBAMcjs.validateSplitPattern; exports.verifyTenantToken = verifyTenantToken;
694
+
695
+
696
+
697
+
698
+ exports.CORS_ALLOW_HEADERS = _chunkQHVID3V2cjs.CORS_ALLOW_HEADERS; exports.CORS_ALLOW_METHODS = _chunkQHVID3V2cjs.CORS_ALLOW_METHODS; exports.CRED_ID_MAX_LENGTH = _chunkQHVID3V2cjs.CRED_ID_MAX_LENGTH; exports.CRED_PUT_BATCH_MAX = _chunkQHVID3V2cjs.CRED_PUT_BATCH_MAX; exports.CRED_REFS_MAX_ENTRIES = _chunkQHVID3V2cjs.CRED_REFS_MAX_ENTRIES; exports.CRED_ROWS_PER_USER_MAX = _chunkQHVID3V2cjs.CRED_ROWS_PER_USER_MAX; exports.DEFAULT_CLAIM_LEASE_MS = _chunkQHVID3V2cjs.DEFAULT_CLAIM_LEASE_MS; exports.DEFAULT_HEARTBEAT_LEASE_TTL_MS = _chunkQHVID3V2cjs.DEFAULT_HEARTBEAT_LEASE_TTL_MS; exports.DEFAULT_LEASE_HEARTBEAT_MS = _chunkQHVID3V2cjs.DEFAULT_LEASE_HEARTBEAT_MS; exports.DEFAULT_MAX_REQUEST_BODY_BYTES = _chunkQHVID3V2cjs.DEFAULT_MAX_REQUEST_BODY_BYTES; exports.DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE = _chunkQHVID3V2cjs.DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE; exports.DEFAULT_MAX_TOOL_ITERATIONS = _chunkQHVID3V2cjs.DEFAULT_MAX_TOOL_ITERATIONS; exports.DEFAULT_TOTAL_TIMEOUT_MS = _chunkQHVID3V2cjs.DEFAULT_TOTAL_TIMEOUT_MS; exports.DeploymentConfigError = _chunkQHVID3V2cjs.DeploymentConfigError; exports.MAX_PUSH_PAYLOAD_BYTES = _chunkQHVID3V2cjs.MAX_PUSH_PAYLOAD_BYTES; exports.MAX_TASK_PAYLOAD_BYTES = _chunkQHVID3V2cjs.MAX_TASK_PAYLOAD_BYTES; exports.MIN_SCHEDULE_LEAD_MS = _chunkQHVID3V2cjs.MIN_SCHEDULE_LEAD_MS; exports.NonRetryableError = _chunkQHVID3V2cjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunkQHVID3V2cjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunkQHVID3V2cjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunkQHVID3V2cjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunkQHVID3V2cjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunkQHVID3V2cjs.advanceOccurrence; exports.createAdapter = createAdapter; exports.createD1Adapter = _chunkQHVID3V2cjs.createD1Adapter; exports.createReiServer = createReiServer; exports.createSingleUserCloudflareWorker = _chunkQHVID3V2cjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunkQHVID3V2cjs.createSingleUserServer; exports.createTenantToken = createTenantToken; exports.createWebCryptoWebPush = _chunkQHVID3V2cjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunkQHVID3V2cjs.decryptFromStorage; exports.decryptPayload = _chunkQHVID3V2cjs.decryptPayload; exports.deriveUserEncryptionKey = _chunkQHVID3V2cjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunkQHVID3V2cjs.encryptForStorage; exports.ensureSchema = _chunkQHVID3V2cjs.ensureSchema; exports.getSchemaVersion = _chunkQHVID3V2cjs.getSchemaVersion; exports.hasChatCredRef = _chunkQHVID3V2cjs.hasChatCredRef; exports.isNonRetryableError = _chunkQHVID3V2cjs.isNonRetryableError; exports.isValidCredId = _chunkQHVID3V2cjs.isValidCredId; exports.isValidISO8601 = _chunkQHVID3V2cjs.isValidISO8601; exports.isValidTimeZoneId = _chunkQHVID3V2cjs.isValidTimeZoneId; exports.isValidUUID = _chunkQHVID3V2cjs.isValidUUID; exports.isValidUUIDv4 = _chunkQHVID3V2cjs.isValidUUIDv4; exports.isValidUrl = _chunkQHVID3V2cjs.isValidUrl; exports.measurePushPayload = _chunkQHVID3V2cjs.measurePushPayload; exports.nextFutureOccurrence = _chunkQHVID3V2cjs.nextFutureOccurrence; exports.planNextOccurrence = _chunkQHVID3V2cjs.planNextOccurrence; exports.readRequestBody = _chunkQHVID3V2cjs.readRequestBody; exports.resolveLlmCredential = _chunkQHVID3V2cjs.resolveLlmCredential; exports.runScheduledTick = _chunkQHVID3V2cjs.runScheduledTick; exports.runTask = _chunkQHVID3V2cjs.runTask; exports.sanitizeErrorSummary = _chunkQHVID3V2cjs.sanitizeErrorSummary; exports.summarizeErrorCause = _chunkQHVID3V2cjs.summarizeErrorCause; exports.supportsLlmCredentialsStore = _chunkQHVID3V2cjs.supportsLlmCredentialsStore; exports.validateAvatarUrl = _chunkQHVID3V2cjs.validateAvatarUrl; exports.validateCredRefs = _chunkQHVID3V2cjs.validateCredRefs; exports.validateCredValue = _chunkQHVID3V2cjs.validateCredValue; exports.validateLlmMessagesArray = _chunkQHVID3V2cjs.validateLlmMessagesArray; exports.validateScheduleMessagePayload = _chunkQHVID3V2cjs.validateScheduleMessagePayload; exports.validateSplitPattern = _chunkQHVID3V2cjs.validateSplitPattern; exports.verifyTenantToken = verifyTenantToken;
package/dist/index.d.cts CHANGED
@@ -18,6 +18,11 @@
18
18
  * @typedef {Object} ReiServerConfig
19
19
  * @property {VapidConfig} [vapid] - VAPID keys for Web Push.
20
20
  * @property {TenantServerConfig} tenant - Tenant config & auth settings.
21
+ * @property {{ maxChunkBytes?: number, maxChunks?: number, maxTotalBytes?: number, ttlMs?: number }} [multipart]
22
+ * 分片传输的限额,跟传给 `installReiSW` 的那一份保持一致(同名同键,原样传过来
23
+ * 即可)。一条 push 装不下的思考过程要切片发,切多大、最多几片、重组窗口多长由
24
+ * 接收端说了算——发送端不知道这份配置的话,切出来的分片到了那边会被逐片拒收,
25
+ * 或者整批没能在重组窗口内发完,一条也拼不回来。不配 = 两边都用默认值。
21
26
  */
22
27
  /**
23
28
  * @typedef {Object} ReiHandlers
@@ -98,6 +103,18 @@ export type ReiServerConfig = {
98
103
  * - Tenant config & auth settings.
99
104
  */
100
105
  tenant: TenantServerConfig;
106
+ /**
107
+ * 分片传输的限额,跟传给 `installReiSW` 的那一份保持一致(同名同键,原样传过来
108
+ * 即可)。一条 push 装不下的思考过程要切片发,切多大、最多几片、重组窗口多长由
109
+ * 接收端说了算——发送端不知道这份配置的话,切出来的分片到了那边会被逐片拒收,
110
+ * 或者整批没能在重组窗口内发完,一条也拼不回来。不配 = 两边都用默认值。
111
+ */
112
+ multipart?: {
113
+ maxChunkBytes?: number;
114
+ maxChunks?: number;
115
+ maxTotalBytes?: number;
116
+ ttlMs?: number;
117
+ };
101
118
  };
102
119
  export type ReiHandlers = {
103
120
  initTenant: {
@@ -142,13 +159,14 @@ export type ReiServer = {
142
159
  handlers: ReiHandlers;
143
160
  };
144
161
  export { runScheduledTick, runTask, DEFAULT_CLAIM_LEASE_MS, DEFAULT_LEASE_HEARTBEAT_MS, DEFAULT_HEARTBEAT_LEASE_TTL_MS, sanitizeErrorSummary } from "./lib/run-tick.js";
145
- export { NonRetryableError, isNonRetryableError, summarizeErrorCause } from "./lib/errors.js";
162
+ export { NonRetryableError, DeploymentConfigError, isNonRetryableError, summarizeErrorCause } from "./lib/errors.js";
146
163
  export { getSchemaVersion, ensureSchema, SCHEMA_VERSION } from "./lib/schema-version.js";
147
164
  export { DEFAULT_MAX_TOOL_ITERATIONS, DEFAULT_TOTAL_TIMEOUT_MS, DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE, MIN_SCHEDULE_LEAD_MS } from "./lib/agentic-fire.js";
148
165
  export { CORS_ALLOW_HEADERS, CORS_ALLOW_METHODS, createSingleUserCloudflareWorker } from "./cloudflare/single-user-worker.js";
149
166
  export { createWebCryptoWebPush, measurePushPayload, MAX_PUSH_PAYLOAD_BYTES, PUSH_ENVELOPE_RESERVED_BYTES, WEB_PUSH_MAX_BODY_BYTES, WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES } from "./lib/webpush-webcrypto.js";
150
167
  export { deriveUserEncryptionKey, decryptPayload, encryptForStorage, decryptFromStorage } from "./lib/encryption.js";
151
- export { validateScheduleMessagePayload, validateLlmMessagesArray, validateSplitPattern, validateAvatarUrl, isValidISO8601, isValidUrl, isValidUUID, isValidUUIDv4, isValidTimeZoneId } from "./lib/validation.js";
168
+ export { validateScheduleMessagePayload, validateLlmMessagesArray, validateSplitPattern, validateAvatarUrl, isValidISO8601, isValidUrl, isValidUUID, isValidUUIDv4, isValidTimeZoneId, MAX_TASK_PAYLOAD_BYTES } from "./lib/validation.js";
169
+ export { readRequestBody, DEFAULT_MAX_REQUEST_BODY_BYTES } from "./lib/request.js";
152
170
  export { supportsLlmCredentialsStore, isValidCredId, validateCredRefs, validateCredValue, hasChatCredRef, resolveLlmCredential, CRED_ID_MAX_LENGTH, CRED_PUT_BATCH_MAX, CRED_ROWS_PER_USER_MAX, CRED_REFS_MAX_ENTRIES } from "./lib/llm-credentials-store.js";
153
171
  export { advanceOccurrence, nextFutureOccurrence, planNextOccurrence } from "./lib/recurrence.js";
154
172
  export { createTenantToken, verifyTenantToken } from "./tenant/token.js";
package/dist/index.d.ts CHANGED
@@ -18,6 +18,11 @@
18
18
  * @typedef {Object} ReiServerConfig
19
19
  * @property {VapidConfig} [vapid] - VAPID keys for Web Push.
20
20
  * @property {TenantServerConfig} tenant - Tenant config & auth settings.
21
+ * @property {{ maxChunkBytes?: number, maxChunks?: number, maxTotalBytes?: number, ttlMs?: number }} [multipart]
22
+ * 分片传输的限额,跟传给 `installReiSW` 的那一份保持一致(同名同键,原样传过来
23
+ * 即可)。一条 push 装不下的思考过程要切片发,切多大、最多几片、重组窗口多长由
24
+ * 接收端说了算——发送端不知道这份配置的话,切出来的分片到了那边会被逐片拒收,
25
+ * 或者整批没能在重组窗口内发完,一条也拼不回来。不配 = 两边都用默认值。
21
26
  */
22
27
  /**
23
28
  * @typedef {Object} ReiHandlers
@@ -98,6 +103,18 @@ export type ReiServerConfig = {
98
103
  * - Tenant config & auth settings.
99
104
  */
100
105
  tenant: TenantServerConfig;
106
+ /**
107
+ * 分片传输的限额,跟传给 `installReiSW` 的那一份保持一致(同名同键,原样传过来
108
+ * 即可)。一条 push 装不下的思考过程要切片发,切多大、最多几片、重组窗口多长由
109
+ * 接收端说了算——发送端不知道这份配置的话,切出来的分片到了那边会被逐片拒收,
110
+ * 或者整批没能在重组窗口内发完,一条也拼不回来。不配 = 两边都用默认值。
111
+ */
112
+ multipart?: {
113
+ maxChunkBytes?: number;
114
+ maxChunks?: number;
115
+ maxTotalBytes?: number;
116
+ ttlMs?: number;
117
+ };
101
118
  };
102
119
  export type ReiHandlers = {
103
120
  initTenant: {
@@ -142,13 +159,14 @@ export type ReiServer = {
142
159
  handlers: ReiHandlers;
143
160
  };
144
161
  export { runScheduledTick, runTask, DEFAULT_CLAIM_LEASE_MS, DEFAULT_LEASE_HEARTBEAT_MS, DEFAULT_HEARTBEAT_LEASE_TTL_MS, sanitizeErrorSummary } from "./lib/run-tick.js";
145
- export { NonRetryableError, isNonRetryableError, summarizeErrorCause } from "./lib/errors.js";
162
+ export { NonRetryableError, DeploymentConfigError, isNonRetryableError, summarizeErrorCause } from "./lib/errors.js";
146
163
  export { getSchemaVersion, ensureSchema, SCHEMA_VERSION } from "./lib/schema-version.js";
147
164
  export { DEFAULT_MAX_TOOL_ITERATIONS, DEFAULT_TOTAL_TIMEOUT_MS, DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE, MIN_SCHEDULE_LEAD_MS } from "./lib/agentic-fire.js";
148
165
  export { CORS_ALLOW_HEADERS, CORS_ALLOW_METHODS, createSingleUserCloudflareWorker } from "./cloudflare/single-user-worker.js";
149
166
  export { createWebCryptoWebPush, measurePushPayload, MAX_PUSH_PAYLOAD_BYTES, PUSH_ENVELOPE_RESERVED_BYTES, WEB_PUSH_MAX_BODY_BYTES, WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES } from "./lib/webpush-webcrypto.js";
150
167
  export { deriveUserEncryptionKey, decryptPayload, encryptForStorage, decryptFromStorage } from "./lib/encryption.js";
151
- export { validateScheduleMessagePayload, validateLlmMessagesArray, validateSplitPattern, validateAvatarUrl, isValidISO8601, isValidUrl, isValidUUID, isValidUUIDv4, isValidTimeZoneId } from "./lib/validation.js";
168
+ export { validateScheduleMessagePayload, validateLlmMessagesArray, validateSplitPattern, validateAvatarUrl, isValidISO8601, isValidUrl, isValidUUID, isValidUUIDv4, isValidTimeZoneId, MAX_TASK_PAYLOAD_BYTES } from "./lib/validation.js";
169
+ export { readRequestBody, DEFAULT_MAX_REQUEST_BODY_BYTES } from "./lib/request.js";
152
170
  export { supportsLlmCredentialsStore, isValidCredId, validateCredRefs, validateCredValue, hasChatCredRef, resolveLlmCredential, CRED_ID_MAX_LENGTH, CRED_PUT_BATCH_MAX, CRED_ROWS_PER_USER_MAX, CRED_REFS_MAX_ENTRIES } from "./lib/llm-credentials-store.js";
153
171
  export { advanceOccurrence, nextFutureOccurrence, planNextOccurrence } from "./lib/recurrence.js";
154
172
  export { createTenantToken, verifyTenantToken } from "./tenant/token.js";
package/dist/index.mjs CHANGED
@@ -8,10 +8,13 @@ import {
8
8
  DEFAULT_CLAIM_LEASE_MS,
9
9
  DEFAULT_HEARTBEAT_LEASE_TTL_MS,
10
10
  DEFAULT_LEASE_HEARTBEAT_MS,
11
+ DEFAULT_MAX_REQUEST_BODY_BYTES,
11
12
  DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE,
12
13
  DEFAULT_MAX_TOOL_ITERATIONS,
13
14
  DEFAULT_TOTAL_TIMEOUT_MS,
15
+ DeploymentConfigError,
14
16
  MAX_PUSH_PAYLOAD_BYTES,
17
+ MAX_TASK_PAYLOAD_BYTES,
15
18
  MIN_SCHEDULE_LEAD_MS,
16
19
  NonRetryableError,
17
20
  PUSH_ENVELOPE_RESERVED_BYTES,
@@ -52,6 +55,7 @@ import {
52
55
  nextFutureOccurrence,
53
56
  parseJsonBody,
54
57
  planNextOccurrence,
58
+ readRequestBody,
55
59
  resolveLlmCredential,
56
60
  runScheduledTick,
57
61
  runTask,
@@ -67,8 +71,8 @@ import {
67
71
  validateLlmMessagesArray,
68
72
  validateScheduleMessagePayload,
69
73
  validateSplitPattern
70
- } from "./chunk-HTGYGGUH.mjs";
71
- import "./chunk-5FXVSC5O.mjs";
74
+ } from "./chunk-KOJQVOYS.mjs";
75
+ import "./chunk-GN44PST5.mjs";
72
76
 
73
77
  // src/server/adapters/factory.js
74
78
  async function createAdapter(config) {
@@ -84,11 +88,11 @@ async function createAdapter(config) {
84
88
  }
85
89
  switch (config.driver) {
86
90
  case "neon": {
87
- const { NeonAdapter } = await import("./neon-Y4KEZO5C.mjs");
91
+ const { NeonAdapter } = await import("./neon-ZIMHALYI.mjs");
88
92
  return new NeonAdapter(config.connectionString);
89
93
  }
90
94
  case "pg": {
91
- const { PgAdapter } = await import("./pg-GWJZBWAM.mjs");
95
+ const { PgAdapter } = await import("./pg-QGC2XHUT.mjs");
92
96
  return new PgAdapter(config.connectionString);
93
97
  }
94
98
  default:
@@ -605,6 +609,10 @@ async function createReiServer(config) {
605
609
  privateKey: vapid.privateKey || ""
606
610
  },
607
611
  webpush: webpushModule,
612
+ // 分片传输的限额(与 installReiSW 的 multipart 同一份)。instant 消息在
613
+ // schedule-message 里就地投递、定时消息走 send-notifications 的 tick,两条路
614
+ // 都从这个 ctx 展开,所以配一次两边都认。
615
+ multipart: config.multipart || null,
608
616
  tenant: {
609
617
  initSecret
610
618
  },
@@ -635,10 +643,13 @@ export {
635
643
  DEFAULT_CLAIM_LEASE_MS,
636
644
  DEFAULT_HEARTBEAT_LEASE_TTL_MS,
637
645
  DEFAULT_LEASE_HEARTBEAT_MS,
646
+ DEFAULT_MAX_REQUEST_BODY_BYTES,
638
647
  DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE,
639
648
  DEFAULT_MAX_TOOL_ITERATIONS,
640
649
  DEFAULT_TOTAL_TIMEOUT_MS,
650
+ DeploymentConfigError,
641
651
  MAX_PUSH_PAYLOAD_BYTES,
652
+ MAX_TASK_PAYLOAD_BYTES,
642
653
  MIN_SCHEDULE_LEAD_MS,
643
654
  NonRetryableError,
644
655
  PUSH_ENVELOPE_RESERVED_BYTES,
@@ -670,6 +681,7 @@ export {
670
681
  measurePushPayload,
671
682
  nextFutureOccurrence,
672
683
  planNextOccurrence,
684
+ readRequestBody,
673
685
  resolveLlmCredential,
674
686
  runScheduledTick,
675
687
  runTask,
@@ -1,5 +1,24 @@
1
1
  /** value 的 UTF-8 字节数——各处限额判断用的都是这个口径。 */
2
2
  export function stateValueBytes(value: any): number;
3
+ /**
4
+ * 把 `clientStateTtl` 配置(`{ 命名空间: 天数 }`)算成清理指令。
5
+ *
6
+ * 一个命名空间出两条:它自己,加上它的切片命名空间(大值分块存在那儿,见
7
+ * lib/state-chunks.js)。两边共用同一个截止时刻——同一次写入的根行和切片行
8
+ * `updated_at` 相同,所以要么一起留、要么一起走,不会留下半截数据。
9
+ *
10
+ * 天数不是正数的条目跳过并告警(每个键只说一次):配错了就该看得见,但不能
11
+ * 让 cron 每分钟刷一条。
12
+ *
13
+ * @param {Record<string, number>|null|undefined} ttl - `{ 命名空间: 天数 }`;天数可带小数
14
+ * @param {number} now - 当前时刻(epoch 毫秒)
15
+ * @returns {Array<{ namespace: string, updatedBefore: number }>}
16
+ * `updatedBefore` 是 epoch 毫秒:这个命名空间下 `updated_at` 早于它的条目该清掉。
17
+ */
18
+ export function planClientStateCleanup(ttl: Record<string, number> | null | undefined, now: number): Array<{
19
+ namespace: string;
20
+ updatedBefore: number;
21
+ }>;
3
22
  /**
4
23
  * 把逻辑条目写进 client_state。条目要么是覆盖写(`value` 是字符串),要么是
5
24
  * 删除(`value` 为 `null`):
@@ -6,12 +6,96 @@
6
6
  * @returns {boolean}
7
7
  */
8
8
  export function isNonRetryableError(error: unknown): boolean;
9
+ /**
10
+ * 把一个已经构造好的错误标成确定性失败(就地改,原样返回),顺带补一个稳定
11
+ * 的 `code`(错误自己带了 code 就不覆盖)。
12
+ *
13
+ * 用在错误由别处构造、又想保住它原本类型的时候——比如契约校验抛的
14
+ * `TypeError`:宿主按 `instanceof TypeError` 分流的代码不该因为库多标了一个
15
+ * 字段就走岔。自己现造错误的地方直接用 {@link NonRetryableError} 更直白。
16
+ *
17
+ * @template T
18
+ * @param {T} error
19
+ * @param {string} [code]
20
+ * @returns {T}
21
+ */
22
+ export function markPermanent<T>(error: T, code?: string): T;
23
+ /**
24
+ * 这个错误是不是「投递期间任务被取消/顶替」。
25
+ *
26
+ * @param {unknown} error
27
+ * @returns {boolean}
28
+ */
29
+ export function isTaskCancelledError(error: unknown): boolean;
30
+ /**
31
+ * 这次投递失败要不要判成永久性的(不再重试)。四个来源:
32
+ * - 已知的永久性错误码(见 {@link PERMANENT_ERROR_CODES});
33
+ * - hook 侧抛出的 NonRetryableError(`permanent`,见 {@link NonRetryableError})——
34
+ * fire_pack 缺失、解析失败这类重试必然同败的错,隔两分钟再试三次只是让用户
35
+ * 多白等十二分钟,还把情绪评估之类的计费重跑三遍;
36
+ * - 推送服务判了这条订阅的死刑(见 {@link TERMINAL_PUSH_STATUSES});
37
+ * - 推送服务说这条 payload 太大(见 {@link PUSH_PAYLOAD_TOO_LARGE_STATUS})。
38
+ *
39
+ * @param {{ permanent?: unknown, errorCode?: unknown, pushStatus?: unknown }} failure
40
+ * @returns {boolean}
41
+ */
42
+ export function isPermanentDeliveryFailure(failure: {
43
+ permanent?: unknown;
44
+ errorCode?: unknown;
45
+ pushStatus?: unknown;
46
+ }): boolean;
47
+ /**
48
+ * 发一条 push,失败时自动标上「这是发 push 那一步抛的」。
49
+ *
50
+ * 发 push 的地方一律走这里,别各自写 `try { send } catch { throw
51
+ * tagPushStatusCode(e) }`:漏标一处,那条路上的 410 就读不出状态码,一条早就
52
+ * 失效的订阅会被当成普通失败,在退避阶梯上把 LLM 重跑三轮。忘了标是没有任何
53
+ * 提示的。
54
+ *
55
+ * @param {{ sendNotification: (subscription: any, payload: string) => Promise<any> }} webpush
56
+ * @param {any} subscription
57
+ * @param {string} payloadJson
58
+ * @returns {Promise<any>}
59
+ */
60
+ export function sendTaggedPush(webpush: {
61
+ sendNotification: (subscription: any, payload: string) => Promise<any>;
62
+ }, subscription: any, payloadJson: string): Promise<any>;
63
+ /**
64
+ * 读推送服务回的状态码。没被 {@link tagPushStatusCode} 标过 → null。
65
+ *
66
+ * @param {unknown} error
67
+ * @returns {number|null}
68
+ */
69
+ export function readPushStatusCode(error: unknown): number | null;
70
+ /**
71
+ * lastError 里的机读标注:`errorCode` 是底层错误的稳定 code(如
72
+ * `PUSH_PAYLOAD_TOO_LARGE`),`pushStatus` 是推送服务回的 HTTP 状态码。两个都
73
+ * 没有 → undefined,不往记录里塞空字段。
74
+ *
75
+ * reason 那句是给用户看的人话、措辞随时会变,判断「该让用户重建订阅还是裁短
76
+ * 内容」得读这两个字段。定时任务(run-tick)与 instant 任务
77
+ * (processMessagesByUuid)共用这一份,两条路记下来的形状一致。
78
+ *
79
+ * code 是标识符不是人话,不用脱敏,但也别让一个来路不明的超长 code 撑大明文
80
+ * 列——截到 64 字符,够放所有约定过的码。
81
+ *
82
+ * @param {string|null|undefined} errorCode
83
+ * @param {number|null|undefined} pushStatus
84
+ * @returns {{ errorCode?: string, pushStatus?: number }|undefined}
85
+ */
86
+ export function buildErrorExtra(errorCode: string | null | undefined, pushStatus: number | null | undefined): {
87
+ errorCode?: string;
88
+ pushStatus?: number;
89
+ } | undefined;
9
90
  /**
10
91
  * 把错误原因脱敏成能明文落库(任务行 last_error 列)的摘要。
11
92
  *
12
93
  * 任务内容一律密文落库,last_error 是唯一一列明文的「为什么没发出去」——
13
94
  * 错误消息偶尔会回显请求细节(上游 API 的报错带 URL、header 片段),所以
14
- * 长得像凭据的 token 一律遮掉,再截断到 500 字符。
95
+ * 长得像凭据的 token 一律遮掉,再截断。
96
+ *
97
+ * 遮什么、怎么遮由 @rei-standard/amsg-shared 的 `redactCredentials` 说了算,
98
+ * 这里只负责压平空白和截断。
15
99
  *
16
100
  * @param {unknown} reason
17
101
  * @returns {string}
@@ -21,7 +105,10 @@ export function sanitizeErrorSummary(reason: unknown): string;
21
105
  * @typedef {Object} ErrorCause
22
106
  * @property {'config'|'request'|'tick'} stage - 在哪一段炸的
23
107
  * @property {string} name - 错误类型(`error.name`,认不出来时是 'Error')
24
- * @property {string} message - 脱敏后的错误消息
108
+ * @property {string} [message] - 脱敏后的错误消息。降级 500(配置都没建起来那条
109
+ * 路)回给跨域调用方时不带这个字段——那条路的 CORS 头是回显来访 Origin 的,任
110
+ * 意第三方页面都能读,而构建期异常原文里常有 binding 名、内网域名、环境变量
111
+ * 名。同源 / 无 Origin 的请求照旧带全文,`wrangler tail` 里也一直有。
25
112
  * @property {string} [code] - 错误自带的 `code` 字符串(有才带)
26
113
  */
27
114
  /**
@@ -42,9 +129,6 @@ export function sanitizeErrorSummary(reason: unknown): string;
42
129
  * @returns {ErrorCause}
43
130
  */
44
131
  export function summarizeErrorCause(error: unknown, stage: "config" | "request" | "tick"): ErrorCause;
45
- /**
46
- * 错误类型:宿主 hook 与库内部共用的失败语义标注。
47
- */
48
132
  /**
49
133
  * 确定性失败——重试必然同败,别再排退避阶梯。
50
134
  *
@@ -73,6 +157,41 @@ export class NonRetryableError extends Error {
73
157
  permanent: boolean;
74
158
  code: string;
75
159
  }
160
+ /**
161
+ * 部署级的配置 / 适配器能力错误——坏的不是这条任务,是这个部署。
162
+ *
163
+ * 典型场景:`hooks.onBeforeFire` 配了但 `onLLMOutput` 忘了配、`executeToolCalls`
164
+ * 没配、自定义适配器缺 `createTask` / `deleteTaskByUuid` / `upsertClientState`。
165
+ * 这类错误重试确实好不了,但**不能**判终态:同一个坏部署下每条到点的任务都会
166
+ * 撞同一个错,判终态就等于在那段时间里把每一条一次性任务都永久标 `failed`,
167
+ * 运维改好配置重新部署也捞不回来了(行已不在 pending,`PUT /update-message`
168
+ * 回 409)。所以留在退避阶梯上——配置一修好,还在阶梯上的任务下一跳就正常发
169
+ * 出去。这跟 VAPID 配错回的 400/401/403 是同一个道理,见
170
+ * {@link PUSH_PAYLOAD_TOO_LARGE_STATUS} 那段注释。
171
+ *
172
+ * 带 `code` 但不带 `permanent`:失败原因照旧进 last_error 的 `errorCode`,宿主
173
+ * 想分流照样读得到,只是不再跳过重试。
174
+ */
175
+ export class DeploymentConfigError extends Error {
176
+ /**
177
+ * @param {string} message
178
+ * @param {{ code?: string, cause?: unknown }} [options]
179
+ */
180
+ constructor(message: string, options?: {
181
+ code?: string;
182
+ cause?: unknown;
183
+ });
184
+ code: string;
185
+ }
186
+ /**
187
+ * 投递期间发现「这条任务已经不归本次投递管了」时,推送侧抛的错误码:行被
188
+ * `DELETE /message` 取消、被 `supersedesUuid` 顶替,或被别的执行者收尾了。
189
+ *
190
+ * 发送方(message-processor 的正文投递、agentic-fire 的 hook 投递)靠它区分
191
+ * 「取消」和「发失败」——两者的收尾完全不同:取消要把这一批还没发出去的
192
+ * outbox 行撤掉,发失败则要把它们留着等补收。
193
+ */
194
+ export const TASK_CANCELLED_CODE: "TASK_CANCELLED";
76
195
  export type ErrorCause = {
77
196
  /**
78
197
  * - 在哪一段炸的
@@ -83,9 +202,12 @@ export type ErrorCause = {
83
202
  */
84
203
  name: string;
85
204
  /**
86
- * - 脱敏后的错误消息
205
+ * - 脱敏后的错误消息。降级 500(配置都没建起来那条
206
+ * 路)回给跨域调用方时不带这个字段——那条路的 CORS 头是回显来访 Origin 的,任
207
+ * 意第三方页面都能读,而构建期异常原文里常有 binding 名、内网域名、环境变量
208
+ * 名。同源 / 无 Origin 的请求照旧带全文,`wrangler tail` 里也一直有。
87
209
  */
88
- message: string;
210
+ message?: string;
89
211
  /**
90
212
  * - 错误自带的 `code` 字符串(有才带)
91
213
  */