yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Harsh Aggarwal (NVIDIA)Bring back hooks for auto formatting and ensure build works (#7811)2d775b54d

master
4.6 KiB120 linesraw
1#!/usr/bin/env python3
2
3import argparse
4import json
5import os
6import sys
7
8
9def parse_transcript_for_todos(transcript_path):
10    """Parse transcript to find the last TodoWrite and check if all todos are completed."""
11    if not os.path.exists(transcript_path):
12        return True  # If no transcript, assume OK to proceed
13
14    try:
15        last_todo_write = None
16
17        # Read .jsonl file and find the last TodoWrite
18        with open(transcript_path, "r") as f:
19            for line in f:
20                line = line.strip()
21                if line:
22                    try:
23                        entry = json.loads(line)
24                        # Check if this is an assistant message with TodoWrite tool use
25                        if (
26                            entry.get("type") == "assistant"
27                            and "message" in entry
28                            and "content" in entry["message"]
29                        ):
30                            content = entry["message"]["content"]
31                            if isinstance(content, list):
32                                for item in content:
33                                    if (
34                                        isinstance(item, dict)
35                                        and item.get("type") == "tool_use"
36                                        and item.get("name") == "TodoWrite"
37                                        and "input" in item
38                                        and "todos" in item["input"]
39                                    ):
40                                        last_todo_write = item["input"]["todos"]
41                    except json.JSONDecodeError:
42                        continue  # Skip invalid lines
43
44        # If no TodoWrite found, assume OK to proceed
45        if not last_todo_write:
46            return True
47
48        # Check if all todos are completed
49        incomplete_todos = []
50        for todo in last_todo_write:
51            if todo.get("status") != "completed":
52                incomplete_todos.append(todo)
53
54        return len(incomplete_todos) == 0, incomplete_todos
55
56    except Exception:
57        # If any error occurs during parsing, assume OK to proceed
58        return True
59
60
61def main():
62    try:
63        # Parse command line arguments
64        parser = argparse.ArgumentParser()
65        parser.add_argument(
66            "--validate",
67            action="store_true",
68            help="Validate that all todos are completed before allowing stop",
69        )
70        args = parser.parse_args()
71
72        # Read JSON input from stdin
73        input_data = json.load(sys.stdin)
74
75        # Extract required fields
76        session_id = input_data.get("session_id", "")
77        stop_hook_active = input_data.get("stop_hook_active", False)
78
79        # Handle --validate switch
80        if args.validate and "transcript_path" in input_data:
81            transcript_path = input_data["transcript_path"]
82            validation_result = parse_transcript_for_todos(transcript_path)
83
84            # Check if validation returned a tuple (incomplete todos found)
85            if isinstance(validation_result, tuple):
86                all_complete, incomplete_todos = validation_result
87                if not all_complete:
88                    # Create a detailed message about incomplete todos
89                    incomplete_items = []
90                    for todo in incomplete_todos:
91                        status = todo.get("status", "unknown")
92                        content = todo.get("content", "unknown task")
93                        incomplete_items.append(f"- {content} ({status})")
94
95                    incomplete_list = "\n".join(incomplete_items)
96                    reason = f"Tasks are not yet complete. Please finish the following todos:\n{incomplete_list}\n\nUse TodoWrite to mark tasks as completed when finished."
97
98                    # Return JSON decision to block stopping
99                    output = {"decision": "block", "reason": reason}
100                    print(json.dumps(output))
101                    sys.exit(0)
102            elif not validation_result:
103                # Single boolean returned as False
104                reason = "Tasks are not yet complete. Please finish all todos before stopping. Use TodoWrite to mark tasks as completed when finished."
105                output = {"decision": "block", "reason": reason}
106                print(json.dumps(output))
107                sys.exit(0)
108
109        sys.exit(0)
110
111    except json.JSONDecodeError:
112        # Handle JSON decode errors gracefully
113        sys.exit(0)
114    except Exception:
115        # Handle any other errors gracefully
116        sys.exit(0)
117
118
119if __name__ == "__main__":
120    main()