@jsonstudio/llms 0.6.1449 → 0.6.1462
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/anthropic-claude-code-system-prompt.d.ts +3 -2
- package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.js +65 -46
- package/dist/conversion/compat/actions/antigravity-thought-signature-cache.js +6 -5
- package/dist/conversion/compat/actions/antigravity-thought-signature-prepare.js +35 -8
- package/dist/conversion/compat/antigravity-session-signature.d.ts +13 -0
- package/dist/conversion/compat/antigravity-session-signature.js +23 -4
- package/dist/conversion/compat/profiles/anthropic-claude-code.json +26 -0
- package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +16 -0
- package/package.json +1 -1
|
@@ -4,7 +4,8 @@ import type { AnthropicClaudeCodeSystemPromptConfig } from '../../hub/pipeline/c
|
|
|
4
4
|
* tabglm (Anthropic-compatible) strict-gates requests to Claude Code official client.
|
|
5
5
|
* It checks the system prompt format, and rejects mismatches with HTTP 403.
|
|
6
6
|
*
|
|
7
|
-
* This compat action
|
|
8
|
-
*
|
|
7
|
+
* This compat action normalizes the Anthropic `system` prompt into Claude Code official format.
|
|
8
|
+
* It ensures the *first* `system` block is Claude Code's official string, while keeping any
|
|
9
|
+
* existing system blocks (unless explicitly disabled).
|
|
9
10
|
*/
|
|
10
11
|
export declare function applyAnthropicClaudeCodeSystemPromptCompat(payload: JsonObject, config?: AnthropicClaudeCodeSystemPromptConfig): JsonObject;
|
|
@@ -2,59 +2,74 @@ const DEFAULT_SYSTEM_TEXT = "You are Claude Code, Anthropic's official CLI for C
|
|
|
2
2
|
function isRecord(value) {
|
|
3
3
|
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
4
4
|
}
|
|
5
|
-
function
|
|
5
|
+
function normalizeSystemBlocks(system) {
|
|
6
|
+
const blocks = [];
|
|
7
|
+
const pushText = (text, extra) => {
|
|
8
|
+
const trimmed = text.trim();
|
|
9
|
+
if (!trimmed) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
blocks.push({
|
|
13
|
+
...(extra ?? {}),
|
|
14
|
+
type: 'text',
|
|
15
|
+
text: trimmed
|
|
16
|
+
});
|
|
17
|
+
};
|
|
6
18
|
if (typeof system === 'string') {
|
|
7
|
-
|
|
19
|
+
pushText(system);
|
|
20
|
+
return blocks;
|
|
8
21
|
}
|
|
9
22
|
if (Array.isArray(system)) {
|
|
10
|
-
const parts = [];
|
|
11
23
|
for (const entry of system) {
|
|
12
24
|
if (typeof entry === 'string') {
|
|
13
|
-
|
|
14
|
-
parts.push(entry.trim());
|
|
25
|
+
pushText(entry);
|
|
15
26
|
continue;
|
|
16
27
|
}
|
|
17
|
-
if (!isRecord(entry))
|
|
28
|
+
if (!isRecord(entry)) {
|
|
18
29
|
continue;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
}
|
|
31
|
+
const text = typeof entry.text === 'string' ? entry.text : '';
|
|
32
|
+
if (text) {
|
|
33
|
+
const extra = { ...entry };
|
|
34
|
+
delete extra.type;
|
|
35
|
+
delete extra.text;
|
|
36
|
+
pushText(text, extra);
|
|
37
|
+
}
|
|
22
38
|
}
|
|
23
|
-
return
|
|
39
|
+
return blocks;
|
|
24
40
|
}
|
|
25
41
|
if (isRecord(system)) {
|
|
26
|
-
const text = typeof system.text === 'string' ? system.text
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (isRecord(first) && typeof first.role === 'string' && first.role.toLowerCase() === 'user') {
|
|
34
|
-
return first;
|
|
42
|
+
const text = typeof system.text === 'string' ? system.text : '';
|
|
43
|
+
if (text) {
|
|
44
|
+
const extra = { ...system };
|
|
45
|
+
delete extra.type;
|
|
46
|
+
delete extra.text;
|
|
47
|
+
pushText(text, extra);
|
|
48
|
+
}
|
|
35
49
|
}
|
|
36
|
-
|
|
37
|
-
messages.unshift(created);
|
|
38
|
-
return created;
|
|
50
|
+
return blocks;
|
|
39
51
|
}
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
function dedupeSystemBlocksByText(blocks) {
|
|
53
|
+
const seen = new Set();
|
|
54
|
+
const result = [];
|
|
55
|
+
for (const block of blocks) {
|
|
56
|
+
const text = typeof block.text === 'string' ? block.text.trim() : '';
|
|
57
|
+
if (!text)
|
|
58
|
+
continue;
|
|
59
|
+
if (seen.has(text))
|
|
60
|
+
continue;
|
|
61
|
+
seen.add(text);
|
|
62
|
+
result.push({ ...block, type: 'text', text });
|
|
48
63
|
}
|
|
49
|
-
|
|
50
|
-
message.content = text;
|
|
64
|
+
return result;
|
|
51
65
|
}
|
|
52
66
|
/**
|
|
53
67
|
* tabglm (Anthropic-compatible) strict-gates requests to Claude Code official client.
|
|
54
68
|
* It checks the system prompt format, and rejects mismatches with HTTP 403.
|
|
55
69
|
*
|
|
56
|
-
* This compat action
|
|
57
|
-
*
|
|
70
|
+
* This compat action normalizes the Anthropic `system` prompt into Claude Code official format.
|
|
71
|
+
* It ensures the *first* `system` block is Claude Code's official string, while keeping any
|
|
72
|
+
* existing system blocks (unless explicitly disabled).
|
|
58
73
|
*/
|
|
59
74
|
export function applyAnthropicClaudeCodeSystemPromptCompat(payload, config) {
|
|
60
75
|
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
|
@@ -64,19 +79,23 @@ export function applyAnthropicClaudeCodeSystemPromptCompat(payload, config) {
|
|
|
64
79
|
const systemText = (typeof config?.systemText === 'string' && config.systemText.trim())
|
|
65
80
|
? config.systemText.trim()
|
|
66
81
|
: DEFAULT_SYSTEM_TEXT;
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
82
|
+
const preserveExisting = config?.preserveExistingSystemAsUserMessage !== false;
|
|
83
|
+
const existingBlocks = dedupeSystemBlocksByText(normalizeSystemBlocks(root.system));
|
|
84
|
+
const official = { type: 'text', text: systemText };
|
|
85
|
+
let nextBlocks = [];
|
|
86
|
+
if (!preserveExisting) {
|
|
87
|
+
nextBlocks = [official];
|
|
71
88
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
else if (existingBlocks.length === 0) {
|
|
90
|
+
nextBlocks = [official];
|
|
91
|
+
}
|
|
92
|
+
else if (existingBlocks[0].text !== systemText) {
|
|
93
|
+
nextBlocks = [official, ...existingBlocks.filter((b) => b.text !== systemText)];
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
nextBlocks = [existingBlocks[0], ...existingBlocks.slice(1).filter((b) => b.text !== systemText)];
|
|
97
|
+
nextBlocks[0] = { ...nextBlocks[0], type: 'text', text: systemText };
|
|
80
98
|
}
|
|
99
|
+
root.system = nextBlocks;
|
|
81
100
|
return root;
|
|
82
101
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cacheAntigravitySessionSignature,
|
|
1
|
+
import { cacheAntigravitySessionSignature, getAntigravityRequestSessionMeta } from '../antigravity-session-signature.js';
|
|
2
2
|
function isRecord(value) {
|
|
3
3
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
4
4
|
}
|
|
@@ -28,17 +28,18 @@ export function cacheAntigravityThoughtSignatureFromGeminiResponse(payload, adap
|
|
|
28
28
|
typeof payloadAny.requestId === 'string' ? String(payloadAny.requestId) : ''
|
|
29
29
|
].filter((k) => typeof k === 'string' && k.trim().length);
|
|
30
30
|
let sessionId = '';
|
|
31
|
+
let messageCount = 1;
|
|
31
32
|
for (const key of keyCandidates) {
|
|
32
|
-
const resolved =
|
|
33
|
-
if (resolved && resolved.trim().length) {
|
|
34
|
-
sessionId = resolved.trim();
|
|
33
|
+
const resolved = getAntigravityRequestSessionMeta(key);
|
|
34
|
+
if (resolved && resolved.sessionId.trim().length) {
|
|
35
|
+
sessionId = resolved.sessionId.trim();
|
|
36
|
+
messageCount = resolved.messageCount;
|
|
35
37
|
break;
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
if (!sessionId) {
|
|
39
41
|
return payload;
|
|
40
42
|
}
|
|
41
|
-
const messageCount = 1;
|
|
42
43
|
const candidatesRaw = payload.candidates;
|
|
43
44
|
const candidates = Array.isArray(candidatesRaw) ? candidatesRaw : [];
|
|
44
45
|
for (const candidate of candidates) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { cacheAntigravityRequestSessionMeta, clearAntigravitySessionSignature, extractAntigravityGeminiSessionId, getAntigravitySessionSignatureEntry, shouldTreatAsMissingThoughtSignature } from '../antigravity-session-signature.js';
|
|
2
3
|
function isRecord(value) {
|
|
3
4
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
4
5
|
}
|
|
@@ -28,6 +29,24 @@ function locateGeminiContentsNode(root) {
|
|
|
28
29
|
}
|
|
29
30
|
return undefined;
|
|
30
31
|
}
|
|
32
|
+
function sha256Hex(value) {
|
|
33
|
+
return createHash('sha256').update(value).digest('hex');
|
|
34
|
+
}
|
|
35
|
+
function resolveStableSessionId(adapterContext) {
|
|
36
|
+
if (!adapterContext) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
const ctxAny = adapterContext;
|
|
40
|
+
const candidates = [ctxAny.sessionId, ctxAny.conversationId].filter((v) => typeof v === 'string');
|
|
41
|
+
const raw = candidates.map((s) => s.trim()).find((s) => s.length > 0);
|
|
42
|
+
if (!raw) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
if (raw.toLowerCase().startsWith('sid-')) {
|
|
46
|
+
return raw;
|
|
47
|
+
}
|
|
48
|
+
return `sid-${sha256Hex(raw).slice(0, 16)}`;
|
|
49
|
+
}
|
|
31
50
|
function injectThoughtSignatureIntoFunctionCalls(contentsNode, signature) {
|
|
32
51
|
const contentsRaw = contentsNode.contents;
|
|
33
52
|
if (!Array.isArray(contentsRaw)) {
|
|
@@ -58,25 +77,33 @@ export function prepareAntigravityThoughtSignatureForGeminiRequest(payload, adap
|
|
|
58
77
|
if (!shouldEnableForAdapter(adapterContext)) {
|
|
59
78
|
return payload;
|
|
60
79
|
}
|
|
61
|
-
const
|
|
80
|
+
const stableSessionId = resolveStableSessionId(adapterContext);
|
|
81
|
+
const derivedSessionId = extractAntigravityGeminiSessionId(payload);
|
|
82
|
+
const sessionId = stableSessionId || derivedSessionId;
|
|
62
83
|
const ctxAny = adapterContext;
|
|
63
84
|
const keys = [
|
|
64
85
|
adapterContext.requestId,
|
|
65
86
|
typeof ctxAny.clientRequestId === 'string' ? String(ctxAny.clientRequestId) : '',
|
|
66
87
|
typeof ctxAny.groupRequestId === 'string' ? String(ctxAny.groupRequestId) : ''
|
|
67
88
|
].filter((k) => typeof k === 'string' && k.trim().length);
|
|
89
|
+
const root = payload;
|
|
90
|
+
const contentsNode = locateGeminiContentsNode(root);
|
|
91
|
+
const messageCount = contentsNode && Array.isArray(contentsNode.contents) ? contentsNode.contents.length : 1;
|
|
68
92
|
for (const key of keys) {
|
|
69
|
-
|
|
93
|
+
cacheAntigravityRequestSessionMeta(key, { sessionId, messageCount });
|
|
70
94
|
}
|
|
71
|
-
const
|
|
72
|
-
if (!
|
|
95
|
+
const cached = getAntigravitySessionSignatureEntry(sessionId);
|
|
96
|
+
if (!cached) {
|
|
97
|
+
return payload;
|
|
98
|
+
}
|
|
99
|
+
if (typeof messageCount === 'number' && messageCount > 0 && messageCount < cached.messageCount) {
|
|
100
|
+
// Rewind detected: do not inject a "future" signature; clear and wait for a fresh signature from upstream.
|
|
101
|
+
clearAntigravitySessionSignature(sessionId);
|
|
73
102
|
return payload;
|
|
74
103
|
}
|
|
75
|
-
const root = payload;
|
|
76
|
-
const contentsNode = locateGeminiContentsNode(root);
|
|
77
104
|
if (!contentsNode) {
|
|
78
105
|
return payload;
|
|
79
106
|
}
|
|
80
|
-
injectThoughtSignatureIntoFunctionCalls(contentsNode, signature);
|
|
107
|
+
injectThoughtSignatureIntoFunctionCalls(contentsNode, cached.signature);
|
|
81
108
|
return payload;
|
|
82
109
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
export declare const DUMMY_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
|
|
2
2
|
export declare function cacheAntigravityRequestSessionId(requestId: string, sessionId: string): void;
|
|
3
|
+
export declare function cacheAntigravityRequestSessionMeta(requestId: string, meta: {
|
|
4
|
+
sessionId: string;
|
|
5
|
+
messageCount?: number;
|
|
6
|
+
}): void;
|
|
3
7
|
export declare function getAntigravityRequestSessionId(requestId: string): string | undefined;
|
|
8
|
+
export declare function getAntigravityRequestSessionMeta(requestId: string): {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
messageCount: number;
|
|
11
|
+
} | undefined;
|
|
4
12
|
/**
|
|
5
13
|
* Antigravity-Manager alignment: derive a stable session fingerprint for Gemini native requests.
|
|
6
14
|
* - sha256(first user text parts joined), if len>10 and no "<system-reminder>"
|
|
@@ -10,4 +18,9 @@ export declare function getAntigravityRequestSessionId(requestId: string): strin
|
|
|
10
18
|
export declare function extractAntigravityGeminiSessionId(payload: unknown): string;
|
|
11
19
|
export declare function cacheAntigravitySessionSignature(sessionId: string, signature: string, messageCount?: number): void;
|
|
12
20
|
export declare function getAntigravitySessionSignature(sessionId: string): string | undefined;
|
|
21
|
+
export declare function getAntigravitySessionSignatureEntry(sessionId: string): {
|
|
22
|
+
signature: string;
|
|
23
|
+
messageCount: number;
|
|
24
|
+
} | undefined;
|
|
25
|
+
export declare function clearAntigravitySessionSignature(sessionId: string): void;
|
|
13
26
|
export declare function shouldTreatAsMissingThoughtSignature(value: unknown): boolean;
|
|
@@ -95,13 +95,19 @@ function ensureCacheLimit() {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
export function cacheAntigravityRequestSessionId(requestId, sessionId) {
|
|
98
|
+
cacheAntigravityRequestSessionMeta(requestId, { sessionId });
|
|
99
|
+
}
|
|
100
|
+
export function cacheAntigravityRequestSessionMeta(requestId, meta) {
|
|
98
101
|
const rid = typeof requestId === 'string' ? requestId.trim() : '';
|
|
99
|
-
const sid = typeof sessionId === 'string' ? sessionId.trim() : '';
|
|
102
|
+
const sid = typeof meta?.sessionId === 'string' ? meta.sessionId.trim() : '';
|
|
100
103
|
if (!rid || !sid) {
|
|
101
104
|
return;
|
|
102
105
|
}
|
|
106
|
+
const messageCount = typeof meta?.messageCount === 'number' && Number.isFinite(meta.messageCount) && meta.messageCount > 0
|
|
107
|
+
? Math.floor(meta.messageCount)
|
|
108
|
+
: 1;
|
|
103
109
|
const ts = nowMs();
|
|
104
|
-
requestSessionIds.set(rid, { sessionId: sid, timestamp: ts });
|
|
110
|
+
requestSessionIds.set(rid, { sessionId: sid, messageCount, timestamp: ts });
|
|
105
111
|
if (requestSessionIds.size <= SESSION_CACHE_LIMIT) {
|
|
106
112
|
return;
|
|
107
113
|
}
|
|
@@ -116,6 +122,10 @@ export function cacheAntigravityRequestSessionId(requestId, sessionId) {
|
|
|
116
122
|
}
|
|
117
123
|
}
|
|
118
124
|
export function getAntigravityRequestSessionId(requestId) {
|
|
125
|
+
const meta = getAntigravityRequestSessionMeta(requestId);
|
|
126
|
+
return meta?.sessionId;
|
|
127
|
+
}
|
|
128
|
+
export function getAntigravityRequestSessionMeta(requestId) {
|
|
119
129
|
const rid = typeof requestId === 'string' ? requestId.trim() : '';
|
|
120
130
|
if (!rid) {
|
|
121
131
|
return undefined;
|
|
@@ -129,7 +139,7 @@ export function getAntigravityRequestSessionId(requestId) {
|
|
|
129
139
|
requestSessionIds.delete(rid);
|
|
130
140
|
return undefined;
|
|
131
141
|
}
|
|
132
|
-
return entry.sessionId;
|
|
142
|
+
return { sessionId: entry.sessionId, messageCount: entry.messageCount };
|
|
133
143
|
}
|
|
134
144
|
function findGeminiContentsNode(payload) {
|
|
135
145
|
if (!isRecord(payload)) {
|
|
@@ -221,6 +231,9 @@ export function cacheAntigravitySessionSignature(sessionId, signature, messageCo
|
|
|
221
231
|
ensureCacheLimit();
|
|
222
232
|
}
|
|
223
233
|
export function getAntigravitySessionSignature(sessionId) {
|
|
234
|
+
return getAntigravitySessionSignatureEntry(sessionId)?.signature;
|
|
235
|
+
}
|
|
236
|
+
export function getAntigravitySessionSignatureEntry(sessionId) {
|
|
224
237
|
if (typeof sessionId !== 'string' || !sessionId.trim()) {
|
|
225
238
|
return undefined;
|
|
226
239
|
}
|
|
@@ -234,7 +247,13 @@ export function getAntigravitySessionSignature(sessionId) {
|
|
|
234
247
|
sessionSignatures.delete(key);
|
|
235
248
|
return undefined;
|
|
236
249
|
}
|
|
237
|
-
return entry.signature;
|
|
250
|
+
return { signature: entry.signature, messageCount: entry.messageCount };
|
|
251
|
+
}
|
|
252
|
+
export function clearAntigravitySessionSignature(sessionId) {
|
|
253
|
+
if (typeof sessionId !== 'string' || !sessionId.trim()) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
sessionSignatures.delete(sessionId.trim());
|
|
238
257
|
}
|
|
239
258
|
export function shouldTreatAsMissingThoughtSignature(value) {
|
|
240
259
|
if (typeof value !== 'string') {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "anthropic:claude-code",
|
|
3
|
+
"protocol": "anthropic-messages",
|
|
4
|
+
"request": {
|
|
5
|
+
"mappings": [
|
|
6
|
+
{ "action": "snapshot", "phase": "compat-pre" },
|
|
7
|
+
{ "action": "set_default", "path": "metadata", "value": {} },
|
|
8
|
+
{ "action": "set", "path": "metadata.userAgent", "value": "Claude-Code/2.1.25 (macos; arm64)" },
|
|
9
|
+
{ "action": "set", "path": "metadata.clientOriginator", "value": "claude-code" },
|
|
10
|
+
{ "action": "set_default", "path": "metadata.clientHeaders", "value": {} },
|
|
11
|
+
{ "action": "set", "path": "metadata.clientHeaders.User-Agent", "value": "Claude-Code/2.1.25 (macos; arm64)" },
|
|
12
|
+
{ "action": "set", "path": "metadata.clientHeaders.originator", "value": "claude-code" },
|
|
13
|
+
{ "action": "set", "path": "metadata.clientHeaders.X-App", "value": "claude-code" },
|
|
14
|
+
{ "action": "set", "path": "metadata.clientHeaders.x-app-version", "value": "2.1.25" },
|
|
15
|
+
{ "action": "set", "path": "metadata.clientHeaders.anthropic-beta", "value": "claude-code-20250219,interleaved-thinking-2025-05-14,context-management-2025-06-27,prompt-caching-scope-2026-01-05" },
|
|
16
|
+
{
|
|
17
|
+
"action": "anthropic_claude_code_system_prompt",
|
|
18
|
+
"config": { "preserveExistingSystemAsUserMessage": true }
|
|
19
|
+
},
|
|
20
|
+
{ "action": "snapshot", "phase": "compat-post" }
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
"response": {
|
|
24
|
+
"mappings": []
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -28,6 +28,9 @@ export function runRequestCompatPipeline(profileId, payload, options) {
|
|
|
28
28
|
if (!profile) {
|
|
29
29
|
return { payload };
|
|
30
30
|
}
|
|
31
|
+
if (!isProtocolCompatible(profile, options?.adapterContext)) {
|
|
32
|
+
return { payload };
|
|
33
|
+
}
|
|
31
34
|
const stage = pickStageConfig(profile, 'request');
|
|
32
35
|
if (!stage) {
|
|
33
36
|
return { payload };
|
|
@@ -49,6 +52,9 @@ export function runResponseCompatPipeline(profileId, payload, options) {
|
|
|
49
52
|
if (!profile) {
|
|
50
53
|
return { payload };
|
|
51
54
|
}
|
|
55
|
+
if (!isProtocolCompatible(profile, options?.adapterContext)) {
|
|
56
|
+
return { payload };
|
|
57
|
+
}
|
|
52
58
|
const stage = pickStageConfig(profile, 'response');
|
|
53
59
|
if (!stage) {
|
|
54
60
|
return { payload };
|
|
@@ -95,6 +101,16 @@ function pickStageConfig(profile, stage) {
|
|
|
95
101
|
}
|
|
96
102
|
return null;
|
|
97
103
|
}
|
|
104
|
+
function isProtocolCompatible(profile, adapterContext) {
|
|
105
|
+
const required = typeof profile.protocol === 'string' ? profile.protocol.trim().toLowerCase() : '';
|
|
106
|
+
if (!required) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
const actual = typeof adapterContext?.providerProtocol === 'string' && adapterContext.providerProtocol.trim()
|
|
110
|
+
? adapterContext.providerProtocol.trim().toLowerCase()
|
|
111
|
+
: '';
|
|
112
|
+
return Boolean(actual) && actual === required;
|
|
113
|
+
}
|
|
98
114
|
function applyMapping(root, mapping, state) {
|
|
99
115
|
switch (mapping.action) {
|
|
100
116
|
case 'remove':
|