mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 05:29:44 +02:00
fix(core): Handle input timeline events and scrub before truncation
- Merge master: the timeline gained an input event variant, which the exhaustive switch in truncateTimeline must handle (CI caught this) - Scrub serialized payloads before slicing so a secret that straddles the cut cannot leave an unscrubbed prefix behind - Pin the newest-first ordering in the pagination test with a two-element page Linear: CONTEXT-178
This commit is contained in:
parent
a43a46ef52
commit
df263a4f61
|
|
@ -1783,17 +1783,22 @@ describe('McpAgentToolsService', () => {
|
|||
],
|
||||
} as never);
|
||||
|
||||
// Two-element page from offset 0: only a real newest-first reversal
|
||||
// yields [exec-3, exec-2]; a raw oldest-first slice would fail here.
|
||||
const result = await callTool('get_agent_session', {
|
||||
agentId: 'agent-1',
|
||||
sessionId: 'thread-1',
|
||||
limit: 1,
|
||||
offset: 1,
|
||||
limit: 2,
|
||||
offset: 0,
|
||||
});
|
||||
|
||||
expect(result.structuredContent).toMatchObject({
|
||||
ok: true,
|
||||
executions: [expect.objectContaining({ executionId: 'exec-2' })],
|
||||
count: 1,
|
||||
executions: [
|
||||
expect.objectContaining({ executionId: 'exec-3' }),
|
||||
expect.objectContaining({ executionId: 'exec-2' }),
|
||||
],
|
||||
count: 2,
|
||||
total: 3,
|
||||
nextOffset: 2,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -86,11 +86,12 @@ export function truncateTimeline(
|
|||
} catch {
|
||||
serialized = String(value);
|
||||
}
|
||||
if (serialized.length <= budget) return value;
|
||||
// Scrub before slicing: a secret that straddles the cut would otherwise
|
||||
// leave an unrecognized — and unscrubbed — prefix behind.
|
||||
const scrubbed = scrubSecretsInText(serialized);
|
||||
if (scrubbed.length <= budget) return scrubbed === serialized ? value : scrubbed;
|
||||
truncated = true;
|
||||
return (
|
||||
scrubSecretsInText(serialized.slice(0, budget)) + truncationMarker(serialized.length - budget)
|
||||
);
|
||||
return scrubbed.slice(0, budget) + truncationMarker(scrubbed.length - budget);
|
||||
};
|
||||
|
||||
const timeline = events.map((event): ShapedTimelineEvent => {
|
||||
|
|
@ -120,6 +121,10 @@ export function truncateTimeline(
|
|||
return { ...event, response: capValue(event.response) };
|
||||
case 'background-task-signal':
|
||||
return { ...event, signal: capValue(event.signal) };
|
||||
// Carries only a message reference — nothing to cap. No default case:
|
||||
// a new event variant must fail the build until it gets a decision here.
|
||||
case 'input':
|
||||
return { ...event };
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user