summaryrefslogtreecommitdiffhomepage
AgeCommit message (Collapse)Author
2026-06-28docs(bug): investigate tool calls appearing in thinking + turn ends abruptlyAdam Malczewski
2026-06-28fix(predev): resolve merge conflicts between concurrency-fixes and ↵Adam Malczewski
workspace-star
2026-06-28Merge branch 'feature/workspace-star' into predevAdam Malczewski
# Conflicts: # packages/provider-concurrency/src/concurrency-manager.ts # packages/provider-concurrency/src/extension.ts
2026-06-28fix(concurrency): usage-gate fast-path overshoot + fetchUsage rejection ↵Adam Malczewski
safety + persist auto-reduce notice Bug 1 (overshoot): acquire() fast-path now queues while a recycle-poll is in flight (gatePolling), and the recycle defers its inFlight decrement until the usage poll resolves — holding inFlight inflated through the poll window so a concurrent caller cannot sneak through before upstream confirms room. The gated path admits exactly one waiter per fresh poll (grantOne), robust against stale upstream counts. Common-case throughput preserved: the fast-path still grants immediately when no poll is in flight. Bug 2 (unhandled rejection): fetchUsage is wrapped in safeFetchUsage — a throwing getUsage() is caught, treated as undefined (cooldown-only fallback), and reported via the new onUsagePollError opt (warn-level). No unhandled promise rejection can crash the process. Bug 3 (lost notice): loadLimits now calls restoreLimit (a new lower-level state-seeding method that does NOT clear autoReduced) instead of setLimit (which is a manual user action that clears the notice). The auto-reduce marker (autoReducedFrom) is persisted under auto-reduce:<providerId> and restored on activate via loadAutoReduce, so the frontend banner survives a restart. +6 tests covering each bug.
2026-06-28fix(workspace-star): clean up starred cache on workspace delete + warn when ↵Adam Malczewski
concurrency service absent Bug 1 (MEDIUM): In-memory starred cache leaks IDs for deleted workspaces. The starredWorkspaces Set in the concurrency manager never cleaned up when a workspace was deleted. FIX: the DELETE /workspaces/:id route now calls concurrencyService.notifyWorkspaceStarred(id, false) after deleting, so the deleted workspace ID is removed from the in-memory cache (preventing stale IDs and preventing a re-created workspace with the same slug from inheriting the old starred state). Bug 2 (MEDIUM): Stale in-memory priority when concurrency extension is absent. If provider-concurrency is not loaded, the star toggle persisted but the in-memory priority cache was never updated (the optional chaining ?. silently skipped the call). Already-queued agents kept their old priority until restart. FIX: the star/unstar routes now check if concurrencyService is defined and log a warning when it is absent, making the degraded behavior visible. The starred state still persists correctly — it just does not affect in-memory scheduling until the extension is loaded. Tests: +5 (star round-trip with concurrency notification, invalid slug 400, delete cleans up cache, absent-service warning log). All 1970 tests pass.
2026-06-28Merge branch 'dev' into feature/concurrency-fixesAdam Malczewski
2026-06-28merge: bring dev crash fixes into feature/workspace-starAdam Malczewski
Merge dev to restore production-critical crash fixes that were committed after the branch was cut: SSH pool permanent error listener, uncaughtException/ unhandledRejection guards in host-bin, MemoryMax=24G circuit breaker, memory telemetry logging, LSP disable precaution, and crash investigation notes. The provider-wrapper.test.ts:102 test passes — it was already fixed by the acquire() signature change (adding workspaceId parameter) that realigned the test arguments. No additional test fix needed. Verification: typecheck 0 errors, 1965 tests pass, biome clean.
2026-06-28Merge branch 'dev' into feature/workspace-starAdam Malczewski
2026-06-28feat(workspace-star): starred workspace priority for concurrency limitingAdam Malczewski
2026-06-28feat(concurrency-fixes): usage-gate + adaptive headroom + configurable cooldownAdam Malczewski
2026-06-28docs(crash): definitive findings + Gemini review reportAdam Malczewski
2026-06-28fix(ssh,host-bin): permanent pooled-client error listener + ↵Adam Malczewski
uncaughtException/unhandledRejection guards Root cause of the live production crash (exit-1 'Timed out while waiting for handshake'): the pooled ssh2.Client had no permanent 'error' listener after connect, so a post-connect ssh2 error escaped as an uncaught EventEmitter 'error' with no process-level guard. See notes/crash-investigation-findings.md §1. - packages/ssh/src/pool.ts: attach a permanent 'error' listener to the pooled client in buildConnection that sets state=error, logs (alias, message, level), and does not throw; cleanup() no longer removes it. - packages/host-bin/src/main.ts: add process.on('uncaughtException') (graceful shutdown after logging) and process.on('unhandledRejection') (log + continue), both logging message/stack, memory snapshot, activeConversations count, and timestamp so the failure site is observable.
2026-06-28docs(memory-leak): comprehensive handoff for OpenCode investigationAdam Malczewski
2026-06-28fix: disable LSP + change memory telemetry interval to 15sAdam Malczewski
- Disable LSP extension (import + CORE_EXTENSIONS) due to crashes - Make transport-http tolerate LSP being absent (optional getService) - Remove lsp from transport-http dependsOn manifest - Change memory telemetry sample interval from 60s to 15s
2026-06-28feat(observability): periodic memory-usage logging to localize leak sourceAdam Malczewski
2026-06-28feat(bin): apply-memory-limits.sh — apply MemoryMax cgroup limits to live ↵Adam Malczewski
service Hands the user a one-command script to apply the systemd MemoryMax/MemoryHigh cgroup limits to the live dispatch.service without a full reinstall. Patches in the real user (same as bin/install), daemon-reloads, and restarts.
2026-06-28fix(systemd): add MemoryMax=24G circuit breaker to prevent segfault crashesAdam Malczewski
The server has a memory leak (~2.5 GB/h) that eventually triggers a Bun runtime segfault. These cgroup limits turn the uncontrolled crash into a controlled OOM-kill → clean restart via Restart=on-failure. MemoryHigh=20G (soft throttle) + MemoryMax=24G (hard cap). Machine has 33.24 GB total; 24G leaves OS headroom.
2026-06-28docs(server-crash): investigate LSP-related server crashAdam Malczewski
2026-06-27fix(lsp): bound pushDiagnostics cache — evict oldest entries for unopened ↵Adam Malczewski
background files
2026-06-27fix(lsp): fix crashes (optional chaining, fs.watch error) + memory leak ↵Adam Malczewski
(document lifecycle) + leaked init promises
2026-06-27Merge branch 'feature/vision-handoff' into devAdam Malczewski
# Conflicts: # packages/session-orchestrator/src/extension.ts # packages/session-orchestrator/src/orchestrator.ts
2026-06-27feat(vision): prefix consultation tab titles with 'IMAGE - 'Adam Malczewski
When a non-vision model (e.g. GLM) calls consult_vision, the new Kimi consultation tab now shows 'IMAGE - <question>' instead of the bare question-derived title, making image-consultation tabs visually distinguishable from normal conversation tabs. - Add formatConsultationTitle(question) pure helper (pure.ts): prefixes 'IMAGE - ' and truncates the question to 80 chars (matching the conversation store's TITLE_MAX) with an ellipsis. - Add setConversationTitle dep to VisionHandoffDeps, wired in the extension to the conversation store's setConversationTitle. - Call it in consultVision BEFORE the turn starts so the title is correct from the first moment (the store keeps a non-'Untitled' title on first message append). Best-effort: a title-write failure logs a warning but does not break the consultation. - Tests: 4 pure + 2 service (title set + optional-dep graceful).
2026-06-27feat(vision): store images in tmp dir instead of SQLite — compact URLs + ↵Adam Malczewski
purge on compaction/close
2026-06-27feat(provider-concurrency): persist concurrency limits across reboots via ↵Adam Malczewski
host storage
2026-06-27feat(concurrency): add "queued" ConversationStatus — emit when request ↵Adam Malczewski
blocks on acquire, re-emit "active" when slot granted
2026-06-27feat(vision): image compaction for vision-capable models + global vision ↵Adam Malczewski
settings
2026-06-27fix(vision): detect umans kimi + qwen models as vision-capable (not just kimi)Adam Malczewski
2026-06-27feat(vision-handoff): model-directed consult_vision tool replacing ↵Adam Malczewski
auto-transcription
2026-06-27fix(vision-handoff): omit temperature on vision transcription call (Kimi ↵Adam Malczewski
rejects temperature: 0) The vision handoff hardcoded temperature: 0 for the transcription sub-call, but the Moonshot/Kimi vision model only allows temperature: 1 (or omitted), causing an HTTP 400 "invalid temperature: only 1 is allowed for this model" that blocked the entire image analysis for non-vision models like GLM 5.2. Fix: omit temperature entirely so each vision provider uses its own default — the truly universal, provider-agnostic approach (different providers have different temperature constraints).
2026-06-27feat(provider-concurrency): add release cooldown (200ms) to prevent N+1 ↵Adam Malczewski
overshoot from provider accounting lag
2026-06-27Merge branch 'dev' into feature/vision-handoffAdam Malczewski
2026-06-27Merge branch 'dev' into feature/provider-concurrencyAdam Malczewski
2026-06-27fix(bin): rename dispatch-web → frontend in up/build scriptsAdam Malczewski
2026-06-27feat(vision-handoff): implement vision for capable models and universal ↵Adam Malczewski
vision handoff
2026-06-27feat(provider-concurrency): implement per-provider in-memory concurrency ↵Adam Malczewski
limits with oldest-agent-first scheduling
2026-06-27style: reformat heartbeat merge to 2-space indentationAdam Malczewski
2026-06-27Merge branch 'dev' into feature/heartbeatAdam Malczewski
# Conflicts: # packages/host-bin/package.json # packages/host-bin/src/main.ts # packages/session-orchestrator/src/orchestrator.ts # packages/system-prompt/src/service.test.ts # packages/system-prompt/src/service.ts # packages/system-prompt/src/types.ts # packages/transport-contract/package.json # packages/transport-http/package.json # packages/transport-http/src/app.test.ts # packages/transport-http/src/app.ts # packages/transport-http/src/extension.ts # packages/transport-http/tsconfig.json # tsconfig.json
2026-06-27Merge branch 'feature/indent-change' into devAdam Malczewski
2026-06-27chore: update path references for directory rename (dispatch-backend → ↵Adam Malczewski
backend, dispatch-web → frontend)
2026-06-27feat(heartbeat): GET /workspaces/:id/heartbeat/next-run endpoint (CR-HB-3)Adam Malczewski
2026-06-27feat(heartbeat): send heartbeat conversations to a dedicated heartbeat workspaceAdam Malczewski
2026-06-26style: switch from tabs to 2-space indentationAdam Malczewski
2026-06-26feat(heartbeat): resolve empty systemPrompt to global default (CR-HB-2)Adam Malczewski
2026-06-26fix(install): restart service instead of start (no-op when already running)Adam Malczewski
2026-06-26fix(install): run build as user, sudo only on privileged linesAdam Malczewski
The script previously required sudo for the entire script (id -u check), which meant bin/build ran as root and created root-owned dist/ files. On the next build, the normal user couldn't overwrite them (EACCES). Now the script runs without a sudo prefix: the build step runs as the normal user (dist/ files are user-owned), and sudo is used only on the specific lines that write to system directories (/usr/bin, /etc, /usr/share) or call systemctl.
2026-06-26fix(build): run tsc --build before bun build --compileAdam Malczewski
bin/build was compiling the binary directly from stale dist/*.js files without first recompiling the TypeScript packages. Since package.json main fields point to dist/index.js, source edits to .ts files were silently lost in the compiled binary. Now tsc --build runs first (composite project references rebuild all packages in dependency order), then bun build --compile bundles the fresh dist/ output.
2026-06-26feat(heartbeat): resolve [type:name] variables in heartbeat prompts (CR-HB-1)Adam Malczewski
2026-06-26fix(kernel): disable MAX_STEPS limit (0 = unlimited)Adam Malczewski
Agents were being cut off mid-task at 50 steps. The MAX_STEPS=50 hardcoded limit was silently terminating turns while the model was actively making tool calls, leaving conversations idle with a dangling tool-result as the last chunk. Setting MAX_STEPS to 0 disables the limit — the loop runs until the model stops making tool calls naturally or the abort signal fires. The max-steps code path is preserved for when MAX_STEPS > 0.
2026-06-26feat(heartbeat): workspace heartbeat loop with configurable AI monitoringAdam Malczewski
2026-06-25fix(ssh): POST /computers/:alias/test hangs after successful SSH connectAdam Malczewski
The test endpoint's runProbe() waited for the ssh2 stream's 'close' event, which some SSH servers never emit for short-lived exec channels (the command 'true' exits instantly). This caused the promise to hang forever — the HTTP response never returned, and the FE's Test spinner spun indefinitely. Three fixes: 1. runProbe now resolves on the 'exit' event (not 'close') — the command has finished and the exit code is available. 'close' is kept as a fallback. Stream data/stderr are drained to prevent buffer deadlocks. 2. runProbe has a 15s timeout safety net — if the exec callback or 'exit' event never fires (e.g. server requires a pty for exec), the probe resolves false instead of hanging forever. 3. The entire test() method is wrapped in a 30s Promise.race timeout — even if pool.acquire() or pool.drop() hangs, the endpoint ALWAYS responds with { ok, error? }. The probe is fully non-interactive (no blocking prompts). tsc EXIT 0, biome clean, 1756 tests pass.