fix: resolve implicit default Telegram status sessions

This commit is contained in:
Peter Steinberger
2026-04-23 07:57:04 +01:00
parent 9dd097a7a5
commit dfca707e4b
2 changed files with 104 additions and 5 deletions

View File

@@ -467,6 +467,55 @@ describe("session_status tool", () => {
expect(details.sessionKey).toBe("main");
});
it("falls back from implicit default-account direct policy keys to persisted direct sessions", async () => {
resetSessionStore({
"agent:main:telegram:direct:1053274893": {
sessionId: "s-direct",
updatedAt: 10,
},
});
const tool = getSessionStatusTool("agent:main:telegram:default:direct:1053274893");
const result = await tool.execute("call-default-direct", {});
const details = result.details as { ok?: boolean; sessionKey?: string };
expect(details.ok).toBe(true);
expect(details.sessionKey).toBe("agent:main:telegram:direct:1053274893");
});
it("falls back from implicit default-account direct policy keys to main sessions", async () => {
resetSessionStore({
"agent:main:main": {
sessionId: "s-main",
updatedAt: 10,
},
});
const tool = getSessionStatusTool("agent:main:telegram:default:direct:1053274893");
const result = await tool.execute("call-default-direct-main", {});
const details = result.details as { ok?: boolean; sessionKey?: string };
expect(details.ok).toBe(true);
expect(details.sessionKey).toBe("agent:main:main");
});
it("keeps explicit default-account direct session lookups strict", async () => {
resetSessionStore({
"agent:main:main": {
sessionId: "s-main",
updatedAt: 10,
},
});
const tool = getSessionStatusTool("agent:main:telegram:default:direct:1053274893");
await expect(
tool.execute("call-default-direct-explicit", {
sessionKey: "agent:main:telegram:default:direct:1053274893",
}),
).rejects.toThrow("Unknown sessionKey: agent:main:telegram:default:direct:1053274893");
});
it("prefers a literal current session key in session_status", async () => {
resetSessionStore({
main: {

View File

@@ -133,6 +133,33 @@ function resolveStoreScopedRequesterKey(params: {
return parsed.rest === params.mainKey ? params.mainKey : params.requesterKey;
}
function listImplicitDefaultDirectFallbackKeys(params: {
keyRaw: string;
mainKey: string;
}): string[] {
const parsed = parseAgentSessionKey(params.keyRaw.trim());
if (!parsed) {
return [];
}
const parts = parsed.rest.split(":");
if (parts.length < 4 || parts[1] !== "default" || parts[2] !== "direct") {
return [];
}
const [channel, , , ...peerParts] = parts;
if (!channel || peerParts.length === 0) {
return [];
}
const candidates = [
`agent:${parsed.agentId}:${channel}:direct:${peerParts.join(":")}`,
buildAgentMainSessionKey({
agentId: parsed.agentId,
mainKey: params.mainKey,
}),
params.mainKey,
];
return [...new Set(candidates)];
}
function formatSessionTaskLine(params: {
relatedSessionKey: string;
callerOwnerKey: string;
@@ -295,6 +322,7 @@ export function createSessionStatusTool(opts?: {
let requestedKeyRaw = requestedKeyParam ?? opts?.agentSessionKey;
const requestedKeyInput = requestedKeyRaw?.trim() ?? "";
let resolvedViaSessionId = false;
let resolvedViaImplicitCurrentFallback = false;
if (!requestedKeyRaw?.trim()) {
throw new Error("sessionKey required");
}
@@ -402,17 +430,39 @@ export function createSessionStatusTool(opts?: {
});
}
if (!resolved && requestedKeyParam === undefined) {
for (const fallbackKey of listImplicitDefaultDirectFallbackKeys({
keyRaw: requestedKeyRaw,
mainKey,
})) {
resolved = resolveSessionEntry({
store,
keyRaw: fallbackKey,
alias,
mainKey,
requesterInternalKey: storeScopedRequesterKey,
includeAliasFallback: true,
});
if (resolved) {
resolvedViaImplicitCurrentFallback = true;
break;
}
}
}
if (!resolved) {
const kind = shouldResolveSessionIdInput(requestedKeyRaw) ? "sessionId" : "sessionKey";
throw new Error(`Unknown ${kind}: ${requestedKeyRaw}`);
}
// Preserve caller-scoped raw-key/current lookups as "self" for visibility checks.
const visibilityTargetKey =
!resolvedViaSessionId &&
(requestedKeyInput === "current" || resolved.key === requestedKeyInput)
? visibilityRequesterKey
: normalizeVisibilityTargetSessionKey(resolved.key, agentId);
const shouldTreatVisibilityTargetAsSelf =
resolvedViaImplicitCurrentFallback ||
(!resolvedViaSessionId &&
(requestedKeyInput === "current" || resolved.key === requestedKeyInput));
const visibilityTargetKey = shouldTreatVisibilityTargetAsSelf
? visibilityRequesterKey
: normalizeVisibilityTargetSessionKey(resolved.key, agentId);
const access = visibilityGuard.check(visibilityTargetKey);
if (!access.allowed) {
throw new Error(access.error);