network-ai 5.12.7 → 5.13.1

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 (77) hide show
  1. package/INTEGRATION_GUIDE.md +2 -2
  2. package/README.md +67 -11
  3. package/SKILL.md +9 -6
  4. package/dist/adapters/anthropic-messages-adapter.d.ts +141 -0
  5. package/dist/adapters/anthropic-messages-adapter.d.ts.map +1 -0
  6. package/dist/adapters/anthropic-messages-adapter.js +218 -0
  7. package/dist/adapters/anthropic-messages-adapter.js.map +1 -0
  8. package/dist/adapters/index.d.ts +2 -0
  9. package/dist/adapters/index.d.ts.map +1 -1
  10. package/dist/adapters/index.js +6 -1
  11. package/dist/adapters/index.js.map +1 -1
  12. package/dist/esm/adapters/anthropic-messages-adapter.js +218 -0
  13. package/dist/esm/adapters/anthropic-messages-adapter.js.map +1 -0
  14. package/dist/esm/adapters/index.js +6 -1
  15. package/dist/esm/adapters/index.js.map +1 -1
  16. package/dist/esm/index.js +30 -1
  17. package/dist/esm/index.js.map +1 -1
  18. package/dist/esm/lib/effort-policy.js +107 -0
  19. package/dist/esm/lib/effort-policy.js.map +1 -0
  20. package/dist/esm/lib/fan-out.js +47 -14
  21. package/dist/esm/lib/fan-out.js.map +1 -1
  22. package/dist/esm/lib/goal-decomposer.js +79 -10
  23. package/dist/esm/lib/goal-decomposer.js.map +1 -1
  24. package/dist/esm/lib/model-budget.js +167 -0
  25. package/dist/esm/lib/model-budget.js.map +1 -0
  26. package/dist/esm/lib/model-gateway.js +243 -0
  27. package/dist/esm/lib/model-gateway.js.map +1 -0
  28. package/dist/esm/lib/owasp-compliance.js +167 -0
  29. package/dist/esm/lib/owasp-compliance.js.map +1 -0
  30. package/dist/esm/lib/retry-budget.js +75 -0
  31. package/dist/esm/lib/retry-budget.js.map +1 -0
  32. package/dist/esm/lib/telemetry-provider.js +109 -1
  33. package/dist/esm/lib/telemetry-provider.js.map +1 -1
  34. package/dist/esm/lib/thinking-blocks.js +106 -0
  35. package/dist/esm/lib/thinking-blocks.js.map +1 -0
  36. package/dist/index.d.ts +16 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +30 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/lib/effort-policy.d.ts +88 -0
  41. package/dist/lib/effort-policy.d.ts.map +1 -0
  42. package/dist/lib/effort-policy.js +107 -0
  43. package/dist/lib/effort-policy.js.map +1 -0
  44. package/dist/lib/fan-out.d.ts +17 -0
  45. package/dist/lib/fan-out.d.ts.map +1 -1
  46. package/dist/lib/fan-out.js +47 -14
  47. package/dist/lib/fan-out.js.map +1 -1
  48. package/dist/lib/goal-decomposer.d.ts +18 -0
  49. package/dist/lib/goal-decomposer.d.ts.map +1 -1
  50. package/dist/lib/goal-decomposer.js +79 -10
  51. package/dist/lib/goal-decomposer.js.map +1 -1
  52. package/dist/lib/model-budget.d.ts +144 -0
  53. package/dist/lib/model-budget.d.ts.map +1 -0
  54. package/dist/lib/model-budget.js +167 -0
  55. package/dist/lib/model-budget.js.map +1 -0
  56. package/dist/lib/model-gateway.d.ts +252 -0
  57. package/dist/lib/model-gateway.d.ts.map +1 -0
  58. package/dist/lib/model-gateway.js +243 -0
  59. package/dist/lib/model-gateway.js.map +1 -0
  60. package/dist/lib/owasp-compliance.d.ts +57 -0
  61. package/dist/lib/owasp-compliance.d.ts.map +1 -0
  62. package/dist/lib/owasp-compliance.js +167 -0
  63. package/dist/lib/owasp-compliance.js.map +1 -0
  64. package/dist/lib/retry-budget.d.ts +51 -0
  65. package/dist/lib/retry-budget.d.ts.map +1 -0
  66. package/dist/lib/retry-budget.js +75 -0
  67. package/dist/lib/retry-budget.js.map +1 -0
  68. package/dist/lib/telemetry-provider.d.ts +72 -0
  69. package/dist/lib/telemetry-provider.d.ts.map +1 -1
  70. package/dist/lib/telemetry-provider.js +109 -1
  71. package/dist/lib/telemetry-provider.js.map +1 -1
  72. package/dist/lib/thinking-blocks.d.ts +77 -0
  73. package/dist/lib/thinking-blocks.d.ts.map +1 -0
  74. package/dist/lib/thinking-blocks.js +106 -0
  75. package/dist/lib/thinking-blocks.js.map +1 -0
  76. package/package.json +3 -3
  77. package/socket.json +8 -0
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ /**
3
+ * GovernedModelGateway — model-interaction lifecycle governance.
4
+ *
5
+ * Absorbs a frontier model's refusal → fallback → billing complexity and
6
+ * presents one governed, budgeted, audited interface. When the primary model
7
+ * declines a request with a classifier refusal (`stop_reason: "refusal"`), the
8
+ * gateway:
9
+ *
10
+ * 1. records the refusal (which classifier `category` fired) to the audit sink,
11
+ * 2. emits a refusal signal to telemetry (a refusal is an HTTP 200, *not* an
12
+ * error — it is invisible to error-rate monitoring),
13
+ * 3. retries on the next model in the fallback chain, redeeming the one-time
14
+ * fallback-credit token so the retry is repriced as a cache read,
15
+ * 4. strips model-specific thinking blocks when it switches models (unless a
16
+ * credit is being redeemed, which requires an exact body match),
17
+ * 5. accounts each attempt's cost against the cross-model budget.
18
+ *
19
+ * This layer is **provider-agnostic**. It operates on a normalized
20
+ * {@link ModelCaller}; the concrete provider binding (e.g. the Anthropic
21
+ * Messages adapter) maps the native API to these shapes. Unlike
22
+ * `AdapterRegistry.fallbackChain` — which fails over on adapter *health*
23
+ * (`CircuitOpenError`) — this gateway falls over on a *classifier refusal*.
24
+ *
25
+ * @module GovernedModelGateway
26
+ * @version 1.0.0
27
+ * @license MIT
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.GovernedModelGateway = void 0;
31
+ exports.isRefusal = isRefusal;
32
+ // ============================================================================
33
+ // HELPERS
34
+ // ============================================================================
35
+ /** Whether a response is a classifier refusal. Branch on this, not on content. */
36
+ function isRefusal(response) {
37
+ return response.stopReason === 'refusal';
38
+ }
39
+ // ============================================================================
40
+ // GATEWAY
41
+ // ============================================================================
42
+ /**
43
+ * Governs the full model-interaction lifecycle: refusal detection, cross-model
44
+ * fallback, fallback-credit redemption, thinking-block handoff, and per-attempt
45
+ * cost accounting — behind one {@link GovernedModelGateway.send} call.
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const gateway = new GovernedModelGateway({
50
+ * caller, // provider binding (e.g. Anthropic adapter)
51
+ * primaryModel: 'claude-fable-5',
52
+ * fallbackModels: ['claude-opus-4-8'],
53
+ * budget, audit, telemetry, thinking, effort,
54
+ * });
55
+ *
56
+ * const r = await gateway.send({ messages: [{ role: 'user', content: 'hi' }] });
57
+ * console.log(r.servedModel, r.servedByFallback, r.totalCostUsd);
58
+ * ```
59
+ */
60
+ class GovernedModelGateway {
61
+ caller;
62
+ primaryModel;
63
+ fallbackModels;
64
+ defaultEffort;
65
+ maxFallbacks;
66
+ allowedFallbacks;
67
+ budget;
68
+ audit;
69
+ telemetry;
70
+ thinking;
71
+ effortPolicy;
72
+ constructor(config) {
73
+ if (typeof config.caller !== 'function') {
74
+ throw new TypeError('GovernedModelGateway: caller must be a function');
75
+ }
76
+ if (!config.primaryModel || typeof config.primaryModel !== 'string') {
77
+ throw new TypeError('GovernedModelGateway: primaryModel must be a non-empty string');
78
+ }
79
+ this.caller = config.caller;
80
+ this.primaryModel = config.primaryModel;
81
+ this.fallbackModels = (config.fallbackModels ?? []).filter((m) => m && m !== config.primaryModel);
82
+ this.defaultEffort = config.defaultEffort;
83
+ this.maxFallbacks = config.maxFallbacks ?? this.fallbackModels.length;
84
+ this.allowedFallbacks = config.allowedFallbacks;
85
+ this.budget = config.budget;
86
+ this.audit = config.audit;
87
+ this.telemetry = config.telemetry;
88
+ this.thinking = config.thinking;
89
+ this.effortPolicy = config.effort;
90
+ }
91
+ /**
92
+ * Send a request through the governed lifecycle.
93
+ *
94
+ * Tries the primary model, then walks the fallback chain on each refusal,
95
+ * redeeming fallback credit and stripping cross-model thinking blocks as it
96
+ * goes. Returns once a model serves the turn or the chain is exhausted.
97
+ *
98
+ * @param request The request. The gateway selects the model(s).
99
+ * @returns A {@link GovernedModelResult} describing every attempt.
100
+ */
101
+ async send(request) {
102
+ if (!request || !Array.isArray(request.messages)) {
103
+ throw new TypeError('GovernedModelGateway.send: request.messages must be an array');
104
+ }
105
+ const agentId = request.agentId;
106
+ const effort = this.resolveEffort(request.effort, agentId);
107
+ const chain = this.buildChain();
108
+ const attempts = [];
109
+ const categories = [];
110
+ let totalCostUsd;
111
+ let lastResponse;
112
+ let creditToken;
113
+ for (let i = 0; i < chain.length; i++) {
114
+ const model = chain[i];
115
+ const isFallback = i > 0;
116
+ const redeeming = Boolean(creditToken);
117
+ // When redeeming a credit the body must match the refused request exactly,
118
+ // so thinking blocks stay. Otherwise, strip them on a model switch.
119
+ const messages = isFallback && !redeeming && this.thinking
120
+ ? this.thinking.stripForModelSwitch(request.messages)
121
+ : request.messages;
122
+ const req = {
123
+ model,
124
+ messages,
125
+ system: request.system,
126
+ maxTokens: request.maxTokens,
127
+ tools: request.tools,
128
+ effort,
129
+ fallbackCreditToken: creditToken,
130
+ metadata: request.metadata,
131
+ };
132
+ const response = await this.caller(req);
133
+ lastResponse = response;
134
+ const refusal = isRefusal(response);
135
+ const category = refusal ? response.refusal?.category ?? null : null;
136
+ // Cost accounting (per attempt — never sum tokens across models).
137
+ let costUsd;
138
+ let budgetAllowed = true;
139
+ if (this.budget) {
140
+ const rec = this.budget.recordAttempt(response.model, response.usage, {
141
+ creditRedeemed: redeeming,
142
+ agentId,
143
+ });
144
+ costUsd = rec.costUsd;
145
+ budgetAllowed = rec.allowed;
146
+ totalCostUsd = (totalCostUsd ?? 0) + rec.costUsd;
147
+ }
148
+ attempts.push({
149
+ model: response.model,
150
+ stopReason: response.stopReason,
151
+ refusalCategory: category,
152
+ usage: response.usage,
153
+ costUsd,
154
+ servedByFallback: isFallback,
155
+ creditRedeemed: redeeming,
156
+ });
157
+ await this.auditAttempt(agentId, response, isFallback, redeeming, costUsd);
158
+ if (!refusal) {
159
+ // A model served the turn.
160
+ if (isFallback) {
161
+ this.telemetry?.recordFallbackServed({
162
+ requestedModel: this.primaryModel,
163
+ servedModel: response.model,
164
+ agentId,
165
+ });
166
+ }
167
+ return {
168
+ response,
169
+ servedModel: response.model,
170
+ refused: false,
171
+ servedByFallback: isFallback,
172
+ attempts,
173
+ refusalCategories: categories,
174
+ totalCostUsd,
175
+ };
176
+ }
177
+ // Refusal: record the signal (refusal !== error), capture credit, continue.
178
+ categories.push(category);
179
+ this.telemetry?.recordRefusal({ model: response.model, category, agentId });
180
+ creditToken = response.refusal?.fallbackCreditToken ?? undefined;
181
+ if (!budgetAllowed)
182
+ break; // budget exhausted — stop trying fallbacks
183
+ }
184
+ // Every model in the chain refused (or the budget stopped us).
185
+ const finalResponse = lastResponse ?? {
186
+ model: this.primaryModel,
187
+ content: [],
188
+ stopReason: 'refusal',
189
+ usage: { inputTokens: 0, outputTokens: 0 },
190
+ };
191
+ return {
192
+ response: finalResponse,
193
+ servedModel: finalResponse.model,
194
+ refused: true,
195
+ servedByFallback: false,
196
+ attempts,
197
+ refusalCategories: categories,
198
+ totalCostUsd,
199
+ };
200
+ }
201
+ /** The ordered model chain: primary followed by permitted fallbacks. */
202
+ buildChain() {
203
+ let fallbacks = this.fallbackModels;
204
+ if (this.allowedFallbacks) {
205
+ const permitted = this.allowedFallbacks[this.primaryModel];
206
+ if (permitted) {
207
+ fallbacks = fallbacks.filter((m) => permitted.includes(m));
208
+ }
209
+ }
210
+ return [this.primaryModel, ...fallbacks.slice(0, Math.max(0, this.maxFallbacks))];
211
+ }
212
+ resolveEffort(requested, agentId) {
213
+ if (this.effortPolicy) {
214
+ return this.effortPolicy.resolve(requested ?? this.defaultEffort, { agentId });
215
+ }
216
+ return requested ?? this.defaultEffort;
217
+ }
218
+ async auditAttempt(agentId, response, isFallback, creditRedeemed, costUsd) {
219
+ if (!this.audit)
220
+ return;
221
+ const refusal = isRefusal(response);
222
+ try {
223
+ await this.audit.log({
224
+ event: refusal ? 'model.refusal' : 'model.attempt',
225
+ agentId: agentId ?? null,
226
+ model: response.model,
227
+ stopReason: response.stopReason,
228
+ refusalCategory: refusal ? response.refusal?.category ?? null : null,
229
+ refusalExplanation: refusal ? response.refusal?.explanation ?? null : undefined,
230
+ servedByFallback: isFallback,
231
+ creditRedeemed,
232
+ costUsd: costUsd ?? null,
233
+ usage: response.usage,
234
+ ts: new Date().toISOString(),
235
+ });
236
+ }
237
+ catch {
238
+ // Audit is best-effort — never break the model lifecycle for logging.
239
+ }
240
+ }
241
+ }
242
+ exports.GovernedModelGateway = GovernedModelGateway;
243
+ //# sourceMappingURL=model-gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-gateway.js","sourceRoot":"","sources":["../../../lib/model-gateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /**
3
+ * OWASP Agentic AI Top 10 (2026) — coverage matrix and verifier.
4
+ *
5
+ * Maps each OWASP Agentic risk category to the deterministic Network-AI control
6
+ * that addresses it, and provides an `agt verify`-style coverage report. Unlike
7
+ * the Python-skill MAESTRO/ASI table in `SKILL.md` (which scopes the bundled
8
+ * scripts), this matrix covers the **TypeScript orchestration engine**.
9
+ *
10
+ * The controls referenced here are existing engine features — not aspirational
11
+ * roadmap items. This module is a single source of truth for the README/SKILL
12
+ * compliance section and for programmatic verification in CI.
13
+ *
14
+ * @module OwaspCompliance
15
+ * @version 1.0.0
16
+ * @license MIT
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.OWASP_AGENTIC_TOP10_2026 = void 0;
20
+ exports.verifyOwaspCoverage = verifyOwaspCoverage;
21
+ exports.formatOwaspReport = formatOwaspReport;
22
+ /**
23
+ * The OWASP Agentic AI Top 10 (2026) mapped to Network-AI engine controls.
24
+ */
25
+ exports.OWASP_AGENTIC_TOP10_2026 = Object.freeze([
26
+ {
27
+ id: 'ASI-01',
28
+ risk: 'Agent Goal Hijack',
29
+ status: 'covered',
30
+ controls: [
31
+ 'AuthGuardian weighted permission gating before sensitive resource access (index.ts)',
32
+ 'JourneyFSM behavioral control plane with ToolAuthorizationMatrix (lib/fsm-journey.ts)',
33
+ 'Scope guard responds directly for simple requests instead of decomposing',
34
+ ],
35
+ },
36
+ {
37
+ id: 'ASI-02',
38
+ risk: 'Tool Misuse & Exploitation',
39
+ status: 'covered',
40
+ controls: [
41
+ 'AgentRuntime SandboxPolicy: command allow-list, shell:false argv execution (lib/agent-runtime.ts)',
42
+ 'ApprovalGate for approval-required operations',
43
+ 'AdapterHookManager beforeExecute matcher-based gating (lib/adapter-hooks.ts)',
44
+ ],
45
+ },
46
+ {
47
+ id: 'ASI-03',
48
+ risk: 'Identity & Privilege Abuse',
49
+ status: 'covered',
50
+ controls: [
51
+ 'SecureTokenManager HMAC-SHA256 / Ed25519 signed tokens with TTL (security.ts)',
52
+ 'AuthGuardian trust scoring (trust 30%) keyed to data/trust_levels.json',
53
+ 'Grant tokens are advisory-only; platform auth required for destructive actions',
54
+ ],
55
+ },
56
+ {
57
+ id: 'ASI-04',
58
+ risk: 'Supply Chain Risks',
59
+ status: 'covered',
60
+ controls: [
61
+ 'Single runtime dependency (commander); BYOC adapters add none',
62
+ 'socket.json capability declarations + scripts/socket-check.js pre-publish gate',
63
+ 'scripts/clawhub-check.js bundle hygiene + scripts/codeql-check.js alert gate',
64
+ ],
65
+ },
66
+ {
67
+ id: 'ASI-05',
68
+ risk: 'Unsafe Code Execution',
69
+ status: 'covered',
70
+ controls: [
71
+ 'AgentRuntime ShellExecutor: tokenized argv, shell-metacharacter rejection, no /bin/sh -c (lib/agent-runtime.ts)',
72
+ 'SourceProtectionError + FileAccessor path-traversal protection',
73
+ 'Per-adapter CircuitBreaker bounds blast radius (lib/circuit-breaker.ts)',
74
+ ],
75
+ },
76
+ {
77
+ id: 'ASI-06',
78
+ risk: 'Memory & Context Poisoning',
79
+ status: 'covered',
80
+ controls: [
81
+ 'LockedBlackboard atomic propose → validate → commit with file-system mutex (lib/locked-blackboard.ts)',
82
+ 'Blackboard validator injection-pattern detection on untrusted content',
83
+ 'ComplianceMonitor real-time behavior surveillance (lib/compliance-monitor.ts)',
84
+ ],
85
+ },
86
+ {
87
+ id: 'ASI-07',
88
+ risk: 'Insecure Inter-Agent Communication',
89
+ status: 'partial',
90
+ controls: [
91
+ 'LockedBlackboard file-system mutex for local coordination origin',
92
+ 'Signed grant tokens (security.ts) authenticate cross-agent handoffs',
93
+ 'Documented boundary: run in a trusted workspace; restrict data/ permissions',
94
+ ],
95
+ },
96
+ {
97
+ id: 'ASI-08',
98
+ risk: 'Cascading Failures',
99
+ status: 'covered',
100
+ controls: [
101
+ 'CircuitBreaker CLOSED/OPEN/HALF_OPEN per adapter with fallbackChain (lib/circuit-breaker.ts)',
102
+ 'FederatedBudget + ModelBudget ceilings bound runaway spend (lib/federated-budget.ts, lib/model-budget.ts)',
103
+ 'GovernedModelGateway + RetryBudget contain refusal-driven retry storms (lib/model-gateway.ts, lib/retry-budget.ts)',
104
+ ],
105
+ },
106
+ {
107
+ id: 'ASI-09',
108
+ risk: 'Human-Agent Trust Exploitation',
109
+ status: 'covered',
110
+ controls: [
111
+ 'ApprovalGate requires human acknowledgment for high-risk actions (lib/agent-runtime.ts)',
112
+ 'AuthGuardian justification scoring (justification 40%) on every grant',
113
+ 'SecureAuditLogger tamper-evident trail of grants and state transitions (security.ts)',
114
+ ],
115
+ },
116
+ {
117
+ id: 'ASI-10',
118
+ risk: 'Rogue Agents',
119
+ status: 'covered',
120
+ controls: [
121
+ 'ComplianceMonitor surveillance flags out-of-policy behavior (lib/compliance-monitor.ts)',
122
+ 'CircuitBreaker isolation + budget ceilings act as a kill switch',
123
+ 'Every write and state transition logged to data/audit_log.jsonl (security.ts)',
124
+ ],
125
+ },
126
+ ]);
127
+ /**
128
+ * Build a coverage report from a control matrix.
129
+ *
130
+ * @param controls The matrix to verify (defaults to {@link OWASP_AGENTIC_TOP10_2026}).
131
+ * @returns Counts plus `allAddressed` (no `not-applicable`-excluded gaps).
132
+ */
133
+ function verifyOwaspCoverage(controls = exports.OWASP_AGENTIC_TOP10_2026) {
134
+ let covered = 0;
135
+ let partial = 0;
136
+ let notApplicable = 0;
137
+ for (const c of controls) {
138
+ if (c.status === 'covered')
139
+ covered++;
140
+ else if (c.status === 'partial')
141
+ partial++;
142
+ else
143
+ notApplicable++;
144
+ }
145
+ const applicable = controls.filter((c) => c.status !== 'not-applicable');
146
+ const allAddressed = applicable.every((c) => c.status === 'covered' || c.status === 'partial');
147
+ return { total: controls.length, covered, partial, notApplicable, controls: [...controls], allAddressed };
148
+ }
149
+ /**
150
+ * Render a coverage report as an `agt verify`-style text block.
151
+ *
152
+ * @param report A report from {@link verifyOwaspCoverage}.
153
+ */
154
+ function formatOwaspReport(report) {
155
+ const lines = [];
156
+ lines.push('Network-AI — OWASP Agentic AI Top 10 (2026) Coverage');
157
+ lines.push('─'.repeat(56));
158
+ for (const c of report.controls) {
159
+ const mark = c.status === 'covered' ? '✅' : c.status === 'partial' ? '🟡' : '⚪';
160
+ lines.push(` ${c.id} ${mark} ${c.risk}`);
161
+ }
162
+ lines.push('─'.repeat(56));
163
+ lines.push(` ${report.covered}/${report.total} covered, ${report.partial} partial`);
164
+ lines.push(` ${report.allAddressed ? 'PASS — all risks addressed' : 'FAIL — gaps present'}`);
165
+ return lines.join('\n');
166
+ }
167
+ //# sourceMappingURL=owasp-compliance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owasp-compliance.js","sourceRoot":"","sources":["../../../lib/owasp-compliance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ /**
3
+ * RetryBudget — per-request retry accounting.
4
+ *
5
+ * Frontier models can refuse independently on the same turn (an orchestrator
6
+ * agent and each of its sub-agents), so retries must be budgeted **per request,
7
+ * not per session**. `RetryBudget` enforces a maximum number of retries for
8
+ * each distinct key (a request id, task id, or sub-agent id) and never shares
9
+ * the allowance across keys — one runaway request cannot starve the others.
10
+ *
11
+ * @module RetryBudget
12
+ * @version 1.0.0
13
+ * @license MIT
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.RetryBudget = void 0;
17
+ /**
18
+ * Per-key retry allowance.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const budget = new RetryBudget({ maxPerKey: 2 });
23
+ * while (budget.tryConsume(requestId)) {
24
+ * const r = await attempt();
25
+ * if (r.ok) break;
26
+ * }
27
+ * ```
28
+ */
29
+ class RetryBudget {
30
+ max;
31
+ consumed = new Map();
32
+ constructor(options) {
33
+ if (typeof options.maxPerKey !== 'number' || options.maxPerKey < 0 || !Number.isInteger(options.maxPerKey)) {
34
+ throw new RangeError('RetryBudget: maxPerKey must be a non-negative integer');
35
+ }
36
+ this.max = options.maxPerKey;
37
+ }
38
+ /**
39
+ * Consume one retry for `key`. Returns `false` (without consuming) once the
40
+ * per-key budget is exhausted.
41
+ *
42
+ * @param key Request/task/sub-agent identifier. Must be a non-empty string.
43
+ */
44
+ tryConsume(key) {
45
+ if (!key || typeof key !== 'string') {
46
+ throw new TypeError('RetryBudget.tryConsume: key must be a non-empty string');
47
+ }
48
+ const used = this.consumed.get(key) ?? 0;
49
+ if (used >= this.max)
50
+ return false;
51
+ this.consumed.set(key, used + 1);
52
+ return true;
53
+ }
54
+ /** Retries already consumed for `key`. */
55
+ used(key) {
56
+ return this.consumed.get(key) ?? 0;
57
+ }
58
+ /** Retries still available for `key`. */
59
+ remaining(key) {
60
+ return Math.max(0, this.max - (this.consumed.get(key) ?? 0));
61
+ }
62
+ /** The configured per-key maximum. */
63
+ getMax() {
64
+ return this.max;
65
+ }
66
+ /** Reset one key, or all keys when `key` is omitted. */
67
+ reset(key) {
68
+ if (key === undefined)
69
+ this.consumed.clear();
70
+ else
71
+ this.consumed.delete(key);
72
+ }
73
+ }
74
+ exports.RetryBudget = RetryBudget;
75
+ //# sourceMappingURL=retry-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-budget.js","sourceRoot":"","sources":["../../../lib/retry-budget.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AAQH;;;;;;;;;;;GAWG;AACH,MAAa,WAAW;IACL,GAAG,CAAS;IACZ,QAAQ,GAAwB,IAAI,GAAG,EAAE,CAAC;IAE3D,YAAY,OAA2B;QACrC,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,IAAI,OAAO,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3G,MAAM,IAAI,UAAU,CAAC,uDAAuD,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,GAAW;QACpB,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACpC,MAAM,IAAI,SAAS,CAAC,wDAAwD,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0CAA0C;IAC1C,IAAI,CAAC,GAAW;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,yCAAyC;IACzC,SAAS,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,sCAAsC;IACtC,MAAM;QACJ,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;IAED,wDAAwD;IACxD,KAAK,CAAC,GAAY;QAChB,IAAI,GAAG,KAAK,SAAS;YAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;;YACxC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;CACF;AA/CD,kCA+CC"}
@@ -48,7 +48,7 @@
48
48
  * ```
49
49
  */
50
50
  Object.defineProperty(exports, "__esModule", { value: true });
51
- exports.CapturingTelemetryProvider = exports.NullTelemetryProvider = void 0;
51
+ exports.RefusalTelemetry = exports.FALLBACK_SERVED_EVENT = exports.REFUSAL_EVENT = exports.CapturingTelemetryProvider = exports.NullTelemetryProvider = void 0;
52
52
  exports.createOtelHooks = createOtelHooks;
53
53
  // ============================================================================
54
54
  // NULL PROVIDER (default — zero overhead when no telemetry is configured)
@@ -204,4 +204,112 @@ function createOtelHooks(provider) {
204
204
  },
205
205
  ];
206
206
  }
207
+ // ============================================================================
208
+ // REFUSAL OBSERVABILITY
209
+ // ============================================================================
210
+ /** Span/event name emitted for a classifier refusal. */
211
+ exports.REFUSAL_EVENT = 'model.refusal';
212
+ /** Span/event name emitted when a fallback model serves a turn. */
213
+ exports.FALLBACK_SERVED_EVENT = 'model.fallback_served';
214
+ /**
215
+ * Refusal/fallback observability.
216
+ *
217
+ * A classifier refusal is a successful **HTTP 200**, so monitoring built on
218
+ * error rates or 5xx responses never sees it. `RefusalTelemetry` records each
219
+ * refusal and each fallback-served response as discrete **non-error** signals,
220
+ * keeps counters, and exposes the gap between them (`unservedRefusalCount`) so
221
+ * you can alert when refusals are not being served by a fallback.
222
+ *
223
+ * It satisfies the `RefusalTelemetrySink` contract consumed by
224
+ * {@link ../lib/model-gateway!GovernedModelGateway}. Pass an
225
+ * {@link ITelemetryProvider} to also emit spans to your tracing backend.
226
+ *
227
+ * @example
228
+ * ```typescript
229
+ * const refusals = new RefusalTelemetry(new CapturingTelemetryProvider());
230
+ * const gateway = new GovernedModelGateway({ caller, primaryModel, fallbackModels, telemetry: refusals });
231
+ * // ...later
232
+ * if (refusals.unservedRefusalCount > 0) alert('refusals are reaching users');
233
+ * ```
234
+ */
235
+ class RefusalTelemetry {
236
+ provider;
237
+ _refusals = 0;
238
+ _fallbackServed = 0;
239
+ _byCategory = new Map();
240
+ _byModel = new Map();
241
+ constructor(provider) {
242
+ this.provider = provider;
243
+ }
244
+ /** Record a classifier refusal (counted as a signal, never as an error). */
245
+ recordRefusal(info) {
246
+ this._refusals++;
247
+ const cat = info.category ?? 'unspecified';
248
+ this._byCategory.set(cat, (this._byCategory.get(cat) ?? 0) + 1);
249
+ this._byModel.set(info.model, (this._byModel.get(info.model) ?? 0) + 1);
250
+ this.emit(exports.REFUSAL_EVENT, { model: info.model, category: cat, agentId: info.agentId ?? '' });
251
+ }
252
+ /** Record that a fallback model served a turn the primary declined. */
253
+ recordFallbackServed(info) {
254
+ this._fallbackServed++;
255
+ this.emit(exports.FALLBACK_SERVED_EVENT, {
256
+ requestedModel: info.requestedModel,
257
+ servedModel: info.servedModel,
258
+ agentId: info.agentId ?? '',
259
+ });
260
+ }
261
+ /** Total refusals observed. */
262
+ get refusalCount() {
263
+ return this._refusals;
264
+ }
265
+ /** Total fallback-served responses observed. */
266
+ get fallbackServedCount() {
267
+ return this._fallbackServed;
268
+ }
269
+ /** Refusals that were never served by a fallback (the gap to alert on). */
270
+ get unservedRefusalCount() {
271
+ return Math.max(0, this._refusals - this._fallbackServed);
272
+ }
273
+ /** Refusal counts keyed by classifier category. */
274
+ byCategory() {
275
+ const out = {};
276
+ for (const [k, v] of this._byCategory)
277
+ out[k] = v;
278
+ return out;
279
+ }
280
+ /** A full counter snapshot. */
281
+ snapshot() {
282
+ const byModel = {};
283
+ for (const [k, v] of this._byModel)
284
+ byModel[k] = v;
285
+ return {
286
+ refusals: this._refusals,
287
+ fallbackServed: this._fallbackServed,
288
+ unservedRefusals: this.unservedRefusalCount,
289
+ byCategory: this.byCategory(),
290
+ byModel,
291
+ };
292
+ }
293
+ /** Reset all counters. */
294
+ reset() {
295
+ this._refusals = 0;
296
+ this._fallbackServed = 0;
297
+ this._byCategory.clear();
298
+ this._byModel.clear();
299
+ }
300
+ /** Emit a discrete non-error span for a refusal/fallback signal. @internal */
301
+ emit(name, attributes) {
302
+ if (!this.provider)
303
+ return;
304
+ try {
305
+ const id = this.provider.startSpan(name, attributes);
306
+ // A refusal is a successful HTTP 200 — close the span 'ok', never 'error'.
307
+ this.provider.endSpan(id, 'ok', attributes);
308
+ }
309
+ catch {
310
+ // Telemetry must never throw.
311
+ }
312
+ }
313
+ }
314
+ exports.RefusalTelemetry = RefusalTelemetry;
207
315
  //# sourceMappingURL=telemetry-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry-provider.js","sourceRoot":"","sources":["../../../lib/telemetry-provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"telemetry-provider.js","sourceRoot":"","sources":["../../../lib/telemetry-provider.ts"],"names":[],"mappings":"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"}