Skip to content

fix: populate cwd and assistant_response in Chronicle session store#312293

Draft
digitarald wants to merge 1 commit intomicrosoft:mainfrom
digitarald:fix/chronicle-cwd-assistant-response
Draft

fix: populate cwd and assistant_response in Chronicle session store#312293
digitarald wants to merge 1 commit intomicrosoft:mainfrom
digitarald:fix/chronicle-cwd-assistant-response

Conversation

@digitarald
Copy link
Copy Markdown
Contributor

@digitarald digitarald commented Apr 24, 2026

Two fields in the Chronicle local session store were always empty. This fixes both with a consumer-only approach (no OTel producer changes) and adds schema caveats for remaining data gaps.

Changes

cwd — set from vscode.workspace.workspaceFolders[0] during session init.

assistant_responsetruncateForOTel produces invalid JSON for long responses (cuts mid-string, appends suffix). The new extractAssistantResponse() handles this:

  1. Fast path: JSON.parse for non-truncated input
  2. Fallback: substring extraction from the fixed JSON prefix + JSON unescape
  3. Stored truncated to 1000 chars

Schema caveats — updated _getSchemaDescription() local branch to warn the LLM that:

  • agent_name / agent_description may be empty for older sessions
  • summary may contain raw JSON — prefer JOINing with turns.user_message
  • assistant_response may be empty for older sessions
  • session_files / session_refs may be empty for older sessions

What's NOT fixed (remaining from #312292)

  • agent_name population — the code reads GenAiAttr.AGENT_NAME from spans but this attribute may not be set by all producers
  • agent_description — no known source for this field
  • summary containing raw JSON — requires changes to the summarization pipeline
  • session_files / session_refs empty — file/ref tracking was added but may need producer-side work

Testing

  • 9 new test cases in extractAssistantResponse.spec.ts (valid JSON, truncated JSON, JSON escape handling, edge cases)
  • All chronicle tests pass, TypeScript compiles clean

Partially addresses #312292

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes missing data in the Chronicle local session store by (1) populating sessions.cwd at session initialization and (2) reliably extracting/storing turns.assistant_response from gen_ai.output.messages, including when that attribute has been truncated by truncateForOTel. It also updates the Chronicle intent’s local SQLite schema description so LLM-driven queries better match what’s actually stored.

Changes:

  • Populate sessions.cwd from vscode.workspace.workspaceFolders?.[0] during session initialization.
  • Replace JSON-parse-only assistant response extraction with extractAssistantResponse() that supports truncated OTel JSON payloads, and store a truncated (~1000 char) value in turns.assistant_response.
  • Add Vitest coverage for extractAssistantResponse() across valid JSON, truncated JSON, and escaping edge cases.
Show a summary per file
File Description
extensions/copilot/src/extension/intents/node/chronicleIntent.ts Updates the local SQLite schema description for cwd and assistant_response.
extensions/copilot/src/extension/chronicle/vscode-node/sessionStoreTracker.ts Sets cwd at session init; extracts and stores truncated assistant responses on turns.
extensions/copilot/src/extension/chronicle/common/test/extractAssistantResponse.spec.ts Adds unit tests covering assistant response extraction, including truncated OTel JSON.
extensions/copilot/src/extension/chronicle/common/sessionStoreTracking.ts Introduces extractAssistantResponse() with a fallback path for truncateForOTel-truncated JSON.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 2

Comment on lines +175 to +186
// Fallback: extract text from truncated JSON via substring.
// The JSON prefix is fixed: [{"role":"assistant","parts":[{"type":"text","content":"
// which is 63 chars. The content value follows, terminated by the truncation marker.
if (!outputMessagesRaw.includes(OTEL_TRUNCATION_MARKER)) {
return undefined;
}
const contentPrefix = '"content":"';
const contentStart = outputMessagesRaw.indexOf(contentPrefix);
if (contentStart === -1) {
return undefined;
}
const textStart = contentStart + contentPrefix.length;
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The truncated-JSON fallback doesn’t actually use the “fixed prefix” it documents (including the hard-coded 63-char note), and it searches for the first occurrence of "content": which can diverge from the fast-path behavior (fast path only returns parts where type === 'text'). Consider anchoring the fallback to the same structure as the expected OTel output (e.g. locate the "role":"assistant" + "type":"text" + "content":" sequence, then terminate at the truncation suffix), and drop/update the misleading fixed-length comment so future changes don’t accidentally break extraction.

Suggested change
// Fallback: extract text from truncated JSON via substring.
// The JSON prefix is fixed: [{"role":"assistant","parts":[{"type":"text","content":"
// which is 63 chars. The content value follows, terminated by the truncation marker.
if (!outputMessagesRaw.includes(OTEL_TRUNCATION_MARKER)) {
return undefined;
}
const contentPrefix = '"content":"';
const contentStart = outputMessagesRaw.indexOf(contentPrefix);
if (contentStart === -1) {
return undefined;
}
const textStart = contentStart + contentPrefix.length;
// Fallback: extract text from truncated JSON by matching the serialized
// assistant text-part prefix, then reading until the truncation marker.
if (!outputMessagesRaw.includes(OTEL_TRUNCATION_MARKER)) {
return undefined;
}
const assistantTextContentPrefix = '"role":"assistant","parts":[{"type":"text","content":"';
const prefixStart = outputMessagesRaw.indexOf(assistantTextContentPrefix);
if (prefixStart === -1) {
return undefined;
}
const textStart = prefixStart + assistantTextContentPrefix.length;

Copilot uses AI. Check for mistakes.
- **sessions**: id, cwd, repository, branch, summary, host_type, agent_name (who created the session, e.g. 'vscode', 'cli', 'CCA', 'CCR'), agent_description, created_at, updated_at
- **turns**: session_id, turn_index, user_message, assistant_response, timestamp. The richest source of what actually happened — contains the user's prompts and the assistant's replies.
- **sessions**: id, cwd (workspace folder path), repository, branch, summary, host_type, agent_name (who created the session, e.g. 'vscode', 'cli', 'CCA', 'CCR'), agent_description, created_at, updated_at
- **turns**: session_id, turn_index, user_message, assistant_response (truncated to ~1000 chars — a summary of the assistant's reply, not the full response), timestamp. The richest source of what actually happened — contains the user's prompts and the assistant's replies.
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local schema description says assistant_response is “a summary of the assistant’s reply”, but the implementation stores a truncated prefix (first ~1000 chars + optional ellipsis), which may cut mid-sentence and isn’t a true summary. To avoid misleading the model when it writes queries/interpretations, consider rewording this to something like “first ~1000 characters of the assistant reply” (and mention the ellipsis behavior if relevant).

Suggested change
- **turns**: session_id, turn_index, user_message, assistant_response (truncated to ~1000 chars a summary of the assistant's reply, not the full response), timestamp. The richest source of what actually happened — contains the user's prompts and the assistant's replies.
- **turns**: session_id, turn_index, user_message, assistant_response (first ~1000 characters of the assistant reply, with an ellipsis if truncated not the full response), timestamp. The richest source of what actually happened contains the user's prompts and the assistant's replies.

Copilot uses AI. Check for mistakes.
@digitarald digitarald force-pushed the fix/chronicle-cwd-assistant-response branch from 33b91e1 to ba5336a Compare April 24, 2026 04:30
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