@euconform/core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -0
- package/LICENSE +21 -0
- package/dist/fairness-metrics.d.ts +65 -0
- package/dist/fairness-metrics.d.ts.map +1 -0
- package/dist/fairness-metrics.js +394 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/inference/browser-inference.d.ts +60 -0
- package/dist/inference/browser-inference.d.ts.map +1 -0
- package/dist/inference/browser-inference.js +221 -0
- package/dist/inference/capability-detection.d.ts +183 -0
- package/dist/inference/capability-detection.d.ts.map +1 -0
- package/dist/inference/capability-detection.js +552 -0
- package/dist/inference/index.d.ts +43 -0
- package/dist/inference/index.d.ts.map +1 -0
- package/dist/inference/index.js +97 -0
- package/dist/inference/inference-factory.d.ts +73 -0
- package/dist/inference/inference-factory.d.ts.map +1 -0
- package/dist/inference/inference-factory.js +175 -0
- package/dist/inference/ollama-client.d.ts +114 -0
- package/dist/inference/ollama-client.d.ts.map +1 -0
- package/dist/inference/ollama-client.js +386 -0
- package/dist/legal-checks/annex-iv-report.d.ts +131 -0
- package/dist/legal-checks/annex-iv-report.d.ts.map +1 -0
- package/dist/legal-checks/annex-iv-report.js +62 -0
- package/dist/legal-checks/bias-metrics.d.ts +162 -0
- package/dist/legal-checks/bias-metrics.d.ts.map +1 -0
- package/dist/legal-checks/bias-metrics.js +408 -0
- package/dist/legal-checks/data-governance.d.ts +30 -0
- package/dist/legal-checks/data-governance.d.ts.map +1 -0
- package/dist/legal-checks/data-governance.js +99 -0
- package/dist/legal-checks/human-oversight-logging.d.ts +27 -0
- package/dist/legal-checks/human-oversight-logging.d.ts.map +1 -0
- package/dist/legal-checks/human-oversight-logging.js +106 -0
- package/dist/legal-checks/index.d.ts +13 -0
- package/dist/legal-checks/index.d.ts.map +1 -0
- package/dist/legal-checks/index.js +6 -0
- package/dist/legal-checks/risk-classifier.d.ts +35 -0
- package/dist/legal-checks/risk-classifier.d.ts.map +1 -0
- package/dist/legal-checks/risk-classifier.js +234 -0
- package/dist/legal-checks/robustness-transparency.d.ts +45 -0
- package/dist/legal-checks/robustness-transparency.d.ts.map +1 -0
- package/dist/legal-checks/robustness-transparency.js +111 -0
- package/dist/metrics/crows-pairs-bias.d.ts +41 -0
- package/dist/metrics/crows-pairs-bias.d.ts.map +1 -0
- package/dist/metrics/crows-pairs-bias.js +172 -0
- package/dist/metrics/index.d.ts +6 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +5 -0
- package/dist/metrics/stereotype-bias.d.ts +89 -0
- package/dist/metrics/stereotype-bias.d.ts.map +1 -0
- package/dist/metrics/stereotype-bias.js +157 -0
- package/dist/risk-engine.d.ts +23 -0
- package/dist/risk-engine.d.ts.map +1 -0
- package/dist/risk-engine.js +451 -0
- package/dist/types.d.ts +131 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/package.json +28 -0
- package/src/fairness-metrics.ts +498 -0
- package/src/index.ts +150 -0
- package/src/inference/browser-inference.ts +258 -0
- package/src/inference/capability-detection.ts +714 -0
- package/src/inference/index.ts +156 -0
- package/src/inference/inference-factory.ts +222 -0
- package/src/inference/ollama-client.ts +514 -0
- package/src/inference/transformers.d.ts +62 -0
- package/src/legal-checks/annex-iv-report.ts +157 -0
- package/src/legal-checks/bias-metrics.ts +590 -0
- package/src/legal-checks/data-governance.ts +148 -0
- package/src/legal-checks/human-oversight-logging.ts +135 -0
- package/src/legal-checks/index.ts +55 -0
- package/src/legal-checks/risk-classifier.ts +285 -0
- package/src/legal-checks/robustness-transparency.ts +162 -0
- package/src/metrics/crows-pairs-bias.ts +245 -0
- package/src/metrics/index.ts +22 -0
- package/src/metrics/stereotype-bias.ts +267 -0
- package/src/risk-engine.ts +525 -0
- package/src/types.ts +154 -0
- package/tests/annex-iv-report.test.ts +323 -0
- package/tests/crows-pairs-bias.test.ts +342 -0
- package/tests/fairness-metrics.test.ts +187 -0
- package/tests/integration/bias-calculation.integration.test.ts +688 -0
- package/tests/legal-checks.test.ts +53 -0
- package/tests/ollama-client.test.ts +427 -0
- package/tests/risk-engine.test.ts +149 -0
- package/tsconfig.json +11 -0
- package/vitest.config.ts +17 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inference Factory
|
|
3
|
+
* Auto-detects available inference engines and provides unified interface
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
BROWSER_MODELS,
|
|
8
|
+
BrowserInference,
|
|
9
|
+
type BrowserModel,
|
|
10
|
+
checkWebGPU,
|
|
11
|
+
} from "./browser-inference";
|
|
12
|
+
import { OllamaClient, type OllamaModel, detectOllama, listOllamaModels } from "./ollama-client";
|
|
13
|
+
|
|
14
|
+
export type InferenceEngine = "ollama" | "browser" | "demo";
|
|
15
|
+
|
|
16
|
+
export interface InferenceCapabilities {
|
|
17
|
+
ollama: {
|
|
18
|
+
available: boolean;
|
|
19
|
+
models: OllamaModel[];
|
|
20
|
+
};
|
|
21
|
+
browser: {
|
|
22
|
+
available: boolean;
|
|
23
|
+
webgpu: boolean;
|
|
24
|
+
models: BrowserModel[];
|
|
25
|
+
};
|
|
26
|
+
recommended: InferenceEngine;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface InferenceClient {
|
|
30
|
+
engine: InferenceEngine;
|
|
31
|
+
modelId: string;
|
|
32
|
+
generate(prompt: string): Promise<string>;
|
|
33
|
+
getLogProb(prompt: string): Promise<number>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Detect all available inference capabilities
|
|
38
|
+
*/
|
|
39
|
+
export async function detectCapabilities(): Promise<InferenceCapabilities> {
|
|
40
|
+
const [ollamaAvailable, webgpuAvailable, ollamaModels] = await Promise.all([
|
|
41
|
+
detectOllama(),
|
|
42
|
+
checkWebGPU(),
|
|
43
|
+
detectOllama().then((ok) => (ok ? listOllamaModels() : [])),
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
// Determine recommended engine
|
|
47
|
+
let recommended: InferenceEngine = "demo";
|
|
48
|
+
if (ollamaAvailable && ollamaModels.length > 0) {
|
|
49
|
+
recommended = "ollama";
|
|
50
|
+
} else if (webgpuAvailable) {
|
|
51
|
+
recommended = "browser";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
ollama: {
|
|
56
|
+
available: ollamaAvailable,
|
|
57
|
+
models: ollamaModels,
|
|
58
|
+
},
|
|
59
|
+
browser: {
|
|
60
|
+
available: webgpuAvailable || true, // CPU fallback always available
|
|
61
|
+
webgpu: webgpuAvailable,
|
|
62
|
+
models: BROWSER_MODELS,
|
|
63
|
+
},
|
|
64
|
+
recommended,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Create an inference client for the specified engine
|
|
70
|
+
*/
|
|
71
|
+
export function createInferenceClient(
|
|
72
|
+
engine: InferenceEngine,
|
|
73
|
+
modelId: string,
|
|
74
|
+
statusCallback?: (status: string) => void
|
|
75
|
+
): InferenceClient {
|
|
76
|
+
switch (engine) {
|
|
77
|
+
case "ollama": {
|
|
78
|
+
const ollamaClient = new OllamaClient(modelId);
|
|
79
|
+
return {
|
|
80
|
+
engine: "ollama",
|
|
81
|
+
modelId,
|
|
82
|
+
generate: (prompt: string) => ollamaClient.generate(prompt),
|
|
83
|
+
getLogProb: (prompt: string) => ollamaClient.getLogProb(prompt),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case "browser": {
|
|
88
|
+
const browserClient = new BrowserInference(modelId, statusCallback);
|
|
89
|
+
return {
|
|
90
|
+
engine: "browser",
|
|
91
|
+
modelId,
|
|
92
|
+
generate: (prompt: string) => browserClient.generate(prompt),
|
|
93
|
+
getLogProb: (prompt: string) => browserClient.getLogProb(prompt),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
default:
|
|
97
|
+
// Demo mode returns simulated results
|
|
98
|
+
return {
|
|
99
|
+
engine: "demo",
|
|
100
|
+
modelId: "demo-model",
|
|
101
|
+
generate: async (prompt: string) => {
|
|
102
|
+
await new Promise((r) => setTimeout(r, 500)); // Simulate latency
|
|
103
|
+
return `[Demo] Response to: ${prompt.slice(0, 50)}...`;
|
|
104
|
+
},
|
|
105
|
+
getLogProb: async () => {
|
|
106
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
107
|
+
// Return random value between -5 and 0 for demo
|
|
108
|
+
return -Math.random() * 5;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Auto-select the best available inference client
|
|
116
|
+
*/
|
|
117
|
+
export async function createAutoInferenceClient(preferredModel?: string): Promise<InferenceClient> {
|
|
118
|
+
const capabilities = await detectCapabilities();
|
|
119
|
+
|
|
120
|
+
if (capabilities.recommended === "ollama") {
|
|
121
|
+
// Use preferred model if available, otherwise first model
|
|
122
|
+
const model = preferredModel || capabilities.ollama.models[0]?.name || "llama3.2:3b";
|
|
123
|
+
return createInferenceClient("ollama", model);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (capabilities.recommended === "browser") {
|
|
127
|
+
const model = preferredModel || BROWSER_MODELS[0]?.id || "Xenova/distilgpt2";
|
|
128
|
+
return createInferenceClient("browser", model);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return createInferenceClient("demo", "demo-model");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Re-export types and utilities
|
|
135
|
+
export { detectOllama, listOllamaModels, OllamaClient } from "./ollama-client";
|
|
136
|
+
export { BrowserInference, checkWebGPU, BROWSER_MODELS } from "./browser-inference";
|
|
137
|
+
export {
|
|
138
|
+
InferenceFactory,
|
|
139
|
+
createInferenceFactory,
|
|
140
|
+
detectBestMethodForConfig,
|
|
141
|
+
type InferenceResult,
|
|
142
|
+
} from "./inference-factory";
|
|
143
|
+
export {
|
|
144
|
+
createCapabilityDetectionService,
|
|
145
|
+
DefaultCapabilityDetectionService,
|
|
146
|
+
EnhancedCapabilityDetectionService,
|
|
147
|
+
type CapabilityDetectionService,
|
|
148
|
+
type ModelCapability,
|
|
149
|
+
type ModelSelectionState,
|
|
150
|
+
type CapabilityCacheEntry,
|
|
151
|
+
type DetectionProgress,
|
|
152
|
+
type UserPreferences,
|
|
153
|
+
type EnhancedModelSelectionState,
|
|
154
|
+
type CapabilityDetectionStatus,
|
|
155
|
+
} from "./capability-detection";
|
|
156
|
+
export type { OllamaModel, BrowserModel };
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inference Factory with Method Detection
|
|
3
|
+
* Provides unified interface for bias calculations across engines with automatic method detection
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { calculateCrowsPairsBias } from "../metrics/crows-pairs-bias";
|
|
7
|
+
import type { BiasCalculationMethod, BiasTestConfig, CrowsPairsBiasResult } from "../types";
|
|
8
|
+
import { BrowserInference } from "./browser-inference";
|
|
9
|
+
import type { ModelCapability } from "./capability-detection";
|
|
10
|
+
import { OllamaClient } from "./ollama-client";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Result wrapper that includes method metadata for all inference operations
|
|
14
|
+
*/
|
|
15
|
+
export interface InferenceResult<T> {
|
|
16
|
+
data: T;
|
|
17
|
+
method: BiasCalculationMethod;
|
|
18
|
+
engine: "browser" | "ollama";
|
|
19
|
+
model: string;
|
|
20
|
+
capability?: ModelCapability;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Inference Factory class that manages inference clients and provides unified interface
|
|
25
|
+
* Automatically detects best available calculation method and returns metadata
|
|
26
|
+
*/
|
|
27
|
+
export class InferenceFactory {
|
|
28
|
+
private browserClient: BrowserInference | null = null;
|
|
29
|
+
private ollamaClient: OllamaClient | null = null;
|
|
30
|
+
private statusCallback: ((status: string) => void) | null = null;
|
|
31
|
+
private selectedCapability: ModelCapability | null = null;
|
|
32
|
+
|
|
33
|
+
constructor(statusCallback?: (status: string) => void) {
|
|
34
|
+
this.statusCallback = statusCallback || null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Set the selected model capability for enhanced metadata tracking
|
|
39
|
+
*/
|
|
40
|
+
setSelectedCapability(capability: ModelCapability): void {
|
|
41
|
+
this.selectedCapability = capability;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Create a bias calculation with automatic method detection
|
|
46
|
+
* Returns InferenceResult with both data and method metadata
|
|
47
|
+
*/
|
|
48
|
+
async createBiasCalculation(
|
|
49
|
+
config: BiasTestConfig
|
|
50
|
+
): Promise<InferenceResult<CrowsPairsBiasResult>> {
|
|
51
|
+
const { engine, model } = config;
|
|
52
|
+
|
|
53
|
+
this.validateConfiguration(config);
|
|
54
|
+
|
|
55
|
+
const inferenceClient = await this.getInferenceClient(engine, model);
|
|
56
|
+
let _detectedMethod: BiasCalculationMethod;
|
|
57
|
+
|
|
58
|
+
if (engine === "browser") {
|
|
59
|
+
_detectedMethod = "logprobs_exact";
|
|
60
|
+
} else {
|
|
61
|
+
// Use capability method if available, otherwise detect
|
|
62
|
+
_detectedMethod =
|
|
63
|
+
this.selectedCapability?.method ?? (await this.detectBestMethod(inferenceClient));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Perform bias calculation
|
|
67
|
+
const biasResult = await calculateCrowsPairsBias(config, inferenceClient);
|
|
68
|
+
|
|
69
|
+
// Return result with metadata including capability information
|
|
70
|
+
return {
|
|
71
|
+
data: biasResult,
|
|
72
|
+
method: biasResult.method, // Use the method determined during calculation
|
|
73
|
+
engine,
|
|
74
|
+
model,
|
|
75
|
+
capability: this.selectedCapability || undefined,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Detect the best available calculation method for the given client
|
|
81
|
+
* Returns the method that should be used for bias calculations
|
|
82
|
+
*/
|
|
83
|
+
private async detectBestMethod(
|
|
84
|
+
client: BrowserInference | OllamaClient
|
|
85
|
+
): Promise<BiasCalculationMethod> {
|
|
86
|
+
if (client instanceof BrowserInference) {
|
|
87
|
+
// Browser inference always supports exact log-probabilities
|
|
88
|
+
return "logprobs_exact";
|
|
89
|
+
}
|
|
90
|
+
if (client instanceof OllamaClient) {
|
|
91
|
+
// Check Ollama's log-probability support
|
|
92
|
+
const supportsLogProbs = await client.detectLogProbSupport();
|
|
93
|
+
return supportsLogProbs ? "logprobs_exact" : "logprobs_fallback_latency";
|
|
94
|
+
}
|
|
95
|
+
throw new Error("Unknown inference client type");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get browser inference client (creates if needed)
|
|
100
|
+
*/
|
|
101
|
+
getBrowserClient(model: string): BrowserInference {
|
|
102
|
+
if (!this.browserClient || this.browserClient.modelId !== model) {
|
|
103
|
+
this.browserClient = new BrowserInference(model, this.statusCallback);
|
|
104
|
+
}
|
|
105
|
+
return this.browserClient;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get Ollama client (creates if needed)
|
|
110
|
+
*/
|
|
111
|
+
getOllamaClient(model: string): OllamaClient {
|
|
112
|
+
if (!this.ollamaClient || this.ollamaClient.model !== model) {
|
|
113
|
+
this.ollamaClient = new OllamaClient(model);
|
|
114
|
+
}
|
|
115
|
+
return this.ollamaClient;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private validateConfiguration(config: BiasTestConfig): void {
|
|
119
|
+
const { engine, model } = config;
|
|
120
|
+
if (!this.selectedCapability) return;
|
|
121
|
+
|
|
122
|
+
if (this.selectedCapability.status !== "available") {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`Selected model ${model} is not available (status: ${this.selectedCapability.status})`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
if (this.selectedCapability.modelId !== model || this.selectedCapability.engine !== engine) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
`Configuration mismatch: expected ${this.selectedCapability.modelId} (${this.selectedCapability.engine}), got ${model} (${engine})`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private async getInferenceClient(engine: "browser" | "ollama", model: string) {
|
|
135
|
+
if (engine === "browser") {
|
|
136
|
+
return this.getBrowserClient(model);
|
|
137
|
+
}
|
|
138
|
+
if (engine === "ollama") {
|
|
139
|
+
return this.getOllamaClient(model);
|
|
140
|
+
}
|
|
141
|
+
throw new Error(`Unsupported engine: ${engine}`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Create inference result wrapper for any data with method detection
|
|
146
|
+
* Useful for wrapping existing inference operations with metadata
|
|
147
|
+
*/
|
|
148
|
+
async createInferenceResult<T>(
|
|
149
|
+
data: T,
|
|
150
|
+
engine: "browser" | "ollama",
|
|
151
|
+
model: string,
|
|
152
|
+
client?: BrowserInference | OllamaClient
|
|
153
|
+
): Promise<InferenceResult<T>> {
|
|
154
|
+
let method: BiasCalculationMethod;
|
|
155
|
+
|
|
156
|
+
// Use capability method if available, otherwise detect
|
|
157
|
+
const selectedMethod = this.selectedCapability?.method;
|
|
158
|
+
if (selectedMethod) {
|
|
159
|
+
method = selectedMethod;
|
|
160
|
+
} else if (engine === "browser") {
|
|
161
|
+
method = "logprobs_exact";
|
|
162
|
+
} else if (engine === "ollama") {
|
|
163
|
+
if (client instanceof OllamaClient) {
|
|
164
|
+
method = await this.detectBestMethod(client);
|
|
165
|
+
} else {
|
|
166
|
+
// Create temporary client for method detection
|
|
167
|
+
const tempClient = new OllamaClient(model);
|
|
168
|
+
method = await this.detectBestMethod(tempClient);
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
throw new Error(`Unsupported engine: ${engine}`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
data,
|
|
176
|
+
method,
|
|
177
|
+
engine,
|
|
178
|
+
model,
|
|
179
|
+
capability: this.selectedCapability || undefined,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Cleanup resources
|
|
185
|
+
*/
|
|
186
|
+
dispose(): void {
|
|
187
|
+
this.browserClient = null;
|
|
188
|
+
this.ollamaClient = null;
|
|
189
|
+
this.statusCallback = null;
|
|
190
|
+
this.selectedCapability = null;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Create a global inference factory instance
|
|
196
|
+
* Provides convenient access to factory methods
|
|
197
|
+
*/
|
|
198
|
+
export function createInferenceFactory(
|
|
199
|
+
statusCallback?: (status: string) => void
|
|
200
|
+
): InferenceFactory {
|
|
201
|
+
return new InferenceFactory(statusCallback);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Utility function to detect best method for a given configuration
|
|
206
|
+
* Useful for pre-flight checks without creating full factory
|
|
207
|
+
*/
|
|
208
|
+
export async function detectBestMethodForConfig(
|
|
209
|
+
config: BiasTestConfig
|
|
210
|
+
): Promise<BiasCalculationMethod> {
|
|
211
|
+
const { engine, model } = config;
|
|
212
|
+
|
|
213
|
+
if (engine === "browser") {
|
|
214
|
+
return "logprobs_exact";
|
|
215
|
+
}
|
|
216
|
+
if (engine === "ollama") {
|
|
217
|
+
const client = new OllamaClient(model);
|
|
218
|
+
const supportsLogProbs = await client.detectLogProbSupport();
|
|
219
|
+
return supportsLogProbs ? "logprobs_exact" : "logprobs_fallback_latency";
|
|
220
|
+
}
|
|
221
|
+
throw new Error(`Unsupported engine: ${engine}`);
|
|
222
|
+
}
|