https://github.com/djdembeck/toon-format-skill
TOON Format Skill for OpenCode - Pre/post-processing middleware for LLM optimization using Token-Oriented Object Notation (TOON). Achieves 40-54% token reduction for structured tabular data.
https://github.com/djdembeck/toon-format-skill
llm opencode optimization serialization tokenization toon
Last synced: about 2 months ago
JSON representation
TOON Format Skill for OpenCode - Pre/post-processing middleware for LLM optimization using Token-Oriented Object Notation (TOON). Achieves 40-54% token reduction for structured tabular data.
- Host: GitHub
- URL: https://github.com/djdembeck/toon-format-skill
- Owner: djdembeck
- License: mit
- Created: 2026-02-20T01:21:33.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-02-20T02:23:26.000Z (3 months ago)
- Last Synced: 2026-02-20T05:27:14.259Z (3 months ago)
- Topics: llm, opencode, optimization, serialization, tokenization, toon
- Language: TypeScript
- Homepage:
- Size: 21.5 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# TOON Format Skill for OpenCode
Pre/post-processing middleware for LLM optimization using [Token-Oriented Object Notation (TOON)](https://github.com/toon-format/toon).
## About TOON
TOON is a compact, human-readable data format designed specifically for LLM input. It reduces token usage by ~40-54% while improving data retrieval accuracy.
- **Original Format**: [github.com/toon-format/toon](https://github.com/toon-format/toon)
- **Official Website**: [toonformat.dev](https://toonformat.dev)
- **Specification**: [TOON Spec](https://github.com/toon-format/spec)
## Benefits
- **~40-54% token reduction** for structured tabular data
- **Improved LLM data retrieval accuracy** (73.9% vs 69.7% for JSON)
- **Lossless JSON round-trips** (100% data preservation)
- **Automatic eligibility detection** - only uses TOON when beneficial
## Installation
### For OpenCode
```bash
# Create skill directory
mkdir -p ~/.config/opencode/skills/toon-format
cd ~/.config/opencode/skills/toon-format
# Clone or copy skill files
git clone https://github.com/djdembeck/toon-format-skill .
```
### For Development
```bash
git clone https://github.com/djdembeck/toon-format-skill.git
cd toon-format-skill
bun install
```
## Quick Start
### Using Hooks (Automatic)
```typescript
import { autoTOON } from 'toon-format'
const result = await autoTOON.process(
{
systemPrompt: 'You are a data analyst.',
userMessage: 'Analyze this data.',
data: {
users: [
{ id: 1, name: 'Alice', salary: 120000 },
{ id: 2, name: 'Bob', salary: 80000 }
]
}
},
async (processedRequest) => {
// Your LLM call here
return await llm.complete(processedRequest)
}
)
console.log(`Token savings: ${result.metrics.percentSaved.toFixed(1)}%`)
console.log('Parsed response:', result.parsedResponse)
```
### Using TOONProcessor (Manual)
```typescript
import { TOONProcessor } from 'toon-format'
const processor = new TOONProcessor()
// Pre-process LLM request
const { request, eligibility } = processor.preProcess({
systemPrompt: 'You are a data analyst.',
userMessage: 'Analyze this data.',
data: { users: [...] }
})
// request.data is now TOON format with token savings
console.log(`Token savings: ${request.metrics?.percentSaved.toFixed(1)}%`)
```
## Automatic Hooks
The hooks API provides automatic pre/post-processing:
### autoTOON.process()
Full request/response cycle with automatic encoding/decoding:
```typescript
import { autoTOON } from 'toon-format'
const result = await autoTOON.process(request, async (processedReq) => {
return await myLLMClient.complete(processedReq)
})
// Returns:
// - result.originalRequest: original request
// - result.toonRequest: TOON-encoded request
// - result.metrics: token savings
// - result.parsedResponse: decoded response
// - result.tokenSavings: number of tokens saved
```
### withTOON() Wrapper
Higher-order function for wrapping any async function:
```typescript
import { withTOON } from 'toon-format'
const toonWrapped = withTOON(myLLMFunction, { logMetrics: true })
const result = await toonWrapped(request)
```
### autoTOON.wrap()
Wrap an existing LLM client:
```typescript
import { autoTOON } from 'toon-format'
const toonClient = autoTOON.wrap(myOpenAIClient)
const result = await toonClient.complete(request)
```
### autoTOON.middleware()
Express/Fastify middleware:
```typescript
import { autoTOON } from 'toon-format'
app.use(autoTOON.middleware())
// Automatically encodes req.body.data and decodes responses
```
### useTOON() Hook
For React or similar frameworks:
```typescript
import { useTOON } from 'toon-format'
const { processWithTOON, wrap } = useTOON({ logMetrics: true })
```
## Core Functions
### Encode/Decode
```typescript
import { encodeToTOON, decodeFromTOON } from 'toon-format'
const data = { users: [{ id: 1, name: 'Alice' }] }
const toon = encodeToTOON(data)
// users[1]{id,name}:
// 1,Alice
const decoded = decodeFromTOON(toon)
// { users: [{ id: 1, name: 'Alice' }] }
```
### Token Savings Analysis
```typescript
import { calculateTokenSavings } from 'toon-format'
const metrics = calculateTokenSavings({ records: [...] })
console.log(metrics)
// { original: 500, toon: 250, savings: 250, percentSaved: 50 }
```
### Eligibility Analysis
```typescript
import { analyzeEligibility } from 'toon-format'
const eligibility = analyzeEligibility(data)
if (eligibility.shouldUseTOON) {
console.log(`Use TOON - ${eligibility.percentTabular}% tabular`)
} else {
console.log(`Skip TOON - ${eligibility.reason}`)
}
```
## TOONProcessor Class
Complete pre/post-processing pipeline:
```typescript
import { TOONProcessor } from 'toon-format'
const processor = new TOONProcessor()
// Pre-process request
const preResult = processor.preProcess(request)
// preResult.request.toonProcessed - true if TOON was applied
// preResult.request.metrics - token savings metrics
// preResult.eligibility - analysis results
// Post-process response
const postResult = processor.postProcess(response)
// postResult.success - whether parsing succeeded
// postResult.parsed - decoded data (if TOON)
// postResult.format - 'toon' | 'json' | 'none'
```
## TOON Format Example
**JSON (verbose):**
```json
{
"users": [
{ "id": 1, "name": "Alice", "role": "admin" },
{ "id": 2, "name": "Bob", "role": "user" }
]
}
```
**TOON (compact):**
```
users[2]{id,name,role}:
1,Alice,admin
2,Bob,user
```
## Running Tests
```bash
bun test
```
## Examples
See [`examples/basic.ts`](examples/basic.ts) and [`examples/hooks.ts`](examples/hooks.ts) for usage examples:
```bash
bun run examples/basic.ts
bun run examples/hooks.ts
```
## Configuration
Default thresholds can be customized:
```typescript
const processor = new TOONProcessor({
eligibility: {
minTabularPercent: 60, // Minimum % tabular arrays
maxNestedDepth: 4, // Maximum nesting depth
minUniformityScore: 0.8 // Minimum uniformity score
}
})
// Or with hooks
const result = await autoTOON.process(request, llmCall, {
minTabularPercent: 70,
maxNestedDepth: 3,
logMetrics: true
})
```
## OpenCode Integration Notes
### Important: How Hooks Actually Work
The TOON hooks are **explicit wrappers for YOUR code**, not automatic interceptors for OpenCode's internal messages.
#### What Works ✅
**When YOU make LLM calls in your code:**
```typescript
import { autoTOON } from 'toon-format/hooks'
// This works - you control the LLM call
const result = await autoTOON.process(
{ systemPrompt: '...', data: {...} },
async (processedReq) => {
return await myLLMClient.complete(processedReq) // YOUR client
}
)
```
#### What Does NOT Work ❌
**Automatic interception of OpenCode's internal messages:**
```typescript
// This does NOT happen automatically
// OpenCode's messages still use normal JSON
// The hooks CANNOT:
// - Automatically convert all OpenCode messages to TOON
// - Intercept OpenCode's internal LLM calls
// - Transform messages without explicit usage
```
### Why?
OpenCode's plugin system uses **event-driven hooks**, not middleware:
| Aspect | OpenCode Plugins | Express Middleware |
|--------|------------------|-------------------|
| Pattern | Event handlers | Request/Response pipeline |
| Can transform data? | Limited | Yes |
| Automatic execution? | No | Yes |
| Access to LLM messages? | No | N/A |
OpenCode hooks can:
- ✅ React to events (`session.created`, `tool.execute.before`)
- ✅ Intercept tool calls
- ✅ Modify system prompts
- ❌ Transform LLM request/response bodies automatically
### OpenCode Plugin Hooks Available
If you want to create an OpenCode plugin:
```typescript
// .opencode/plugin/toon-plugin.ts
export const TOONPlugin = async ({ client }) => {
return {
// Intercept tool calls
"tool.execute.before": async (input, output) => {
if (input.tool === "your-custom-tool") {
// Modify arguments before execution
}
},
// React to events
event: async ({ event }) => {
if (event.type === "session.created") {
// Do something when session starts
}
}
}
}
```
**Note:** This won't automatically process OpenCode's LLM messages - it only works for your custom tools and event reactions.
### Research Findings
After researching oh-my-opencode and OpenCode's plugin system:
1. **OpenCode uses event-driven hooks** - not middleware
2. **No pipeline access** - Can't intercept/transform all messages
3. **Skills are markdown** - Not executable code
4. **Plugins are reactive** - Can't transform data flowing through core
**Reference:**
- [OpenCode Plugins Guide](https://gist.github.com/johnlindquist/0adf1032b4e84942f3e1050aba3c5e4a)
- [OpenCode Plugin Docs](https://opencode.ai/docs/plugins/)
- [oh-my-opencode Hooks](https://ohmyopencode.com/hooks/)
### Recommendation
Use TOON hooks **explicitly** in your code when making LLM calls. Don't expect automatic interception of OpenCode's internal messages.
## When to Use TOON
| Data Structure | TOON Benefit |
|----------------|--------------|
| Uniform arrays of objects | ✅ Excellent (40-54% savings) |
| Semi-uniform data | ⚠️ Moderate (20-40% savings) |
| Deeply nested objects | ❌ Not recommended |
| Non-tabular structures | ❌ Not recommended |
## Benchmark Results
| Format | Accuracy | Tokens | Efficiency |
|--------|-----------|--------|------------|
| TOON | 73.9% | 2,744 | 26.9 acc%/1K tok |
| JSON | 69.7% | 4,545 | 15.3 acc%/1K tok |
*Source: TOON benchmarks (toonformat.dev)*
## License
MIT - See LICENSE file
---
Built with ❤️ using the [TOON Format](https://github.com/toon-format/toon)