@enderfga/openclaw-claude-code 2.0.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/LICENSE +21 -0
- package/README.md +179 -0
- package/dist/bin/cli.d.ts +10 -0
- package/dist/bin/cli.js +301 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/src/embedded-server.d.ts +19 -0
- package/dist/src/embedded-server.js +190 -0
- package/dist/src/embedded-server.js.map +1 -0
- package/dist/src/hooks/prompt-bypass.d.ts +20 -0
- package/dist/src/hooks/prompt-bypass.js +37 -0
- package/dist/src/hooks/prompt-bypass.js.map +1 -0
- package/dist/src/index.d.ts +47 -0
- package/dist/src/index.js +230 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/persistent-session.d.ts +100 -0
- package/dist/src/persistent-session.js +563 -0
- package/dist/src/persistent-session.js.map +1 -0
- package/dist/src/proxy/anthropic-adapter.d.ts +136 -0
- package/dist/src/proxy/anthropic-adapter.js +394 -0
- package/dist/src/proxy/anthropic-adapter.js.map +1 -0
- package/dist/src/proxy/handler.d.ts +39 -0
- package/dist/src/proxy/handler.js +261 -0
- package/dist/src/proxy/handler.js.map +1 -0
- package/dist/src/proxy/schema-cleaner.d.ts +11 -0
- package/dist/src/proxy/schema-cleaner.js +34 -0
- package/dist/src/proxy/schema-cleaner.js.map +1 -0
- package/dist/src/proxy/thought-cache.d.ts +19 -0
- package/dist/src/proxy/thought-cache.js +53 -0
- package/dist/src/proxy/thought-cache.js.map +1 -0
- package/dist/src/session-manager.d.ts +79 -0
- package/dist/src/session-manager.js +329 -0
- package/dist/src/session-manager.js.map +1 -0
- package/dist/src/types.d.ts +160 -0
- package/dist/src/types.js +20 -0
- package/dist/src/types.js.map +1 -0
- package/openclaw.plugin.json +76 -0
- package/package.json +46 -0
- package/skills/SKILL.md +594 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxy HTTP Handler — registerHttpRoute handler for OpenClaw Plugin SDK
|
|
3
|
+
*
|
|
4
|
+
* Receives Anthropic-format requests from Claude Code CLI,
|
|
5
|
+
* translates to OpenAI format, forwards to the target provider,
|
|
6
|
+
* and translates the response back to Anthropic format.
|
|
7
|
+
*
|
|
8
|
+
* Supports:
|
|
9
|
+
* - Direct Anthropic API passthrough (zero conversion)
|
|
10
|
+
* - OpenAI/GPT models via format conversion
|
|
11
|
+
* - Gemini models via format conversion + schema cleaning
|
|
12
|
+
* - Gateway passthrough (OpenClaw gateway handles routing)
|
|
13
|
+
* - Streaming and non-streaming modes
|
|
14
|
+
*/
|
|
15
|
+
import { convertAnthropicToOpenAI, convertOpenAIToAnthropic, convertStreamOpenAIToAnthropic, } from './anthropic-adapter.js';
|
|
16
|
+
import { injectThoughtSigs } from './thought-cache.js';
|
|
17
|
+
// ─── Model Routing ───────────────────────────────────────────────────────────
|
|
18
|
+
function resolveProviderModel(model) {
|
|
19
|
+
const lower = model.toLowerCase();
|
|
20
|
+
// Strip prefixes
|
|
21
|
+
let clean = model;
|
|
22
|
+
for (const prefix of ['anthropic/', 'openai/', 'gemini/', 'google/']) {
|
|
23
|
+
if (clean.startsWith(prefix)) {
|
|
24
|
+
clean = clean.slice(prefix.length);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (lower.includes('claude') || lower.includes('opus') || lower.includes('sonnet') || lower.includes('haiku')) {
|
|
29
|
+
return { provider: 'anthropic', apiModel: clean };
|
|
30
|
+
}
|
|
31
|
+
if (lower.includes('gemini')) {
|
|
32
|
+
return { provider: 'gemini', apiModel: clean };
|
|
33
|
+
}
|
|
34
|
+
if (lower.includes('gpt') || lower.includes('o1') || lower.includes('o3')) {
|
|
35
|
+
return { provider: 'openai', apiModel: clean };
|
|
36
|
+
}
|
|
37
|
+
// Default: treat as OpenAI-compatible
|
|
38
|
+
return { provider: 'openai', apiModel: clean };
|
|
39
|
+
}
|
|
40
|
+
// ─── Extract Real Model from URL ─────────────────────────────────────────────
|
|
41
|
+
/**
|
|
42
|
+
* Claude Code CLI passes the real model via URL path:
|
|
43
|
+
* /v1/claude-code-proxy/real/<model>/messages
|
|
44
|
+
*
|
|
45
|
+
* Extract the model name from the URL.
|
|
46
|
+
*/
|
|
47
|
+
function extractRealModel(url) {
|
|
48
|
+
const match = url.match(/\/real\/(.+?)\/messages/);
|
|
49
|
+
return match ? decodeURIComponent(match[1]) : null;
|
|
50
|
+
}
|
|
51
|
+
// ─── Handler ─────────────────────────────────────────────────────────────────
|
|
52
|
+
export function createProxyHandler(config, env) {
|
|
53
|
+
/**
|
|
54
|
+
* Main proxy handler — receives Anthropic-format request, returns Anthropic-format response.
|
|
55
|
+
*/
|
|
56
|
+
return async function handleProxy(req, res) {
|
|
57
|
+
try {
|
|
58
|
+
const body = await req.json();
|
|
59
|
+
// Determine real model from URL path or request body
|
|
60
|
+
const urlModel = extractRealModel(req.url);
|
|
61
|
+
const requestModel = urlModel || body.model;
|
|
62
|
+
body.model = requestModel;
|
|
63
|
+
const { provider, apiModel } = resolveProviderModel(requestModel);
|
|
64
|
+
const isStream = body.stream ?? false;
|
|
65
|
+
// ─── Direct Anthropic passthrough ─────────────────────────────
|
|
66
|
+
if (provider === 'anthropic') {
|
|
67
|
+
return await forwardToAnthropic(body, env, res, isStream);
|
|
68
|
+
}
|
|
69
|
+
// ─── Gateway passthrough ──────────────────────────────────────
|
|
70
|
+
if (env.gatewayUrl && env.gatewayKey) {
|
|
71
|
+
return await forwardToGateway(body, apiModel, env, res, isStream, requestModel);
|
|
72
|
+
}
|
|
73
|
+
// ─── Direct provider via format conversion ────────────────────
|
|
74
|
+
const openaiReq = convertAnthropicToOpenAI(body);
|
|
75
|
+
openaiReq.model = apiModel;
|
|
76
|
+
// Inject thought signatures for Gemini round-trip
|
|
77
|
+
if (provider === 'gemini') {
|
|
78
|
+
injectThoughtSigs(openaiReq.messages);
|
|
79
|
+
}
|
|
80
|
+
// Determine API endpoint and key
|
|
81
|
+
let apiUrl;
|
|
82
|
+
let apiKey;
|
|
83
|
+
if (provider === 'gemini') {
|
|
84
|
+
apiUrl = 'https://generativelanguage.googleapis.com/v1beta/chat/completions';
|
|
85
|
+
apiKey = env.geminiApiKey || '';
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
apiUrl = 'https://api.openai.com/v1/chat/completions';
|
|
89
|
+
apiKey = env.openaiApiKey || '';
|
|
90
|
+
}
|
|
91
|
+
if (!apiKey) {
|
|
92
|
+
res.status(401).json({ error: `No API key configured for provider: ${provider}` });
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
if (isStream) {
|
|
96
|
+
return await handleStreamingResponse(apiUrl, apiKey, openaiReq, res, requestModel);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
return await handleNonStreamingResponse(apiUrl, apiKey, openaiReq, res, requestModel);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
console.error('[proxy] Error:', err.message);
|
|
104
|
+
res.status(500).json({
|
|
105
|
+
type: 'error',
|
|
106
|
+
error: { type: 'server_error', message: err.message },
|
|
107
|
+
});
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// ─── Anthropic Passthrough ───────────────────────────────────────────────────
|
|
113
|
+
async function forwardToAnthropic(body, env, res, isStream) {
|
|
114
|
+
const apiKey = env.anthropicApiKey;
|
|
115
|
+
if (!apiKey) {
|
|
116
|
+
res.status(401).json({ error: 'No ANTHROPIC_API_KEY configured' });
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
const resp = await fetch('https://api.anthropic.com/v1/messages', {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
headers: {
|
|
122
|
+
'Content-Type': 'application/json',
|
|
123
|
+
'x-api-key': apiKey,
|
|
124
|
+
'anthropic-version': '2023-06-01',
|
|
125
|
+
},
|
|
126
|
+
body: JSON.stringify(body),
|
|
127
|
+
});
|
|
128
|
+
if (isStream) {
|
|
129
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
130
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
131
|
+
res.flushHeaders?.();
|
|
132
|
+
const reader = resp.body?.getReader();
|
|
133
|
+
if (reader) {
|
|
134
|
+
const decoder = new TextDecoder();
|
|
135
|
+
while (true) {
|
|
136
|
+
const { done, value } = await reader.read();
|
|
137
|
+
if (done)
|
|
138
|
+
break;
|
|
139
|
+
res.write(decoder.decode(value, { stream: true }));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
res.end();
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
const data = await resp.json();
|
|
146
|
+
res.status(resp.status).json(data);
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
// ─── Gateway Passthrough ─────────────────────────────────────────────────────
|
|
151
|
+
async function forwardToGateway(body, apiModel, env, res, isStream, originalModel) {
|
|
152
|
+
const openaiReq = convertAnthropicToOpenAI(body);
|
|
153
|
+
openaiReq.model = apiModel;
|
|
154
|
+
// Inject thought signatures for Gemini
|
|
155
|
+
injectThoughtSigs(openaiReq.messages);
|
|
156
|
+
const resp = await fetch(`${env.gatewayUrl}/chat/completions`, {
|
|
157
|
+
method: 'POST',
|
|
158
|
+
headers: {
|
|
159
|
+
'Content-Type': 'application/json',
|
|
160
|
+
'Authorization': `Bearer ${env.gatewayKey}`,
|
|
161
|
+
'x-openclaw-agent-id': 'claude-code-raw',
|
|
162
|
+
},
|
|
163
|
+
body: JSON.stringify(openaiReq),
|
|
164
|
+
});
|
|
165
|
+
if (!resp.ok) {
|
|
166
|
+
const err = await resp.text();
|
|
167
|
+
res.status(resp.status).json({ type: 'error', error: { type: 'gateway_error', message: err } });
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
if (isStream) {
|
|
171
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
172
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
173
|
+
res.flushHeaders?.();
|
|
174
|
+
const reader = resp.body?.getReader();
|
|
175
|
+
if (!reader) {
|
|
176
|
+
res.end();
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
const lineStream = readSSELines(reader);
|
|
180
|
+
for await (const sseChunk of convertStreamOpenAIToAnthropic(lineStream, originalModel)) {
|
|
181
|
+
res.write(sseChunk);
|
|
182
|
+
}
|
|
183
|
+
res.end();
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
const data = await resp.json();
|
|
187
|
+
const anthropicResp = convertOpenAIToAnthropic(data, originalModel);
|
|
188
|
+
res.status(200).json(anthropicResp);
|
|
189
|
+
}
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
// ─── Direct Provider ─────────────────────────────────────────────────────────
|
|
193
|
+
async function handleNonStreamingResponse(apiUrl, apiKey, openaiReq, res, originalModel) {
|
|
194
|
+
const resp = await fetch(apiUrl, {
|
|
195
|
+
method: 'POST',
|
|
196
|
+
headers: {
|
|
197
|
+
'Content-Type': 'application/json',
|
|
198
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
199
|
+
},
|
|
200
|
+
body: JSON.stringify(Object.assign({}, openaiReq, { stream: false })),
|
|
201
|
+
});
|
|
202
|
+
if (!resp.ok) {
|
|
203
|
+
const err = await resp.text();
|
|
204
|
+
res.status(resp.status).json({ type: 'error', error: { type: 'api_error', message: err } });
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
const data = await resp.json();
|
|
208
|
+
const anthropicResp = convertOpenAIToAnthropic(data, originalModel);
|
|
209
|
+
res.status(200).json(anthropicResp);
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
async function handleStreamingResponse(apiUrl, apiKey, openaiReq, res, originalModel) {
|
|
213
|
+
const resp = await fetch(apiUrl, {
|
|
214
|
+
method: 'POST',
|
|
215
|
+
headers: {
|
|
216
|
+
'Content-Type': 'application/json',
|
|
217
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
218
|
+
},
|
|
219
|
+
body: JSON.stringify(Object.assign({}, openaiReq, { stream: true })),
|
|
220
|
+
});
|
|
221
|
+
if (!resp.ok) {
|
|
222
|
+
const err = await resp.text();
|
|
223
|
+
res.status(resp.status).json({ type: 'error', error: { type: 'api_error', message: err } });
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
227
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
228
|
+
res.flushHeaders?.();
|
|
229
|
+
const reader = resp.body?.getReader();
|
|
230
|
+
if (!reader) {
|
|
231
|
+
res.end();
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
const lineStream = readSSELines(reader);
|
|
235
|
+
for await (const sseChunk of convertStreamOpenAIToAnthropic(lineStream, originalModel)) {
|
|
236
|
+
res.write(sseChunk);
|
|
237
|
+
}
|
|
238
|
+
res.end();
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
// ─── SSE Line Reader ─────────────────────────────────────────────────────────
|
|
242
|
+
async function* readSSELines(reader) {
|
|
243
|
+
const decoder = new TextDecoder();
|
|
244
|
+
let buffer = '';
|
|
245
|
+
while (true) {
|
|
246
|
+
const { done, value } = await reader.read();
|
|
247
|
+
if (done)
|
|
248
|
+
break;
|
|
249
|
+
buffer += decoder.decode(value, { stream: true });
|
|
250
|
+
const lines = buffer.split('\n');
|
|
251
|
+
buffer = lines.pop() || '';
|
|
252
|
+
for (const line of lines) {
|
|
253
|
+
const trimmed = line.trim();
|
|
254
|
+
if (trimmed)
|
|
255
|
+
yield trimmed;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (buffer.trim())
|
|
259
|
+
yield buffer.trim();
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/proxy/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini Tool Schema Cleaner
|
|
3
|
+
*
|
|
4
|
+
* Gemini doesn't support certain JSON Schema fields that Anthropic tools use.
|
|
5
|
+
* This recursively cleans schemas for compatibility.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Recursively clean a JSON Schema for Gemini compatibility.
|
|
9
|
+
* Removes unsupported fields and string formats.
|
|
10
|
+
*/
|
|
11
|
+
export declare function cleanGeminiSchema(schema: unknown): unknown;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini Tool Schema Cleaner
|
|
3
|
+
*
|
|
4
|
+
* Gemini doesn't support certain JSON Schema fields that Anthropic tools use.
|
|
5
|
+
* This recursively cleans schemas for compatibility.
|
|
6
|
+
*/
|
|
7
|
+
const UNSUPPORTED_KEYS = new Set(['additionalProperties', 'default', '$schema']);
|
|
8
|
+
const ALLOWED_STRING_FORMATS = new Set(['enum', 'date-time']);
|
|
9
|
+
/**
|
|
10
|
+
* Recursively clean a JSON Schema for Gemini compatibility.
|
|
11
|
+
* Removes unsupported fields and string formats.
|
|
12
|
+
*/
|
|
13
|
+
export function cleanGeminiSchema(schema) {
|
|
14
|
+
if (schema === null || schema === undefined || typeof schema !== 'object')
|
|
15
|
+
return schema;
|
|
16
|
+
if (Array.isArray(schema))
|
|
17
|
+
return schema.map(cleanGeminiSchema);
|
|
18
|
+
const obj = schema;
|
|
19
|
+
const cleaned = {};
|
|
20
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
21
|
+
// Skip unsupported keys
|
|
22
|
+
if (UNSUPPORTED_KEYS.has(key))
|
|
23
|
+
continue;
|
|
24
|
+
// Clean string format restrictions
|
|
25
|
+
if (key === 'format' && obj.type === 'string') {
|
|
26
|
+
if (typeof value === 'string' && !ALLOWED_STRING_FORMATS.has(value))
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
// Recurse into nested objects/arrays
|
|
30
|
+
cleaned[key] = cleanGeminiSchema(value);
|
|
31
|
+
}
|
|
32
|
+
return cleaned;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=schema-cleaner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-cleaner.js","sourceRoot":"","sources":["../../../src/proxy/schema-cleaner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AACjF,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAe;IAC/C,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IACzF,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEhE,MAAM,GAAG,GAAG,MAAiC,CAAC;IAC9C,MAAM,OAAO,GAA4B,EAAE,CAAC;IAE5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,wBAAwB;QACxB,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAExC,mCAAmC;QACnC,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;QAChF,CAAC;QAED,qCAAqC;QACrC,OAAO,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thought Signature Cache — Gemini round-trip support
|
|
3
|
+
*
|
|
4
|
+
* Gemini 2.5+ with thinking requires `thought_signature` in tool_calls
|
|
5
|
+
* for 2nd+ turns. We cache signatures from responses and inject on next request.
|
|
6
|
+
*
|
|
7
|
+
* Uses in-memory LRU cache (no file I/O needed in plugin context).
|
|
8
|
+
*/
|
|
9
|
+
/** Cache a thought signature from a tool call response */
|
|
10
|
+
export declare function cacheThoughtSig(toolCallId: string, signature: string): void;
|
|
11
|
+
/** Get a cached thought signature for a tool call */
|
|
12
|
+
export declare function getThoughtSig(toolCallId: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Inject cached thought signatures into messages for Gemini round-trip.
|
|
15
|
+
* Mutates the messages array in place.
|
|
16
|
+
*/
|
|
17
|
+
export declare function injectThoughtSigs(messages: Array<Record<string, unknown>>): void;
|
|
18
|
+
/** Clear the cache (for testing) */
|
|
19
|
+
export declare function clearCache(): void;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thought Signature Cache — Gemini round-trip support
|
|
3
|
+
*
|
|
4
|
+
* Gemini 2.5+ with thinking requires `thought_signature` in tool_calls
|
|
5
|
+
* for 2nd+ turns. We cache signatures from responses and inject on next request.
|
|
6
|
+
*
|
|
7
|
+
* Uses in-memory LRU cache (no file I/O needed in plugin context).
|
|
8
|
+
*/
|
|
9
|
+
const MAX_CACHE_SIZE = 100;
|
|
10
|
+
const cache = new Map();
|
|
11
|
+
/** Cache a thought signature from a tool call response */
|
|
12
|
+
export function cacheThoughtSig(toolCallId, signature) {
|
|
13
|
+
if (!toolCallId || !signature)
|
|
14
|
+
return;
|
|
15
|
+
// Evict oldest if over limit
|
|
16
|
+
if (cache.size >= MAX_CACHE_SIZE) {
|
|
17
|
+
const oldest = cache.keys().next().value;
|
|
18
|
+
if (oldest !== undefined)
|
|
19
|
+
cache.delete(oldest);
|
|
20
|
+
}
|
|
21
|
+
cache.set(toolCallId, signature);
|
|
22
|
+
}
|
|
23
|
+
/** Get a cached thought signature for a tool call */
|
|
24
|
+
export function getThoughtSig(toolCallId) {
|
|
25
|
+
return cache.get(toolCallId) || '';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Inject cached thought signatures into messages for Gemini round-trip.
|
|
29
|
+
* Mutates the messages array in place.
|
|
30
|
+
*/
|
|
31
|
+
export function injectThoughtSigs(messages) {
|
|
32
|
+
for (const msg of messages) {
|
|
33
|
+
if (msg.role !== 'assistant')
|
|
34
|
+
continue;
|
|
35
|
+
const toolCalls = msg.tool_calls;
|
|
36
|
+
if (!toolCalls)
|
|
37
|
+
continue;
|
|
38
|
+
for (const tc of toolCalls) {
|
|
39
|
+
const id = tc.id;
|
|
40
|
+
if (!id)
|
|
41
|
+
continue;
|
|
42
|
+
const sig = getThoughtSig(id);
|
|
43
|
+
if (sig) {
|
|
44
|
+
tc.extra_content = { google: { thought_signature: sig } };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Clear the cache (for testing) */
|
|
50
|
+
export function clearCache() {
|
|
51
|
+
cache.clear();
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=thought-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thought-cache.js","sourceRoot":"","sources":["../../../src/proxy/thought-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;AAExC,0DAA0D;AAC1D,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE,SAAiB;IACnE,IAAI,CAAC,UAAU,IAAI,CAAC,SAAS;QAAE,OAAO;IAEtC,6BAA6B;IAC7B,IAAI,KAAK,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;QACzC,IAAI,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AACnC,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAwC;IACxE,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QACvC,MAAM,SAAS,GAAG,GAAG,CAAC,UAAwD,CAAC;QAC/E,IAAI,CAAC,SAAS;YAAE,SAAS;QAEzB,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,EAAE,CAAC,EAAY,CAAC;YAC3B,IAAI,CAAC,EAAE;gBAAE,SAAS;YAClB,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;YAC9B,IAAI,GAAG,EAAE,CAAC;gBACR,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,EAAE,CAAC;YAC5D,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,UAAU;IACxB,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionManager — manages multiple PersistentClaudeSession instances
|
|
3
|
+
*
|
|
4
|
+
* Replaces the Express server layer. Pure class with no HTTP dependency.
|
|
5
|
+
* Can be used by Plugin tools, CLI, or any other consumer.
|
|
6
|
+
*/
|
|
7
|
+
import { PersistentClaudeSession } from './persistent-session.js';
|
|
8
|
+
import { type SessionConfig, type SessionInfo, type SendResult, type PluginConfig, type EffortLevel, type AgentInfo, type SkillInfo, type RuleInfo, type StreamEvent } from './types.js';
|
|
9
|
+
interface SendOptions {
|
|
10
|
+
effort?: EffortLevel;
|
|
11
|
+
plan?: boolean;
|
|
12
|
+
autoResume?: boolean;
|
|
13
|
+
timeout?: number;
|
|
14
|
+
onEvent?: (event: StreamEvent) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare class SessionManager {
|
|
17
|
+
private sessions;
|
|
18
|
+
private cleanupTimer;
|
|
19
|
+
private pluginConfig;
|
|
20
|
+
constructor(config?: Partial<PluginConfig>);
|
|
21
|
+
startSession(config: Partial<SessionConfig> & {
|
|
22
|
+
name?: string;
|
|
23
|
+
}): Promise<SessionInfo>;
|
|
24
|
+
sendMessage(name: string, message: string, options?: SendOptions): Promise<SendResult>;
|
|
25
|
+
stopSession(name: string): Promise<void>;
|
|
26
|
+
listSessions(): SessionInfo[];
|
|
27
|
+
getStatus(name: string): SessionInfo & {
|
|
28
|
+
stats: ReturnType<PersistentClaudeSession['getStats']>;
|
|
29
|
+
};
|
|
30
|
+
grepSession(name: string, pattern: string, limit?: number): Promise<Array<{
|
|
31
|
+
time: string;
|
|
32
|
+
type: string;
|
|
33
|
+
content: string;
|
|
34
|
+
}>>;
|
|
35
|
+
compactSession(name: string, summary?: string): Promise<void>;
|
|
36
|
+
setEffort(name: string, level: EffortLevel): void;
|
|
37
|
+
setModel(name: string, model: string): void;
|
|
38
|
+
getCost(name: string): {
|
|
39
|
+
model: string;
|
|
40
|
+
tokensIn: number;
|
|
41
|
+
tokensOut: number;
|
|
42
|
+
cachedTokens: number;
|
|
43
|
+
pricing: {
|
|
44
|
+
inputPer1M: number;
|
|
45
|
+
outputPer1M: number;
|
|
46
|
+
cachedPer1M: number | undefined;
|
|
47
|
+
};
|
|
48
|
+
breakdown: {
|
|
49
|
+
inputCost: number;
|
|
50
|
+
cachedCost: number;
|
|
51
|
+
outputCost: number;
|
|
52
|
+
};
|
|
53
|
+
totalUsd: number;
|
|
54
|
+
};
|
|
55
|
+
listAgents(cwd?: string): AgentInfo[];
|
|
56
|
+
createAgent(name: string, cwd?: string, description?: string, prompt?: string): string;
|
|
57
|
+
listSkills(cwd?: string): SkillInfo[];
|
|
58
|
+
createSkill(name: string, cwd?: string, opts?: {
|
|
59
|
+
description?: string;
|
|
60
|
+
prompt?: string;
|
|
61
|
+
trigger?: string;
|
|
62
|
+
}): string;
|
|
63
|
+
listRules(cwd?: string): RuleInfo[];
|
|
64
|
+
createRule(name: string, cwd?: string, opts?: {
|
|
65
|
+
description?: string;
|
|
66
|
+
content?: string;
|
|
67
|
+
paths?: string;
|
|
68
|
+
condition?: string;
|
|
69
|
+
}): string;
|
|
70
|
+
teamList(name: string): Promise<string>;
|
|
71
|
+
teamSend(name: string, teammate: string, message: string): Promise<SendResult>;
|
|
72
|
+
shutdown(): Promise<void>;
|
|
73
|
+
private _getSession;
|
|
74
|
+
private _toSessionInfo;
|
|
75
|
+
private _resolveModel;
|
|
76
|
+
private _listMdFiles;
|
|
77
|
+
private _cleanupIdleSessions;
|
|
78
|
+
}
|
|
79
|
+
export {};
|