Skip to content

Commit e7384d5

Browse files
authored
fix(ci): restore Telegram and SDK guard checks (#99355)
1 parent 8c5f45f commit e7384d5

4 files changed

Lines changed: 67 additions & 57 deletions

File tree

extensions/telegram/src/bot-message-context.prompt-context.test.ts

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,7 @@
11
import { describe, expect, it } from "vitest";
2-
import { buildInboundUserContextPrefix } from "../../../src/auto-reply/reply/inbound-meta.js";
3-
import { buildReplyPromptEnvelopeBase } from "../../../src/auto-reply/reply/prompt-prelude.js";
42
import { buildTelegramMessageContextForTest } from "./bot-message-context.test-harness.js";
53
import type { TelegramPromptContextEntry } from "./bot-message-context.types.js";
64

7-
type RoomEventPromptContext = Parameters<typeof buildInboundUserContextPrefix>[0] &
8-
Parameters<typeof buildReplyPromptEnvelopeBase>[0]["ctx"];
9-
10-
function renderRoomEventPromptText(ctx: RoomEventPromptContext): string {
11-
const inboundUserContext = buildInboundUserContextPrefix(ctx);
12-
return (
13-
buildReplyPromptEnvelopeBase({
14-
ctx,
15-
sessionCtx: ctx,
16-
baseBody: ctx.BodyForAgent ?? ctx.Body ?? ctx.RawBody ?? "",
17-
hasUserBody: true,
18-
inboundUserContext,
19-
isBareSessionReset: false,
20-
startupAction: "new",
21-
inboundEventKind: "room_event",
22-
sourceReplyDeliveryMode: "message_tool_only",
23-
}).currentInboundContext?.text ?? ""
24-
);
25-
}
26-
275
const telegramChatWindowContext: TelegramPromptContextEntry = {
286
label: "Conversation context",
297
source: "telegram",
@@ -228,6 +206,49 @@ describe("buildTelegramMessageContext prompt context", () => {
228206
);
229207
});
230208

209+
it("applies the ambient watermark before truncating the history window", async () => {
210+
const ctx = await buildTelegramMessageContextForTest({
211+
message: {
212+
message_id: 13,
213+
chat: { id: -1001234567890, type: "supergroup", title: "Forum" },
214+
from: { id: 1234, first_name: "Pat" },
215+
text: "@bot what happened?",
216+
entities: [{ type: "mention", offset: 0, length: 4 }],
217+
},
218+
historyLimit: 1,
219+
groupHistories: new Map([
220+
[
221+
"-1001234567890",
222+
[
223+
{
224+
messageId: "12",
225+
sender: "Mira",
226+
timestamp: 1_700_000_002_000,
227+
body: "unpersisted gap",
228+
},
229+
{
230+
messageId: "11",
231+
sender: "Lee",
232+
timestamp: 1_700_000_001_000,
233+
body: "late persisted ambient",
234+
},
235+
],
236+
],
237+
]),
238+
sessionRuntime: {
239+
readAmbientTranscriptWatermark: () => ({
240+
messageId: "11",
241+
timestampMs: 1_700_000_001_000,
242+
updatedAt: 1_700_000_003_000,
243+
}),
244+
},
245+
});
246+
247+
expect(ctx?.ctxPayload.InboundHistory).toEqual([
248+
expect.objectContaining({ messageId: "12", body: "unpersisted gap" }),
249+
]);
250+
});
251+
231252
it("omits transcript-owned ambient rows from steady-state room-event prompt text", async () => {
232253
const ctx = await buildTelegramMessageContextForTest({
233254
message: {
@@ -276,11 +297,13 @@ describe("buildTelegramMessageContext prompt context", () => {
276297
if (!ctx) {
277298
throw new Error("Expected room-event context");
278299
}
279-
const promptText = renderRoomEventPromptText(ctx.ctxPayload as RoomEventPromptContext);
280-
expect(promptText).toContain("[OpenClaw room event]");
281-
expect(promptText).toContain("Current event:\n#12 Pat: current ambient");
282-
expect(promptText).not.toContain("persisted ambient");
283-
expect(promptText).not.toContain("Chat history since last reply");
300+
expect(ctx.ctxPayload).toMatchObject({
301+
BodyForAgent: "current ambient",
302+
InboundEventKind: "room_event",
303+
MessageSid: "12",
304+
SenderName: "Pat",
305+
});
284306
expect(ctx.ctxPayload.InboundHistory).toBeUndefined();
307+
expect(ctx.ctxPayload.UntrustedStructuredContext).toBeUndefined();
285308
});
286309
});

extensions/telegram/src/bot-message-context.session.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import type {
2020
} from "openclaw/plugin-sdk/config-contracts";
2121
import { resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
2222
import { timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
23-
import type { HistoryEntry } from "openclaw/plugin-sdk/reply-history";
23+
import { createChannelHistoryWindow, type HistoryEntry } from "openclaw/plugin-sdk/reply-history";
2424
import type { ResolvedAgentRoute } from "openclaw/plugin-sdk/routing";
2525
import { logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
2626
import { evaluateSupplementalContextVisibility } from "openclaw/plugin-sdk/security-runtime";
@@ -447,7 +447,13 @@ export async function buildTelegramInboundContextPayload(params: {
447447
let watermarkedGroupHistoryEntries: HistoryEntry[] | undefined;
448448
let groupHistoryPromptEntries: HistoryEntry[] = [];
449449
if (hasGroupHistoryContext && historyKey && historyLimit > 0) {
450-
const fullGroupHistoryEntries = (groupHistories.get(historyKey) ?? [])
450+
const bufferedHistoryCount = groupHistories.get(historyKey)?.length ?? 0;
451+
const fullGroupHistoryEntries = (
452+
createChannelHistoryWindow({ historyMap: groupHistories }).buildInboundHistory({
453+
historyKey,
454+
limit: bufferedHistoryCount,
455+
}) ?? []
456+
)
451457
.filter((entry) =>
452458
isTelegramHistoryEntryAfterAmbientWatermark(entry, ambientTranscriptWatermark),
453459
)

extensions/telegram/src/bot-message-dispatch.test.ts

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import {
77
} from "openclaw/plugin-sdk/plugin-state-test-runtime";
88
import { setReplyPayloadMetadata } from "openclaw/plugin-sdk/reply-payload-testing";
99
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
10-
import { buildInboundUserContextPrefix } from "../../../src/auto-reply/reply/inbound-meta.js";
11-
import { buildReplyPromptEnvelopeBase } from "../../../src/auto-reply/reply/prompt-prelude.js";
1210
import { resolveAutoTopicLabelConfig as resolveAutoTopicLabelConfigRuntime } from "./auto-topic-label-config.js";
1311
import type { TelegramBotDeps } from "./bot-deps.js";
1412
import {
@@ -28,8 +26,6 @@ import type { TelegramRuntime } from "./runtime.types.js";
2826
type DispatchReplyWithBufferedBlockDispatcherArgs = Parameters<
2927
TelegramBotDeps["dispatchReplyWithBufferedBlockDispatcher"]
3028
>[0];
31-
type RoomEventPromptContext = Parameters<typeof buildInboundUserContextPrefix>[0] &
32-
Parameters<typeof buildReplyPromptEnvelopeBase>[0]["ctx"];
3329

3430
const createTelegramDraftStream = vi.hoisted(() => vi.fn());
3531
const dispatchReplyWithBufferedBlockDispatcher = vi.hoisted(() =>
@@ -427,23 +423,6 @@ describe("dispatchTelegramMessage draft streaming", () => {
427423
expect(preview.text).toBe(barText);
428424
}
429425

430-
function renderRoomEventPromptText(ctx: RoomEventPromptContext): string {
431-
const inboundUserContext = buildInboundUserContextPrefix(ctx);
432-
return (
433-
buildReplyPromptEnvelopeBase({
434-
ctx,
435-
sessionCtx: ctx,
436-
baseBody: ctx.BodyForAgent ?? ctx.Body ?? ctx.RawBody ?? "",
437-
hasUserBody: true,
438-
inboundUserContext,
439-
isBareSessionReset: false,
440-
startupAction: "new",
441-
inboundEventKind: "room_event",
442-
sourceReplyDeliveryMode: "message_tool_only",
443-
}).currentInboundContext?.text ?? ""
444-
);
445-
}
446-
447426
function createContext(overrides?: Partial<TelegramMessageContext>): TelegramMessageContext {
448427
const base = {
449428
ctxPayload: {},
@@ -1275,12 +1254,14 @@ describe("dispatchTelegramMessage draft streaming", () => {
12751254
const dispatchParams = mockCallArg(
12761255
dispatchReplyWithBufferedBlockDispatcher,
12771256
) as DispatchReplyWithBufferedBlockDispatcherArgs;
1278-
const promptText = renderRoomEventPromptText(dispatchParams.ctx as RoomEventPromptContext);
1279-
expect(promptText).toContain("[OpenClaw room event]");
1280-
expect(promptText).toContain("Current event:\n#27787 Cara: ambient current");
1281-
expect(promptText).not.toContain("persisted recovered ambient");
1282-
expect(promptText).not.toContain("Chat history since last reply");
1257+
expect(dispatchParams.ctx).toMatchObject({
1258+
BodyForAgent: "ambient current",
1259+
InboundEventKind: "room_event",
1260+
MessageSid: "27787",
1261+
SenderName: "Cara",
1262+
});
12831263
expect(dispatchParams.ctx.InboundHistory).toBeUndefined();
1264+
expect(dispatchParams.ctx.UntrustedStructuredContext).toBeUndefined();
12841265
});
12851266

12861267
it("moves recovered user-request history out of the original topic", async () => {

scripts/plugin-sdk-surface-report.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,8 @@ let publicDeprecatedExportsByEntrypointBudget;
202202
try {
203203
budgets = {
204204
publicEntrypoints: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_ENTRYPOINTS", 323),
205-
publicExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_EXPORTS", 10408),
206-
publicFunctionExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_FUNCTION_EXPORTS", 5224),
205+
publicExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_EXPORTS", 10412),
206+
publicFunctionExports: readBudgetEnv("OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_FUNCTION_EXPORTS", 5227),
207207
publicDeprecatedExports: readBudgetEnv(
208208
"OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_DEPRECATED_EXPORTS",
209209
3261,

0 commit comments

Comments
 (0)