File size: 5,089 Bytes
cd8bd0a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/**
 * tests/unit/compression/context-editing-telemetry.test.ts
 *
 * TDD for F4.1 — extractContextEditingTelemetry: pulls the server-side context
 * editing receipt (`applied_edits[].cleared_input_tokens` / `cleared_tool_uses`)
 * out of a Claude (Anthropic Messages) response body. Defensive over the exact
 * response shape: the array may live at `context_management.applied_edits`
 * (top-level) or nested under `usage` — we tolerate both rather than hardcode a
 * single guess (the spec's Task-1 caution).
 *
 * Run: node --import tsx/esm --test tests/unit/compression/context-editing-telemetry.test.ts
 */

import { describe, it } from "node:test";
import assert from "node:assert/strict";

import { extractContextEditingTelemetry } from "../../../open-sse/config/contextEditing.ts";

describe("extractContextEditingTelemetry", () => {
  it("returns null for null/undefined/non-object bodies", () => {
    assert.equal(extractContextEditingTelemetry(null), null);
    assert.equal(extractContextEditingTelemetry(undefined), null);
    assert.equal(extractContextEditingTelemetry("nope"), null);
    assert.equal(extractContextEditingTelemetry(42), null);
  });

  it("returns null when there is no context_management / applied_edits", () => {
    assert.equal(extractContextEditingTelemetry({ usage: { input_tokens: 10 } }), null);
    assert.equal(extractContextEditingTelemetry({ context_management: {} }), null);
    assert.equal(
      extractContextEditingTelemetry({ context_management: { applied_edits: [] } }),
      null
    );
  });

  it("reads applied_edits from the top-level context_management object", () => {
    const body = {
      context_management: {
        applied_edits: [
          { type: "clear_tool_uses_20250919", cleared_tool_uses: 8, cleared_input_tokens: 50000 },
        ],
      },
    };
    const out = extractContextEditingTelemetry(body);
    assert.ok(out);
    assert.equal(out.editCount, 1);
    assert.equal(out.clearedInputTokens, 50000);
    assert.equal(out.clearedToolUses, 8);
  });

  it("reads applied_edits nested under usage.context_management (alt shape)", () => {
    const body = {
      usage: {
        input_tokens: 120000,
        context_management: {
          applied_edits: [{ type: "clear_tool_uses_20250919", cleared_input_tokens: 30000 }],
        },
      },
    };
    const out = extractContextEditingTelemetry(body);
    assert.ok(out);
    assert.equal(out.clearedInputTokens, 30000);
  });

  it("reads applied_edits directly under usage.applied_edits (alt shape)", () => {
    const body = {
      usage: {
        applied_edits: [{ type: "clear_tool_uses_20250919", cleared_input_tokens: 12345 }],
      },
    };
    const out = extractContextEditingTelemetry(body);
    assert.ok(out);
    assert.equal(out.clearedInputTokens, 12345);
  });

  it("sums cleared tokens/tool_uses across multiple edits", () => {
    const body = {
      context_management: {
        applied_edits: [
          { type: "clear_thinking_20251015", cleared_input_tokens: 4000, cleared_tool_uses: 0 },
          { type: "clear_tool_uses_20250919", cleared_input_tokens: 6000, cleared_tool_uses: 5 },
        ],
      },
    };
    const out = extractContextEditingTelemetry(body);
    assert.ok(out);
    assert.equal(out.editCount, 2);
    assert.equal(out.clearedInputTokens, 10000);
    assert.equal(out.clearedToolUses, 5);
  });

  it("falls back to camelCase field names if present", () => {
    const body = {
      context_management: {
        applied_edits: [
          { type: "clear_tool_uses_20250919", clearedInputTokens: 777, clearedToolUses: 2 },
        ],
      },
    };
    const out = extractContextEditingTelemetry(body);
    assert.ok(out);
    assert.equal(out.clearedInputTokens, 777);
    assert.equal(out.clearedToolUses, 2);
  });

  it("returns null when edits exist but cleared nothing (no real telemetry)", () => {
    const body = {
      context_management: {
        applied_edits: [
          { type: "clear_tool_uses_20250919", cleared_input_tokens: 0, cleared_tool_uses: 0 },
        ],
      },
    };
    assert.equal(extractContextEditingTelemetry(body), null);
  });

  it("skips malformed (non-object) edit entries and still sums the valid ones", () => {
    const body = {
      context_management: {
        applied_edits: [
          null,
          "garbage",
          { type: "clear_tool_uses_20250919", cleared_input_tokens: 999 },
        ],
      },
    };
    const out = extractContextEditingTelemetry(body);
    assert.ok(out);
    assert.equal(out.clearedInputTokens, 999);
  });

  it("coerces numeric strings and ignores non-numeric junk", () => {
    const body = {
      context_management: {
        applied_edits: [
          {
            type: "clear_tool_uses_20250919",
            cleared_input_tokens: "1500",
            cleared_tool_uses: "x",
          },
        ],
      },
    };
    const out = extractContextEditingTelemetry(body);
    assert.ok(out);
    assert.equal(out.clearedInputTokens, 1500);
    assert.equal(out.clearedToolUses, 0);
  });
});