Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gine selection Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Engine Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…plicate in monitorExecution Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ine and i18n keys
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add ai.AllEngines as canonical engine list; derive validEngines map and error message from it instead of duplicating names in three places - Use ai.AllEngines in buildAllEngines to eliminate the local literal slice - Add ENGINES/Engine to web/src/lib/types.ts; replace hardcoded SelectItems in create-worker-sheet and worker-detail with a mapped loop - Fix onValueChange null-safety (string | null -> string) TS errors - Remove "what" comment in resolveEngine Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…en types - Move validateEngine into ai.ValidateEngine alongside AllEngines; use slices.Contains - Make EngineConfigRaw delegate to EngineConfigRawFor, eliminating duplicated switch body - Trim redundant what-comments on AllEngines, buildAllEngines, resolveEngine, ENGINES - Replace raw "claude" default strings with DEFAULT_ENGINE constant in frontend - Type Worker.engine as Engine; use useState<Engine> in create-worker-sheet and worker-detail Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolve engine once in ExecuteWorker and thread it through launchRuntime and monitorExecution instead of calling resolveEngine three times per execution. Trim the narrating half of the buildAllEngines comment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add Kimi engine support design spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add Kimi engine implementation plan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(engine): add EngineKimi constant and register in AllEngines
* feat(config): add KimiConfig and wire into BeeConfig, WorkerTimeout, EngineConfigRawFor
* feat(kimi): add invoker with ExtractResultFromLog and Run
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(kimi): add adapter, register factory, wire into app bootstrap
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(config): add kimi to config template, wizard, and i18n
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(frontend): add kimi to ENGINES type and i18n labels
* feat(log-viewer): detect Kimi engine from top-level role field
* feat(log-viewer): add KimiParser for role-based stream-JSON format
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(log-viewer): wire KimiParser into log viewer engine selection
* fix(kimi-parser): handle array content blocks in tool results
Kimi returns tool result content as an array of text blocks rather than
a plain string. The parser was falling back to an empty string for
non-string content, causing blank output in the session detail log view.
Reuse extractToolResultText from claude-parser to handle both string
and array content shapes. Add a test case covering the array format.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(kimi-parser): surface sent message content when assistant returns empty response
When Kimi calls `openbee ctl message send --stdin` and the subsequent
assistant turn is a placeholder `(Empty response: {...})`, the actual
content the model wrote is embedded in the Shell command's heredoc.
Detect this pattern: cache the stdin content from each
`openbee ctl message send --stdin` Shell call, then replace any
`(Empty response:` text block with that cached content. If no cached
content exists, silently drop the placeholder text.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add Kimi AI engine to supported engines table
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(kimi): fall back to sent message when last assistant response is empty
When Kimi ends a session with an "(Empty response: ...)" placeholder, the
actual reply was already delivered via `openbee ctl message send --stdin`.
ExtractResultFromLog now skips "(Empty response:" text blocks and tracks
the heredoc body from the last Shell tool call as a fallback, mirroring
the existing frontend kimi-parser logic.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(kimi): add Kimi agent changelog entry and remove plan/spec docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(kimi): set default timeout to 30m in applyDefaults
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove non-deterministic map-range fallback in resolveEngine; panic directly when default engine is missing (unreachable via buildAllEngines) - Remove redundant slice reclip in kimi NewInvoker after append - Eliminate double JSON parse in detectEngine by parsing once per line - Extract shared EngineSelectItems component to remove duplicated ENGINES.map JSX - Fix inconsistent alignment for Kimi fields in messages.go and config.go - Add missing "kimi is valid" case to TestValidateEngine - Add "// Kimi setup" section comment in PromptMessages to match Pi/Claude/Codex Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- kimi/invoker.go: re-clip baseEnv slice after extraEnv appends to prevent concurrent Run() calls from sharing the backing array - manager.go: resolveEngine returns error instead of panicking when no engine adapter is found, preventing server crashes on misconfiguration - manager.go + config.go: replace single workerTimeout with per-engine timeout map so workers use their own engine's configured timeout, not the default - create-worker-sheet.tsx: remove dead !engine guard (Engine is always non-empty) - kimi/invoker.go + adapter.go: remove what-comments that restate obvious code Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… + EnginesConfig Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- useExecutions: add refetchInterval 500ms so sessions list auto-refreshes - useSessionExecutions: reduce active-execution poll from 3000ms to 500ms - rename pages/executions.tsx → pages/sessions.tsx to match /sessions route - update app.tsx lazy import path accordingly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ons → nav.sessions
- en.json / zh.json: rename top-level "executions" key to "sessions"
- en.json / zh.json: rename nav.executions to nav.sessions
- Update all t("executions.*") call sites to t("sessions.*")
- Update nav.executions references in sidebar, nav, and breadcrumb config
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7714e7d to
54e8499
Compare
* feat: add /clear slash command for session context clearing
Implements two variants scoped to the current session:
- /clear: clears all session contexts after two-step confirmation (stops running tasks first)
- /clear {workerName}: clears a specific worker's active-engine context after confirmation
Confirmation state is held in memory with a 30-second expiry; the second
command must match the first exactly (case-sensitive). Worker name lookup
is case-insensitive and errors on duplicate names.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* simplify: deduplicate reply helper, unify GetByName, fix pending map leak
- Extract sendReply package-level helper; both EngineCommandHandler and
ClearCommandHandler delegate to it instead of duplicating the logic
- GetByName now delegates to ListByName, eliminating the duplicate SQL
- Add sweepExpired goroutine to ClearCommandHandler so unconfirmed
/clear entries don't accumulate in memory indefinitely
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* simplify: remove WHAT comments and fix silent error discard in /clear handler
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* simplify: fix silent error discard and extract consumePending helper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
The confirmation prompt and post-clear message were calling ListSessionContexts which returns all engine rows, so codex sessions appeared in the prompt even when claude was the active engine. Add ListActiveSessionContexts that mirrors the WHERE filtering of ClearSessionContexts, and use it in handleClearAll so the prompt reflects exactly what will (or was) cleared. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ncelled
- Full /clear with no running tasks executes immediately
- /clear {worker} always executes immediately (no tasks are cancelled)
- Confirmation is only required when stopping running tasks (destructive)
- Simplify pending map from struct to time.Time, remove unused i18n keys
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ions, or immediate tasks Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… and serial busy checks - ConfigHandler.defaultEngine was a startup snapshot that became stale after /engine switches; replaced with live enginecfg.Get() call and removed the constructor param - handleClearWorker pre-checked existence then deleted (TOCTOU); DeleteSessionContextForEngine now returns (bool, error) so a single delete both removes the row and indicates whether it existed - GetByName called ListByName (no LIMIT) then discarded all but first row; replaced with a direct QueryRow with LIMIT 1 - checkBusy ran three DB checks serially; now runs all three concurrently and evaluates results in priority order - Removed WHAT comment from engineMappings() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rror conflation, and dead field - ClearCommandHandler.sweepExpired now accepts a context and exits on cancellation - executeClearAll accepts prefetched agents/runningTasks to avoid redundant DB reads - busyCheck.warnMsg field replaces parallel-indexed warns slice in checkBusy - handleWorkerEngine distinguishes sql.ErrNoRows from DB errors - Extract scanSessionAgents helper to deduplicate row-scan loop in session_store - Simplify enginecfg.Set initialization in BuildApp (set default first, overwrite if valid) - Remove dead AppConfig.default_engine field from Go response and TypeScript type - Fix edit-worker-info-sheet dirty-check to use enabledEngines[0] instead of DEFAULT_ENGINE - Add --yolo comment in kimi/invoker.go Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ec polling, engine label helper
- msgingest.Gateway: cap seen dedup with 10k two-generation rotation to prevent unbounded growth in long-running processes
- session_store: extract shared activeWorkerSessionContextsFilter constant so List/Clear active-contexts SQL can't drift; drop scanSessionAgents nil→[] normalization (callers len-check anyway)
- use-executions: /executions list now only polls when an active execution exists (matches useSessionExecutions behavior); shares isActiveStatus helper
- format.ts: add formatEngineLabel(engine, t) helper; use in workers and worker-detail pages to dedupe inline t(`workers.engines.${engine}`) mappings
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…BusyChecker Constructor now takes 5 args instead of 7 by bundling the three independent activity checks (messages, executions, immediate tasks) behind a single SystemBusyChecker interface composed via NewSystemBusyChecker.
Backend now exposes ReadLogSince(id, since) returning a LogSlice with (content, size, truncated). GET /api/executions/:id/logs accepts an optional since query parameter and responds with JSON instead of plain text. The log viewer frontend tracks the authoritative byte size from the server and passes it as since on each 500ms poll, so active executions stream only the new tail instead of re-reading the entire file every interval.
Previously DynamicAdapter.ExtractResult read enginecfg.Get() on every call, creating a TOCTOU window where /engine firing between Run and ExtractResult would route result parsing to the wrong engine. The EngineResultExtractor escape hatch existed but was never wired up through BeeProcess, so the safe path was dead code. Run now returns a RunResult whose ExtractResult closure is bound to the engine chosen at Run time. DynamicAdapter routes once at Run; result extraction travels with the handle. The ExtractResult method is removed from the EngineAdapter interface, the EngineResultExtractor extension interface is deleted, and Feeder/Worker Manager use the RunResult directly.
The enginecfg package no longer holds process-wide state. It now exposes a Store struct with NewStore/Get/Set, and every subsystem receives a *enginecfg.Store through its constructor: DynamicAdapter, Feeder, worker.Manager, task.TaskDispatcher, EngineCommandHandler, ClearCommandHandler, SystemConfigHandler, and app.go wiring. This removes implicit coupling, fixes the init order hazard that was causing mcp tests to fail (they no longer depend on a global Set from another test), and makes per-test engine isolation trivial.
ListActiveSessionContexts joined bee_workers for the worker name lookup, but the outer WHERE kept `engine` and `updated_at` unqualified. SQLite rejected the query with "ambiguous column name: engine", and the error was only logged — handleClearAll then treated the empty result as "no sessions" and replied NoContext. /clear therefore always reported "No session contexts to clear." while /clear <worker> (different DELETE path, no JOIN) worked. Qualify the ambiguous references with bee_session_contexts.*, surface lookup failures to the user instead of swallowing them, and add a ListActiveSessionContexts test that mirrors ClearSessionContexts so the regression is caught next time. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…us read, add Store.Resolve - ai.NewRunResult helper removes (proc, out, err, extract) boilerplate from claude/codex/kimi/pi adapters. - compositeBusyChecker embeds the three activity-check interfaces; method promotion replaces hand-written delegations. - ReadLogSince now returns the execution status alongside the log slice, eliminating the duplicate GetByID query in GetLogs polling (~2× DB calls per 500ms tick). - enginecfg.Store gains Resolve(workerEngine) used by /clear and dispatcher to fold the worker-or-default fallback. - Trim narration comments and the stale enginecfg.Set reference in dispatcher_test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…g, adapter cfg helpers - /engine: check engine name validity before busy check; merge case 2/3 busy guard; replace 3-goroutine concurrent busy probe with sequential short-circuit (SQLite serializes reads anyway). Add CmdEngine/CmdClear constants, replacing raw "/engine" / "/clear" string compares. - /clear: drop the always-on sweepExpired goroutine and clearCmdHandler.Run runner; reap stale pending entries inside storePending (the only growth path). Inline executeClearAll into handleClearAll, removing the nil-as- sentinel re-fetch in the confirm path. - ai.EngineConfig: add PathOrDefault and ExtraEnv helpers; collapse the duplicated path-and-env type-assertion blocks in the four adapter init funcs (claude/codex/pi/kimi) to single-line constructors. - DynamicAdapter.Prepare: drop errgroup over a one-element-of-real-work loop; sequential is sufficient and removes a dependency. - Frontend: extract SectionHeading into its own component instead of importing it across feature sheets; add pickDefaultEngine helper used by both create- and edit-worker sheets.
… edit-worker mutations Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.