Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions plugins/workiq-preview/skills/workiq-preview/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@ See [Resolving tool names in your host](#resolving-tool-names-in-your-host) belo
| Sending/replying/reacting in Teams, setting presence | "Send a chat to Alex", "Post in the Daily channel", "React with 👍", "Set me to Busy" | entity tools on `/chats/...` or `/teams/...` — see `references/teams-work-iq.md` |
| Fetching a known entity by ID | "Get event `AAMk...` details" | `fetch` |
| Listing files in a OneDrive/SharePoint folder | "List files in my OneDrive 'Specs' folder" | `fetch` |
| Listing tasks/plans/buckets in Planner | "List my Planner tasks due this week" | `fetch` |
| Listing tasks/plans/buckets in Planner | "List my Planner tasks due this week" | `fetch` — see `references/tasks-work-iq.md` avoid `ask` |
| Listing / creating / completing Planner tasks | "Add a task to follow up with finance", "Mark my task done", "List my Planner tasks" | entity tools on `/planner/...` — see `references/tasks-work-iq.md` |
| List my To Do task lists | "Show me my to-do lists" | `fetch` (`/me/todo/lists`) — subject to server policy |
| Get a personal contact by name | "Get the contact card for Morgan Avery" | `fetch` (`/me/contacts?$filter=...`) — subject to server policy |
| List or manage Outlook categories | "What Outlook categories do I have?" | `fetch` (`/me/outlook/masterCategories`); writes subject to server policy |
| Org chart / direct reports / manager lookup | "Who are Rob's direct reports?" | `fetch` (`/users/{id}/directReports`) |
Expand All @@ -68,7 +67,8 @@ See [Resolving tool names in your host](#resolving-tool-names-in-your-host) belo
> local markdown file, insert into a local/SQL table, or use any other builtin
> task tracker — that does not satisfy the request and the user cannot see it in Planner.
> If a WorkIQ task call fails, report the failure; do not silently substitute local storage.
> See `references/tasks-work-iq.md`.
> See `references/tasks-work-iq.md`; for named Planner plan requests, read that
> reference before resolving the plan so group-backed plans are checked correctly.

### Required workflow order — don't stop after a preparatory lookup

Expand Down Expand Up @@ -228,7 +228,6 @@ Entity tools provide **fast, direct access to specific M365 data** via Work IQ A
| Planner | `/me/planner/plans`, `/planner/tasks` | list/create/update/complete/delete — see `references/tasks-work-iq.md` |
| Teams | `/me/chats`, `/chats/{chatId}/messages`, `/me/joinedTeams`, `/teams/{teamId}/channels/{channelId}/messages`, `/me/presence` | chats vs channels are different surfaces — see `references/teams-work-iq.md` |
| People | `/me`, `/users/{id}`, `/users/{id}/directReports`, `/me/manager`, `/me/contacts` | profile, org, contacts — see directory-vs-contacts warning below |
| To Do | `/me/todo/lists`, `/me/todo/lists/{listId}/tasks` | list/create/update/delete — **commonly policy-denied**, see note below |
| Outlook categories | `/me/outlook/masterCategories` | list/get/create/update/delete — writes commonly policy-denied |
| Files | `/me/drive`, `/drives/{id}`, `/sites/{id}` | list/get JSON metadata only — binary content (file bytes, attachment payloads) is not released yet, see the deny rule below |
| Change tracking | `/me/mailFolders/inbox/messages/delta`, `/me/calendarView/delta?...`, `/me/contacts/delta` | "what's new/changed since" — via `call_function` only, never `fetch` |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,43 @@ with…", "mark … done", or "list my tasks", that is M365 data: route it to Wo
Planner task body fields: `planId`, `title`, `bucketId`, `assignments`, `dueDateTime`,
`percentComplete` (`0` = not started, `50` = in progress, `100` = complete).

- **Find the plan before using `ask` (required for named-plan requests):**
1. Fetch owned plans with `/me/planner/plans?$select=id,title,owner`.
2. Search that full result locally for the requested title or keywords. Do not stop after the
first page if the response includes `@odata.nextLink`.
3. If the plan is not in `/me/planner/plans`, resolve likely backing groups before using `ask`.
Fetch `/me/joinedTeams?$select=id,displayName,description` to get group IDs for Teams the
user has joined, guess likely team/group names, then fetch
`/groups/{group-id}/planner/plans?$select=id,title,owner` to get the plan ID. Do not pass
`$top` to `/me/joinedTeams`.
4. If `/me/joinedTeams` misses, use known group IDs when provided or fetch the user's joined
groups and then fetch `/groups/{group-id}/planner/plans?$select=id,title,owner`.
5. If you have an owner/group ID but not the group-plans path, use
`/planner/plans?$filter=owner eq '{Group or UserId}'&$select=id,title,owner`.
6. Only use `ask` after the structured `/me/planner/plans`, assigned-task `planId`, group-backed
`/groups/{group-id}/planner/plans`, and owner-filtered `/planner/plans` lookup paths are
exhausted, unavailable, or policy-blocked.
- **Private tasks and "Assigned to me" tasks:** use `/me/planner/tasks`.
- **Enforce filtering on Planner collection GETs:**
- `GET /planner/plans` requires `$filter=owner eq '{Group or UserId}'`.
- `GET /planner/tasks` requires a `$filter` containing `planId`.
- **Forbidden create plans/tasks paths** Do not use `create_entity`, `update_entity`, `delete_entity` for the following paths
- /me/planner/plans
- /me/planner/tasks
- /users/{user-id}/planner/plans
- /users/{user-id}/planner/tasks
- /groups/{group-id}/planner/plans

- **Mark a Planner task done:** `update_entity` with `{"percentComplete":100}`.
- **Planner gotcha:** `update_entity` / `delete_entity` on Planner resources
require the current `@odata.etag` (an `If-Match` precondition). Fetch the task first to
read its etag; if a Planner write returns a `412`/precondition error, re-fetch and retry.


## Resolve-then-act (do not loop)

1. Resolve the target with **one** `fetch` (Planner task) — match by `title`.
2. If the first fetch does not find it, try **one** `ask` to locate it semantically.
1. Resolve the target with `fetch` (Planner task) — match by `title`. (Planner plan) - first using `/me/planner/plans` else using `/groups/{group-id}/planner/plans`
2. If the fetch does not find it, try **one** `ask` to locate it semantically.
3. If still not found, **stop and report "not found"** — do not fire 10+ more `fetch`/`search_paths`/`ask` calls.
4. Once you have the id, call the mutation (`create_entity` / `update_entity` / `delete_entity`).

Expand Down
7 changes: 3 additions & 4 deletions plugins/workiq/skills/workiq/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@ See [Resolving tool names in your host](#resolving-tool-names-in-your-host) belo
| Sending/replying/reacting in Teams, setting presence | "Send a chat to Alex", "Post in the Daily channel", "React with 👍", "Set me to Busy" | entity tools on `/chats/...` or `/teams/...` — see `references/teams-work-iq.md` |
| Fetching a known entity by ID | "Get event `AAMk...` details" | `fetch` |
| Listing files in a OneDrive/SharePoint folder | "List files in my OneDrive 'Specs' folder" | `fetch` |
| Listing tasks/plans/buckets in Planner | "List my Planner tasks due this week" | `fetch` |
| Listing tasks/plans/buckets in Planner | "List my Planner tasks due this week" | `fetch` — see `references/tasks-work-iq.md` avoid `ask` |
Comment thread
husain-zaidi marked this conversation as resolved.
| Listing / creating / completing Planner tasks | "Add a task to follow up with finance", "Mark my task done", "List my Planner tasks" | entity tools on `/planner/...` — see `references/tasks-work-iq.md` |
| List my To Do task lists | "Show me my to-do lists" | `fetch` (`/me/todo/lists`) — subject to server policy |
| Get a personal contact by name | "Get the contact card for Morgan Avery" | `fetch` (`/me/contacts?$filter=...`) — subject to server policy |
| List or manage Outlook categories | "What Outlook categories do I have?" | `fetch` (`/me/outlook/masterCategories`); writes subject to server policy |
| Org chart / direct reports / manager lookup | "Who are Rob's direct reports?" | `fetch` (`/users/{id}/directReports`) |
Expand All @@ -68,7 +67,8 @@ See [Resolving tool names in your host](#resolving-tool-names-in-your-host) belo
> local markdown file, insert into a local/SQL table, or use any other builtin
> task tracker — that does not satisfy the request and the user cannot see it in Planner.
> If a WorkIQ task call fails, report the failure; do not silently substitute local storage.
> See `references/tasks-work-iq.md`.
> See `references/tasks-work-iq.md`; for named Planner plan requests, read that
> reference before resolving the plan so group-backed plans are checked correctly.

### Required workflow order — don't stop after a preparatory lookup

Expand Down Expand Up @@ -228,7 +228,6 @@ Entity tools provide **fast, direct access to specific M365 data** via Work IQ A
| Planner | `/me/planner/plans`, `/planner/tasks` | list/create/update/complete/delete — see `references/tasks-work-iq.md` |
| Teams | `/me/chats`, `/chats/{chatId}/messages`, `/me/joinedTeams`, `/teams/{teamId}/channels/{channelId}/messages`, `/me/presence` | chats vs channels are different surfaces — see `references/teams-work-iq.md` |
| People | `/me`, `/users/{id}`, `/users/{id}/directReports`, `/me/manager`, `/me/contacts` | profile, org, contacts — see directory-vs-contacts warning below |
| To Do | `/me/todo/lists`, `/me/todo/lists/{listId}/tasks` | list/create/update/delete — **commonly policy-denied**, see note below |
| Outlook categories | `/me/outlook/masterCategories` | list/get/create/update/delete — writes commonly policy-denied |
| Files | `/me/drive`, `/drives/{id}`, `/sites/{id}` | list/get JSON metadata only — binary content (file bytes, attachment payloads) is not released yet, see the deny rule below |
| Change tracking | `/me/mailFolders/inbox/messages/delta`, `/me/calendarView/delta?...`, `/me/contacts/delta` | "what's new/changed since" — via `call_function` only, never `fetch` |
Expand Down
32 changes: 30 additions & 2 deletions plugins/workiq/skills/workiq/references/tasks-work-iq.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,43 @@ with…", "mark … done", or "list my tasks", that is M365 data: route it to Wo
Planner task body fields: `planId`, `title`, `bucketId`, `assignments`, `dueDateTime`,
`percentComplete` (`0` = not started, `50` = in progress, `100` = complete).

- **Find the plan before using `ask` (required for named-plan requests):**
1. Fetch owned plans with `/me/planner/plans?$select=id,title,owner`.
2. Search that full result locally for the requested title or keywords. Do not stop after the
first page if the response includes `@odata.nextLink`.
3. If the plan is not in `/me/planner/plans`, resolve likely backing groups before using `ask`.
Fetch `/me/joinedTeams?$select=id,displayName,description` to get group IDs for Teams the
user has joined, guess likely team/group names, then fetch
`/groups/{group-id}/planner/plans?$select=id,title,owner` to get the plan ID. Do not pass
`$top` to `/me/joinedTeams`.
4. If `/me/joinedTeams` misses, use known group IDs when provided or fetch the user's joined
groups and then fetch `/groups/{group-id}/planner/plans?$select=id,title,owner`.
5. If you have an owner/group ID but not the group-plans path, use
`/planner/plans?$filter=owner eq '{Group or UserId}'&$select=id,title,owner`.
6. Only use `ask` after the structured `/me/planner/plans`, assigned-task `planId`, group-backed
`/groups/{group-id}/planner/plans`, and owner-filtered `/planner/plans` lookup paths are
exhausted, unavailable, or policy-blocked.
- **Private tasks and "Assigned to me" tasks:** use `/me/planner/tasks`.
- **Enforce filtering on Planner collection GETs:**
- `GET /planner/plans` requires `$filter=owner eq '{Group or UserId}'`.
- `GET /planner/tasks` requires a `$filter` containing `planId`.
- **Forbidden create plans/tasks paths** Do not use `create_entity`, `update_entity`, `delete_entity` for the following paths
- /me/planner/plans
- /me/planner/tasks
- /users/{user-id}/planner/plans
- /users/{user-id}/planner/tasks
- /groups/{group-id}/planner/plans

- **Mark a Planner task done:** `update_entity` with `{"percentComplete":100}`.
- **Planner gotcha:** `update_entity` / `delete_entity` on Planner resources
require the current `@odata.etag` (an `If-Match` precondition). Fetch the task first to
read its etag; if a Planner write returns a `412`/precondition error, re-fetch and retry.


## Resolve-then-act (do not loop)

1. Resolve the target with **one** `fetch` (Planner task) — match by `title`.
2. If the first fetch does not find it, try **one** `ask` to locate it semantically.
1. Resolve the target with `fetch` (Planner task) — match by `title`. (Planner plan) - first using `/me/planner/plans` else using `/groups/{group-id}/planner/plans`
2. If the fetch does not find it, try **one** `ask` to locate it semantically.
3. If still not found, **stop and report "not found"** — do not fire 10+ more `fetch`/`search_paths`/`ask` calls.
4. Once you have the id, call the mutation (`create_entity` / `update_entity` / `delete_entity`).

Expand Down