v0.0.79 - Enhance existing-agent wizard with full config recovery review edit flow and new-agent fallback
This commit is contained in:
149
plans/enhanced_existing_agent_wizard.md
Normal file
149
plans/enhanced_existing_agent_wizard.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# Enhanced Existing Agent Wizard Flow
|
||||
|
||||
## Problem
|
||||
|
||||
When choosing "existing agent" in the wizard, the current flow:
|
||||
1. Asks for nsec
|
||||
2. Recovers kind 10002 relay list from Nostr
|
||||
3. Immediately boots the agent
|
||||
|
||||
This is insufficient when installing an existing agent on a **new server** because:
|
||||
- You cannot review or change the admin pubkey
|
||||
- You cannot review or change the LLM provider/model/API key
|
||||
- You cannot install a systemd service with a dedicated user
|
||||
- You cannot see what config was recovered from Nostr
|
||||
- The agent name is not recovered from the kind 0 profile
|
||||
|
||||
## Current Code
|
||||
|
||||
- [`existing_agent_flow()`](src/setup_wizard.c:1795) — 22 lines, minimal recovery
|
||||
- [`recover_existing_config_from_nostr()`](src/setup_wizard.c:792) — only recovers kind 10002 relays
|
||||
- Returns `SETUP_WIZARD_RC_EXISTING` (2) which does NOT set `bootstrap_mode`
|
||||
- In `main.c`, existing agents skip `reconcile_startup_events()` unless `first_run` is detected
|
||||
|
||||
## Data Available on Nostr for an Existing Agent
|
||||
|
||||
| Data | Kind | Storage | Recovery Method |
|
||||
|------|------|---------|-----------------|
|
||||
| Relay list | 10002 | Public tags | `query_and_extract_kind10002_relays()` |
|
||||
| Agent profile/name | 0 | Public JSON content | Query kind 0 by agent pubkey |
|
||||
| LLM config | 30078 d=llm_config | NIP-44 encrypted to self | `fetch_self_config_plaintext()` |
|
||||
| Agent config - admin pubkey, DM protocol | 30078 d=agent_config | NIP-44 encrypted to self | `fetch_self_config_plaintext()` |
|
||||
| Default skill | 31124 d=didactyl-default | Public content | Query kind 31124 by agent pubkey |
|
||||
| Adoption list | 10123 | Public tags | Query kind 10123 by agent pubkey |
|
||||
|
||||
## Proposed Enhanced Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Enter nsec] --> B[Connect to default relays]
|
||||
B --> C[Recover kind 10002 relay list]
|
||||
C --> D{Relay list found?}
|
||||
D -->|No| E{Offer to create new agent with this nsec}
|
||||
E -->|Yes| E2[Jump to new_agent_flow with nsec pre-loaded]
|
||||
E -->|No| E3[Return to main menu]
|
||||
D -->|Yes| F[Reconnect with recovered relays]
|
||||
F --> G[Recover all config from Nostr]
|
||||
G --> H[Display recovered config summary]
|
||||
H --> I{Review each setting}
|
||||
I -->|Keep all| J[Review summary + launch options]
|
||||
I -->|Change admin| K[Prompt new admin pubkey]
|
||||
I -->|Change LLM| L[Prompt LLM config]
|
||||
I -->|Change relays| M[Prompt relay config]
|
||||
K --> I
|
||||
L --> I
|
||||
M --> I
|
||||
J --> N{Launch option}
|
||||
N -->|Boot now| O[Return EXISTING]
|
||||
N -->|Install systemd| P[Install dedicated-user service]
|
||||
N -->|Quit| Q[Exit]
|
||||
```
|
||||
|
||||
### Step-by-step
|
||||
|
||||
#### Step 1: Identity — Enter nsec
|
||||
Same as current. Derive keys from nsec.
|
||||
|
||||
#### Step 2: Recovery — Connect and fetch config from Nostr
|
||||
1. Init nostr handler with default relays
|
||||
2. Wait for relay connections
|
||||
3. Query kind 10002 for relay list — if not found, offer to create a new agent with this nsec (jump to `new_agent_flow` with keys pre-loaded, skipping identity step)
|
||||
4. Cleanup and re-init with recovered relays
|
||||
5. Wait for relay connections on recovered relays
|
||||
6. Query kind 0 for agent profile — extract display_name/name
|
||||
7. Query kind 30078 d=llm_config — decrypt and parse LLM settings
|
||||
8. Query kind 30078 d=agent_config — decrypt and parse admin pubkey + DM protocol
|
||||
9. Cleanup nostr handler
|
||||
|
||||
#### Step 3: Review — Present recovered config
|
||||
Display all recovered values:
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Existing Agent -- Recovered Configuration │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ Agent name: Simon │
|
||||
│ Identity: b27072b7fc2edf45... │
|
||||
│ Admin: a1b2c3d4e5f6... │
|
||||
│ LLM Provider: ppq │
|
||||
│ LLM Model: claude-haiku-4.5 │
|
||||
│ LLM Base URL: https://api.ppq.ai │
|
||||
│ LLM API Key: sk-...**** │
|
||||
│ DM Protocol: nip04 │
|
||||
│ Relays: 5 configured │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Then offer a menu:
|
||||
```
|
||||
[a] change Admin pubkey
|
||||
[l] change LLM provider/model/key
|
||||
[r] change Relay configuration
|
||||
[c] continue with these settings
|
||||
[q] quit
|
||||
```
|
||||
|
||||
Each change option reuses the existing prompt functions (`prompt_admin_pubkey`, `prompt_llm_config`, `prompt_relay_configuration`) but with context-appropriate headers.
|
||||
|
||||
After any change, redisplay the summary and menu.
|
||||
|
||||
#### Step 4: Launch — Boot or install systemd
|
||||
Same as the new-agent flow's final step:
|
||||
```
|
||||
[b] boot the agent now
|
||||
[i] install dedicated-user systemd service and boot
|
||||
[q] quit
|
||||
```
|
||||
|
||||
The systemd install reuses `install_system_service_with_dedicated_user()`.
|
||||
|
||||
### Return Codes
|
||||
|
||||
- If user chooses "boot now": return `SETUP_WIZARD_RC_EXISTING` (2) — same as current
|
||||
- If user chooses "install systemd": return `SETUP_WIZARD_RC_EXIT` (1) — agent runs as systemd service
|
||||
- If user changed config values: the `main()` flow should still work because `recover_missing_runtime_config_from_nostr()` at line 1108 will fill in any gaps, and the existing agent path at line 1163 loads system context from adopted skills
|
||||
|
||||
### Key Consideration: bootstrap_mode for changed configs
|
||||
|
||||
If the user changes LLM or admin config in the wizard, those changes need to be persisted back to Nostr. Currently, `persist_runtime_config_to_nostr()` is only called when `bootstrap_mode || first_run`.
|
||||
|
||||
**Solution**: When the existing-agent wizard detects that config was changed, return `SETUP_WIZARD_RC_BOOTSTRAP` (0) instead of `SETUP_WIZARD_RC_EXISTING` (2). This triggers the full reconcile path which persists the updated config.
|
||||
|
||||
## Files to Modify
|
||||
|
||||
1. **`src/setup_wizard.c`**:
|
||||
- Add `recover_full_config_from_nostr()` — fetches kind 0, kind 30078 llm_config, kind 30078 agent_config
|
||||
- Add `query_self_kind0_name()` — queries agent's own kind 0 profile for name
|
||||
- Add `fetch_and_decrypt_self_config()` — replicates `fetch_self_config_plaintext()` logic from main.c for use in wizard context
|
||||
- Rewrite `existing_agent_flow()` with the enhanced multi-step flow
|
||||
- Make `prompt_admin_pubkey()`, `prompt_llm_config()`, `prompt_relay_configuration()` accept a context string parameter for the page header, or add wrapper versions for the existing-agent context
|
||||
|
||||
2. **`src/main.c`**:
|
||||
- Potentially expose `fetch_self_config_plaintext()`, `apply_recalled_llm_config()`, `apply_recalled_agent_config()` as non-static, OR duplicate the logic in setup_wizard.c
|
||||
- Better approach: move these to a shared location or make them accessible via a header
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The wizard already calls `nostr_handler_init()` / `nostr_handler_cleanup()` for validation queries. The enhanced flow will do the same but with two init/cleanup cycles: first with default relays to get kind 10002, then with recovered relays to get everything else.
|
||||
- The `prompt_admin_pubkey()` and `prompt_llm_config()` functions currently have hardcoded step headers like "Step 3 of 7". These should be parameterized or have existing-agent variants.
|
||||
- The `fetch_self_config_plaintext()` function in main.c requires an active nostr handler. The wizard will need to have the handler initialized when calling it.
|
||||
- API key display should be masked — show only first 4 and last 4 characters.
|
||||
Reference in New Issue
Block a user