Skip to content

Your team & routing

Ask about this page ChatGPT Gemini Claude

A teammate is a person who can answer questions — the routing target when the knowledge base comes up empty. Each teammate has roles, skills, and an availability state. When an agent calls ask_expert and the question misses the knowledge base, Halyard uses those attributes plus the person’s Slack identity to pick someone and deliver the question. Slack is the human side of the loop.

AttributeWhat it isExample values
rolesWhat the person does, stored as lowercase free text"engineer", "pm", "architect", "product manager"
skillsDomains they’re strong in, stored as Title-Case names"React", "System Design", "Product Strategy"
availabilityWhether they can take a question nowONLINE, AWAY, DND

list_team(role?, skill?, available_only?) returns the roster:

{
"status": "success",
"count": 8,
"match_type": "unfiltered",
"members": [
{
"id": "4fbca6b9-…",
"name": "Priya Sharma",
"roles": ["pm", "product manager"],
"skills": ["Product Strategy", "Roadmapping", "Analytics"],
"availability": "ONLINE"
},
{
"id": "1ed79467-…",
"name": "David Kim",
"roles": ["engineer"],
"skills": ["React", "TypeScript", "Accessibility"],
"availability": "ONLINE"
},
{
"id": "779ac70a-…",
"name": "James Okonkwo",
"roles": ["architect", "engineer"],
"skills": ["System Design", "Cloud Architecture", "Security"],
"availability": "ONLINE"
}
]
}

When ask_expert misses the knowledge base, the reachable pool is every teammate with a linked Slack account who has not opted out of teammate questions and is not DND. Routing ranks that pool on a three-rung ladder and reports which rung applied as routing_tier:

  1. role_skill — people whose roles or skills match the hint the agent passed (role / skill). Matching is fuzzy: eng, dev, and software engineer all resolve to engineer.
  2. semantic — people whose profile document is close to the question, best match first.
  3. connected — anyone else reachable. A question with no obvious owner still lands with a person who can answer it or say who can.

Within a rung, ONLINE teammates come before AWAY. A hint never disables the lower rungs — it orders them — so an over-constrained role no longer means nobody is asked.

Fan-out. One ask can reach several people at once. MCP hosts default to one teammate (they wait on a single conversation_id). The Slack assistant asks up to three, so a question that misses the knowledge base gets in front of the people most likely to know instead of stalling on whoever ranked first. Every conversation created by one ask shares an ask group; replies from any of them are delivered back to the asker’s thread and folded into one captured knowledge entry.

One person is never a routing target: the asker. Routing a question back to the person who asked it is a dead end, so the requester is always excluded. When nobody else can be reached, ask_expert returns status: ask_requester (resolved_from: 'requester') instead of notifying anyone, with a reason: requester_matched (the asker is themself the best match) or no_teammate_available (nobody else is Slack-linked and not DND). Either way the agent should ask its own user directly in the conversation — what they know, or who would know — and capture the answer into the knowledge base, so the answer gets written down where a Slack round-trip would have gone nowhere.

ask_expert(prompt, role?, skill?) [knowledge base misses]
-> Halyard DMs a matching teammate in Slack
-> agent polls check_response(conversation_id, wait?) [wait blocks ≤ 55s]
-> the teammate replies in Slack
-> reply_to_expert / get_conversation as needed
-> summarize_conversation(conversation_id, question, answer) [captured to knowledge]

The teammate answers in Slack — the place they already work — and the agent captures the reply back into the knowledge base, so the next agent that asks the same thing resolves it from memory instead of interrupting the person again. Pass entry_type to summarize_conversation when you know what the answer is — PROCESS for a repeatable how-to, DECISION for a choice.

When the question was asked in Slack (Haly in a channel or DM), capture is automatic: each teammate reply is delivered back to the asker’s thread and written into one knowledge entry for the ask group — typed PROCESS when the answer describes how something is done, written as steps a reader can follow again — authored by the teammate who answered and linked to the thread.

Every member also has an accessRoleADMIN or MEMBER. This governs permissions in Halyard (for example, get_delivery_metrics is admin-only), not who answers questions. A MEMBER can be a routing target; an ADMIN may never be routed a single question. Keep the two axes separate: accessRole is about what you can do, roles / skills are about what you can answer.