Re-applies the tenant-isolation extension from the deleted pkg/agent/loop.go
to upstream's split agent_*.go layout. Phase 1 plumbs the protocol; Phase 2
(future PR) wires effective sessions / provider / context per turn.
What's added:
- New file pkg/agent/agent_tenant.go (kept isolated for sync friendliness):
- extractTenantOverrides reads workspace_override, config_dir,
allowed_tools, allowed_skills from msg.Context.Raw
- Validates workspace_override and config_dir resolve within the
workspace_root boundary set in agents.defaults; rejects path escape
- Fails closed when any override is present but workspace_root is unset,
so tenants cannot bypass the security boundary
- applyTo copies the overrides onto processOptions
- logIfPresent logs a single line summarising tenant routing per turn
- processOptions in agent.go gains four override fields (WorkspaceOverride,
ConfigDir, AllowedTools, AllowedSkills)
- agent_message.go processMessage extracts and applies the overrides right
after building processOptions
- agent_tenant_test.go covers the happy path, escape rejection, missing
boundary rejection, and CSV parsing
Phase 2 will introduce effSessions, effContextBuilder, effProvider, effModel
on processOptions and thread them through pipeline_llm/turn_state/context_*
so each tenant turn runs against an isolated session store, context builder,
and provider credential set. Phase 2 is deferred because:
- MagicForm doesn't currently send webhook traffic (verified), so phase 1's
protocol-level plumbing has no live consumer that requires the swap yet.
- Phase 2 needs design discussion (per-tenant credential storage, session
backend selection) that warrants its own focused PR.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the old agent EventBus, SubscribeEvents/EventDrops public surface, legacy hook observer dispatch, and hook.event process notification path. Agent observations now flow through pkg/events runtime events.
Validation: go test ./pkg/agent; make lint
Introduce pkg/events with filtered channels, subscription policies, backpressure, and stats. Wire AgentLoop to dual-publish legacy agent events into runtime events while preserving old event APIs.
Validation: go test ./pkg/events/... ./pkg/agent; go test -race ./pkg/events/...; make lint
Add a context window usage indicator to the web chat UI and a /context
slash command that works across all channels.
Backend:
- Add computeContextUsage() estimating history + system + tool tokens
- Attach ContextUsage to outbound messages via the pico WebSocket protocol
- Add /context command showing context stats as formatted text
- Add EstimateSystemTokens() on ContextBuilder for system prompt estimation
Frontend:
- Add ContextUsageRing component (SVG ring + hover/tap popover)
- Show usage percentage, token counts, and compression threshold
- Hover on desktop (150ms leave delay), tap on mobile
- "View Details" sends /context with 1s cooldown
- i18n support (en/zh) for popover labels
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>