@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 +10 -2
- package/index.js +21 -1
- package/package.json +1 -1
- package/providers.js +7 -1
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
|
-
|
|
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.
|
|
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' && (
|
|
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) {
|