ACP: remove maxMetaEventsPerTurn limit

This commit is contained in:
Onur 2026-03-01 18:01:32 +01:00 committed by Onur Solmaz
parent 6c08652c8d
commit 053e5eb506
9 changed files with 2 additions and 96 deletions

View File

@ -680,57 +680,6 @@ describe("createAcpReplyProjector", () => {
});
});
it("enforces maxMetaEventsPerTurn without suppressing assistant text", async () => {
const deliveries: Array<{ kind: string; text?: string }> = [];
const projector = createAcpReplyProjector({
cfg: createCfg({
acp: {
enabled: true,
stream: {
coalesceIdleMs: 0,
maxChunkChars: 256,
deliveryMode: "live",
maxMetaEventsPerTurn: 1,
tagVisibility: {
usage_update: true,
},
},
},
}),
shouldSendToolSummaries: true,
deliver: async (kind, payload) => {
deliveries.push({ kind, text: payload.text });
return true;
},
});
await projector.onEvent({
type: "status",
text: "usage updated: 10/100",
tag: "usage_update",
used: 10,
size: 100,
});
await projector.onEvent({
type: "status",
text: "usage updated: 11/100",
tag: "usage_update",
used: 11,
size: 100,
});
await projector.onEvent({
type: "text_delta",
text: "hello",
tag: "agent_message_chunk",
});
await projector.flush(true);
expect(deliveries).toEqual([
{ kind: "tool", text: prefixSystemMessage("usage updated: 10/100") },
{ kind: "block", text: "hello" },
]);
});
it("supports tagVisibility overrides for tool updates", async () => {
const deliveries: Array<{ kind: string; text?: string }> = [];
const projector = createAcpReplyProjector({

View File

@ -195,7 +195,6 @@ export function createAcpReplyProjector(params: {
const liveIdleFlushMs = Math.max(streaming.coalescing.idleMs, ACP_LIVE_IDLE_FLUSH_FLOOR_MS);
let emittedTurnChars = 0;
let emittedMetaEvents = 0;
let truncationNoticeEmitted = false;
let lastStatusHash: string | undefined;
let lastToolHash: string | undefined;
@ -264,7 +263,6 @@ export function createAcpReplyProjector(params: {
blockReplyPipeline.stop();
blockReplyPipeline = createTurnBlockReplyPipeline();
emittedTurnChars = 0;
emittedMetaEvents = 0;
truncationNoticeEmitted = false;
lastStatusHash = undefined;
lastToolHash = undefined;
@ -295,21 +293,10 @@ export function createAcpReplyProjector(params: {
await blockReplyPipeline.flush({ force });
};
const consumeMetaQuota = (force: boolean): boolean => {
if (force) {
return true;
}
if (emittedMetaEvents >= settings.maxMetaEventsPerTurn) {
return false;
}
emittedMetaEvents += 1;
return true;
};
const emitSystemStatus = async (
text: string,
meta?: AcpProjectedDeliveryMeta,
opts?: { force?: boolean; dedupe?: boolean },
opts?: { dedupe?: boolean },
) => {
if (!params.shouldSendToolSummaries) {
return;
@ -324,9 +311,6 @@ export function createAcpReplyProjector(params: {
if (shouldDedupe && lastStatusHash === hash) {
return;
}
if (!consumeMetaQuota(opts?.force === true)) {
return;
}
if (settings.deliveryMode === "final_only") {
pendingToolDeliveries.push({
payload: { text: formatted },
@ -339,10 +323,7 @@ export function createAcpReplyProjector(params: {
lastStatusHash = hash;
};
const emitToolSummary = async (
event: Extract<AcpRuntimeEvent, { type: "tool_call" }>,
opts?: { force?: boolean },
) => {
const emitToolSummary = async (event: Extract<AcpRuntimeEvent, { type: "tool_call" }>) => {
if (!params.shouldSendToolSummaries) {
return;
}
@ -386,9 +367,6 @@ export function createAcpReplyProjector(params: {
}
}
if (!consumeMetaQuota(opts?.force === true)) {
return;
}
const deliveryMeta: AcpProjectedDeliveryMeta = {
...(event.tag ? { tag: event.tag } : {}),
...(toolCallId ? { toolCallId } : {}),
@ -418,7 +396,6 @@ export function createAcpReplyProjector(params: {
tag: "session_info_update",
},
{
force: true,
dedupe: false,
},
);

View File

@ -13,7 +13,6 @@ describe("acp stream settings", () => {
expect(settings.hiddenBoundarySeparator).toBe("paragraph");
expect(settings.repeatSuppression).toBe(true);
expect(settings.maxTurnChars).toBe(24_000);
expect(settings.maxMetaEventsPerTurn).toBe(64);
});
it("applies explicit stream overrides", () => {
@ -26,7 +25,6 @@ describe("acp stream settings", () => {
hiddenBoundarySeparator: "space",
repeatSuppression: false,
maxTurnChars: 500,
maxMetaEventsPerTurn: 7,
tagVisibility: {
usage_update: true,
},
@ -38,7 +36,6 @@ describe("acp stream settings", () => {
expect(settings.hiddenBoundarySeparator).toBe("space");
expect(settings.repeatSuppression).toBe(false);
expect(settings.maxTurnChars).toBe(500);
expect(settings.maxMetaEventsPerTurn).toBe(7);
expect(settings.tagVisibility.usage_update).toBe(true);
});

View File

@ -11,7 +11,6 @@ const DEFAULT_ACP_HIDDEN_BOUNDARY_SEPARATOR_LIVE = "space";
const DEFAULT_ACP_MAX_TURN_CHARS = 24_000;
const DEFAULT_ACP_MAX_TOOL_SUMMARY_CHARS = 320;
const DEFAULT_ACP_MAX_STATUS_CHARS = 320;
const DEFAULT_ACP_MAX_META_EVENTS_PER_TURN = 64;
export const ACP_TAG_VISIBILITY_DEFAULTS: Record<AcpSessionUpdateTag, boolean> = {
agent_message_chunk: true,
@ -36,7 +35,6 @@ export type AcpProjectionSettings = {
maxTurnChars: number;
maxToolSummaryChars: number;
maxStatusChars: number;
maxMetaEventsPerTurn: number;
tagVisibility: Partial<Record<AcpSessionUpdateTag, boolean>>;
};
@ -127,14 +125,6 @@ export function resolveAcpProjectionSettings(cfg: OpenClawConfig): AcpProjection
min: 64,
max: 8_000,
}),
maxMetaEventsPerTurn: clampPositiveInteger(
stream?.maxMetaEventsPerTurn,
DEFAULT_ACP_MAX_META_EVENTS_PER_TURN,
{
min: 1,
max: 2_000,
},
),
tagVisibility: stream?.tagVisibility ?? {},
};
}

View File

@ -183,8 +183,6 @@ export const FIELD_HELP: Record<string, string> = {
"acp.stream.maxToolSummaryChars":
"Maximum characters for projected ACP tool lifecycle/progress summary lines.",
"acp.stream.maxStatusChars": "Maximum characters for projected ACP status/meta lines.",
"acp.stream.maxMetaEventsPerTurn":
"Maximum ACP meta events projected per turn (text deltas continue unaffected).",
"acp.stream.tagVisibility":
"Per-sessionUpdate visibility overrides for ACP projection (for example usage_update, available_commands_update).",
"acp.runtime.ttlMinutes":

View File

@ -375,7 +375,6 @@ export const FIELD_LABELS: Record<string, string> = {
"acp.stream.maxTurnChars": "ACP Stream Max Turn Chars",
"acp.stream.maxToolSummaryChars": "ACP Stream Max Tool Summary Chars",
"acp.stream.maxStatusChars": "ACP Stream Max Status Chars",
"acp.stream.maxMetaEventsPerTurn": "ACP Stream Max Meta Events Per Turn",
"acp.stream.tagVisibility": "ACP Stream Tag Visibility",
"acp.runtime.ttlMinutes": "ACP Runtime TTL (minutes)",
"acp.runtime.installCommand": "ACP Runtime Install Command",

View File

@ -22,8 +22,6 @@ export type AcpStreamConfig = {
maxToolSummaryChars?: number;
/** Maximum visible characters for status lines. */
maxStatusChars?: number;
/** Maximum number of meta events projected per turn. */
maxMetaEventsPerTurn?: number;
/**
* Per-sessionUpdate visibility overrides.
* Keys not listed here fall back to OpenClaw defaults.

View File

@ -352,7 +352,6 @@ export const OpenClawSchema = z
maxTurnChars: z.number().int().positive().optional(),
maxToolSummaryChars: z.number().int().positive().optional(),
maxStatusChars: z.number().int().positive().optional(),
maxMetaEventsPerTurn: z.number().int().positive().optional(),
tagVisibility: z.record(z.string(), z.boolean()).optional(),
})
.strict()

View File

@ -25,7 +25,6 @@ Use only these ACP stream controls for this behavior:
- `maxTurnChars`
- `maxToolSummaryChars`
- `maxStatusChars`
- `maxMetaEventsPerTurn`
Removed from plan/config: