You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by "wu-sheng (via GitHub)" <gi...@apache.org> on 2026/09/16 14:27:01 UTC
[PR] A scenario writes the prompt its agent sends, and asz view draws it [skywalking-ai-sessionizer]
wu-sheng opened a new pull request, #12:
URL: https://github.com/apache/skywalking-ai-sessionizer/pull/12
With `provider_bodies: true` a scenario already wrote the request and the response of every call, and their `messages` were already real. Two fields inside the request were not, and one was missing.
| Request field | Was | Now |
| --- | --- | --- |
| `system[1]` system prompt | `"Use the tools to answer. "` × 80 | written by the scenario |
| `tools[]` | `Read`, `Bash`, descriptions one sentence × 40, whatever the agent did | written by the scenario |
| response `usage` | absent | the call's own, the numbers its transcript already records |
In the SkyWalking showcase this drew a calendar and mail assistant as a coding agent.
## What a scenario writes
`system_prompt` and `tools` say what a stream sends — on the scenario for the main stream, and on an `agent`, `skill` or workflow child for its own, since a narrower set is the reason to start one.
A scenario writes its own and shares none with another. A request body is read as a document, and a borrowed description describes the wrong agent: the same tool name means one thing to a release manager and another to an inbox assistant. They cannot be derived from the calls either, because a description is prose about what a tool is for, which no call carries.
A scenario that writes neither keeps the stand-in, which is filler sized to make a body worth cutting rather than something to read — `tests/scenarios/provider-bodies.expect.yaml` pins `provider_files: 5` against it.
Three rules came out of review:
- **Both or neither.** Each field falls back on its own, so half a declaration would leave an authored prompt beside the stand-in's `Read` and `Bash` — the very thing writing them is meant to stop.
- **Written and empty is not unwritten.** A stream may advertise no tools at all, and sends an empty list, not `null`.
- **A stream must advertise every tool it calls**, starting a child included, since the block is named `Agent`, `Skill` or `Workflow`. A model cannot call a tool the request never offered it. This caught a draft that advertised two tools and called nine.
A value YAML writes as a plain scalar but JSON refuses — an infinity or a NaN — is refused when the scenario loads, naming the tool. The body writer cannot report it, so such a value used to leave an **empty body** and surface much later as a digest that did not match.
## `asz view` draws the prompt
The embedded renderer moves to Horizon `0ce1f8d6`, which added the inspector's Prompt tab, and the page gains the route that tab reads:
```
GET /api/c/{id}/files?session=&seq=
```
Landed files by sequence, at most 32 and 64 MiB a request, as base64 in a JSON array. The OAP frames its equivalent by length because it serves a browser it does not own and bodies of any size; this serves the page beside it, and the simpler shape saves parsing a framed stream by hand in an inline script.
The renderer offers the tab **only to a host that can read files**, so the pin alone would have moved `asz view` to a renderer whose Prompt tab it could never show, and the page beside the storage root would have drawn less than the SkyWalking UI does.
A repeated sequence is read once. A file that is gone is left out, as an unknown sequence is, and the renderer reports which it did not get; a permission or an I/O failure is reported instead, so a reader can ask again rather than being told the file is absent.
**The scanner takes regular files only.** A landed file is written once and left read-only, so anything else carrying a landed name is not one: a symlink in a root from somewhere else would otherwise have been read and served as though it were landed data, whatever it pointed at. That closes the same hole on the record route, where it is older than this change.
## Checked
- 39 packages pass, `go vet` and `gofmt` silent, license headers clean.
- `tools/conversation-view.sh check` — the embedded renderer is exactly what the pinned commit builds.
- Served from a real root: a planted `leak-999999.sd -> /etc/passwd` returns nothing while the real sequence still serves; `seq=4&seq=4&seq=4` returns one file; bytes are byte-exact against the file on disk.
- Two rounds of adversarial review; every finding either fixed or answered, including one that showed a documented example in `docs/en/guides/scenario.md` no longer loaded.
Bodies are still rendered at the scale a scenario declares. A real Claude Code request was measured at 121–196 KB, of which the tool schemas were 74 KB — sizing the showcase scenarios to that is the next change, not this one.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] A scenario writes the prompt its agent sends, and asz view draws it [skywalking-ai-sessionizer]
Posted by "wu-sheng (via GitHub)" <gi...@apache.org>.
wu-sheng merged PR #12:
URL: https://github.com/apache/skywalking-ai-sessionizer/pull/12
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org