- Output channels generate per-channel tools: output_send__{name} (type=output) + output_send__{name}_help
- content is JSON string transparently passed to plugin handler for routing
- EventAgentLLMChain: full LLM response forwarded after each turn for webui/logs
- sdk.New refactored to SDKConfig struct (no more 13 positional args)
- RegisterOutputChannel adds desc param for JSON format documentation
- channelDevice simplified (no Tools method), desc field added
- Child agent permission updated for output_send__ prefix
- System prompt: output gates, multi-call, long messages split
- WebUI: subscribes to EventAgentLLMChain in SSE, no output channel
- Tests updated for new naming convention
Root node items (items without category) were skipped by depth>0 check,
causing knowledge_list to always return '(空)'. Also simplified formatTree
to avoid redundant child item rendering.
- Prune context BEFORE processing (LSTM forget gate pattern)
so LLM only sees relevant context, instead of pruning after the fact
- Fix ensureTrained() to recompute all event vectors after retraining
vectorizer, fixing feature-space mismatch between stored vectors and
query vector that made relevance scoring effectively random
- Add read lock to knowledge BuildTree() (data race fix)
- Log writeIndex() errors instead of discarding them
- Fix TOCTOU race in document ContextToDoc() dedup
- Fix healthcheck timing (measure elapsed before cleanup)
- Refactor waiter CLI into separate files (state, conn, config, editor,
history, builtin) for maintainability
- Add CLI plugin API key authentication
- Add explicit -chat flag for blocking one-shot requests
- Keep -say as deprecated alias for compatibility
- Preserve existing interactive mode for upcoming TUI rewrite
- add auth middleware tests for API key, login, and root redirect
- auto-bootstrap admin username/password and API key when unset
- add logout control to dashboard and cookie-aware client behavior
- protect API routes with API key or authenticated session
- add /login page and /api/v1/login, /api/v1/logout endpoints
- gate dashboard behind session cookie
- auto-bootstrap webui username/password/api_key if unset
- add logout action to dashboard and cookie-aware API client
- Add structured CLI commands for status/kernel/settings/plugins/memory/knowledge/agents
- Inject core dependencies directly into CLI plugin for non-HTTP operator workflows
- Add plugin management panel and API proxy endpoints to WebUI
- Let cmd_run inherit default workdir from core.agent.workdir
- Use fixed loopback address for pluginmgr API
- Remove stale MaxToolTurns config usage from homed wiring
- replace vendored third_party/homeagent-sdk with formal module dependency
- keep canonical SDK via go.mod pinned commit
- optimize distiller startup loading to stream recent raw records only
- parse timestamps correctly and cap startup load to 5000 records
- remove quadratic string building in raw record parsing
- restore fast startup while preserving memory pipeline
- annotate queued and interrupt inputs with source/output channel context
- drain all pending interrupts instead of only one
- avoid double-processing by routing interrupts exclusively:
active LLM -> intercept channel, idle -> input queue
- keep interrupt source/channel in payload and system context
- Remove SKILL tool registration with nil handler (was causing nil
pointer in StageHost.ExecuteTool)
- Rewrite loadOCPlugin: notifications are the only registration path.
Synchronously drain all buffered register notifications after
waitReady, then start persistent notifyLoop for future registrations.
ListTools is verification-only, no longer registers tools.
- notifyLoop: persistent via for n := range sp.NotifyChan(), lifecycle
bound to sidecar process
- StageHost.ExecuteTool: add nil-handler check (defense-in-depth)
- Remove unused OCNamedParam, DrainNotify from sidecar.go
- simulator/main.js: All 30+ register* methods now send JSON-RPC notifications
to Go instead of being silent no-ops. Each plugin capability registration
(tool, provider, channel, hook, http_route, command, service, etc.) is
forwarded to Go via the notify channel.
- sidecar.go: Refactored to async reader goroutine. Single goroutine reads
all stdout lines, routes responses to pending callers via channel by ID,
and dispatches notifications (no-ID messages) to notifyCh for handling.
- plugin.go: drainNotify() collects all capabilities registered during
plugin init. handleNotify() logs each registered capability for visibility.
- All 9 openclaw tests pass including simulator + full pipeline tests.
- /api/v1/settings endpoint: GET (list by prefix) + PUT (set key/value)
- Config tab redesigned: left sidebar (core + per-plugin) + right editor
- Sidebar groups: core.* and plugin.<name>.* from plugin registry
- Each setting rendered as editable input with save button
- WebUI now receives cfgReg and pluginReg from main
- handler_test.go updated with new NewHandler signature
Core exposes a unified settings interface through Plugin SDK:
- internal/config/registry.go: thread-safe namespaced KV store
- Register/Get/Set/List/Delete with JSON persistence
- Flush() for explicit save to disk
- SettingsAPI in SDK: plugins call plugin.Settings().Get/Set/List
- Full access: read/write any key (core.*, plugin.<name>.*)
- plugin.Registry.SetConfigRegistry() wires it into SDK plugins
- main.go registers core.* keys at startup, flushes on shutdown
- 7 tests for ConfigRegistry
- Add selfInputCh (chan string, buf 64) to Agent struct
- eventLoop reads from both io.InputChan() and selfInputCh
- enqueueConsolidationTask uses injectSelf() instead of io.InjectTextTo()
- SelfInputChan() exposes read-only channel for testing
- Core no longer depends on IO layer for internal tasks