@sliday/tamp 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Tamp
2
2
 
3
- **Token compression proxy for coding agents.** 33.9% fewer input tokens, zero code changes. Works with Claude Code, Aider, Cursor, Cline, Windsurf, and any OpenAI-compatible agent.
3
+ **Token compression proxy for coding agents.** 33.9% fewer input tokens, zero code changes. Works with Claude Code, Codex, Aider, Cursor, Cline, Windsurf, and any OpenAI-compatible agent.
4
4
 
5
5
  ```
6
6
  npx @sliday/tamp
@@ -19,6 +19,7 @@ Tamp auto-detects your agent's API format and compresses tool result blocks befo
19
19
  ```
20
20
  Claude Code ──► Tamp (localhost:7778) ──► Anthropic API
21
21
  Aider/Cursor ──► │ ──► OpenAI API
22
+ Codex CLI ─────► │ ──► OpenAI API
22
23
  Gemini CLI ────► │ ──► Google AI API
23
24
 
24
25
  ├─ JSON → minify whitespace
@@ -34,6 +35,7 @@ Gemini CLI ────► │ ──► Google AI API
34
35
  |--------|----------|--------|
35
36
  | Anthropic Messages | `POST /v1/messages` | Claude Code |
36
37
  | OpenAI Chat Completions | `POST /v1/chat/completions` | Aider, Cursor, Cline, Windsurf, OpenCode |
38
+ | OpenAI Responses | `POST /v1/responses` | Codex CLI |
37
39
  | Google Gemini | `POST .../generateContent` | Gemini CLI |
38
40
 
39
41
  ### Compression Stages
@@ -81,6 +83,12 @@ export OPENAI_API_BASE=http://localhost:7778
81
83
  aider
82
84
  ```
83
85
 
86
+ **Codex CLI:**
87
+ Add to `~/.codex/config.toml`:
88
+ ```toml
89
+ openai_base_url = "http://localhost:7778"
90
+ ```
91
+
84
92
  **Cursor / Cline / Windsurf:**
85
93
  Set the API base URL to `http://localhost:7778` in your editor's settings.
86
94
 
@@ -96,7 +104,7 @@ All configuration via environment variables:
96
104
  | `TAMP_UPSTREAM` | `https://api.anthropic.com` | Default upstream API URL |
97
105
  | `TAMP_UPSTREAM_OPENAI` | `https://api.openai.com` | Upstream for OpenAI-format requests |
98
106
  | `TAMP_UPSTREAM_GEMINI` | `https://generativelanguage.googleapis.com` | Upstream for Gemini-format requests |
99
- | `TAMP_STAGES` | `minify` | Comma-separated compression stages |
107
+ | `TAMP_STAGES` | `minify,toon` | Comma-separated compression stages |
100
108
  | `TAMP_MIN_SIZE` | `200` | Minimum content size (chars) to attempt compression |
101
109
  | `TAMP_LOG` | `true` | Enable request logging to stderr |
102
110
  | `TAMP_LOG_FILE` | _(none)_ | Write logs to file |
package/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import http from 'node:http'
2
2
  import https from 'node:https'
3
+ import zlib from 'node:zlib'
3
4
  import { loadConfig } from './config.js'
4
5
  import { compressRequest } from './compress.js'
5
6
  import { detectProvider } from './providers.js'
@@ -138,10 +139,29 @@ return http.createServer(async (req, res) => {
138
139
  const headers = { ...req.headers }
139
140
  delete headers.host
140
141
 
142
+ // Decompress gzip/deflate/br if needed
143
+ const encoding = (req.headers['content-encoding'] || '').toLowerCase()
144
+ let textBody
141
145
  try {
142
- const parsed = JSON.parse(rawBody.toString('utf-8'))
146
+ if (encoding === 'gzip') {
147
+ textBody = zlib.gunzipSync(rawBody)
148
+ } else if (encoding === 'deflate') {
149
+ textBody = zlib.inflateSync(rawBody)
150
+ } else if (encoding === 'br') {
151
+ textBody = zlib.brotliDecompressSync(rawBody)
152
+ } else {
153
+ textBody = rawBody
154
+ }
155
+ } catch {
156
+ textBody = rawBody
157
+ }
158
+
159
+ try {
160
+ const parsed = JSON.parse(textBody.toString('utf-8'))
143
161
  const { body, stats } = await compressRequest(parsed, config, provider)
144
162
  finalBody = Buffer.from(JSON.stringify(body), 'utf-8')
163
+ // Send uncompressed — simpler and content-length is accurate
164
+ delete headers['content-encoding']
145
165
 
146
166
  if (config.log && stats.length) {
147
167
  session.record(stats)
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "providers.js",
10
10
  "stats.js"
11
11
  ],
12
- "version": "0.2.3",
12
+ "version": "0.2.5",
13
13
  "description": "Token compression proxy for coding agents. Works with Claude Code, Aider, Cursor, Cline, Windsurf. 33.9% fewer input tokens.",
14
14
  "type": "module",
15
15
  "main": "index.js",
package/providers.js CHANGED
@@ -51,10 +51,16 @@ const anthropic = {
51
51
  const openai = {
52
52
  name: 'openai',
53
53
  match(method, url) {
54
- return method === 'POST' && (url.startsWith('/v1/chat/completions') || url.startsWith('/chat/completions'))
54
+ return method === 'POST' && (
55
+ url.startsWith('/v1/chat/completions') ||
56
+ url.startsWith('/chat/completions') ||
57
+ url.startsWith('/v1/responses') ||
58
+ url.startsWith('/responses')
59
+ )
55
60
  },
56
61
  normalizeUrl(url) {
57
62
  if (url.startsWith('/chat/completions')) return '/v1' + url
63
+ if (url.startsWith('/responses')) return '/v1' + url
58
64
  return url
59
65
  },
60
66
  extract(body) {