@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.
- package/LICENSE +21 -0
- package/README.md +308 -0
- package/dist/aahar/index.d.ts +179 -0
- package/dist/aahar/index.d.ts.map +1 -0
- package/dist/aahar/index.js +657 -0
- package/dist/aahar/index.js.map +1 -0
- package/dist/aahar/scoring.d.ts +85 -0
- package/dist/aahar/scoring.d.ts.map +1 -0
- package/dist/aahar/scoring.js +268 -0
- package/dist/aahar/scoring.js.map +1 -0
- package/dist/agni/index.d.ts +113 -0
- package/dist/agni/index.d.ts.map +1 -0
- package/dist/agni/index.js +328 -0
- package/dist/agni/index.js.map +1 -0
- package/dist/agni/model-router.d.ts +77 -0
- package/dist/agni/model-router.d.ts.map +1 -0
- package/dist/agni/model-router.js +163 -0
- package/dist/agni/model-router.js.map +1 -0
- package/dist/agni/response-distiller.d.ts +37 -0
- package/dist/agni/response-distiller.d.ts.map +1 -0
- package/dist/agni/response-distiller.js +193 -0
- package/dist/agni/response-distiller.js.map +1 -0
- package/dist/agni/tiktoken-adapter.d.ts +55 -0
- package/dist/agni/tiktoken-adapter.d.ts.map +1 -0
- package/dist/agni/tiktoken-adapter.js +113 -0
- package/dist/agni/tiktoken-adapter.js.map +1 -0
- package/dist/chikitsa/index.d.ts +130 -0
- package/dist/chikitsa/index.d.ts.map +1 -0
- package/dist/chikitsa/index.js +565 -0
- package/dist/chikitsa/index.js.map +1 -0
- package/dist/demo.d.ts +15 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/demo.js +278 -0
- package/dist/demo.js.map +1 -0
- package/dist/index.d.ts +201 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +588 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/audit.d.ts +39 -0
- package/dist/mcp/audit.d.ts.map +1 -0
- package/dist/mcp/audit.js +73 -0
- package/dist/mcp/audit.js.map +1 -0
- package/dist/mcp/contracts.d.ts +76 -0
- package/dist/mcp/contracts.d.ts.map +1 -0
- package/dist/mcp/contracts.js +44 -0
- package/dist/mcp/contracts.js.map +1 -0
- package/dist/mcp/envelope.d.ts +107 -0
- package/dist/mcp/envelope.d.ts.map +1 -0
- package/dist/mcp/envelope.js +162 -0
- package/dist/mcp/envelope.js.map +1 -0
- package/dist/mcp/registry.d.ts +110 -0
- package/dist/mcp/registry.d.ts.map +1 -0
- package/dist/mcp/registry.js +258 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/server.d.ts +26 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +107 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/agent.d.ts +4 -0
- package/dist/mcp/tools/agent.d.ts.map +1 -0
- package/dist/mcp/tools/agent.js +300 -0
- package/dist/mcp/tools/agent.js.map +1 -0
- package/dist/mcp/tools/context.d.ts +4 -0
- package/dist/mcp/tools/context.d.ts.map +1 -0
- package/dist/mcp/tools/context.js +261 -0
- package/dist/mcp/tools/context.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +5 -0
- package/dist/mcp/tools/index.d.ts.map +1 -0
- package/dist/mcp/tools/index.js +20 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/memory.d.ts +4 -0
- package/dist/mcp/tools/memory.d.ts.map +1 -0
- package/dist/mcp/tools/memory.js +220 -0
- package/dist/mcp/tools/memory.js.map +1 -0
- package/dist/mcp/tools/output.d.ts +4 -0
- package/dist/mcp/tools/output.d.ts.map +1 -0
- package/dist/mcp/tools/output.js +206 -0
- package/dist/mcp/tools/output.js.map +1 -0
- package/dist/mcp/tools/recovery.d.ts +4 -0
- package/dist/mcp/tools/recovery.d.ts.map +1 -0
- package/dist/mcp/tools/recovery.js +165 -0
- package/dist/mcp/tools/recovery.js.map +1 -0
- package/dist/mcp/tools/registrar.d.ts +4 -0
- package/dist/mcp/tools/registrar.d.ts.map +1 -0
- package/dist/mcp/tools/registrar.js +17 -0
- package/dist/mcp/tools/registrar.js.map +1 -0
- package/dist/mcp/tools/report.d.ts +4 -0
- package/dist/mcp/tools/report.d.ts.map +1 -0
- package/dist/mcp/tools/report.js +68 -0
- package/dist/mcp/tools/report.js.map +1 -0
- package/dist/mcp/tools/shared.d.ts +37 -0
- package/dist/mcp/tools/shared.d.ts.map +1 -0
- package/dist/mcp/tools/shared.js +214 -0
- package/dist/mcp/tools/shared.js.map +1 -0
- package/dist/mcp/trace.d.ts +47 -0
- package/dist/mcp/trace.d.ts.map +1 -0
- package/dist/mcp/trace.js +216 -0
- package/dist/mcp/trace.js.map +1 -0
- package/dist/nidra/index.d.ts +275 -0
- package/dist/nidra/index.d.ts.map +1 -0
- package/dist/nidra/index.js +889 -0
- package/dist/nidra/index.js.map +1 -0
- package/dist/persistence/migrations.d.ts +10 -0
- package/dist/persistence/migrations.d.ts.map +1 -0
- package/dist/persistence/migrations.js +77 -0
- package/dist/persistence/migrations.js.map +1 -0
- package/dist/persistence/sqlite.d.ts +30 -0
- package/dist/persistence/sqlite.d.ts.map +1 -0
- package/dist/persistence/sqlite.js +209 -0
- package/dist/persistence/sqlite.js.map +1 -0
- package/dist/persistence/types.d.ts +104 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +5 -0
- package/dist/persistence/types.js.map +1 -0
- package/dist/pulse/index.d.ts +144 -0
- package/dist/pulse/index.d.ts.map +1 -0
- package/dist/pulse/index.js +453 -0
- package/dist/pulse/index.js.map +1 -0
- package/dist/raksha/classifiers/http-classifier.d.ts +26 -0
- package/dist/raksha/classifiers/http-classifier.d.ts.map +1 -0
- package/dist/raksha/classifiers/http-classifier.js +62 -0
- package/dist/raksha/classifiers/http-classifier.js.map +1 -0
- package/dist/raksha/classifiers/index.d.ts +5 -0
- package/dist/raksha/classifiers/index.d.ts.map +1 -0
- package/dist/raksha/classifiers/index.js +8 -0
- package/dist/raksha/classifiers/index.js.map +1 -0
- package/dist/raksha/classifiers/onnx-classifier.d.ts +41 -0
- package/dist/raksha/classifiers/onnx-classifier.d.ts.map +1 -0
- package/dist/raksha/classifiers/onnx-classifier.js +99 -0
- package/dist/raksha/classifiers/onnx-classifier.js.map +1 -0
- package/dist/raksha/hallucination-detectors.d.ts +106 -0
- package/dist/raksha/hallucination-detectors.d.ts.map +1 -0
- package/dist/raksha/hallucination-detectors.js +327 -0
- package/dist/raksha/hallucination-detectors.js.map +1 -0
- package/dist/raksha/index.d.ts +168 -0
- package/dist/raksha/index.d.ts.map +1 -0
- package/dist/raksha/index.js +597 -0
- package/dist/raksha/index.js.map +1 -0
- package/dist/raksha/prompt-injection-detectors.d.ts +30 -0
- package/dist/raksha/prompt-injection-detectors.d.ts.map +1 -0
- package/dist/raksha/prompt-injection-detectors.js +153 -0
- package/dist/raksha/prompt-injection-detectors.js.map +1 -0
- package/dist/types.d.ts +1115 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +71 -0
- package/dist/types.js.map +1 -0
- package/dist/util/calibration.d.ts +32 -0
- package/dist/util/calibration.d.ts.map +1 -0
- package/dist/util/calibration.js +108 -0
- package/dist/util/calibration.js.map +1 -0
- package/dist/util/id.d.ts +2 -0
- package/dist/util/id.d.ts.map +1 -0
- package/dist/util/id.js +9 -0
- package/dist/util/id.js.map +1 -0
- package/dist/vyayam/index.d.ts +76 -0
- package/dist/vyayam/index.d.ts.map +1 -0
- package/dist/vyayam/index.js +528 -0
- package/dist/vyayam/index.js.map +1 -0
- package/dist/vyayam/tool-fault-proxy.d.ts +95 -0
- package/dist/vyayam/tool-fault-proxy.d.ts.map +1 -0
- package/dist/vyayam/tool-fault-proxy.js +170 -0
- package/dist/vyayam/tool-fault-proxy.js.map +1 -0
- package/docs/ARCHITECTURE.md +162 -0
- package/docs/BACKLOG.md +342 -0
- package/docs/CONFIGURATION.md +305 -0
- package/docs/EVIDENCE.md +232 -0
- package/docs/EVIDENCE_MATRIX.md +293 -0
- package/docs/KNOWN_FAILURES.md +367 -0
- package/docs/MCP.md +614 -0
- package/docs/MODULES.md +368 -0
- package/docs/SECURITY.md +251 -0
- package/docs/TRUST.md +88 -0
- package/docs/assets/ojas-hero.png +0 -0
- package/package.json +101 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/mcp/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEvC,MAAM,MAAM,cAAc,GACtB,gBAAgB,GAChB,kBAAkB,GAClB,cAAc,GACd,kBAAkB,GAClB,eAAe,GACf,mBAAmB,GACnB,cAAc,GACd,gBAAgB,GAChB,UAAU,CAAC;AAEf,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,cAAc,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;gBAE7B,MAAM,CAAC,EAAE,QAAQ,GAAG,IAAI;IAIpC,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAa5B;;;OAGG;IACG,IAAI,CAAC,CAAC,EACV,SAAS,EAAE,cAAc,EACzB,IAAI,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EAC9E,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC;CA4Bd"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Structured JSONL audit logger for critical MCP operations.
|
|
4
|
+
*
|
|
5
|
+
* Emits one JSON line per audited event to a configurable writable stream
|
|
6
|
+
* (default: disabled). Each entry captures operation type, agent/session
|
|
7
|
+
* context, a summary of arguments and results, and wall-clock duration.
|
|
8
|
+
*
|
|
9
|
+
* Design constraints:
|
|
10
|
+
* - Zero overhead when disabled (no-op fast path).
|
|
11
|
+
* - Does not throw on write failures — audit is best-effort.
|
|
12
|
+
* - Does not buffer — each event is flushed immediately.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AuditLogger = void 0;
|
|
16
|
+
class AuditLogger {
|
|
17
|
+
stream;
|
|
18
|
+
constructor(stream) {
|
|
19
|
+
this.stream = stream ?? null;
|
|
20
|
+
}
|
|
21
|
+
get enabled() {
|
|
22
|
+
return this.stream !== null;
|
|
23
|
+
}
|
|
24
|
+
log(entry) {
|
|
25
|
+
if (!this.stream)
|
|
26
|
+
return;
|
|
27
|
+
try {
|
|
28
|
+
const line = JSON.stringify({
|
|
29
|
+
...entry,
|
|
30
|
+
timestamp: entry.timestamp || new Date().toISOString(),
|
|
31
|
+
});
|
|
32
|
+
this.stream.write(line + '\n');
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Best-effort — never crash the MCP server for audit failures.
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Convenience: wraps an async handler, emitting an audit entry with
|
|
40
|
+
* timing around the call. Returns the handler's result transparently.
|
|
41
|
+
*/
|
|
42
|
+
async wrap(operation, opts, fn) {
|
|
43
|
+
if (!this.stream)
|
|
44
|
+
return fn();
|
|
45
|
+
const start = Date.now();
|
|
46
|
+
try {
|
|
47
|
+
const result = await fn();
|
|
48
|
+
this.log({
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
operation,
|
|
51
|
+
agentId: opts.agentId,
|
|
52
|
+
sessionId: opts.sessionId,
|
|
53
|
+
args_summary: opts.args,
|
|
54
|
+
durationMs: Date.now() - start,
|
|
55
|
+
});
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
this.log({
|
|
60
|
+
timestamp: new Date().toISOString(),
|
|
61
|
+
operation,
|
|
62
|
+
agentId: opts.agentId,
|
|
63
|
+
sessionId: opts.sessionId,
|
|
64
|
+
args_summary: opts.args,
|
|
65
|
+
result_summary: { error: err instanceof Error ? err.message : String(err) },
|
|
66
|
+
durationMs: Date.now() - start,
|
|
67
|
+
});
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.AuditLogger = AuditLogger;
|
|
73
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/mcp/audit.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAyBH,MAAa,WAAW;IACL,MAAM,CAAkB;IAEzC,YAAY,MAAwB;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,IAAI,CAAC;IAC/B,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;IAC9B,CAAC;IAED,GAAG,CAAC,KAAiB;QACnB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC1B,GAAG,KAAK;gBACR,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACvD,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,+DAA+D;QACjE,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI,CACR,SAAyB,EACzB,IAA8E,EAC9E,EAAoB;QAEpB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,EAAE,CAAC;QAE9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC;gBACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,SAAS;gBACT,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,YAAY,EAAE,IAAI,CAAC,IAAI;gBACvB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;aAC/B,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC;gBACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,SAAS;gBACT,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,YAAY,EAAE,IAAI,CAAC,IAAI;gBACvB,cAAc,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;gBAC3E,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;aAC/B,CAAC,CAAC;YACH,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;CACF;AA5DD,kCA4DC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Health contracts, risk levels, and recovery policy types used by the
|
|
3
|
+
* Ojas MCP server.
|
|
4
|
+
*
|
|
5
|
+
* A health contract is the "service-level agreement" between Ojas and an
|
|
6
|
+
* agent: what counts as healthy, what risks the agent carries, what
|
|
7
|
+
* recovery actions apply when things go wrong.
|
|
8
|
+
*/
|
|
9
|
+
import type { OjasModuleName } from '../types';
|
|
10
|
+
export type AgentRiskLevel = 'low' | 'medium' | 'high' | 'critical';
|
|
11
|
+
export type ToolMode = 'observe' | 'recommend' | 'apply';
|
|
12
|
+
export type RecoveryActionId = 'compress_context' | 'reset_plan' | 'freeze_memory_writes' | 'quarantine_input' | 'generate_fallback_response' | 'enter_safe_mode' | 'human_escalation' | 'reduce_tool_calls' | 'switch_to_cached_sources';
|
|
13
|
+
export interface HealthThresholds {
|
|
14
|
+
/** Minimum overall Ojas score (0–100) the agent must maintain. */
|
|
15
|
+
minimum_ojas_score?: number;
|
|
16
|
+
/** Minimum Aahar context-quality score (0–100). */
|
|
17
|
+
minimum_context_quality?: number;
|
|
18
|
+
/** Maximum tolerated hallucination risk (0–100 percent). */
|
|
19
|
+
maximum_hallucination_risk?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface RecoveryPolicy {
|
|
22
|
+
on_context_overload?: RecoveryActionId;
|
|
23
|
+
on_prompt_injection?: RecoveryActionId;
|
|
24
|
+
on_repeated_failure?: RecoveryActionId;
|
|
25
|
+
on_memory_conflict?: RecoveryActionId;
|
|
26
|
+
on_tool_failure_loop?: RecoveryActionId;
|
|
27
|
+
}
|
|
28
|
+
export interface HealthContract {
|
|
29
|
+
agent_id: string;
|
|
30
|
+
agent_name?: string;
|
|
31
|
+
agent_type?: string;
|
|
32
|
+
risk_level: AgentRiskLevel;
|
|
33
|
+
description?: string;
|
|
34
|
+
allowed_tools?: string[];
|
|
35
|
+
health_thresholds: Required<Pick<HealthThresholds, 'minimum_ojas_score'>> & HealthThresholds;
|
|
36
|
+
recovery_policy: RecoveryPolicy;
|
|
37
|
+
/** ISO timestamp when the contract was created. */
|
|
38
|
+
created_at: string;
|
|
39
|
+
/** Stable id assigned to the contract. */
|
|
40
|
+
health_contract_id: string;
|
|
41
|
+
}
|
|
42
|
+
export interface AgentToolHealth {
|
|
43
|
+
tool_name: string;
|
|
44
|
+
total_calls: number;
|
|
45
|
+
successes: number;
|
|
46
|
+
failures: number;
|
|
47
|
+
timeouts: number;
|
|
48
|
+
latency_sum_ms: number;
|
|
49
|
+
last_seen_at: string;
|
|
50
|
+
}
|
|
51
|
+
export type HealthState = 'healthy' | 'watch' | 'degraded' | 'critical';
|
|
52
|
+
export interface ModuleScoresPercent {
|
|
53
|
+
aahar: number;
|
|
54
|
+
nidra: number;
|
|
55
|
+
vyayam: number;
|
|
56
|
+
raksha: number;
|
|
57
|
+
agni: number;
|
|
58
|
+
pulse: number;
|
|
59
|
+
chikitsa: number;
|
|
60
|
+
}
|
|
61
|
+
export interface AffectedModulesList {
|
|
62
|
+
modules: OjasModuleName[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Defaults applied when an agent is auto-registered (i.e. a tool is called
|
|
66
|
+
* with an `agent_id` that has not yet been explicitly registered).
|
|
67
|
+
*/
|
|
68
|
+
export declare const DEFAULT_HEALTH_THRESHOLDS: Required<HealthThresholds>;
|
|
69
|
+
export declare const DEFAULT_RECOVERY_POLICY: RecoveryPolicy;
|
|
70
|
+
/**
|
|
71
|
+
* Classify a 0–100 Ojas score into a human-readable health state.
|
|
72
|
+
* Thresholds are tuned to match the spec example ("Agent is healthy but
|
|
73
|
+
* shows mild degradation under broad research tasks" at 82, etc.).
|
|
74
|
+
*/
|
|
75
|
+
export declare function classifyHealthState(score100: number, contract?: HealthContract): HealthState;
|
|
76
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/mcp/contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEpE,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;AAEzD,MAAM,MAAM,gBAAgB,GACxB,kBAAkB,GAClB,YAAY,GACZ,sBAAsB,GACtB,kBAAkB,GAClB,4BAA4B,GAC5B,iBAAiB,GACjB,kBAAkB,GAClB,mBAAmB,GACnB,0BAA0B,CAAC;AAE/B,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mDAAmD;IACnD,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,4DAA4D;IAC5D,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,mBAAmB,CAAC,EAAE,gBAAgB,CAAC;IACvC,mBAAmB,CAAC,EAAE,gBAAgB,CAAC;IACvC,mBAAmB,CAAC,EAAE,gBAAgB,CAAC;IACvC,kBAAkB,CAAC,EAAE,gBAAgB,CAAC;IACtC,oBAAoB,CAAC,EAAE,gBAAgB,CAAC;CACzC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,EAAE,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,oBAAoB,CAAC,CAAC,GAAG,gBAAgB,CAAC;IAC7F,eAAe,EAAE,cAAc,CAAC;IAChC,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;AAExE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,gBAAgB,CAIhE,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,cAMrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,WAAW,CAM5F"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Health contracts, risk levels, and recovery policy types used by the
|
|
4
|
+
* Ojas MCP server.
|
|
5
|
+
*
|
|
6
|
+
* A health contract is the "service-level agreement" between Ojas and an
|
|
7
|
+
* agent: what counts as healthy, what risks the agent carries, what
|
|
8
|
+
* recovery actions apply when things go wrong.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.DEFAULT_RECOVERY_POLICY = exports.DEFAULT_HEALTH_THRESHOLDS = void 0;
|
|
12
|
+
exports.classifyHealthState = classifyHealthState;
|
|
13
|
+
/**
|
|
14
|
+
* Defaults applied when an agent is auto-registered (i.e. a tool is called
|
|
15
|
+
* with an `agent_id` that has not yet been explicitly registered).
|
|
16
|
+
*/
|
|
17
|
+
exports.DEFAULT_HEALTH_THRESHOLDS = {
|
|
18
|
+
minimum_ojas_score: 70,
|
|
19
|
+
minimum_context_quality: 65,
|
|
20
|
+
maximum_hallucination_risk: 20,
|
|
21
|
+
};
|
|
22
|
+
exports.DEFAULT_RECOVERY_POLICY = {
|
|
23
|
+
on_context_overload: 'compress_context',
|
|
24
|
+
on_prompt_injection: 'quarantine_input',
|
|
25
|
+
on_repeated_failure: 'enter_safe_mode',
|
|
26
|
+
on_memory_conflict: 'freeze_memory_writes',
|
|
27
|
+
on_tool_failure_loop: 'generate_fallback_response',
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Classify a 0–100 Ojas score into a human-readable health state.
|
|
31
|
+
* Thresholds are tuned to match the spec example ("Agent is healthy but
|
|
32
|
+
* shows mild degradation under broad research tasks" at 82, etc.).
|
|
33
|
+
*/
|
|
34
|
+
function classifyHealthState(score100, contract) {
|
|
35
|
+
const minimum = contract?.health_thresholds.minimum_ojas_score ?? exports.DEFAULT_HEALTH_THRESHOLDS.minimum_ojas_score;
|
|
36
|
+
if (score100 >= 90)
|
|
37
|
+
return 'healthy';
|
|
38
|
+
if (score100 >= minimum)
|
|
39
|
+
return 'watch';
|
|
40
|
+
if (score100 >= Math.max(40, minimum - 20))
|
|
41
|
+
return 'degraded';
|
|
42
|
+
return 'critical';
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/mcp/contracts.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAoGH,kDAMC;AA7BD;;;GAGG;AACU,QAAA,yBAAyB,GAA+B;IACnE,kBAAkB,EAAE,EAAE;IACtB,uBAAuB,EAAE,EAAE;IAC3B,0BAA0B,EAAE,EAAE;CAC/B,CAAC;AAEW,QAAA,uBAAuB,GAAmB;IACrD,mBAAmB,EAAE,kBAAkB;IACvC,mBAAmB,EAAE,kBAAkB;IACvC,mBAAmB,EAAE,iBAAiB;IACtC,kBAAkB,EAAE,sBAAsB;IAC1C,oBAAoB,EAAE,4BAA4B;CACnD,CAAC;AAEF;;;;GAIG;AACH,SAAgB,mBAAmB,CAAC,QAAgB,EAAE,QAAyB;IAC7E,MAAM,OAAO,GAAG,QAAQ,EAAE,iBAAiB,CAAC,kBAAkB,IAAI,iCAAyB,CAAC,kBAAkB,CAAC;IAC/G,IAAI,QAAQ,IAAI,EAAE;QAAE,OAAO,SAAS,CAAC;IACrC,IAAI,QAAQ,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IACxC,IAAI,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,CAAC;QAAE,OAAO,UAAU,CAAC;IAC9D,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard response envelope for every Ojas MCP tool.
|
|
3
|
+
*
|
|
4
|
+
* Per the Ojas tool-design contract, every tool returns a uniform set of
|
|
5
|
+
* meta fields (`status`, `ojas_score_delta`, `affected_modules`,
|
|
6
|
+
* `events_created`, `recommended_next_actions`, `requires_human_review`)
|
|
7
|
+
* plus a `correlation_id` and `agent_id`, with the tool-specific payload
|
|
8
|
+
* merged on top.
|
|
9
|
+
*/
|
|
10
|
+
import type { OjasModuleName } from '../types';
|
|
11
|
+
export type EnvelopeStatus = 'success' | 'warning' | 'failed';
|
|
12
|
+
export interface EnvelopeMeta {
|
|
13
|
+
status?: EnvelopeStatus;
|
|
14
|
+
agent_id?: string;
|
|
15
|
+
correlation_id?: string;
|
|
16
|
+
ojas_score_delta?: number;
|
|
17
|
+
affected_modules?: OjasModuleName[];
|
|
18
|
+
events_created?: string[];
|
|
19
|
+
recommended_next_actions?: string[];
|
|
20
|
+
requires_human_review?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Public envelope shape returned to clients. Tool-specific fields are
|
|
24
|
+
* merged in via `T`.
|
|
25
|
+
*/
|
|
26
|
+
export type Envelope<T extends object = Record<string, unknown>> = T & {
|
|
27
|
+
status: EnvelopeStatus;
|
|
28
|
+
agent_id: string | null;
|
|
29
|
+
correlation_id: string;
|
|
30
|
+
ojas_score_delta: number;
|
|
31
|
+
affected_modules: OjasModuleName[];
|
|
32
|
+
events_created: string[];
|
|
33
|
+
recommended_next_actions: string[];
|
|
34
|
+
requires_human_review: boolean;
|
|
35
|
+
};
|
|
36
|
+
export declare function generateCorrelationId(): string;
|
|
37
|
+
export declare function envelope<T extends object>(data: T, meta?: EnvelopeMeta): Envelope<T>;
|
|
38
|
+
/** Convenience: wrap an envelope as an MCP `tools/call` text-content reply. */
|
|
39
|
+
export declare function mcpReply<T extends object>(data: T, meta?: EnvelopeMeta): {
|
|
40
|
+
content: {
|
|
41
|
+
type: "text";
|
|
42
|
+
text: string;
|
|
43
|
+
}[];
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Payload for every tool that accepts a `session_id` input. Session
|
|
47
|
+
* isolation is implemented in the MCP registry: non-default session IDs
|
|
48
|
+
* receive their own Ojas runtime state and optional persistence row.
|
|
49
|
+
*/
|
|
50
|
+
export declare function sessionScopeFields(session_id: string | undefined | null): {
|
|
51
|
+
session_id: string | null;
|
|
52
|
+
session_scope_supported: true;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Categories returned by `classifyError`, attached to every failed
|
|
56
|
+
* envelope as `error_code`. See the comment on `OjasError` for the
|
|
57
|
+
* canonical mapping.
|
|
58
|
+
*/
|
|
59
|
+
export type ErrorCode = 'invalid_input' | 'policy_violation' | 'not_found' | 'internal_error';
|
|
60
|
+
/**
|
|
61
|
+
* Typed error thrown from internal Ojas boundaries (registry, schema
|
|
62
|
+
* validators, policy gates) so `safeHandler` can label the failed
|
|
63
|
+
* envelope without pattern-matching on the message string. Message
|
|
64
|
+
* heuristics in `classifyError` remain as a fallback for third-party
|
|
65
|
+
* throws and unexpected internal exceptions.
|
|
66
|
+
*
|
|
67
|
+
* Canonical category mapping:
|
|
68
|
+
*
|
|
69
|
+
* - `invalid_input` — schema validation, malformed dates, bad types.
|
|
70
|
+
* Caller bug, not a safety event.
|
|
71
|
+
* - `policy_violation` — health-contract or allowlist refusals
|
|
72
|
+
* (duplicate-register, replacement disabled,
|
|
73
|
+
* unknown agent on a strict allowlist).
|
|
74
|
+
* Caller asked for something the policy forbids.
|
|
75
|
+
* - `not_found` — agent or resource lookup failures.
|
|
76
|
+
* - `internal_error` — everything else. These are the only ones that
|
|
77
|
+
* require human review by default; everything
|
|
78
|
+
* else is a caller-side problem.
|
|
79
|
+
*/
|
|
80
|
+
export declare class OjasError extends Error {
|
|
81
|
+
readonly code: ErrorCode;
|
|
82
|
+
readonly humanReview: boolean;
|
|
83
|
+
constructor(code: ErrorCode, message: string, humanReview?: boolean);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Classify any thrown value into an `ErrorCode`. Prefers a typed
|
|
87
|
+
* `OjasError.code` when available; otherwise falls back to message
|
|
88
|
+
* substring heuristics. The heuristics path is intentionally narrow —
|
|
89
|
+
* unknown messages are labelled `internal_error` so they still page a
|
|
90
|
+
* human and we get a signal to convert that throw site to `OjasError`.
|
|
91
|
+
*/
|
|
92
|
+
export declare function classifyError(err: unknown): ErrorCode;
|
|
93
|
+
/**
|
|
94
|
+
* Wrap an Ojas tool handler so any thrown error is returned as a
|
|
95
|
+
* structured `status: 'failed'` envelope rather than escaping as an MCP
|
|
96
|
+
* protocol-level error. Variadic to preserve any extra args (context,
|
|
97
|
+
* request-id, cancellation handle) the MCP SDK may pass alongside the
|
|
98
|
+
* input arguments — dropping those would lock us out of future SDK
|
|
99
|
+
* features like per-call auth context.
|
|
100
|
+
*
|
|
101
|
+
* Errors are classified by message into `invalid_input`,
|
|
102
|
+
* `policy_violation`, `not_found`, or `internal_error`. Only internal
|
|
103
|
+
* errors set `requires_human_review: true` so dashboards aren't paged
|
|
104
|
+
* for routine validation failures.
|
|
105
|
+
*/
|
|
106
|
+
export declare function safeHandler(toolName: string, handler: (...args: any[]) => Promise<ReturnType<typeof mcpReply>>): (...args: unknown[]) => Promise<ReturnType<typeof mcpReply>>;
|
|
107
|
+
//# sourceMappingURL=envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/mcp/envelope.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG/C,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;IACpC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG;IACrE,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,cAAc,EAAE,CAAC;IACnC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAYxF;AAED,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAE,YAAiB;;;;;EAO1E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG;IACzE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uBAAuB,EAAE,IAAI,CAAC;CAC/B,CAKA;AAED;;;;GAIG;AACH,MAAM,MAAM,SAAS,GACjB,eAAe,GACf,kBAAkB,GAClB,WAAW,GACX,gBAAgB,CAAC;AAErB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;gBAClB,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,UAAQ;CAMlE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,CA2BrD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAEhB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,GAChE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAgC9D"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Standard response envelope for every Ojas MCP tool.
|
|
4
|
+
*
|
|
5
|
+
* Per the Ojas tool-design contract, every tool returns a uniform set of
|
|
6
|
+
* meta fields (`status`, `ojas_score_delta`, `affected_modules`,
|
|
7
|
+
* `events_created`, `recommended_next_actions`, `requires_human_review`)
|
|
8
|
+
* plus a `correlation_id` and `agent_id`, with the tool-specific payload
|
|
9
|
+
* merged on top.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.OjasError = void 0;
|
|
13
|
+
exports.generateCorrelationId = generateCorrelationId;
|
|
14
|
+
exports.envelope = envelope;
|
|
15
|
+
exports.mcpReply = mcpReply;
|
|
16
|
+
exports.sessionScopeFields = sessionScopeFields;
|
|
17
|
+
exports.classifyError = classifyError;
|
|
18
|
+
exports.safeHandler = safeHandler;
|
|
19
|
+
const id_1 = require("../util/id");
|
|
20
|
+
function generateCorrelationId() {
|
|
21
|
+
return (0, id_1.newId)('cor');
|
|
22
|
+
}
|
|
23
|
+
function envelope(data, meta = {}) {
|
|
24
|
+
return {
|
|
25
|
+
status: meta.status ?? 'success',
|
|
26
|
+
agent_id: meta.agent_id ?? null,
|
|
27
|
+
correlation_id: meta.correlation_id ?? generateCorrelationId(),
|
|
28
|
+
ojas_score_delta: meta.ojas_score_delta ?? 0,
|
|
29
|
+
affected_modules: meta.affected_modules ?? [],
|
|
30
|
+
events_created: meta.events_created ?? [],
|
|
31
|
+
recommended_next_actions: meta.recommended_next_actions ?? [],
|
|
32
|
+
requires_human_review: meta.requires_human_review ?? false,
|
|
33
|
+
...data,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Convenience: wrap an envelope as an MCP `tools/call` text-content reply. */
|
|
37
|
+
function mcpReply(data, meta = {}) {
|
|
38
|
+
const payload = envelope(data, meta);
|
|
39
|
+
return {
|
|
40
|
+
content: [
|
|
41
|
+
{ type: 'text', text: JSON.stringify(payload, null, 2) },
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Payload for every tool that accepts a `session_id` input. Session
|
|
47
|
+
* isolation is implemented in the MCP registry: non-default session IDs
|
|
48
|
+
* receive their own Ojas runtime state and optional persistence row.
|
|
49
|
+
*/
|
|
50
|
+
function sessionScopeFields(session_id) {
|
|
51
|
+
return {
|
|
52
|
+
session_id: session_id ?? null,
|
|
53
|
+
session_scope_supported: true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Typed error thrown from internal Ojas boundaries (registry, schema
|
|
58
|
+
* validators, policy gates) so `safeHandler` can label the failed
|
|
59
|
+
* envelope without pattern-matching on the message string. Message
|
|
60
|
+
* heuristics in `classifyError` remain as a fallback for third-party
|
|
61
|
+
* throws and unexpected internal exceptions.
|
|
62
|
+
*
|
|
63
|
+
* Canonical category mapping:
|
|
64
|
+
*
|
|
65
|
+
* - `invalid_input` — schema validation, malformed dates, bad types.
|
|
66
|
+
* Caller bug, not a safety event.
|
|
67
|
+
* - `policy_violation` — health-contract or allowlist refusals
|
|
68
|
+
* (duplicate-register, replacement disabled,
|
|
69
|
+
* unknown agent on a strict allowlist).
|
|
70
|
+
* Caller asked for something the policy forbids.
|
|
71
|
+
* - `not_found` — agent or resource lookup failures.
|
|
72
|
+
* - `internal_error` — everything else. These are the only ones that
|
|
73
|
+
* require human review by default; everything
|
|
74
|
+
* else is a caller-side problem.
|
|
75
|
+
*/
|
|
76
|
+
class OjasError extends Error {
|
|
77
|
+
code;
|
|
78
|
+
humanReview;
|
|
79
|
+
constructor(code, message, humanReview = false) {
|
|
80
|
+
super(message);
|
|
81
|
+
this.name = 'OjasError';
|
|
82
|
+
this.code = code;
|
|
83
|
+
this.humanReview = humanReview;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.OjasError = OjasError;
|
|
87
|
+
/**
|
|
88
|
+
* Classify any thrown value into an `ErrorCode`. Prefers a typed
|
|
89
|
+
* `OjasError.code` when available; otherwise falls back to message
|
|
90
|
+
* substring heuristics. The heuristics path is intentionally narrow —
|
|
91
|
+
* unknown messages are labelled `internal_error` so they still page a
|
|
92
|
+
* human and we get a signal to convert that throw site to `OjasError`.
|
|
93
|
+
*/
|
|
94
|
+
function classifyError(err) {
|
|
95
|
+
if (err instanceof OjasError)
|
|
96
|
+
return err.code;
|
|
97
|
+
const message = err instanceof Error ? err.message : typeof err === 'string' ? err : String(err);
|
|
98
|
+
const m = message.toLowerCase();
|
|
99
|
+
if (m.includes('already registered') ||
|
|
100
|
+
m.includes('replacement is disabled') ||
|
|
101
|
+
m.includes('not allowed') ||
|
|
102
|
+
m.includes('auto-registration is disabled') ||
|
|
103
|
+
m.includes('maxagents')) {
|
|
104
|
+
return 'policy_violation';
|
|
105
|
+
}
|
|
106
|
+
if (m.includes('not found') || m.includes('unknown agent')) {
|
|
107
|
+
return 'not_found';
|
|
108
|
+
}
|
|
109
|
+
if (m.includes('must be') ||
|
|
110
|
+
m.includes('must include') ||
|
|
111
|
+
m.includes('invalid') ||
|
|
112
|
+
m.includes('is in the future') ||
|
|
113
|
+
m.includes('iso-8601')) {
|
|
114
|
+
return 'invalid_input';
|
|
115
|
+
}
|
|
116
|
+
return 'internal_error';
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Wrap an Ojas tool handler so any thrown error is returned as a
|
|
120
|
+
* structured `status: 'failed'` envelope rather than escaping as an MCP
|
|
121
|
+
* protocol-level error. Variadic to preserve any extra args (context,
|
|
122
|
+
* request-id, cancellation handle) the MCP SDK may pass alongside the
|
|
123
|
+
* input arguments — dropping those would lock us out of future SDK
|
|
124
|
+
* features like per-call auth context.
|
|
125
|
+
*
|
|
126
|
+
* Errors are classified by message into `invalid_input`,
|
|
127
|
+
* `policy_violation`, `not_found`, or `internal_error`. Only internal
|
|
128
|
+
* errors set `requires_human_review: true` so dashboards aren't paged
|
|
129
|
+
* for routine validation failures.
|
|
130
|
+
*/
|
|
131
|
+
function safeHandler(toolName,
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
133
|
+
handler) {
|
|
134
|
+
return async (...args) => {
|
|
135
|
+
try {
|
|
136
|
+
return await handler(...args);
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
140
|
+
const errorCode = classifyError(err);
|
|
141
|
+
const firstArg = args[0];
|
|
142
|
+
const agent_id = firstArg && typeof firstArg.agent_id === 'string' ? firstArg.agent_id : null;
|
|
143
|
+
// Only true internal crashes page a human by default. Validation /
|
|
144
|
+
// policy / not-found are caller-side problems and should show up
|
|
145
|
+
// in client logs, not the operator pager. A typed OjasError can
|
|
146
|
+
// override this when an internal boundary needs human attention
|
|
147
|
+
// even though the code itself is a validation / policy class.
|
|
148
|
+
const requires_human_review = err instanceof OjasError ? err.humanReview : errorCode === 'internal_error';
|
|
149
|
+
return mcpReply({
|
|
150
|
+
accepted: false,
|
|
151
|
+
error: message,
|
|
152
|
+
error_class: `${toolName}_error`,
|
|
153
|
+
error_code: errorCode,
|
|
154
|
+
}, {
|
|
155
|
+
status: 'failed',
|
|
156
|
+
agent_id: agent_id ?? undefined,
|
|
157
|
+
requires_human_review,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/mcp/envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-agent registry for the Ojas MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Each registered agent gets its own `Ojas` instance plus a stored
|
|
5
|
+
* `HealthContract`, recent-history caches, and operational flags
|
|
6
|
+
* (e.g. safe mode). The MCP server proxies tool calls to the
|
|
7
|
+
* registry, which routes by `agent_id`.
|
|
8
|
+
*/
|
|
9
|
+
import { Ojas } from '../index';
|
|
10
|
+
import type { AgentHealthReport } from '../types';
|
|
11
|
+
import type { PersistenceStore } from '../persistence/types';
|
|
12
|
+
import { AgentRiskLevel, AgentToolHealth, HealthContract, HealthThresholds, RecoveryPolicy } from './contracts';
|
|
13
|
+
export interface RegisterAgentInput {
|
|
14
|
+
agent_id: string;
|
|
15
|
+
agent_name?: string;
|
|
16
|
+
agent_type?: string;
|
|
17
|
+
risk_level?: AgentRiskLevel;
|
|
18
|
+
description?: string;
|
|
19
|
+
allowed_tools?: string[];
|
|
20
|
+
health_thresholds?: HealthThresholds;
|
|
21
|
+
recovery_policy?: RecoveryPolicy;
|
|
22
|
+
/** Explicitly replace an existing registration and all its runtime state. */
|
|
23
|
+
replace_existing?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface RecentEvent {
|
|
26
|
+
id: string;
|
|
27
|
+
timestamp: string;
|
|
28
|
+
event_type: string;
|
|
29
|
+
description: string;
|
|
30
|
+
}
|
|
31
|
+
export interface AgentEntry {
|
|
32
|
+
agent_id: string;
|
|
33
|
+
session_id: string;
|
|
34
|
+
ojas: Ojas;
|
|
35
|
+
contract: HealthContract;
|
|
36
|
+
safe_mode: boolean;
|
|
37
|
+
safe_mode_reason?: string;
|
|
38
|
+
safe_mode_restrictions: string[];
|
|
39
|
+
tool_health: Map<string, AgentToolHealth>;
|
|
40
|
+
recent_events: RecentEvent[];
|
|
41
|
+
last_health_score: number;
|
|
42
|
+
last_health_report?: AgentHealthReport;
|
|
43
|
+
}
|
|
44
|
+
export interface AgentRegistryOptions {
|
|
45
|
+
/** Hard cap on simultaneously-tracked agents. Registration fails once full. */
|
|
46
|
+
maxAgents?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Whether unknown `agent_id`s may be silently auto-registered when a tool
|
|
49
|
+
* is invoked. Defaults to true for developer-friendly local use; set to
|
|
50
|
+
* false (e.g. via the OJAS_DISABLE_AUTO_REGISTER env var on the MCP
|
|
51
|
+
* server) to require an explicit `ojas_register_agent` call.
|
|
52
|
+
*/
|
|
53
|
+
autoRegister?: boolean;
|
|
54
|
+
/** Optional allowlist of agent IDs this registry will accept. */
|
|
55
|
+
allowedAgentIds?: string[];
|
|
56
|
+
/**
|
|
57
|
+
* Whether `register(replace_existing: true)` is honoured. **Defaults to
|
|
58
|
+
* false** — replacing an existing registration wipes its accumulated
|
|
59
|
+
* Ojas state (traces, memories, events, contract). Production
|
|
60
|
+
* deployments should leave this off and rely on operator action to
|
|
61
|
+
* reset state intentionally. The MCP server wires this from
|
|
62
|
+
* `OJAS_ALLOW_REPLACE_EXISTING=1`.
|
|
63
|
+
*/
|
|
64
|
+
allowReplaceExisting?: boolean;
|
|
65
|
+
/** Optional durable store used to hydrate and persist session state. */
|
|
66
|
+
persistenceStore?: PersistenceStore;
|
|
67
|
+
}
|
|
68
|
+
export declare class AgentRegistry {
|
|
69
|
+
private agents;
|
|
70
|
+
private readonly maxAgents;
|
|
71
|
+
private readonly autoRegister;
|
|
72
|
+
private readonly allowedAgentIds?;
|
|
73
|
+
private readonly allowReplaceExisting;
|
|
74
|
+
private readonly persistenceStore?;
|
|
75
|
+
constructor(opts?: AgentRegistryOptions);
|
|
76
|
+
private getSessionMap;
|
|
77
|
+
private putEntry;
|
|
78
|
+
private buildEntry;
|
|
79
|
+
private hydrate;
|
|
80
|
+
private snapshot;
|
|
81
|
+
persist(entry: AgentEntry): void;
|
|
82
|
+
private assertAgentAllowed;
|
|
83
|
+
/** Register an agent. Existing registrations are protected unless replace_existing=true. */
|
|
84
|
+
register(input: RegisterAgentInput): AgentEntry;
|
|
85
|
+
/** Look up an existing agent (returns undefined if not registered). */
|
|
86
|
+
get(agentId: string, sessionId?: string): AgentEntry | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Look up an agent, auto-registering with conservative defaults if
|
|
89
|
+
* missing. Throws when auto-registration is disabled — production
|
|
90
|
+
* deployments should disable it and require an explicit register call.
|
|
91
|
+
*/
|
|
92
|
+
getOrAutoRegister(agentId: string, fallbackRisk?: AgentRiskLevel): AgentEntry;
|
|
93
|
+
getOrAutoRegisterSession(agentId: string, sessionId: string | undefined, fallbackRisk?: AgentRiskLevel): AgentEntry;
|
|
94
|
+
list(): readonly Readonly<AgentEntry>[];
|
|
95
|
+
/** Add an event to the agent's recent-events ring buffer. */
|
|
96
|
+
recordEvent(entry: AgentEntry, eventType: string, description: string): RecentEvent;
|
|
97
|
+
/** Update tool-health stats for an agent. */
|
|
98
|
+
recordToolOutcome(entry: AgentEntry, toolName: string, outcome: {
|
|
99
|
+
success: boolean;
|
|
100
|
+
latencyMs: number;
|
|
101
|
+
timeout: boolean;
|
|
102
|
+
}): AgentToolHealth;
|
|
103
|
+
/**
|
|
104
|
+
* Replace the agent's stored health snapshot and return the score delta
|
|
105
|
+
* (new − previous) so the caller can include it in the envelope.
|
|
106
|
+
*/
|
|
107
|
+
updateHealthSnapshot(entry: AgentEntry, report: AgentHealthReport): number;
|
|
108
|
+
setSafeMode(entry: AgentEntry, on: boolean, reason?: string, restrictions?: string[]): void;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/mcp/registry.ts"],"names":[],"mappings":"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"}
|