GetSessionSnapshot returns the full, self-contained state of a session: its stored fields plus, when an active runtime is attached, its live runtime state (streaming, current agent) and the sequence number of the most recent event on its /events stream. It is the resync primitive for the control pla
(ctx context.Context, id string)
| 288 | // plane: a client reads the snapshot, then tails /events?since=<LastEventSeq> |
| 289 | // to continue without a gap. |
| 290 | func (sm *SessionManager) GetSessionSnapshot(ctx context.Context, id string) (*api.SessionSnapshotResponse, error) { |
| 291 | // Prefer the live in-memory session (it has the freshest messages and |
| 292 | // title) and fall back to the store when the session is not attached. |
| 293 | var sess *session.Session |
| 294 | streaming := false |
| 295 | agent := "" |
| 296 | if rs, ok := sm.runtimeSessions.Load(id); ok { |
| 297 | sess = rs.session |
| 298 | agent = rs.runtime.CurrentAgentName(ctx) |
| 299 | // Probe streaming state without interfering: TryLock succeeds only |
| 300 | // when no RunStream is in progress. |
| 301 | if rs.streaming.TryLock() { |
| 302 | rs.streaming.Unlock() |
| 303 | } else { |
| 304 | streaming = true |
| 305 | } |
| 306 | } |
| 307 | if sess == nil { |
| 308 | var err error |
| 309 | sess, err = sm.sessionStore.GetSession(ctx, id) |
| 310 | if err != nil { |
| 311 | return nil, err |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | lastSeq, _ := sm.LastEventSeq(id) |
| 316 | |
| 317 | return &api.SessionSnapshotResponse{ |
| 318 | ID: sess.ID, |
| 319 | Title: sess.Title, |
| 320 | CreatedAt: sess.CreatedAt, |
| 321 | WorkingDir: sess.WorkingDir, |
| 322 | Messages: sess.GetAllMessages(), |
| 323 | ToolsApproved: sess.ToolsApproved, |
| 324 | Permissions: sess.Permissions, |
| 325 | InputTokens: sess.InputTokens, |
| 326 | OutputTokens: sess.OutputTokens, |
| 327 | Streaming: streaming, |
| 328 | Agent: agent, |
| 329 | LastEventSeq: lastSeq, |
| 330 | }, nil |
| 331 | } |
| 332 | |
| 333 | // CreateSession creates a new session from a template. |
| 334 | func (sm *SessionManager) CreateSession(ctx context.Context, sessionTemplate *session.Session) (*session.Session, error) { |
no test coverage detected