@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.
Files changed (89) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/LICENSE +21 -0
  3. package/dist/fairness-metrics.d.ts +65 -0
  4. package/dist/fairness-metrics.d.ts.map +1 -0
  5. package/dist/fairness-metrics.js +394 -0
  6. package/dist/index.d.ts +14 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +17 -0
  9. package/dist/inference/browser-inference.d.ts +60 -0
  10. package/dist/inference/browser-inference.d.ts.map +1 -0
  11. package/dist/inference/browser-inference.js +221 -0
  12. package/dist/inference/capability-detection.d.ts +183 -0
  13. package/dist/inference/capability-detection.d.ts.map +1 -0
  14. package/dist/inference/capability-detection.js +552 -0
  15. package/dist/inference/index.d.ts +43 -0
  16. package/dist/inference/index.d.ts.map +1 -0
  17. package/dist/inference/index.js +97 -0
  18. package/dist/inference/inference-factory.d.ts +73 -0
  19. package/dist/inference/inference-factory.d.ts.map +1 -0
  20. package/dist/inference/inference-factory.js +175 -0
  21. package/dist/inference/ollama-client.d.ts +114 -0
  22. package/dist/inference/ollama-client.d.ts.map +1 -0
  23. package/dist/inference/ollama-client.js +386 -0
  24. package/dist/legal-checks/annex-iv-report.d.ts +131 -0
  25. package/dist/legal-checks/annex-iv-report.d.ts.map +1 -0
  26. package/dist/legal-checks/annex-iv-report.js +62 -0
  27. package/dist/legal-checks/bias-metrics.d.ts +162 -0
  28. package/dist/legal-checks/bias-metrics.d.ts.map +1 -0
  29. package/dist/legal-checks/bias-metrics.js +408 -0
  30. package/dist/legal-checks/data-governance.d.ts +30 -0
  31. package/dist/legal-checks/data-governance.d.ts.map +1 -0
  32. package/dist/legal-checks/data-governance.js +99 -0
  33. package/dist/legal-checks/human-oversight-logging.d.ts +27 -0
  34. package/dist/legal-checks/human-oversight-logging.d.ts.map +1 -0
  35. package/dist/legal-checks/human-oversight-logging.js +106 -0
  36. package/dist/legal-checks/index.d.ts +13 -0
  37. package/dist/legal-checks/index.d.ts.map +1 -0
  38. package/dist/legal-checks/index.js +6 -0
  39. package/dist/legal-checks/risk-classifier.d.ts +35 -0
  40. package/dist/legal-checks/risk-classifier.d.ts.map +1 -0
  41. package/dist/legal-checks/risk-classifier.js +234 -0
  42. package/dist/legal-checks/robustness-transparency.d.ts +45 -0
  43. package/dist/legal-checks/robustness-transparency.d.ts.map +1 -0
  44. package/dist/legal-checks/robustness-transparency.js +111 -0
  45. package/dist/metrics/crows-pairs-bias.d.ts +41 -0
  46. package/dist/metrics/crows-pairs-bias.d.ts.map +1 -0
  47. package/dist/metrics/crows-pairs-bias.js +172 -0
  48. package/dist/metrics/index.d.ts +6 -0
  49. package/dist/metrics/index.d.ts.map +1 -0
  50. package/dist/metrics/index.js +5 -0
  51. package/dist/metrics/stereotype-bias.d.ts +89 -0
  52. package/dist/metrics/stereotype-bias.d.ts.map +1 -0
  53. package/dist/metrics/stereotype-bias.js +157 -0
  54. package/dist/risk-engine.d.ts +23 -0
  55. package/dist/risk-engine.d.ts.map +1 -0
  56. package/dist/risk-engine.js +451 -0
  57. package/dist/types.d.ts +131 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/dist/types.js +5 -0
  60. package/package.json +28 -0
  61. package/src/fairness-metrics.ts +498 -0
  62. package/src/index.ts +150 -0
  63. package/src/inference/browser-inference.ts +258 -0
  64. package/src/inference/capability-detection.ts +714 -0
  65. package/src/inference/index.ts +156 -0
  66. package/src/inference/inference-factory.ts +222 -0
  67. package/src/inference/ollama-client.ts +514 -0
  68. package/src/inference/transformers.d.ts +62 -0
  69. package/src/legal-checks/annex-iv-report.ts +157 -0
  70. package/src/legal-checks/bias-metrics.ts +590 -0
  71. package/src/legal-checks/data-governance.ts +148 -0
  72. package/src/legal-checks/human-oversight-logging.ts +135 -0
  73. package/src/legal-checks/index.ts +55 -0
  74. package/src/legal-checks/risk-classifier.ts +285 -0
  75. package/src/legal-checks/robustness-transparency.ts +162 -0
  76. package/src/metrics/crows-pairs-bias.ts +245 -0
  77. package/src/metrics/index.ts +22 -0
  78. package/src/metrics/stereotype-bias.ts +267 -0
  79. package/src/risk-engine.ts +525 -0
  80. package/src/types.ts +154 -0
  81. package/tests/annex-iv-report.test.ts +323 -0
  82. package/tests/crows-pairs-bias.test.ts +342 -0
  83. package/tests/fairness-metrics.test.ts +187 -0
  84. package/tests/integration/bias-calculation.integration.test.ts +688 -0
  85. package/tests/legal-checks.test.ts +53 -0
  86. package/tests/ollama-client.test.ts +427 -0
  87. package/tests/risk-engine.test.ts +149 -0
  88. package/tsconfig.json +11 -0
  89. 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
+ }