fix(dify-agent): persist interrupted run history (#40972)

This commit is contained in:
盐粒 Yanli authored and GitHub committed 2026-08-19 10:35:13 +00:00
1 parent 356e3a8ab6
commit 930f4e6c26
7 files changed
+235 -140

No files matched your search

+6 -5
View File
@@ -341,11 +341,12 @@ whose Agenton layers provide user input. With the MVP provider set, use
effective prompts are rejected during create-run validation before the run is
persisted or scheduled.
There is no Pydantic AI history layer. To resume Agenton layer state, pass the
`session_snapshot` from a previous terminal event together with a composition
that has the same layer names and order. Success always contains a snapshot.
Failure and cancellation contain one only when compositor entry succeeded and
layer exit completed; otherwise callers should retain their previous snapshot.
The optional Pydantic AI history layer uses the reserved name `history` and
persists captured messages in session snapshots for later resume. Resume from a
terminal event's `session_snapshot` using the same layer composition, names, and
order. Success always contains a snapshot. Failure and cancellation contain one
only when compositor entry succeeded and layer exit completed; otherwise callers
should retain their previous snapshot.
## Observing runs
@@ -47,15 +47,22 @@ tool-call/result pairs and their inputs. If the history is still over target, th
same current model incrementally summarizes older messages while retaining the
latest twenty messages and the first user message.
With a history layer, a successful run replaces its stored messages with the
rewritten complete history in the returned session snapshot. Without this layer,
compaction affects only the current run. Failed runs do not write a resumable
success snapshot, so their history rewrites do not persist across runs.
With a history layer, once pydantic-ai binds and builds messages in the run
capture, the captured, possibly rewritten history replaces the stored messages
in the terminal session snapshot. This applies to successful, failed, and
cancelled runs. A failure or cancellation before the capture contains any
messages preserves the previously restored history. An interrupted capture can
include a partial response or tool-return request marked `state="interrupted"`;
pydantic-ai repairs that state when the snapshot is used by a later independent
run. Without this layer, compaction and interrupted messages affect only the
current run.
## Resume a conversation
Successful runs return a terminal event with both final output and a resumable
session snapshot:
session snapshot. Failed and cancelled terminal events can also carry a session
snapshot that checkpoints current history, but they do not change the interrupted
run's terminal status into success.
```python {test="skip" lint="skip"}
accepted = await client.create_run(request)
@@ -87,10 +94,16 @@ Dify Agent handles memory conservatively:
2. Stored history is sent to the model before the current user prompt.
3. When the LLM layer includes `context_window_tokens`, Harness may rewrite
over-target history immediately before a model request as described above.
4. After a successful run, the complete possibly compacted history is written
back to the layer.
5. Run-level system instructions are removed before history is persisted.
6. Failed runs emit `run_failed` and do not return a success snapshot to resume.
4. Once pydantic-ai binds and builds messages in the run capture, the complete
captured and possibly compacted history is written back to the layer on
success, failure, timeout, or cancellation.
5. If failure or cancellation occurs before the capture contains any messages,
the previously restored history remains unchanged.
6. Run-level system instructions are removed before history is persisted.
7. Interrupted partial messages retain pydantic-ai's `state="interrupted"` marker
so a later independent run can repair and continue from the checkpoint.
8. Failed and cancelled runs keep their terminal status; their snapshot is a
checkpoint, not a successful continuation of the interrupted run.
## Persist snapshots outside the client process
@@ -118,5 +131,5 @@ Always restore snapshots with the same layer names and order that produced them.
| --- | --- |
| `must use reserved layer name 'history'` | Rename the layer to `history`. |
| `does not support dependencies` | Remove `deps` from the history layer. |
| Resume fails with snapshot lifecycle errors | Use the success snapshot from `run_succeeded` and keep layer names/order unchanged. |
| Resume fails with snapshot lifecycle errors | Use a terminal snapshot whose layers were suspended, and keep layer names/order unchanged. |
| System prompts appear missing from saved memory | This is expected; current system prompts are temporary and are not persisted. |
@@ -72,8 +72,13 @@ model incrementally summarizes older history while retaining the latest twenty
messages and the first user message.
Compaction affects later runs only when the composition has a
[history layer](../history-layer/index.md) and a successful run writes the
rewritten history into its session snapshot.
[history layer](../history-layer/index.md). Once pydantic-ai binds and builds
messages in the run capture, successful, failed, timed-out, and cancelled runs
write the captured rewritten history into their terminal session snapshot. A
failure or cancellation before the capture contains any messages preserves the
previously restored history. Interrupted partial messages may be included and
repaired when that checkpoint is used by a later independent run; the interrupted
run's terminal status remains unchanged.
## Complete minimal model composition