Skip to content

Commit f3d614d

Browse files
committed
docs(sdk): describe chat.turn() in the advanced chat agent skill
The bundled skill still told an action to return a StreamTextResult, string or UIMessage to answer, an API #4816 removed. It now describes edit-only actions, chat.turn() for an answer, the action-turn trigger, persistence for both models, and sending actions through useChat.
1 parent 7fb8310 commit f3d614d

1 file changed

Lines changed: 22 additions & 11 deletions

File tree

  • packages/trigger-sdk/skills/trigger-chat-agent-advanced

packages/trigger-sdk/skills/trigger-chat-agent-advanced/SKILL.md

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -185,37 +185,48 @@ compaction: {
185185
},
186186
```
187187

188-
### 5. Actions: mutate state without a turn
188+
### 5. Actions: edit state, and optionally answer
189189

190-
`actionSchema` validates; `onAction` mutates via `chat.history` (`slice`, `replace`, `rollbackTo`,
191-
`remove`, `getPendingToolCalls`, `extractNewToolResults`). Actions fire `hydrateMessages` and
192-
`onAction` only, never `run()` or the turn hooks. Return a `StreamTextResult`, string, or `UIMessage`
193-
to also emit a model response, built with the `streamText` from `onAction`'s own argument so it
194-
carries the agent's prompt and tools like any other turn.
190+
`actionSchema` validates; `onAction` edits via `chat.history` (`slice`, `replace`, `rollbackTo`,
191+
`remove`, `getPendingToolCalls`, `extractNewToolResults`). An action fires `hydrateMessages` and
192+
`onAction` only. Return nothing for an edit-only action: no model call, and the turn counter does not
193+
advance. Return `chat.turn()` to answer after the edit: a turn runs on the edited history with
194+
everything a turn has (the agent's system prompt and tools, steering, compaction, injected
195+
instructions, `onTurnStart` and `onTurnComplete`, persistence), and `run()` receives it with
196+
`trigger: "action-turn"`. `onAction` has no `streamText` argument, and returning a
197+
`StreamTextResult`, string or `UIMessage` from it throws.
195198

196199
Persistence splits by model. Without `hydrateMessages` the runtime snapshots the conversation after
197-
an action that changed it, so a rollback or a returned response survives the run ending. With
200+
an action that changed it, before any turn starts, so a rollback survives the run ending. With
198201
`hydrateMessages` your store is the source of truth and the runtime does not write, so mirror every
199-
mutation yourself: a regenerate is a delete and an insert, and `chat.pipeAndCapture` hands back the
200-
same assistant message the runtime would have captured.
202+
mutation yourself: a regenerate is a delete in `onAction` and an insert that arrives in
203+
`onTurnComplete` like any turn's answer.
201204

202205
```ts
203206
export const myChat = chat.agent({
204207
id: "my-chat",
205208
actionSchema: z.discriminatedUnion("type", [
206209
z.object({ type: z.literal("undo") }),
210+
z.object({ type: z.literal("regenerate") }),
207211
z.object({ type: z.literal("rollback"), targetMessageId: z.string() }),
208212
]),
209213
onAction: async ({ action }) => {
210-
if (action.type === "undo") chat.history.slice(0, -2);
214+
if (action.type === "undo") chat.history.slice(0, -2); // edit only
211215
if (action.type === "rollback") chat.history.rollbackTo(action.targetMessageId);
216+
if (action.type === "regenerate") {
217+
chat.history.slice(0, -1);
218+
return chat.turn(); // answer the edited history
219+
}
212220
},
213221
run: async ({ messages, signal, streamText }) =>
214222
streamText({ model: anthropic("claude-sonnet-4-5"), messages, abortSignal: signal }),
215223
});
216224
```
217225

218-
Send from the browser with `transport.sendAction(chatId, { type: "undo" })`, or server-side with
226+
Send from the browser through `useChat`, so the answer a turn produces renders like any turn:
227+
`sendMessage(undefined, { body: { action: { type: "regenerate" } } })`, `regenerate({ body: { action } })`,
228+
or `useChatActions({ sendMessage })` from `@trigger.dev/sdk/chat/react`. `transport.sendAction(chatId, action)`
229+
returns a raw stream the caller must read itself. Server-side, use
219230
`agentChat.sendAction({ type: "rollback", targetMessageId: "msg-3" })`.
220231

221232
### 6. Fast starts: Head Start

0 commit comments

Comments
 (0)