Commit 1f1a366
authored
fix(sdk): custom agent loop parity for continuations, steering, and subtasks (#3936)
## Summary
Three fixes that bring custom agent loops (`chat.customAgent`
hand-rolled loops and `chat.createSession`) up to the behavior
`chat.agent` users already get, and that the docs already promise:
- **Continuation runs no longer replay already-answered messages.** A
chat continuing after a cancel, crash, or upgrade re-delivered every
prior user message into the loop's first wait, so the model re-answered
an old message while the real new one had to arrive via steering. The
`.in` resume cursor is now seeded before any listener attaches, using
the same boot logic as `chat.agent`.
- **Mid-stream steering no longer wipes the in-flight response.**
`chat.pipeAndCapture` (also backing `turn.complete()`) streamed without
a server-generated message id, so a `prepareStep` injection regenerated
the assistant id mid-stream and the frontend replaced the partial
message, discarding everything streamed before the injection.
- **Task-backed tools now work from custom agent loops.** A child task
triggered via `ai.toolExecute` failed with "chat.agent session handle is
not initialized" because the parent's chatId only threaded from the
per-turn context that hand-rolled loops never set. It now falls back to
the session handle the `chat.customAgent` wrapper binds at run boot, so
children can stream progress into the chat with `chat.stream.writer({
target: "root" })` (the documented sub-agent pattern).
## Root cause on the replay fix
Attaching any `.in` listener (`chat.createStopSignal`,
`chat.messages.on`, the first wait) opens the SSE tail with
`Last-Event-ID` taken from the seq cursor at attach time. Custom loops
attached before any cursor existed, so S2 replayed from seq 0. The fix
resolves the cursor from the latest turn-complete header and seeds both
manager cursors (`setLastSeqNum` drives the SSE resume point,
`setLastDispatchedSeqNum` gates waiter dispatch) before attach;
`chat.createSession` now creates its stop signal lazily on the first
iteration, after the seed. Seeding only the first cursor after attach
does not work, which is why the earlier attempt at this was reverted.
All three were reproduced red-green against the references ai-chat
project: the replay repro showed the continuation wait consuming a stale
message in 403ms with the real message arriving via steering injection;
post-fix the wait consumes the real message directly with no injection.
Steering now preserves the full in-flight response, and the deepResearch
sub-agent streams its progress parts into a raw-loop parent. Existing
behavior verified unchanged: full SDK unit suite, `chat.agent` steering,
and stop-then-continue on `chat.createSession`.1 parent 85d93ff commit 1f1a366
2 files changed
Lines changed: 96 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
160 | 160 | | |
161 | 161 | | |
162 | 162 | | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
163 | 167 | | |
164 | 168 | | |
165 | 169 | | |
| |||
221 | 225 | | |
222 | 226 | | |
223 | 227 | | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
224 | 269 | | |
225 | 270 | | |
226 | 271 | | |
| |||
921 | 966 | | |
922 | 967 | | |
923 | 968 | | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
924 | 978 | | |
925 | 979 | | |
926 | 980 | | |
| |||
5104 | 5158 | | |
5105 | 5159 | | |
5106 | 5160 | | |
| 5161 | + | |
5107 | 5162 | | |
5108 | 5163 | | |
5109 | 5164 | | |
| |||
5113 | 5168 | | |
5114 | 5169 | | |
5115 | 5170 | | |
| 5171 | + | |
| 5172 | + | |
| 5173 | + | |
| 5174 | + | |
5116 | 5175 | | |
5117 | 5176 | | |
5118 | 5177 | | |
| |||
5213 | 5272 | | |
5214 | 5273 | | |
5215 | 5274 | | |
| 5275 | + | |
5216 | 5276 | | |
5217 | 5277 | | |
5218 | 5278 | | |
| |||
8613 | 8673 | | |
8614 | 8674 | | |
8615 | 8675 | | |
| 8676 | + | |
8616 | 8677 | | |
8617 | | - | |
| 8678 | + | |
| 8679 | + | |
| 8680 | + | |
| 8681 | + | |
| 8682 | + | |
| 8683 | + | |
| 8684 | + | |
8618 | 8685 | | |
8619 | 8686 | | |
8620 | 8687 | | |
| |||
8936 | 9003 | | |
8937 | 9004 | | |
8938 | 9005 | | |
| 9006 | + | |
| 9007 | + | |
| 9008 | + | |
| 9009 | + | |
| 9010 | + | |
8939 | 9011 | | |
8940 | 9012 | | |
8941 | | - | |
8942 | 9013 | | |
8943 | 9014 | | |
8944 | 9015 | | |
8945 | 9016 | | |
8946 | | - | |
| 9017 | + | |
8947 | 9018 | | |
8948 | 9019 | | |
8949 | 9020 | | |
| |||
8979 | 9050 | | |
8980 | 9051 | | |
8981 | 9052 | | |
8982 | | - | |
| 9053 | + | |
| 9054 | + | |
| 9055 | + | |
| 9056 | + | |
| 9057 | + | |
| 9058 | + | |
8983 | 9059 | | |
8984 | 9060 | | |
8985 | 9061 | | |
8986 | 9062 | | |
8987 | 9063 | | |
8988 | 9064 | | |
| 9065 | + | |
| 9066 | + | |
| 9067 | + | |
| 9068 | + | |
| 9069 | + | |
8989 | 9070 | | |
8990 | 9071 | | |
8991 | 9072 | | |
| |||
9328 | 9409 | | |
9329 | 9410 | | |
9330 | 9411 | | |
9331 | | - | |
| 9412 | + | |
| 9413 | + | |
9332 | 9414 | | |
9333 | 9415 | | |
9334 | 9416 | | |
| |||
0 commit comments