Skip to content
Merged
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
2 changes: 1 addition & 1 deletion application/single_app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
EXECUTOR_TYPE = 'thread'
EXECUTOR_MAX_WORKERS = 30
SESSION_TYPE = 'filesystem'
VERSION = "0.261.227"
VERSION = "0.261.228"
IS_DEVELOPMENT = is_development_env_enabled()

# Opt-out for deployments where App Service Easy Auth is active but the platform
Expand Down
346 changes: 186 additions & 160 deletions application/v2_ui/src/components/notifications/WorkflowAlertCard.tsx

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion application/v2_ui/src/components/ui/primitives.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ export function GlassPanel({
);
}

type ButtonVariant = 'primary' | 'ghost' | 'subtle' | 'danger';
type ButtonVariant = 'primary' | 'success' | 'ghost' | 'subtle' | 'danger';
type ButtonSize = 'sm' | 'md' | 'lg' | 'icon';

const variantClass: Record<ButtonVariant, string> = {
primary:
'bg-accent text-on-accent hover:bg-accent-hover shadow-sm disabled:hover:bg-accent',
success:
'bg-ok-strong text-on-ok hover:bg-ok-strong-hover shadow-sm disabled:hover:bg-ok-strong',
ghost: 'text-text-2 hover:text-text-1 hover:bg-surface-2',
subtle: 'glass-flat text-text-1 hover:bg-surface-2 rounded-xl',
danger: 'bg-danger-soft text-danger hover:bg-danger hover:text-white',
Expand Down
5 changes: 4 additions & 1 deletion application/v2_ui/src/lib/workflowAlertNotices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ function readLabels(value: unknown): string[] {
return labels.slice(0, MAX_CHIPS);
}

/** The link to a conversation the workflow created: where the card's Open button goes first. */
export const WORKFLOW_ALERT_CREATED_LINK_LABEL = 'Open created conversation';

/**
* What a link button says.
*
Expand All @@ -245,7 +248,7 @@ function linkLabel(raw: unknown): string {
return 'Open workflow conversation';
}
if (lower.startsWith('open created')) {
return 'Open created conversation';
return WORKFLOW_ALERT_CREATED_LINK_LABEL;
}
if (lower.startsWith('open updated')) {
return 'Open conversation';
Expand Down
10 changes: 5 additions & 5 deletions application/v2_ui/src/stores/workflowAlertStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ interface WorkflowAlertState {
dismissEntry: () => Promise<void>;
markAllRead: () => Promise<void>;
/**
* Follow a link or an open action from the card. The entry's lead alert -- the one the
* card was showing -- is marked read, and the card closes.
* Follow a link or an open action from the card. Every alert in the entry shown is marked
* read, as Mark read did before Open replaced it, and the card closes.
*/
openFromCard: (target: NotificationTarget, context: NotificationNavigationContext) => Promise<void>;
}
Expand Down Expand Up @@ -395,10 +395,10 @@ export const useWorkflowAlertStore = create<WorkflowAlertState>((set, get) => {
if (state.phase !== 'card' || !entry || state.busy) {
return;
}
const leadId = entry.lead.id;
settled.add(leadId);
const ids = workflowAlertEntryIds(entry);
ids.forEach((id) => settled.add(id));
finish();
const read = actions.markRead([leadId]).catch(() => [] as string[]);
const read = actions.markRead(ids).catch(() => [] as string[]);
// A full page load would cancel a request still on its way, so a link that leaves
// the application waits for the read first. Inside it the read carries on regardless.
if (target.kind === 'classic') {
Expand Down
10 changes: 10 additions & 0 deletions application/v2_ui/src/styles/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ html[data-font-size='xl'] {
--warn-soft: rgb(217 119 6 / 0.12);
--ok: #059669;
--ok-soft: rgb(5 150 105 / 0.12);
/* A solid green that keeps text on it at 4.5:1 or better. */
--ok-strong: #047857;
--ok-strong-hover: #065f46;
--on-ok: #ffffff;
/* Informational, used for the group workspace badge. Distinct from --accent so a
group badge is not mistaken for a selected control. */
--info: #0e7490;
Expand Down Expand Up @@ -142,6 +146,9 @@ html[data-font-size='xl'] {
--warn-soft: rgb(251 191 36 / 0.16);
--ok: #34d399;
--ok-soft: rgb(52 211 153 / 0.16);
--ok-strong: #34d399;
--ok-strong-hover: #6ee7b7;
--on-ok: #022c22;
--info: #22d3ee;
--info-soft: rgb(34 211 238 / 0.16);
--change-ai: #bfdbfe;
Expand Down Expand Up @@ -182,6 +189,9 @@ html[data-font-size='xl'] {
--color-warn-soft: var(--warn-soft);
--color-ok: var(--ok);
--color-ok-soft: var(--ok-soft);
--color-ok-strong: var(--ok-strong);
--color-ok-strong-hover: var(--ok-strong-hover);
--color-on-ok: var(--on-ok);
--color-info: var(--info);
--color-info-soft: var(--info-soft);
--color-change-ai: var(--change-ai);
Expand Down
3 changes: 2 additions & 1 deletion docs/explanation/features/CHAT_WORKFLOW_RESULTS_FOLLOW_UP.md
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,8 @@ only while the bootstrap flag is on. Group alerts, alerts without a run, and
failed or cancelled runs get no button. An alert doesn't record the workflow's
definition version, so a structured workflow's alert still offers it, and the
descriptor read then refuses the run with `workflow_result_unsupported`.
Choosing it closes the alert and leaves it unread.
Choosing it closes the alert and leaves it unread. Since 0.261.228 it sits under the
alert's **Show more**, with the alert's other secondary actions.

### Errors

Expand Down
41 changes: 30 additions & 11 deletions docs/explanation/features/V2_WORKFLOW_ALERT_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Implemented in version: **0.261.199**, tracked in
[chat orchestration workflows roadmap](CHAT_ORCHESTRATION_WORKFLOWS_ROADMAP.md)
(#1553, part of #1543).

Open and Dismiss up front, with everything else under Show more, since version: **0.261.228** (#1624).

Dependencies:

- The V2 bell ([V2 Notification Bell and Desktop Notifications](V2_NOTIFICATIONS_BELL.md)).
Expand Down Expand Up @@ -151,7 +153,7 @@ shell. Escape, the backdrop and the focus trap behave as in every other V2 dialo
Focus moves into the card and goes back to where the reader was when it closes,
because the notice that opened it is gone by then.

The card shows:
The card shows just enough to decide what to do:

- **A header band** in the priority's colors, with the priority, the kind ("Alert"
or "Run failed"), the title, the workflow and when it arrived.
Expand All @@ -162,13 +164,24 @@ The card shows:
reason. The runner's own log line ("HIGH alert triggered by: …") is left out,
because the sentence and the rules already say it. A reason that says anything
else is shown.
- **The summary**, and **Show more** for the detail.
- **The summary.**
- **What went wrong**, for a failed run.
- **Open**, a large green button, and **Dismiss**. Open goes to the conversation the
workflow created when it created one; otherwise to the conversation it posted
into, then its run, then the workflow. Its accessible name and tooltip name the
destination, for example "Open created conversation". An alert with nothing to
open offers **Mark read** in its place.

**Show more** holds everything else, so a busy alert, such as one that stood up a
response group, a meeting, a map and a briefing, doesn't bury its summary and Open
button under a dozen chips and links:

- **The detail**.
- **Chips** for the alert's enrichments and its trigger, runner and agent.
- **Links** the alert carries, checked by the bell's resolver. Classic labels the
link to the conversation a workflow posts into "Open workflow"; V2 names it
**Open workflow conversation**, because the card's own **Open workflow** goes to
the workflow. A link to another site isn't offered; a note says so.
- **The other links** the alert carries, checked by the bell's resolver. Classic
labels the link to the conversation a workflow posts into "Open workflow"; V2
names it **Open workflow conversation**, because the card's own **Open workflow**
goes to the workflow. A link to another site isn't offered; a note says so.
- **Open workflow**, which goes to the workflows list of the workspace the workflow
lives in and opens the run that raised the alert:
`/workspace/workflows?workflow_id=<id>&run_id=<id>`, or
Expand All @@ -184,17 +197,21 @@ The card shows:
Alerts from before this release have no recorded scope. For those, it is taken
from the workspace named on their **Open workflow** conversation link, and when
that doesn't name one the button isn't shown rather than guessing.
- **Mark read** and **Dismiss** for the entry shown.
- **Ask about this**, when the alert offers it.

Below the card's body:

- **"1 of 3", Next and Mark all read** when more than one entry is waiting. Next
steps through the entries and wraps around.

### What the actions change

| Action | Effect |
|---|---|
| Mark read, Dismiss | Every alert in the entry shown, so a grouped workflow's alerts are handled together. The button's tooltip says how many, for example "Acts on all 2 alerts from this workflow." |
| Open, Dismiss | Every alert in the entry shown, so a grouped workflow's alerts are handled together. Open marks them read and goes to its destination. The button's tooltip says how many, for example "Acts on all 2 alerts from this workflow." |
| Mark read | Shown in Open's place only when the alert has nothing to open. Every alert in the entry shown. |
| Mark all read | Every alert the card holds, one request each. It never calls the bell's own `mark-all-read`, which would also clear notices the card never showed. |
| A link, Open workflow | Opens the page and marks the entry's lead alert read, as opening a notice in the bell does |
| Another link, Open workflow | Opens the page and marks every alert in the entry read, as Open does |
| Ask about this | Opens a new chat that answers from the run's stored result ([Phase 6a](CHAT_WORKFLOW_RESULTS_FOLLOW_UP.md)). Nothing is marked, as with Close: the alert stays unread in the bell. |
| Close (×, Escape, backdrop) | Nothing is marked. The alerts stay unread in the bell and don't pop up again. |

Expand Down Expand Up @@ -396,7 +413,9 @@ as Flask does in production. Before, it answered those with Vite's "did you mean
minutes to appear. Focusing the window or returning to the tab reads it at once.
- Open run arrives with Phase 6b. Ask about this (Phase 6a) is offered for personal
workflows only, and only while **Use Workflow Results In Chat** is on.
- The card's primary button (**Mark read**) pairs `--accent` with `--on-accent` at
- The card's **Open** button uses `--ok-strong` with `--on-ok`, a green chosen to keep
its text at 5.5:1 in the light theme and 7.9:1 in the dark theme. **Mark read**,
shown only when there is nothing to open, pairs `--accent` with `--on-accent` at
4.49:1 in the light theme, just under 4.5:1. That is a design-token matter shared
by every V2 primary button.

Expand All @@ -408,7 +427,7 @@ as Flask does in production. Before, it answered those with Vite's "did you mean
| `functional_tests/route_tests/test_workflow_alert_since_hours_policy.py` | 8 functions | The route keeps its Blueprint, Swagger and authentication policy; classic's request is unchanged; V2's window is validated and passed through; out-of-range limits fall back as before; invalid windows are refused without reading; a reader failure keeps the existing error shape; through the real reader with a failing Cosmos query, V2's read answers `500` and classic's still answers an empty list |
| `functional_tests/test_v2_alert_lab_excluded_from_build.py` | 4 | The lab's markers exist only in lab code; the reference scanner recognizes every import form; the only reference to the lab is App.tsx's lazy import inside the `import.meta.env.DEV` branch; an existing production build has no file named for the lab and no lab marker (skipped without a build) |
| `functional_tests/test_workflow_priority_alerts.py` | Existing | Classic's workflow alert contract, with the new signature |
| `ui_tests/test_v2_workflow_alert_notices.py` | 28 | Pop-up versus notify-only and the 24-hour window against a server that leaves both filters out; one claim across two tabs of one browser, and a tab opened later; waiting behind a dialog, the bell's panel and a hidden tab; only a successful read retiring an alert, through a failed read on return and a zero count whose confirming read fails; a rise on return read behind a read already on its way; the eight-second tuck, its hover and focus pause, and high and critical staying; storm grouping; every card action; keyboard focus, Escape and the tuck on covering focus; motion with and without reduced motion, including the Web Animations' properties and every `wf-*` keyframe; the rail expanded, collapsed and on a 360 px phone in both themes; text contrast for every priority and category in both themes, with and without reduced transparency; hostile text rendered as text; refused off-site links; and Open workflow's personal, group and unplaceable cases |
| `ui_tests/test_v2_workflow_alert_notices.py` | 29 | Pop-up versus notify-only and the 24-hour window against a server that leaves both filters out; one claim across two tabs of one browser, and a tab opened later; waiting behind a dialog, the bell's panel and a hidden tab; only a successful read retiring an alert, through a failed read on return and a zero count whose confirming read fails; a rise on return read behind a read already on its way; the eight-second tuck, its hover and focus pause, and high and critical staying; storm grouping; every card action; only Close, Show more, Dismiss and the green Open shown up front, with Open going to the created conversation and settling every alert of the entry, and the detail, chips and other actions under Show more; keyboard focus, Escape and the tuck on covering focus; motion with and without reduced motion, including the Web Animations' properties and every `wf-*` keyframe; the rail expanded, collapsed and on a 360 px phone in both themes; text contrast for every priority and category in both themes, with and without reduced transparency; hostile text rendered as text; refused off-site links; and Open workflow's personal, group and unplaceable cases |
| `ui_tests/test_v2_document_provenance.py` | 6 added | Against the real workflows section, personal and group: Open workflow while the list is open expands the run; a second Open workflow for the same run opens it again; running another workflow afterwards doesn't reopen it; a workflow created after the list was read is found with exactly one more list read, which opens its run; a workflow missing from that read too costs one list read per navigation and no more, opens nothing, shows no error and leaves the list usable |

The UI suite mounts the real V2 frame in a harness build, following
Expand Down
11 changes: 11 additions & 0 deletions docs/explanation/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

For feature-focused and fix-focused drill-downs by version, see [Features by Version](https://github.com/microsoft/simplechat/tree/main/docs/explanation/features) and [Fixes by Version](https://github.com/microsoft/simplechat/tree/main/docs/explanation/fixes).

### **(v0.261.228)**

#### User Interface Enhancements

* **V2 Workflow Alerts Lead With One Open Button**
* The full workflow alert now shows just what's needed to act: why it came, its summary, and a large green **Open** button next to **Dismiss**. Open goes to the conversation the workflow created, or else to the conversation it posted into, its run or the workflow, and marks the alert read.
* **Mark read** is gone from alerts that have somewhere to open, because Open marks the alert read and takes you there. When one workflow raised several alerts together, Open and Dismiss act on all of them. An alert with nothing to open still offers Mark read.
* The detail, the pills for the alert's enrichments, trigger, runner and agent, and the other ways in (other links, **Open workflow** and **Ask about this**) are under **Show more**.
* Open's green keeps its text at 4.5:1 contrast or better in the light and dark themes.
* (Ref: #1624, `WorkflowAlertCard.tsx`, `workflowAlertStore.ts`, `theme.css`, [V2 Workflow Alert Notices](features/V2_WORKFLOW_ALERT_NOTICES.md))

### **(v0.261.227)**

#### New Features
Expand Down
27 changes: 16 additions & 11 deletions docs/guides/manage-notifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,22 @@ tucks it into the bell, where it stays unread; it doesn't pop up again.
capture="Capture the V2 rail with a high priority workflow alert notice under My Workspace, using realistic sample alerts. Redact workflow and conversation names." %}

Select the notice to open the full alert. It says why you are seeing it and which
rules matched, what went wrong for a failed run, the summary and details, and the
links the alert carries. From there you can:

- Select **Open workflow** to go to the workflow in its personal or group workspace,
with the run that raised the alert open. This marks the alert read.
- Select **Ask about this**, on an alert about a completed run of one of your
personal workflows, to ask chat about that run's stored result without running
the workflow again. The alert closes and stays unread. See
[Ask about workflow results]({{ '/guides/ask-about-workflow-results/' | relative_url }}).
- Select **Mark read** or **Dismiss**. When the notice stands for several alerts
from one workflow, both act on all of them.
rules matched, the summary, and what went wrong for a failed run. From there you
can:

- Select **Open** to go to what the workflow made: the conversation it created, or
else the conversation it posted into, its run or the workflow itself. This marks
the alert read. An alert with nothing to open offers **Mark read** instead.
- Select **Dismiss** to dismiss it. When the notice stands for several alerts from
one workflow, Open and Dismiss both act on all of them.
- Select **Show more** for the details, the alert's facts, and the other ways in:
- **Open workflow** goes to the workflow in its personal or group workspace,
with the run that raised the alert open. This marks the alert read.
- Other links the alert carries, such as **Open workflow conversation**.
- **Ask about this**, on an alert about a completed run of one of your personal
workflows, asks chat about that run's stored result without running the
workflow again. The alert closes and stays unread. See
[Ask about workflow results]({{ '/guides/ask-about-workflow-results/' | relative_url }}).
- Select **Next** to step through the other waiting alerts, or **Mark all read** to
clear them all. Both appear when more than one alert is waiting.

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/chat-controls.md
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ answer ends with a line that names the run. See
| Control | What it does | Why you would use it | Enabled by |
| --- | --- | --- | --- |
| Ask in chat | On a run in a personal workflow's run history, opens a new chat with that run selected. | Ask what a run found without copying its output into chat or running the workflow again. | `allow_user_workflows` and `enable_chat_workflow_results`, plus the `WorkflowUser` role while `require_member_of_workflow_user` is on, for a completed or partially completed run that isn't a structured run |
| Ask about this | In the full workflow alert, opens a new chat with the alert's run selected. The alert closes and stays unread. | Go straight from an alert to asking what the run found. | The same settings, for a personal workflow's alert about a completed or partially completed run |
| Ask about this | In the full workflow alert, under **Show more**, opens a new chat with the alert's run selected. The alert closes and stays unread. | Go straight from an alert to asking what the run found. | The same settings, for a personal workflow's alert about a completed or partially completed run |
| Workflow result notice | Names the run your next question is about, for example "Answering from the Weekly digest run of Mon, Jun 2, 9:02 AM — not re-running the workflow". While it's shown, every other source and **Orchestrate** are off, and the message box reads "Ask about the workflow results…". | Confirm which result the answer will use before you send. | A run selected with Ask in chat or Ask about this, or inherited from the chat's latest answer |
| Remove workflow result context | Removes the notice, so the next question is an ordinary chat question. | Go back to normal chat in the same conversation. | The notice is shown |
| Unavailable answer | Shows "This answer is unavailable because access to the workflow result it used could not be confirmed." in place of an answer that used a workflow result. Your question stays. | Know that an answer relied on a result you can no longer read, such as a deleted run's. | The result is no longer available to you, or the chat was shared or converted to a collaboration |
Expand Down
Loading
Loading