perf(runtime): reduce slack prep and qmd cache-key overhead
This commit is contained in:
@@ -24,8 +24,9 @@ export async function getMemorySearchManager(params: {
|
||||
const resolved = resolveMemoryBackendConfig(params);
|
||||
if (resolved.backend === "qmd" && resolved.qmd) {
|
||||
const statusOnly = params.purpose === "status";
|
||||
const cacheKey = buildQmdCacheKey(params.agentId, resolved.qmd);
|
||||
let cacheKey: string | undefined;
|
||||
if (!statusOnly) {
|
||||
cacheKey = buildQmdCacheKey(params.agentId, resolved.qmd);
|
||||
const cached = QMD_MANAGER_CACHE.get(cacheKey);
|
||||
if (cached) {
|
||||
return { manager: cached };
|
||||
@@ -51,9 +52,15 @@ export async function getMemorySearchManager(params: {
|
||||
return await MemoryIndexManager.get(params);
|
||||
},
|
||||
},
|
||||
() => QMD_MANAGER_CACHE.delete(cacheKey),
|
||||
() => {
|
||||
if (cacheKey) {
|
||||
QMD_MANAGER_CACHE.delete(cacheKey);
|
||||
}
|
||||
},
|
||||
);
|
||||
QMD_MANAGER_CACHE.set(cacheKey, wrapper);
|
||||
if (cacheKey) {
|
||||
QMD_MANAGER_CACHE.set(cacheKey, wrapper);
|
||||
}
|
||||
return { manager: wrapper };
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -217,22 +224,7 @@ class FallbackMemoryManager implements MemorySearchManager {
|
||||
}
|
||||
|
||||
function buildQmdCacheKey(agentId: string, config: ResolvedQmdConfig): string {
|
||||
return `${agentId}:${stableSerialize(config)}`;
|
||||
}
|
||||
|
||||
function stableSerialize(value: unknown): string {
|
||||
return JSON.stringify(sortValue(value));
|
||||
}
|
||||
|
||||
function sortValue(value: unknown): unknown {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((entry) => sortValue(entry));
|
||||
}
|
||||
if (value && typeof value === "object") {
|
||||
const sortedEntries = Object.keys(value as Record<string, unknown>)
|
||||
.toSorted((a, b) => a.localeCompare(b))
|
||||
.map((key) => [key, sortValue((value as Record<string, unknown>)[key])]);
|
||||
return Object.fromEntries(sortedEntries);
|
||||
}
|
||||
return value;
|
||||
// ResolvedQmdConfig is assembled in a stable field order in resolveMemoryBackendConfig.
|
||||
// Fast stringify avoids deep key-sorting overhead on this hot path.
|
||||
return `${agentId}:${JSON.stringify(config)}`;
|
||||
}
|
||||
|
||||
@@ -66,13 +66,17 @@ export async function prepareSlackMessage(params: {
|
||||
topic?: string;
|
||||
purpose?: string;
|
||||
} = {};
|
||||
let channelType = message.channel_type;
|
||||
if (!channelType || channelType !== "im") {
|
||||
let resolvedChannelType = normalizeSlackChannelType(message.channel_type, message.channel);
|
||||
// D-prefixed channels are always direct messages. Skip channel lookups in
|
||||
// that common path to avoid an unnecessary API round-trip.
|
||||
if (resolvedChannelType !== "im" && (!message.channel_type || message.channel_type !== "im")) {
|
||||
channelInfo = await ctx.resolveChannelName(message.channel);
|
||||
channelType = channelType ?? channelInfo.type;
|
||||
resolvedChannelType = normalizeSlackChannelType(
|
||||
message.channel_type ?? channelInfo.type,
|
||||
message.channel,
|
||||
);
|
||||
}
|
||||
const channelName = channelInfo?.name;
|
||||
const resolvedChannelType = normalizeSlackChannelType(channelType, message.channel);
|
||||
const isDirectMessage = resolvedChannelType === "im";
|
||||
const isGroupDm = resolvedChannelType === "mpim";
|
||||
const isRoom = resolvedChannelType === "channel" || resolvedChannelType === "group";
|
||||
|
||||
Reference in New Issue
Block a user