Report an unsaved trajectory somewhere that survives
A failed save must not fail the run -- the answer already exists -- but until now the only record of the loss was an error entry appended to the trajectory that had just failed to save. §6 says the trajectory is not optional telemetry; losing one silently is the worst version of losing one. The runtime has no logger by design, so ExecutionResult gains an Unsaved list the surface reads and turns into a §10 log line with run_id, tenant_id, agent_key and agent_version. Never serialised to the client. Covered on all three run paths, streaming included. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJvibeSc1JYXjatankqM1g
This commit is contained in:
@@ -162,10 +162,24 @@ func (s *Server) handleAgentRun(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, s.log, runLoadError(runErr))
|
||||
return
|
||||
}
|
||||
s.logUnsaved(ident, res)
|
||||
|
||||
writeJSON(w, http.StatusOK, buildRunResponse(res))
|
||||
}
|
||||
|
||||
// logUnsaved is the operator's record of a run whose trajectory did not
|
||||
// persist. The run itself already answered; §6 says the trajectory is not
|
||||
// optional telemetry, so losing one is an error even when nothing else went
|
||||
// wrong, and it carries every field §10 asks a log line to carry.
|
||||
func (s *Server) logUnsaved(ident authctx.Identity, res *runtime.ExecutionResult) {
|
||||
for _, detail := range res.Unsaved {
|
||||
s.log.Error("trajectory unsaved",
|
||||
"run_id", res.RunID, "tenant_id", ident.OrgID,
|
||||
"agent_key", res.AgentID, "agent_version", res.AgentVersion,
|
||||
"detail", detail)
|
||||
}
|
||||
}
|
||||
|
||||
// buildRunResponse turns a runtime result into the client's shape.
|
||||
//
|
||||
// Every termination answers 200. That looks wrong at first and is not: the
|
||||
@@ -336,6 +350,7 @@ func (s *Server) streamAgentRun(w http.ResponseWriter, r *http.Request, ident au
|
||||
writeError(w, s.log, runLoadError(runErr))
|
||||
return
|
||||
}
|
||||
s.logUnsaved(ident, res)
|
||||
writeJSON(w, http.StatusOK, buildRunResponse(res))
|
||||
return
|
||||
}
|
||||
@@ -383,6 +398,7 @@ func (s *Server) streamAgentRun(w http.ResponseWriter, r *http.Request, ident au
|
||||
return
|
||||
}
|
||||
|
||||
s.logUnsaved(ident, res)
|
||||
send(map[string]any{"run": buildRunResponse(res)})
|
||||
fmt.Fprint(w, "data: [DONE]\n\n")
|
||||
flusher.Flush()
|
||||
|
||||
Reference in New Issue
Block a user