feat: refactor model selection to use developer tiers
- Replaced raw model aliases with developer tiers (junior, medior, senior, qa) in dispatch and model selection logic. - Updated `dispatchTask` to resolve models based on tiers and plugin configuration. - Modified `selectModel` to return tier names instead of model aliases based on task description. - Implemented migration logic for transitioning from old model aliases to new tier names in worker state. - Added setup logic for agent creation and model configuration in `setup.ts`. - Created shared templates for workspace files and instructions for DEV/QA workers. - Enhanced project registration to scaffold role files based on developer tiers. - Updated task management tools to reflect changes in model selection and tier assignment. - Introduced a new `devclaw_setup` tool for agent-driven setup and configuration. - Updated plugin configuration schema to support model mapping per developer tier.
This commit is contained in:
@@ -8,28 +8,28 @@ Understanding the OpenClaw model is key to understanding how DevClaw works:
|
||||
- **Session** — A runtime conversation instance. Each session has its own context window and conversation history, stored as a `.jsonl` transcript file.
|
||||
- **Sub-agent session** — A session created under the orchestrator agent for a specific worker role. NOT a separate agent — it's a child session running under the same agent, with its own isolated context. Format: `agent:<parent>:subagent:<uuid>`.
|
||||
|
||||
### Session-per-model design
|
||||
### Session-per-tier design
|
||||
|
||||
Each project maintains **separate sessions per model per role**. A project's DEV might have a Haiku session, a Sonnet session, and an Opus session — each accumulating its own codebase context over time.
|
||||
Each project maintains **separate sessions per developer tier per role**. A project's DEV might have a junior session, a medior session, and a senior session — each accumulating its own codebase context over time.
|
||||
|
||||
```
|
||||
Orchestrator Agent (configured in openclaw.json)
|
||||
└─ Main session (long-lived, handles all projects)
|
||||
│
|
||||
├─ Project A
|
||||
│ ├─ DEV sessions: { haiku: <uuid>, sonnet: <uuid>, opus: null }
|
||||
│ └─ QA sessions: { grok: <uuid> }
|
||||
│ ├─ DEV sessions: { junior: <uuid>, medior: <uuid>, senior: null }
|
||||
│ └─ QA sessions: { qa: <uuid> }
|
||||
│
|
||||
└─ Project B
|
||||
├─ DEV sessions: { haiku: null, sonnet: <uuid>, opus: null }
|
||||
└─ QA sessions: { grok: <uuid> }
|
||||
├─ DEV sessions: { junior: null, medior: <uuid>, senior: null }
|
||||
└─ QA sessions: { qa: <uuid> }
|
||||
```
|
||||
|
||||
Why per-model instead of switching models on one session:
|
||||
Why per-tier instead of switching models on one session:
|
||||
- **No model switching overhead** — each session always uses the same model
|
||||
- **Accumulated context** — a Haiku session that's done 20 typo fixes knows the project well; a Sonnet session that's done 5 features knows it differently
|
||||
- **Accumulated context** — a junior session that's done 20 typo fixes knows the project well; a medior session that's done 5 features knows it differently
|
||||
- **No cross-model confusion** — conversation history stays with the model that generated it
|
||||
- **Deterministic reuse** — model selection directly maps to a session key, no patching needed
|
||||
- **Deterministic reuse** — tier selection directly maps to a session key, no patching needed
|
||||
|
||||
### Plugin-controlled session lifecycle
|
||||
|
||||
@@ -37,14 +37,14 @@ DevClaw controls the **full** session lifecycle end-to-end. The orchestrator age
|
||||
|
||||
```
|
||||
Plugin dispatch (inside task_pickup):
|
||||
1. Select model, look up session, decide spawn vs send
|
||||
1. Assign tier, look up session, decide spawn vs send
|
||||
2. New session: openclaw gateway call sessions.patch → create entry + set model
|
||||
openclaw agent --session-id <key> --message "task..."
|
||||
3. Existing: openclaw agent --session-id <key> --message "task..."
|
||||
4. Return result to orchestrator (announcement text, no session instructions)
|
||||
```
|
||||
|
||||
The agent's only job after `task_pickup` returns is to post the announcement to Telegram. Everything else — model selection, session creation, task dispatch, state update, audit logging — is deterministic plugin code.
|
||||
The agent's only job after `task_pickup` returns is to post the announcement to Telegram. Everything else — tier assignment, session creation, task dispatch, state update, audit logging — is deterministic plugin code.
|
||||
|
||||
**Why this matters:** Previously the plugin returned instructions like `{ sessionAction: "spawn", model: "sonnet" }` and the agent had to correctly call `sessions_spawn` with the right params. This was the fragile handoff point where agents would forget `cleanup: "keep"`, use wrong models, or corrupt session state. Moving dispatch into the plugin eliminates that entire class of errors.
|
||||
|
||||
@@ -75,10 +75,10 @@ graph TB
|
||||
MS[Main Session<br/>orchestrator agent]
|
||||
GW[Gateway RPC<br/>sessions.patch / sessions.list]
|
||||
CLI[openclaw agent CLI]
|
||||
DEV_H[DEV session<br/>haiku]
|
||||
DEV_S[DEV session<br/>sonnet]
|
||||
DEV_O[DEV session<br/>opus]
|
||||
QA_G[QA session<br/>grok]
|
||||
DEV_J[DEV session<br/>junior]
|
||||
DEV_M[DEV session<br/>medior]
|
||||
DEV_S[DEV session<br/>senior]
|
||||
QA_E[QA session<br/>qa]
|
||||
end
|
||||
|
||||
subgraph "DevClaw Plugin"
|
||||
@@ -88,13 +88,14 @@ graph TB
|
||||
QS[queue_status]
|
||||
SH[session_health]
|
||||
PR[project_register]
|
||||
MS_SEL[Model Selector]
|
||||
DS[devclaw_setup]
|
||||
TIER[Tier Resolver]
|
||||
PJ[projects.json]
|
||||
AL[audit.log]
|
||||
end
|
||||
|
||||
subgraph "External"
|
||||
GL[GitLab]
|
||||
GL[Issue Tracker]
|
||||
REPO[Git Repository]
|
||||
end
|
||||
|
||||
@@ -108,8 +109,9 @@ graph TB
|
||||
MS -->|calls| QS
|
||||
MS -->|calls| SH
|
||||
MS -->|calls| PR
|
||||
MS -->|calls| DS
|
||||
|
||||
TP -->|selects model| MS_SEL
|
||||
TP -->|resolves tier| TIER
|
||||
TP -->|transitions labels| GL
|
||||
TP -->|reads/writes| PJ
|
||||
TP -->|appends| AL
|
||||
@@ -139,15 +141,15 @@ graph TB
|
||||
PR -->|writes entry| PJ
|
||||
PR -->|appends| AL
|
||||
|
||||
CLI -->|sends task| DEV_H
|
||||
CLI -->|sends task| DEV_J
|
||||
CLI -->|sends task| DEV_M
|
||||
CLI -->|sends task| DEV_S
|
||||
CLI -->|sends task| DEV_O
|
||||
CLI -->|sends task| QA_G
|
||||
CLI -->|sends task| QA_E
|
||||
|
||||
DEV_H -->|writes code, creates MRs| REPO
|
||||
DEV_J -->|writes code, creates MRs| REPO
|
||||
DEV_M -->|writes code, creates MRs| REPO
|
||||
DEV_S -->|writes code, creates MRs| REPO
|
||||
DEV_O -->|writes code, creates MRs| REPO
|
||||
QA_G -->|reviews code, tests| REPO
|
||||
QA_E -->|reviews code, tests| REPO
|
||||
```
|
||||
|
||||
## End-to-end flow: human to sub-agent
|
||||
@@ -162,8 +164,8 @@ sequenceDiagram
|
||||
participant DC as DevClaw Plugin
|
||||
participant GW as Gateway RPC
|
||||
participant CLI as openclaw agent CLI
|
||||
participant DEV as DEV Session<br/>(sonnet)
|
||||
participant GL as GitLab
|
||||
participant DEV as DEV Session<br/>(medior)
|
||||
participant GL as Issue Tracker
|
||||
|
||||
Note over H,GL: Issue exists in queue (To Do)
|
||||
|
||||
@@ -173,49 +175,49 @@ sequenceDiagram
|
||||
DC->>GL: glab issue list --label "To Do"
|
||||
DC-->>MS: { toDo: [#42], dev: idle }
|
||||
|
||||
Note over MS: Decides to pick up #42 for DEV
|
||||
Note over MS: Decides to pick up #42 for DEV as medior
|
||||
|
||||
MS->>DC: task_pickup({ issueId: 42, role: "dev", ... })
|
||||
DC->>DC: selectModel → "sonnet"
|
||||
DC->>DC: lookup dev.sessions.sonnet → null (first time)
|
||||
MS->>DC: task_pickup({ issueId: 42, role: "dev", model: "medior", ... })
|
||||
DC->>DC: resolve tier "medior" → model ID
|
||||
DC->>DC: lookup dev.sessions.medior → null (first time)
|
||||
DC->>GL: glab issue update 42 --unlabel "To Do" --label "Doing"
|
||||
DC->>GW: sessions.patch({ key: new-session-key, model: "sonnet" })
|
||||
DC->>GW: sessions.patch({ key: new-session-key, model: "anthropic/claude-sonnet-4-5" })
|
||||
DC->>CLI: openclaw agent --session-id <key> --message "Build login page for #42..."
|
||||
CLI->>DEV: creates session, delivers task
|
||||
DC->>DC: store session key in projects.json + append audit.log
|
||||
DC-->>MS: { success: true, announcement: "🔧 DEV (sonnet) picking up #42" }
|
||||
DC-->>MS: { success: true, announcement: "🔧 DEV (medior) picking up #42" }
|
||||
|
||||
MS->>TG: "🔧 DEV (sonnet) picking up #42: Add login page"
|
||||
MS->>TG: "🔧 DEV (medior) picking up #42: Add login page"
|
||||
TG->>H: sees announcement
|
||||
|
||||
Note over DEV: Works autonomously — reads code, writes code, creates MR
|
||||
Note over MS: Heartbeat detects DEV session idle → triggers task_complete
|
||||
Note over DEV: Calls task_complete when done
|
||||
|
||||
MS->>DC: task_complete({ role: "dev", result: "done", ... })
|
||||
DEV->>DC: task_complete({ role: "dev", result: "done", ... })
|
||||
DC->>GL: glab issue update 42 --unlabel "Doing" --label "To Test"
|
||||
DC->>DC: deactivate worker (sessions preserved)
|
||||
DC-->>MS: { announcement: "✅ DEV done #42" }
|
||||
DC-->>DEV: { announcement: "✅ DEV done #42" }
|
||||
|
||||
MS->>TG: "✅ DEV done #42 — moved to QA queue"
|
||||
TG->>H: sees announcement
|
||||
```
|
||||
|
||||
On the **next DEV task** for this project that also selects Sonnet:
|
||||
On the **next DEV task** for this project that also assigns medior:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant MS as Main Session
|
||||
participant DC as DevClaw Plugin
|
||||
participant CLI as openclaw agent CLI
|
||||
participant DEV as DEV Session<br/>(sonnet, existing)
|
||||
participant DEV as DEV Session<br/>(medior, existing)
|
||||
|
||||
MS->>DC: task_pickup({ issueId: 57, role: "dev", ... })
|
||||
DC->>DC: selectModel → "sonnet"
|
||||
DC->>DC: lookup dev.sessions.sonnet → existing key!
|
||||
MS->>DC: task_pickup({ issueId: 57, role: "dev", model: "medior", ... })
|
||||
DC->>DC: resolve tier "medior" → model ID
|
||||
DC->>DC: lookup dev.sessions.medior → existing key!
|
||||
Note over DC: No sessions.patch needed — session already exists
|
||||
DC->>CLI: openclaw agent --session-id <key> --message "Fix validation for #57..."
|
||||
CLI->>DEV: delivers task to existing session (has full codebase context)
|
||||
DC-->>MS: { success: true, announcement: "⚡ DEV (sonnet) picking up #57" }
|
||||
DC-->>MS: { success: true, announcement: "⚡ DEV (medior) picking up #57" }
|
||||
```
|
||||
|
||||
Session reuse saves ~50K tokens per task by not re-reading the codebase.
|
||||
@@ -229,10 +231,10 @@ This traces a single issue from creation to completion, showing every component
|
||||
Issues are created by the orchestrator agent or by sub-agent sessions via `glab`. The orchestrator can create issues based on user requests in Telegram, backlog planning, or QA feedback. Sub-agents can also create issues when they discover bugs or related work during development.
|
||||
|
||||
```
|
||||
Orchestrator Agent → GitLab: creates issue #42 with label "To Do"
|
||||
Orchestrator Agent → Issue Tracker: creates issue #42 with label "To Do"
|
||||
```
|
||||
|
||||
**State:** GitLab has issue #42 labeled "To Do". Nothing in DevClaw yet.
|
||||
**State:** Issue tracker has issue #42 labeled "To Do". Nothing in DevClaw yet.
|
||||
|
||||
### Phase 2: Heartbeat detects work
|
||||
|
||||
@@ -244,7 +246,7 @@ Heartbeat triggers → Orchestrator calls queue_status()
|
||||
sequenceDiagram
|
||||
participant A as Orchestrator
|
||||
participant QS as queue_status
|
||||
participant GL as GitLab
|
||||
participant GL as Issue Tracker
|
||||
participant PJ as projects.json
|
||||
participant AL as audit.log
|
||||
|
||||
@@ -261,33 +263,33 @@ sequenceDiagram
|
||||
QS-->>A: { dev: idle, queue: { toDo: [#42] } }
|
||||
```
|
||||
|
||||
**Orchestrator decides:** DEV is idle, issue #42 is in To Do → pick it up.
|
||||
**Orchestrator decides:** DEV is idle, issue #42 is in To Do → pick it up. Evaluates complexity → assigns medior tier.
|
||||
|
||||
### Phase 3: DEV pickup
|
||||
|
||||
The plugin handles everything end-to-end — model selection, session lookup, label transition, state update, **and** task dispatch to the worker session. The agent's only job after is to post the announcement.
|
||||
The plugin handles everything end-to-end — tier resolution, session lookup, label transition, state update, **and** task dispatch to the worker session. The agent's only job after is to post the announcement.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant A as Orchestrator
|
||||
participant TP as task_pickup
|
||||
participant GL as GitLab
|
||||
participant MS as Model Selector
|
||||
participant GL as Issue Tracker
|
||||
participant TIER as Tier Resolver
|
||||
participant GW as Gateway RPC
|
||||
participant CLI as openclaw agent CLI
|
||||
participant PJ as projects.json
|
||||
participant AL as audit.log
|
||||
|
||||
A->>TP: task_pickup({ issueId: 42, role: "dev", projectGroupId: "-123" })
|
||||
A->>TP: task_pickup({ issueId: 42, role: "dev", projectGroupId: "-123", model: "medior" })
|
||||
TP->>PJ: readProjects()
|
||||
TP->>GL: glab issue view 42 --output json
|
||||
GL-->>TP: { title: "Add login page", labels: ["To Do"] }
|
||||
TP->>TP: Verify label is "To Do" ✓
|
||||
TP->>TP: model from agent param (LLM-selected) or fallback heuristic
|
||||
TP->>PJ: lookup dev.sessions.sonnet
|
||||
TP->>TIER: resolve "medior" → "anthropic/claude-sonnet-4-5"
|
||||
TP->>PJ: lookup dev.sessions.medior
|
||||
TP->>GL: glab issue update 42 --unlabel "To Do" --label "Doing"
|
||||
alt New session
|
||||
TP->>GW: sessions.patch({ key: new-key, model: "sonnet" })
|
||||
TP->>GW: sessions.patch({ key: new-key, model: "anthropic/claude-sonnet-4-5" })
|
||||
end
|
||||
TP->>CLI: openclaw agent --session-id <key> --message "task..."
|
||||
TP->>PJ: activateWorker + store session key
|
||||
@@ -296,8 +298,8 @@ sequenceDiagram
|
||||
```
|
||||
|
||||
**Writes:**
|
||||
- `GitLab`: label "To Do" → "Doing"
|
||||
- `projects.json`: dev.active=true, dev.issueId="42", dev.model="sonnet", dev.sessions.sonnet=key
|
||||
- `Issue Tracker`: label "To Do" → "Doing"
|
||||
- `projects.json`: dev.active=true, dev.issueId="42", dev.model="medior", dev.sessions.medior=key
|
||||
- `audit.log`: 2 entries (task_pickup, model_selection)
|
||||
- `Session`: task message delivered to worker session via CLI
|
||||
|
||||
@@ -316,7 +318,7 @@ This happens inside the OpenClaw session. The worker calls `task_complete` direc
|
||||
sequenceDiagram
|
||||
participant DEV as DEV Session
|
||||
participant TC as task_complete
|
||||
participant GL as GitLab
|
||||
participant GL as Issue Tracker
|
||||
participant PJ as projects.json
|
||||
participant AL as audit.log
|
||||
participant REPO as Git Repo
|
||||
@@ -333,7 +335,7 @@ sequenceDiagram
|
||||
|
||||
alt autoChain enabled
|
||||
TC->>GL: transition label "To Test" → "Testing"
|
||||
TC->>QA: dispatchTask(role: "qa", model: "grok")
|
||||
TC->>QA: dispatchTask(role: "qa", tier: "qa")
|
||||
TC->>PJ: activateWorker(-123, qa)
|
||||
TC-->>DEV: { announcement: "✅ DEV done #42", autoChain: { dispatched: true, role: "qa" } }
|
||||
else autoChain disabled
|
||||
@@ -344,12 +346,12 @@ sequenceDiagram
|
||||
**Writes:**
|
||||
- `Git repo`: pulled latest (has DEV's merged code)
|
||||
- `projects.json`: dev.active=false, dev.issueId=null (sessions map preserved for reuse)
|
||||
- `GitLab`: label "Doing" → "To Test" (+ "To Test" → "Testing" if auto-chain)
|
||||
- `Issue Tracker`: label "Doing" → "To Test" (+ "To Test" → "Testing" if auto-chain)
|
||||
- `audit.log`: 1 entry (task_complete) + optional auto-chain entries
|
||||
|
||||
### Phase 6: QA pickup
|
||||
|
||||
Same as Phase 3, but with `role: "qa"`. Label transitions "To Test" → "Testing". Model defaults to Grok for QA.
|
||||
Same as Phase 3, but with `role: "qa"`. Label transitions "To Test" → "Testing". Uses the qa tier.
|
||||
|
||||
### Phase 7: QA result (3 possible outcomes)
|
||||
|
||||
@@ -359,7 +361,7 @@ Same as Phase 3, but with `role: "qa"`. Label transitions "To Test" → "Testing
|
||||
sequenceDiagram
|
||||
participant A as Orchestrator
|
||||
participant TC as task_complete
|
||||
participant GL as GitLab
|
||||
participant GL as Issue Tracker
|
||||
participant PJ as projects.json
|
||||
participant AL as audit.log
|
||||
|
||||
@@ -379,8 +381,7 @@ sequenceDiagram
|
||||
sequenceDiagram
|
||||
participant A as Orchestrator
|
||||
participant TC as task_complete
|
||||
participant GL as GitLab
|
||||
participant MS as Model Selector
|
||||
participant GL as Issue Tracker
|
||||
participant PJ as projects.json
|
||||
participant AL as audit.log
|
||||
|
||||
@@ -421,12 +422,12 @@ sequenceDiagram
|
||||
A->>QS: queue_status()
|
||||
QS-->>A: { projects: [{ dev: idle, queue: { toDo: [#43], toTest: [#44] } }] }
|
||||
|
||||
Note over A: DEV idle + To Do #43 → pick up
|
||||
A->>TP: task_pickup({ issueId: 43, role: "dev", ... })
|
||||
Note over TP: Plugin handles everything:<br/>model select → session lookup →<br/>label transition → dispatch task →<br/>state update → audit log
|
||||
Note over A: DEV idle + To Do #43 → assign medior
|
||||
A->>TP: task_pickup({ issueId: 43, role: "dev", model: "medior", ... })
|
||||
Note over TP: Plugin handles everything:<br/>tier resolve → session lookup →<br/>label transition → dispatch task →<br/>state update → audit log
|
||||
|
||||
Note over A: QA idle + To Test #44 → pick up
|
||||
A->>TP: task_pickup({ issueId: 44, role: "qa", ... })
|
||||
Note over A: QA idle + To Test #44 → assign qa
|
||||
A->>TP: task_pickup({ issueId: 44, role: "qa", model: "qa", ... })
|
||||
```
|
||||
|
||||
## Data flow map
|
||||
@@ -447,7 +448,8 @@ Every piece of data and where it lives:
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ DevClaw Plugin (orchestration logic) │
|
||||
│ │
|
||||
│ task_pickup → model + label + dispatch + role instr (e2e) │
|
||||
│ devclaw_setup → agent creation + workspace + model config │
|
||||
│ task_pickup → tier + label + dispatch + role instr (e2e) │
|
||||
│ task_complete → label + state + git pull + auto-chain │
|
||||
│ task_create → create issue in tracker │
|
||||
│ queue_status → read labels + read state │
|
||||
@@ -462,13 +464,13 @@ Every piece of data and where it lives:
|
||||
│ dev: │ │ openclaw gateway call │
|
||||
│ active, issueId, model │ │ sessions.patch → create │
|
||||
│ sessions: │ │ sessions.list → health │
|
||||
│ haiku: <key> │ │ sessions.delete → cleanup │
|
||||
│ sonnet: <key> │ │ │
|
||||
│ opus: <key> │ │ openclaw agent │
|
||||
│ junior: <key> │ │ sessions.delete → cleanup │
|
||||
│ medior: <key> │ │ │
|
||||
│ senior: <key> │ │ openclaw agent │
|
||||
│ qa: │ │ --session-id <key> │
|
||||
│ active, issueId, model │ │ --message "task..." │
|
||||
│ sessions: │ │ → dispatches to session │
|
||||
│ grok: <key> │ │ │
|
||||
│ qa: <key> │ │ │
|
||||
└────────────────────────────────┘ └──────────────────────────────┘
|
||||
↕ append-only
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
@@ -477,7 +479,7 @@ Every piece of data and where it lives:
|
||||
│ NDJSON, one line per event: │
|
||||
│ task_pickup, task_complete, model_selection, │
|
||||
│ queue_status, health_check, session_spawn, session_reuse, │
|
||||
│ project_register │
|
||||
│ project_register, devclaw_setup │
|
||||
│ │
|
||||
│ Query with: cat audit.log | jq 'select(.event=="task_pickup")' │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
@@ -486,8 +488,8 @@ Every piece of data and where it lives:
|
||||
│ Telegram (user-facing messages) │
|
||||
│ │
|
||||
│ Per group chat: │
|
||||
│ "🔧 Spawning DEV (sonnet) for #42: Add login page" │
|
||||
│ "⚡ Sending DEV (sonnet) for #57: Fix validation" │
|
||||
│ "🔧 Spawning DEV (medior) for #42: Add login page" │
|
||||
│ "⚡ Sending DEV (medior) for #57: Fix validation" │
|
||||
│ "✅ DEV done #42 — Login page with OAuth. Moved to QA queue."│
|
||||
│ "🎉 QA PASS #42. Issue closed." │
|
||||
│ "❌ QA FAIL #42 — OAuth redirect broken. Sent back to DEV." │
|
||||
@@ -512,6 +514,7 @@ graph LR
|
||||
L[Label transitions]
|
||||
S[Worker state]
|
||||
PR[Project registration]
|
||||
SETUP[Agent + workspace setup]
|
||||
SD[Session dispatch<br/>create + send via CLI]
|
||||
AC[Auto-chaining<br/>DEV→QA, QA fail→DEV]
|
||||
RI[Role instructions<br/>loaded per project]
|
||||
@@ -523,7 +526,7 @@ graph LR
|
||||
MSG[Telegram announcements]
|
||||
HB[Heartbeat scheduling]
|
||||
DEC[Task prioritization]
|
||||
M[Model selection]
|
||||
M[Developer assignment<br/>junior/medior/senior]
|
||||
end
|
||||
|
||||
subgraph "Sub-agent sessions handle"
|
||||
@@ -565,7 +568,7 @@ Provider selection is handled by `createProvider()` in `lib/providers/index.ts`.
|
||||
|
||||
| Failure | Detection | Recovery |
|
||||
|---|---|---|
|
||||
| Session dies mid-task | `session_health` checks via `sessions.list` Gateway RPC | `autoFix`: reverts label, clears active state, removes dead session from sessions map. Next heartbeat picks up task again (creates fresh session for that model). |
|
||||
| Session dies mid-task | `session_health` checks via `sessions.list` Gateway RPC | `autoFix`: reverts label, clears active state, removes dead session from sessions map. Next heartbeat picks up task again (creates fresh session for that tier). |
|
||||
| glab command fails | Plugin tool throws error, returns to agent | Agent retries or reports to Telegram group |
|
||||
| `openclaw agent` CLI fails | Plugin catches error during dispatch | Plugin rolls back: reverts label, clears active state. Returns error to agent for reporting. |
|
||||
| `sessions.patch` fails | Plugin catches error during session creation | Plugin rolls back label transition. Returns error. No orphaned state. |
|
||||
@@ -581,7 +584,7 @@ Provider selection is handled by `createProvider()` in `lib/providers/index.ts`.
|
||||
|---|---|---|
|
||||
| Plugin source | `~/.openclaw/extensions/devclaw/` | Plugin code |
|
||||
| Plugin manifest | `~/.openclaw/extensions/devclaw/openclaw.plugin.json` | Plugin registration |
|
||||
| Agent config | `~/.openclaw/openclaw.json` | Agent definition + tool permissions |
|
||||
| Agent config | `~/.openclaw/openclaw.json` | Agent definition + tool permissions + tier config |
|
||||
| Worker state | `~/.openclaw/workspace-<agent>/memory/projects.json` | Per-project DEV/QA state |
|
||||
| Audit log | `~/.openclaw/workspace-<agent>/memory/audit.log` | NDJSON event log |
|
||||
| Session transcripts | `~/.openclaw/agents/<agent>/sessions/<uuid>.jsonl` | Conversation history per session |
|
||||
|
||||
Reference in New Issue
Block a user