Releases: anima-research/agent-framework
Releases · anima-research/agent-framework
v0.3.0
Highlights
Batch of conhost-driven improvements to MCPL plumbing, channel/typing semantics, the workspace watcher, and framework surface area.
MCPL
- Per-server tool allow/deny policy —
enabledTools/disabledToolsonMcplServerConfig, bare names with*substring wildcards. Dual-gated: tools are filtered both attools/listtime (model never sees them) and at dispatch time (calls rejected with a tool-result error). The dual gate is deliberate — schema omission alone doesn't stop a model from imitating a denied call it's already seen in its own prior message history. Deny wins over allow on overlap. Regex metacharacters in patterns are escaped; only*is special. (#26, 0452663) - Subprocess stderr forwarded as
mcpl:server-stderrtrace events — child stderr was previously silently dropped. Every line becomes a trace event keyed onserverId, with pre-handshake lines buffered and drained once the instance exists; rebindable for the reconnect probe → persistent swap. (#26, 7225364) - Opaque routing metadata on channels/typing —
sendChannelsTyping/ChannelRegistry.startTypingaccept an optionalRecord<string, unknown>that travels with the notification. Intentionally untyped per-server: Zulip readstopic, others pick their own keys. The registry caches per-channel metadata so the 7s refresh stays on the same thread. (#26, af4b679) - Explicit
op: 'start' | 'stop'on typing —ChannelRegistry.stopTypingdispatches one finalstopbefore clearing the interval, so servers that support explicit stop (Zulip) clear immediately instead of waiting for auto-expire. Metadata carries on the stop too. Single-channelstopTypingand globalstopTyping()have symmetric semantics: both dispatchstoponly for channels that had an active interval. (#26, 7be4c71, 32cb10c) - Immediate refresh on mid-typing metadata change —
startTyping(ch, newMetadata)on an already-typing channel now dispatches an immediate notification when the metadata differs from the cached one, instead of waiting up to 7s for the next refresh tick. This is the Zulip topic-switch case — newer incoming message moves the relevant topic, caller bumps startTyping, server sees the new routing within the current request. (32cb10c)
Framework
AgentFramework.channelsgetter —ChannelRegistrywas a private field; modules that need channel-level ops (typing indicators, default-publish channel selection) had no way in. Returnsnullwhen no MCPL servers are configured;ChannelRegistryis re-exported from the package entry so consumers can type against it. (#26, f521991)
Workspace
- Public
WorkspaceModule.resolveAbsolutePath— turns a mount-prefixed path (mount/sub/file.md) into an absolute FS path without peer modules reaching into privateparsePathstate. Honors the same CWE-22 traversal guard. (#26, cf882e1) - chokidar silent-failure mitigations — reproducibly on Linux/WSL (and consistent with macOS), chokidar 4's fs.watch backend silently drops events when the watched path — or any parent directory — doesn't exist at subscribe time, and surfaces no error unless an
errorhandler is attached. Post-failure state is indistinguishable from watching an empty directory. Three canonical-chokidar mitigations: (#26, 8961a7f)MountWatcher.start()mkdir -p's the watch path for read-write mounts before attach. Read-only mounts are left alone.WatcherLifecyclecallbacks (onReady,onError) give the workspace module observability into the watcher's attach state. Errors forward asworkspace:watcher-errorevents.- Mount state now carries
watcherReadyAt+watcherError, persisted via snapshot. A nullwatcherReadyAton a live mount means watcher never attached; a set timestamp with an empty tree means attached-but-empty.watcherReadyAtis intentionally not restored across restarts — a stale timestamp would mask a fresh attach failure. - Does not address the inode-replace failure mode (dir rm'd + recreated post-subscribe); chokidar can't recover from that without re-attach logic, and
@parcel/watcheris the better fix when that's prioritized.
Tests
Adds test/channel-registry-typing.test.ts (6 cases) and test/tool-policy.test.ts (8 cases); extends test/workspace-watcher.test.ts. Full suite: 88 tests across 7 files.
Full changelog
v0.2.0…v0.3.0: v0.2.0...v0.3.0