feat: number a turn's sources once and store them with the records

runAgent owns the list, so every call in one turn shares its numbering, and each
record carries only the entries its own call added: the turn's whole list is the
flattening of its records. The schema accepts the field as optional, because zod
drops unknown keys and a reopened conversation would otherwise lose every link.
This commit is contained in:
2026-10-07 16:10:01 +08:00
parent 5d7eec53dc
commit 1a8e767fbe
4 changed files with 197 additions and 131 deletions
@@ -174,13 +174,15 @@ The answer then gains a list, after the body and before the `_Tools:_` line:
```
_Sources_
- [[1]](https://example.com/page) Result title
- [[2]](https://example.com/page-two) Page title
- [\[1\]](https://example.com/page) Result title
- [\[2\]](https://example.com/page-two) Page title
```
The marker is the link, matching the inline marker character for character, so
the same token means the same thing in both places. An entry whose URL cannot be
linked keeps its title and shows no marker link.
the same token means the same thing in both places. The brackets are
escaped because `markdownLink` escapes them: an unescaped `]` would end the link
text early, and the renderer draws the escaped form as a plain `[1]`. An entry
whose URL cannot be linked keeps its title and shows no marker link.
### Prompt