fix(agent): serialize runs per session
This commit is contained in:
@@ -131,6 +131,7 @@ Controls the embedded agent runtime (provider/model/thinking/verbose/timeouts).
|
||||
timeoutSeconds: 600,
|
||||
mediaMaxMb: 5,
|
||||
heartbeatMinutes: 30,
|
||||
maxConcurrent: 3,
|
||||
bash: {
|
||||
backgroundMs: 20000,
|
||||
timeoutSec: 1800,
|
||||
@@ -146,6 +147,10 @@ Controls the embedded agent runtime (provider/model/thinking/verbose/timeouts).
|
||||
- `timeoutSec`: auto-kill after this runtime (seconds, default 1800)
|
||||
- `cleanupMs`: how long to keep finished sessions in memory (ms, default 1800000)
|
||||
|
||||
`agent.maxConcurrent` sets the maximum number of embedded agent runs that can
|
||||
execute in parallel across sessions. Each session is still serialized (one run
|
||||
per session key at a time). Default: 1.
|
||||
|
||||
### `models` (custom providers + base URLs)
|
||||
|
||||
Clawdis uses the **pi-coding-agent** model catalog. You can add custom providers
|
||||
|
||||
@@ -5,22 +5,24 @@ read_when:
|
||||
---
|
||||
# Command Queue (2025-11-25)
|
||||
|
||||
We now serialize all command-based auto-replies (WhatsApp Web listener) through a tiny in-process queue to prevent multiple commands from running at once.
|
||||
We now serialize command-based auto-replies (WhatsApp Web listener) through a tiny in-process queue to prevent multiple commands from running at once, while allowing safe parallelism across sessions.
|
||||
|
||||
## Why
|
||||
- Some auto-reply commands are expensive (LLM calls) and can collide when multiple inbound messages arrive close together.
|
||||
- Serializing avoids competing for terminal/stdin, keeps logs readable, and reduces the chance of rate limits from upstream tools.
|
||||
|
||||
## How it works
|
||||
- `src/process/command-queue.ts` holds a single FIFO queue and drains it synchronously; only one task runs at a time.
|
||||
- `getReplyFromConfig` wraps command execution with `enqueueCommand(...)`, so every config-driven command reply flows through the queue automatically.
|
||||
- `src/process/command-queue.ts` holds a lane-aware FIFO queue and drains each lane synchronously.
|
||||
- `runEmbeddedPiAgent` enqueues by **session key** (lane `session:<key>`) to guarantee only one active run per session.
|
||||
- Each session run is then queued into a **global lane** (`main` by default) so overall parallelism is capped by `agent.maxConcurrent`.
|
||||
- When verbose logging is enabled, queued commands emit a short notice if they waited more than ~2s before starting.
|
||||
- Typing indicators (`onReplyStart`) still fire immediately on enqueue so user experience is unchanged while we wait our turn.
|
||||
|
||||
## Scope and guarantees
|
||||
- Applies only to config-driven command replies; plain text replies are unaffected.
|
||||
- Default lane (`main`) is process-wide for inbound + main heartbeats to keep the primary workflow serialized.
|
||||
- Default lane (`main`) is process-wide for inbound + main heartbeats; set `agent.maxConcurrent` to allow multiple sessions in parallel.
|
||||
- Additional lanes may exist (e.g. `cron`) so background jobs can run in parallel without blocking inbound replies.
|
||||
- Per-session lanes guarantee that only one agent run touches a given session at a time.
|
||||
- No external dependencies or background worker threads; pure TypeScript + promises.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Reference in New Issue
Block a user