@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
package/docs/MCP.md
ADDED
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
# MCP Server
|
|
2
|
+
|
|
3
|
+
Ojas ships an MCP server that exposes 18 agent-health tools to Claude Code, Cursor, Windsurf, and other MCP-compatible clients.
|
|
4
|
+
|
|
5
|
+
Each IDE session gets its own multi-agent registry. Every `agent_id` maps to an Ojas instance and `HealthContract`. Unknown agents can auto-register with conservative defaults so tools can be called without manual setup — but production deployments should disable that and use the allowlist (see [Environment variables](#env)).
|
|
6
|
+
|
|
7
|
+
| Section | What's inside |
|
|
8
|
+
|---|---|
|
|
9
|
+
| [Build](#build) | Compile the MCP server entry point |
|
|
10
|
+
| [MCP Configuration](#mcp-config) | Claude Code, Cursor, Windsurf wiring |
|
|
11
|
+
| [Environment variables](#env) | Operational knobs for shared deployments |
|
|
12
|
+
| [A typical first session](#first-session) | Six tool calls that show the full loop |
|
|
13
|
+
| [Tools — Setup & telemetry](#tools-setup) | `ojas_register_agent`, `ojas_ingest_trace` |
|
|
14
|
+
| [Tools — Decisions](#tools-decisions) | `ojas_get_health`, `ojas_is_agent_fit_to_continue` |
|
|
15
|
+
| [Tools — Context safety](#tools-context) | `ojas_score_context`, `ojas_build_context`, `ojas_scan_for_injection` |
|
|
16
|
+
| [Tools — Output quality & routing](#tools-output) | `ojas_detect_hallucination`, `ojas_recommend_model_route`, `ojas_distill_response`, `ojas_record_task_outcome` |
|
|
17
|
+
| [Tools — Memory hygiene](#tools-memory) | `ojas_audit_memory`, `ojas_validate_memory_write`, `ojas_consolidate_memory` |
|
|
18
|
+
| [Tools — Repair](#tools-repair) | `ojas_diagnose_failure`, `ojas_run_recovery` |
|
|
19
|
+
| [Tools — Reporting & handoff](#tools-reporting) | `ojas_generate_handoff`, `ojas_generate_health_report` |
|
|
20
|
+
| [Response envelope](#envelope) | Standard fields wrapping every tool reply |
|
|
21
|
+
| [Suggested usage loop](#usage-loop) | The canonical call order |
|
|
22
|
+
| [Verification](#verification) | One-line smoke test for a fresh install |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
<a id="build"></a>
|
|
27
|
+
## Build
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install
|
|
31
|
+
npm run build
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Compiled entry point:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
dist/mcp/server.js
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Replace `/absolute/path/to/ojas` in the examples below with your local clone path.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
<a id="mcp-config"></a>
|
|
45
|
+
## MCP Configuration
|
|
46
|
+
|
|
47
|
+
### Claude Code
|
|
48
|
+
|
|
49
|
+
Project-level `.mcp.json`:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"ojas": {
|
|
55
|
+
"command": "node",
|
|
56
|
+
"args": ["/absolute/path/to/ojas/dist/mcp/server.js"],
|
|
57
|
+
"env": {
|
|
58
|
+
"OJAS_AGENT_ID": "claude-code"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or with the CLI:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
claude mcp add ojas -- node /absolute/path/to/ojas/dist/mcp/server.js
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Cursor
|
|
72
|
+
|
|
73
|
+
Project-level `.cursor/mcp.json` or global `~/.cursor/mcp.json`:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"mcpServers": {
|
|
78
|
+
"ojas": {
|
|
79
|
+
"command": "node",
|
|
80
|
+
"args": ["/absolute/path/to/ojas/dist/mcp/server.js"],
|
|
81
|
+
"env": {
|
|
82
|
+
"OJAS_AGENT_ID": "cursor"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Windsurf
|
|
90
|
+
|
|
91
|
+
`~/.codeium/windsurf/mcp_config.json`:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"mcpServers": {
|
|
96
|
+
"ojas": {
|
|
97
|
+
"command": "node",
|
|
98
|
+
"args": ["/absolute/path/to/ojas/dist/mcp/server.js"],
|
|
99
|
+
"env": {
|
|
100
|
+
"OJAS_AGENT_ID": "windsurf"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
<a id="env"></a>
|
|
110
|
+
## Environment variables
|
|
111
|
+
|
|
112
|
+
| Variable | Default | Effect |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| `OJAS_AGENT_ID` | unset | Pre-register a single agent at startup with conservative defaults. Additional agents can still be added via `ojas_register_agent`. |
|
|
115
|
+
| `OJAS_DISABLE_AUTO_REGISTER` | unset | Set to `1` to reject MCP calls whose `agent_id` has not been explicitly registered. Recommended for production. |
|
|
116
|
+
| `OJAS_MAX_AGENTS` | `256` | Hard cap on simultaneously-tracked agents. Once full, `ojas_register_agent` throws rather than silently evicting. |
|
|
117
|
+
| `OJAS_ALLOWED_AGENT_IDS` | unset | Comma-separated allowlist of `agent_id`s. When set, any registration or auto-register attempt for an id outside this list is rejected. |
|
|
118
|
+
| `OJAS_ALLOW_REPLACE_EXISTING` | unset | Set to `1` to permit `register_agent(replace_existing=true)`. **Disabled by default** because replacement wipes the agent's accumulated Ojas state. |
|
|
119
|
+
| `OJAS_TRUSTED_SINGLE_TENANT` | unset | Acknowledgement that the operator understands the no-auth single-tenant trust model. Suppresses the loud stderr warning emitted at startup; does **not** add authentication. |
|
|
120
|
+
|
|
121
|
+
> `register_agent` rejects a duplicate `agent_id` by default. To replace an existing agent (and discard its accumulated Ojas state) the caller must pass `replace_existing: true` **and** the registry must be configured with `allowReplaceExisting: true` (or the server started with `OJAS_ALLOW_REPLACE_EXISTING=1`). Silently overwriting a long-lived agent's history would erase the very telemetry the system exists to capture.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
<a id="trust-boundary"></a>
|
|
126
|
+
## Local-only stdio trust boundary
|
|
127
|
+
|
|
128
|
+
The MCP server is designed for **local stdio use**. It assumes the MCP
|
|
129
|
+
host that starts the process is trusted. Agent IDs are routing
|
|
130
|
+
identifiers, **not credentials**, and there is no per-call authentication
|
|
131
|
+
inside the server — there is no portable stdio auth channel for one to
|
|
132
|
+
hook into. This is the intended trust boundary for v0.2, not a deferred
|
|
133
|
+
fix; see the [security non-goals](./SECURITY.md#security-non-goals-for-v02).
|
|
134
|
+
|
|
135
|
+
Recommended locked-down local configuration:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
OJAS_TRUSTED_SINGLE_TENANT=1 # acknowledge the trust model (silences warning)
|
|
139
|
+
OJAS_DISABLE_AUTO_REGISTER=1 # reject unknown agent_id, force explicit registration
|
|
140
|
+
OJAS_ALLOWED_AGENT_IDS=my-agent # hard allowlist
|
|
141
|
+
OJAS_MAX_AGENTS=1 # one agent per process
|
|
142
|
+
# do NOT set OJAS_ALLOW_REPLACE_EXISTING unless intentionally resetting state
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Operationally:
|
|
146
|
+
|
|
147
|
+
- Run **one process per trusted user / workspace**.
|
|
148
|
+
- Do **not** expose this server over a network or share one process across untrusted users.
|
|
149
|
+
- For multi-user or network deployments, front Ojas with an authenticated MCP gateway, or run one isolated Ojas process per user / workspace.
|
|
150
|
+
|
|
151
|
+
If Ojas ever ships a non-stdio transport (HTTP, SSE, streamable-HTTP),
|
|
152
|
+
that transport will fail closed unless auth is configured.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
<a id="first-session"></a>
|
|
157
|
+
## A typical first session
|
|
158
|
+
|
|
159
|
+
A new agent typically issues this exact sequence during one task. Each step shows the request shape (`→`) and the most-relevant response fields (`←`). The standard envelope (`status`, `correlation_id`, `affected_modules`, …) is present on every response but omitted here for brevity.
|
|
160
|
+
|
|
161
|
+
```jsonc
|
|
162
|
+
// 1. Register the agent and create its health contract.
|
|
163
|
+
→ ojas_register_agent
|
|
164
|
+
{
|
|
165
|
+
"agent_id": "research-agent",
|
|
166
|
+
"risk_level": "medium",
|
|
167
|
+
"health_thresholds": { "minimum_ojas_score": 80 },
|
|
168
|
+
"recovery_policy": { "on_prompt_injection": "quarantine_input" }
|
|
169
|
+
}
|
|
170
|
+
← {
|
|
171
|
+
"registered": true,
|
|
172
|
+
"initial_ojas_score": 100,
|
|
173
|
+
"health_state": "healthy",
|
|
174
|
+
"health_contract": { "agent_id": "research-agent", "health_contract_id": "contract_..." }
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 2. Filter retrieved content through Raksha + Aahar before reading it.
|
|
178
|
+
→ ojas_build_context
|
|
179
|
+
{
|
|
180
|
+
"agent_id": "research-agent",
|
|
181
|
+
"task": "Compare vector databases for enterprise RAG",
|
|
182
|
+
"max_tokens": 4096,
|
|
183
|
+
"candidate_items": [ /* 17 retrieved items */ ]
|
|
184
|
+
}
|
|
185
|
+
← {
|
|
186
|
+
"context_bundle_id": "bundle_...",
|
|
187
|
+
"context_health_score": 87,
|
|
188
|
+
"included_items": 7,
|
|
189
|
+
"excluded_items": 10,
|
|
190
|
+
"retained_token_ratio": 0.42, // accepted_tokens / total_tokens
|
|
191
|
+
"compression_ratio": 0.42, // legacy alias for retained_token_ratio
|
|
192
|
+
"warnings": ["excluded 2 stale items", "quarantined 1 injection attempt"],
|
|
193
|
+
"context": "[#ctx-001 | analyst_report] Pinecone offers managed scaling ..."
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 3. Stream a trace every time the agent calls a tool.
|
|
197
|
+
→ ojas_ingest_trace
|
|
198
|
+
{
|
|
199
|
+
"agent_id": "research-agent",
|
|
200
|
+
"event_type": "tool_call_failed",
|
|
201
|
+
"data": { "tool_name": "web_search", "error_type": "timeout", "latency_ms": 8000 }
|
|
202
|
+
}
|
|
203
|
+
← {
|
|
204
|
+
"accepted": true,
|
|
205
|
+
"event_id": "evt_...",
|
|
206
|
+
"trace_id": "trace_...",
|
|
207
|
+
"health_impact_detected": true,
|
|
208
|
+
"recommended_action": "diagnose_tool_failure"
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// 4. Before the next risky action, ask the gate.
|
|
212
|
+
→ ojas_is_agent_fit_to_continue
|
|
213
|
+
{
|
|
214
|
+
"agent_id": "research-agent",
|
|
215
|
+
"task_risk_level": "high",
|
|
216
|
+
"planned_next_action": "call_web_search"
|
|
217
|
+
}
|
|
218
|
+
← {
|
|
219
|
+
"fit_to_continue": false,
|
|
220
|
+
"confidence": 0.62,
|
|
221
|
+
"health_state": "watch",
|
|
222
|
+
"ojas_score": 62,
|
|
223
|
+
"required_score": 90,
|
|
224
|
+
"risks": ["recent tool timeout"],
|
|
225
|
+
"required_actions_before_continue": ["run ojas_run_recovery to lift score above threshold"],
|
|
226
|
+
"safe_mode_required": false
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 5. Not fit — diagnose, then run recovery in recommend mode (the default).
|
|
230
|
+
→ ojas_diagnose_failure
|
|
231
|
+
{
|
|
232
|
+
"agent_id": "research-agent",
|
|
233
|
+
"failure_description": "web_search timed out 3 times in 60 seconds"
|
|
234
|
+
}
|
|
235
|
+
← {
|
|
236
|
+
"diagnosis_id": "chikitsa-...",
|
|
237
|
+
"primary_cause": "loop",
|
|
238
|
+
"secondary_causes": ["high_cost_pressure"],
|
|
239
|
+
"recommended_repair": ["context_reset", "plan_regeneration"],
|
|
240
|
+
"severity": "warning"
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
→ ojas_run_recovery
|
|
244
|
+
{ "agent_id": "research-agent", "recovery_type": "tool_failure_loop" }
|
|
245
|
+
← {
|
|
246
|
+
"recovery_id": "recovery_...",
|
|
247
|
+
"mode": "recommend",
|
|
248
|
+
"outcome": "recommended",
|
|
249
|
+
"actions": [
|
|
250
|
+
{ "action": "freeze_memory_writes", "reason": "avoid storing degraded loop behavior" },
|
|
251
|
+
{ "action": "reset_plan", "reason": "agent is stuck in a repeated tool-call loop" },
|
|
252
|
+
{ "action": "generate_fallback_response", "reason": "underlying tool unavailable after repeated attempts" }
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// 6. After applying recovery, generate the session report.
|
|
257
|
+
→ ojas_generate_health_report
|
|
258
|
+
{ "agent_id": "research-agent", "scope": "session" }
|
|
259
|
+
← {
|
|
260
|
+
"overall_ojas_score": 87,
|
|
261
|
+
"module_scores": { "aahar": 91, "nidra": 78, "vyayam": 97, "raksha": 93, "agni": 96, "pulse": 68, "chikitsa": 72 },
|
|
262
|
+
"summary": "research-agent recovered from a tool-failure loop; healthy to resume.",
|
|
263
|
+
"top_risks": ["over_retrieval"],
|
|
264
|
+
"recommended_next_steps": ["compress_context"]
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
<a id="tools-setup"></a>
|
|
271
|
+
## 1. Setup & telemetry
|
|
272
|
+
|
|
273
|
+
Every interaction starts here.
|
|
274
|
+
|
|
275
|
+
| Tool | Purpose | Key input | Key output |
|
|
276
|
+
|---|---|---|---|
|
|
277
|
+
| `ojas_register_agent` | Create the agent's health contract | `agent_id`, `risk_level`, `health_thresholds`, `recovery_policy`, optional `allowed_tools[]`, optional `replace_existing` | `registered`, `health_contract`, `initial_ojas_score`, `health_state` |
|
|
278
|
+
| `ojas_ingest_trace` | Stream a runtime event into Ojas | `event_type` (one of 17), `data` | `accepted`, `event_id`, `health_impact_detected`, `policy_violation`, `recommended_action` |
|
|
279
|
+
|
|
280
|
+
> When a contract sets `allowed_tools`, any `ojas_ingest_trace` call with `data.tool_name` outside that list is recorded as a `tool_policy_violation`. The response sets `accepted: false`, `policy_violation: true`, `health_impact_detected: true`, `recommended_action: "review_tool_policy_violation"`, and flags `requires_human_review: true` in the envelope. The tool name is also reflected in the trace's `error` field so Chikitsa picks it up for diagnosis.
|
|
281
|
+
|
|
282
|
+
Supported `event_type` values:
|
|
283
|
+
|
|
284
|
+
```text
|
|
285
|
+
agent_input agent_output
|
|
286
|
+
tool_call_started tool_call_succeeded tool_call_failed
|
|
287
|
+
retrieval_result memory_read memory_write
|
|
288
|
+
failure latency_measurement token_usage
|
|
289
|
+
user_correction planning_loop fallback
|
|
290
|
+
policy_violation prompt_injection_detected context_overload_detected
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Each event is routed to the relevant modules — for example `tool_call_failed` flows to Agni (cost), Pulse (telemetry), and Chikitsa (diagnosis), and the response includes the recommended follow-up.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
<a id="tools-decisions"></a>
|
|
298
|
+
## 2. Decisions
|
|
299
|
+
|
|
300
|
+
Current state, fitness gating, and operational fitness.
|
|
301
|
+
|
|
302
|
+
| Tool | Purpose | Key input | Key output |
|
|
303
|
+
|---|---|---|---|
|
|
304
|
+
| `ojas_get_health` | Current Ojas snapshot | `agent_id`, `include_modules`, `include_recent_events` | `ojas_score`, `health_state`, `module_scores`, `active_risks`, `recommended_actions` |
|
|
305
|
+
| **`ojas_is_agent_fit_to_continue`** | **Signature gate.** Should the agent proceed? | `agent_id`, `task_risk_level`, `planned_next_action` | `fit_to_continue`, `confidence`, `required_score`, `required_actions_before_continue`, `safe_mode_required` |
|
|
306
|
+
|
|
307
|
+
The fitness gate answers the operational question most agent frameworks don't ask:
|
|
308
|
+
|
|
309
|
+
> Is this agent cognitively healthy enough to proceed?
|
|
310
|
+
|
|
311
|
+
The required score scales with `task_risk_level`: **medium** uses the contract's `minimum_ojas_score`, **high** adds +10, **critical** adds +20. Critical-risk tasks on a non-healthy agent flip `safe_mode_required` to `true` and `requires_human_review` to `true` in the envelope.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
<a id="tools-context"></a>
|
|
316
|
+
## 3. Context safety
|
|
317
|
+
|
|
318
|
+
Everything the agent reads passes through one of these.
|
|
319
|
+
|
|
320
|
+
| Tool | Purpose | Key input | Key output |
|
|
321
|
+
|---|---|---|---|
|
|
322
|
+
| `ojas_score_context` | Per-item nutrition + threat scoring | `agent_id`, `task`, `context_items[]` | `context_health_score`, `item_scores[]` (with `relevance_score`, `relevance_source` (`caller`/`lexical_fallback`), `freshness_score`, `trust_score`, `risk_score`, `recommendation`), `warnings` |
|
|
323
|
+
| `ojas_build_context` | Assemble a clean bundle within a token budget | `agent_id`, `task`, `max_tokens`, `risk_level`, `candidate_items[]` | `context_bundle_id`, `included_ids`, `retained_token_ratio` (and legacy `compression_ratio = retained_token_ratio`), `warnings`, `context` |
|
|
324
|
+
| `ojas_scan_for_injection` | One-shot threat scan on a single piece of content | `agent_id`, `source_type`, `content`, `intended_use` | `injection_detected`, `risk_score`, `attack_type`, `allowed_for_context`, `allowed_for_memory`, `reasons` |
|
|
325
|
+
|
|
326
|
+
`scan_for_injection` is the right tool when you want a verdict on a single string (e.g. one retrieved page) without putting it through Aahar. `score_context` and `build_context` are batch tools that run the same Raksha scan plus Aahar nutrition.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
<a id="tools-output"></a>
|
|
331
|
+
## 4. Output quality & routing
|
|
332
|
+
|
|
333
|
+
These tools operate after or around generation: checking the answer, trimming response load, and feeding success/failure learning back into Agni and Chikitsa.
|
|
334
|
+
|
|
335
|
+
| Tool | Purpose | Key input | Key output |
|
|
336
|
+
|---|---|---|---|
|
|
337
|
+
| `ojas_detect_hallucination` | Score an agent output for hallucination risk | `output`, optional `prompt`, `samples[]`, `context[]` | `hallucination_detected`, `risk_score`, `confidence`, `detector`, `reasons`, `claims[]`, `abstention` |
|
|
338
|
+
| `ojas_recommend_model_route` | Decide whether a task class can use a cheap route | `task_class`, optional `include_report` | `route` (`cheap` / `flagship`), `reason`, `observations`, `success_ci`, `router_report?` |
|
|
339
|
+
| `ojas_distill_response` | Remove low-signal filler from an output | `response`, optional `intensity` (`lite` / `full` / `ultra`) | `distilled_response`, `tokens_removed`, `chars_removed`, `removed_categories`, `distiller` |
|
|
340
|
+
| `ojas_record_task_outcome` | Feed task success/failure back into routing and velocity stats | `task_id`, `succeeded`, `duration_ms`, optional `task_class`, `category`, `completed_at` | `recorded`, `route_after_recording`, `velocity_stats` |
|
|
341
|
+
|
|
342
|
+
`recommend_model_route` is deliberately fail-closed: sparse data, safety classes such as `security` / `auth`, or a weak Wilson confidence lower bound all return `flagship`. `record_task_outcome` is how MCP clients teach that router over time; it also updates Chikitsa's rolling velocity window for handoffs.
|
|
343
|
+
|
|
344
|
+
`distill_response` uses the configured Agni distiller by default and updates `lifetime_output_tokens_saved`. If a per-call `intensity` is supplied, Ojas uses a temporary default distiller at that intensity and reports `lifetime_counter_updated: false`.
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
<a id="tools-memory"></a>
|
|
349
|
+
## 5. Memory hygiene
|
|
350
|
+
|
|
351
|
+
Memory is a living organ; these tools curate it.
|
|
352
|
+
|
|
353
|
+
| Tool | Purpose | Key input | Key output |
|
|
354
|
+
|---|---|---|---|
|
|
355
|
+
| `ojas_audit_memory` | Audit the agent's memory store | `agent_id`, `scope`, `include_recommendations` | `memory_health_score`, `issues` (stale / duplicate / conflicting / high_risk / low_usefulness), `recommended_actions` |
|
|
356
|
+
| **`ojas_validate_memory_write`** | Policy gate before a memory commit | `candidate_memory` (`content`, `source`, `confidence`), `reason_for_write` | `allowed`, `memory_status` (`committed` / `candidate` / `session_note` / `rejected`), `reason`, `risk_score` |
|
|
357
|
+
| `ojas_consolidate_memory` | Run a Nidra cycle over recent traces | `consolidation_depth`, `allow_new_memories`, `allow_memory_pruning`, `include_failure_reflection` | `consolidation_id`, `cycle_status`, `memories[]` (proposed), `memories_to_prune`, `lessons_extracted`, `drift_reduction` |
|
|
358
|
+
|
|
359
|
+
`validate_memory_write` is deliberately conservative by default:
|
|
360
|
+
|
|
361
|
+
```text
|
|
362
|
+
confidence ≥ 0.75 + no Raksha hit → committed
|
|
363
|
+
confidence ≥ 0.50 + no Raksha hit → candidate (not yet committed)
|
|
364
|
+
confidence < 0.50 → session_note (scoped to this session)
|
|
365
|
+
any Raksha hit (risk_score > 0.5) → rejected
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
`consolidate_memory` **proposes** memories but does not commit them unless `allow_new_memories: true`. The default is `false` — memory writes are dangerous and should require explicit opt-in.
|
|
369
|
+
|
|
370
|
+
- A preview run emits a `recovery_cycle_previewed` event and returns `cycle_status: "preview"`, `health_after_estimated: true`. The unprocessed-trace set is untouched, so calling `consolidate_memory` twice with `allow_new_memories: false` is guaranteed to be a no-op.
|
|
371
|
+
- A commit run emits `recovery_cycle_completed` and returns `cycle_status: "committed"`, `health_after_estimated: false`. The bound agent's `injectMemory()` is invoked for every memory before Nidra commits — see the SDK note below.
|
|
372
|
+
|
|
373
|
+
> **SDK transactionality:** when you bind an `AgentAdapter` and call `Ojas.recover()`, the cycle runs as `analyse → injectMemory(...) → commit`. If any `injectMemory` throws, Nidra state is **not** mutated: no traces are marked processed, no memories are persisted, and a `recovery_injection_failed` pulse event explains the abort. This guarantees the agent's view of memory and Ojas's view stay in sync.
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
<a id="tools-repair"></a>
|
|
378
|
+
## 6. Repair
|
|
379
|
+
|
|
380
|
+
Diagnose failures and apply structured recovery.
|
|
381
|
+
|
|
382
|
+
| Tool | Purpose | Key input | Key output |
|
|
383
|
+
|---|---|---|---|
|
|
384
|
+
| `ojas_diagnose_failure` | Chikitsa classifies a failure | `agent_id`, `failure_description`, `failure_type?`, `severity` | `diagnosis_id`, `primary_cause`, `secondary_causes`, `recommended_repair`, `severity` |
|
|
385
|
+
| **`ojas_run_recovery`** | Execute a recovery protocol | `recovery_type`, `mode` (`observe` / `recommend` / `apply`), `allowed_actions?` | `recovery_id`, `mode`, `outcome` (`recommended` / `applied` / `instructed` / `no_effect` / `requires_human_review`), `actions[]`, `mutated_actions[]`, `instruction_actions[]`, `skipped_actions[]`, `applied_actions[]` (deprecated alias for durable mutations), `ojas_score_before`, `ojas_score_after`, `ojas_score_delta` |
|
|
386
|
+
|
|
387
|
+
`run_recovery` is safe-by-default: `mode` defaults to `recommend`, so the tool returns the action plan without executing it. In `apply` mode, Ojas separates durable mutations from caller instructions: `enter_safe_mode` appears under `mutated_actions`, advisory steps such as `compress_context` appear under `instruction_actions`, and `human_escalation` appears under `skipped_actions`. The legacy `applied_actions` field is retained for one release as a deprecated alias for `mutated_actions` only.
|
|
388
|
+
|
|
389
|
+
`recovery_type` values:
|
|
390
|
+
|
|
391
|
+
```text
|
|
392
|
+
tool_failure_loop context_overload prompt_injection
|
|
393
|
+
memory_conflict hallucination high_cost_pressure
|
|
394
|
+
unknown
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Recovery action vocabulary (also reusable as `allowed_actions`):
|
|
398
|
+
|
|
399
|
+
```text
|
|
400
|
+
compress_context reset_plan freeze_memory_writes
|
|
401
|
+
quarantine_input generate_fallback_response
|
|
402
|
+
enter_safe_mode human_escalation
|
|
403
|
+
reduce_tool_calls switch_to_cached_sources
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
<a id="tools-reporting"></a>
|
|
409
|
+
## 7. Reporting & handoff
|
|
410
|
+
|
|
411
|
+
Human-readable continuity and summary tools.
|
|
412
|
+
|
|
413
|
+
| Tool | Purpose | Key input | Key output |
|
|
414
|
+
|---|---|---|---|
|
|
415
|
+
| `ojas_generate_handoff` | Markdown handoff for another agent/session | `focus`, `pending_tasks[]`, `completed_tasks[]`, `notes[]`, `include_velocity` | `handoff_markdown`, `generated_at`, `pending_count`, `completed_count`, `velocity_stats` |
|
|
416
|
+
| `ojas_generate_health_report` | Executive summary for dashboards / release gates / postmortems | `agent_id`, `scope`, `report_type`, `include_recommendations` | `report_id`, `overall_ojas_score`, `health_state`, `module_scores`, `summary`, `top_risks`, `recommended_next_steps` |
|
|
417
|
+
|
|
418
|
+
Use `generate_handoff` when work is moving between agents or sessions. Use `generate_health_report` at session end, on a periodic cron, or as a CI release gate. `scope` accepts `current`, `session`, or `last_24h`; `report_type` accepts `executive_summary` or `technical`.
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
<a id="session-isolation"></a>
|
|
423
|
+
## Session isolation
|
|
424
|
+
|
|
425
|
+
Ojas MCP tools accept an optional `session_id` argument. Calls with the same
|
|
426
|
+
`agent_id` but different `session_id`s receive separate Ojas runtime state:
|
|
427
|
+
trace windows, memories, tool-outcome history, recovery cycles, safe-mode
|
|
428
|
+
flags, and health snapshots are isolated per session. Omitting `session_id`
|
|
429
|
+
uses the backward-compatible default session.
|
|
430
|
+
|
|
431
|
+
Every response from a session-aware tool surfaces this honestly:
|
|
432
|
+
|
|
433
|
+
```json
|
|
434
|
+
{
|
|
435
|
+
"session_id": "sess_abc",
|
|
436
|
+
"session_scope_supported": true
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
When `OJAS_DB_PATH=/path/to/ojas.sqlite` is set, the registry persists those
|
|
441
|
+
session snapshots to SQLite and hydrates them on server restart.
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
<a id="error-semantics"></a>
|
|
446
|
+
## Error semantics: structured envelopes vs MCP protocol errors
|
|
447
|
+
|
|
448
|
+
Ojas distinguishes two error paths and clients should handle both.
|
|
449
|
+
|
|
450
|
+
**1. Structured `failed` envelope (`status: 'failed'`).** Any exception
|
|
451
|
+
raised *inside* an Ojas tool handler — including typed `OjasError`s and
|
|
452
|
+
unexpected throws — is caught by `safeHandler` and returned as a normal
|
|
453
|
+
tool response with this shape:
|
|
454
|
+
|
|
455
|
+
```json
|
|
456
|
+
{
|
|
457
|
+
"status": "failed",
|
|
458
|
+
"accepted": false,
|
|
459
|
+
"error": "Agent 'x' is already registered. ...",
|
|
460
|
+
"error_class": "ojas_register_agent_error",
|
|
461
|
+
"error_code": "policy_violation",
|
|
462
|
+
"requires_human_review": false
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
`error_code` is one of `invalid_input`, `policy_violation`, `not_found`,
|
|
467
|
+
or `internal_error`. Only `internal_error` defaults to
|
|
468
|
+
`requires_human_review: true` — validation and policy refusals are
|
|
469
|
+
caller-side problems and should be surfaced in the client UI, not the
|
|
470
|
+
operator pager.
|
|
471
|
+
|
|
472
|
+
**2. MCP-protocol-level error.** Input that fails the tool's Zod
|
|
473
|
+
`inputSchema` (e.g. a string where a number was required, an unknown
|
|
474
|
+
`event_type`, a non-ISO-8601 `created_at`) is rejected by the MCP SDK
|
|
475
|
+
*before* the handler runs. That arrives at the client as an MCP protocol
|
|
476
|
+
error, not as a `status: 'failed'` envelope, because `safeHandler` has
|
|
477
|
+
no opportunity to wrap it.
|
|
478
|
+
|
|
479
|
+
In practice this means MCP clients need two error-handling paths:
|
|
480
|
+
|
|
481
|
+
- check `response.status === 'failed'` first to detect tool-level errors;
|
|
482
|
+
- catch transport / protocol errors as a separate branch for schema
|
|
483
|
+
rejection and SDK-internal failures.
|
|
484
|
+
|
|
485
|
+
The split is intentional. Loosening schemas to let everything reach the
|
|
486
|
+
handler would weaken the input contract and force every tool to
|
|
487
|
+
re-implement validation. Documenting the split here so clients aren't
|
|
488
|
+
surprised.
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
<a id="envelope"></a>
|
|
493
|
+
## Response envelope
|
|
494
|
+
|
|
495
|
+
Every MCP tool returns a standard envelope merged with tool-specific fields.
|
|
496
|
+
|
|
497
|
+
```jsonc
|
|
498
|
+
{
|
|
499
|
+
"status": "success | warning | failed",
|
|
500
|
+
"agent_id": "research_agent_01",
|
|
501
|
+
"correlation_id": "cor-...",
|
|
502
|
+
"ojas_score_delta": 0,
|
|
503
|
+
"affected_modules": ["aahar", "raksha"],
|
|
504
|
+
"events_created": ["evt_..."],
|
|
505
|
+
"recommended_next_actions": ["compress_context"],
|
|
506
|
+
"requires_human_review": false
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
`ojas_ingest_trace` also returns these three orthogonal booleans for
|
|
511
|
+
unambiguous client branching (previously folded into `accepted`):
|
|
512
|
+
|
|
513
|
+
```jsonc
|
|
514
|
+
{
|
|
515
|
+
"event_recorded": true, // trace landed in the store
|
|
516
|
+
"policy_accepted": true, // health-contract / allowed_tools gates passed
|
|
517
|
+
"telemetry_accepted": true // every reported token / cost field parsed cleanly
|
|
518
|
+
}
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
`accepted` is preserved for backward compatibility and equals
|
|
522
|
+
`policy_accepted` — new code should branch on the three explicit fields.
|
|
523
|
+
|
|
524
|
+
Tool-specific fields may include:
|
|
525
|
+
|
|
526
|
+
```text
|
|
527
|
+
ojas_score
|
|
528
|
+
health_state
|
|
529
|
+
fit_to_continue
|
|
530
|
+
required_score
|
|
531
|
+
context_health_score
|
|
532
|
+
injection_detected
|
|
533
|
+
hallucination_detected
|
|
534
|
+
route
|
|
535
|
+
distilled_response
|
|
536
|
+
velocity_stats
|
|
537
|
+
handoff_markdown
|
|
538
|
+
recommended_repair
|
|
539
|
+
recovery_actions
|
|
540
|
+
memory_write_decision
|
|
541
|
+
provenance // 'full' | 'degraded' on consolidated memories
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
<a id="usage-loop"></a>
|
|
547
|
+
## Suggested usage loop
|
|
548
|
+
|
|
549
|
+
```text
|
|
550
|
+
register
|
|
551
|
+
↓
|
|
552
|
+
ingest_trace
|
|
553
|
+
↓
|
|
554
|
+
score_context / build_context
|
|
555
|
+
↓
|
|
556
|
+
scan_for_injection on retrieval or tool outputs
|
|
557
|
+
↓
|
|
558
|
+
recommend_model_route before model choice
|
|
559
|
+
↓
|
|
560
|
+
detect_hallucination / distill_response after generation
|
|
561
|
+
↓
|
|
562
|
+
record_task_outcome after completion
|
|
563
|
+
↓
|
|
564
|
+
is_agent_fit_to_continue
|
|
565
|
+
↓
|
|
566
|
+
if unhealthy: diagnose_failure → run_recovery
|
|
567
|
+
↓
|
|
568
|
+
consolidate_memory
|
|
569
|
+
↓
|
|
570
|
+
audit_memory
|
|
571
|
+
↓
|
|
572
|
+
generate_handoff / generate_health_report
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
Recommended call points:
|
|
576
|
+
|
|
577
|
+
- **Before retrieval-augmented work**: call `ojas_score_context` and `ojas_build_context`
|
|
578
|
+
- **After every tool call**: call `ojas_ingest_trace`
|
|
579
|
+
- **Before risky actions**: call `ojas_is_agent_fit_to_continue`
|
|
580
|
+
- **Before model choice**: call `ojas_recommend_model_route`
|
|
581
|
+
- **After generation**: call `ojas_detect_hallucination` and optionally `ojas_distill_response`
|
|
582
|
+
- **After task completion**: call `ojas_record_task_outcome`
|
|
583
|
+
- **Before memory writes**: call `ojas_validate_memory_write`
|
|
584
|
+
- **After failures**: call `ojas_diagnose_failure`, then `ojas_run_recovery`
|
|
585
|
+
- **At session end**: call `ojas_consolidate_memory`, `ojas_generate_handoff`, and `ojas_generate_health_report`
|
|
586
|
+
|
|
587
|
+
---
|
|
588
|
+
|
|
589
|
+
<a id="verification"></a>
|
|
590
|
+
## Verification
|
|
591
|
+
|
|
592
|
+
After registering the server, restart your IDE and ask the assistant:
|
|
593
|
+
|
|
594
|
+
```text
|
|
595
|
+
Call ojas_register_agent with agent_id=my-coding-agent, then call ojas_is_agent_fit_to_continue with task_risk_level=high.
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
Expected response:
|
|
599
|
+
|
|
600
|
+
```json
|
|
601
|
+
{
|
|
602
|
+
"fit_to_continue": true,
|
|
603
|
+
"confidence": 0.91,
|
|
604
|
+
"health_state": "healthy",
|
|
605
|
+
"ojas_score": 91,
|
|
606
|
+
"required_score": 80,
|
|
607
|
+
"risks": [],
|
|
608
|
+
"required_actions_before_continue": [],
|
|
609
|
+
"safe_mode_required": false,
|
|
610
|
+
"status": "success",
|
|
611
|
+
"agent_id": "my-coding-agent",
|
|
612
|
+
"correlation_id": "cor-..."
|
|
613
|
+
}
|
|
614
|
+
```
|