Skip to content

fix(sessions): reconstruct Copilot transcripts from GenAI spans - #10

Merged
tobilg merged 2 commits into
tobilg:mainfrom
siddiqueirshad:fix/copilot-session-transcripts
Sep 15, 2026
Merged

tobilg merged 2 commits into
tobilg:mainfrom
siddiqueirshad:fix/copilot-session-transcripts

Conversation

@siddiqueirshad

@siddiqueirshad siddiqueirshad commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Copilot session-start logs make a session visible in the dashboard, but do not map to transcript roles. Opening those sessions previously returned 404 even when conversation content was available on GenAI spans. The transcript API now reconstructs the conversation from spans and returns an empty transcript for a known session when no message content is available. Addresses #9.

  • Preserve OTLP LogRecord.eventName as event.name and recognize Copilot session-ID attributes.
  • Follow session-scoped child spans, including tools with alternate session IDs or no session attribute, while excluding unrelated siblings, services, and explicitly different sessions.
  • Recover assistant output from parent agent spans when descendants do not already supply it, without duplicating child replies or token usage.
  • Timestamp tool results at span completion so overlapping calls retain their actual completion order.
  • Preserve imported transcript records, indices, and bounds. Correlate matching live log/span messages using their service, trace, and span identity; keep distinct messages even when their timestamps and content are identical.

Validation

  • Full backend suite: go test ./... -timeout 60s (isolated source directories for exporter tests).
  • Backend static checks: go vet ./....
  • Frontend production build: pnpm --dir frontend build.
  • Frontend tests: pnpm --dir frontend test:run — 294 tests passed.
  • Regression coverage for distinct Claude tool results, imported transcripts alongside live spans, alternate/missing child IDs, session/service boundaries, multi-level traces, parent-output fallback, repeated replies, log/span correlation, and overlapping tools.

Copilot lists sessions from session-start logs, but those events do not map to transcript roles, so opening a listed session 404ed. Build the conversation from matching GenAI spans instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
@tobilg

tobilg commented Sep 15, 2026

Copy link
Copy Markdown
Owner

The change addresses the distinction between a missing session and a known session without mapped log events. The existing backend test suite passes locally.

I found four cases worth addressing before merging:

1. Preserve distinct imported transcript entries

Deduplication logic

Two separate tool results can legitimately have identical timestamps and content. For example, the Claude importer can produce results for call-a and call-b that both contain "success" within the same message.

A regression test using the actual importer returns both results on main, but only one on this branch. The database records remain intact; one result disappears from the returned transcript.

Could we preserve distinct imported entries and use message/tool-call identity when correlating duplicates across sources?

2. Include related child spans with different session identifiers

Session-span query

Copilot can use an internal conversation ID on the session-start log while a tool span carries only the VS Code chat-session ID. The parent agent span can contain both identifiers.

With that arrangement, opening the listed session currently returns the user prompt but omits the related tool call and result. The same happens when a child has valid trace/parent IDs but no session attribute.

Resolving alternate identifiers and parent/child relationships would cover these cases. The current test fixture gives every span the requested conversation ID, so it does not exercise this difference.

3. Recover assistant output available on the parent agent span

invoke_agent handling

Copilot also records gen_ai.output.messages on agent spans. Currently, this branch reads the user input and returns without using that output.

A fixture containing both a user prompt and an assistant response on the agent span returns only the prompt. Could we use the parent output as a fallback when child chat spans do not supply the response, while avoiding duplicate messages and token counts?

4. Use the tool’s completion time for its result

Tool-result timestamp

Tool results currently receive a timestamp one millisecond after the span starts. A five-second tool invocation therefore appears to return after one millisecond. This can also reorder results for overlapping or nested calls.

Using the span’s start time plus duration would preserve the actual completion order.

Validation

  • The full existing backend suite passes locally.
  • go vet passes for storage, OTLP, and handlers.
  • Additional reproduction tests demonstrate the four cases above.
  • The imported-message regression test passes on main and fails on this branch.

I recommend addressing these cases and adding regression coverage before merging.

Resolve Copilot child spans through session aliases and parent relationships. Preserve imported records and correlate live messages by span identity. Recover parent assistant output without duplicating child replies or usage, and timestamp tool results at completion.

Add regression coverage for imported tool results, session boundaries, child identifiers, parent output, repeated replies, log/span correlation, and overlapping tools.
@tobilg
tobilg merged commit 31e384b into tobilg:main Sep 15, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants