|
1 | | -import { CircuitBreaker } from './circuitBreaker'; |
2 | | -import type { ModelProvider, ModelResponse } from './types'; |
3 | | -import { calculateDemographicParity } from './fairness'; |
4 | | -import { generateCAE } from './interpretability'; |
| 1 | +import { CircuitBreaker } from './circuitBreaker' |
| 2 | +import type { ModelProvider, ModelResponse } from './types' |
| 3 | +import { calculateDemographicParity } from './fairness' |
| 4 | +import { generateCAE } from './interpretability' |
5 | 5 |
|
6 | | -type Intent = 'casual' | 'actionable' | 'analytical' | 'sensitive'; |
7 | | -export type RouteDecision = { intent: Intent; target: 'surface' | 'depth'; reason: string }; |
| 6 | +type Intent = 'casual' | 'actionable' | 'analytical' | 'sensitive' |
| 7 | +export type RouteDecision = { intent: Intent, target: 'surface' | 'depth', reason: string } |
8 | 8 |
|
9 | 9 | export class Orchestrator { |
10 | | - private breakerDepth = new CircuitBreaker(3, 15000); |
11 | | - constructor(private surface: ModelProvider, private depth: ModelProvider, private intentDetect: (msg: string) => Intent) {} |
12 | | - |
13 | | - route(input: string, override?: 'surface' | 'depth'): RouteDecision { |
14 | | - if (override) return { intent: this.intentDetect(input), target: override, reason: 'user_override' }; |
15 | | - const intent = this.intentDetect(input); |
16 | | - const target = intent === 'analytical' ? 'depth' : 'surface'; |
17 | | - return { intent, target, reason: 'policy' }; |
| 10 | + private breakerDepth = new CircuitBreaker(3, 15000) |
| 11 | + constructor (private surface: ModelProvider, private depth: ModelProvider, private intentDetect: (msg: string) => Intent) {} |
| 12 | + |
| 13 | + route (input: string, override?: 'surface' | 'depth'): RouteDecision { |
| 14 | + if (override) return { intent: this.intentDetect(input), target: override, reason: 'user_override' } |
| 15 | + const intent = this.intentDetect(input) |
| 16 | + const target = intent === 'analytical' ? 'depth' : 'surface' |
| 17 | + return { intent, target, reason: 'policy' } |
18 | 18 | } |
19 | 19 |
|
20 | | - async respond(input: string, stream = true): Promise<ModelResponse> { |
21 | | - const decision = this.route(input); |
22 | | - const primary = decision.target === 'depth' ? this.depth : this.surface; |
23 | | - const fallback = decision.target === 'depth' ? this.surface : this.depth; |
| 20 | + async respond (input: string, stream = true): Promise<ModelResponse> { |
| 21 | + const decision = this.route(input) |
| 22 | + const primary = decision.target === 'depth' ? this.depth : this.surface |
| 23 | + const fallback = decision.target === 'depth' ? this.surface : this.depth |
24 | 24 |
|
25 | 25 | if (decision.target === 'depth' && !this.breakerDepth.canPass()) { |
26 | | - return this.surface.invoke(this.decorate(input, { fallback: 'depth_breaker_open' })); |
| 26 | + return this.surface.invoke(this.decorate(input, { fallback: 'depth_breaker_open' })) |
27 | 27 | } |
28 | 28 |
|
29 | 29 | try { |
30 | 30 | const res = stream && primary.supportsStreaming |
31 | 31 | ? await primary.stream(this.decorate(input, decision)) |
32 | | - : await primary.invoke(this.decorate(input, decision)); |
| 32 | + : await primary.invoke(this.decorate(input, decision)) |
33 | 33 |
|
34 | | - if (decision.target === 'depth') this.breakerDepth.recordSuccess(); |
| 34 | + if (decision.target === 'depth') this.breakerDepth.recordSuccess() |
35 | 35 |
|
36 | 36 | // MAS FEAT & HKMA Compliance for MoE expert nodes (depth layer) |
37 | 37 | if (decision.target === 'depth' && res.text) { |
38 | 38 | // MAS FEAT: Demographic Parity |
39 | | - res.meta.fairness = calculateDemographicParity(input, res.text); |
| 39 | + res.meta.fairness = calculateDemographicParity(input, res.text) |
40 | 40 | // HKMA Ethics: Contextual Attribution Envelopes (CAE) |
41 | | - res.meta.cae = generateCAE(input, res.text); |
| 41 | + res.meta.cae = generateCAE(input, res.text) |
42 | 42 | } |
43 | 43 |
|
44 | | - return res; |
| 44 | + return res |
45 | 45 | } catch (e) { |
46 | | - if (decision.target === 'depth') this.breakerDepth.recordFailure(); |
47 | | - return fallback.invoke(this.decorate(input, { fallback: 'primary_failed' })); |
| 46 | + if (decision.target === 'depth') this.breakerDepth.recordFailure() |
| 47 | + return fallback.invoke(this.decorate(input, { fallback: 'primary_failed' })) |
48 | 48 | } |
49 | 49 | } |
50 | 50 |
|
51 | | - private decorate(input: string, meta: Record<string, unknown>): string { |
52 | | - return `<!-- orchestration:${JSON.stringify(meta)} -->\n${input}`; |
| 51 | + private decorate (input: string, meta: Record<string, unknown>): string { |
| 52 | + return `<!-- orchestration:${JSON.stringify(meta)} -->\n${input}` |
53 | 53 | } |
54 | 54 | } |
0 commit comments