fix: preserve telegram exec approval topic routing

This commit is contained in:
Peter Steinberger
2026-04-01 13:33:56 +01:00
parent f55b6b1acf
commit ab3c646bb1
8 changed files with 152 additions and 9 deletions

View File

@@ -3,7 +3,8 @@ import type { FollowupRun } from "./queue.js";
const hoisted = vi.hoisted(() => {
const resolveRunModelFallbacksOverrideMock = vi.fn();
return { resolveRunModelFallbacksOverrideMock };
const getChannelPluginMock = vi.fn();
return { resolveRunModelFallbacksOverrideMock, getChannelPluginMock };
});
vi.mock("../../agents/agent-scope.js", () => ({
@@ -11,6 +12,10 @@ vi.mock("../../agents/agent-scope.js", () => ({
hoisted.resolveRunModelFallbacksOverrideMock(...args),
}));
vi.mock("../../channels/plugins/index.js", () => ({
getChannelPlugin: (...args: unknown[]) => hoisted.getChannelPluginMock(...args),
}));
const {
buildThreadingToolContext,
buildEmbeddedRunBaseParams,
@@ -46,6 +51,7 @@ function makeRun(overrides: Partial<FollowupRun["run"]> = {}): FollowupRun["run"
describe("agent-runner-utils", () => {
beforeEach(() => {
hoisted.resolveRunModelFallbacksOverrideMock.mockClear();
hoisted.getChannelPluginMock.mockReset();
});
it("resolves model fallback options from run context", () => {
@@ -175,7 +181,24 @@ describe("agent-runner-utils", () => {
expect(resolved.embeddedContext.messageTo).toBe("268300329");
});
it("uses OriginatingTo for telegram native command tool context without implicit thread state", () => {
it("uses telegram plugin threading context for native commands", () => {
hoisted.getChannelPluginMock.mockReturnValue({
threading: {
buildToolContext: ({
context,
hasRepliedRef,
}: {
context: { To?: string; MessageThreadId?: string | number };
hasRepliedRef?: { value: boolean };
}) => ({
currentChannelId: context.To?.trim() || undefined,
currentThreadTs:
context.MessageThreadId != null ? String(context.MessageThreadId) : undefined,
hasRepliedRef,
}),
},
});
const context = buildThreadingToolContext({
sessionCtx: {
Provider: "telegram",
@@ -191,9 +214,9 @@ describe("agent-runner-utils", () => {
expect(context).toMatchObject({
currentChannelId: "telegram:-1003841603622",
currentThreadTs: "928",
currentMessageId: "2284",
});
expect(context.currentThreadTs).toBeUndefined();
});
it("uses OriginatingTo for threading tool context on discord native commands", () => {

View File

@@ -798,6 +798,25 @@ describe("resolveSessionDeliveryTarget — cross-channel reply guard (#24152)",
expect(resolved.threadId).toBe(1122);
});
it("keeps Telegram topic thread routing when turnSourceTo uses the plugin-owned topic target", () => {
const resolved = resolveSessionDeliveryTarget({
entry: {
sessionId: "sess-forum-topic-scoped",
updatedAt: 1,
lastChannel: "telegram",
lastTo: "telegram:-1001234567890:topic:1122",
lastThreadId: 1122,
},
requestedChannel: "last",
turnSourceChannel: "telegram",
turnSourceTo: "telegram:-1001234567890:topic:1122",
});
expect(resolved.channel).toBe("telegram");
expect(resolved.to).toBe("telegram:-1001234567890:topic:1122");
expect(resolved.threadId).toBe(1122);
});
it("does not fall back to session lastThreadId when turnSourceChannel differs from session channel", () => {
const resolved = resolveSessionDeliveryTarget({
entry: {