Frun1na opened a new pull request, #4693: URL: https://github.com/apache/rocketmq-dashboard/pull/4693
### Brief Description A conversation remembers the runtime session id of its last run so that the next turn can `--resume` it. That id lives in MySQL and survives a container restart; the CLI's workspace lives under `/tmp` and does not. After a restart the CLI exits 1 with `No conversation found with session ID: <id>` and a single `result` frame whose subtype is `error_during_execution` — and because a failed frame echoes the *requested* id back, the executor persisted that dead id over the conversation's. Every later turn then resumed the same missing session: the conversation was stuck for good, with no recovery path. `ResumeRecovery` already specifies the repair — retry the turn once without `--resume` and clear `conversation.runtime_session_id` — and had no production caller. This wires it up: - `ClaudeCodeAgentProvider` detects the signal where the exit code and the stderr are still in scope, and reports it as `ResumeRecovery.RESUME_LOST_CODE` (`llm.provider.resume_lost`). The frames already said what happened, so this adds no second diagnosis; what the caller cannot know on its own is that the retry has to drop `--resume`, which is a property of the command the provider builds. The subtype alone is not enough, because `error_during_execution` also reports failures no retry can fix. - `AiRunExecutor` retries the turn exactly once without `--resume`, after forgetting the dead id so that the retry — and every later turn — starts from a session that exists. The user gets a `notice` on the timeline, because losing the earlier turns' context is the price. - `record()` no longer takes a session id from a frame that did not succeed, so the echoed id cannot be persisted in the first place. The `system/init` id is a real one and still survives a later failure, which is what keeps a stopped or `error_max_turns` run resumable. - The prompt is prepared once, outside the retry, so the optional enhancement is not paid for twice and its reasoning is not written to the timeline twice. Both attempts share one `finalizeRun` and its `beginTerminal` guard, and the first attempt's outcome is discarded before the retry: one run row, one terminal event. ### How Did You Test This Change? `cd server && mvn -B -ntp test` — `Tests run: 3058, Failures: 0, Errors: 0` (the suite also runs Checkstyle and the ArchUnit checks). New tests, each verified to fail against the unfixed code: - `AiRunExecutorTest.aLostResumeSessionShouldBeForgottenAndTheTurnRetriedWithoutResumeTest` — the provider is called twice with `["gone-session", null]` as the resume id, the conversation's id is cleared, the run row ends `COMPLETED` with the session the retry created, and exactly one `run_finished` reached the wire. - `AiRunExecutorTest.aRetryThatFailsTooShouldStillLeaveTheDeadSessionIdForgottenTest` — a retry that also fails must not put the dead id back. - `AiRunExecutorTest.aFailedResultFrameShouldNotPersistTheSessionIdItEchoesBackTest`. - `ClaudeCodeAgentProviderTest.streamEventsShouldReportALostResumeSessionTest` and `...ShouldNotReportALostResumeWhenTheRunNeverResumedTest` — the real subprocess path, in both directions. - `AiTimelineRepositoryTest.forgettingTheRuntimeSessionShouldNullTheColumnByNameTest` — `updateById` skips null fields, so the clear has to name the column; the assertion is on the SQL and the null it binds. ### Checklist - [x] One coherent change; unrelated modifications are not bundled in - [x] Commit subject follows Conventional Commits (`fix:`) - [x] Tests added or updated for non-trivial changes, test methods named `...Test` - [x] New UI text has both Chinese and English entries under `web/src/i18n/` (not applicable: server change, and the timeline notice is existing vocabulary) - [x] Architecture constraints stay green (`mvn test` runs the ArchUnit checks) - [x] New source files carry the ASF license header (no new files) - [x] Documentation touched where behaviour changed (`ResumeRecovery` records where the signal is detected and how it reaches the caller) -- 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: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
