feat(cli): multi-agent workspaces with @alias, expert.toml and expert use#3
Closed
feliperun wants to merge 1 commit into
Closed
feat(cli): multi-agent workspaces with @alias, expert.toml and expert use#3feliperun wants to merge 1 commit into
feliperun wants to merge 1 commit into
Conversation
…expert use` Single-agent repos keep their existing ergonomics; multi-agent repos get a first-class experience via three equivalent targeting syntaxes and a shared resolver so every command picks up precedence rules automatically. ## New surface - `expert agents` — list every agent (TOML-declared + auto-discovered siblings) - `expert use <name>` — pin an agent in `.expert/state.json` for this workspace - `expert which [--agent ...]` — preview what a bare command would resolve to - `@alias` positional shortcut: `expert @derm ask "..."` → same as `expert ask --agent derm "..."` - `--agent/-a <name>` flag on `ask`, `validate`, `count-tokens`, `sync`, `test`, `sessions list|show|delete`, plus `which` for previewing resolution - `expert.toml` at the workspace root with `[defaults]` + `[agents.<name>]` sections (schema path, endpoint, api_key_env, description) ## Resolution precedence (first match wins) 1. `--schema <path>` short-circuits to that file (preserves legacy behaviour) 2. `--agent <name>` / `@alias` (explicit selector) 3. `EXPERT_AGENT` env var 4. `.expert/state.json` (set by `expert use`) 5. `[defaults] agent = "..."` in `expert.toml` 6. Exactly-one-agent short-circuit Failing to disambiguate raises `AmbiguousAgentError` with a helpful message listing every candidate and the three ways to pick one. ## Architecture - `cli/expert/workspace.py`: `Workspace.discover()`, `AgentContext`, `AgentInfo`, `AmbiguousAgentError`. Walks up for `expert.toml` or `.expert/state.json`; falls back to sibling-schema discovery rooted at cwd. - `cli/expert/context.py`: single `resolve()` helper called by every command, so changing precedence rules in the future is a one-file edit. - `cli/expert/main.py`: argv rewriter that expands `@alias` before Typer parses, with an allow-list of agent-aware subcommands so nonsense like `expert @foo use bar` is left alone for Typer's error renderer. ## Docs & CI - Reusable workflow (`.github/workflows/expert-e2e.yml`) gains an `agent:` input so monorepos can run `expert test --agent X` via matrix. - README grows a "Multi-agent workspaces" section with `expert.toml` sample. - `docs/AGENT_E2E_SETUP.md` gains a matrix snippet for monorepo integrations. ## Tests - 20 new unit tests for `workspace.py` covering every precedence rule, prefix matching, state file round-trips, and API-key env resolution. - 14 new tests for the argv rewriter + CLI integration of `agents`/`use`/`which`. - All 85 existing + new tests green; ruff + mypy clean. Made-with: Cursor
Owner
Author
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.
Summary
Single-agent repos keep the same ergonomics; multi-agent repos get a first-class experience via three equivalent targeting syntaxes backed by a shared resolver.
What's new
expert agents,expert use <name>/--clear,expert which [--agent ...]--agent/-a <name>onask,validate,count-tokens,sync,test,sessions {list,show,delete},which@aliaspositional —expert @ecg ask "..."rewritten toexpert ask "..." --agent ecgbefore Typer parsesexpert.tomlat repo root:[defaults]+ one[agents.<name>]section per agent (schema path, endpoint, api_key_env, description)expert.toml/.expert/state.json; fall back to sibling*/agent_schema.yamlrooted at cwdagent:input so monorepos can matrix over agentsAGENT_E2E_SETUP.mdgrows a monorepo matrix snippetResolution precedence (first match wins)
--schema <path>short-circuits to that file (preserves legacy behaviour)--agent <name>/@alias(explicit selector)EXPERT_AGENTenv var.expert/state.json(set byexpert use)[defaults] agent = "..."inexpert.tomlAmbiguity raises
AmbiguousAgentErrorwith a helpful multi-line message listing every candidate and the three ways to pick one.Architecture
Tests
cli/tests/test_workspace.pycovering every precedence rule, prefix matching (unique / ambiguous / unknown), TOML + sibling coexistence, API-key resolution viaapi_key_env,require_remote()guard, state-file round-trip.cli/tests/test_main_alias.pyfor the argv rewriter (agent-aware allow-list, sub-Typer end-append, empty-alias no-ops) plus CLI integration ofagents/use/whichviaCliRunner.ruff checkclean,mypyclean onbackend/app + cli/expert.Backward compatibility
expert validate --schema ...,expert ask --endpoint ... --api-key ...) keep working — the--schemaflag short-circuits the resolver and CLI flags continue to override env/config.micromed-agentsworkflow (e2e-ecg-expert.yml) needs no changes; it's already single-agent.Test plan
python -m pytest cli/tests backend/tests→ 85 passedruff check+ruff format --checkcleanmypy backend/app cli/expertcleanexpert agents,expert use,expert which,expert @alias ask, ambiguous workspace error messageexpert @ecg-expert ask "..."inmicromed-agentsFollow-ups (not in this PR)
shell_complete=)expert register <name> --schema <path>to updateexpert.tomlnon-destructivelyaskstreaming UI ("→ ecg · session xxx")Made with Cursor