@rulemetric/proxy 0.7.4 → 0.7.5
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/package.json +3 -18
- package/dist/index.d.ts +0 -10
- package/dist/index.js +0 -9
- package/dist/providers/anthropic.d.ts +0 -8
- package/dist/providers/anthropic.js +0 -135
- package/dist/providers/base.d.ts +0 -11
- package/dist/providers/base.js +0 -43
- package/dist/providers/bedrock.d.ts +0 -8
- package/dist/providers/bedrock.js +0 -125
- package/dist/providers/gemini.d.ts +0 -9
- package/dist/providers/gemini.js +0 -140
- package/dist/providers/index.d.ts +0 -8
- package/dist/providers/index.js +0 -116
- package/dist/providers/openai.d.ts +0 -9
- package/dist/providers/openai.js +0 -129
- package/dist/session-linker.d.ts +0 -6
- package/dist/session-linker.js +0 -68
- package/dist/types.d.ts +0 -41
- package/dist/types.js +0 -2
package/package.json
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulemetric/proxy",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "./dist/index.js",
|
|
6
|
-
"types": "./dist/index.d.ts",
|
|
7
5
|
"publishConfig": {
|
|
8
6
|
"access": "public"
|
|
9
7
|
},
|
|
@@ -13,22 +11,9 @@
|
|
|
13
11
|
"!addon/.pytest_cache",
|
|
14
12
|
"!addon/.agents",
|
|
15
13
|
"!addon/test_*.py",
|
|
16
|
-
"
|
|
17
|
-
"Dockerfile",
|
|
18
|
-
"!dist/**/*.map"
|
|
14
|
+
"Dockerfile"
|
|
19
15
|
],
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"zod": "^3.24.0"
|
|
22
|
-
},
|
|
23
|
-
"devDependencies": {
|
|
24
|
-
"@types/node": "^22.0.0",
|
|
25
|
-
"typescript": "^5.9.0",
|
|
26
|
-
"vitest": "^3.2.0",
|
|
27
|
-
"@rulemetric/typescript-config": "0.0.0"
|
|
28
|
-
},
|
|
29
16
|
"scripts": {
|
|
30
|
-
"
|
|
31
|
-
"test": "vitest run",
|
|
32
|
-
"type-check": "tsc --noEmit"
|
|
17
|
+
"test:python": "python3 -m pytest addon -q"
|
|
33
18
|
}
|
|
34
19
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export * from './types.js';
|
|
2
|
-
export { BaseAdapter } from './providers/base.js';
|
|
3
|
-
export { ProviderRegistry, detectProvider } from './providers/index.js';
|
|
4
|
-
export { AnthropicAdapter } from './providers/anthropic.js';
|
|
5
|
-
export { OpenAIAdapter } from './providers/openai.js';
|
|
6
|
-
export { GeminiAdapter } from './providers/gemini.js';
|
|
7
|
-
export { BedrockAdapter } from './providers/bedrock.js';
|
|
8
|
-
export { findActiveSession } from './session-linker.js';
|
|
9
|
-
export type { ActiveSession } from './session-linker.js';
|
|
10
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export * from './types.js';
|
|
2
|
-
export { BaseAdapter } from './providers/base.js';
|
|
3
|
-
export { ProviderRegistry, detectProvider } from './providers/index.js';
|
|
4
|
-
export { AnthropicAdapter } from './providers/anthropic.js';
|
|
5
|
-
export { OpenAIAdapter } from './providers/openai.js';
|
|
6
|
-
export { GeminiAdapter } from './providers/gemini.js';
|
|
7
|
-
export { BedrockAdapter } from './providers/bedrock.js';
|
|
8
|
-
export { findActiveSession } from './session-linker.js';
|
|
9
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ContextSnapshot, Provider } from '../types.js';
|
|
2
|
-
import { BaseAdapter } from './base.js';
|
|
3
|
-
export declare class AnthropicAdapter extends BaseAdapter {
|
|
4
|
-
provider: Provider;
|
|
5
|
-
canHandle(host: string, path: string): boolean;
|
|
6
|
-
parse(body: string): ContextSnapshot | null;
|
|
7
|
-
}
|
|
8
|
-
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -1,135 +0,0 @@
|
|
|
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
|
package/dist/providers/base.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
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
|
package/dist/providers/base.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
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
|
|
@@ -1,8 +0,0 @@
|
|
|
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
|
|
@@ -1,125 +0,0 @@
|
|
|
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
|
|
@@ -1,9 +0,0 @@
|
|
|
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
|
package/dist/providers/gemini.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
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
|
|
@@ -1,8 +0,0 @@
|
|
|
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
|
package/dist/providers/index.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
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
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { ContextSnapshot, Provider } from '../types.js';
|
|
2
|
-
import { BaseAdapter } from './base.js';
|
|
3
|
-
export declare class OpenAIAdapter extends BaseAdapter {
|
|
4
|
-
provider: Provider;
|
|
5
|
-
canHandle(host: string, path: string): boolean;
|
|
6
|
-
parse(body: string): ContextSnapshot | null;
|
|
7
|
-
private extractContent;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=openai.d.ts.map
|
package/dist/providers/openai.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { BaseAdapter } from './base.js';
|
|
2
|
-
export class OpenAIAdapter extends BaseAdapter {
|
|
3
|
-
provider = 'openai';
|
|
4
|
-
canHandle(host, path) {
|
|
5
|
-
return ((host.includes('openai') || host.includes('azure') || host.includes('ollama') || host.includes('localhost')) &&
|
|
6
|
-
path.includes('/v1/chat/completions'));
|
|
7
|
-
}
|
|
8
|
-
parse(body) {
|
|
9
|
-
const parsed = this.safeJsonParse(body);
|
|
10
|
-
if (!parsed || typeof parsed !== 'object')
|
|
11
|
-
return null;
|
|
12
|
-
const raw = parsed;
|
|
13
|
-
// Model
|
|
14
|
-
const model = typeof raw.model === 'string' ? raw.model : 'unknown';
|
|
15
|
-
// Separate system messages, developer messages, and regular messages
|
|
16
|
-
const rawMessages = Array.isArray(raw.messages) ? raw.messages : [];
|
|
17
|
-
const systemTexts = [];
|
|
18
|
-
const developerTexts = [];
|
|
19
|
-
const messages = [];
|
|
20
|
-
for (const msg of rawMessages) {
|
|
21
|
-
if (!msg || typeof msg !== 'object')
|
|
22
|
-
continue;
|
|
23
|
-
const m = msg;
|
|
24
|
-
const role = m.role;
|
|
25
|
-
const content = this.extractContent(m);
|
|
26
|
-
if (role === 'system') {
|
|
27
|
-
systemTexts.push(content);
|
|
28
|
-
}
|
|
29
|
-
else if (role === 'developer') {
|
|
30
|
-
developerTexts.push(content);
|
|
31
|
-
}
|
|
32
|
-
else if (role === 'user') {
|
|
33
|
-
messages.push({ role: 'user', content });
|
|
34
|
-
}
|
|
35
|
-
else if (role === 'assistant') {
|
|
36
|
-
const normalized = { role: 'assistant', content };
|
|
37
|
-
if (Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
|
|
38
|
-
normalized.hasToolCalls = true;
|
|
39
|
-
}
|
|
40
|
-
messages.push(normalized);
|
|
41
|
-
}
|
|
42
|
-
else if (role === 'tool') {
|
|
43
|
-
messages.push({ role: 'tool', content });
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
// System prompt from system messages
|
|
47
|
-
const systemPrompt = systemTexts.join('\n');
|
|
48
|
-
// System blocks
|
|
49
|
-
const systemBlocks = systemTexts.map((text) => ({ text }));
|
|
50
|
-
// Tools
|
|
51
|
-
const tools = [];
|
|
52
|
-
if (Array.isArray(raw.tools)) {
|
|
53
|
-
for (const tool of raw.tools) {
|
|
54
|
-
if (!tool || typeof tool !== 'object')
|
|
55
|
-
continue;
|
|
56
|
-
const t = tool;
|
|
57
|
-
if (t.function && typeof t.function === 'object') {
|
|
58
|
-
const fn = t.function;
|
|
59
|
-
tools.push({
|
|
60
|
-
name: typeof fn.name === 'string' ? fn.name : '',
|
|
61
|
-
description: typeof fn.description === 'string' ? fn.description : '',
|
|
62
|
-
parameters: fn.parameters ?? {},
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
// Injected instructions: extract from system prompt and user messages
|
|
68
|
-
const injectedInstructions = [];
|
|
69
|
-
injectedInstructions.push(...this.extractInjectedInstructions(systemPrompt));
|
|
70
|
-
for (const msg of messages) {
|
|
71
|
-
if (msg.role === 'user') {
|
|
72
|
-
injectedInstructions.push(...this.extractInjectedInstructions(msg.content));
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
// Developer messages → injected instructions
|
|
76
|
-
for (const text of developerTexts) {
|
|
77
|
-
injectedInstructions.push(text);
|
|
78
|
-
}
|
|
79
|
-
// max_completion_tokens takes precedence over max_tokens
|
|
80
|
-
let maxTokens = 0;
|
|
81
|
-
if (typeof raw.max_completion_tokens === 'number') {
|
|
82
|
-
maxTokens = raw.max_completion_tokens;
|
|
83
|
-
}
|
|
84
|
-
else if (typeof raw.max_tokens === 'number') {
|
|
85
|
-
maxTokens = raw.max_tokens;
|
|
86
|
-
}
|
|
87
|
-
// Build snapshot
|
|
88
|
-
const snapshot = {
|
|
89
|
-
provider: 'openai',
|
|
90
|
-
model,
|
|
91
|
-
systemPrompt,
|
|
92
|
-
systemBlocks,
|
|
93
|
-
messages,
|
|
94
|
-
tools,
|
|
95
|
-
maxTokens,
|
|
96
|
-
injectedInstructions,
|
|
97
|
-
systemPromptHash: this.computeSystemHash(systemPrompt),
|
|
98
|
-
messageCount: messages.length,
|
|
99
|
-
toolCount: tools.length,
|
|
100
|
-
estimatedTokens: 0,
|
|
101
|
-
capturedAt: new Date().toISOString(),
|
|
102
|
-
};
|
|
103
|
-
if (typeof raw.temperature === 'number') {
|
|
104
|
-
snapshot.temperature = raw.temperature;
|
|
105
|
-
}
|
|
106
|
-
snapshot.estimatedTokens = this.estimateTokens(snapshot);
|
|
107
|
-
return snapshot;
|
|
108
|
-
}
|
|
109
|
-
extractContent(msg) {
|
|
110
|
-
if (typeof msg.content === 'string') {
|
|
111
|
-
return msg.content;
|
|
112
|
-
}
|
|
113
|
-
if (Array.isArray(msg.content)) {
|
|
114
|
-
const textParts = [];
|
|
115
|
-
for (const part of msg.content) {
|
|
116
|
-
if (!part || typeof part !== 'object')
|
|
117
|
-
continue;
|
|
118
|
-
const p = part;
|
|
119
|
-
if (p.type === 'text' && typeof p.text === 'string') {
|
|
120
|
-
textParts.push(p.text);
|
|
121
|
-
}
|
|
122
|
-
// Skip image_url and other non-text parts
|
|
123
|
-
}
|
|
124
|
-
return textParts.join('\n');
|
|
125
|
-
}
|
|
126
|
-
return '';
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
//# sourceMappingURL=openai.js.map
|
package/dist/session-linker.d.ts
DELETED
package/dist/session-linker.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
4
|
-
const MAX_SESSION_AGE_MS = 4 * 60 * 60 * 1000; // 4 hours
|
|
5
|
-
export function findActiveSession(sessionDir) {
|
|
6
|
-
let entries;
|
|
7
|
-
try {
|
|
8
|
-
entries = readdirSync(sessionDir);
|
|
9
|
-
}
|
|
10
|
-
catch (err) {
|
|
11
|
-
const code = err.code;
|
|
12
|
-
if (code === 'ENOENT') {
|
|
13
|
-
// Directory doesn't exist — session tracking likely not installed
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
// Permission error or other OS error — worth logging
|
|
17
|
-
console.warn(`[rulemetric] Cannot read session dir ${sessionDir}: ${err}`);
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
const now = Date.now();
|
|
21
|
-
// Sort by mtime descending (most recent first)
|
|
22
|
-
const files = entries
|
|
23
|
-
.map((name) => {
|
|
24
|
-
const fullPath = join(sessionDir, name);
|
|
25
|
-
try {
|
|
26
|
-
const stat = statSync(fullPath);
|
|
27
|
-
if (!stat.isFile())
|
|
28
|
-
return null;
|
|
29
|
-
// Skip stale files
|
|
30
|
-
if (now - stat.mtimeMs > MAX_SESSION_AGE_MS)
|
|
31
|
-
return null;
|
|
32
|
-
return { path: fullPath, name, mtime: stat.mtimeMs };
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
})
|
|
38
|
-
.filter((f) => f !== null)
|
|
39
|
-
.sort((a, b) => b.mtime - a.mtime);
|
|
40
|
-
for (const file of files) {
|
|
41
|
-
try {
|
|
42
|
-
const content = readFileSync(file.path, 'utf-8').trim();
|
|
43
|
-
if (!content)
|
|
44
|
-
continue;
|
|
45
|
-
const lines = content.split('\n');
|
|
46
|
-
const sessionId = lines[0].trim();
|
|
47
|
-
const rwSessionId = lines.length > 1 ? lines[1].trim() : '';
|
|
48
|
-
// Validate UUID format
|
|
49
|
-
if (!UUID_RE.test(sessionId)) {
|
|
50
|
-
console.warn(`[rulemetric] Invalid session ID format in ${file.name}: '${sessionId.slice(0, 50)}'`);
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
if (rwSessionId && !UUID_RE.test(rwSessionId)) {
|
|
54
|
-
console.warn(`[rulemetric] Invalid RW session ID in ${file.name}: '${rwSessionId.slice(0, 50)}'`);
|
|
55
|
-
return { sessionId, rwSessionId: '' };
|
|
56
|
-
}
|
|
57
|
-
if (sessionId) {
|
|
58
|
-
return { sessionId, rwSessionId };
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
catch (err) {
|
|
62
|
-
console.warn(`[rulemetric] Cannot read session file ${file.name}: ${err}`);
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
//# sourceMappingURL=session-linker.js.map
|
package/dist/types.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export type KnownProvider = 'anthropic' | 'openai' | 'azure_openai' | 'azure_ai' | 'gemini' | 'bedrock' | 'ollama' | 'cortex' | 'groq' | 'together' | 'fireworks' | 'deepseek' | 'perplexity' | 'cerebras' | 'sambanova' | 'xai' | 'mistral' | 'nvidia_nim' | 'ai21' | 'cohere' | 'openrouter' | 'replicate' | 'cloudflare' | 'databricks';
|
|
2
|
-
/** Known providers or any string for generic OpenAI-compatible providers. */
|
|
3
|
-
export type Provider = KnownProvider | (string & {});
|
|
4
|
-
export interface SystemBlock {
|
|
5
|
-
text: string;
|
|
6
|
-
cacheControl?: unknown;
|
|
7
|
-
}
|
|
8
|
-
export interface NormalizedMessage {
|
|
9
|
-
role: 'user' | 'assistant' | 'tool';
|
|
10
|
-
content: string;
|
|
11
|
-
hasToolCalls?: boolean;
|
|
12
|
-
}
|
|
13
|
-
export interface NormalizedTool {
|
|
14
|
-
name: string;
|
|
15
|
-
description: string;
|
|
16
|
-
parameters: Record<string, unknown>;
|
|
17
|
-
}
|
|
18
|
-
export interface ContextSnapshot {
|
|
19
|
-
provider: Provider;
|
|
20
|
-
model: string;
|
|
21
|
-
systemPrompt: string;
|
|
22
|
-
systemBlocks: SystemBlock[];
|
|
23
|
-
messages: NormalizedMessage[];
|
|
24
|
-
tools: NormalizedTool[];
|
|
25
|
-
maxTokens: number;
|
|
26
|
-
temperature?: number;
|
|
27
|
-
injectedInstructions: string[];
|
|
28
|
-
systemPromptHash: string;
|
|
29
|
-
messageCount: number;
|
|
30
|
-
toolCount: number;
|
|
31
|
-
estimatedTokens: number;
|
|
32
|
-
sessionId?: string;
|
|
33
|
-
projectPath?: string;
|
|
34
|
-
capturedAt: string;
|
|
35
|
-
}
|
|
36
|
-
export interface ProviderAdapter {
|
|
37
|
-
provider: Provider;
|
|
38
|
-
canHandle(host: string, path: string): boolean;
|
|
39
|
-
parse(body: string): ContextSnapshot | null;
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.js
DELETED