@rei-standard/amsg-server 2.6.0-next.21 → 2.6.0-next.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -8
- package/dist/{chunk-KOJQVOYS.mjs → chunk-3JEWYDM4.mjs} +33 -15
- package/dist/{chunk-QHVID3V2.cjs → chunk-BNZLICCI.cjs} +33 -15
- package/dist/cloudflare.cjs +2 -2
- package/dist/cloudflare.mjs +1 -1
- package/dist/index.cjs +25 -25
- package/dist/index.mjs +1 -1
- package/dist/lib/push-policy.d.ts +11 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,7 +15,46 @@ npm install @neondatabase/serverless
|
|
|
15
15
|
npm install pg
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## 两条部署线
|
|
19
|
+
|
|
20
|
+
| | 单用户线(推荐) | 多租户线 |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| 入口 | `createSingleUserCloudflareWorker` / `createSingleUserServer` | `createReiServer` |
|
|
23
|
+
| 数据库 | D1 | pg / neon |
|
|
24
|
+
| 一个部署 | 服务一个用户 | 服务多个租户(Blob 存租户配置 + token 鉴权) |
|
|
25
|
+
| 服务端收件箱(`GET /outbox` 补拉) | ✅ | ❌ |
|
|
26
|
+
| `client_state` 云端镜像 | ✅ | ❌ |
|
|
27
|
+
| 推送订阅、LLM 凭据、定时 / 周期任务 | ✅ | ✅ |
|
|
28
|
+
|
|
29
|
+
**新接入走单用户线。** 收件箱是这套 SDK 的到达保证:每条 payload 发出去之前先落一行 `message_outbox`,客户端上线 `GET /outbox?since=` 一条不少地补得回来。有了它,到了客户端不会弹通知的 payload(思考过程、工具请求、错误)就不必占用推送通道——这是[哪些 payload 会发推送](#哪些-payload-会发推送)那一节的前提,也是不去赌 iOS 订阅宽限期的唯一办法。
|
|
30
|
+
|
|
31
|
+
多租户线继续维护,任务、推送、凭据这些照常能用——但它的 pg / neon 适配器还没有 `message_outbox` 和 `client_state`,收件箱相关的端点返回 501,不会弹通知的 payload 也只能照旧推送。
|
|
32
|
+
|
|
33
|
+
> **TODO**:给 pg / neon 适配器补 `message_outbox` 那组方法(D1 的实现见 `src/server/adapters/d1.js`,建表 SQL 见 `adapters/schema.sqlite.js`)。补上之前,多租户线省不掉那些不会弹通知的推送。
|
|
34
|
+
|
|
35
|
+
## 快速使用(单用户线)
|
|
36
|
+
|
|
37
|
+
一个 Cloudflare Worker 装完两个入口:`fetch` 收客户端请求,`scheduled` 跑 cron 投递。
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
import { createSingleUserCloudflareWorker, createD1Adapter } from '@rei-standard/amsg-server';
|
|
41
|
+
|
|
42
|
+
export default createSingleUserCloudflareWorker((env) => ({
|
|
43
|
+
db: createD1Adapter(env.DB),
|
|
44
|
+
masterKey: env.MASTER_KEY,
|
|
45
|
+
vapid: {
|
|
46
|
+
email: env.VAPID_EMAIL,
|
|
47
|
+
publicKey: env.VAPID_PUBLIC_KEY,
|
|
48
|
+
privateKey: env.VAPID_PRIVATE_KEY,
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
建表、绑定、cron 配置和 fire-time hook 的完整走法见 [`examples/cloudflare-single-user`](https://github.com/Tosd0/ReiStandard/blob/main/packages/rei-standard-amsg/server/examples/cloudflare-single-user/README.md)。
|
|
54
|
+
|
|
55
|
+
客户端那侧还差一步:**应用启动时拉一次收件箱**。不会弹通知的内容(思考过程、工具请求、错误)只落收件箱、不发推送,不补拉就等于没有——做法见 [`@rei-standard/amsg-client` README 的「上线补一次收件箱」](https://github.com/Tosd0/ReiStandard/blob/main/packages/rei-standard-amsg/client/README.md#上线补一次收件箱)。
|
|
56
|
+
|
|
57
|
+
## 快速使用(多租户线)
|
|
19
58
|
|
|
20
59
|
```js
|
|
21
60
|
import { createReiServer } from '@rei-standard/amsg-server';
|
|
@@ -54,9 +93,9 @@ const rei = await createReiServer({
|
|
|
54
93
|
|
|
55
94
|
## 关于 `messageType: 'instant'`
|
|
56
95
|
|
|
57
|
-
> **两条 instant
|
|
58
|
-
> - **本端点的 `messageType: 'instant'`**(create task → process by UUID → delete task
|
|
59
|
-
> - **[@rei-standard/amsg-instant](https://github.com/Tosd0/ReiStandard/blob/main/packages/rei-standard-amsg/instant/README.md)**:纯 SSE 流 + Web Push backup
|
|
96
|
+
> **两条 instant 路径:**
|
|
97
|
+
> - **本端点的 `messageType: 'instant'`**(create task → process by UUID → delete task):任务先写进数据库再处理,投递不绑在请求连接上——客户端断开也没关系,任务行还在,能继续跑、能重试,想跑多久跑多久。落进收件箱的那份客户端上线也补得回来。有数据库就走这条。
|
|
98
|
+
> - **[@rei-standard/amsg-instant](https://github.com/Tosd0/ReiStandard/blob/main/packages/rei-standard-amsg/instant/README.md)**:纯 SSE 流 + Web Push backup,不需要数据库,跑得动无状态边缘运行时。处理挂在响应连接上,客户端一断开就只剩平台给的那点宽限期把活干完(Deno Deploy 实测 ≈20-30s);它也没有服务端收件箱,push 漏了的内容补不回来。这个包现在是维护态,新接入不从它起步。
|
|
60
99
|
|
|
61
100
|
## AI 接口 `apiUrl` 约束
|
|
62
101
|
|
|
@@ -142,9 +181,30 @@ const message = body.length <= remainingBytes ? body : body.slice(0, remainingBy
|
|
|
142
181
|
|
|
143
182
|
用比 64 字符更长的 uuid(`scheduleTask` 允许传任意字符串)就自己再多留一点。
|
|
144
183
|
|
|
184
|
+
### 哪些 payload 会发推送
|
|
185
|
+
|
|
186
|
+
一条 payload 出门有两条腿:**落进 `message_outbox`**(到达的保证,客户端上线 `GET /outbox?since=` 补拉)和**发一条 Web Push**(及时性,当场叫人回来看)。收件箱那条腿每条 payload 都走,推送这条腿只留给「到了客户端会弹通知」的那些。
|
|
187
|
+
|
|
188
|
+
| payload | 落收件箱 | 发推送 |
|
|
189
|
+
| --- | --- | --- |
|
|
190
|
+
| `content` / `result` | ✅ | ✅ |
|
|
191
|
+
| `reasoning` / `tool_request` / `error` | ✅ | ❌ |
|
|
192
|
+
| 任意 kind + `notification: { show: false }` | ✅ | ❌ |
|
|
193
|
+
| 任意 kind + `notification: { show: 'always' \| 'when-hidden' }` | ✅ | ✅ |
|
|
194
|
+
|
|
195
|
+
为什么这么分:订阅是按 `userVisibleOnly: true` 建的,每条 push 都欠用户一次可见反馈。`reasoning` / `tool_request` / `error` 在 Service Worker 那边是静默送给页面的,推过去不会有任何可见反馈,却要跟浏览器赊一次账——Firefox 对这类 push 有配额、超了退掉订阅,iOS 给新订阅几天宽限期、过后一条就吊销订阅,而且掉订阅是静默发生的,服务端只看得到后续推送返回 410。而这些内容在收件箱里一个字不少,客户端上线补拉就行(完整取舍见 `@rei-standard/amsg-sw` README 的「不展示通知的代价」一节)。
|
|
196
|
+
|
|
197
|
+
**想让某一条照样弹**,给它带上 `notification: { show: 'always' }`——判定读的是与 Service Worker 同一份规则(`@rei-standard/amsg-shared` 的 `notificationIntent`),宿主说了要弹,发送端就当它值得占用推送通道。逐条控制,不需要在服务端配开关。嫌打扰就配 `tag` 折叠加 `silent`,而不是不弹——只在用户看着页面时想安静的写 `silent: 'when-visible'`,静不静音由 Service Worker 收到时现算(发送端定不了这件事,它不知道用户此刻在不在前台)。`show: 'when-hidden'` 也照推(它到底弹不弹只有 Service Worker 当场知道),但那是给老部署留的兼容档,新代码在「一定弹」和「压根不推」里挑一个。
|
|
198
|
+
|
|
199
|
+
跳过推送的那条不标 `delivered_at`,行留在收件箱里等客户端补收;这正是能跳过的前提。
|
|
200
|
+
|
|
201
|
+
**前提是这个部署有收件箱。** 内置适配器里只有 D1 实现了 `message_outbox`(见[两条部署线](#两条部署线))。落不进收件箱时——适配器没实现,或者这一批落行失败——推送是这条内容唯一的腿,所有 payload 照旧全推,包括不会弹通知的那些。宁可跟浏览器违约一次,也不能让内容凭空消失。
|
|
202
|
+
|
|
203
|
+
agentic 链路的 `onAfterSend` / `onFireSettled` 回执里,`sentCount` 是这批走完了几段,`pushedCount` 是其中真的占用了推送通道的有几条。`sentCount === total` 照旧表示整批都到位了。
|
|
204
|
+
|
|
145
205
|
### 装不下就切片:`multipart`
|
|
146
206
|
|
|
147
|
-
思考过程(reasoning)常常一条 push
|
|
207
|
+
思考过程(reasoning)常常一条 push 装不下。真要把它推出去时(宿主给它配了 `notification.show`,或者这个部署没有收件箱),服务端会把它切成分片逐条发,Service Worker 收齐后还原成原样再走正常派发。切多大一片、最多切几片、收齐前能等多久,都是接收端说了算——所以给 `installReiSW` 传了什么,就把同一份原样传给服务端:
|
|
148
208
|
|
|
149
209
|
```js
|
|
150
210
|
const multipart = { maxChunkBytes: 1800, maxChunks: 128, maxTotalBytes: 256_000, ttlMs: 60_000 };
|
|
@@ -168,6 +228,8 @@ createSingleUserCloudflareWorker((env) => ({ …, multipart })); // CF Worker
|
|
|
168
228
|
|
|
169
229
|
### 思考过程没送到时的可见性
|
|
170
230
|
|
|
231
|
+
> 这一节说的是**推送真的发出去过、但发挂了**的情况。有收件箱的部署上思考过程只落行、不推送(见[哪些 payload 会发推送](#哪些-payload-会发推送)),那条路上内容没丢,也就不会有下面这些信号。
|
|
232
|
+
|
|
171
233
|
思考过程是正文之外的附赠内容:它没发出去不影响正文,任务照样算成功。这件事有三处看得见——
|
|
172
234
|
|
|
173
235
|
- 定时任务的 tick 汇总多一个 `details.reasoningSkippedTasks`:`[{ taskId, reason }]`。这些任务同时计在 `successCount` 里。
|
|
@@ -324,14 +386,16 @@ hook 在 `pushPayloads` 里自己写了这几个字段的话会被库覆盖:
|
|
|
324
386
|
|
|
325
387
|
| hook | 什么时候调 | 载荷 |
|
|
326
388
|
|---|---|---|
|
|
327
|
-
| `onAfterSend` | fire 的 pushPayloads 逐段发完,或中途发挂 | `{ task, sentCount, total, error, scratch, readState, writeState, emitResult }` |
|
|
328
|
-
| `onFireSettled` | 一次 fire 收尾——只要 `onBeforeFire` 被调用过,什么结局都调一次 | `{ task, status, skipReason, sentCount, total, iterations, error, scratch, readState, writeState, emitResult }` |
|
|
389
|
+
| `onAfterSend` | fire 的 pushPayloads 逐段发完,或中途发挂 | `{ task, sentCount, pushedCount, total, error, scratch, readState, writeState, emitResult }` |
|
|
390
|
+
| `onFireSettled` | 一次 fire 收尾——只要 `onBeforeFire` 被调用过,什么结局都调一次 | `{ task, status, skipReason, sentCount, pushedCount, total, iterations, error, scratch, readState, writeState, emitResult }` |
|
|
329
391
|
| `onStaleSkip` | 任务错过触发时刻超过 60 分钟、这一次(或这几次)不再补发 | `{ reason, action, metadata, recurrenceType, occurrenceMs, skippedCount, skippedOccurrences, skippedTruncated, nextSendAt, readState, writeState, emitResult }` |
|
|
330
392
|
|
|
331
393
|
三个 hook 都自带 `readState` / `writeState` / `emitResult`,作用于当前用户,语义与 fire 级那套一致。`onStaleSkip` 尤其需要:服务停摆恢复后的第一跳里可能一次 fire 都没跑过,而那正是它要留痕迹的时候。
|
|
332
394
|
|
|
333
395
|
`onAfterSend` 的 `scratch` 与本次 fire 的 `onBeforeFire` / `onLLMOutput` 是同一个引用——「这次生成了哪几段正文」之类的上下文直接从这里读,不用自建按任务分格的登记表。全部成功时 `error` 为 `null`;第 k 段失败时 `sentCount = k`、`error` 带原始错误,且在错误往上抛之前调用完。
|
|
334
396
|
|
|
397
|
+
`sentCount` 与 `pushedCount` 数的是两件事:`sentCount` 是这批走完了几段(只落收件箱、没占推送通道的那些也算走完),`pushedCount` 是其中真的发了 Web Push 的有几条。判整批跑完没有看 `sentCount === total`。
|
|
398
|
+
|
|
335
399
|
`onFireSettled` 是「这次 fire 结束了」这一个信号,`status` 说明结局:
|
|
336
400
|
|
|
337
401
|
| status | 什么时候 |
|
|
@@ -412,7 +476,9 @@ const { messageId, pushed } = await ctx.emitResult({
|
|
|
412
476
|
|
|
413
477
|
**通知**默认弹(结果与聊天正文同待遇,其余 push 类型是静默送给页面)。标题正文在 `notification` 里自定义,字段与 SW 那套一致(`title` / `body` / `icon` / `tag` / …);不想弹就 `notification: { show: false }`。
|
|
414
478
|
|
|
415
|
-
|
|
479
|
+
> 带 `show: false` 的结果不发推送、只落收件箱(见[哪些 payload 会发推送](#哪些-payload-会发推送)):订阅按 `userVisibleOnly: true` 建,收到 push 却不弹通知,Firefox 按配额退订,iOS 在订阅的宽限期过后直接吊销(完整取舍见 `@rei-standard/amsg-sw` README 的「不展示通知的代价」一节)。结果这条本来就有收件箱兜底,客户端上线补拉拿得到。
|
|
480
|
+
|
|
481
|
+
**返回值**里 `pushed` 是「这次推送有没有真的发出去」。两种情况会是 `false`:带 `notification: { show: false }` 的结果按策略压根不推(见[哪些 payload 会发推送](#哪些-payload-会发推送)),以及推了但没送出去(订阅失效、推送服务抽风、payload 超过 4KB)。两种都不算失败,行还在收件箱里等补收,`emitResult` 也不会因此抛错。
|
|
416
482
|
|
|
417
483
|
**落行失败会抛**:收件箱是到达的保证,静默丢掉正是这个能力要修的病。适配器没有 `message_outbox`(自定义适配器)时同样抛,`code` 是 `OUTBOX_UNSUPPORTED`。
|
|
418
484
|
|
|
@@ -1293,6 +1293,13 @@ async function discardUndeliveredPushesForTask({ db, userId, taskUuid }) {
|
|
|
1293
1293
|
await discardPushesFromOutbox({ db, userId, messageIds });
|
|
1294
1294
|
}
|
|
1295
1295
|
|
|
1296
|
+
// src/server/lib/push-policy.js
|
|
1297
|
+
import { notificationIntent } from "@rei-standard/amsg-shared";
|
|
1298
|
+
function shouldSendPush(push, { outboxed }) {
|
|
1299
|
+
if (!outboxed) return true;
|
|
1300
|
+
return notificationIntent(push) !== "never";
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1296
1303
|
// src/server/lib/push-subscription-store.js
|
|
1297
1304
|
function supportsPushSubscriptionStore(db) {
|
|
1298
1305
|
return !!db && typeof db.getPushSubscription === "function" && typeof db.upsertPushSubscription === "function" && typeof db.deletePushSubscription === "function";
|
|
@@ -1379,7 +1386,7 @@ function createResultEmitter({
|
|
|
1379
1386
|
await db.appendOutboxMessages(task.user_id, await toOutboxRows([push], userKey, nowFn()));
|
|
1380
1387
|
let pushed;
|
|
1381
1388
|
try {
|
|
1382
|
-
pushed = await sendResultPush({ db, task, userKey, decryptedPayload, webpush, push });
|
|
1389
|
+
pushed = shouldSendPush(push, { outboxed: true }) ? await sendResultPush({ db, task, userKey, decryptedPayload, webpush, push }) : false;
|
|
1383
1390
|
} catch (error) {
|
|
1384
1391
|
await discardUndeliveredPushes({ db, userId: task.user_id, pushes: [push], sentIds: [] });
|
|
1385
1392
|
throw error;
|
|
@@ -1826,7 +1833,7 @@ async function runAgenticFire({ task, decryptedPayload, userKey, ctx }) {
|
|
|
1826
1833
|
now: new Date(nowFn()),
|
|
1827
1834
|
scratch
|
|
1828
1835
|
});
|
|
1829
|
-
const progress = { sentCount: 0, total: 0, iterations: 0, skipReason: null, usage: null };
|
|
1836
|
+
const progress = { sentCount: 0, pushedCount: 0, total: 0, iterations: 0, skipReason: null, usage: null };
|
|
1830
1837
|
let settledStatus = "failed";
|
|
1831
1838
|
let settledError = null;
|
|
1832
1839
|
try {
|
|
@@ -1863,6 +1870,7 @@ async function runAgenticFire({ task, decryptedPayload, userKey, ctx }) {
|
|
|
1863
1870
|
status: settledStatus,
|
|
1864
1871
|
skipReason: settledStatus === "skipped" ? progress.skipReason : null,
|
|
1865
1872
|
sentCount: progress.sentCount,
|
|
1873
|
+
pushedCount: progress.pushedCount,
|
|
1866
1874
|
total: progress.total,
|
|
1867
1875
|
iterations: progress.iterations,
|
|
1868
1876
|
error: settledError,
|
|
@@ -2085,6 +2093,7 @@ async function sendHookPushPayloads({
|
|
|
2085
2093
|
}) {
|
|
2086
2094
|
const total = pushPayloads.length;
|
|
2087
2095
|
let sentCount = 0;
|
|
2096
|
+
let pushedCount = 0;
|
|
2088
2097
|
progress.total = total;
|
|
2089
2098
|
const afterSendBase = { task, total, scratch, readState, writeState, emitResult, usage: progress.usage };
|
|
2090
2099
|
const sentIds = [];
|
|
@@ -2109,13 +2118,20 @@ async function sendHookPushPayloads({
|
|
|
2109
2118
|
stampTaskIdentity(push, task, decryptedPayload, occurrenceMs);
|
|
2110
2119
|
finalized.push(push);
|
|
2111
2120
|
}
|
|
2112
|
-
await appendPushesToOutbox({ db: ctx.db, userId: task.user_id, userKey, pushes: finalized });
|
|
2121
|
+
const outboxed = await appendPushesToOutbox({ db: ctx.db, userId: task.user_id, userKey, pushes: finalized });
|
|
2122
|
+
const pushGate = { outboxed };
|
|
2123
|
+
const willPush = finalized.map((push) => shouldSendPush(push, pushGate));
|
|
2124
|
+
const lastPushIndex = willPush.lastIndexOf(true);
|
|
2113
2125
|
for (let i = 0; i < total; i++) {
|
|
2114
|
-
|
|
2126
|
+
if (willPush[i]) {
|
|
2127
|
+
await sendTaggedPush(ctx.webpush, pushSubscription, JSON.stringify(finalized[i]));
|
|
2128
|
+
pushedCount++;
|
|
2129
|
+
progress.pushedCount = pushedCount;
|
|
2130
|
+
sentIds.push(finalized[i].messageId);
|
|
2131
|
+
}
|
|
2115
2132
|
sentCount++;
|
|
2116
2133
|
progress.sentCount = sentCount;
|
|
2117
|
-
|
|
2118
|
-
if (i < total - 1) await sleep(SLEEP_BETWEEN_MESSAGES_MS);
|
|
2134
|
+
if (willPush[i] && i < lastPushIndex) await sleep(SLEEP_BETWEEN_MESSAGES_MS);
|
|
2119
2135
|
}
|
|
2120
2136
|
} catch (error) {
|
|
2121
2137
|
await markPushesDelivered({ db: ctx.db, userId: task.user_id, messageIds: sentIds });
|
|
@@ -2127,11 +2143,11 @@ async function sendHookPushPayloads({
|
|
|
2127
2143
|
sentIds
|
|
2128
2144
|
});
|
|
2129
2145
|
}
|
|
2130
|
-
await notifyAfterSend(ctx, { ...afterSendBase, sentCount, error });
|
|
2146
|
+
await notifyAfterSend(ctx, { ...afterSendBase, sentCount, pushedCount, error });
|
|
2131
2147
|
throw error;
|
|
2132
2148
|
}
|
|
2133
2149
|
await markPushesDelivered({ db: ctx.db, userId: task.user_id, messageIds: sentIds });
|
|
2134
|
-
await notifyAfterSend(ctx, { ...afterSendBase, sentCount, error: null });
|
|
2150
|
+
await notifyAfterSend(ctx, { ...afterSendBase, sentCount, pushedCount, error: null });
|
|
2135
2151
|
return total;
|
|
2136
2152
|
}
|
|
2137
2153
|
|
|
@@ -2334,12 +2350,14 @@ async function processSingleMessage(task, ctx, providedMasterKey, predecrypted =
|
|
|
2334
2350
|
contentPushes.push(contentPush);
|
|
2335
2351
|
}
|
|
2336
2352
|
const pushesToSend = reasoningPush ? [reasoningPush, ...contentPushes] : contentPushes;
|
|
2337
|
-
await appendPushesToOutbox({ db: ctx.db, userId: task.user_id, userKey, pushes: pushesToSend });
|
|
2353
|
+
const outboxed = await appendPushesToOutbox({ db: ctx.db, userId: task.user_id, userKey, pushes: pushesToSend });
|
|
2354
|
+
const pushGate = { outboxed };
|
|
2355
|
+
const contentToPush = contentPushes.filter((push) => shouldSendPush(push, pushGate));
|
|
2338
2356
|
const sentIds = [];
|
|
2339
2357
|
let cancelledMidBurst = false;
|
|
2340
2358
|
let reasoningError;
|
|
2341
2359
|
try {
|
|
2342
|
-
if (reasoningPush) {
|
|
2360
|
+
if (reasoningPush && shouldSendPush(reasoningPush, pushGate)) {
|
|
2343
2361
|
const reasoning2 = await deliverReasoningPush(ctx, pushSubscription, reasoningPush);
|
|
2344
2362
|
if (reasoning2.shipped) {
|
|
2345
2363
|
sentIds.push(reasoningPush.messageId);
|
|
@@ -2348,10 +2366,10 @@ async function processSingleMessage(task, ctx, providedMasterKey, predecrypted =
|
|
|
2348
2366
|
reasoningError = reasoning2.error;
|
|
2349
2367
|
}
|
|
2350
2368
|
}
|
|
2351
|
-
for (let i = 0; i <
|
|
2352
|
-
await sendTaggedPush(ctx.webpush, pushSubscription, JSON.stringify(
|
|
2353
|
-
sentIds.push(
|
|
2354
|
-
if (i <
|
|
2369
|
+
for (let i = 0; i < contentToPush.length; i++) {
|
|
2370
|
+
await sendTaggedPush(ctx.webpush, pushSubscription, JSON.stringify(contentToPush[i]));
|
|
2371
|
+
sentIds.push(contentToPush[i].messageId);
|
|
2372
|
+
if (i < contentToPush.length - 1) {
|
|
2355
2373
|
await sleepFor(ctx, SLEEP_BETWEEN_MESSAGES_MS2);
|
|
2356
2374
|
}
|
|
2357
2375
|
}
|
|
@@ -5195,7 +5213,7 @@ function createClientStateHandler(ctx) {
|
|
|
5195
5213
|
}
|
|
5196
5214
|
|
|
5197
5215
|
// src/server/lib/version.js
|
|
5198
|
-
var SERVER_VERSION = true ? "2.6.0-next.
|
|
5216
|
+
var SERVER_VERSION = true ? "2.6.0-next.23" : "0.0.0-dev";
|
|
5199
5217
|
|
|
5200
5218
|
// src/server/handlers/capabilities.js
|
|
5201
5219
|
var SERVER_FEATURES = Object.freeze([
|
|
@@ -1293,6 +1293,13 @@ async function discardUndeliveredPushesForTask({ db, userId, taskUuid }) {
|
|
|
1293
1293
|
await discardPushesFromOutbox({ db, userId, messageIds });
|
|
1294
1294
|
}
|
|
1295
1295
|
|
|
1296
|
+
// src/server/lib/push-policy.js
|
|
1297
|
+
|
|
1298
|
+
function shouldSendPush(push, { outboxed }) {
|
|
1299
|
+
if (!outboxed) return true;
|
|
1300
|
+
return _amsgshared.notificationIntent.call(void 0, push) !== "never";
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1296
1303
|
// src/server/lib/push-subscription-store.js
|
|
1297
1304
|
function supportsPushSubscriptionStore(db) {
|
|
1298
1305
|
return !!db && typeof db.getPushSubscription === "function" && typeof db.upsertPushSubscription === "function" && typeof db.deletePushSubscription === "function";
|
|
@@ -1379,7 +1386,7 @@ function createResultEmitter({
|
|
|
1379
1386
|
await db.appendOutboxMessages(task.user_id, await toOutboxRows([push], userKey, nowFn()));
|
|
1380
1387
|
let pushed;
|
|
1381
1388
|
try {
|
|
1382
|
-
pushed = await sendResultPush({ db, task, userKey, decryptedPayload, webpush, push });
|
|
1389
|
+
pushed = shouldSendPush(push, { outboxed: true }) ? await sendResultPush({ db, task, userKey, decryptedPayload, webpush, push }) : false;
|
|
1383
1390
|
} catch (error) {
|
|
1384
1391
|
await discardUndeliveredPushes({ db, userId: task.user_id, pushes: [push], sentIds: [] });
|
|
1385
1392
|
throw error;
|
|
@@ -1826,7 +1833,7 @@ async function runAgenticFire({ task, decryptedPayload, userKey, ctx }) {
|
|
|
1826
1833
|
now: new Date(nowFn()),
|
|
1827
1834
|
scratch
|
|
1828
1835
|
});
|
|
1829
|
-
const progress = { sentCount: 0, total: 0, iterations: 0, skipReason: null, usage: null };
|
|
1836
|
+
const progress = { sentCount: 0, pushedCount: 0, total: 0, iterations: 0, skipReason: null, usage: null };
|
|
1830
1837
|
let settledStatus = "failed";
|
|
1831
1838
|
let settledError = null;
|
|
1832
1839
|
try {
|
|
@@ -1863,6 +1870,7 @@ async function runAgenticFire({ task, decryptedPayload, userKey, ctx }) {
|
|
|
1863
1870
|
status: settledStatus,
|
|
1864
1871
|
skipReason: settledStatus === "skipped" ? progress.skipReason : null,
|
|
1865
1872
|
sentCount: progress.sentCount,
|
|
1873
|
+
pushedCount: progress.pushedCount,
|
|
1866
1874
|
total: progress.total,
|
|
1867
1875
|
iterations: progress.iterations,
|
|
1868
1876
|
error: settledError,
|
|
@@ -2085,6 +2093,7 @@ async function sendHookPushPayloads({
|
|
|
2085
2093
|
}) {
|
|
2086
2094
|
const total = pushPayloads.length;
|
|
2087
2095
|
let sentCount = 0;
|
|
2096
|
+
let pushedCount = 0;
|
|
2088
2097
|
progress.total = total;
|
|
2089
2098
|
const afterSendBase = { task, total, scratch, readState, writeState, emitResult, usage: progress.usage };
|
|
2090
2099
|
const sentIds = [];
|
|
@@ -2109,13 +2118,20 @@ async function sendHookPushPayloads({
|
|
|
2109
2118
|
stampTaskIdentity(push, task, decryptedPayload, occurrenceMs);
|
|
2110
2119
|
finalized.push(push);
|
|
2111
2120
|
}
|
|
2112
|
-
await appendPushesToOutbox({ db: ctx.db, userId: task.user_id, userKey, pushes: finalized });
|
|
2121
|
+
const outboxed = await appendPushesToOutbox({ db: ctx.db, userId: task.user_id, userKey, pushes: finalized });
|
|
2122
|
+
const pushGate = { outboxed };
|
|
2123
|
+
const willPush = finalized.map((push) => shouldSendPush(push, pushGate));
|
|
2124
|
+
const lastPushIndex = willPush.lastIndexOf(true);
|
|
2113
2125
|
for (let i = 0; i < total; i++) {
|
|
2114
|
-
|
|
2126
|
+
if (willPush[i]) {
|
|
2127
|
+
await sendTaggedPush(ctx.webpush, pushSubscription, JSON.stringify(finalized[i]));
|
|
2128
|
+
pushedCount++;
|
|
2129
|
+
progress.pushedCount = pushedCount;
|
|
2130
|
+
sentIds.push(finalized[i].messageId);
|
|
2131
|
+
}
|
|
2115
2132
|
sentCount++;
|
|
2116
2133
|
progress.sentCount = sentCount;
|
|
2117
|
-
|
|
2118
|
-
if (i < total - 1) await sleep(SLEEP_BETWEEN_MESSAGES_MS);
|
|
2134
|
+
if (willPush[i] && i < lastPushIndex) await sleep(SLEEP_BETWEEN_MESSAGES_MS);
|
|
2119
2135
|
}
|
|
2120
2136
|
} catch (error) {
|
|
2121
2137
|
await markPushesDelivered({ db: ctx.db, userId: task.user_id, messageIds: sentIds });
|
|
@@ -2127,11 +2143,11 @@ async function sendHookPushPayloads({
|
|
|
2127
2143
|
sentIds
|
|
2128
2144
|
});
|
|
2129
2145
|
}
|
|
2130
|
-
await notifyAfterSend(ctx, { ...afterSendBase, sentCount, error });
|
|
2146
|
+
await notifyAfterSend(ctx, { ...afterSendBase, sentCount, pushedCount, error });
|
|
2131
2147
|
throw error;
|
|
2132
2148
|
}
|
|
2133
2149
|
await markPushesDelivered({ db: ctx.db, userId: task.user_id, messageIds: sentIds });
|
|
2134
|
-
await notifyAfterSend(ctx, { ...afterSendBase, sentCount, error: null });
|
|
2150
|
+
await notifyAfterSend(ctx, { ...afterSendBase, sentCount, pushedCount, error: null });
|
|
2135
2151
|
return total;
|
|
2136
2152
|
}
|
|
2137
2153
|
|
|
@@ -2334,12 +2350,14 @@ async function processSingleMessage(task, ctx, providedMasterKey, predecrypted =
|
|
|
2334
2350
|
contentPushes.push(contentPush);
|
|
2335
2351
|
}
|
|
2336
2352
|
const pushesToSend = reasoningPush ? [reasoningPush, ...contentPushes] : contentPushes;
|
|
2337
|
-
await appendPushesToOutbox({ db: ctx.db, userId: task.user_id, userKey, pushes: pushesToSend });
|
|
2353
|
+
const outboxed = await appendPushesToOutbox({ db: ctx.db, userId: task.user_id, userKey, pushes: pushesToSend });
|
|
2354
|
+
const pushGate = { outboxed };
|
|
2355
|
+
const contentToPush = contentPushes.filter((push) => shouldSendPush(push, pushGate));
|
|
2338
2356
|
const sentIds = [];
|
|
2339
2357
|
let cancelledMidBurst = false;
|
|
2340
2358
|
let reasoningError;
|
|
2341
2359
|
try {
|
|
2342
|
-
if (reasoningPush) {
|
|
2360
|
+
if (reasoningPush && shouldSendPush(reasoningPush, pushGate)) {
|
|
2343
2361
|
const reasoning2 = await deliverReasoningPush(ctx, pushSubscription, reasoningPush);
|
|
2344
2362
|
if (reasoning2.shipped) {
|
|
2345
2363
|
sentIds.push(reasoningPush.messageId);
|
|
@@ -2348,10 +2366,10 @@ async function processSingleMessage(task, ctx, providedMasterKey, predecrypted =
|
|
|
2348
2366
|
reasoningError = reasoning2.error;
|
|
2349
2367
|
}
|
|
2350
2368
|
}
|
|
2351
|
-
for (let i = 0; i <
|
|
2352
|
-
await sendTaggedPush(ctx.webpush, pushSubscription, JSON.stringify(
|
|
2353
|
-
sentIds.push(
|
|
2354
|
-
if (i <
|
|
2369
|
+
for (let i = 0; i < contentToPush.length; i++) {
|
|
2370
|
+
await sendTaggedPush(ctx.webpush, pushSubscription, JSON.stringify(contentToPush[i]));
|
|
2371
|
+
sentIds.push(contentToPush[i].messageId);
|
|
2372
|
+
if (i < contentToPush.length - 1) {
|
|
2355
2373
|
await sleepFor(ctx, SLEEP_BETWEEN_MESSAGES_MS2);
|
|
2356
2374
|
}
|
|
2357
2375
|
}
|
|
@@ -5195,7 +5213,7 @@ function createClientStateHandler(ctx) {
|
|
|
5195
5213
|
}
|
|
5196
5214
|
|
|
5197
5215
|
// src/server/lib/version.js
|
|
5198
|
-
var SERVER_VERSION = true ? "2.6.0-next.
|
|
5216
|
+
var SERVER_VERSION = true ? "2.6.0-next.23" : "0.0.0-dev";
|
|
5199
5217
|
|
|
5200
5218
|
// src/server/handlers/capabilities.js
|
|
5201
5219
|
var SERVER_FEATURES = Object.freeze([
|
package/dist/cloudflare.cjs
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
var
|
|
29
|
+
var _chunkBNZLICCIcjs = require('./chunk-BNZLICCI.cjs');
|
|
30
30
|
require('./chunk-7NMQFTDJ.cjs');
|
|
31
31
|
|
|
32
32
|
|
|
@@ -56,4 +56,4 @@ require('./chunk-7NMQFTDJ.cjs');
|
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
|
|
59
|
-
exports.DEFAULT_MAX_REQUEST_BODY_BYTES =
|
|
59
|
+
exports.DEFAULT_MAX_REQUEST_BODY_BYTES = _chunkBNZLICCIcjs.DEFAULT_MAX_REQUEST_BODY_BYTES; exports.MAX_PUSH_PAYLOAD_BYTES = _chunkBNZLICCIcjs.MAX_PUSH_PAYLOAD_BYTES; exports.NonRetryableError = _chunkBNZLICCIcjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunkBNZLICCIcjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunkBNZLICCIcjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunkBNZLICCIcjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunkBNZLICCIcjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunkBNZLICCIcjs.advanceOccurrence; exports.createD1Adapter = _chunkBNZLICCIcjs.createD1Adapter; exports.createSingleUserCloudflareWorker = _chunkBNZLICCIcjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunkBNZLICCIcjs.createSingleUserServer; exports.createWebCryptoWebPush = _chunkBNZLICCIcjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunkBNZLICCIcjs.decryptFromStorage; exports.decryptPayload = _chunkBNZLICCIcjs.decryptPayload; exports.deriveUserEncryptionKey = _chunkBNZLICCIcjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunkBNZLICCIcjs.encryptForStorage; exports.ensureSchema = _chunkBNZLICCIcjs.ensureSchema; exports.getSchemaVersion = _chunkBNZLICCIcjs.getSchemaVersion; exports.isNonRetryableError = _chunkBNZLICCIcjs.isNonRetryableError; exports.isValidTimeZoneId = _chunkBNZLICCIcjs.isValidTimeZoneId; exports.measurePushPayload = _chunkBNZLICCIcjs.measurePushPayload; exports.nextFutureOccurrence = _chunkBNZLICCIcjs.nextFutureOccurrence; exports.planNextOccurrence = _chunkBNZLICCIcjs.planNextOccurrence; exports.readRequestBody = _chunkBNZLICCIcjs.readRequestBody; exports.runScheduledTick = _chunkBNZLICCIcjs.runScheduledTick; exports.runTask = _chunkBNZLICCIcjs.runTask; exports.summarizeErrorCause = _chunkBNZLICCIcjs.summarizeErrorCause;
|
package/dist/cloudflare.mjs
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
|
|
74
|
-
var
|
|
74
|
+
var _chunkBNZLICCIcjs = require('./chunk-BNZLICCI.cjs');
|
|
75
75
|
require('./chunk-7NMQFTDJ.cjs');
|
|
76
76
|
|
|
77
77
|
// src/server/adapters/factory.js
|
|
@@ -105,7 +105,7 @@ async function createAdapter(config) {
|
|
|
105
105
|
// src/server/handlers/init-tenant.js
|
|
106
106
|
function createInitTenantHandler(ctx) {
|
|
107
107
|
async function POST(headers, body) {
|
|
108
|
-
const initSecret =
|
|
108
|
+
const initSecret = _chunkBNZLICCIcjs.getHeader.call(void 0, headers, "x-init-secret");
|
|
109
109
|
if (ctx.tenant.initSecret && initSecret !== ctx.tenant.initSecret) {
|
|
110
110
|
return {
|
|
111
111
|
status: 401,
|
|
@@ -118,7 +118,7 @@ function createInitTenantHandler(ctx) {
|
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
|
-
const parsed =
|
|
121
|
+
const parsed = _chunkBNZLICCIcjs.parseJsonBody.call(void 0, body);
|
|
122
122
|
if (!parsed.ok) {
|
|
123
123
|
return {
|
|
124
124
|
status: 400,
|
|
@@ -132,7 +132,7 @@ function createInitTenantHandler(ctx) {
|
|
|
132
132
|
const tenantId = payload.tenantId || void 0;
|
|
133
133
|
const driver = payload.driver;
|
|
134
134
|
const databaseUrl = payload.databaseUrl || payload.connectionString;
|
|
135
|
-
if (tenantId && !
|
|
135
|
+
if (tenantId && !_chunkBNZLICCIcjs.isValidUUIDv4.call(void 0, tenantId)) {
|
|
136
136
|
return {
|
|
137
137
|
status: 400,
|
|
138
138
|
body: {
|
|
@@ -252,7 +252,7 @@ function createSendNotificationsHandler(ctx) {
|
|
|
252
252
|
}
|
|
253
253
|
};
|
|
254
254
|
}
|
|
255
|
-
const data = await
|
|
255
|
+
const data = await _chunkBNZLICCIcjs.runScheduledTick.call(void 0, { ...ctx, db, masterKey });
|
|
256
256
|
return { status: 200, body: { success: true, data } };
|
|
257
257
|
}
|
|
258
258
|
return { POST };
|
|
@@ -274,16 +274,16 @@ function encryptConfig(config, kekBuffer) {
|
|
|
274
274
|
const plaintext = Buffer.from(JSON.stringify(config), "utf8");
|
|
275
275
|
const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
276
276
|
const authTag = cipher.getAuthTag();
|
|
277
|
-
return `v1.${
|
|
277
|
+
return `v1.${_chunkBNZLICCIcjs.bytesToBase64Url.call(void 0, iv)}.${_chunkBNZLICCIcjs.bytesToBase64Url.call(void 0, authTag)}.${_chunkBNZLICCIcjs.bytesToBase64Url.call(void 0, ciphertext)}`;
|
|
278
278
|
}
|
|
279
279
|
function decryptConfig(encrypted, kekBuffer) {
|
|
280
280
|
const parts = String(encrypted || "").split(".");
|
|
281
281
|
if (parts.length !== 4 || parts[0] !== "v1") {
|
|
282
282
|
throw new Error("INVALID_TENANT_CONFIG");
|
|
283
283
|
}
|
|
284
|
-
const iv =
|
|
285
|
-
const authTag =
|
|
286
|
-
const ciphertext =
|
|
284
|
+
const iv = _chunkBNZLICCIcjs.base64UrlToBytes.call(void 0, parts[1]);
|
|
285
|
+
const authTag = _chunkBNZLICCIcjs.base64UrlToBytes.call(void 0, parts[2]);
|
|
286
|
+
const ciphertext = _chunkBNZLICCIcjs.base64UrlToBytes.call(void 0, parts[3]);
|
|
287
287
|
const decipher = _crypto.createDecipheriv.call(void 0, "aes-256-gcm", kekBuffer, iv);
|
|
288
288
|
decipher.setAuthTag(authTag);
|
|
289
289
|
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
@@ -351,7 +351,7 @@ function createTenantBlobStore(options) {
|
|
|
351
351
|
// src/server/tenant/token.js
|
|
352
352
|
|
|
353
353
|
function sign(input, secret) {
|
|
354
|
-
return
|
|
354
|
+
return _chunkBNZLICCIcjs.bytesToBase64Url.call(void 0, _crypto.createHmac.call(void 0, "sha256", secret).update(input).digest());
|
|
355
355
|
}
|
|
356
356
|
function nowEpochSeconds() {
|
|
357
357
|
return Math.floor(Date.now() / 1e3);
|
|
@@ -367,8 +367,8 @@ function createTenantToken(params, secret) {
|
|
|
367
367
|
v: 1
|
|
368
368
|
};
|
|
369
369
|
const header = { alg: "HS256", typ: "JWT" };
|
|
370
|
-
const encodedHeader =
|
|
371
|
-
const encodedPayload =
|
|
370
|
+
const encodedHeader = _chunkBNZLICCIcjs.bytesToBase64Url.call(void 0, _chunkBNZLICCIcjs.utf8.call(void 0, JSON.stringify(header)));
|
|
371
|
+
const encodedPayload = _chunkBNZLICCIcjs.bytesToBase64Url.call(void 0, _chunkBNZLICCIcjs.utf8.call(void 0, JSON.stringify(payload)));
|
|
372
372
|
const signingInput = `${encodedHeader}.${encodedPayload}`;
|
|
373
373
|
const signature = sign(signingInput, secret);
|
|
374
374
|
return `${signingInput}.${signature}`;
|
|
@@ -387,17 +387,17 @@ function verifyTenantToken(token, secret, options = {}) {
|
|
|
387
387
|
let receivedBytes;
|
|
388
388
|
let expectedBytes;
|
|
389
389
|
try {
|
|
390
|
-
receivedBytes =
|
|
391
|
-
expectedBytes =
|
|
390
|
+
receivedBytes = _chunkBNZLICCIcjs.base64UrlToBytes.call(void 0, receivedSignature);
|
|
391
|
+
expectedBytes = _chunkBNZLICCIcjs.base64UrlToBytes.call(void 0, expectedSignature);
|
|
392
392
|
} catch (e) {
|
|
393
393
|
throw new Error("INVALID_TENANT_AUTH");
|
|
394
394
|
}
|
|
395
|
-
if (!
|
|
395
|
+
if (!_chunkBNZLICCIcjs.timingSafeEqualBytes.call(void 0, receivedBytes, expectedBytes)) {
|
|
396
396
|
throw new Error("INVALID_TENANT_AUTH");
|
|
397
397
|
}
|
|
398
398
|
let payload;
|
|
399
399
|
try {
|
|
400
|
-
payload = JSON.parse(
|
|
400
|
+
payload = JSON.parse(_chunkBNZLICCIcjs.utf8Decode.call(void 0, _chunkBNZLICCIcjs.base64UrlToBytes.call(void 0, encodedPayload)));
|
|
401
401
|
} catch (e2) {
|
|
402
402
|
throw new Error("INVALID_TENANT_AUTH");
|
|
403
403
|
}
|
|
@@ -621,15 +621,15 @@ async function createReiServer(config) {
|
|
|
621
621
|
return {
|
|
622
622
|
handlers: {
|
|
623
623
|
initTenant: createInitTenantHandler(ctx),
|
|
624
|
-
getUserKey:
|
|
625
|
-
scheduleMessage:
|
|
624
|
+
getUserKey: _chunkBNZLICCIcjs.createGetUserKeyHandler.call(void 0, ctx),
|
|
625
|
+
scheduleMessage: _chunkBNZLICCIcjs.createScheduleMessageHandler.call(void 0, ctx),
|
|
626
626
|
sendNotifications: createSendNotificationsHandler(ctx),
|
|
627
|
-
updateMessage:
|
|
628
|
-
cancelMessage:
|
|
629
|
-
messages:
|
|
630
|
-
getMessage:
|
|
631
|
-
pushSubscription:
|
|
632
|
-
llmCredentials:
|
|
627
|
+
updateMessage: _chunkBNZLICCIcjs.createUpdateMessageHandler.call(void 0, ctx),
|
|
628
|
+
cancelMessage: _chunkBNZLICCIcjs.createCancelMessageHandler.call(void 0, ctx),
|
|
629
|
+
messages: _chunkBNZLICCIcjs.createMessagesHandler.call(void 0, ctx),
|
|
630
|
+
getMessage: _chunkBNZLICCIcjs.createGetMessageHandler.call(void 0, ctx),
|
|
631
|
+
pushSubscription: _chunkBNZLICCIcjs.createPushSubscriptionHandler.call(void 0, ctx),
|
|
632
|
+
llmCredentials: _chunkBNZLICCIcjs.createLlmCredentialsHandler.call(void 0, ctx)
|
|
633
633
|
}
|
|
634
634
|
};
|
|
635
635
|
}
|
|
@@ -695,4 +695,4 @@ async function createReiServer(config) {
|
|
|
695
695
|
|
|
696
696
|
|
|
697
697
|
|
|
698
|
-
exports.CORS_ALLOW_HEADERS =
|
|
698
|
+
exports.CORS_ALLOW_HEADERS = _chunkBNZLICCIcjs.CORS_ALLOW_HEADERS; exports.CORS_ALLOW_METHODS = _chunkBNZLICCIcjs.CORS_ALLOW_METHODS; exports.CRED_ID_MAX_LENGTH = _chunkBNZLICCIcjs.CRED_ID_MAX_LENGTH; exports.CRED_PUT_BATCH_MAX = _chunkBNZLICCIcjs.CRED_PUT_BATCH_MAX; exports.CRED_REFS_MAX_ENTRIES = _chunkBNZLICCIcjs.CRED_REFS_MAX_ENTRIES; exports.CRED_ROWS_PER_USER_MAX = _chunkBNZLICCIcjs.CRED_ROWS_PER_USER_MAX; exports.DEFAULT_CLAIM_LEASE_MS = _chunkBNZLICCIcjs.DEFAULT_CLAIM_LEASE_MS; exports.DEFAULT_HEARTBEAT_LEASE_TTL_MS = _chunkBNZLICCIcjs.DEFAULT_HEARTBEAT_LEASE_TTL_MS; exports.DEFAULT_LEASE_HEARTBEAT_MS = _chunkBNZLICCIcjs.DEFAULT_LEASE_HEARTBEAT_MS; exports.DEFAULT_MAX_REQUEST_BODY_BYTES = _chunkBNZLICCIcjs.DEFAULT_MAX_REQUEST_BODY_BYTES; exports.DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE = _chunkBNZLICCIcjs.DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE; exports.DEFAULT_MAX_TOOL_ITERATIONS = _chunkBNZLICCIcjs.DEFAULT_MAX_TOOL_ITERATIONS; exports.DEFAULT_TOTAL_TIMEOUT_MS = _chunkBNZLICCIcjs.DEFAULT_TOTAL_TIMEOUT_MS; exports.DeploymentConfigError = _chunkBNZLICCIcjs.DeploymentConfigError; exports.MAX_PUSH_PAYLOAD_BYTES = _chunkBNZLICCIcjs.MAX_PUSH_PAYLOAD_BYTES; exports.MAX_TASK_PAYLOAD_BYTES = _chunkBNZLICCIcjs.MAX_TASK_PAYLOAD_BYTES; exports.MIN_SCHEDULE_LEAD_MS = _chunkBNZLICCIcjs.MIN_SCHEDULE_LEAD_MS; exports.NonRetryableError = _chunkBNZLICCIcjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunkBNZLICCIcjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunkBNZLICCIcjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunkBNZLICCIcjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunkBNZLICCIcjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunkBNZLICCIcjs.advanceOccurrence; exports.createAdapter = createAdapter; exports.createD1Adapter = _chunkBNZLICCIcjs.createD1Adapter; exports.createReiServer = createReiServer; exports.createSingleUserCloudflareWorker = _chunkBNZLICCIcjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunkBNZLICCIcjs.createSingleUserServer; exports.createTenantToken = createTenantToken; exports.createWebCryptoWebPush = _chunkBNZLICCIcjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunkBNZLICCIcjs.decryptFromStorage; exports.decryptPayload = _chunkBNZLICCIcjs.decryptPayload; exports.deriveUserEncryptionKey = _chunkBNZLICCIcjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunkBNZLICCIcjs.encryptForStorage; exports.ensureSchema = _chunkBNZLICCIcjs.ensureSchema; exports.getSchemaVersion = _chunkBNZLICCIcjs.getSchemaVersion; exports.hasChatCredRef = _chunkBNZLICCIcjs.hasChatCredRef; exports.isNonRetryableError = _chunkBNZLICCIcjs.isNonRetryableError; exports.isValidCredId = _chunkBNZLICCIcjs.isValidCredId; exports.isValidISO8601 = _chunkBNZLICCIcjs.isValidISO8601; exports.isValidTimeZoneId = _chunkBNZLICCIcjs.isValidTimeZoneId; exports.isValidUUID = _chunkBNZLICCIcjs.isValidUUID; exports.isValidUUIDv4 = _chunkBNZLICCIcjs.isValidUUIDv4; exports.isValidUrl = _chunkBNZLICCIcjs.isValidUrl; exports.measurePushPayload = _chunkBNZLICCIcjs.measurePushPayload; exports.nextFutureOccurrence = _chunkBNZLICCIcjs.nextFutureOccurrence; exports.planNextOccurrence = _chunkBNZLICCIcjs.planNextOccurrence; exports.readRequestBody = _chunkBNZLICCIcjs.readRequestBody; exports.resolveLlmCredential = _chunkBNZLICCIcjs.resolveLlmCredential; exports.runScheduledTick = _chunkBNZLICCIcjs.runScheduledTick; exports.runTask = _chunkBNZLICCIcjs.runTask; exports.sanitizeErrorSummary = _chunkBNZLICCIcjs.sanitizeErrorSummary; exports.summarizeErrorCause = _chunkBNZLICCIcjs.summarizeErrorCause; exports.supportsLlmCredentialsStore = _chunkBNZLICCIcjs.supportsLlmCredentialsStore; exports.validateAvatarUrl = _chunkBNZLICCIcjs.validateAvatarUrl; exports.validateCredRefs = _chunkBNZLICCIcjs.validateCredRefs; exports.validateCredValue = _chunkBNZLICCIcjs.validateCredValue; exports.validateLlmMessagesArray = _chunkBNZLICCIcjs.validateLlmMessagesArray; exports.validateScheduleMessagePayload = _chunkBNZLICCIcjs.validateScheduleMessagePayload; exports.validateSplitPattern = _chunkBNZLICCIcjs.validateSplitPattern; exports.verifyTenantToken = verifyTenantToken;
|
package/dist/index.mjs
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 这条 push 要不要真的发出去。
|
|
3
|
+
*
|
|
4
|
+
* @param {Record<string, unknown>} push - 定稿后的 push 对象
|
|
5
|
+
* @param {Object} options
|
|
6
|
+
* @param {boolean} options.outboxed - 这一批是否真的落进了 outbox
|
|
7
|
+
* @returns {boolean}
|
|
8
|
+
*/
|
|
9
|
+
export function shouldSendPush(push: Record<string, unknown>, { outboxed }: {
|
|
10
|
+
outboxed: boolean;
|
|
11
|
+
}): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rei-standard/amsg-server",
|
|
3
|
-
"version": "2.6.0-next.
|
|
3
|
+
"version": "2.6.0-next.23",
|
|
4
4
|
"description": "ReiStandard Active Messaging server SDK with pluggable database adapters. Three-axis push schema (messageKind / messageType / messageSubtype) from @rei-standard/amsg-shared. Auto-emits ReasoningPush when the LLM response carries reasoning_content.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@netlify/blobs": "^8.1.0",
|
|
42
|
-
"@rei-standard/amsg-shared": "^0.4.0-next.
|
|
42
|
+
"@rei-standard/amsg-shared": "^0.4.0-next.8",
|
|
43
43
|
"web-push": "^3.6.7"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|