@rei-standard/amsg-server 2.6.0-next.33 → 2.6.0-next.34

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 CHANGED
@@ -1014,3 +1014,18 @@ async function executeToolCalls(calls, ctx) {
1014
1014
  取消收尾使用 `onFireSettled({ status: 'cancelled', willRetry: false, error, ... })`,不是生成失败。应用应在这里释放资源、结算已发生的用量,避免发出失败提示或把未送达内容记为已回复。取消时已经开始写入的 outbox 批次会在写完后检查信号并撤掉未投递部分;已经发到客户端的消息仍由客户端处理。应用需要记录停止的任务身份,拦住迟到推送、补收以及尚未显示的本地内容。已完成的外部副作用无法撤销;不支持 AbortSignal 的工具也需要自己在执行步骤之间检查取消。
1015
1015
 
1016
1016
  执行阶段的 `ctx.writeState`、`scheduleTask`、`cancelTask`、`renewTask` 和 `emitResult` 会拒绝取消后新发起的操作。`onFireSettled` 的 `info.writeState` 特意仍可用,供宿主释放锁、保存账单等收尾;它不能用于继续生成阶段的业务动作。已经开始的数据库写入不支持回滚,宿主仍需处理并发状态版本。
1017
+
1018
+ ### Cloud data inventory and cleanup (D1)
1019
+
1020
+ Single-user D1 deployments expose `cloud-data-management` in `/capabilities`.
1021
+ The management API lists actual cloud resources, including acknowledged outbox
1022
+ rows, orphan state chunks and resources missing a local character. Cleanup uses
1023
+ server previews, persistent operations and cron continuation. Owner retirement
1024
+ fences future writes and in-flight task outputs; restoration is explicit and
1025
+ returns the generation required on subsequent writes.
1026
+
1027
+ See the repository [cloud data management contract](../../../docs/cloud-data-management.md)
1028
+ for routes, encrypted metadata, host `cloudData.resolveOwner` configuration,
1029
+ retention, and upgrade requirements. Other adapters do not advertise this
1030
+ capability. Use the matching client SDK management methods rather than composing
1031
+ bulk deletes from the browser's local resource list.
@@ -49,6 +49,81 @@ export class D1Adapter {
49
49
  * @returns {Promise<number>} 各批影响行数之和
50
50
  */
51
51
  private _runInClauseWrite;
52
+ /** A complete management implementation needs real transactional batches. */
53
+ get cloudDataManagement(): boolean;
54
+ _cloudGuardPredicate(userId: any, guard: any): {
55
+ sql: string;
56
+ args: any[];
57
+ };
58
+ _cloudBatch(statements: any, userId: any, guards?: any[], metadata?: Map<any, any>): Promise<any[]>;
59
+ getCloudResourceMetadata(userId: any, resourceKey: any): Promise<any>;
60
+ listCloudResourceRows(userId: any): Promise<{
61
+ gaps: any[];
62
+ }>;
63
+ _cloudRecord(row: any): Promise<{
64
+ id: any;
65
+ userId: any;
66
+ kind: any;
67
+ data: any;
68
+ updatedAt: any;
69
+ }>;
70
+ putCloudDataRecord(userId: any, kind: any, id: any, data: any, { idempotencyKey, createOnly, leaseToken }?: {
71
+ idempotencyKey?: any;
72
+ createOnly?: boolean;
73
+ }): Promise<{
74
+ id: any;
75
+ userId: any;
76
+ kind: any;
77
+ data: any;
78
+ updatedAt: any;
79
+ }>;
80
+ getCloudDataRecord(userId: any, kind: any, id: any): Promise<{
81
+ id: any;
82
+ userId: any;
83
+ kind: any;
84
+ data: any;
85
+ updatedAt: any;
86
+ }>;
87
+ getCloudDataRecordByIdempotency(userId: any, kind: any, idempotencyKey: any): Promise<{
88
+ id: any;
89
+ userId: any;
90
+ kind: any;
91
+ data: any;
92
+ updatedAt: any;
93
+ }>;
94
+ _cloudRecordForList(row: any): Promise<{
95
+ id: any;
96
+ userId: any;
97
+ kind: any;
98
+ data: any;
99
+ updatedAt: any;
100
+ }>;
101
+ listCloudDataRecords(userId: any, kind: any): Promise<any[]>;
102
+ listCloudDataRecordsAcrossUsers(kind: any): Promise<any[]>;
103
+ claimCloudDataRecord(userId: any, kind: any, id: any, leaseMs: any, leaseToken?: any): Promise<boolean>;
104
+ releaseCloudDataRecord(userId: any, kind: any, id: any, leaseToken: any): Promise<void>;
105
+ renewCloudDataRecordLease(userId: any, kind: any, id: any, leaseMs: any, leaseToken: any): Promise<boolean>;
106
+ deleteCloudDataRecord(userId: any, kind: any, id: any): Promise<boolean>;
107
+ cleanupCloudDataRecords(kind: any, beforeMs: any): Promise<any>;
108
+ /** Sidecars are indexes only. Remove them only while their backing row is absent. */
109
+ cleanupCloudResourceMetadata(userId?: any): Promise<any>;
110
+ listCloudOwners(userId: any): Promise<any>;
111
+ getCloudOwner(userId: any, owner: any): Promise<{
112
+ active: boolean;
113
+ generation: any;
114
+ updatedAt: any;
115
+ }>;
116
+ setCloudOwnerActive(userId: any, owner: any, active: any, expectedGeneration: any): Promise<{
117
+ active: boolean;
118
+ generation: any;
119
+ updatedAt: any;
120
+ }>;
121
+ isCloudOwnerGuardValid(userId: any, guard: any): Promise<boolean>;
122
+ /** Delete only the exact physical snapshot; no untrusted SQL identifiers. */
123
+ deleteCloudResourceRows(userId: any, locators: any, { operationId, leaseToken }?: {}): Promise<{
124
+ deleted: number;
125
+ changed: number;
126
+ }>;
52
127
  initSchema(): Promise<{
53
128
  columnsCreated: number;
54
129
  indexesCreated: number;
@@ -83,7 +158,7 @@ export class D1Adapter {
83
158
  indexes: string[];
84
159
  }>;
85
160
  dropSchema(): Promise<void>;
86
- createTask(params: any): Promise<any>;
161
+ createTask(params: any, cloudGuard?: any): Promise<any>;
87
162
  /**
88
163
  * 建新任务的同时取消旧的那条(`POST /schedule-message` 的 supersedesUuid)。
89
164
  *
@@ -96,7 +171,7 @@ export class D1Adapter {
96
171
  * @returns {Promise<Object>} createTask 的返回行 + `superseded`(旧行是否
97
172
  * 真的被删掉;false = 旧行本就不存在)
98
173
  */
99
- createTaskSuperseding(params: import("./interface.js").InsertTaskParams, supersedesUuid: string): Promise<any>;
174
+ createTaskSuperseding(params: import("./interface.js").InsertTaskParams, supersedesUuid: string, cloudGuard?: any): Promise<any>;
100
175
  getTaskByUuid(uuid: any, userId: any): Promise<any>;
101
176
  getTaskByUuidOnly(uuid: any): Promise<any>;
102
177
  /**
@@ -109,7 +184,7 @@ export class D1Adapter {
109
184
  getTaskStatusByUuidOnly(uuid: string): Promise<{
110
185
  status: string;
111
186
  } | null>;
112
- updateTaskById(taskId: any, updates: any): Promise<any>;
187
+ updateTaskById(taskId: any, updates: any, cloudGuard?: any): Promise<any>;
113
188
  /**
114
189
  * 按 uuid 改一条 pending 任务(PUT /update-message、fire hook 的 renewTask)。
115
190
  *
@@ -119,7 +194,7 @@ export class D1Adapter {
119
194
  * ——用户以为改期生效了,实际什么都没留下。正文这类字段不受这道门约束:它们
120
195
  * 只影响以后的触发,收尾那边本来就不会覆盖(见 run-tick 的收尾守卫)。
121
196
  */
122
- updateTaskByUuid(uuid: any, userId: any, encryptedPayload: any, extraFields: any): Promise<{
197
+ updateTaskByUuid(uuid: any, userId: any, encryptedPayload: any, extraFields: any, cloudGuard?: any): Promise<{
123
198
  uuid: any;
124
199
  updated_at: string;
125
200
  }>;
@@ -160,7 +235,7 @@ export class D1Adapter {
160
235
  * @returns {Promise<boolean>} true = 领到了;false = 别人正拿着租约、同分组
161
236
  * 有任务正在跑、排期被改过、或行已不是 pending
162
237
  */
163
- claimTask(taskId: number, expectedNextSendAt: string, leaseUntil: string | Date, serializeGroup?: string | null): Promise<boolean>;
238
+ claimTask(taskId: number, expectedNextSendAt: string, leaseUntil: string | Date, serializeGroup?: string | null, cloudGuard?: any): Promise<boolean>;
164
239
  /**
165
240
  * 投递期间的租约续期(run-tick 的心跳用)。只在行仍是 pending 且确实持有
166
241
  * 租约(lease_until 非空)时生效——收尾把租约放掉之后,迟到的心跳不会把
@@ -170,7 +245,7 @@ export class D1Adapter {
170
245
  * @param {string|Date} leaseUntil - 新的租期末尾
171
246
  * @returns {Promise<boolean>} true = 续上了
172
247
  */
173
- renewTaskLease(taskId: number, leaseUntil: string | Date): Promise<boolean>;
248
+ renewTaskLease(taskId: number, leaseUntil: string | Date, cloudGuard?: any): Promise<boolean>;
174
249
  listTasks(userId: any, opts?: {}): Promise<{
175
250
  tasks: any;
176
251
  total: number;
@@ -241,7 +316,7 @@ export class D1Adapter {
241
316
  key?: string;
242
317
  keyPrefix?: string;
243
318
  updatedAt: number;
244
- }>, now?: number): Promise<{
319
+ }>, now?: number, cloudGuard?: any): Promise<{
245
320
  upserted: number;
246
321
  skipped: number;
247
322
  outcomes: boolean[];
@@ -377,7 +452,7 @@ export class D1Adapter {
377
452
  upsertLlmCredentials(userId: string, entries: Array<{
378
453
  credId: string;
379
454
  encryptedValue: string;
380
- }>): Promise<number>;
455
+ }>, cloudGuard?: any): Promise<number>;
381
456
  /**
382
457
  * 按 cred_id 批量读这个用户的凭据行(`encrypted_value` 是密文,解密在上
383
458
  * 层)。排程时的存在性检查和 fire 时的解析共用这一个口。
@@ -456,7 +531,7 @@ export class D1Adapter {
456
531
  total_messages?: number | null;
457
532
  payload: string;
458
533
  created_at: number;
459
- }>): Promise<number>;
534
+ }>, cloudGuard?: any): Promise<number>;
460
535
  /**
461
536
  * 把这一批标记为「Web Push 已发出」。发送失败的段不标——delivered_at 为
462
537
  * null 的行正是客户端最需要拉的那部分。
@@ -53,6 +53,7 @@ export const SQLITE_ALL_INDEXES: {
53
53
  description: string;
54
54
  critical: boolean;
55
55
  }[];
56
+ export const CLOUD_DATA_TABLES_SQL: string[];
56
57
  /**
57
58
  * 这一版代码跑起来需要的表 / 列 / 索引。
58
59
  *