openclaw-langcache 1.1.0 → 1.2.0
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 +4 -4
- package/package.json +3 -10
- package/scripts/postinstall.js +33 -67
- package/claude-skills/langcache/SKILL.md +0 -173
- package/claude-skills/langcache/examples/agent-integration.py +0 -453
- package/claude-skills/langcache/examples/basic-caching.sh +0 -56
- package/claude-skills/langcache/references/api-reference.md +0 -260
- package/claude-skills/langcache/references/best-practices.md +0 -215
- package/claude-skills/langcache/scripts/langcache.sh +0 -528
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# openclaw-langcache
|
|
2
2
|
|
|
3
|
-
Semantic caching skill for [OpenClaw](https://openclaw.ai)
|
|
3
|
+
Semantic caching skill for [OpenClaw](https://openclaw.ai) using [Redis LangCache](https://redis.io/langcache/).
|
|
4
|
+
|
|
5
|
+
> **For Claude Code users:** See [claude-code-langcache](https://www.npmjs.com/package/claude-code-langcache)
|
|
4
6
|
|
|
5
7
|
Reduce LLM costs and latency by caching responses for semantically similar queries, with built-in privacy and security guardrails.
|
|
6
8
|
|
|
@@ -23,9 +25,7 @@ Reduce LLM costs and latency by caching responses for semantically similar queri
|
|
|
23
25
|
npm install -g openclaw-langcache
|
|
24
26
|
```
|
|
25
27
|
|
|
26
|
-
The skill will be automatically installed to
|
|
27
|
-
- **OpenClaw**: `~/.openclaw/workspace/skills/langcache/`
|
|
28
|
-
- **Claude Code**: `~/.claude/skills/langcache/`
|
|
28
|
+
The skill will be automatically installed to `~/.openclaw/workspace/skills/langcache/`
|
|
29
29
|
|
|
30
30
|
### Via Git
|
|
31
31
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-langcache",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Semantic caching skill for OpenClaw
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Semantic caching skill for OpenClaw using Redis LangCache",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openclaw",
|
|
7
|
-
"claude-code",
|
|
8
7
|
"skill",
|
|
9
8
|
"langcache",
|
|
10
9
|
"redis",
|
|
@@ -23,11 +22,10 @@
|
|
|
23
22
|
},
|
|
24
23
|
"license": "MIT",
|
|
25
24
|
"author": {
|
|
26
|
-
"name": "
|
|
25
|
+
"name": "Manvinder Singh"
|
|
27
26
|
},
|
|
28
27
|
"files": [
|
|
29
28
|
"skills/",
|
|
30
|
-
"claude-skills/",
|
|
31
29
|
"scripts/",
|
|
32
30
|
"README.md",
|
|
33
31
|
"LICENSE"
|
|
@@ -42,10 +40,5 @@
|
|
|
42
40
|
"type": "skill",
|
|
43
41
|
"skills": ["langcache"],
|
|
44
42
|
"installPath": "skills/"
|
|
45
|
-
},
|
|
46
|
-
"claude-code": {
|
|
47
|
-
"type": "skill",
|
|
48
|
-
"skills": ["langcache"],
|
|
49
|
-
"installPath": "claude-skills/"
|
|
50
43
|
}
|
|
51
44
|
}
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Postinstall script for openclaw-langcache
|
|
4
|
-
* Installs the skill to
|
|
4
|
+
* Installs the skill to OpenClaw workspace
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const fs = require('fs');
|
|
@@ -10,26 +10,16 @@ const os = require('os');
|
|
|
10
10
|
|
|
11
11
|
const SKILL_NAME = 'langcache';
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
function getInstallPaths() {
|
|
13
|
+
function getOpenClawPath() {
|
|
15
14
|
const home = os.homedir();
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
'workspace', 'skills'
|
|
21
|
-
),
|
|
22
|
-
claude: path.join(
|
|
23
|
-
process.env.CLAUDE_HOME || path.join(home, '.claude'),
|
|
24
|
-
'skills'
|
|
25
|
-
)
|
|
26
|
-
};
|
|
15
|
+
return path.join(
|
|
16
|
+
process.env.OPENCLAW_HOME || path.join(home, '.openclaw'),
|
|
17
|
+
'workspace', 'skills'
|
|
18
|
+
);
|
|
27
19
|
}
|
|
28
20
|
|
|
29
|
-
// Recursively copy directory
|
|
30
21
|
function copyDir(src, dest) {
|
|
31
22
|
fs.mkdirSync(dest, { recursive: true });
|
|
32
|
-
|
|
33
23
|
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
34
24
|
|
|
35
25
|
for (const entry of entries) {
|
|
@@ -40,8 +30,6 @@ function copyDir(src, dest) {
|
|
|
40
30
|
copyDir(srcPath, destPath);
|
|
41
31
|
} else {
|
|
42
32
|
fs.copyFileSync(srcPath, destPath);
|
|
43
|
-
|
|
44
|
-
// Make shell scripts and python files executable
|
|
45
33
|
if (entry.name.endsWith('.sh') || entry.name.endsWith('.py')) {
|
|
46
34
|
fs.chmodSync(destPath, 0o755);
|
|
47
35
|
}
|
|
@@ -49,67 +37,45 @@ function copyDir(src, dest) {
|
|
|
49
37
|
}
|
|
50
38
|
}
|
|
51
39
|
|
|
52
|
-
function installSkill(name, srcDir, destDir, skillSrcPath) {
|
|
53
|
-
const destPath = path.join(destDir, SKILL_NAME);
|
|
54
|
-
|
|
55
|
-
if (!fs.existsSync(skillSrcPath)) {
|
|
56
|
-
console.log(` ⚠ ${name}: Source not found, skipping`);
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Create skills directory if needed
|
|
61
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
62
|
-
|
|
63
|
-
// Check if already exists
|
|
64
|
-
if (fs.existsSync(destPath)) {
|
|
65
|
-
console.log(` ⚠ ${name}: Already exists at ${destPath}`);
|
|
66
|
-
console.log(` To update: rm -rf ${destPath} && npm install openclaw-langcache`);
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Copy skill
|
|
71
|
-
copyDir(skillSrcPath, destPath);
|
|
72
|
-
console.log(` ✓ ${name}: Installed to ${destPath}`);
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
40
|
function main() {
|
|
77
|
-
console.log('\n📦 Installing langcache skill...\n');
|
|
41
|
+
console.log('\n📦 Installing langcache skill for OpenClaw...\n');
|
|
78
42
|
|
|
79
43
|
try {
|
|
80
|
-
const
|
|
44
|
+
const skillsPath = getOpenClawPath();
|
|
45
|
+
const destPath = path.join(skillsPath, SKILL_NAME);
|
|
81
46
|
const packageRoot = path.dirname(__dirname);
|
|
47
|
+
const srcPath = path.join(packageRoot, 'skills', SKILL_NAME);
|
|
82
48
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const openclawSrc = path.join(packageRoot, 'skills', SKILL_NAME);
|
|
87
|
-
if (installSkill('OpenClaw', 'skills', paths.openclaw, openclawSrc)) {
|
|
88
|
-
installed++;
|
|
49
|
+
if (!fs.existsSync(srcPath)) {
|
|
50
|
+
console.log('Source skill not found, skipping');
|
|
51
|
+
return;
|
|
89
52
|
}
|
|
90
53
|
|
|
91
|
-
|
|
92
|
-
const claudeSrc = path.join(packageRoot, 'claude-skills', SKILL_NAME);
|
|
93
|
-
if (installSkill('Claude Code', 'claude-skills', paths.claude, claudeSrc)) {
|
|
94
|
-
installed++;
|
|
95
|
-
}
|
|
54
|
+
fs.mkdirSync(skillsPath, { recursive: true });
|
|
96
55
|
|
|
97
|
-
if (
|
|
98
|
-
console.log(
|
|
99
|
-
console.log('
|
|
100
|
-
|
|
101
|
-
console.log(' export LANGCACHE_HOST=your-instance.redis.cloud');
|
|
102
|
-
console.log(' export LANGCACHE_CACHE_ID=your-cache-id');
|
|
103
|
-
console.log(' export LANGCACHE_API_KEY=your-api-key');
|
|
104
|
-
console.log('');
|
|
105
|
-
console.log('2. The skill auto-activates when you mention "semantic caching"');
|
|
106
|
-
console.log(' or invoke manually with /langcache');
|
|
107
|
-
console.log('');
|
|
56
|
+
if (fs.existsSync(destPath)) {
|
|
57
|
+
console.log(`⚠ Skill already exists at ${destPath}`);
|
|
58
|
+
console.log(' To update: rm -rf ~/.openclaw/workspace/skills/langcache && npm install -g openclaw-langcache');
|
|
59
|
+
return;
|
|
108
60
|
}
|
|
109
61
|
|
|
62
|
+
copyDir(srcPath, destPath);
|
|
63
|
+
|
|
64
|
+
console.log(`✓ Installed to ${destPath}\n`);
|
|
65
|
+
console.log('Next steps:');
|
|
66
|
+
console.log('1. Set your Redis LangCache credentials:');
|
|
67
|
+
console.log(' export LANGCACHE_HOST=your-instance.redis.cloud');
|
|
68
|
+
console.log(' export LANGCACHE_CACHE_ID=your-cache-id');
|
|
69
|
+
console.log(' export LANGCACHE_API_KEY=your-api-key');
|
|
70
|
+
console.log('');
|
|
71
|
+
console.log('2. The skill auto-activates when you mention "semantic caching"');
|
|
72
|
+
console.log(' or invoke manually with /langcache');
|
|
73
|
+
console.log('');
|
|
74
|
+
console.log('For Claude Code users: npm install -g claude-code-langcache\n');
|
|
75
|
+
|
|
110
76
|
} catch (err) {
|
|
111
77
|
console.warn(`⚠ Warning: ${err.message}`);
|
|
112
|
-
console.warn('
|
|
78
|
+
console.warn('Manually copy from node_modules/openclaw-langcache/skills/');
|
|
113
79
|
}
|
|
114
80
|
}
|
|
115
81
|
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: langcache
|
|
3
|
-
description: This skill should be used when the user asks to "enable semantic caching", "cache LLM responses", "reduce API costs", "speed up AI responses", "configure LangCache", "check the cache", or mentions Redis LangCache, semantic similarity caching, or LLM response caching. Provides integration with Redis LangCache managed service for semantic caching of prompts and responses.
|
|
4
|
-
version: 1.0.0
|
|
5
|
-
tools: Read, Bash, WebFetch
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Redis LangCache Semantic Caching
|
|
9
|
-
|
|
10
|
-
Integrate [Redis LangCache](https://redis.io/langcache/) for semantic caching of LLM prompts and responses. Reduces costs and latency by returning cached results for semantically similar queries.
|
|
11
|
-
|
|
12
|
-
## Prerequisites
|
|
13
|
-
|
|
14
|
-
Set credentials in environment or `~/.claude/settings.local.json`:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
export LANGCACHE_HOST=your-instance.redis.cloud
|
|
18
|
-
export LANGCACHE_CACHE_ID=your-cache-id
|
|
19
|
-
export LANGCACHE_API_KEY=your-api-key
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## Quick Reference
|
|
23
|
-
|
|
24
|
-
| Operation | Command |
|
|
25
|
-
|-----------|---------|
|
|
26
|
-
| Search cache | `./scripts/langcache.sh search "query"` |
|
|
27
|
-
| Store response | `./scripts/langcache.sh store "prompt" "response"` |
|
|
28
|
-
| Check if blocked | `./scripts/langcache.sh check "text"` |
|
|
29
|
-
| Delete entry | `./scripts/langcache.sh delete --id <id>` |
|
|
30
|
-
| Flush cache | `./scripts/langcache.sh flush` |
|
|
31
|
-
|
|
32
|
-
## Default Caching Policy
|
|
33
|
-
|
|
34
|
-
This policy is **enforced automatically** by the CLI and integration code.
|
|
35
|
-
|
|
36
|
-
### CACHEABLE (white-list)
|
|
37
|
-
|
|
38
|
-
| Category | Examples | Threshold |
|
|
39
|
-
|----------|----------|-----------|
|
|
40
|
-
| Factual Q&A | "What is X?", "How does Y work?" | 0.90 |
|
|
41
|
-
| Definitions / docs | API docs, command help | 0.90 |
|
|
42
|
-
| Command explanations | "What does `git rebase` do?" | 0.92 |
|
|
43
|
-
| Reply templates | "polite no", "follow-up", "intro" | 0.88 |
|
|
44
|
-
| Style transforms | "make this warmer/shorter" | 0.85 |
|
|
45
|
-
|
|
46
|
-
### NEVER CACHE (hard blocks)
|
|
47
|
-
|
|
48
|
-
| Category | Patterns | Reason |
|
|
49
|
-
|----------|----------|--------|
|
|
50
|
-
| **Temporal** | today, tomorrow, deadline, ETA, "in 20 min" | Stale immediately |
|
|
51
|
-
| **Credentials** | API keys, passwords, tokens, OTP/2FA | Security |
|
|
52
|
-
| **Identifiers** | emails, phones, account IDs, UUIDs | Privacy/PII |
|
|
53
|
-
| **Personal** | "my wife said", relationships, private chats | Privacy |
|
|
54
|
-
|
|
55
|
-
## Core Operations
|
|
56
|
-
|
|
57
|
-
### Search for Cached Response
|
|
58
|
-
|
|
59
|
-
Before calling an LLM, check for semantically similar cached response:
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
# Basic search
|
|
63
|
-
./scripts/langcache.sh search "What is semantic caching?"
|
|
64
|
-
|
|
65
|
-
# With similarity threshold (0.0-1.0, higher = stricter)
|
|
66
|
-
./scripts/langcache.sh search "What is semantic caching?" --threshold 0.95
|
|
67
|
-
|
|
68
|
-
# With attribute filtering
|
|
69
|
-
./scripts/langcache.sh search "query" --attr "model=gpt-5"
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**Response (hit):**
|
|
73
|
-
```json
|
|
74
|
-
{"hit": true, "response": "...", "similarity": 0.94, "entryId": "abc123"}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**Response (miss):**
|
|
78
|
-
```json
|
|
79
|
-
{"hit": false}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
**Response (blocked):**
|
|
83
|
-
```json
|
|
84
|
-
{"hit": false, "blocked": true, "reason": "temporal_info"}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Store New Response
|
|
88
|
-
|
|
89
|
-
After LLM call, cache for future use:
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
# Basic store
|
|
93
|
-
./scripts/langcache.sh store "What is Redis?" "Redis is an in-memory data store..."
|
|
94
|
-
|
|
95
|
-
# With attributes for organization/filtering
|
|
96
|
-
./scripts/langcache.sh store "prompt" "response" --attr "model=gpt-5" --attr "category=factual"
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Check Policy Compliance
|
|
100
|
-
|
|
101
|
-
Test if content would be blocked:
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
./scripts/langcache.sh check "What's on my calendar today?"
|
|
105
|
-
# Output: BLOCKED: temporal_info
|
|
106
|
-
|
|
107
|
-
./scripts/langcache.sh check "What is Redis?"
|
|
108
|
-
# Output: ALLOWED: Content can be cached
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Delete Entries
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
# By ID
|
|
115
|
-
./scripts/langcache.sh delete --id "abc123"
|
|
116
|
-
|
|
117
|
-
# By attributes (bulk)
|
|
118
|
-
./scripts/langcache.sh delete --attr "model=gpt-4"
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### Flush Cache
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
./scripts/langcache.sh flush # Interactive confirmation
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Integration Pattern
|
|
128
|
-
|
|
129
|
-
Recommended cache-aside pattern for agent workflows:
|
|
130
|
-
|
|
131
|
-
```
|
|
132
|
-
1. Receive user prompt
|
|
133
|
-
2. Check policy: is it cacheable?
|
|
134
|
-
- If blocked → skip cache, call LLM
|
|
135
|
-
3. Search LangCache for similar cached response
|
|
136
|
-
- If hit (similarity ≥ threshold) → return cached
|
|
137
|
-
4. Call LLM API
|
|
138
|
-
5. Store prompt + response in LangCache
|
|
139
|
-
6. Return response
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Search Strategies
|
|
143
|
-
|
|
144
|
-
| Strategy | Description |
|
|
145
|
-
|----------|-------------|
|
|
146
|
-
| `semantic` (default) | Vector similarity matching |
|
|
147
|
-
| `exact` | Case-insensitive exact match |
|
|
148
|
-
| `exact,semantic` | Try exact first, fall back to semantic |
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
./scripts/langcache.sh search "query" --strategy "exact,semantic"
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Attributes for Cache Partitioning
|
|
155
|
-
|
|
156
|
-
Use attributes to organize and filter cache entries:
|
|
157
|
-
|
|
158
|
-
| Attribute | Purpose |
|
|
159
|
-
|-----------|---------|
|
|
160
|
-
| `model` | Separate caches per LLM model |
|
|
161
|
-
| `category` | `factual`, `template`, `style`, `command` |
|
|
162
|
-
| `version` | Invalidate when prompts change |
|
|
163
|
-
| `user_id` | Per-user isolation (if needed) |
|
|
164
|
-
|
|
165
|
-
## References
|
|
166
|
-
|
|
167
|
-
- [API Reference](references/api-reference.md) - Complete REST API documentation
|
|
168
|
-
- [Best Practices](references/best-practices.md) - Optimization techniques
|
|
169
|
-
|
|
170
|
-
## Examples
|
|
171
|
-
|
|
172
|
-
- [examples/basic-caching.sh](examples/basic-caching.sh) - Shell workflow
|
|
173
|
-
- [examples/agent-integration.py](examples/agent-integration.py) - Python pattern with policy enforcement
|