clawaid 1.0.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/README.md +118 -0
- package/dist/diagnose.d.ts +41 -0
- package/dist/diagnose.d.ts.map +1 -0
- package/dist/diagnose.js +410 -0
- package/dist/diagnose.js.map +1 -0
- package/dist/execute.d.ts +16 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +153 -0
- package/dist/execute.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +115 -0
- package/dist/index.js.map +1 -0
- package/dist/loop.d.ts +43 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +316 -0
- package/dist/loop.js.map +1 -0
- package/dist/observe.d.ts +29 -0
- package/dist/observe.d.ts.map +1 -0
- package/dist/observe.js +330 -0
- package/dist/observe.js.map +1 -0
- package/dist/rules.d.ts +11 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +300 -0
- package/dist/rules.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +126 -0
- package/dist/server.js.map +1 -0
- package/dist/verify.d.ts +10 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +29 -0
- package/dist/verify.js.map +1 -0
- package/package.json +32 -0
- package/web/index.html +1226 -0
package/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# 🩺 OpenClaw Doctor
|
|
2
|
+
|
|
3
|
+
AI-powered diagnostic and repair tool for [OpenClaw](https://github.com/openclaw/openclaw).
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
1. **Scans** your OpenClaw installation (read-only, zero risk)
|
|
8
|
+
2. **Analyzes** the system data with Claude Opus (via OpenRouter)
|
|
9
|
+
3. **Shows** you what's wrong and the repair plan
|
|
10
|
+
4. **Fixes** it with one click, in real-time
|
|
11
|
+
5. **Verifies** the fix worked
|
|
12
|
+
6. If not fixed: **meta-thinks** and tries a different approach (up to 9 attempts)
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx openclaw-doctor
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This opens a clean web interface in your browser. No terminal interaction needed.
|
|
21
|
+
|
|
22
|
+
## How it works
|
|
23
|
+
|
|
24
|
+
### Three-Layer Loop Architecture
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
Initial Diagnosis → Fix → Verify
|
|
28
|
+
↓ (if not fixed)
|
|
29
|
+
Meta-Think #1 → Fix → Verify
|
|
30
|
+
↓ (if not fixed)
|
|
31
|
+
Meta-Think #2 → Fix → Verify
|
|
32
|
+
↓ (if not fixed)
|
|
33
|
+
Meta-Think #3 → Fix → Verify
|
|
34
|
+
↓ (if still not fixed)
|
|
35
|
+
Show diagnostic report + ask for help
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Each "Fix" phase runs up to 3 rounds of: Observe → AI Diagnose → Execute → Verify
|
|
39
|
+
|
|
40
|
+
Total maximum: 9 automated repair attempts with 3 strategy changes.
|
|
41
|
+
|
|
42
|
+
### AI Integration
|
|
43
|
+
|
|
44
|
+
- Uses **Claude Opus** (`anthropic/claude-opus-4-6`) via OpenRouter
|
|
45
|
+
- Looks for your OpenRouter API key in `~/.openclaw/openclaw.json` automatically
|
|
46
|
+
- If not found, asks you to enter it in the UI (with clear trust indicators)
|
|
47
|
+
|
|
48
|
+
### Real-time Updates
|
|
49
|
+
|
|
50
|
+
The web UI receives live progress via SSE (Server-Sent Events). You watch the diagnosis and repair happen in real time.
|
|
51
|
+
|
|
52
|
+
## Trust & Privacy
|
|
53
|
+
|
|
54
|
+
- **No data sent to any server except OpenRouter** (for AI analysis)
|
|
55
|
+
- **API key used only in-session**, never stored to disk
|
|
56
|
+
- **All fixes run locally** on your machine
|
|
57
|
+
- **Open source** — you can verify everything
|
|
58
|
+
|
|
59
|
+
## What it diagnoses
|
|
60
|
+
|
|
61
|
+
- Gateway not running or crashed
|
|
62
|
+
- Port 18789 conflicts
|
|
63
|
+
- Config file validation errors (invalid JSON5, unknown fields)
|
|
64
|
+
- Missing `gateway.mode: "local"` in config
|
|
65
|
+
- LaunchAgent plist with broken Node.js paths (nvm/fnm/volta)
|
|
66
|
+
- Proxy environment variables interfering
|
|
67
|
+
- Stale launchd service needing reinstall
|
|
68
|
+
- Channel connectivity issues
|
|
69
|
+
- Log file errors (auth failures, rate limits, etc.)
|
|
70
|
+
- And anything else Claude Opus can reason about from system state
|
|
71
|
+
|
|
72
|
+
## Repair Actions (in priority order)
|
|
73
|
+
|
|
74
|
+
1. **Official CLI**: `openclaw gateway restart`, `openclaw doctor --yes`, etc.
|
|
75
|
+
2. **System commands**: `kill`, `lsof`, `launchctl`
|
|
76
|
+
3. **File edits**: Config fixes (always backed up first)
|
|
77
|
+
|
|
78
|
+
## Development
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
git clone <this-repo>
|
|
82
|
+
cd openclaw-doctor
|
|
83
|
+
npm install
|
|
84
|
+
npm run build # compile TypeScript
|
|
85
|
+
npm start # run the compiled version
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For development with auto-recompile:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npm run dev # uses ts-node directly
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Structure
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
openclaw-doctor/
|
|
98
|
+
├── src/
|
|
99
|
+
│ ├── index.ts # Entry: find port, start server, open browser
|
|
100
|
+
│ ├── server.ts # Express + SSE endpoints
|
|
101
|
+
│ ├── observe.ts # Read-only system checks
|
|
102
|
+
│ ├── diagnose.ts # OpenRouter/Claude Opus integration
|
|
103
|
+
│ ├── execute.ts # Execute repair actions
|
|
104
|
+
│ ├── verify.ts # Verify fix worked
|
|
105
|
+
│ └── loop.ts # Three-layer loop controller
|
|
106
|
+
├── web/
|
|
107
|
+
│ └── index.html # Single-page UI (inline CSS+JS)
|
|
108
|
+
├── context/
|
|
109
|
+
│ ├── openclaw-arch.md # OpenClaw architecture knowledge
|
|
110
|
+
│ ├── cli-reference.md # CLI commands reference
|
|
111
|
+
│ ├── log-guide.md # Log locations and formats
|
|
112
|
+
│ └── config-schema.md # Config file schema
|
|
113
|
+
└── dist/ # Compiled JS (generated by `npm run build`)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
MIT
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface DiagnosticAction {
|
|
2
|
+
description: string;
|
|
3
|
+
command: string;
|
|
4
|
+
type: 'cli' | 'system' | 'file_edit';
|
|
5
|
+
risk: 'low' | 'medium' | 'high';
|
|
6
|
+
backup: string | null;
|
|
7
|
+
}
|
|
8
|
+
export interface RepairOption {
|
|
9
|
+
id: string;
|
|
10
|
+
title: string;
|
|
11
|
+
description: string;
|
|
12
|
+
recommended: boolean;
|
|
13
|
+
risk: 'low' | 'medium' | 'high';
|
|
14
|
+
autoExecute: boolean;
|
|
15
|
+
steps: DiagnosticAction[];
|
|
16
|
+
}
|
|
17
|
+
export interface DiagnosisResult {
|
|
18
|
+
healthy?: boolean;
|
|
19
|
+
diagnosis: string;
|
|
20
|
+
confidence: number;
|
|
21
|
+
rootCause: string;
|
|
22
|
+
reasoning: string[];
|
|
23
|
+
warnings: string[];
|
|
24
|
+
options: RepairOption[];
|
|
25
|
+
alternativeHypotheses: string[];
|
|
26
|
+
rawResponse?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface DiagnoseOptions {
|
|
29
|
+
apiKey: string;
|
|
30
|
+
observationData: string;
|
|
31
|
+
previousAttempts?: string[];
|
|
32
|
+
round?: number;
|
|
33
|
+
}
|
|
34
|
+
declare function extractApiKey(): string | null;
|
|
35
|
+
export declare function diagnose(options: DiagnoseOptions): Promise<DiagnosisResult>;
|
|
36
|
+
export declare function verifyFix(apiKey: string, originalObservation: string, actionsPerformed: string[], newObservation: string): Promise<{
|
|
37
|
+
fixed: boolean;
|
|
38
|
+
explanation: string;
|
|
39
|
+
}>;
|
|
40
|
+
export { extractApiKey };
|
|
41
|
+
//# sourceMappingURL=diagnose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnose.d.ts","sourceRoot":"","sources":["../src/diagnose.ts"],"names":[],"mappings":"AAgDA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,WAAW,CAAC;IACrC,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAChC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAChC,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsFD,iBAAS,aAAa,IAAI,MAAM,GAAG,IAAI,CAwBtC;AAiID,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAqDjF;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,MAAM,EAC3B,gBAAgB,EAAE,MAAM,EAAE,EAC1B,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CA8ClD;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/diagnose.js
ADDED
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.diagnose = diagnose;
|
|
37
|
+
exports.verifyFix = verifyFix;
|
|
38
|
+
exports.extractApiKey = extractApiKey;
|
|
39
|
+
const https = __importStar(require("https"));
|
|
40
|
+
const http = __importStar(require("http"));
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const os = __importStar(require("os"));
|
|
44
|
+
// ClawAid backend API URL — set CLAWAID_API to override (e.g. for local dev)
|
|
45
|
+
const CLAWAID_API = process.env.CLAWAID_API || 'https://clawaid-backend.vercel.app';
|
|
46
|
+
async function callClawAidAPI(observationData, previousAttempts, round) {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const body = JSON.stringify({ observationData, previousAttempts, round });
|
|
49
|
+
const url = new URL(`${CLAWAID_API}/api/diagnose`);
|
|
50
|
+
const isLocal = url.hostname === 'localhost' || url.hostname === '127.0.0.1';
|
|
51
|
+
const lib = isLocal ? http : https;
|
|
52
|
+
const options = {
|
|
53
|
+
hostname: url.hostname,
|
|
54
|
+
port: parseInt(url.port) || (isLocal ? 3001 : 443),
|
|
55
|
+
path: url.pathname,
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers: {
|
|
58
|
+
'Content-Type': 'application/json',
|
|
59
|
+
'Content-Length': Buffer.byteLength(body),
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
const req = lib.request(options, (res) => {
|
|
63
|
+
let data = '';
|
|
64
|
+
res.on('data', chunk => { data += chunk; });
|
|
65
|
+
res.on('end', () => {
|
|
66
|
+
try {
|
|
67
|
+
const parsed = JSON.parse(data);
|
|
68
|
+
if (parsed.error)
|
|
69
|
+
reject(new Error(parsed.error));
|
|
70
|
+
else
|
|
71
|
+
resolve(parsed);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
reject(new Error(`Failed to parse backend response: ${data.slice(0, 200)}`));
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
req.on('error', reject);
|
|
79
|
+
req.setTimeout(90000, () => { req.destroy(); reject(new Error('Backend request timeout')); });
|
|
80
|
+
req.write(body);
|
|
81
|
+
req.end();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
const SYSTEM_PROMPT = `You are a top-tier OpenClaw diagnostics engineer. OpenClaw is a local AI gateway/assistant platform that runs on macOS. Your tool is called ClawAid 🩺.
|
|
85
|
+
|
|
86
|
+
IMPORTANT: The observation data starts with "AUTOMATED RULE CHECKS" — these are deterministic findings verified by code, NOT guesses. If any CRITICAL rules are flagged:
|
|
87
|
+
1. They MUST be your primary diagnosis (highest priority)
|
|
88
|
+
2. Use the suggested fix command in your repair options
|
|
89
|
+
3. Do NOT downgrade them to warnings or secondary issues
|
|
90
|
+
4. The rule check is authoritative — trust it over other signals
|
|
91
|
+
|
|
92
|
+
Key facts about OpenClaw:
|
|
93
|
+
- Default gateway port: 18789
|
|
94
|
+
- Config: ~/.openclaw/openclaw.json (JSON5 format)
|
|
95
|
+
- Log files: /tmp/openclaw/openclaw-YYYY-MM-DD.log
|
|
96
|
+
- LaunchAgent plist: ~/Library/LaunchAgents/ai.openclaw.gateway.plist
|
|
97
|
+
- Service commands: openclaw gateway start/stop/restart/install
|
|
98
|
+
- gateway.mode must be "local" in config for local operation
|
|
99
|
+
- Doctor command: openclaw doctor / openclaw doctor --yes / openclaw doctor --repair
|
|
100
|
+
|
|
101
|
+
IMPORTANT - Solution priority (always prefer higher in the list):
|
|
102
|
+
1. \`openclaw doctor --yes\` or \`openclaw doctor --repair\` — if the official doctor already identified the issue, use its built-in fix first
|
|
103
|
+
2. \`openclaw gateway restart\` — restart the gateway service
|
|
104
|
+
3. \`openclaw gateway install --force\` — reinstall the launch agent
|
|
105
|
+
4. System commands: kill, launchctl (only if CLI commands above fail)
|
|
106
|
+
5. File edits — absolute LAST resort only
|
|
107
|
+
|
|
108
|
+
ALWAYS check the official \`openclaw doctor\` output first. It already identifies many common issues like:
|
|
109
|
+
- WhatsApp groupPolicy warnings
|
|
110
|
+
- Missing or misconfigured gateway
|
|
111
|
+
- LaunchAgent issues
|
|
112
|
+
If the official doctor already identified an issue AND has a CLI fix, use that fix first.
|
|
113
|
+
|
|
114
|
+
You think like a scientist: observe, hypothesize, test, refine.
|
|
115
|
+
|
|
116
|
+
Given the system data:
|
|
117
|
+
1. What anomalies do you see? (List facts only — check the official doctor output FIRST)
|
|
118
|
+
2. What root cause do these point to?
|
|
119
|
+
3. What is the minimal fix using the priority order above?
|
|
120
|
+
4. What are the risks?
|
|
121
|
+
|
|
122
|
+
IMPORTANT RULES:
|
|
123
|
+
- If the core system is healthy (gateway running, RPC probe ok, no errors), return "healthy": true.
|
|
124
|
+
- BUT still report non-critical issues in the "warnings" array (e.g., channel config warnings, version mismatches, orphan files). Users should know about these even if they don't need immediate fixing.
|
|
125
|
+
- Focus options ONLY on things that prevent OpenClaw from functioning. Non-critical warnings don't need fix options.
|
|
126
|
+
- Return 1-3 options, ALWAYS mark exactly one as recommended. If healthy with no critical issues, options can be empty.
|
|
127
|
+
- Options with risk "low" SHOULD have autoExecute: true (they run automatically without asking the user).
|
|
128
|
+
- Options with risk "medium" or "high" MUST have autoExecute: false.
|
|
129
|
+
|
|
130
|
+
Output ONLY valid JSON (no markdown, no code fences):
|
|
131
|
+
{
|
|
132
|
+
"healthy": false,
|
|
133
|
+
"diagnosis": "plain language description of what's wrong (2-3 sentences max). If healthy, describe the overall status briefly.",
|
|
134
|
+
"confidence": 0.0-1.0,
|
|
135
|
+
"rootCause": "technical root cause (one sentence). If healthy, say 'No critical issues found'",
|
|
136
|
+
"reasoning": [
|
|
137
|
+
"Checked gateway status → running normally on port 18789",
|
|
138
|
+
"Read LaunchAgent plist → found proxy configuration pointing to localhost:9999",
|
|
139
|
+
"This proxy will cause failures on next gateway restart — treat as critical"
|
|
140
|
+
],
|
|
141
|
+
"warnings": [
|
|
142
|
+
"Non-critical: WhatsApp groupPolicy set to allowlist but allowFrom is empty — messages in groups would be dropped if WhatsApp were enabled. Safe to ignore for now.",
|
|
143
|
+
"Non-critical: Desktop app version (2026.2.22) is older than gateway (2026.3.2). Consider updating."
|
|
144
|
+
],
|
|
145
|
+
"options": [
|
|
146
|
+
{
|
|
147
|
+
"id": "A",
|
|
148
|
+
"title": "Restart gateway",
|
|
149
|
+
"description": "brief explanation of what this option does and why it should work",
|
|
150
|
+
"recommended": true,
|
|
151
|
+
"risk": "low",
|
|
152
|
+
"autoExecute": true,
|
|
153
|
+
"steps": [
|
|
154
|
+
{
|
|
155
|
+
"description": "what this step does in plain language",
|
|
156
|
+
"command": "the actual command to run",
|
|
157
|
+
"type": "cli",
|
|
158
|
+
"risk": "low",
|
|
159
|
+
"backup": null
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
],
|
|
164
|
+
"alternativeHypotheses": ["other possible causes if this doesn't work"]
|
|
165
|
+
}
|
|
166
|
+
reasoning: 3-6 plain language sentences summarizing your diagnostic thinking, written for non-technical users.`;
|
|
167
|
+
function extractApiKey() {
|
|
168
|
+
const configPath = path.join(os.homedir(), '.openclaw', 'openclaw.json');
|
|
169
|
+
try {
|
|
170
|
+
if (!fs.existsSync(configPath))
|
|
171
|
+
return null;
|
|
172
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
173
|
+
// Look for openrouter API key
|
|
174
|
+
const patterns = [
|
|
175
|
+
/"openrouter"\s*:\s*\{[^}]*"apiKey"\s*:\s*"([^"]+)"/s,
|
|
176
|
+
/"apiKey"\s*:\s*"(sk-or-[^"]+)"/,
|
|
177
|
+
/"apiKey"\s*:\s*"(sk-or-v1-[^"]+)"/,
|
|
178
|
+
];
|
|
179
|
+
for (const pattern of patterns) {
|
|
180
|
+
const match = content.match(pattern);
|
|
181
|
+
if (match)
|
|
182
|
+
return match[1];
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async function callOpenRouter(apiKey, systemPrompt, userMessage) {
|
|
191
|
+
return new Promise((resolve, reject) => {
|
|
192
|
+
const body = JSON.stringify({
|
|
193
|
+
model: 'anthropic/claude-sonnet-4-6',
|
|
194
|
+
messages: [
|
|
195
|
+
{ role: 'system', content: systemPrompt },
|
|
196
|
+
{ role: 'user', content: userMessage }
|
|
197
|
+
],
|
|
198
|
+
max_tokens: 2000,
|
|
199
|
+
temperature: 0,
|
|
200
|
+
});
|
|
201
|
+
const options = {
|
|
202
|
+
hostname: 'openrouter.ai',
|
|
203
|
+
port: 443,
|
|
204
|
+
path: '/api/v1/chat/completions',
|
|
205
|
+
method: 'POST',
|
|
206
|
+
headers: {
|
|
207
|
+
'Content-Type': 'application/json',
|
|
208
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
209
|
+
'HTTP-Referer': 'https://github.com/openclaw-clawaid',
|
|
210
|
+
'X-Title': 'ClawAid',
|
|
211
|
+
'Content-Length': Buffer.byteLength(body),
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
const req = https.request(options, (res) => {
|
|
215
|
+
let data = '';
|
|
216
|
+
res.on('data', chunk => { data += chunk; });
|
|
217
|
+
res.on('end', () => {
|
|
218
|
+
try {
|
|
219
|
+
const parsed = JSON.parse(data);
|
|
220
|
+
if (parsed.error) {
|
|
221
|
+
reject(new Error(`OpenRouter API error: ${parsed.error.message || JSON.stringify(parsed.error)}`));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const content = parsed.choices?.[0]?.message?.content;
|
|
225
|
+
if (!content) {
|
|
226
|
+
reject(new Error(`No content in response: ${data}`));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
resolve(content);
|
|
230
|
+
}
|
|
231
|
+
catch (e) {
|
|
232
|
+
reject(new Error(`Failed to parse response: ${data}`));
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
req.on('error', (err) => {
|
|
237
|
+
reject(new Error(`OpenRouter connection error: ${err.message}`));
|
|
238
|
+
});
|
|
239
|
+
req.setTimeout(90000, () => {
|
|
240
|
+
req.destroy();
|
|
241
|
+
reject(new Error('OpenRouter request timed out after 90s. Check your internet connection.'));
|
|
242
|
+
});
|
|
243
|
+
req.write(body);
|
|
244
|
+
req.end();
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function parseJsonResponse(response) {
|
|
248
|
+
// Try to extract JSON from the response (in case model added markdown)
|
|
249
|
+
let jsonStr = response.trim();
|
|
250
|
+
// Remove markdown code blocks if present
|
|
251
|
+
const jsonMatch = jsonStr.match(/```(?:json)?\s*(\{[\s\S]*\})\s*```/);
|
|
252
|
+
if (jsonMatch) {
|
|
253
|
+
jsonStr = jsonMatch[1];
|
|
254
|
+
}
|
|
255
|
+
else if (!jsonStr.startsWith('{')) {
|
|
256
|
+
// Try to find the first { and last }
|
|
257
|
+
const start = jsonStr.indexOf('{');
|
|
258
|
+
const end = jsonStr.lastIndexOf('}');
|
|
259
|
+
if (start !== -1 && end !== -1) {
|
|
260
|
+
jsonStr = jsonStr.slice(start, end + 1);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const parsed = JSON.parse(jsonStr);
|
|
264
|
+
// Normalize options array
|
|
265
|
+
const rawOptions = Array.isArray(parsed.options) ? parsed.options : [];
|
|
266
|
+
const options = rawOptions.map((o) => ({
|
|
267
|
+
id: o.id || 'A',
|
|
268
|
+
title: o.title || 'Fix',
|
|
269
|
+
description: o.description || '',
|
|
270
|
+
recommended: Boolean(o.recommended),
|
|
271
|
+
risk: o.risk || 'low',
|
|
272
|
+
autoExecute: Boolean(o.autoExecute),
|
|
273
|
+
steps: Array.isArray(o.steps) ? o.steps.map((s) => ({
|
|
274
|
+
description: s.description || 'Unknown action',
|
|
275
|
+
command: s.command || '',
|
|
276
|
+
type: s.type || 'cli',
|
|
277
|
+
risk: s.risk || 'low',
|
|
278
|
+
backup: s.backup || null,
|
|
279
|
+
})) : [],
|
|
280
|
+
}));
|
|
281
|
+
// Validate and normalize
|
|
282
|
+
return {
|
|
283
|
+
healthy: Boolean(parsed.healthy),
|
|
284
|
+
diagnosis: parsed.diagnosis || 'Unable to determine diagnosis',
|
|
285
|
+
confidence: typeof parsed.confidence === 'number' ? parsed.confidence : 0.5,
|
|
286
|
+
rootCause: parsed.rootCause || 'Unknown root cause',
|
|
287
|
+
reasoning: Array.isArray(parsed.reasoning) ? parsed.reasoning : [],
|
|
288
|
+
warnings: Array.isArray(parsed.warnings) ? parsed.warnings : [],
|
|
289
|
+
options,
|
|
290
|
+
alternativeHypotheses: Array.isArray(parsed.alternativeHypotheses) ? parsed.alternativeHypotheses : [],
|
|
291
|
+
rawResponse: response,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function loadContextDocs() {
|
|
295
|
+
const contextDir = path.join(__dirname, '..', 'context');
|
|
296
|
+
let docs = '';
|
|
297
|
+
try {
|
|
298
|
+
if (!fs.existsSync(contextDir))
|
|
299
|
+
return '';
|
|
300
|
+
const files = fs.readdirSync(contextDir).filter(f => f.endsWith('.md'));
|
|
301
|
+
for (const file of files) {
|
|
302
|
+
const content = fs.readFileSync(path.join(contextDir, file), 'utf-8');
|
|
303
|
+
// Truncate each file to 2000 chars to avoid bloating the prompt
|
|
304
|
+
const truncated = content.length > 2000 ? content.slice(0, 2000) + '\n...[truncated]' : content;
|
|
305
|
+
docs += `\n--- ${file} ---\n${truncated}\n`;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch { /* ignore */ }
|
|
309
|
+
return docs;
|
|
310
|
+
}
|
|
311
|
+
async function diagnose(options) {
|
|
312
|
+
const { apiKey, observationData, previousAttempts, round } = options;
|
|
313
|
+
let userMessage;
|
|
314
|
+
const contextDocs = loadContextDocs();
|
|
315
|
+
if (previousAttempts && previousAttempts.length > 0) {
|
|
316
|
+
userMessage = `
|
|
317
|
+
## Reference Documentation
|
|
318
|
+
${contextDocs}
|
|
319
|
+
|
|
320
|
+
## System Observation Data
|
|
321
|
+
|
|
322
|
+
${observationData}
|
|
323
|
+
|
|
324
|
+
## Previous Repair Attempts (Round ${round || previousAttempts.length} — these did NOT fully fix the issue)
|
|
325
|
+
${previousAttempts.join('\n\n---\n\n')}
|
|
326
|
+
|
|
327
|
+
Based on the failure of previous attempts, please provide a revised diagnosis and a new approach.
|
|
328
|
+
|
|
329
|
+
IMPORTANT: You MUST respond with valid JSON only. No prose, no markdown, no explanation outside the JSON object. Start your response with { and end with }.
|
|
330
|
+
`.trim();
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
userMessage = `
|
|
334
|
+
## Reference Documentation
|
|
335
|
+
${contextDocs}
|
|
336
|
+
|
|
337
|
+
## System Observation Data
|
|
338
|
+
|
|
339
|
+
${observationData}
|
|
340
|
+
|
|
341
|
+
Please diagnose any OpenClaw issues and provide a repair plan.
|
|
342
|
+
|
|
343
|
+
IMPORTANT: You MUST respond with valid JSON only. No prose, no markdown, no explanation outside the JSON object. Start your response with { and end with }.
|
|
344
|
+
`.trim();
|
|
345
|
+
}
|
|
346
|
+
try {
|
|
347
|
+
return await callClawAidAPI(observationData, previousAttempts, round);
|
|
348
|
+
}
|
|
349
|
+
catch (err) {
|
|
350
|
+
const msg = err.message || String(err);
|
|
351
|
+
// Fallback: try with user's own key if available
|
|
352
|
+
if (apiKey) {
|
|
353
|
+
try {
|
|
354
|
+
const response = await callOpenRouter(apiKey, SYSTEM_PROMPT, userMessage);
|
|
355
|
+
return parseJsonResponse(response);
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
// ignore fallback error, throw original
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
throw new Error(`Diagnosis failed: ${msg}`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
async function verifyFix(apiKey, originalObservation, actionsPerformed, newObservation) {
|
|
365
|
+
const userMessage = `
|
|
366
|
+
## Original System State (before repair)
|
|
367
|
+
${originalObservation}
|
|
368
|
+
|
|
369
|
+
## Actions Performed
|
|
370
|
+
${actionsPerformed.join('\n')}
|
|
371
|
+
|
|
372
|
+
## Current System State (after repair)
|
|
373
|
+
${newObservation}
|
|
374
|
+
|
|
375
|
+
Is the OpenClaw issue fixed? Respond with ONLY valid JSON:
|
|
376
|
+
{
|
|
377
|
+
"fixed": true|false,
|
|
378
|
+
"explanation": "brief explanation of what you see"
|
|
379
|
+
}
|
|
380
|
+
`.trim();
|
|
381
|
+
const systemPrompt = `You are an OpenClaw diagnostics engineer verifying if a repair was successful.
|
|
382
|
+
Compare the before and after states and determine if the issue is resolved.
|
|
383
|
+
Key success indicators:
|
|
384
|
+
- "Runtime: running" in gateway status
|
|
385
|
+
- "RPC probe: ok" in gateway status
|
|
386
|
+
- No error messages in logs
|
|
387
|
+
- Gateway responding on port 18789
|
|
388
|
+
Output ONLY valid JSON with "fixed" (boolean) and "explanation" (string).`;
|
|
389
|
+
const response = await callOpenRouter(apiKey, systemPrompt, userMessage);
|
|
390
|
+
try {
|
|
391
|
+
let jsonStr = response.trim();
|
|
392
|
+
const jsonMatch = jsonStr.match(/```(?:json)?\s*(\{[\s\S]*\})\s*```/);
|
|
393
|
+
if (jsonMatch)
|
|
394
|
+
jsonStr = jsonMatch[1];
|
|
395
|
+
const parsed = JSON.parse(jsonStr);
|
|
396
|
+
return {
|
|
397
|
+
fixed: Boolean(parsed.fixed),
|
|
398
|
+
explanation: parsed.explanation || 'Verification complete',
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
const looksFixed = response.toLowerCase().includes('"fixed": true') ||
|
|
403
|
+
response.toLowerCase().includes('"fixed":true');
|
|
404
|
+
return {
|
|
405
|
+
fixed: looksFixed,
|
|
406
|
+
explanation: response.slice(0, 300),
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
//# sourceMappingURL=diagnose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnose.js","sourceRoot":"","sources":["../src/diagnose.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DiagnosticAction } from './diagnose';
|
|
2
|
+
export interface ActionResult {
|
|
3
|
+
action: DiagnosticAction;
|
|
4
|
+
success: boolean;
|
|
5
|
+
output: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
backupPath?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ExecuteResult {
|
|
10
|
+
results: ActionResult[];
|
|
11
|
+
allSucceeded: boolean;
|
|
12
|
+
summary: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function executeActions(actions: DiagnosticAction[], onProgress?: (msg: string, result?: ActionResult) => void, dryRun?: boolean): Promise<ExecuteResult>;
|
|
15
|
+
export declare function formatExecuteResults(results: ActionResult[]): string;
|
|
16
|
+
//# sourceMappingURL=execute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAI9C,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAuCD,wBAAsB,cAAc,CAClC,OAAO,EAAE,gBAAgB,EAAE,EAC3B,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,KAAK,IAAI,EACzD,MAAM,UAAQ,GACb,OAAO,CAAC,aAAa,CAAC,CA8ExB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAOpE"}
|