parseAssistantRole uses the structural heuristic to distinguish legacy fantasy envelope from new SDK parts. We don't use try/fallback here because json.Unmarshal of a fantasy envelope into []ChatMessagePart can partially succeed (Type gets set from the envelope's "type" field) while silently losing
(raw pqtype.NullRawMessage)
| 402 | // the envelope's "data" JSON object, but that's a brittle |
| 403 | // invariant tied to Go's json decoder behavior for []byte. |
| 404 | func parseAssistantRole(raw pqtype.NullRawMessage) ([]codersdk.ChatMessagePart, error) { |
| 405 | if isFantasyEnvelopeFormat(raw.RawMessage) { |
| 406 | return parseLegacyFantasyBlocks(string(codersdk.ChatMessageRoleAssistant), raw) |
| 407 | } |
| 408 | |
| 409 | // New SDK format. |
| 410 | var parts []codersdk.ChatMessagePart |
| 411 | if err := json.Unmarshal(raw.RawMessage, &parts); err != nil { |
| 412 | return nil, xerrors.Errorf("parse assistant content: %w", err) |
| 413 | } |
| 414 | if !hasNonEmptyType(parts) { |
| 415 | return nil, nil |
| 416 | } |
| 417 | return parts, nil |
| 418 | } |
| 419 | |
| 420 | // parseToolRole tries SDK parts first, then falls back to legacy |
| 421 | // tool result rows. Unlike assistant/user roles, tool messages |
no test coverage detected