mirror of
https://github.com/dtzp555-max/clawkeeper.git
synced 2026-07-19 09:41:42 +00:00
feat: add switch --dry-run preview mode
This commit is contained in:
@@ -14,10 +14,12 @@ Goals:
|
|||||||
- Shows OpenClaw memory status when available
|
- Shows OpenClaw memory status when available
|
||||||
- For `provider=openai`, runs a real minimal embeddings probe
|
- For `provider=openai`, runs a real minimal embeddings probe
|
||||||
- For `provider=ollama`, checks reachability and whether `nomic-embed-text` is present
|
- For `provider=ollama`, checks reachability and whether `nomic-embed-text` is present
|
||||||
- `clawkeeper switch openai|ollama`
|
- `clawkeeper switch openai|ollama [--dry-run]`
|
||||||
- Switches `agents.defaults.memorySearch.provider`
|
- `--dry-run` previews the provider/config change without writing config or restarting the gateway
|
||||||
- Makes a timestamped backup of `~/.openclaw/openclaw.json`
|
- Real switches update `agents.defaults.memorySearch.provider`
|
||||||
- Restarts the gateway after switching
|
- Switching to `ollama` removes `memorySearch.remote` from that section to avoid stale OpenAI config there
|
||||||
|
- Makes a timestamped backup of `~/.openclaw/openclaw.json` before any real write
|
||||||
|
- Restarts the gateway after a real config change
|
||||||
- `clawkeeper backup-plan [--json]`
|
- `clawkeeper backup-plan [--json]`
|
||||||
- Prints recommended daily/weekly backup coverage
|
- Prints recommended daily/weekly backup coverage
|
||||||
- `--json` emits machine-readable include/exclude structure
|
- `--json` emits machine-readable include/exclude structure
|
||||||
@@ -55,6 +57,8 @@ memops --help
|
|||||||
clawkeeper doctor
|
clawkeeper doctor
|
||||||
clawkeeper switch ollama
|
clawkeeper switch ollama
|
||||||
clawkeeper switch openai
|
clawkeeper switch openai
|
||||||
|
clawkeeper switch ollama --dry-run
|
||||||
|
clawkeeper switch openai --dry-run
|
||||||
clawkeeper backup-plan
|
clawkeeper backup-plan
|
||||||
clawkeeper backup-plan --json
|
clawkeeper backup-plan --json
|
||||||
clawkeeper verify-backup ~/openclaw-backup.tgz
|
clawkeeper verify-backup ~/openclaw-backup.tgz
|
||||||
|
|||||||
+39
-7
@@ -188,10 +188,13 @@ function backupPlan(opts: { json?: boolean } = {}) {
|
|||||||
for (const p of plan.weeklyFull.include) console.log(`- ${p}`);
|
for (const p of plan.weeklyFull.include) console.log(`- ${p}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchProvider(to: 'openai' | 'ollama') {
|
function switchProvider(to: 'openai' | 'ollama', opts: { dryRun?: boolean } = {}) {
|
||||||
const cfg = loadConfig();
|
const cfg = loadConfig();
|
||||||
const path = ['agents', 'defaults', 'memorySearch'];
|
const path = ['agents', 'defaults', 'memorySearch'];
|
||||||
const ms = get(cfg, path) || {};
|
const msBefore = structuredClone(get(cfg, path) || {});
|
||||||
|
const from = msBefore?.provider;
|
||||||
|
const hadRemote = !!msBefore?.remote;
|
||||||
|
const hadOpenAIKey = !!msBefore?.remote?.apiKey;
|
||||||
|
|
||||||
if (to === 'ollama') {
|
if (to === 'ollama') {
|
||||||
set(cfg, [...path, 'provider'], 'ollama');
|
set(cfg, [...path, 'provider'], 'ollama');
|
||||||
@@ -200,9 +203,37 @@ function switchProvider(to: 'openai' | 'ollama') {
|
|||||||
} else {
|
} else {
|
||||||
set(cfg, [...path, 'provider'], 'openai');
|
set(cfg, [...path, 'provider'], 'openai');
|
||||||
// keep existing remote.apiKey if present; do not prompt
|
// keep existing remote.apiKey if present; do not prompt
|
||||||
if (!ms?.remote?.apiKey) {
|
}
|
||||||
|
|
||||||
|
const msAfter = get(cfg, path) || {};
|
||||||
|
const removedRemote = hadRemote && !msAfter?.remote;
|
||||||
|
const changed = JSON.stringify(msBefore) !== JSON.stringify(msAfter);
|
||||||
|
|
||||||
|
if (opts.dryRun) {
|
||||||
|
console.log('Dry run: no changes applied.');
|
||||||
|
console.log(`config: ${OPENCLAW_CONFIG}`);
|
||||||
|
console.log(`memorySearch.provider: ${from} -> ${to}`);
|
||||||
|
if (to === 'ollama') {
|
||||||
|
console.log(`memorySearch.remote: ${removedRemote ? 'would be removed' : 'no change'}`);
|
||||||
|
} else {
|
||||||
|
console.log(`memorySearch.remote.apiKey.present: ${hadOpenAIKey}`);
|
||||||
|
if (!hadOpenAIKey) {
|
||||||
|
console.log('WARN: memorySearch.remote.apiKey is not set. A real switch to openai would still proceed, but memory search may remain broken until configured.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`config mutation: ${changed ? 'would update openclaw.json' : 'no-op (already matches requested provider)'}`);
|
||||||
|
console.log(`config backup: ${changed ? 'would create timestamped backup before write' : 'would skip (no write needed)'}`);
|
||||||
|
console.log(`gateway restart: ${changed ? 'would restart after config write' : 'would skip (no write needed)'}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to === 'openai' && !hadOpenAIKey) {
|
||||||
console.error('WARN: memorySearch.remote.apiKey is not set. Configure it in openclaw.json first.');
|
console.error('WARN: memorySearch.remote.apiKey is not set. Configure it in openclaw.json first.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!changed) {
|
||||||
|
console.log(`memorySearch.provider is already ${to}; no config changes made and gateway restart skipped.`);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveConfig(cfg);
|
saveConfig(cfg);
|
||||||
@@ -221,7 +252,7 @@ if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
|
|||||||
console.log('clawkeeper');
|
console.log('clawkeeper');
|
||||||
console.log('Commands:');
|
console.log('Commands:');
|
||||||
console.log(' clawkeeper doctor');
|
console.log(' clawkeeper doctor');
|
||||||
console.log(' clawkeeper switch openai|ollama');
|
console.log(' clawkeeper switch openai|ollama [--dry-run]');
|
||||||
console.log(' clawkeeper backup-plan [--json]');
|
console.log(' clawkeeper backup-plan [--json]');
|
||||||
console.log(' clawkeeper verify-backup <path.tgz>');
|
console.log(' clawkeeper verify-backup <path.tgz>');
|
||||||
console.log(' clawkeeper restore-guide');
|
console.log(' clawkeeper restore-guide');
|
||||||
@@ -275,9 +306,10 @@ else if (cmd === 'restore-apply') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cmd === 'switch') {
|
else if (cmd === 'switch') {
|
||||||
const to = args[0];
|
const to = args.find(arg => arg === 'openai' || arg === 'ollama');
|
||||||
if (to !== 'openai' && to !== 'ollama') die('Usage: clawkeeper switch openai|ollama');
|
const dryRun = args.includes('--dry-run');
|
||||||
switchProvider(to);
|
if (to !== 'openai' && to !== 'ollama') die('Usage: clawkeeper switch openai|ollama [--dry-run]');
|
||||||
|
switchProvider(to, { dryRun });
|
||||||
} else {
|
} else {
|
||||||
die(`Unknown command: ${cmd}`);
|
die(`Unknown command: ${cmd}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user