Created
November 20, 2025 03:22
-
-
Save xbalajipge/9e3dfaa023ac156a94682fdd12a4b345 to your computer and use it in GitHub Desktop.
extract_chat.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #! /usr/bin/env python3 | |
| import json | |
| import argparse | |
| from pathlib import Path | |
| def extract_chat_to_markdown(json_file_path: str, output_file_path: str): | |
| """ | |
| Extract chat prompts and responses from a Copilot chat JSON file and save as markdown. | |
| Args: | |
| json_file_path: Path to the input JSON file | |
| output_file_path: Path to the output markdown file | |
| """ | |
| try: | |
| # Read the JSON file | |
| with open(json_file_path, 'r', encoding='utf-8') as f: | |
| data = json.load(f) | |
| # Open markdown file for writing | |
| with open(output_file_path, 'w', encoding='utf-8') as md_file: | |
| md_file.write("# GitHub Copilot Chat History\n\n") | |
| # Iterate through each request in the session | |
| for idx, request in enumerate(data.get('requests', []), 1): | |
| # Extract user message | |
| message = request.get('message', {}) | |
| user_text = message.get('text', '') | |
| # Extract model information | |
| model_id = request.get('modelId', 'Unknown') | |
| result_details = request.get('result', {}).get('details', '') | |
| # Write exchange header with model info | |
| md_file.write(f"## Exchange {idx}\n\n") | |
| md_file.write(f"**Model**: {model_id}") | |
| if result_details: | |
| md_file.write(f" ({result_details})") | |
| md_file.write("\n\n") | |
| # Write user prompt | |
| md_file.write(f"### User Prompt\n\n") | |
| md_file.write(f"{user_text}\n\n") | |
| # Extract and write response | |
| md_file.write(f"### Copilot Response\n\n") | |
| response_parts = request.get('response', []) | |
| for part in response_parts: | |
| # Handle different response part types | |
| if isinstance(part, dict): | |
| if 'value' in part: | |
| # Replace literal \n strings with actual newlines | |
| text = part['value'].replace('\\n', '\n') | |
| md_file.write(text) | |
| elif part.get('kind') == 'inlineReference': | |
| # Handle inline references (file paths, etc.) | |
| ref = part.get('inlineReference', {}) | |
| if isinstance(ref, dict) and 'fsPath' in ref: | |
| path = Path(ref['fsPath']).name | |
| md_file.write(f"`{path}`") | |
| elif isinstance(ref, dict) and 'name' in ref: | |
| md_file.write(f"`{ref['name']}`") | |
| md_file.write("\n\n---\n\n") | |
| print(f"✓ Chat history successfully extracted to {output_file_path}") | |
| except FileNotFoundError: | |
| print(f"✗ Error: Input file '{json_file_path}' not found") | |
| return 1 | |
| except json.JSONDecodeError: | |
| print(f"✗ Error: Invalid JSON format in '{json_file_path}'") | |
| return 1 | |
| except Exception as e: | |
| print(f"✗ Error: {str(e)}") | |
| return 1 | |
| return 0 | |
| def main(): | |
| parser = argparse.ArgumentParser( | |
| description='Extract GitHub Copilot chat history from JSON to Markdown format', | |
| formatter_class=argparse.RawDescriptionHelpFormatter, | |
| epilog=""" | |
| How to export chat from VS Code: | |
| Use Ctrl+Shift+P | Chat: Export Session... | |
| Or: View > Command Palette | Chat: Export Session... | |
| To import a chat session: | |
| Use Ctrl+Shift+P | Chat: Import Session... | |
| Or: View > Command Palette | Chat: Import Session... | |
| Examples: | |
| %(prog)s -i chat.json -o output.md | |
| %(prog)s --infile copilot-chat.json --outfile history.md | |
| """ | |
| ) | |
| parser.add_argument( | |
| '-i', '--infile', | |
| required=True, | |
| help='Path to the input JSON file containing Copilot chat history' | |
| ) | |
| parser.add_argument( | |
| '-o', '--outfile', | |
| default='extracted.md', | |
| help='Path to the output Markdown file (default: extracted.md)' | |
| ) | |
| parser.add_argument( | |
| '-v', '--version', | |
| action='version', | |
| version='%(prog)s 1.0' | |
| ) | |
| args = parser.parse_args() | |
| return extract_chat_to_markdown(args.infile, args.outfile) | |
| if __name__ == "__main__": | |
| exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment