@aalis/plugin-checkpoint 0.1.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.
- package/README.md +21 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +210 -0
- package/dist/index.js.map +1 -0
- package/dist/service.d.ts +138 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +381 -0
- package/dist/service.js.map +1 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @aalis/plugin-checkpoint
|
|
2
|
+
|
|
3
|
+
运行时插件
|
|
4
|
+
|
|
5
|
+
## 角色
|
|
6
|
+
|
|
7
|
+
运行时插件
|
|
8
|
+
|
|
9
|
+
## 安装
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @aalis/plugin-checkpoint
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 使用
|
|
16
|
+
|
|
17
|
+
参考 [docs/architecture.md](../../docs/architecture.md) 与 [docs/guide/third-party-plugin.md](../../docs/guide/third-party-plugin.md)。
|
|
18
|
+
|
|
19
|
+
## 许可
|
|
20
|
+
|
|
21
|
+
见仓库根目录 LICENSE。
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ConfigSchema, Context, PluginModule } from '@aalis/core';
|
|
2
|
+
import '@aalis/plugin-agent-api';
|
|
3
|
+
export declare const name = "@aalis/plugin-checkpoint";
|
|
4
|
+
export declare const displayName = "\u56DE\u6EDA\u68C0\u67E5\u70B9";
|
|
5
|
+
export declare const subsystem = "scheduler";
|
|
6
|
+
export declare const provides: string[];
|
|
7
|
+
export declare const configSchema: ConfigSchema;
|
|
8
|
+
export declare const defaultConfig: {
|
|
9
|
+
rootDir: string;
|
|
10
|
+
maxFileSize: number;
|
|
11
|
+
keepSessions: number;
|
|
12
|
+
scopes: string[];
|
|
13
|
+
};
|
|
14
|
+
export declare const actions: PluginModule['actions'];
|
|
15
|
+
export declare function apply(ctx: Context, rawConfig: Record<string, unknown>): Promise<void>;
|
|
16
|
+
export type { CheckpointFileRecord, CheckpointService, RollbackResult, RollbackWithChatResult, TurnManifest, TurnSummary, } from './service.js';
|
|
17
|
+
declare module '@aalis/core' {
|
|
18
|
+
interface ServiceTypeMap {
|
|
19
|
+
checkpoint: import('./service.js').CheckpointService;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIvE,OAAO,yBAAyB,CAAC;AAQjC,eAAO,MAAM,IAAI,6BAA6B,CAAC;AAC/C,eAAO,MAAM,WAAW,mCAAU,CAAC;AACnC,eAAO,MAAM,SAAS,cAAc,CAAC;AACrC,eAAO,MAAM,QAAQ,UAAiB,CAAC;AAEvC,eAAO,MAAM,YAAY,EAAE,YAkC1B,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;CAKzB,CAAC;AAIF,eAAO,MAAM,OAAO,EAAE,YAAY,CAAC,SAAS,CA2C3C,CAAC;AAIF,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAgI3F;AAED,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,YAAY,EACZ,WAAW,GACZ,MAAM,cAAc,CAAC;AAGtB,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,cAAc;QACtB,UAAU,EAAE,OAAO,cAAc,EAAE,iBAAiB,CAAC;KACtD;CACF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { createStorageGateway } from '@aalis/plugin-storage-api';
|
|
2
|
+
import '@aalis/plugin-agent-api'; // 加载 agent:* 钩子的 HookContextMap augmentation
|
|
3
|
+
import { CheckpointServiceImpl, resolveConfig } from './service.js';
|
|
4
|
+
// ════════════════════════════════════════════════════════════
|
|
5
|
+
// plugin-checkpoint — 文件操作快照与回滚
|
|
6
|
+
// ════════════════════════════════════════════════════════════
|
|
7
|
+
export const name = '@aalis/plugin-checkpoint';
|
|
8
|
+
export const displayName = '回滚检查点';
|
|
9
|
+
export const subsystem = 'scheduler';
|
|
10
|
+
export const provides = ['checkpoint'];
|
|
11
|
+
export const configSchema = {
|
|
12
|
+
rootDir: {
|
|
13
|
+
type: 'string',
|
|
14
|
+
label: '存储目录',
|
|
15
|
+
description: '存储 URI(默认 data:/checkpoints),也兼容裸名/相对路径。所有 checkpoint blob 和 manifest 写入此位置。',
|
|
16
|
+
default: 'data:/checkpoints',
|
|
17
|
+
},
|
|
18
|
+
maxFileSize: {
|
|
19
|
+
type: 'number',
|
|
20
|
+
label: '单文件大小上限(字节)',
|
|
21
|
+
description: '超过此大小的文件不做内容快照,只在 manifest 里记录为 skipped。',
|
|
22
|
+
default: 10 * 1024 * 1024,
|
|
23
|
+
},
|
|
24
|
+
keepSessions: {
|
|
25
|
+
type: 'number',
|
|
26
|
+
label: '保留的会话数',
|
|
27
|
+
description: 'GC 阈值。每次提交回合后,若 session 目录数超过此值,删除最早的几个。设为 0 关闭 GC。',
|
|
28
|
+
default: 20,
|
|
29
|
+
},
|
|
30
|
+
scopes: {
|
|
31
|
+
type: 'multiselect',
|
|
32
|
+
label: '启用作用域',
|
|
33
|
+
description: '仅在匹配下列 platform:sessionType 的会话中参与 turn 生命周期(建 checkpoint)。格式举例:`webui:*` / `onebot:group` / `*` 表示全部。默认仅 `webui:*`:onebot 等聊天平台不会为每条消息创建 checkpoint。留空数组 = 禁用 checkpoint(仅允许手动 rollback)。',
|
|
34
|
+
options: [
|
|
35
|
+
{ label: '所有会话', value: '*' },
|
|
36
|
+
{ label: 'WebUI 会话(推荐)', value: 'webui:*' },
|
|
37
|
+
{ label: 'OneBot 群聊', value: 'onebot:group' },
|
|
38
|
+
{ label: 'OneBot 私聊', value: 'onebot:private' },
|
|
39
|
+
{ label: 'CLI', value: 'cli:*' },
|
|
40
|
+
],
|
|
41
|
+
default: ['webui:*'],
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
export const defaultConfig = {
|
|
45
|
+
rootDir: 'data:/checkpoints',
|
|
46
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
47
|
+
keepSessions: 20,
|
|
48
|
+
scopes: ['webui:*'],
|
|
49
|
+
};
|
|
50
|
+
// ──────────── Plugin actions (供 WebUI 调用) ────────────
|
|
51
|
+
export const actions = {
|
|
52
|
+
async listTurns(ctx, args) {
|
|
53
|
+
const svc = ctx.getService('checkpoint');
|
|
54
|
+
if (!svc)
|
|
55
|
+
return [];
|
|
56
|
+
const sessionId = args.sessionId ?? '';
|
|
57
|
+
if (!sessionId)
|
|
58
|
+
return { error: '缺少 sessionId' };
|
|
59
|
+
return svc.listTurns(sessionId);
|
|
60
|
+
},
|
|
61
|
+
async getManifest(ctx, args) {
|
|
62
|
+
const svc = ctx.getService('checkpoint');
|
|
63
|
+
if (!svc)
|
|
64
|
+
return null;
|
|
65
|
+
const sessionId = args.sessionId;
|
|
66
|
+
const turnId = args.turnId;
|
|
67
|
+
return svc.getManifest(sessionId, turnId);
|
|
68
|
+
},
|
|
69
|
+
async rollback(ctx, args) {
|
|
70
|
+
const svc = ctx.getService('checkpoint');
|
|
71
|
+
if (!svc)
|
|
72
|
+
return { ok: false, errors: [{ uri: '', reason: 'checkpoint 服务未启用' }] };
|
|
73
|
+
const sessionId = args.sessionId;
|
|
74
|
+
const turnId = args.turnId;
|
|
75
|
+
if (!sessionId || !turnId)
|
|
76
|
+
return { ok: false, errors: [{ uri: '', reason: '缺少 sessionId 或 turnId' }] };
|
|
77
|
+
return svc.rollback(sessionId, turnId);
|
|
78
|
+
},
|
|
79
|
+
async rollbackWithChat(ctx, args) {
|
|
80
|
+
const svc = ctx.getService('checkpoint');
|
|
81
|
+
if (!svc)
|
|
82
|
+
return {
|
|
83
|
+
ok: false,
|
|
84
|
+
errors: [{ uri: '', reason: 'checkpoint 服务未启用' }],
|
|
85
|
+
deletedMessages: 0,
|
|
86
|
+
chatDeleted: false,
|
|
87
|
+
};
|
|
88
|
+
const sessionId = args.sessionId;
|
|
89
|
+
const turnId = args.turnId;
|
|
90
|
+
if (!sessionId || !turnId)
|
|
91
|
+
return {
|
|
92
|
+
ok: false,
|
|
93
|
+
errors: [{ uri: '', reason: '缺少 sessionId 或 turnId' }],
|
|
94
|
+
deletedMessages: 0,
|
|
95
|
+
chatDeleted: false,
|
|
96
|
+
};
|
|
97
|
+
return svc.rollbackWithChat(sessionId, turnId);
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
// ──────────── 插件入口 ────────────
|
|
101
|
+
export async function apply(ctx, rawConfig) {
|
|
102
|
+
const config = resolveConfig(rawConfig);
|
|
103
|
+
const logger = ctx.logger.child('checkpoint');
|
|
104
|
+
const storage = createStorageGateway(ctx);
|
|
105
|
+
const service = new CheckpointServiceImpl(config, logger, storage);
|
|
106
|
+
ctx.provide('checkpoint', service);
|
|
107
|
+
// 注入回滚后端:通过 storage gateway helper 按 URI 路由到各 root
|
|
108
|
+
// 在 apply 阶段,storage 可能还没注册;gateway 本身是闭包,调用时才枚举 entry
|
|
109
|
+
service.setBackend(async (uri, data) => {
|
|
110
|
+
if (ctx.getAllServices('storage').length === 0)
|
|
111
|
+
throw new Error('storage 服务不可用');
|
|
112
|
+
await storage.writeFile(uri, data);
|
|
113
|
+
}, async (uri) => {
|
|
114
|
+
if (ctx.getAllServices('storage').length === 0)
|
|
115
|
+
throw new Error('storage 服务不可用');
|
|
116
|
+
await storage.delete(uri);
|
|
117
|
+
});
|
|
118
|
+
// 注入 chat 回滚所需依赖:memory + 事件发出器(懒解析 memory,但事件发出器立即可用)
|
|
119
|
+
const memoryProxy = new Proxy({}, {
|
|
120
|
+
get(_t, prop) {
|
|
121
|
+
const m = ctx.getService('memory');
|
|
122
|
+
if (!m)
|
|
123
|
+
return undefined;
|
|
124
|
+
const v = m[prop];
|
|
125
|
+
return typeof v === 'function' ? v.bind(m) : v;
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
service.setChatRollbackDeps({
|
|
129
|
+
memory: memoryProxy,
|
|
130
|
+
emitMessagesDeleted: (sessionId, timestamps) => {
|
|
131
|
+
ctx
|
|
132
|
+
.emit('memory:messages-deleted', { sessionId, timestamps })
|
|
133
|
+
.catch(err => logger.debug(`emit memory:messages-deleted 失败: ${err.message}`));
|
|
134
|
+
},
|
|
135
|
+
emitHistoryChanged: sessionId => {
|
|
136
|
+
ctx
|
|
137
|
+
.emit('history:changed', { sessionId })
|
|
138
|
+
.catch(err => logger.debug(`emit history:changed 失败: ${err.message}`));
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
// ──────────── 回合生命周期 ────────────
|
|
142
|
+
// agent:input:before:一次 LLM 回合开始(一个用户消息进来)
|
|
143
|
+
// 仅对配置 scopes 匹配的会话参与回合生命周期,避免 onebot 等聊天平台为每条消息都创建空 checkpoint。
|
|
144
|
+
const isScopeEnabled = (platform, sessionType) => {
|
|
145
|
+
if (config.scopes.length === 0)
|
|
146
|
+
return false;
|
|
147
|
+
const p = platform ?? '';
|
|
148
|
+
const t = sessionType ?? '';
|
|
149
|
+
for (const raw of config.scopes) {
|
|
150
|
+
const [sp = '*', st = '*'] = raw.includes(':') ? raw.split(':', 2) : [raw, '*'];
|
|
151
|
+
const platOk = sp === '*' || sp === '' || sp === p;
|
|
152
|
+
const typeOk = st === '*' || st === '' || st === t;
|
|
153
|
+
if (platOk && typeOk)
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
};
|
|
158
|
+
ctx.middleware('agent:input:before', async (data, next) => {
|
|
159
|
+
if (isScopeEnabled(data.message.platform, data.message.sessionType)) {
|
|
160
|
+
service.beginTurn(data.message.sessionId);
|
|
161
|
+
}
|
|
162
|
+
await next();
|
|
163
|
+
});
|
|
164
|
+
// agent:turn:after:回合结束(endTurn 是幂等的:没 current 则直接 return)
|
|
165
|
+
ctx.middleware('agent:turn:after', async (_data, next) => {
|
|
166
|
+
await next();
|
|
167
|
+
await service.endTurn();
|
|
168
|
+
});
|
|
169
|
+
// 监听 exec 工具调用,给当前 turn 打 execUsed 标记(UI 显示 "部分未保护")
|
|
170
|
+
ctx.middleware('agent:tool:before', async (data, next) => {
|
|
171
|
+
if (data.name === 'exec' || data.name === 'shell') {
|
|
172
|
+
service.markExecUsed();
|
|
173
|
+
}
|
|
174
|
+
await next();
|
|
175
|
+
});
|
|
176
|
+
// ──────────── 参与统一的 memory:clear ────────────
|
|
177
|
+
// /clear 与 session-manager.deleteSession 都通过 memory:clear hook 编排,
|
|
178
|
+
// 之前 checkpoint 没监听,导致 checkpoint 目录无人清理,长期泄漏。
|
|
179
|
+
ctx.middleware('memory:clear', async (data, next) => {
|
|
180
|
+
if (data.types && !data.types.includes('checkpoint')) {
|
|
181
|
+
await next();
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
if (data.scope === 'all') {
|
|
186
|
+
const n = await service.clearAll();
|
|
187
|
+
data.results.push({
|
|
188
|
+
source: 'checkpoint',
|
|
189
|
+
success: true,
|
|
190
|
+
message: `所有 checkpoint 已清空(${n} 个 session)`,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
else if (data.sessionId) {
|
|
194
|
+
const n = await service.clearSession(data.sessionId);
|
|
195
|
+
data.results.push({
|
|
196
|
+
source: 'checkpoint',
|
|
197
|
+
success: true,
|
|
198
|
+
message: n > 0 ? `当前会话 checkpoint 已清空(${n} 个 turn)` : '当前会话无 checkpoint',
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
204
|
+
data.results.push({ source: 'checkpoint', success: false, message: `checkpoint 清空失败: ${msg}` });
|
|
205
|
+
}
|
|
206
|
+
await next();
|
|
207
|
+
});
|
|
208
|
+
logger.info(`checkpoint 服务就绪 rootUri=${config.rootUri} maxFileSize=${config.maxFileSize} scopes=${config.scopes.join('|') || '<空>'}`);
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { Logger } from '@aalis/core';
|
|
2
|
+
import type { MemoryService } from '@aalis/plugin-memory-api';
|
|
3
|
+
import type { StorageService } from '@aalis/plugin-storage-api';
|
|
4
|
+
/**
|
|
5
|
+
* Checkpoint 服务
|
|
6
|
+
*
|
|
7
|
+
* 在 LLM 一次回合(assistant turn)期间记录所有受控存储中的写入/删除/重命名操作,
|
|
8
|
+
* 在改动发生前自动备份原始文件内容,使用户可以从 WebUI 一键回滚整轮操作。
|
|
9
|
+
*
|
|
10
|
+
* 协作模型:
|
|
11
|
+
* - plugin-storage-local 在执行 writeFile/delete/rename 之前,通过
|
|
12
|
+
* `ctx.getService<CheckpointService>('checkpoint')?.beforeMutate(...)` 探测本服务。
|
|
13
|
+
* - 本服务通过 hooks `agent:input:before` / `agent:turn:after` 维护「当前回合」状态。
|
|
14
|
+
* - exec 工具直接调用系统命令,不在本服务保护范围内(前端 UI 标注「未保护」)。
|
|
15
|
+
*/
|
|
16
|
+
export interface CheckpointService {
|
|
17
|
+
/** 探测:是否在某个回合内(storage-local 提早判断以避免无谓 stat) */
|
|
18
|
+
isActive(): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* 在 storage 即将修改 uri 时调用。本调用是 op="write"|"delete"|"rename" 之前的一次性快照机会。
|
|
21
|
+
* 如果同一 uri 在当前回合内已被快照过,则跳过(保留最早的原始内容)。
|
|
22
|
+
* loadOriginal 是按需读取原始内容的闭包;首次需要快照时才调用。
|
|
23
|
+
*/
|
|
24
|
+
beforeMutate(uri: string, op: 'write' | 'delete' | 'rename', loadOriginal: () => Promise<{
|
|
25
|
+
data: Buffer;
|
|
26
|
+
size: number;
|
|
27
|
+
} | null>): Promise<void>;
|
|
28
|
+
/** 列出某个 session 的所有回合 checkpoint */
|
|
29
|
+
listTurns(sessionId: string): Promise<TurnSummary[]>;
|
|
30
|
+
/** 读取某回合 manifest */
|
|
31
|
+
getManifest(sessionId: string, turnId: string): Promise<TurnManifest | null>;
|
|
32
|
+
/** 回滚某回合(恢复 / 删除 / 重命名复原)。返回受影响文件计数 */
|
|
33
|
+
rollback(sessionId: string, turnId: string): Promise<RollbackResult>;
|
|
34
|
+
/** 回滚某回合并同步删除本轮对话消息与向量条目 */
|
|
35
|
+
rollbackWithChat(sessionId: string, turnId: string): Promise<RollbackWithChatResult>;
|
|
36
|
+
/** 清除某会话的所有 checkpoint(/clear 与 deleteSession 调用)。幂等;不存在也返回 0。 */
|
|
37
|
+
clearSession(sessionId: string): Promise<number>;
|
|
38
|
+
/** 清除全部 checkpoint(/clear all 调用)。幂等。 */
|
|
39
|
+
clearAll(): Promise<number>;
|
|
40
|
+
}
|
|
41
|
+
export interface CheckpointFileRecord {
|
|
42
|
+
uri: string;
|
|
43
|
+
/** write=覆盖已有, write-new=新创建, delete=删除, rename=重命名 */
|
|
44
|
+
action: 'write' | 'write-new' | 'delete' | 'rename';
|
|
45
|
+
/** 原始大小(如果有快照) */
|
|
46
|
+
originalSize?: number;
|
|
47
|
+
/** 备份 blob 文件名(相对于 turn 目录) */
|
|
48
|
+
blob?: string;
|
|
49
|
+
/** 跳过原因(过大、读取失败等) */
|
|
50
|
+
skipped?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface TurnManifest {
|
|
53
|
+
turnId: string;
|
|
54
|
+
sessionId: string;
|
|
55
|
+
startedAt: number;
|
|
56
|
+
endedAt?: number;
|
|
57
|
+
files: CheckpointFileRecord[];
|
|
58
|
+
/** 本轮对话内消息的时间戳,用于 rollbackWithChat 精确删除消息与向量条目 */
|
|
59
|
+
messageTimestamps?: number[];
|
|
60
|
+
}
|
|
61
|
+
export interface TurnSummary {
|
|
62
|
+
turnId: string;
|
|
63
|
+
sessionId: string;
|
|
64
|
+
startedAt: number;
|
|
65
|
+
endedAt?: number;
|
|
66
|
+
fileCount: number;
|
|
67
|
+
/** 是否在 turn 内调用过 exec 工具(前端用于显示「部分未保护」) */
|
|
68
|
+
execUsed?: boolean;
|
|
69
|
+
/** 摘要预览(前 3 个文件 URI) */
|
|
70
|
+
filesPreview: string[];
|
|
71
|
+
}
|
|
72
|
+
export interface RollbackResult {
|
|
73
|
+
ok: boolean;
|
|
74
|
+
restored: string[];
|
|
75
|
+
deleted: string[];
|
|
76
|
+
errors: Array<{
|
|
77
|
+
uri: string;
|
|
78
|
+
reason: string;
|
|
79
|
+
}>;
|
|
80
|
+
}
|
|
81
|
+
export interface RollbackWithChatResult extends RollbackResult {
|
|
82
|
+
/** 实际从 memory 中删除的消息条数 */
|
|
83
|
+
deletedMessages: number;
|
|
84
|
+
/** chat 删除是否成功;若失败,errors 也会记录原因 */
|
|
85
|
+
chatDeleted: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface ServiceConfig {
|
|
88
|
+
rootUri: string;
|
|
89
|
+
maxFileSize: number;
|
|
90
|
+
keepSessions: number;
|
|
91
|
+
scopes: string[];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 实现
|
|
95
|
+
*/
|
|
96
|
+
export declare class CheckpointServiceImpl implements CheckpointService {
|
|
97
|
+
private readonly cfg;
|
|
98
|
+
private readonly logger;
|
|
99
|
+
private readonly storage;
|
|
100
|
+
private current;
|
|
101
|
+
/** 当前回合内已快照过的 uri 集合(用于去重) */
|
|
102
|
+
private snapshotted;
|
|
103
|
+
/** 文件计数器,用于命名 blob 文件 */
|
|
104
|
+
private blobIndex;
|
|
105
|
+
constructor(cfg: ServiceConfig, logger: Logger, storage: StorageService);
|
|
106
|
+
beginTurn(sessionId: string): string;
|
|
107
|
+
endTurn(): Promise<void>;
|
|
108
|
+
/** 标记当前回合调用过 exec,UI 端会提示「部分未保护」 */
|
|
109
|
+
markExecUsed(): void;
|
|
110
|
+
isActive(): boolean;
|
|
111
|
+
beforeMutate(uri: string, op: 'write' | 'delete' | 'rename', loadOriginal: () => Promise<{
|
|
112
|
+
data: Buffer;
|
|
113
|
+
size: number;
|
|
114
|
+
} | null>): Promise<void>;
|
|
115
|
+
listTurns(sessionId: string): Promise<TurnSummary[]>;
|
|
116
|
+
getManifest(sessionId: string, turnId: string): Promise<TurnManifest | null>;
|
|
117
|
+
rollback(sessionId: string, turnId: string): Promise<RollbackResult>;
|
|
118
|
+
private _backendWrite?;
|
|
119
|
+
private _backendDelete?;
|
|
120
|
+
private _memory?;
|
|
121
|
+
private _emitMessagesDeleted?;
|
|
122
|
+
private _emitHistoryChanged?;
|
|
123
|
+
setBackend(write: (uri: string, data: Buffer) => Promise<void>, del: (uri: string) => Promise<void>): void;
|
|
124
|
+
/** 注入聊天回滚所需的依赖:memory 服务 + 事件发出器 */
|
|
125
|
+
setChatRollbackDeps(deps: {
|
|
126
|
+
memory: MemoryService;
|
|
127
|
+
emitMessagesDeleted: (sessionId: string, timestamps: number[]) => void;
|
|
128
|
+
emitHistoryChanged: (sessionId: string) => void;
|
|
129
|
+
}): void;
|
|
130
|
+
rollbackWithChat(sessionId: string, turnId: string): Promise<RollbackWithChatResult>;
|
|
131
|
+
private gc;
|
|
132
|
+
private turnDir;
|
|
133
|
+
clearSession(sessionId: string): Promise<number>;
|
|
134
|
+
clearAll(): Promise<number>;
|
|
135
|
+
}
|
|
136
|
+
export declare function resolveConfig(raw: Record<string, unknown>): ServiceConfig;
|
|
137
|
+
export {};
|
|
138
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/dist/service.js
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 实现
|
|
3
|
+
*/
|
|
4
|
+
export class CheckpointServiceImpl {
|
|
5
|
+
cfg;
|
|
6
|
+
logger;
|
|
7
|
+
storage;
|
|
8
|
+
current = null;
|
|
9
|
+
/** 当前回合内已快照过的 uri 集合(用于去重) */
|
|
10
|
+
snapshotted = new Set();
|
|
11
|
+
/** 文件计数器,用于命名 blob 文件 */
|
|
12
|
+
blobIndex = 0;
|
|
13
|
+
constructor(cfg, logger, storage) {
|
|
14
|
+
this.cfg = cfg;
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
this.storage = storage;
|
|
17
|
+
}
|
|
18
|
+
// ──────────── 生命周期 ────────────
|
|
19
|
+
beginTurn(sessionId) {
|
|
20
|
+
// 如果上一回合没有正常结束,先把它 commit 掉避免遗失
|
|
21
|
+
if (this.current) {
|
|
22
|
+
this.endTurn().catch(err => this.logger.warn(`finalize 旧回合失败: ${err.message}`));
|
|
23
|
+
}
|
|
24
|
+
const turnId = crypto.randomUUID();
|
|
25
|
+
this.current = {
|
|
26
|
+
turnId,
|
|
27
|
+
sessionId,
|
|
28
|
+
startedAt: Date.now(),
|
|
29
|
+
files: [],
|
|
30
|
+
};
|
|
31
|
+
this.snapshotted = new Set();
|
|
32
|
+
this.blobIndex = 0;
|
|
33
|
+
this.logger.debug(`checkpoint 回合开始 ${sessionId} turn=${turnId}`);
|
|
34
|
+
return turnId;
|
|
35
|
+
}
|
|
36
|
+
async endTurn() {
|
|
37
|
+
if (!this.current)
|
|
38
|
+
return;
|
|
39
|
+
this.current.endedAt = Date.now();
|
|
40
|
+
// 在持久化前抓取本轮对话的消息时间戳(供 rollbackWithChat 使用)
|
|
41
|
+
// 即使本轮无文件改动,只要有消息就会持久化 manifest
|
|
42
|
+
if (this._memory && typeof this._memory.getMessagesBySessionRange === 'function') {
|
|
43
|
+
try {
|
|
44
|
+
// 宽松边界 200ms,用于容纳 archiveIncoming/saveMessage 时钟偏差
|
|
45
|
+
const msgs = await this._memory.getMessagesBySessionRange(this.current.sessionId, this.current.startedAt - 200, this.current.endedAt + 200);
|
|
46
|
+
this.current.messageTimestamps = msgs.map(m => m.timestamp).filter((t) => typeof t === 'number');
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
this.logger.warn(`抓取本轮消息时间戳失败: ${err.message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// 若整个回合没有任何文件改动且没有任何消息时间戳,跳过持久化
|
|
53
|
+
if (this.current.files.length === 0 &&
|
|
54
|
+
(!this.current.messageTimestamps || this.current.messageTimestamps.length === 0)) {
|
|
55
|
+
this.logger.debug(`checkpoint 回合无改动,跳过 ${this.current.turnId}`);
|
|
56
|
+
this.current = null;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const turnDir = this.turnDir(this.current.sessionId, this.current.turnId);
|
|
60
|
+
await this.storage.writeFile(joinUri(turnDir, 'manifest.json'), JSON.stringify(this.current, null, 2));
|
|
61
|
+
this.logger.info(`checkpoint 回合提交 turn=${this.current.turnId} 文件数=${this.current.files.length}`);
|
|
62
|
+
this.current = null;
|
|
63
|
+
this.gc().catch(err => this.logger.warn(`checkpoint GC 失败: ${err.message}`));
|
|
64
|
+
}
|
|
65
|
+
/** 标记当前回合调用过 exec,UI 端会提示「部分未保护」 */
|
|
66
|
+
markExecUsed() {
|
|
67
|
+
if (!this.current)
|
|
68
|
+
return;
|
|
69
|
+
this.current.execUsed = true;
|
|
70
|
+
}
|
|
71
|
+
// ──────────── beforeMutate ────────────
|
|
72
|
+
isActive() {
|
|
73
|
+
return this.current !== null;
|
|
74
|
+
}
|
|
75
|
+
async beforeMutate(uri, op, loadOriginal) {
|
|
76
|
+
if (!this.current)
|
|
77
|
+
return; // 回合外,忽略
|
|
78
|
+
if (this.snapshotted.has(uri))
|
|
79
|
+
return; // 同回合已快照过
|
|
80
|
+
this.snapshotted.add(uri);
|
|
81
|
+
let original = null;
|
|
82
|
+
try {
|
|
83
|
+
original = await loadOriginal();
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
this.logger.warn(`checkpoint 加载原文件失败 ${uri}: ${err.message}`);
|
|
87
|
+
}
|
|
88
|
+
// 情况 1:write 且原文件不存在 → 标记为新创建(回滚时需要删除)
|
|
89
|
+
if (!original && op === 'write') {
|
|
90
|
+
this.current.files.push({ uri, action: 'write-new' });
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// 情况 2:原文件不存在但是 delete/rename → 不可能,跳过
|
|
94
|
+
if (!original)
|
|
95
|
+
return;
|
|
96
|
+
// 情况 3:过大 → 跳过快照但记录为「skipped」
|
|
97
|
+
if (original.size > this.cfg.maxFileSize) {
|
|
98
|
+
this.current.files.push({
|
|
99
|
+
uri,
|
|
100
|
+
action: op === 'rename' ? 'rename' : op,
|
|
101
|
+
originalSize: original.size,
|
|
102
|
+
skipped: `文件过大 (${original.size} > ${this.cfg.maxFileSize})`,
|
|
103
|
+
});
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// 情况 4:正常快照
|
|
107
|
+
const blobName = `${this.blobIndex++}.bin`;
|
|
108
|
+
const turnDir = this.turnDir(this.current.sessionId, this.current.turnId);
|
|
109
|
+
await this.storage.writeFile(joinUri(turnDir, `blobs/${blobName}`), original.data);
|
|
110
|
+
this.current.files.push({
|
|
111
|
+
uri,
|
|
112
|
+
action: op === 'rename' ? 'rename' : op,
|
|
113
|
+
originalSize: original.size,
|
|
114
|
+
blob: blobName,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// ──────────── 查询 ────────────
|
|
118
|
+
async listTurns(sessionId) {
|
|
119
|
+
const sessionDir = joinUri(this.cfg.rootUri, encodeSegment(sessionId));
|
|
120
|
+
let entries;
|
|
121
|
+
try {
|
|
122
|
+
const listed = await this.storage.list(sessionDir);
|
|
123
|
+
entries = listed.entries.filter(e => e.isDirectory).map(e => e.name);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
const summaries = [];
|
|
129
|
+
for (const turnId of entries) {
|
|
130
|
+
const manifest = await this.getManifest(sessionId, turnId);
|
|
131
|
+
if (!manifest)
|
|
132
|
+
continue;
|
|
133
|
+
summaries.push({
|
|
134
|
+
turnId: manifest.turnId,
|
|
135
|
+
sessionId: manifest.sessionId,
|
|
136
|
+
startedAt: manifest.startedAt,
|
|
137
|
+
endedAt: manifest.endedAt,
|
|
138
|
+
fileCount: manifest.files.length,
|
|
139
|
+
execUsed: manifest.execUsed,
|
|
140
|
+
filesPreview: manifest.files.slice(0, 3).map(f => f.uri),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
summaries.sort((a, b) => b.startedAt - a.startedAt);
|
|
144
|
+
return summaries;
|
|
145
|
+
}
|
|
146
|
+
async getManifest(sessionId, turnId) {
|
|
147
|
+
const uri = joinUri(this.turnDir(sessionId, turnId), 'manifest.json');
|
|
148
|
+
try {
|
|
149
|
+
const raw = await this.storage.readFile(uri, 'utf-8');
|
|
150
|
+
return JSON.parse(String(raw));
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// ──────────── 回滚 ────────────
|
|
157
|
+
async rollback(sessionId, turnId) {
|
|
158
|
+
const manifest = await this.getManifest(sessionId, turnId);
|
|
159
|
+
if (!manifest) {
|
|
160
|
+
return { ok: false, restored: [], deleted: [], errors: [{ uri: '', reason: 'checkpoint 不存在' }] };
|
|
161
|
+
}
|
|
162
|
+
// 通过 storage service 来执行回滚操作,避免直接绕过权限
|
|
163
|
+
// 此处通过模块外部注入 writeBack/deleteBack 函数
|
|
164
|
+
const result = { ok: true, restored: [], deleted: [], errors: [] };
|
|
165
|
+
if (!this._backendWrite || !this._backendDelete) {
|
|
166
|
+
return { ok: false, restored: [], deleted: [], errors: [{ uri: '', reason: '回滚后端未注入' }] };
|
|
167
|
+
}
|
|
168
|
+
const turnDir = this.turnDir(sessionId, turnId);
|
|
169
|
+
for (const file of manifest.files) {
|
|
170
|
+
try {
|
|
171
|
+
if (file.action === 'write-new') {
|
|
172
|
+
// 新创建的文件 → 删除
|
|
173
|
+
await this._backendDelete(file.uri);
|
|
174
|
+
result.deleted.push(file.uri);
|
|
175
|
+
}
|
|
176
|
+
else if (file.skipped) {
|
|
177
|
+
// 跳过快照的,无法恢复
|
|
178
|
+
result.errors.push({ uri: file.uri, reason: file.skipped });
|
|
179
|
+
}
|
|
180
|
+
else if (file.blob) {
|
|
181
|
+
const data = await this.storage.readFile(joinUri(turnDir, `blobs/${file.blob}`));
|
|
182
|
+
await this._backendWrite(file.uri, Buffer.from(data));
|
|
183
|
+
result.restored.push(file.uri);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
result.errors.push({ uri: file.uri, reason: err.message });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (result.errors.length > 0)
|
|
191
|
+
result.ok = false;
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
// ──────────── 回滚后端注入 ────────────
|
|
195
|
+
_backendWrite;
|
|
196
|
+
_backendDelete;
|
|
197
|
+
_memory;
|
|
198
|
+
_emitMessagesDeleted;
|
|
199
|
+
_emitHistoryChanged;
|
|
200
|
+
setBackend(write, del) {
|
|
201
|
+
this._backendWrite = write;
|
|
202
|
+
this._backendDelete = del;
|
|
203
|
+
}
|
|
204
|
+
/** 注入聊天回滚所需的依赖:memory 服务 + 事件发出器 */
|
|
205
|
+
setChatRollbackDeps(deps) {
|
|
206
|
+
this._memory = deps.memory;
|
|
207
|
+
this._emitMessagesDeleted = deps.emitMessagesDeleted;
|
|
208
|
+
this._emitHistoryChanged = deps.emitHistoryChanged;
|
|
209
|
+
}
|
|
210
|
+
async rollbackWithChat(sessionId, turnId) {
|
|
211
|
+
const manifest = await this.getManifest(sessionId, turnId);
|
|
212
|
+
if (!manifest) {
|
|
213
|
+
return {
|
|
214
|
+
ok: false,
|
|
215
|
+
restored: [],
|
|
216
|
+
deleted: [],
|
|
217
|
+
errors: [{ uri: '', reason: 'checkpoint 不存在' }],
|
|
218
|
+
deletedMessages: 0,
|
|
219
|
+
chatDeleted: false,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
// 先执行文件回滚
|
|
223
|
+
const fileResult = await this.rollback(sessionId, turnId);
|
|
224
|
+
const result = {
|
|
225
|
+
...fileResult,
|
|
226
|
+
deletedMessages: 0,
|
|
227
|
+
chatDeleted: false,
|
|
228
|
+
};
|
|
229
|
+
const timestamps = manifest.messageTimestamps ?? [];
|
|
230
|
+
if (timestamps.length === 0) {
|
|
231
|
+
// 无消息可删(例如旧 checkpoint),仅文件回滚生效
|
|
232
|
+
result.chatDeleted = true;
|
|
233
|
+
return result;
|
|
234
|
+
}
|
|
235
|
+
if (!this._memory || typeof this._memory.deleteMessagesByTimestamps !== 'function') {
|
|
236
|
+
result.errors.push({ uri: '', reason: '当前 memory 后端不支持 deleteMessagesByTimestamps' });
|
|
237
|
+
result.ok = false;
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
result.deletedMessages = await this._memory.deleteMessagesByTimestamps(sessionId, timestamps);
|
|
242
|
+
result.chatDeleted = true;
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
result.errors.push({ uri: '', reason: `删除消息失败: ${err.message}` });
|
|
246
|
+
result.ok = false;
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
// 通知向量插件清理同时间戳的向量条目
|
|
250
|
+
try {
|
|
251
|
+
this._emitMessagesDeleted?.(sessionId, timestamps);
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
this.logger.warn(`emit memory:messages-deleted 失败: ${err.message}`);
|
|
255
|
+
}
|
|
256
|
+
// 通知前端刷新历史
|
|
257
|
+
try {
|
|
258
|
+
this._emitHistoryChanged?.(sessionId);
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
this.logger.warn(`emit history:changed 失败: ${err.message}`);
|
|
262
|
+
}
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
265
|
+
// ──────────── GC ────────────
|
|
266
|
+
async gc() {
|
|
267
|
+
if (this.cfg.keepSessions <= 0)
|
|
268
|
+
return;
|
|
269
|
+
let sessions;
|
|
270
|
+
try {
|
|
271
|
+
const listed = await this.storage.list(this.cfg.rootUri);
|
|
272
|
+
sessions = listed.entries.filter(e => e.isDirectory).map(e => ({ name: e.name, uri: e.uri }));
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
if (sessions.length <= this.cfg.keepSessions)
|
|
278
|
+
return;
|
|
279
|
+
// 按 session 目录的最新 mtime 排序,淘汰最旧的
|
|
280
|
+
const sessionInfo = [];
|
|
281
|
+
for (const item of sessions) {
|
|
282
|
+
try {
|
|
283
|
+
const s = await this.storage.stat(item.uri);
|
|
284
|
+
sessionInfo.push({ name: item.name, uri: item.uri, mtime: new Date(s.mtime).getTime() || 0 });
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
/* skip */
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
sessionInfo.sort((a, b) => b.mtime - a.mtime);
|
|
291
|
+
const toDelete = sessionInfo.slice(this.cfg.keepSessions);
|
|
292
|
+
for (const item of toDelete) {
|
|
293
|
+
try {
|
|
294
|
+
await this.storage.delete(item.uri);
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
this.logger.warn(`GC 删除 ${item.name} 失败: ${err.message}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
turnDir(sessionId, turnId) {
|
|
302
|
+
return joinUri(this.cfg.rootUri, `${encodeSegment(sessionId)}/${encodeSegment(turnId)}`);
|
|
303
|
+
}
|
|
304
|
+
// ──────────── 会话级清理 ────────────
|
|
305
|
+
// 与 plugin-commands / plugin-session-manager 的 memory:clear 调度对齐,
|
|
306
|
+
// 避免 /clear 与 deleteSession 后 checkpoint 目录泄露。
|
|
307
|
+
async clearSession(sessionId) {
|
|
308
|
+
const sessionDir = joinUri(this.cfg.rootUri, encodeSegment(sessionId));
|
|
309
|
+
try {
|
|
310
|
+
const listed = await this.storage.list(sessionDir);
|
|
311
|
+
const count = listed.entries.filter(e => e.isDirectory).length;
|
|
312
|
+
await this.storage.delete(sessionDir);
|
|
313
|
+
if (count > 0)
|
|
314
|
+
this.logger.info(`checkpoint 清理 session=${sessionId} 共 ${count} 个 turn`);
|
|
315
|
+
return count;
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
// 目录不存在是正常情况
|
|
319
|
+
this.logger.debug(`checkpoint clearSession ${sessionId} 跳过: ${err.message}`);
|
|
320
|
+
return 0;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
async clearAll() {
|
|
324
|
+
try {
|
|
325
|
+
const listed = await this.storage.list(this.cfg.rootUri);
|
|
326
|
+
const sessions = listed.entries.filter(e => e.isDirectory);
|
|
327
|
+
for (const item of sessions) {
|
|
328
|
+
try {
|
|
329
|
+
await this.storage.delete(item.uri);
|
|
330
|
+
}
|
|
331
|
+
catch (err) {
|
|
332
|
+
this.logger.warn(`checkpoint clearAll 删 ${item.name} 失败: ${err.message}`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (sessions.length > 0)
|
|
336
|
+
this.logger.info(`checkpoint 全量清理:${sessions.length} 个 session`);
|
|
337
|
+
return sessions.length;
|
|
338
|
+
}
|
|
339
|
+
catch (err) {
|
|
340
|
+
this.logger.debug(`checkpoint clearAll 跳过: ${err.message}`);
|
|
341
|
+
return 0;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function joinUri(base, rel) {
|
|
346
|
+
const b = base.endsWith('/') ? base : `${base}/`;
|
|
347
|
+
return `${b}${rel.replace(/^\/+/, '')}`;
|
|
348
|
+
}
|
|
349
|
+
/** 文件系统路径段:把 ":" "/" "\" 等特殊字符 URL 编码 */
|
|
350
|
+
function encodeSegment(s) {
|
|
351
|
+
return s.replace(/[^A-Za-z0-9._-]/g, c => `_${c.charCodeAt(0).toString(16)}`);
|
|
352
|
+
}
|
|
353
|
+
export function resolveConfig(raw) {
|
|
354
|
+
const rootInput = typeof raw.rootDir === 'string' ? raw.rootDir : 'data:/checkpoints';
|
|
355
|
+
const rawScopes = raw.scopes;
|
|
356
|
+
const scopes = Array.isArray(rawScopes)
|
|
357
|
+
? rawScopes.filter((x) => typeof x === 'string' && x.length > 0)
|
|
358
|
+
: typeof rawScopes === 'string' && rawScopes.length > 0
|
|
359
|
+
? rawScopes
|
|
360
|
+
.split(/[,\s]+/)
|
|
361
|
+
.map(s => s.trim())
|
|
362
|
+
.filter(Boolean)
|
|
363
|
+
: ['webui:*'];
|
|
364
|
+
return {
|
|
365
|
+
rootUri: toUri(rootInput),
|
|
366
|
+
maxFileSize: typeof raw.maxFileSize === 'number' ? Math.max(1024, raw.maxFileSize) : 10 * 1024 * 1024,
|
|
367
|
+
keepSessions: typeof raw.keepSessions === 'number' ? Math.max(0, Math.floor(raw.keepSessions)) : 20,
|
|
368
|
+
scopes,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function toUri(input) {
|
|
372
|
+
const s = String(input ?? '').trim();
|
|
373
|
+
if (!s)
|
|
374
|
+
return 'data:/checkpoints';
|
|
375
|
+
if (s.includes(':/'))
|
|
376
|
+
return s;
|
|
377
|
+
const cleaned = s.replace(/^\.?\/+/, '');
|
|
378
|
+
const idx = cleaned.indexOf('/');
|
|
379
|
+
return idx > 0 ? `${cleaned.slice(0, idx)}:/${cleaned.slice(idx + 1)}` : `data:/${cleaned}`;
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aalis/plugin-checkpoint",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"aalis-plugin"
|
|
7
|
+
],
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@aalis/plugin-agent-api": "^0.1.0",
|
|
15
|
+
"@aalis/plugin-storage-api": "^0.1.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "^22.0.0",
|
|
19
|
+
"typescript": "^5.7.0",
|
|
20
|
+
"@aalis/plugin-memory-api": "0.1.0",
|
|
21
|
+
"@aalis/plugin-webui-api": "0.1.0",
|
|
22
|
+
"@aalis/core": "0.1.0"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@aalis/core": "^0.1.0"
|
|
26
|
+
},
|
|
27
|
+
"aalis": {
|
|
28
|
+
"service": {
|
|
29
|
+
"provides": [
|
|
30
|
+
"checkpoint"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc",
|
|
36
|
+
"dev": "tsc --watch"
|
|
37
|
+
}
|
|
38
|
+
}
|