@jsonstudio/llms 0.6.1423 → 0.6.1435
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/dist/conversion/compat/actions/antigravity-thought-signature-cache.d.ts +3 -0
- package/dist/conversion/compat/actions/antigravity-thought-signature-cache.js +60 -0
- package/dist/conversion/compat/actions/gemini-cli-request.js +21 -1
- package/dist/conversion/compat/antigravity-session-signature.d.ts +2 -0
- package/dist/conversion/compat/antigravity-session-signature.js +52 -0
- package/dist/conversion/compat/profiles/chat-gemini.json +3 -1
- package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +6 -0
- package/dist/conversion/hub/pipeline/compat/compat-types.d.ts +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { AdapterContext } from '../../hub/types/chat-envelope.js';
|
|
2
|
+
import type { JsonObject } from '../../hub/types/json.js';
|
|
3
|
+
export declare function cacheAntigravityThoughtSignatureFromGeminiResponse(payload: JsonObject, adapterContext?: AdapterContext): JsonObject;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { cacheAntigravitySessionSignature, getAntigravityRequestSessionId } from '../antigravity-session-signature.js';
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function shouldEnableForAdapter(adapterContext) {
|
|
6
|
+
if (!adapterContext) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
const protocol = typeof adapterContext.providerProtocol === 'string' ? adapterContext.providerProtocol.trim().toLowerCase() : '';
|
|
10
|
+
if (protocol !== 'gemini-chat') {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
const providerIdOrKey = typeof adapterContext.providerId === 'string' ? adapterContext.providerId.trim().toLowerCase() : '';
|
|
14
|
+
const effectiveProviderId = providerIdOrKey.split('.')[0] ?? '';
|
|
15
|
+
return effectiveProviderId === 'antigravity';
|
|
16
|
+
}
|
|
17
|
+
export function cacheAntigravityThoughtSignatureFromGeminiResponse(payload, adapterContext) {
|
|
18
|
+
if (!shouldEnableForAdapter(adapterContext)) {
|
|
19
|
+
return payload;
|
|
20
|
+
}
|
|
21
|
+
const ctxAny = adapterContext;
|
|
22
|
+
const payloadAny = payload;
|
|
23
|
+
const keyCandidates = [
|
|
24
|
+
adapterContext?.requestId,
|
|
25
|
+
typeof ctxAny.clientRequestId === 'string' ? String(ctxAny.clientRequestId) : '',
|
|
26
|
+
typeof ctxAny.groupRequestId === 'string' ? String(ctxAny.groupRequestId) : '',
|
|
27
|
+
typeof payloadAny.request_id === 'string' ? String(payloadAny.request_id) : '',
|
|
28
|
+
typeof payloadAny.requestId === 'string' ? String(payloadAny.requestId) : ''
|
|
29
|
+
].filter((k) => typeof k === 'string' && k.trim().length);
|
|
30
|
+
let sessionId = '';
|
|
31
|
+
for (const key of keyCandidates) {
|
|
32
|
+
const resolved = getAntigravityRequestSessionId(key);
|
|
33
|
+
if (resolved && resolved.trim().length) {
|
|
34
|
+
sessionId = resolved.trim();
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!sessionId) {
|
|
39
|
+
return payload;
|
|
40
|
+
}
|
|
41
|
+
const messageCount = 1;
|
|
42
|
+
const candidatesRaw = payload.candidates;
|
|
43
|
+
const candidates = Array.isArray(candidatesRaw) ? candidatesRaw : [];
|
|
44
|
+
for (const candidate of candidates) {
|
|
45
|
+
const content = isRecord(candidate.content) ? candidate.content : undefined;
|
|
46
|
+
const partsRaw = content?.parts;
|
|
47
|
+
const parts = Array.isArray(partsRaw) ? partsRaw : [];
|
|
48
|
+
for (const part of parts) {
|
|
49
|
+
if (!isRecord(part.functionCall)) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const sig = typeof part.thoughtSignature === 'string' ? String(part.thoughtSignature) : '';
|
|
53
|
+
if (!sig.trim().length) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
cacheAntigravitySessionSignature(sessionId, sig.trim(), messageCount);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return payload;
|
|
60
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extractAntigravityGeminiSessionId, getAntigravitySessionSignature, shouldTreatAsMissingThoughtSignature } from '../antigravity-session-signature.js';
|
|
1
|
+
import { cacheAntigravityRequestSessionId, extractAntigravityGeminiSessionId, getAntigravitySessionSignature, shouldTreatAsMissingThoughtSignature } from '../antigravity-session-signature.js';
|
|
2
2
|
const REQUEST_FIELDS = [
|
|
3
3
|
'contents',
|
|
4
4
|
'systemInstruction',
|
|
@@ -515,9 +515,29 @@ export function wrapGeminiCliRequest(payload, adapterContext) {
|
|
|
515
515
|
normalizeToolDeclarations(requestNode);
|
|
516
516
|
normalizeFunctionCallArgs(requestNode);
|
|
517
517
|
const enableSignature = shouldEnableAntigravitySignature(adapterContext) ||
|
|
518
|
+
(typeof requestNode.userAgent === 'string' && requestNode.userAgent.trim().toLowerCase() === 'antigravity') ||
|
|
519
|
+
(typeof requestNode.requestId === 'string' && requestNode.requestId.trim().toLowerCase().startsWith('agent-')) ||
|
|
518
520
|
(typeof root.userAgent === 'string' && root.userAgent.trim().toLowerCase() === 'antigravity') ||
|
|
519
521
|
(typeof root.requestId === 'string' && root.requestId.trim().toLowerCase().startsWith('agent-'));
|
|
520
522
|
if (enableSignature) {
|
|
523
|
+
// Antigravity-Manager alignment:
|
|
524
|
+
if (adapterContext) {
|
|
525
|
+
try {
|
|
526
|
+
const sessionId = extractAntigravityGeminiSessionId(requestNode);
|
|
527
|
+
const ctxAny = adapterContext;
|
|
528
|
+
const keys = [
|
|
529
|
+
adapterContext.requestId,
|
|
530
|
+
typeof ctxAny.clientRequestId === 'string' ? String(ctxAny.clientRequestId) : '',
|
|
531
|
+
typeof ctxAny.groupRequestId === 'string' ? String(ctxAny.groupRequestId) : ''
|
|
532
|
+
].filter((k) => typeof k === 'string' && k.trim().length);
|
|
533
|
+
for (const key of keys) {
|
|
534
|
+
cacheAntigravityRequestSessionId(key, sessionId);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
catch {
|
|
538
|
+
// best-effort only
|
|
539
|
+
}
|
|
540
|
+
}
|
|
521
541
|
injectAntigravityThoughtSignature(requestNode);
|
|
522
542
|
}
|
|
523
543
|
// Cloud Code Assist request wrapper should not carry metadata/action/web_search/stream.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export declare const DUMMY_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
|
|
2
|
+
export declare function cacheAntigravityRequestSessionId(requestId: string, sessionId: string): void;
|
|
3
|
+
export declare function getAntigravityRequestSessionId(requestId: string): string | undefined;
|
|
2
4
|
/**
|
|
3
5
|
* Antigravity-Manager alignment: derive a stable session fingerprint for Gemini native requests.
|
|
4
6
|
* - sha256(first user text parts joined), if len>10 and no "<system-reminder>"
|
|
@@ -5,6 +5,7 @@ const SIGNATURE_TTL_MS = 2 * 60 * 60 * 1000;
|
|
|
5
5
|
const MIN_SIGNATURE_LENGTH = 50;
|
|
6
6
|
const SESSION_CACHE_LIMIT = 1000;
|
|
7
7
|
const GLOBAL_SIGNATURE_CACHE_KEY = '__LLMSWITCH_ANTIGRAVITY_SESSION_SIGNATURE_CACHE__';
|
|
8
|
+
const GLOBAL_REQUEST_SESSION_CACHE_KEY = '__LLMSWITCH_ANTIGRAVITY_REQUEST_SESSION_ID_CACHE__';
|
|
8
9
|
function getGlobalSignatureCache() {
|
|
9
10
|
const g = globalThis;
|
|
10
11
|
const existing = g[GLOBAL_SIGNATURE_CACHE_KEY];
|
|
@@ -16,6 +17,17 @@ function getGlobalSignatureCache() {
|
|
|
16
17
|
return created;
|
|
17
18
|
}
|
|
18
19
|
const sessionSignatures = getGlobalSignatureCache();
|
|
20
|
+
function getGlobalRequestSessionCache() {
|
|
21
|
+
const g = globalThis;
|
|
22
|
+
const existing = g[GLOBAL_REQUEST_SESSION_CACHE_KEY];
|
|
23
|
+
if (existing instanceof Map) {
|
|
24
|
+
return existing;
|
|
25
|
+
}
|
|
26
|
+
const created = new Map();
|
|
27
|
+
g[GLOBAL_REQUEST_SESSION_CACHE_KEY] = created;
|
|
28
|
+
return created;
|
|
29
|
+
}
|
|
30
|
+
const requestSessionIds = getGlobalRequestSessionCache();
|
|
19
31
|
function nowMs() {
|
|
20
32
|
return Date.now();
|
|
21
33
|
}
|
|
@@ -53,6 +65,9 @@ function sha256Hex(value) {
|
|
|
53
65
|
function isExpired(entry, ts) {
|
|
54
66
|
return ts - entry.timestamp > SIGNATURE_TTL_MS;
|
|
55
67
|
}
|
|
68
|
+
function isRequestSessionExpired(entry, ts) {
|
|
69
|
+
return ts - entry.timestamp > SIGNATURE_TTL_MS;
|
|
70
|
+
}
|
|
56
71
|
function pruneExpired() {
|
|
57
72
|
const ts = nowMs();
|
|
58
73
|
for (const [key, entry] of sessionSignatures.entries()) {
|
|
@@ -79,6 +94,43 @@ function ensureCacheLimit() {
|
|
|
79
94
|
}
|
|
80
95
|
}
|
|
81
96
|
}
|
|
97
|
+
export function cacheAntigravityRequestSessionId(requestId, sessionId) {
|
|
98
|
+
const rid = typeof requestId === 'string' ? requestId.trim() : '';
|
|
99
|
+
const sid = typeof sessionId === 'string' ? sessionId.trim() : '';
|
|
100
|
+
if (!rid || !sid) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const ts = nowMs();
|
|
104
|
+
requestSessionIds.set(rid, { sessionId: sid, timestamp: ts });
|
|
105
|
+
if (requestSessionIds.size <= SESSION_CACHE_LIMIT) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
// Best-effort cleanup to avoid unbounded growth.
|
|
109
|
+
const entries = Array.from(requestSessionIds.entries()).sort((a, b) => a[1].timestamp - b[1].timestamp);
|
|
110
|
+
const overflow = requestSessionIds.size - SESSION_CACHE_LIMIT;
|
|
111
|
+
for (let i = 0; i < overflow; i++) {
|
|
112
|
+
const key = entries[i]?.[0];
|
|
113
|
+
if (key) {
|
|
114
|
+
requestSessionIds.delete(key);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export function getAntigravityRequestSessionId(requestId) {
|
|
119
|
+
const rid = typeof requestId === 'string' ? requestId.trim() : '';
|
|
120
|
+
if (!rid) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
const entry = requestSessionIds.get(rid);
|
|
124
|
+
if (!entry) {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
const ts = nowMs();
|
|
128
|
+
if (isRequestSessionExpired(entry, ts)) {
|
|
129
|
+
requestSessionIds.delete(rid);
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
return entry.sessionId;
|
|
133
|
+
}
|
|
82
134
|
function findGeminiContentsNode(payload) {
|
|
83
135
|
if (!isRecord(payload)) {
|
|
84
136
|
return undefined;
|
|
@@ -18,6 +18,7 @@ import { applyGlmImageContentTransform } from '../../../compat/actions/glm-image
|
|
|
18
18
|
import { applyGlmVisionPromptTransform } from '../../../compat/actions/glm-vision-prompt.js';
|
|
19
19
|
import { applyClaudeThinkingToolSchemaCompat } from '../../../compat/actions/claude-thinking-tools.js';
|
|
20
20
|
import { wrapGeminiCliRequest } from '../../../compat/actions/gemini-cli-request.js';
|
|
21
|
+
import { cacheAntigravityThoughtSignatureFromGeminiResponse } from '../../../compat/actions/antigravity-thought-signature-cache.js';
|
|
21
22
|
const RATE_LIMIT_ERROR = 'ERR_COMPAT_RATE_LIMIT_DETECTED';
|
|
22
23
|
const INTERNAL_STATE = Symbol('compat.internal_state');
|
|
23
24
|
export function runRequestCompatPipeline(profileId, payload, options) {
|
|
@@ -206,6 +207,11 @@ function applyMapping(root, mapping, state) {
|
|
|
206
207
|
replaceRoot(root, wrapGeminiCliRequest(root, state.adapterContext));
|
|
207
208
|
}
|
|
208
209
|
break;
|
|
210
|
+
case 'antigravity_thought_signature_cache':
|
|
211
|
+
if (state.direction === 'response') {
|
|
212
|
+
replaceRoot(root, cacheAntigravityThoughtSignatureFromGeminiResponse(root, state.adapterContext));
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
209
215
|
case 'glm_image_content':
|
|
210
216
|
if (state.direction === 'request') {
|
|
211
217
|
replaceRoot(root, applyGlmImageContentTransform(root));
|
|
@@ -118,6 +118,8 @@ export type MappingInstruction = {
|
|
|
118
118
|
action: 'claude_thinking_tool_schema';
|
|
119
119
|
} | {
|
|
120
120
|
action: 'gemini_cli_request_wrap';
|
|
121
|
+
} | {
|
|
122
|
+
action: 'antigravity_thought_signature_cache';
|
|
121
123
|
};
|
|
122
124
|
export type FilterInstruction = {
|
|
123
125
|
action: 'rate_limit_text';
|