| name | looking-up-members |
| description | Internal shared skill to resolve member names or email addresses to provider user IDs. Not intended for direct user invocation. |
| user-invocable | false |
Waggle — Member Lookup
Resolve a member name or email to a provider user ID.
Uses the org_members cache populated by resolving-identity.
Silent operation: This skill runs as an internal step of an invoking skill. Return
results to the invoking flow without user-facing narration — the caller owns all user
communication. Only errors, warnings, and prompts required to proceed may surface directly.
Prerequisites
active_provider must already be determined.
org_members must already be populated (caller must trigger resolving-identity Step 2 first).
Team Name Detection
Before running the Resolution Algorithm, check if the query matches a team name rather than a person name:
- If
teamsDatabaseId is available in headless_config:
a. Fetch team names from the Teams database (Name/title property of each row).
b. If the query (case-insensitive) exactly matches any team name, or if any team name contains the query as a substring:
- Return empty array
[] with metadata: { "teamMatch": true, "teamName": "<matched team name>" }
- The caller MUST NOT expand this to team members.
- The caller should ask the user: "'{query}' is a team name. Assignee must be exactly 1 person. Which member of {team} should be assigned?"
- If
teamsDatabaseId is not available, skip this check and proceed to the Resolution Algorithm.
Resolution Algorithm
Given a query string (name or email fragment):
- Exact email match: compare query (case-insensitive) against
org_members[*].email. Return immediately if exactly one match.
- Exact name match: compare query (case-insensitive) against
org_members[*].name. Return immediately if exactly one match.
- Partial name match: check if any
name contains the query string (case-insensitive). Collect all matches.
- Return results:
- 0 matches → return empty array
[]. Do not error — let the caller handle the missing case.
- 1 match → return
[{ id, name, email }].
- 2–5 matches → return the array. Caller should present candidates and ask the user to confirm.
- 6+ matches → return the first 5 with a note that the query is too broad. Caller should ask for a more specific name.
TeamsDB Fallback
If org_members is empty (provider does not support member listing), fall back to TeamsDB:
- If
teamsDatabaseId is not in headless_config, return empty array [] (no fallback available).
- Fetch the Teams database using
teamsDatabaseId from config.
- Collect all unique persons from the
Members (people-type) field across all teams.
- Use this as the search corpus. Cache result in
org_members for the session.
- Apply the same Resolution Algorithm above.
Caller Responsibility
The caller (delegating-tasks, ingesting-messages, managing-tasks) must:
- Run detecting-provider + resolving-identity (org_members) before calling this skill.
- Handle the returned candidates with AskUserQuestion if multiple matches exist.
- Not call this skill for the current user — use
current_user.id directly from resolving-identity.