feat: 完善智能体图片聊天与会话恢复
- 增加私有图片上传、绑定、历史回显与生命周期清理 - 支持输入草稿恢复、图片交互和模型图片能力约束 - 修复旧脏会话幂等删除与前端会话恢复
This commit is contained in:
83
easyflow-ui-admin/app/src/utils/agent-chat-cache.ts
Normal file
83
easyflow-ui-admin/app/src/utils/agent-chat-cache.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
const COMPOSER_SHADOW_PREFIX = 'easyflow:agent-composer-shadow';
|
||||
const RUNTIME_STORAGE_PREFIX = 'easyflow:agent-chat-runtime';
|
||||
|
||||
type AccountIdentity =
|
||||
| null
|
||||
| undefined
|
||||
| {
|
||||
id?: number | string;
|
||||
tenantId?: number | string;
|
||||
};
|
||||
|
||||
const clearListeners = new Set<(identity: string) => void>();
|
||||
|
||||
/**
|
||||
* 生成聊天本地缓存使用的账号隔离标识。
|
||||
*/
|
||||
export function resolveAgentChatIdentity(account: AccountIdentity) {
|
||||
if (!account?.id) {
|
||||
return '';
|
||||
}
|
||||
return `${String(account.tenantId || 'default')}:${String(account.id)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册账号聊天缓存清理监听器。
|
||||
*/
|
||||
export function onAgentChatCacheClear(listener: (identity: string) => void) {
|
||||
clearListeners.add(listener);
|
||||
return () => clearListeners.delete(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理指定账号的草稿影子和运行快照。
|
||||
*/
|
||||
export function clearAgentChatBrowserCache(account: AccountIdentity) {
|
||||
const identity = resolveAgentChatIdentity(account);
|
||||
if (!identity) {
|
||||
return;
|
||||
}
|
||||
removeStorageEntries(safeStorage('localStorage'), [
|
||||
`${COMPOSER_SHADOW_PREFIX}:${identity}:`,
|
||||
]);
|
||||
removeStorageEntries(safeStorage('sessionStorage'), [
|
||||
`${RUNTIME_STORAGE_PREFIX}:${identity}:`,
|
||||
]);
|
||||
for (const listener of clearListeners) {
|
||||
listener(identity);
|
||||
}
|
||||
}
|
||||
|
||||
/** 草稿影子存储前缀。 */
|
||||
export { COMPOSER_SHADOW_PREFIX, RUNTIME_STORAGE_PREFIX };
|
||||
|
||||
function removeStorageEntries(
|
||||
storage: Storage | undefined,
|
||||
prefixes: string[],
|
||||
) {
|
||||
if (!storage) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const keys: string[] = [];
|
||||
for (let index = 0; index < storage.length; index++) {
|
||||
const key = storage.key(index);
|
||||
if (key && prefixes.some((prefix) => key.startsWith(prefix))) {
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
for (const key of keys) {
|
||||
storage.removeItem(key);
|
||||
}
|
||||
} catch {
|
||||
// 浏览器禁用存储时,登录退出流程仍应继续。
|
||||
}
|
||||
}
|
||||
|
||||
function safeStorage(type: 'localStorage' | 'sessionStorage') {
|
||||
try {
|
||||
return globalThis[type];
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user