Cette page est publiée en anglais et en ukrainien ; la version anglaise figure ci-dessous.
Proactive findings: the assistant's raised hand
For developers, in code: a tool bound to a screen that the assistant calls when a user has dwelt on it, the findings shape it reads, the cooldown, and how to measure whether the raised hand is welcome.
On a screen of your application the assistant can volunteer what it noticed — an unfinished setup, a failing import, an invoice overdue — instead of waiting to be asked. Everything about it is built to earn the interruption: the check is yours, it runs with no model, and it says nothing when there is nothing to say.
Proactive findings are part of the Growth plan and above.
In the panel: the screen’s source → For applications → Proactive analysis (Sources).
How a tick runs
- The widget sends a
proactive_tickafter the user has been on a screen for 8 seconds — only on screens whose source names a proactive tool, and only while the widget is closed. - The runtime calls that tool directly, with no model:
{{user}}and{{screen.*}}filled, no model-authored arguments. An empty result ends the tick for free. - On a non-empty result a small model turn reads the findings and either stays silent or picks the first finding worth saying — screen-first, loud before quiet — and writes one sentence.
- The widget shows the sentence on the launcher’s bubble with the character’s hand raised. A
click runs the finding’s action: a route to open (through the ordinary cancelable
shukai:action:navigate) or a question to ask.
What your endpoint returns
A JSON list of findings, or { "findings": [ … ] }. Anything else counts as empty.
[
{
"code": "sources_failed",
"title": "3 pages failed to process",
"detail": "Reprocess them from the Sources screen.",
"severity": "warning",
"routes": ["/sites/{siteId}/sources"],
"action": { "route": "/sites/{siteId}/sources", "params": { "siteId": "c4b7…" } },
"proactive": true
}
]
| Key | Read by code? | Meaning |
|---|---|---|
code |
yes | names the finding; the teaser carries it, and the cooldown is keyed on it |
proactive |
yes | false keeps the finding for a model that asks and leaves it out of a tick — for improvements and choices, where a real fault stays loud |
routes |
yes | routes the click may open; resolved against the current screen, refused if they would leave the origin |
action.route, action.params |
yes | what the click does; params (scalars, as strings) take priority over the screen’s and the model’s |
title, detail, severity, anything else |
no | passed to the model as JSON, which is what it writes the sentence from |
At most 8 findings are read, and the JSON handed to the model is capped at 6,000 characters — return the ones that matter, loud first.
Bind it to a screen
On the screen’s source, under For applications: Proactive analysis — pick the tool — and
Say it again after (seconds). A screen with no tool is silent; the unit of opt-in is a screen,
not a site. The tool may be global or scoped to that screen; the same tool can serve every
screen when {{screen.route}} tells it which one is asking.
The cooldown
The widget records when a finding was shown on which path, and sends the age with the next tick
as shown_ago_ms. The server applies your current window — the source’s seconds, or the
agent’s default (24 hours), or 0 for every entry — so shortening it in the panel takes effect
at once. A dismissed finding is not shown again inside the window; a new finding with a new code
on the same screen is.
Measure it
Three events carry detail.codes:
Shukai.on("suggestion:shown", (e) => track("finding_shown", e.detail.codes));
Shukai.on("suggestion:accepted", (e) => track("finding_clicked", e.detail.codes));
Shukai.on("suggestion:dismissed", (e) => track("finding_dismissed", e.detail.codes));
The dismissal rate per code is the real test. A finding people close without clicking is one to
make quiet ("proactive": false) or to stop returning.
Cost and gates
A tick is free until your endpoint returns something; the model turn that follows is metered
like any other, even when it stays silent. The tick runs behind the plan gate and the site’s
rate limit, and the tool call passes the same egress policy as any other call. Our own panel’s
check — site_insights, which looks at sources, keys, requests and credits — is one consumer of
this mechanism, not the mechanism: any endpoint returning that shape works.