@beingmartinbmc/ojas 0.2.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 (174) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +308 -0
  3. package/dist/aahar/index.d.ts +179 -0
  4. package/dist/aahar/index.d.ts.map +1 -0
  5. package/dist/aahar/index.js +657 -0
  6. package/dist/aahar/index.js.map +1 -0
  7. package/dist/aahar/scoring.d.ts +85 -0
  8. package/dist/aahar/scoring.d.ts.map +1 -0
  9. package/dist/aahar/scoring.js +268 -0
  10. package/dist/aahar/scoring.js.map +1 -0
  11. package/dist/agni/index.d.ts +113 -0
  12. package/dist/agni/index.d.ts.map +1 -0
  13. package/dist/agni/index.js +328 -0
  14. package/dist/agni/index.js.map +1 -0
  15. package/dist/agni/model-router.d.ts +77 -0
  16. package/dist/agni/model-router.d.ts.map +1 -0
  17. package/dist/agni/model-router.js +163 -0
  18. package/dist/agni/model-router.js.map +1 -0
  19. package/dist/agni/response-distiller.d.ts +37 -0
  20. package/dist/agni/response-distiller.d.ts.map +1 -0
  21. package/dist/agni/response-distiller.js +193 -0
  22. package/dist/agni/response-distiller.js.map +1 -0
  23. package/dist/agni/tiktoken-adapter.d.ts +55 -0
  24. package/dist/agni/tiktoken-adapter.d.ts.map +1 -0
  25. package/dist/agni/tiktoken-adapter.js +113 -0
  26. package/dist/agni/tiktoken-adapter.js.map +1 -0
  27. package/dist/chikitsa/index.d.ts +130 -0
  28. package/dist/chikitsa/index.d.ts.map +1 -0
  29. package/dist/chikitsa/index.js +565 -0
  30. package/dist/chikitsa/index.js.map +1 -0
  31. package/dist/demo.d.ts +15 -0
  32. package/dist/demo.d.ts.map +1 -0
  33. package/dist/demo.js +278 -0
  34. package/dist/demo.js.map +1 -0
  35. package/dist/index.d.ts +201 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +588 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/mcp/audit.d.ts +39 -0
  40. package/dist/mcp/audit.d.ts.map +1 -0
  41. package/dist/mcp/audit.js +73 -0
  42. package/dist/mcp/audit.js.map +1 -0
  43. package/dist/mcp/contracts.d.ts +76 -0
  44. package/dist/mcp/contracts.d.ts.map +1 -0
  45. package/dist/mcp/contracts.js +44 -0
  46. package/dist/mcp/contracts.js.map +1 -0
  47. package/dist/mcp/envelope.d.ts +107 -0
  48. package/dist/mcp/envelope.d.ts.map +1 -0
  49. package/dist/mcp/envelope.js +162 -0
  50. package/dist/mcp/envelope.js.map +1 -0
  51. package/dist/mcp/registry.d.ts +110 -0
  52. package/dist/mcp/registry.d.ts.map +1 -0
  53. package/dist/mcp/registry.js +258 -0
  54. package/dist/mcp/registry.js.map +1 -0
  55. package/dist/mcp/server.d.ts +26 -0
  56. package/dist/mcp/server.d.ts.map +1 -0
  57. package/dist/mcp/server.js +107 -0
  58. package/dist/mcp/server.js.map +1 -0
  59. package/dist/mcp/tools/agent.d.ts +4 -0
  60. package/dist/mcp/tools/agent.d.ts.map +1 -0
  61. package/dist/mcp/tools/agent.js +300 -0
  62. package/dist/mcp/tools/agent.js.map +1 -0
  63. package/dist/mcp/tools/context.d.ts +4 -0
  64. package/dist/mcp/tools/context.d.ts.map +1 -0
  65. package/dist/mcp/tools/context.js +261 -0
  66. package/dist/mcp/tools/context.js.map +1 -0
  67. package/dist/mcp/tools/index.d.ts +5 -0
  68. package/dist/mcp/tools/index.d.ts.map +1 -0
  69. package/dist/mcp/tools/index.js +20 -0
  70. package/dist/mcp/tools/index.js.map +1 -0
  71. package/dist/mcp/tools/memory.d.ts +4 -0
  72. package/dist/mcp/tools/memory.d.ts.map +1 -0
  73. package/dist/mcp/tools/memory.js +220 -0
  74. package/dist/mcp/tools/memory.js.map +1 -0
  75. package/dist/mcp/tools/output.d.ts +4 -0
  76. package/dist/mcp/tools/output.d.ts.map +1 -0
  77. package/dist/mcp/tools/output.js +206 -0
  78. package/dist/mcp/tools/output.js.map +1 -0
  79. package/dist/mcp/tools/recovery.d.ts +4 -0
  80. package/dist/mcp/tools/recovery.d.ts.map +1 -0
  81. package/dist/mcp/tools/recovery.js +165 -0
  82. package/dist/mcp/tools/recovery.js.map +1 -0
  83. package/dist/mcp/tools/registrar.d.ts +4 -0
  84. package/dist/mcp/tools/registrar.d.ts.map +1 -0
  85. package/dist/mcp/tools/registrar.js +17 -0
  86. package/dist/mcp/tools/registrar.js.map +1 -0
  87. package/dist/mcp/tools/report.d.ts +4 -0
  88. package/dist/mcp/tools/report.d.ts.map +1 -0
  89. package/dist/mcp/tools/report.js +68 -0
  90. package/dist/mcp/tools/report.js.map +1 -0
  91. package/dist/mcp/tools/shared.d.ts +37 -0
  92. package/dist/mcp/tools/shared.d.ts.map +1 -0
  93. package/dist/mcp/tools/shared.js +214 -0
  94. package/dist/mcp/tools/shared.js.map +1 -0
  95. package/dist/mcp/trace.d.ts +47 -0
  96. package/dist/mcp/trace.d.ts.map +1 -0
  97. package/dist/mcp/trace.js +216 -0
  98. package/dist/mcp/trace.js.map +1 -0
  99. package/dist/nidra/index.d.ts +275 -0
  100. package/dist/nidra/index.d.ts.map +1 -0
  101. package/dist/nidra/index.js +889 -0
  102. package/dist/nidra/index.js.map +1 -0
  103. package/dist/persistence/migrations.d.ts +10 -0
  104. package/dist/persistence/migrations.d.ts.map +1 -0
  105. package/dist/persistence/migrations.js +77 -0
  106. package/dist/persistence/migrations.js.map +1 -0
  107. package/dist/persistence/sqlite.d.ts +30 -0
  108. package/dist/persistence/sqlite.d.ts.map +1 -0
  109. package/dist/persistence/sqlite.js +209 -0
  110. package/dist/persistence/sqlite.js.map +1 -0
  111. package/dist/persistence/types.d.ts +104 -0
  112. package/dist/persistence/types.d.ts.map +1 -0
  113. package/dist/persistence/types.js +5 -0
  114. package/dist/persistence/types.js.map +1 -0
  115. package/dist/pulse/index.d.ts +144 -0
  116. package/dist/pulse/index.d.ts.map +1 -0
  117. package/dist/pulse/index.js +453 -0
  118. package/dist/pulse/index.js.map +1 -0
  119. package/dist/raksha/classifiers/http-classifier.d.ts +26 -0
  120. package/dist/raksha/classifiers/http-classifier.d.ts.map +1 -0
  121. package/dist/raksha/classifiers/http-classifier.js +62 -0
  122. package/dist/raksha/classifiers/http-classifier.js.map +1 -0
  123. package/dist/raksha/classifiers/index.d.ts +5 -0
  124. package/dist/raksha/classifiers/index.d.ts.map +1 -0
  125. package/dist/raksha/classifiers/index.js +8 -0
  126. package/dist/raksha/classifiers/index.js.map +1 -0
  127. package/dist/raksha/classifiers/onnx-classifier.d.ts +41 -0
  128. package/dist/raksha/classifiers/onnx-classifier.d.ts.map +1 -0
  129. package/dist/raksha/classifiers/onnx-classifier.js +99 -0
  130. package/dist/raksha/classifiers/onnx-classifier.js.map +1 -0
  131. package/dist/raksha/hallucination-detectors.d.ts +106 -0
  132. package/dist/raksha/hallucination-detectors.d.ts.map +1 -0
  133. package/dist/raksha/hallucination-detectors.js +327 -0
  134. package/dist/raksha/hallucination-detectors.js.map +1 -0
  135. package/dist/raksha/index.d.ts +168 -0
  136. package/dist/raksha/index.d.ts.map +1 -0
  137. package/dist/raksha/index.js +597 -0
  138. package/dist/raksha/index.js.map +1 -0
  139. package/dist/raksha/prompt-injection-detectors.d.ts +30 -0
  140. package/dist/raksha/prompt-injection-detectors.d.ts.map +1 -0
  141. package/dist/raksha/prompt-injection-detectors.js +153 -0
  142. package/dist/raksha/prompt-injection-detectors.js.map +1 -0
  143. package/dist/types.d.ts +1115 -0
  144. package/dist/types.d.ts.map +1 -0
  145. package/dist/types.js +71 -0
  146. package/dist/types.js.map +1 -0
  147. package/dist/util/calibration.d.ts +32 -0
  148. package/dist/util/calibration.d.ts.map +1 -0
  149. package/dist/util/calibration.js +108 -0
  150. package/dist/util/calibration.js.map +1 -0
  151. package/dist/util/id.d.ts +2 -0
  152. package/dist/util/id.d.ts.map +1 -0
  153. package/dist/util/id.js +9 -0
  154. package/dist/util/id.js.map +1 -0
  155. package/dist/vyayam/index.d.ts +76 -0
  156. package/dist/vyayam/index.d.ts.map +1 -0
  157. package/dist/vyayam/index.js +528 -0
  158. package/dist/vyayam/index.js.map +1 -0
  159. package/dist/vyayam/tool-fault-proxy.d.ts +95 -0
  160. package/dist/vyayam/tool-fault-proxy.d.ts.map +1 -0
  161. package/dist/vyayam/tool-fault-proxy.js +170 -0
  162. package/dist/vyayam/tool-fault-proxy.js.map +1 -0
  163. package/docs/ARCHITECTURE.md +162 -0
  164. package/docs/BACKLOG.md +342 -0
  165. package/docs/CONFIGURATION.md +305 -0
  166. package/docs/EVIDENCE.md +232 -0
  167. package/docs/EVIDENCE_MATRIX.md +293 -0
  168. package/docs/KNOWN_FAILURES.md +367 -0
  169. package/docs/MCP.md +614 -0
  170. package/docs/MODULES.md +368 -0
  171. package/docs/SECURITY.md +251 -0
  172. package/docs/TRUST.md +88 -0
  173. package/docs/assets/ojas-hero.png +0 -0
  174. package/package.json +101 -0
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Ojas Pulse — AI Health Telemetry System
3
+ *
4
+ * Tracks cognitive vital signs, degradation signals, and health events.
5
+ */
6
+ import { HealthEvent, HealthRecommendation, LatencyStats, StuckAgentReport, TelemetryHealth, TelemetryPolicy } from '../types';
7
+ import type { PulseStateSnapshot } from '../persistence/types';
8
+ /** Callback invoked for every emitted `HealthEvent`. Subscriber errors are swallowed. */
9
+ export type HealthEventSubscriber = (event: HealthEvent) => void;
10
+ /** Returned by `Pulse.subscribe()` — call to detach. */
11
+ export type Unsubscribe = () => void;
12
+ /**
13
+ * Standard context-budget milestone thresholds. Emits a structured
14
+ * "you've used 50% / 75% / 90% / 95% of your context window" event
15
+ * the first time each milestone is crossed. Latched per-agent so an
16
+ * agent that just crossed 75% doesn't keep getting paged about it.
17
+ */
18
+ export declare const CONTEXT_BUDGET_MILESTONES: readonly [0.5, 0.75, 0.9, 0.95];
19
+ export type ContextBudgetMilestone = (typeof CONTEXT_BUDGET_MILESTONES)[number];
20
+ export declare class Pulse {
21
+ private policy;
22
+ private events;
23
+ /**
24
+ * Latch tracking which context-budget milestones have already been
25
+ * emitted for each agent. Resets when the agent's utilisation falls
26
+ * back below the milestone (so the next crossing emits again).
27
+ * Key: agentId. Value: set of milestones currently latched.
28
+ */
29
+ private budgetMilestonesEmitted;
30
+ /**
31
+ * Latch tracking which memory IDs have already produced a
32
+ * `memory_cold` event. Cleared per-memory by `clearColdMemoryLatch`.
33
+ */
34
+ private coldMemoryEmitted;
35
+ /**
36
+ * Trailing latency samples per `(agentId, taskClass)` key. The key
37
+ * format is `${agentId}::${taskClass}`. Each entry is an array of
38
+ * millisecond durations capped at `policy.latencyWindowSize`.
39
+ */
40
+ private latencyWindows;
41
+ /**
42
+ * Latch per `(agentId, taskClass)` for `latency_breach` events.
43
+ * Cleared when the windowed p95 falls back below the policy budget
44
+ * so a sustained breach paged once, not on every sample.
45
+ */
46
+ private latencyBreachLatched;
47
+ /** Last `heartbeat()` ISO timestamp per agentId. */
48
+ private lastHeartbeatAt;
49
+ /**
50
+ * Per-agent latch for `agent_stuck` event. Set when
51
+ * `detectStuckAgents()` flags the agent as stuck, cleared on the
52
+ * next heartbeat. Prevents continuous paging while the agent
53
+ * remains silent.
54
+ */
55
+ private stuckLatched;
56
+ /** Active push-subscribers. Errors thrown inside handlers are swallowed. */
57
+ private subscribers;
58
+ constructor(policy?: Partial<TelemetryPolicy>);
59
+ /**
60
+ * Record context-budget utilisation for `agentId` and emit a
61
+ * `context_budget_milestone` event for each newly crossed
62
+ * milestone (50/75/90/95 percent). Idempotent — re-recording the
63
+ * same utilisation never re-emits.
64
+ *
65
+ * Returns the list of milestone fractions that emitted on this call
66
+ * (empty when nothing crossed).
67
+ */
68
+ recordContextBudgetUtilisation(agentId: string, tokensUsed: number, tokensMax: number): ContextBudgetMilestone[];
69
+ /**
70
+ * Emit a `memory_cold` event for each item in `items` that hasn't
71
+ * already been notified. Each item is `{ id, temperature, abstraction }`,
72
+ * matching the shape produced by `Nidra.detectColdMemories()`. Returns
73
+ * the IDs that actually triggered an emission this call.
74
+ */
75
+ recordColdMemories(agentId: string, items: {
76
+ id: string;
77
+ temperature: number;
78
+ abstraction: string;
79
+ }[]): string[];
80
+ /** Clear the cold-memory latch for `id` (e.g. after the memory was re-warmed or compacted). */
81
+ clearColdMemoryLatch(id: string): void;
82
+ /**
83
+ * Reject malformed TelemetryPolicy fields. `maxRecentEvents` drives the
84
+ * trailing event window used by `emit` and `assess`; a non-positive or
85
+ * non-finite value would either silently disable retention or crash on
86
+ * `Array.slice(-NaN)`.
87
+ */
88
+ private validatePolicy;
89
+ emit(event: HealthEvent): void;
90
+ emitMany(events: HealthEvent[]): void;
91
+ assess(): TelemetryHealth;
92
+ recommend(): HealthRecommendation[];
93
+ getEvents(): readonly Readonly<HealthEvent>[];
94
+ exportState(): PulseStateSnapshot;
95
+ importState(snapshot: Partial<PulseStateSnapshot> | undefined): void;
96
+ getPolicy(): TelemetryPolicy;
97
+ updatePolicy(updates: Partial<TelemetryPolicy>): void;
98
+ /**
99
+ * Push-subscribe to every emitted `HealthEvent`. The returned function
100
+ * detaches the subscriber. Handler exceptions are swallowed so a
101
+ * buggy subscriber can never corrupt Pulse state. Useful for live
102
+ * dashboards, log streaming, and external alerting integrations.
103
+ */
104
+ subscribe(handler: HealthEventSubscriber): Unsubscribe;
105
+ /**
106
+ * Record a single observed task latency. Adds the sample to the
107
+ * trailing per-(agentId, taskClass) window, returns the resulting
108
+ * windowed stats, and \u2014 if `policy.latencyP95BreachMs` is configured
109
+ * and the new windowed p95 exceeds it \u2014 emits a one-shot
110
+ * `latency_breach` event. The breach latch clears when p95 drops
111
+ * back below the budget so a recovered system can re-page on a
112
+ * future breach.
113
+ *
114
+ * Rejects malformed input (non-finite or negative `durationMs`,
115
+ * empty strings) at the boundary so a buggy caller can't poison
116
+ * percentile math.
117
+ */
118
+ recordLatency(agentId: string, taskClass: string, durationMs: number): LatencyStats;
119
+ /**
120
+ * Windowed latency summary for one `(agentId, taskClass)`. Returns a
121
+ * zero-valued struct when no samples have been recorded yet.
122
+ */
123
+ getLatencyStats(agentId: string, taskClass: string): LatencyStats;
124
+ private computeLatencyStats;
125
+ /**
126
+ * Stamp `agentId` as alive *now*. Clears the per-agent stuck latch
127
+ * so a subsequent silence can re-fire a fresh `agent_stuck` event.
128
+ */
129
+ heartbeat(agentId: string): void;
130
+ /** Last heartbeat timestamp for `agentId`, or `undefined` if never seen. */
131
+ getLastHeartbeat(agentId: string): string | undefined;
132
+ /**
133
+ * Identify agents whose last `heartbeat()` is older than the
134
+ * configured `stuckAfterMs` budget. For each newly-stuck agent
135
+ * (latched per agentId), emits an `agent_stuck` event. The latch
136
+ * clears on the next heartbeat from that agent.
137
+ *
138
+ * `maxIdleMs` overrides the policy budget for this call. Agents
139
+ * that have never sent a heartbeat are not reported \u2014 they're not
140
+ * "stuck", they're "unknown".
141
+ */
142
+ detectStuckAgents(maxIdleMs?: number): StuckAgentReport[];
143
+ }
144
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pulse/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEL,WAAW,EACX,oBAAoB,EAEpB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,eAAe,EAChB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,yFAAyF;AACzF,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AACjE,wDAAwD;AACxD,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAcrC;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,iCAAkC,CAAC;AAEzE,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhF,qBAAa,KAAK;IAChB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,MAAM,CAAqB;IACnC;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB,CAAkD;IACjF;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAAqB;IAC9C;;;;OAIG;IACH,OAAO,CAAC,cAAc,CAA+B;IACrD;;;;OAIG;IACH,OAAO,CAAC,oBAAoB,CAAqB;IACjD,oDAAoD;IACpD,OAAO,CAAC,eAAe,CAA6B;IACpD;;;;;OAKG;IACH,OAAO,CAAC,YAAY,CAAqB;IACzC,4EAA4E;IAC5E,OAAO,CAAC,WAAW,CAA+B;gBAEtC,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM;IAIjD;;;;;;;;OAQG;IACH,8BAA8B,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,sBAAsB,EAAE;IAwC3B;;;;;OAKG;IACH,kBAAkB,CAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,GAChE,MAAM,EAAE;IAuBX,+FAA+F;IAC/F,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAItC;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAiCtB,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAkB9B,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI;IAIrC,MAAM,IAAI,eAAe;IAgBzB,SAAS,IAAI,oBAAoB,EAAE;IA6BnC,SAAS,IAAI,SAAS,QAAQ,CAAC,WAAW,CAAC,EAAE;IAI7C,WAAW,IAAI,kBAAkB;IAYjC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,SAAS,GAAG,IAAI;IAapE,SAAS,IAAI,eAAe;IAI5B,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IASrD;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,qBAAqB,GAAG,WAAW;IAatD;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY;IAgDnF;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY;IAMjE,OAAO,CAAC,mBAAmB;IAuB3B;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQhC,4EAA4E;IAC5E,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIrD;;;;;;;;;OASG;IACH,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,gBAAgB,EAAE;CA8B1D"}
@@ -0,0 +1,453 @@
1
+ "use strict";
2
+ /**
3
+ * Ojas Pulse — AI Health Telemetry System
4
+ *
5
+ * Tracks cognitive vital signs, degradation signals, and health events.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.Pulse = exports.CONTEXT_BUDGET_MILESTONES = void 0;
9
+ const types_1 = require("../types");
10
+ function now() {
11
+ return new Date().toISOString();
12
+ }
13
+ function clamp(v, min = 0, max = 1) {
14
+ return Math.max(min, Math.min(max, v));
15
+ }
16
+ function healthScore(value, source) {
17
+ return { value: clamp(value), timestamp: now(), source };
18
+ }
19
+ /**
20
+ * Standard context-budget milestone thresholds. Emits a structured
21
+ * "you've used 50% / 75% / 90% / 95% of your context window" event
22
+ * the first time each milestone is crossed. Latched per-agent so an
23
+ * agent that just crossed 75% doesn't keep getting paged about it.
24
+ */
25
+ exports.CONTEXT_BUDGET_MILESTONES = [0.5, 0.75, 0.9, 0.95];
26
+ class Pulse {
27
+ policy;
28
+ events = [];
29
+ /**
30
+ * Latch tracking which context-budget milestones have already been
31
+ * emitted for each agent. Resets when the agent's utilisation falls
32
+ * back below the milestone (so the next crossing emits again).
33
+ * Key: agentId. Value: set of milestones currently latched.
34
+ */
35
+ budgetMilestonesEmitted = new Map();
36
+ /**
37
+ * Latch tracking which memory IDs have already produced a
38
+ * `memory_cold` event. Cleared per-memory by `clearColdMemoryLatch`.
39
+ */
40
+ coldMemoryEmitted = new Set();
41
+ /**
42
+ * Trailing latency samples per `(agentId, taskClass)` key. The key
43
+ * format is `${agentId}::${taskClass}`. Each entry is an array of
44
+ * millisecond durations capped at `policy.latencyWindowSize`.
45
+ */
46
+ latencyWindows = new Map();
47
+ /**
48
+ * Latch per `(agentId, taskClass)` for `latency_breach` events.
49
+ * Cleared when the windowed p95 falls back below the policy budget
50
+ * so a sustained breach paged once, not on every sample.
51
+ */
52
+ latencyBreachLatched = new Set();
53
+ /** Last `heartbeat()` ISO timestamp per agentId. */
54
+ lastHeartbeatAt = new Map();
55
+ /**
56
+ * Per-agent latch for `agent_stuck` event. Set when
57
+ * `detectStuckAgents()` flags the agent as stuck, cleared on the
58
+ * next heartbeat. Prevents continuous paging while the agent
59
+ * remains silent.
60
+ */
61
+ stuckLatched = new Set();
62
+ /** Active push-subscribers. Errors thrown inside handlers are swallowed. */
63
+ subscribers = [];
64
+ constructor(policy = {}) {
65
+ this.policy = this.validatePolicy({ ...types_1.DEFAULT_TELEMETRY_POLICY, ...policy });
66
+ }
67
+ /**
68
+ * Record context-budget utilisation for `agentId` and emit a
69
+ * `context_budget_milestone` event for each newly crossed
70
+ * milestone (50/75/90/95 percent). Idempotent — re-recording the
71
+ * same utilisation never re-emits.
72
+ *
73
+ * Returns the list of milestone fractions that emitted on this call
74
+ * (empty when nothing crossed).
75
+ */
76
+ recordContextBudgetUtilisation(agentId, tokensUsed, tokensMax) {
77
+ if (!Number.isFinite(tokensUsed) || !Number.isFinite(tokensMax) || tokensMax <= 0) {
78
+ return [];
79
+ }
80
+ const ratio = Math.max(0, tokensUsed / tokensMax);
81
+ const latched = this.budgetMilestonesEmitted.get(agentId) ?? new Set();
82
+ const newlyCrossed = [];
83
+ for (const m of exports.CONTEXT_BUDGET_MILESTONES) {
84
+ if (ratio >= m && !latched.has(m)) {
85
+ latched.add(m);
86
+ newlyCrossed.push(m);
87
+ }
88
+ else if (ratio < m && latched.has(m)) {
89
+ // Fell back below — un-latch so the next crossing can emit again.
90
+ latched.delete(m);
91
+ }
92
+ }
93
+ if (latched.size > 0)
94
+ this.budgetMilestonesEmitted.set(agentId, latched);
95
+ else
96
+ this.budgetMilestonesEmitted.delete(agentId);
97
+ for (const m of newlyCrossed) {
98
+ const severity = m >= 0.95 ? 'critical' : m >= 0.9 ? 'warning' : 'info';
99
+ this.emit({
100
+ id: `pulse-budget-${agentId}-${Math.round(m * 100)}-${Date.now()}`,
101
+ eventType: 'context_budget_milestone',
102
+ severity,
103
+ timestamp: now(),
104
+ agentId,
105
+ detectedBy: 'pulse',
106
+ details: {
107
+ milestone: m,
108
+ tokensUsed,
109
+ tokensMax,
110
+ utilisation: ratio,
111
+ },
112
+ });
113
+ }
114
+ return newlyCrossed;
115
+ }
116
+ /**
117
+ * Emit a `memory_cold` event for each item in `items` that hasn't
118
+ * already been notified. Each item is `{ id, temperature, abstraction }`,
119
+ * matching the shape produced by `Nidra.detectColdMemories()`. Returns
120
+ * the IDs that actually triggered an emission this call.
121
+ */
122
+ recordColdMemories(agentId, items) {
123
+ const emitted = [];
124
+ for (const c of items) {
125
+ if (this.coldMemoryEmitted.has(c.id))
126
+ continue;
127
+ this.coldMemoryEmitted.add(c.id);
128
+ emitted.push(c.id);
129
+ this.emit({
130
+ id: `pulse-cold-${c.id}-${Date.now()}`,
131
+ eventType: 'memory_cold',
132
+ severity: 'info',
133
+ timestamp: now(),
134
+ agentId,
135
+ detectedBy: 'pulse',
136
+ details: {
137
+ memoryId: c.id,
138
+ temperature: c.temperature,
139
+ abstraction: c.abstraction,
140
+ },
141
+ });
142
+ }
143
+ return emitted;
144
+ }
145
+ /** Clear the cold-memory latch for `id` (e.g. after the memory was re-warmed or compacted). */
146
+ clearColdMemoryLatch(id) {
147
+ this.coldMemoryEmitted.delete(id);
148
+ }
149
+ /**
150
+ * Reject malformed TelemetryPolicy fields. `maxRecentEvents` drives the
151
+ * trailing event window used by `emit` and `assess`; a non-positive or
152
+ * non-finite value would either silently disable retention or crash on
153
+ * `Array.slice(-NaN)`.
154
+ */
155
+ validatePolicy(policy) {
156
+ if (!Number.isInteger(policy.maxRecentEvents) || policy.maxRecentEvents <= 0) {
157
+ throw new Error('Pulse: maxRecentEvents must be a positive integer');
158
+ }
159
+ if (typeof policy.degradationThreshold !== 'number' ||
160
+ !Number.isFinite(policy.degradationThreshold) ||
161
+ policy.degradationThreshold < 0 ||
162
+ policy.degradationThreshold > 1) {
163
+ throw new Error('Pulse: degradationThreshold must be a finite number in [0,1]');
164
+ }
165
+ if (policy.latencyWindowSize !== undefined &&
166
+ (!Number.isInteger(policy.latencyWindowSize) || policy.latencyWindowSize <= 0)) {
167
+ throw new Error('Pulse: latencyWindowSize must be a positive integer if set');
168
+ }
169
+ if (policy.latencyP95BreachMs !== undefined &&
170
+ (!Number.isFinite(policy.latencyP95BreachMs) || policy.latencyP95BreachMs <= 0)) {
171
+ throw new Error('Pulse: latencyP95BreachMs must be a positive finite number if set');
172
+ }
173
+ if (policy.stuckAfterMs !== undefined &&
174
+ (!Number.isFinite(policy.stuckAfterMs) || policy.stuckAfterMs <= 0)) {
175
+ throw new Error('Pulse: stuckAfterMs must be a positive finite number if set');
176
+ }
177
+ return policy;
178
+ }
179
+ emit(event) {
180
+ this.events.push(event);
181
+ if (this.events.length > this.policy.maxRecentEvents) {
182
+ this.events = this.events.slice(-this.policy.maxRecentEvents);
183
+ }
184
+ // Push to subscribers. Errors inside handlers are caught so a buggy
185
+ // subscriber can't corrupt Pulse state mid-emit.
186
+ if (this.subscribers.length > 0) {
187
+ for (const sub of this.subscribers) {
188
+ try {
189
+ sub(event);
190
+ }
191
+ catch {
192
+ // Intentional: subscriber errors must not break the emit path.
193
+ }
194
+ }
195
+ }
196
+ }
197
+ emitMany(events) {
198
+ for (const event of events)
199
+ this.emit(event);
200
+ }
201
+ assess() {
202
+ const recent = this.events.slice(-this.policy.maxRecentEvents);
203
+ const critical = recent.filter((event) => event.severity === 'critical').length;
204
+ const warning = recent.filter((event) => event.severity === 'warning').length;
205
+ const activeAlerts = critical + warning;
206
+ const degradationRisk = clamp((critical * 0.2) + (warning * 0.05));
207
+ return {
208
+ vitalSigns: healthScore(1 - degradationRisk, 'pulse.vitalSigns'),
209
+ degradationRisk: healthScore(1 - degradationRisk, 'pulse.degradationRisk'),
210
+ observabilityCoverage: healthScore(recent.length > 0 ? 1 : 0.4, 'pulse.coverage'),
211
+ eventsEmitted: recent.length,
212
+ activeAlerts,
213
+ };
214
+ }
215
+ recommend() {
216
+ const health = this.assess();
217
+ const recs = [];
218
+ if (health.activeAlerts > 0) {
219
+ recs.push({
220
+ module: 'pulse',
221
+ severity: health.degradationRisk.value < 0.5 ? 'critical' : 'warning',
222
+ message: `${health.activeAlerts} active health alerts detected.`,
223
+ action: 'Inspect recent health events and trigger recovery or repair if needed.',
224
+ });
225
+ }
226
+ if (health.observabilityCoverage.value < 0.5) {
227
+ recs.push({
228
+ module: 'pulse',
229
+ severity: 'warning',
230
+ message: 'Telemetry coverage is low; no recent health events are available.',
231
+ action: 'Connect Pulse to runtime traces and module events.',
232
+ });
233
+ }
234
+ if (recs.length === 0) {
235
+ recs.push({ module: 'pulse', severity: 'info', message: 'Health telemetry is stable.' });
236
+ }
237
+ return recs;
238
+ }
239
+ getEvents() {
240
+ return this.events.map((e) => ({ ...e, details: { ...e.details } }));
241
+ }
242
+ exportState() {
243
+ return {
244
+ events: [...this.getEvents()],
245
+ budgetMilestonesEmitted: Array.from(this.budgetMilestonesEmitted.entries()).map(([k, v]) => [k, Array.from(v)]),
246
+ coldMemoryEmitted: Array.from(this.coldMemoryEmitted),
247
+ latencyWindows: Array.from(this.latencyWindows.entries()).map(([k, v]) => [k, [...v]]),
248
+ latencyBreachLatched: Array.from(this.latencyBreachLatched),
249
+ lastHeartbeatAt: Array.from(this.lastHeartbeatAt.entries()),
250
+ stuckLatched: Array.from(this.stuckLatched),
251
+ };
252
+ }
253
+ importState(snapshot) {
254
+ if (!snapshot)
255
+ return;
256
+ this.events = (snapshot.events ?? []).map((e) => ({ ...e, details: { ...e.details } }));
257
+ this.budgetMilestonesEmitted = new Map((snapshot.budgetMilestonesEmitted ?? []).map(([k, v]) => [k, new Set(v)]));
258
+ this.coldMemoryEmitted = new Set(snapshot.coldMemoryEmitted ?? []);
259
+ this.latencyWindows = new Map((snapshot.latencyWindows ?? []).map(([k, v]) => [k, [...v]]));
260
+ this.latencyBreachLatched = new Set(snapshot.latencyBreachLatched ?? []);
261
+ this.lastHeartbeatAt = new Map(snapshot.lastHeartbeatAt ?? []);
262
+ this.stuckLatched = new Set(snapshot.stuckLatched ?? []);
263
+ }
264
+ getPolicy() {
265
+ return { ...this.policy };
266
+ }
267
+ updatePolicy(updates) {
268
+ this.policy = this.validatePolicy({ ...this.policy, ...updates });
269
+ if (this.events.length > this.policy.maxRecentEvents) {
270
+ this.events = this.events.slice(-this.policy.maxRecentEvents);
271
+ }
272
+ }
273
+ // ── Push subscription ────────────────────────────────────────────────────
274
+ /**
275
+ * Push-subscribe to every emitted `HealthEvent`. The returned function
276
+ * detaches the subscriber. Handler exceptions are swallowed so a
277
+ * buggy subscriber can never corrupt Pulse state. Useful for live
278
+ * dashboards, log streaming, and external alerting integrations.
279
+ */
280
+ subscribe(handler) {
281
+ if (typeof handler !== 'function') {
282
+ throw new Error('Pulse: subscribe requires a function handler');
283
+ }
284
+ this.subscribers.push(handler);
285
+ return () => {
286
+ const idx = this.subscribers.indexOf(handler);
287
+ if (idx !== -1)
288
+ this.subscribers.splice(idx, 1);
289
+ };
290
+ }
291
+ // ── Latency tracking ─────────────────────────────────────────────────────
292
+ /**
293
+ * Record a single observed task latency. Adds the sample to the
294
+ * trailing per-(agentId, taskClass) window, returns the resulting
295
+ * windowed stats, and \u2014 if `policy.latencyP95BreachMs` is configured
296
+ * and the new windowed p95 exceeds it \u2014 emits a one-shot
297
+ * `latency_breach` event. The breach latch clears when p95 drops
298
+ * back below the budget so a recovered system can re-page on a
299
+ * future breach.
300
+ *
301
+ * Rejects malformed input (non-finite or negative `durationMs`,
302
+ * empty strings) at the boundary so a buggy caller can't poison
303
+ * percentile math.
304
+ */
305
+ recordLatency(agentId, taskClass, durationMs) {
306
+ if (typeof agentId !== 'string' || agentId.length === 0) {
307
+ throw new Error('Pulse: recordLatency requires a non-empty agentId');
308
+ }
309
+ if (typeof taskClass !== 'string' || taskClass.length === 0) {
310
+ throw new Error('Pulse: recordLatency requires a non-empty taskClass');
311
+ }
312
+ if (typeof durationMs !== 'number' || !Number.isFinite(durationMs) || durationMs < 0) {
313
+ throw new Error('Pulse: recordLatency requires a non-negative finite durationMs');
314
+ }
315
+ const key = `${agentId}::${taskClass}`;
316
+ const cap = this.policy.latencyWindowSize ?? 100;
317
+ let window = this.latencyWindows.get(key);
318
+ if (!window) {
319
+ window = [];
320
+ this.latencyWindows.set(key, window);
321
+ }
322
+ window.push(durationMs);
323
+ if (window.length > cap) {
324
+ window.splice(0, window.length - cap);
325
+ }
326
+ const stats = this.computeLatencyStats(agentId, taskClass, window);
327
+ const budget = this.policy.latencyP95BreachMs;
328
+ if (budget !== undefined) {
329
+ if (stats.p95Ms > budget && !this.latencyBreachLatched.has(key)) {
330
+ this.latencyBreachLatched.add(key);
331
+ this.emit({
332
+ id: `pulse-latency-${key}-${Date.now()}`,
333
+ eventType: 'latency_breach',
334
+ severity: 'warning',
335
+ timestamp: now(),
336
+ agentId,
337
+ detectedBy: 'pulse',
338
+ details: {
339
+ taskClass,
340
+ p95Ms: stats.p95Ms,
341
+ budgetMs: budget,
342
+ samples: stats.samples,
343
+ },
344
+ });
345
+ }
346
+ else if (stats.p95Ms <= budget && this.latencyBreachLatched.has(key)) {
347
+ this.latencyBreachLatched.delete(key);
348
+ }
349
+ }
350
+ return stats;
351
+ }
352
+ /**
353
+ * Windowed latency summary for one `(agentId, taskClass)`. Returns a
354
+ * zero-valued struct when no samples have been recorded yet.
355
+ */
356
+ getLatencyStats(agentId, taskClass) {
357
+ const key = `${agentId}::${taskClass}`;
358
+ const window = this.latencyWindows.get(key);
359
+ return this.computeLatencyStats(agentId, taskClass, window ?? []);
360
+ }
361
+ computeLatencyStats(agentId, taskClass, samples) {
362
+ if (samples.length === 0) {
363
+ return { agentId, taskClass, samples: 0, meanMs: 0, p50Ms: 0, p95Ms: 0, maxMs: 0 };
364
+ }
365
+ const sorted = [...samples].sort((a, b) => a - b);
366
+ const sum = sorted.reduce((acc, v) => acc + v, 0);
367
+ return {
368
+ agentId,
369
+ taskClass,
370
+ samples: sorted.length,
371
+ meanMs: sum / sorted.length,
372
+ p50Ms: percentileSample(sorted, 0.5),
373
+ p95Ms: percentileSample(sorted, 0.95),
374
+ maxMs: sorted[sorted.length - 1],
375
+ };
376
+ }
377
+ // ── Heartbeat / stuck-agent detection ────────────────────────────────────
378
+ /**
379
+ * Stamp `agentId` as alive *now*. Clears the per-agent stuck latch
380
+ * so a subsequent silence can re-fire a fresh `agent_stuck` event.
381
+ */
382
+ heartbeat(agentId) {
383
+ if (typeof agentId !== 'string' || agentId.length === 0) {
384
+ throw new Error('Pulse: heartbeat requires a non-empty agentId');
385
+ }
386
+ this.lastHeartbeatAt.set(agentId, now());
387
+ this.stuckLatched.delete(agentId);
388
+ }
389
+ /** Last heartbeat timestamp for `agentId`, or `undefined` if never seen. */
390
+ getLastHeartbeat(agentId) {
391
+ return this.lastHeartbeatAt.get(agentId);
392
+ }
393
+ /**
394
+ * Identify agents whose last `heartbeat()` is older than the
395
+ * configured `stuckAfterMs` budget. For each newly-stuck agent
396
+ * (latched per agentId), emits an `agent_stuck` event. The latch
397
+ * clears on the next heartbeat from that agent.
398
+ *
399
+ * `maxIdleMs` overrides the policy budget for this call. Agents
400
+ * that have never sent a heartbeat are not reported \u2014 they're not
401
+ * "stuck", they're "unknown".
402
+ */
403
+ detectStuckAgents(maxIdleMs) {
404
+ const budget = maxIdleMs ?? this.policy.stuckAfterMs ?? 60_000;
405
+ const nowMs = Date.now();
406
+ const out = [];
407
+ for (const [agentId, ts] of this.lastHeartbeatAt) {
408
+ const idleMs = nowMs - Date.parse(ts);
409
+ // `>=`: at the moment the agent's idle reaches the configured
410
+ // budget it counts as stuck. A budget of 0 therefore means "any
411
+ // agent that has ever sent a heartbeat" — useful for tests.
412
+ if (idleMs < budget)
413
+ continue;
414
+ out.push({ agentId, lastHeartbeatAt: ts, idleMs });
415
+ if (!this.stuckLatched.has(agentId)) {
416
+ this.stuckLatched.add(agentId);
417
+ this.emit({
418
+ id: `pulse-stuck-${agentId}-${nowMs}`,
419
+ eventType: 'agent_stuck',
420
+ severity: idleMs > budget * 4 ? 'critical' : 'warning',
421
+ timestamp: now(),
422
+ agentId,
423
+ detectedBy: 'pulse',
424
+ details: {
425
+ lastHeartbeatAt: ts,
426
+ idleMs,
427
+ budgetMs: budget,
428
+ },
429
+ });
430
+ }
431
+ }
432
+ return out;
433
+ }
434
+ }
435
+ exports.Pulse = Pulse;
436
+ /**
437
+ * Linear-interpolated percentile over a sorted-ascending sample.
438
+ * Kept module-private (sibling helper of `Pulse.computeLatencyStats`)
439
+ * so the dependency footprint stays at zero.
440
+ */
441
+ function percentileSample(sortedAsc, p) {
442
+ if (sortedAsc.length === 0)
443
+ return 0;
444
+ const q = Math.max(0, Math.min(1, p));
445
+ const idx = q * (sortedAsc.length - 1);
446
+ const lo = Math.floor(idx);
447
+ const hi = Math.ceil(idx);
448
+ if (lo === hi)
449
+ return sortedAsc[lo];
450
+ const w = idx - lo;
451
+ return sortedAsc[lo] * (1 - w) + sortedAsc[hi] * w;
452
+ }
453
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pulse/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * HTTP-backed prompt injection classifier — reference implementation.
3
+ *
4
+ * Calls an external HTTP endpoint that accepts `{ text }` and returns
5
+ * `{ injectionProbability, label }`. Works with any service that follows
6
+ * this contract (e.g. a Python FastAPI wrapping a HuggingFace classifier,
7
+ * the OpenAI moderation endpoint behind a thin adapter, Rebuff, etc.).
8
+ */
9
+ import type { PromptInjectionClassifier, ClassifierResult } from '../../types';
10
+ export interface HttpClassifierOptions {
11
+ /** Full URL of the classification endpoint. */
12
+ url: string;
13
+ /** Optional bearer token for authenticated endpoints. */
14
+ apiKey?: string;
15
+ /** Request timeout in milliseconds. Default: 5000. */
16
+ timeoutMs?: number;
17
+ /** Custom headers merged into every request. */
18
+ headers?: Record<string, string>;
19
+ }
20
+ export declare class HttpPromptInjectionClassifier implements PromptInjectionClassifier {
21
+ readonly name: string;
22
+ private readonly opts;
23
+ constructor(options: HttpClassifierOptions);
24
+ classify(text: string, signal?: AbortSignal): Promise<ClassifierResult>;
25
+ }
26
+ //# sourceMappingURL=http-classifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-classifier.d.ts","sourceRoot":"","sources":["../../../src/raksha/classifiers/http-classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/E,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,qBAAa,6BAA8B,YAAW,yBAAyB;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkH;gBAE3H,OAAO,EAAE,qBAAqB;IAUpC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAyC9E"}