Skip to content

Add @describe capability to describe agent / actions#2671

Merged
GeorgeNgMsft merged 13 commits into
mainfrom
dev/georgeng/describe_agents_actions
Jul 15, 2026
Merged

Add @describe capability to describe agent / actions#2671
GeorgeNgMsft merged 13 commits into
mainfrom
dev/georgeng/describe_agents_actions

Conversation

@GeorgeNgMsft

@GeorgeNgMsft GeorgeNgMsft commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Add @describe — capability discovery for agents and actions

Summary

Adds a new @describe command (and matching system.describe natural-language schema) that answers "what can this do?" — a read-only capability summary, distinct from @action which executes. It works even for installed-but-disabled agents, so users can discover what an agent offers before enabling it. Intended for new users who may or may not visit our repo and have no familiarity with our agents/actions.

Usage

  • @describe <agent> — agent summary + a table of its first 10 actions
  • @describe <agent> --all / -a — full action table, no truncation
  • @describe <agent> <action> — detailed explanation of one action, including its parameters
  • @describe <action> — same, when the action name alone is unambiguous across agents
  • Natural language: "what can the spotify agent do", "show me all of spotify's actions", "what does the play action do"

Agent Describe Command
image

Agent Describe NL
image

Action Description
image

- Fix CodeQL-flagged incomplete escaping in escapeTableCell: escape
  backslashes before pipes so a literal backslash can't combine with
  the pipe-escape into an ambiguous sequence.
- Rename shadowing local variable in describeActionHandler.ts
  (describeAction -> nlAction) to avoid confusion with the
  describeCore.ts function of the same name.
- Restructure resolveAction's dotted schema.action lookup to make the
  'schema names are unique across agents' invariant explicit instead
  of implied by a loop-with-early-return.
- Inline the single-use isSchemaEnabledFn factory at its one call site.
- Split extractActionParameters into findParametersBlock (structural
  brace-matching scan) and parseParameterFields (line-based field
  parsing) - two independently-testable concerns that were glued into
  one function.
- Add a one-line rationale comment for the closestMatch edit-distance
  threshold formula.
- Add regression tests for the escaping fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@GeorgeNgMsft GeorgeNgMsft marked this pull request as ready for review July 14, 2026 23:01
GeorgeNgMsft and others added 5 commits July 14, 2026 16:01
Code-quality pass on the @Describe core:
- Extract agentTitle() so the deterministic summary and LLM-polished
  header share one bolded heading (fixes divergent punctuation).
- Extract didYouMean() and renderAndPolishAction() to remove duplication.
- Derive the agent table header/separator from a single columns array.
- Drop the dead 'nameMatch === undefined' branch (exec() returns null).
- Rename complete() -> tryComplete() to signal its graceful-failure contract.
- Use strict '!== undefined' for the optional agentName filter.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…scribe

The system.describe NL handler forwards to the @Describe command (which
renders the markdown itself) and previously returned undefined, so the
dispatcher appended its generic 'Action <name> completed.' fallback on top
of the real output. Return a no-display ActionResult instead so only the
describe markdown is shown; record a concise historyText for memory.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the full O(a*b)-space matrix with the O(min(a,b))-space two-row
form (matching the proven @typeagent/agent-flows levenshtein). Behavior
is identical; kept local rather than adding a dispatcher -> agent-flows
dependency for a ~15-line primitive.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the inline schemaName.split('.')[0] with the canonical
getAppAgentName() helper (translation/agentTranslators.ts) used by 40+
other dispatcher call sites. Self-documenting and consistent; the grouping
loop itself stays local (only bucket-all caller, not worth a shared abstraction).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@curtisman

Copy link
Copy Markdown
Member

there is also the @help command as well. that serve similar function for commands.... should all of them under one command?

…ndler calls core directly

The describe files introduced 5 new circular-dependency cycles that failed
the CI ratchet. Four closed via CommandHandlerContext imported as a value but
used only as a type; the fifth via describeActionHandler forwarding through the
\@Describe\ command (processCommandNoLock in command.ts).

Fixes:
- Import CommandHandlerContext with \import type\ in the four describe files
  (madge's skipTypeImports drops type-only edges), breaking the first four cycles.
- Have the NL handler (describeActionHandler) call describeCore directly and
  append the markdown itself, instead of string-forwarding through the command.
  This removes the command.ts edge (breaks the fifth cycle), drops the quoteArg
  escaping, and makes describeCore the single shared implementation for both
  entry points.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread ts/packages/dispatcher/dispatcher/src/context/system/describe/agentSchemaInfo.ts Outdated
Comment thread ts/packages/dispatcher/dispatcher/src/context/system/describe/agentSchemaInfo.ts Outdated
…llback

Adds a getActionDescription(actionType) helper to @typeagent/action-schema
(the action description is the first line of its doc comment, else undefined)
and reuses it in both agentSchemaInfo.extractActions and unknownSwitcher, per
review feedback.

Also drops extractActions' name-derived description fallback: a camelCase->spaced
rendering of the action name (e.g. sendEmail -> 'Send Email') just duplicates the
Name column in the table and adds no signal to the LLM prompt. Actions with no
comment now get an empty description; renderActionView omits the trailing em dash
in that case.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@GeorgeNgMsft

Copy link
Copy Markdown
Contributor Author

there is also the @help command as well. that serve similar function for commands.... should all of them under one command?

I've been thinking about it and I do agree that instinctively @help feels like it should be merged. They function differently under the hood and operate on different sources (command tree vs action schema). I might do a follow up PR that adds a similar NL rule to allow @help to function the same way and let @Describe also describe the agent commands. But I'm not entirely convinced yet that we should merge their scopes

@GeorgeNgMsft GeorgeNgMsft enabled auto-merge July 15, 2026 00:47
@GeorgeNgMsft GeorgeNgMsft added this pull request to the merge queue Jul 15, 2026
Merged via the queue into main with commit 5c9fc63 Jul 15, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants