mirror of
https://github.com/teamchong/pxpipe.git
synced 2026-07-22 02:02:51 +02:00
transform: KNOWN_STATIC_TAGS allowlist (silence <types> canary)
The canary in splitStaticDynamic flags tag-shaped blocks in the static slab that aren't in DYNAMIC_BLOCK_TAGS — designed to catch a new Claude Code release that ships a per-turn tag we'd accidentally bake into the cached image. In production it has been firing on `<types>` for 93% of real requests (125 of 134 in the user's events log), which is noise: `<types>` is part of Claude Code's built-in tool documentation, not a per-turn rotation. Add a second list, KNOWN_STATIC_TAGS, that mirrors DYNAMIC_BLOCK_TAGS in shape. The unknown-tag computation now subtracts BOTH lists, so a tag is only "unknown" when it's in neither the per-turn set nor the known-static set. Seed KNOWN_STATIC_TAGS with ['types']. Updates the warn log in src/node.ts to mention both options so a reviewer of a NEW unknown tag knows which list to extend. Adds a regression test pinning that <types> in the static slab no longer produces info.unknownStaticTags.
This commit is contained in:
+17
-1
@@ -159,6 +159,20 @@ const DYNAMIC_BLOCK_TAGS = [
|
||||
'system-reminder',
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Tag-shaped blocks that DO appear in the static slab and SHOULD be baked into
|
||||
* the cached image. These are part of Claude Code's built-in system prompt /
|
||||
* tool documentation, not per-turn injections, so they're stable across turns.
|
||||
*
|
||||
* The canary in splitStaticDynamic flags any tag-shaped block in the static
|
||||
* slab that isn't in DYNAMIC_BLOCK_TAGS — designed to catch a new Claude Code
|
||||
* release that ships a per-turn tag we'd accidentally cache. Without this
|
||||
* allowlist, known-static tags like <types> trigger the canary on most turns
|
||||
* and drown out the real signal. Add a tag here only after confirming it's
|
||||
* static (appears in the cacheable part of the prompt, not rotated per turn).
|
||||
*/
|
||||
const KNOWN_STATIC_TAGS = ['types'] as const;
|
||||
|
||||
function splitStaticDynamic(text: string): {
|
||||
staticText: string;
|
||||
dynamicText: string;
|
||||
@@ -190,12 +204,14 @@ function splitStaticDynamic(text: string): {
|
||||
// collapse. Surfacing the tag name as telemetry lets us detect that
|
||||
// within hours of a Claude Code release.
|
||||
const known = new Set<string>(DYNAMIC_BLOCK_TAGS);
|
||||
const knownStatic = new Set<string>(KNOWN_STATIC_TAGS);
|
||||
const sniffer = /<([a-zA-Z][a-zA-Z0-9_-]*)(?:\s[^>]*)?>[\s\S]*?<\/\1>/g;
|
||||
const unknown = new Set<string>();
|
||||
let s: RegExpExecArray | null;
|
||||
while ((s = sniffer.exec(staticBuf)) !== null) {
|
||||
const tag = s[1]!;
|
||||
if (!known.has(tag) && tag.length <= 64) unknown.add(tag);
|
||||
if (!known.has(tag) && !knownStatic.has(tag) && tag.length <= 64)
|
||||
unknown.add(tag);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
+1
-1
@@ -369,7 +369,7 @@ async function main(): Promise<void> {
|
||||
if (e.info?.unknownStaticTags && e.info.unknownStaticTags.length > 0) {
|
||||
console.warn(
|
||||
`[pixelpipe warn] unknown tag(s) in static slab: ${e.info.unknownStaticTags.join(', ')} ` +
|
||||
`— may need to add to DYNAMIC_BLOCK_TAGS in src/core/transform.ts`,
|
||||
`— may need to add to DYNAMIC_BLOCK_TAGS (per-turn) or KNOWN_STATIC_TAGS (static) in src/core/transform.ts`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -322,6 +322,23 @@ describe('transform', () => {
|
||||
expect(info.unknownStaticTags).not.toContain('env');
|
||||
});
|
||||
|
||||
it('does not flag <types> as an unknown tag (it lives in KNOWN_STATIC_TAGS)', async () => {
|
||||
const sys =
|
||||
'claude.md\n'.repeat(400) +
|
||||
'<types>\nstring\nnumber\n</types>\n' +
|
||||
'<env>\nWorking directory: /tmp\n</env>';
|
||||
const body = new TextEncoder().encode(
|
||||
JSON.stringify({
|
||||
model: 'claude',
|
||||
messages: [{ role: 'user', content: 'hi' }],
|
||||
system: sys,
|
||||
}),
|
||||
);
|
||||
const { info } = await transformRequest(body);
|
||||
// <types> is known-static; it should NOT show up as an unknown tag.
|
||||
expect(info.unknownStaticTags).toBeUndefined();
|
||||
});
|
||||
|
||||
it('omits unknownStaticTags when the static slab has no tag-shaped blocks', async () => {
|
||||
const sys = 'claude.md\n'.repeat(400) + '<env>\nWorking directory: /tmp\n</env>';
|
||||
const body = new TextEncoder().encode(
|
||||
|
||||
Reference in New Issue
Block a user