@rulemetric/proxy 0.2.2
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/Dockerfile +28 -0
- package/addon/context_classifier.py +375 -0
- package/addon/providers.py +483 -0
- package/addon/reporter.py +778 -0
- package/addon/requirements.txt +1 -0
- package/addon/rulemetric_addon.py +1288 -0
- package/addon/secret_redactor.py +130 -0
- package/addon/security_scanner.py +828 -0
- package/addon/session_linker.py +206 -0
- package/addon/sse_parser.py +364 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/anthropic.d.ts +8 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +135 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/base.d.ts +11 -0
- package/dist/providers/base.d.ts.map +1 -0
- package/dist/providers/base.js +43 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/bedrock.d.ts +8 -0
- package/dist/providers/bedrock.d.ts.map +1 -0
- package/dist/providers/bedrock.js +125 -0
- package/dist/providers/bedrock.js.map +1 -0
- package/dist/providers/gemini.d.ts +9 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +140 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +116 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai.d.ts +9 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +129 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/session-linker.d.ts +6 -0
- package/dist/session-linker.d.ts.map +1 -0
- package/dist/session-linker.js +68 -0
- package/dist/session-linker.js.map +1 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { BaseAdapter } from './base.js';
|
|
2
|
+
export class AnthropicAdapter extends BaseAdapter {
|
|
3
|
+
provider = 'anthropic';
|
|
4
|
+
canHandle(host, path) {
|
|
5
|
+
return host.includes('anthropic') && path.startsWith('/v1/messages');
|
|
6
|
+
}
|
|
7
|
+
parse(body) {
|
|
8
|
+
const parsed = this.safeJsonParse(body);
|
|
9
|
+
if (!parsed || typeof parsed !== 'object')
|
|
10
|
+
return null;
|
|
11
|
+
const raw = parsed;
|
|
12
|
+
// Model
|
|
13
|
+
const model = typeof raw.model === 'string' ? raw.model : 'unknown';
|
|
14
|
+
// System blocks
|
|
15
|
+
const systemBlocks = [];
|
|
16
|
+
if (typeof raw.system === 'string') {
|
|
17
|
+
systemBlocks.push({ text: raw.system });
|
|
18
|
+
}
|
|
19
|
+
else if (Array.isArray(raw.system)) {
|
|
20
|
+
for (const block of raw.system) {
|
|
21
|
+
if (block && typeof block === 'object') {
|
|
22
|
+
const b = block;
|
|
23
|
+
const sb = { text: typeof b.text === 'string' ? b.text : '' };
|
|
24
|
+
if (b.cache_control !== undefined) {
|
|
25
|
+
sb.cacheControl = b.cache_control;
|
|
26
|
+
}
|
|
27
|
+
systemBlocks.push(sb);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// System prompt = concatenation of all system block texts
|
|
32
|
+
const systemPrompt = systemBlocks.map((b) => b.text).join('\n');
|
|
33
|
+
// Messages
|
|
34
|
+
const messages = [];
|
|
35
|
+
const rawMessages = Array.isArray(raw.messages) ? raw.messages : [];
|
|
36
|
+
for (const msg of rawMessages) {
|
|
37
|
+
if (!msg || typeof msg !== 'object')
|
|
38
|
+
continue;
|
|
39
|
+
const m = msg;
|
|
40
|
+
const role = m.role;
|
|
41
|
+
if (typeof m.content === 'string') {
|
|
42
|
+
messages.push({
|
|
43
|
+
role: role === 'user' ? 'user' : 'assistant',
|
|
44
|
+
content: m.content,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else if (Array.isArray(m.content)) {
|
|
48
|
+
const textParts = [];
|
|
49
|
+
let hasToolCalls = false;
|
|
50
|
+
let isToolResult = false;
|
|
51
|
+
for (const block of m.content) {
|
|
52
|
+
if (!block || typeof block !== 'object')
|
|
53
|
+
continue;
|
|
54
|
+
const bl = block;
|
|
55
|
+
if (bl.type === 'text' && typeof bl.text === 'string') {
|
|
56
|
+
textParts.push(bl.text);
|
|
57
|
+
}
|
|
58
|
+
else if (bl.type === 'tool_use') {
|
|
59
|
+
hasToolCalls = true;
|
|
60
|
+
}
|
|
61
|
+
else if (bl.type === 'tool_result') {
|
|
62
|
+
isToolResult = true;
|
|
63
|
+
// Extract text from tool_result content
|
|
64
|
+
if (typeof bl.content === 'string') {
|
|
65
|
+
textParts.push(bl.content);
|
|
66
|
+
}
|
|
67
|
+
else if (Array.isArray(bl.content)) {
|
|
68
|
+
for (const inner of bl.content) {
|
|
69
|
+
if (inner && typeof inner === 'object') {
|
|
70
|
+
const ib = inner;
|
|
71
|
+
if (ib.type === 'text' && typeof ib.text === 'string') {
|
|
72
|
+
textParts.push(ib.text);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// type: "image" → skip
|
|
79
|
+
}
|
|
80
|
+
const normalized = {
|
|
81
|
+
role: isToolResult ? 'tool' : role === 'user' ? 'user' : 'assistant',
|
|
82
|
+
content: textParts.join('\n'),
|
|
83
|
+
};
|
|
84
|
+
if (hasToolCalls) {
|
|
85
|
+
normalized.hasToolCalls = true;
|
|
86
|
+
}
|
|
87
|
+
messages.push(normalized);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Tools
|
|
91
|
+
const tools = [];
|
|
92
|
+
if (Array.isArray(raw.tools)) {
|
|
93
|
+
for (const tool of raw.tools) {
|
|
94
|
+
if (!tool || typeof tool !== 'object')
|
|
95
|
+
continue;
|
|
96
|
+
const t = tool;
|
|
97
|
+
tools.push({
|
|
98
|
+
name: typeof t.name === 'string' ? t.name : '',
|
|
99
|
+
description: typeof t.description === 'string' ? t.description : '',
|
|
100
|
+
parameters: t.input_schema ?? {},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Injected instructions: extract from system prompt and user messages only
|
|
105
|
+
const injectedInstructions = [];
|
|
106
|
+
injectedInstructions.push(...this.extractInjectedInstructions(systemPrompt));
|
|
107
|
+
for (const msg of messages) {
|
|
108
|
+
if (msg.role === 'user') {
|
|
109
|
+
injectedInstructions.push(...this.extractInjectedInstructions(msg.content));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Build snapshot
|
|
113
|
+
const snapshot = {
|
|
114
|
+
provider: 'anthropic',
|
|
115
|
+
model,
|
|
116
|
+
systemPrompt,
|
|
117
|
+
systemBlocks,
|
|
118
|
+
messages,
|
|
119
|
+
tools,
|
|
120
|
+
maxTokens: typeof raw.max_tokens === 'number' ? raw.max_tokens : 0,
|
|
121
|
+
injectedInstructions,
|
|
122
|
+
systemPromptHash: this.computeSystemHash(systemPrompt),
|
|
123
|
+
messageCount: messages.length,
|
|
124
|
+
toolCount: tools.length,
|
|
125
|
+
estimatedTokens: 0,
|
|
126
|
+
capturedAt: new Date().toISOString(),
|
|
127
|
+
};
|
|
128
|
+
if (typeof raw.temperature === 'number') {
|
|
129
|
+
snapshot.temperature = raw.temperature;
|
|
130
|
+
}
|
|
131
|
+
snapshot.estimatedTokens = this.estimateTokens(snapshot);
|
|
132
|
+
return snapshot;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ContextSnapshot, Provider, ProviderAdapter } from '../types.js';
|
|
2
|
+
export declare abstract class BaseAdapter implements ProviderAdapter {
|
|
3
|
+
abstract provider: Provider;
|
|
4
|
+
abstract canHandle(host: string, path: string): boolean;
|
|
5
|
+
abstract parse(body: string): ContextSnapshot | null;
|
|
6
|
+
extractInjectedInstructions(text: string): string[];
|
|
7
|
+
computeSystemHash(systemPrompt: string): string;
|
|
8
|
+
estimateTokens(snapshot: ContextSnapshot): number;
|
|
9
|
+
safeJsonParse(body: string): unknown | null;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAK9E,8BAAsB,WAAY,YAAW,eAAe;IAC1D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IACvD,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAEpD,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAanD,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAI/C,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM;IAWjD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;CAW5C"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
const SYSTEM_REMINDER_RE = /<system-reminder>([\s\S]*?)<\/system-reminder>/g;
|
|
3
|
+
const MAX_BODY_SIZE = 2 * 1024 * 1024; // 2MB safety limit
|
|
4
|
+
export class BaseAdapter {
|
|
5
|
+
extractInjectedInstructions(text) {
|
|
6
|
+
const results = [];
|
|
7
|
+
let match;
|
|
8
|
+
const re = new RegExp(SYSTEM_REMINDER_RE.source, 'gs');
|
|
9
|
+
while ((match = re.exec(text)) !== null) {
|
|
10
|
+
const content = match[1].trim();
|
|
11
|
+
if (content) {
|
|
12
|
+
results.push(content);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return results;
|
|
16
|
+
}
|
|
17
|
+
computeSystemHash(systemPrompt) {
|
|
18
|
+
return createHash('sha256').update(systemPrompt).digest('hex');
|
|
19
|
+
}
|
|
20
|
+
estimateTokens(snapshot) {
|
|
21
|
+
let chars = snapshot.systemPrompt.length;
|
|
22
|
+
for (const msg of snapshot.messages) {
|
|
23
|
+
chars += msg.content.length;
|
|
24
|
+
}
|
|
25
|
+
for (const tool of snapshot.tools) {
|
|
26
|
+
chars += tool.name.length + tool.description.length + JSON.stringify(tool.parameters).length;
|
|
27
|
+
}
|
|
28
|
+
return Math.ceil(chars / 4);
|
|
29
|
+
}
|
|
30
|
+
safeJsonParse(body) {
|
|
31
|
+
if (body.length > MAX_BODY_SIZE) {
|
|
32
|
+
console.warn(`[rulemetric] Request body truncated from ${body.length} to ${MAX_BODY_SIZE} bytes — snapshot may be incomplete`);
|
|
33
|
+
body = body.slice(0, MAX_BODY_SIZE);
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(body);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,kBAAkB,GAAG,iDAAiD,CAAC;AAC7E,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,mBAAmB;AAE1D,MAAM,OAAgB,WAAW;IAK/B,2BAA2B,CAAC,IAAY;QACtC,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,KAA6B,CAAC;QAClC,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACvD,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACxC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,iBAAiB,CAAC,YAAoB;QACpC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjE,CAAC;IAED,cAAc,CAAC,QAAyB;QACtC,IAAI,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC;QACzC,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACpC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QAC9B,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YAClC,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC;QAC/F,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,aAAa,CAAC,IAAY;QACxB,IAAI,IAAI,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,4CAA4C,IAAI,CAAC,MAAM,OAAO,aAAa,qCAAqC,CAAC,CAAC;YAC/H,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ContextSnapshot, Provider } from '../types.js';
|
|
2
|
+
import { BaseAdapter } from './base.js';
|
|
3
|
+
export declare class BedrockAdapter extends BaseAdapter {
|
|
4
|
+
provider: Provider;
|
|
5
|
+
canHandle(host: string, path: string): boolean;
|
|
6
|
+
parse(body: string): ContextSnapshot | null;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=bedrock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../src/providers/bedrock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAqC,QAAQ,EAAe,MAAM,aAAa,CAAC;AAC7G,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,qBAAa,cAAe,SAAQ,WAAW;IAC7C,QAAQ,EAAE,QAAQ,CAAa;IAE/B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;CAiI5C"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { BaseAdapter } from './base.js';
|
|
2
|
+
export class BedrockAdapter extends BaseAdapter {
|
|
3
|
+
provider = 'bedrock';
|
|
4
|
+
canHandle(host, path) {
|
|
5
|
+
return host.includes('bedrock-runtime') && path.includes('/converse');
|
|
6
|
+
}
|
|
7
|
+
parse(body) {
|
|
8
|
+
const parsed = this.safeJsonParse(body);
|
|
9
|
+
if (!parsed || typeof parsed !== 'object')
|
|
10
|
+
return null;
|
|
11
|
+
const raw = parsed;
|
|
12
|
+
// Model
|
|
13
|
+
const model = typeof raw.modelId === 'string' ? raw.modelId : 'unknown';
|
|
14
|
+
// System blocks — always an array of { text: string }
|
|
15
|
+
const systemBlocks = [];
|
|
16
|
+
if (Array.isArray(raw.system)) {
|
|
17
|
+
for (const block of raw.system) {
|
|
18
|
+
if (block && typeof block === 'object') {
|
|
19
|
+
const b = block;
|
|
20
|
+
systemBlocks.push({ text: typeof b.text === 'string' ? b.text : '' });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const systemPrompt = systemBlocks.map((b) => b.text).join('\n');
|
|
25
|
+
// Messages
|
|
26
|
+
const messages = [];
|
|
27
|
+
const rawMessages = Array.isArray(raw.messages) ? raw.messages : [];
|
|
28
|
+
for (const msg of rawMessages) {
|
|
29
|
+
if (!msg || typeof msg !== 'object')
|
|
30
|
+
continue;
|
|
31
|
+
const m = msg;
|
|
32
|
+
const role = m.role;
|
|
33
|
+
if (Array.isArray(m.content)) {
|
|
34
|
+
const textParts = [];
|
|
35
|
+
let hasToolCalls = false;
|
|
36
|
+
let isToolResult = false;
|
|
37
|
+
for (const block of m.content) {
|
|
38
|
+
if (!block || typeof block !== 'object')
|
|
39
|
+
continue;
|
|
40
|
+
const bl = block;
|
|
41
|
+
if (typeof bl.text === 'string') {
|
|
42
|
+
textParts.push(bl.text);
|
|
43
|
+
}
|
|
44
|
+
else if (bl.toolUse !== undefined) {
|
|
45
|
+
hasToolCalls = true;
|
|
46
|
+
}
|
|
47
|
+
else if (bl.toolResult !== undefined) {
|
|
48
|
+
isToolResult = true;
|
|
49
|
+
// Extract text from toolResult.content[].text
|
|
50
|
+
const tr = bl.toolResult;
|
|
51
|
+
if (tr && Array.isArray(tr.content)) {
|
|
52
|
+
for (const inner of tr.content) {
|
|
53
|
+
if (inner && typeof inner === 'object') {
|
|
54
|
+
const ib = inner;
|
|
55
|
+
if (typeof ib.text === 'string') {
|
|
56
|
+
textParts.push(ib.text);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const normalized = {
|
|
64
|
+
role: isToolResult ? 'tool' : role === 'user' ? 'user' : 'assistant',
|
|
65
|
+
content: textParts.join('\n'),
|
|
66
|
+
};
|
|
67
|
+
if (hasToolCalls) {
|
|
68
|
+
normalized.hasToolCalls = true;
|
|
69
|
+
}
|
|
70
|
+
messages.push(normalized);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Tools — toolConfig.tools[].toolSpec
|
|
74
|
+
const tools = [];
|
|
75
|
+
const toolConfig = raw.toolConfig;
|
|
76
|
+
if (toolConfig && Array.isArray(toolConfig.tools)) {
|
|
77
|
+
for (const tool of toolConfig.tools) {
|
|
78
|
+
if (!tool || typeof tool !== 'object')
|
|
79
|
+
continue;
|
|
80
|
+
const t = tool;
|
|
81
|
+
const spec = t.toolSpec;
|
|
82
|
+
if (!spec)
|
|
83
|
+
continue;
|
|
84
|
+
const inputSchema = spec.inputSchema;
|
|
85
|
+
const parameters = inputSchema?.json ?? {};
|
|
86
|
+
tools.push({
|
|
87
|
+
name: typeof spec.name === 'string' ? spec.name : '',
|
|
88
|
+
description: typeof spec.description === 'string' ? spec.description : '',
|
|
89
|
+
parameters,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Injected instructions from system prompt and user messages
|
|
94
|
+
const injectedInstructions = [];
|
|
95
|
+
injectedInstructions.push(...this.extractInjectedInstructions(systemPrompt));
|
|
96
|
+
for (const msg of messages) {
|
|
97
|
+
if (msg.role === 'user') {
|
|
98
|
+
injectedInstructions.push(...this.extractInjectedInstructions(msg.content));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Inference config
|
|
102
|
+
const inferenceConfig = raw.inferenceConfig;
|
|
103
|
+
const snapshot = {
|
|
104
|
+
provider: 'bedrock',
|
|
105
|
+
model,
|
|
106
|
+
systemPrompt,
|
|
107
|
+
systemBlocks,
|
|
108
|
+
messages,
|
|
109
|
+
tools,
|
|
110
|
+
maxTokens: typeof inferenceConfig?.maxTokens === 'number' ? inferenceConfig.maxTokens : 0,
|
|
111
|
+
injectedInstructions,
|
|
112
|
+
systemPromptHash: this.computeSystemHash(systemPrompt),
|
|
113
|
+
messageCount: messages.length,
|
|
114
|
+
toolCount: tools.length,
|
|
115
|
+
estimatedTokens: 0,
|
|
116
|
+
capturedAt: new Date().toISOString(),
|
|
117
|
+
};
|
|
118
|
+
if (typeof inferenceConfig?.temperature === 'number') {
|
|
119
|
+
snapshot.temperature = inferenceConfig.temperature;
|
|
120
|
+
}
|
|
121
|
+
snapshot.estimatedTokens = this.estimateTokens(snapshot);
|
|
122
|
+
return snapshot;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=bedrock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bedrock.js","sourceRoot":"","sources":["../../src/providers/bedrock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ContextSnapshot, Provider } from '../types.js';
|
|
2
|
+
import { BaseAdapter } from './base.js';
|
|
3
|
+
export declare class GeminiAdapter extends BaseAdapter {
|
|
4
|
+
provider: Provider;
|
|
5
|
+
private estimateGeminiTokens;
|
|
6
|
+
canHandle(host: string, path: string): boolean;
|
|
7
|
+
parse(body: string): ContextSnapshot | null;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/providers/gemini.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAqC,QAAQ,EAAe,MAAM,aAAa,CAAC;AAC7G,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,qBAAa,aAAc,SAAQ,WAAW;IAC5C,QAAQ,EAAE,QAAQ,CAAY;IAE9B,OAAO,CAAC,oBAAoB;IAI5B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;CA4I5C"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { BaseAdapter } from './base.js';
|
|
2
|
+
export class GeminiAdapter extends BaseAdapter {
|
|
3
|
+
provider = 'gemini';
|
|
4
|
+
estimateGeminiTokens(snapshot) {
|
|
5
|
+
return Math.floor(snapshot.systemPrompt.length / 4);
|
|
6
|
+
}
|
|
7
|
+
canHandle(host, path) {
|
|
8
|
+
return host.includes('googleapis.com') && path.includes(':generateContent');
|
|
9
|
+
}
|
|
10
|
+
parse(body) {
|
|
11
|
+
const parsed = this.safeJsonParse(body);
|
|
12
|
+
if (!parsed || typeof parsed !== 'object')
|
|
13
|
+
return null;
|
|
14
|
+
const raw = parsed;
|
|
15
|
+
// Model
|
|
16
|
+
const model = typeof raw.model === 'string' ? raw.model : 'unknown';
|
|
17
|
+
// System blocks from systemInstruction
|
|
18
|
+
const systemBlocks = [];
|
|
19
|
+
const sysInst = raw.systemInstruction;
|
|
20
|
+
if (sysInst && typeof sysInst === 'object' && Array.isArray(sysInst.parts)) {
|
|
21
|
+
for (const part of sysInst.parts) {
|
|
22
|
+
if (part && typeof part === 'object') {
|
|
23
|
+
const p = part;
|
|
24
|
+
if (typeof p.text === 'string') {
|
|
25
|
+
systemBlocks.push({ text: p.text });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// System prompt = concatenation of all system block texts
|
|
31
|
+
const systemPrompt = systemBlocks.map((b) => b.text).join('\n');
|
|
32
|
+
// Messages from contents[]
|
|
33
|
+
const messages = [];
|
|
34
|
+
const rawContents = Array.isArray(raw.contents) ? raw.contents : [];
|
|
35
|
+
for (const content of rawContents) {
|
|
36
|
+
if (!content || typeof content !== 'object')
|
|
37
|
+
continue;
|
|
38
|
+
const c = content;
|
|
39
|
+
const role = c.role;
|
|
40
|
+
const textParts = [];
|
|
41
|
+
let hasToolCalls = false;
|
|
42
|
+
let hasFunctionResponse = false;
|
|
43
|
+
if (Array.isArray(c.parts)) {
|
|
44
|
+
for (const part of c.parts) {
|
|
45
|
+
if (!part || typeof part !== 'object')
|
|
46
|
+
continue;
|
|
47
|
+
const p = part;
|
|
48
|
+
if (typeof p.text === 'string') {
|
|
49
|
+
textParts.push(p.text);
|
|
50
|
+
}
|
|
51
|
+
else if (p.inlineData !== undefined) {
|
|
52
|
+
// skip inline data
|
|
53
|
+
}
|
|
54
|
+
else if (p.functionCall !== undefined) {
|
|
55
|
+
hasToolCalls = true;
|
|
56
|
+
}
|
|
57
|
+
else if (p.functionResponse !== undefined) {
|
|
58
|
+
hasFunctionResponse = true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
let normalizedRole;
|
|
63
|
+
if (hasFunctionResponse) {
|
|
64
|
+
normalizedRole = 'tool';
|
|
65
|
+
}
|
|
66
|
+
else if (role === 'model') {
|
|
67
|
+
normalizedRole = 'assistant';
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
normalizedRole = 'user';
|
|
71
|
+
}
|
|
72
|
+
const normalized = {
|
|
73
|
+
role: normalizedRole,
|
|
74
|
+
content: textParts.join(''),
|
|
75
|
+
};
|
|
76
|
+
if (hasToolCalls) {
|
|
77
|
+
normalized.hasToolCalls = true;
|
|
78
|
+
}
|
|
79
|
+
messages.push(normalized);
|
|
80
|
+
}
|
|
81
|
+
// Tools from tools[].functionDeclarations[]
|
|
82
|
+
const tools = [];
|
|
83
|
+
if (Array.isArray(raw.tools)) {
|
|
84
|
+
for (const toolGroup of raw.tools) {
|
|
85
|
+
if (!toolGroup || typeof toolGroup !== 'object')
|
|
86
|
+
continue;
|
|
87
|
+
const tg = toolGroup;
|
|
88
|
+
if (Array.isArray(tg.functionDeclarations)) {
|
|
89
|
+
for (const decl of tg.functionDeclarations) {
|
|
90
|
+
if (!decl || typeof decl !== 'object')
|
|
91
|
+
continue;
|
|
92
|
+
const d = decl;
|
|
93
|
+
tools.push({
|
|
94
|
+
name: typeof d.name === 'string' ? d.name : '',
|
|
95
|
+
description: typeof d.description === 'string' ? d.description : '',
|
|
96
|
+
parameters: d.parameters ?? {},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Generation config
|
|
103
|
+
const genConfig = raw.generationConfig;
|
|
104
|
+
const maxTokens = genConfig && typeof genConfig === 'object' && typeof genConfig.maxOutputTokens === 'number'
|
|
105
|
+
? genConfig.maxOutputTokens
|
|
106
|
+
: 0;
|
|
107
|
+
// Injected instructions: extract from system prompt and user messages
|
|
108
|
+
const injectedInstructions = [];
|
|
109
|
+
injectedInstructions.push(...this.extractInjectedInstructions(systemPrompt));
|
|
110
|
+
for (const msg of messages) {
|
|
111
|
+
if (msg.role === 'user') {
|
|
112
|
+
injectedInstructions.push(...this.extractInjectedInstructions(msg.content));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Build snapshot
|
|
116
|
+
const snapshot = {
|
|
117
|
+
provider: 'gemini',
|
|
118
|
+
model,
|
|
119
|
+
systemPrompt,
|
|
120
|
+
systemBlocks,
|
|
121
|
+
messages,
|
|
122
|
+
tools,
|
|
123
|
+
maxTokens,
|
|
124
|
+
injectedInstructions,
|
|
125
|
+
systemPromptHash: this.computeSystemHash(systemPrompt),
|
|
126
|
+
messageCount: messages.length,
|
|
127
|
+
toolCount: tools.length,
|
|
128
|
+
estimatedTokens: 0,
|
|
129
|
+
capturedAt: new Date().toISOString(),
|
|
130
|
+
};
|
|
131
|
+
if (genConfig &&
|
|
132
|
+
typeof genConfig === 'object' &&
|
|
133
|
+
typeof genConfig.temperature === 'number') {
|
|
134
|
+
snapshot.temperature = genConfig.temperature;
|
|
135
|
+
}
|
|
136
|
+
snapshot.estimatedTokens = this.estimateGeminiTokens(snapshot);
|
|
137
|
+
return snapshot;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=gemini.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/providers/gemini.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Provider, ProviderAdapter } from '../types.js';
|
|
2
|
+
export declare function detectProvider(host: string, path: string): Provider | null;
|
|
3
|
+
export declare class ProviderRegistry {
|
|
4
|
+
private adapters;
|
|
5
|
+
register(adapter: ProviderAdapter): void;
|
|
6
|
+
detect(host: string, path: string): ProviderAdapter | null;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAsF7D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAmC1E;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAyB;IAEzC,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAIxC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;CAQ3D"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/** Map of known OpenAI-compatible hostnames to provider names. */
|
|
2
|
+
const KNOWN_OPENAI_COMPAT_HOSTS = {
|
|
3
|
+
'api.openai.com': 'openai',
|
|
4
|
+
'api.groq.com': 'groq',
|
|
5
|
+
'api.together.xyz': 'together',
|
|
6
|
+
'api.fireworks.ai': 'fireworks',
|
|
7
|
+
'api.deepseek.com': 'deepseek',
|
|
8
|
+
'api.perplexity.ai': 'perplexity',
|
|
9
|
+
'api.cerebras.ai': 'cerebras',
|
|
10
|
+
'api.sambanova.ai': 'sambanova',
|
|
11
|
+
'api.x.ai': 'xai',
|
|
12
|
+
'api.mistral.ai': 'mistral',
|
|
13
|
+
'integrate.api.nvidia.com': 'nvidia_nim',
|
|
14
|
+
'api.ai21.com': 'ai21',
|
|
15
|
+
'api.cohere.com': 'cohere',
|
|
16
|
+
'openrouter.ai': 'openrouter',
|
|
17
|
+
'openai-proxy.replicate.com': 'replicate',
|
|
18
|
+
};
|
|
19
|
+
/** Derive a short provider name from a hostname (for unknown OpenAI-compat providers). */
|
|
20
|
+
function providerFromHost(host) {
|
|
21
|
+
const h = host.split(':')[0];
|
|
22
|
+
const parts = h.split('.');
|
|
23
|
+
if (parts.length >= 2) {
|
|
24
|
+
const candidate = parts[parts.length - 2];
|
|
25
|
+
if (['co', 'com', 'net', 'org', 'io', 'ai'].includes(candidate)) {
|
|
26
|
+
return parts.length >= 3 ? parts[parts.length - 3] : parts[0];
|
|
27
|
+
}
|
|
28
|
+
return candidate;
|
|
29
|
+
}
|
|
30
|
+
return parts[0];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Specific rules for non-OpenAI formats. These are checked first,
|
|
34
|
+
* before the generic OpenAI-compatible catch-all.
|
|
35
|
+
*/
|
|
36
|
+
const specificRules = [
|
|
37
|
+
{
|
|
38
|
+
provider: 'anthropic',
|
|
39
|
+
match: (host, path) => host === 'api.anthropic.com' && path.startsWith('/v1/messages'),
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
provider: 'gemini',
|
|
43
|
+
match: (host, path) => host === 'generativelanguage.googleapis.com' && path.includes(':generateContent'),
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
provider: 'bedrock',
|
|
47
|
+
match: (host, path) => host.includes('bedrock-runtime') && path.includes('/converse'),
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
provider: 'cortex',
|
|
51
|
+
match: (host, path) => host.endsWith('.snowflakecomputing.com') &&
|
|
52
|
+
path.includes('/api/v2/cortex/inference:complete'),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
provider: 'azure_openai',
|
|
56
|
+
match: (host, path) => host.endsWith('.openai.azure.com') && path.includes('/chat/completions'),
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
provider: 'azure_ai',
|
|
60
|
+
match: (host, path) => host.endsWith('.models.ai.azure.com') && path.includes('/chat/completions'),
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
provider: 'cloudflare',
|
|
64
|
+
match: (host, path) => host === 'api.cloudflare.com' && path.includes('/ai/v1/chat/completions'),
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
provider: 'databricks',
|
|
68
|
+
match: (host, path) => host.endsWith('.cloud.databricks.com') && path.includes('/invocations'),
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
export function detectProvider(host, path) {
|
|
72
|
+
if (!host)
|
|
73
|
+
return null;
|
|
74
|
+
// 1. Check specific non-OpenAI and special-case rules
|
|
75
|
+
for (const rule of specificRules) {
|
|
76
|
+
if (rule.match(host, path)) {
|
|
77
|
+
return rule.provider;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// 2. Check known OpenAI-compatible hosts
|
|
81
|
+
for (const [knownHost, provider] of Object.entries(KNOWN_OPENAI_COMPAT_HOSTS)) {
|
|
82
|
+
if (host === knownHost || host.endsWith('.' + knownHost)) {
|
|
83
|
+
if (path.includes('chat/completions') || path.includes('/completions')) {
|
|
84
|
+
return provider;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// 3. Ollama native API
|
|
89
|
+
if (host.startsWith('localhost') && path.startsWith('/api/chat')) {
|
|
90
|
+
return 'ollama';
|
|
91
|
+
}
|
|
92
|
+
// 4. Ollama OpenAI-compat endpoint
|
|
93
|
+
if (host.startsWith('localhost') && path.includes('/v1/chat/completions')) {
|
|
94
|
+
return 'ollama';
|
|
95
|
+
}
|
|
96
|
+
// 5. Generic catch-all: any request to a chat/completions path
|
|
97
|
+
if (path.includes('chat/completions')) {
|
|
98
|
+
return providerFromHost(host);
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
export class ProviderRegistry {
|
|
103
|
+
adapters = [];
|
|
104
|
+
register(adapter) {
|
|
105
|
+
this.adapters.push(adapter);
|
|
106
|
+
}
|
|
107
|
+
detect(host, path) {
|
|
108
|
+
for (const adapter of this.adapters) {
|
|
109
|
+
if (adapter.canHandle(host, path)) {
|
|
110
|
+
return adapter;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=index.js.map
|