Views
No views yet
1import time
2import difflib
3from transformers import AutoTokenizer, Qwen2ForCausalLM
4import torch
5
6# Load model and tokenizer
7model_id = "Xenova/sweep-next-edit-1.5B"
8
9print("Loading tokenizer...")
10tokenizer = AutoTokenizer.from_pretrained(model_id)
11
12print("Loading model...")
13model = Qwen2ForCausalLM.from_pretrained(model_id, device_map="auto")
14
15
16def build_prompt(
17 context_files: dict[str, str],
18 recent_diffs: list[dict[str, str]],
19 file_path: str,
20 original_content: str,
21 current_content: str,
22) -> str:
23 """
24 Build a prompt following Sweep Next Edit's training format.
25
26 Format:
27 <|file_sep|>{file_path_1}
28 {file_content_1}
29 <|file_sep|>{file_path_2}
30 {file_content_2}
31 <|file_sep|>{changed_file_1}.diff
32 original:
33 {before_changes_of_diff}
34 updated:
35 {after_changes_of_diff}
36 <|file_sep|>original/{file_path}
37 {contents_prior_to_most_recent_change}
38 <|file_sep|>current/{file_path}
39 {current_state_of_contents}
40 <|file_sep|>updated/{file_path}
41 {updated_state_of_contents}
42
43 Args:
44 context_files: Dict mapping file paths to their contents (related files for context)
45 recent_diffs: List of dicts with 'file_path', 'original', and 'updated' keys
46 file_path: Path of the file being edited
47 original_content: Contents prior to most recent change
48 current_content: Current state of the file being edited
49
50 Returns:
51 Formatted prompt string
52 """
53 prompt_parts = []
54
55 # Add context files
56 for path, content in context_files.items():
57 prompt_parts.append(f"<|file_sep|>{path}")
58 prompt_parts.append(content)
59
60 # Add recent diffs
61 for diff in recent_diffs:
62 prompt_parts.append(f"<|file_sep|>{diff['file_path']}.diff")
63 prompt_parts.append("original:")
64 prompt_parts.append(diff['original'])
65 prompt_parts.append("updated:")
66 prompt_parts.append(diff['updated'])
67
68 # Add original and current states
69 prompt_parts.append(f"<|file_sep|>original/{file_path}")
70 prompt_parts.append(original_content)
71 prompt_parts.append(f"<|file_sep|>current/{file_path}")
72 prompt_parts.append(current_content)
73 prompt_parts.append(f"<|file_sep|>updated/{file_path}")
74
75 return "\n".join(prompt_parts)
76
77
78def generate(prompt: str, max_new_tokens: int = 512) -> str:
79 """Generate completion using the Sweep Next Edit model."""
80 inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
81
82 # Get the stop token ids
83 stop_token_ids = [
84 tokenizer.convert_tokens_to_ids("<|file_sep|>"),
85 tokenizer.eos_token_id,
86 ]
87
88 with torch.no_grad():
89 outputs = model.generate(
90 **inputs,
91 max_new_tokens=max_new_tokens,
92 do_sample=False, # Use greedy decoding for deterministic output
93 pad_token_id=tokenizer.pad_token_id,
94 eos_token_id=stop_token_ids,
95 )
96
97 # Decode only the generated tokens (exclude the prompt)
98 generated_ids = outputs[0][inputs["input_ids"].shape[1]:]
99 generated_text = tokenizer.decode(generated_ids, skip_special_tokens=True)
100
101 return generated_text
102
103
104if __name__ == "__main__":
105 # Simple example: User is writing a greeting function
106 # The model predicts what they'll write next based on the pattern
107
108 file_path = "greet.py"
109
110 # Context: Other files in the codebase
111 context_files = {
112 "utils.py": """def get_time_of_day():
113 from datetime import datetime
114 hour = datetime.now().hour
115 if hour < 12:
116 return "morning"
117 elif hour < 18:
118 return "afternoon"
119 else:
120 return "evening"
121""",
122 }
123
124 # Recent changes: User just added a personalized greeting
125 recent_diffs = [
126 {
127 "file_path": "greet.py",
128 "original": """def greet():
129 print("Hello!")""",
130 "updated": """def greet(name):
131 print(f"Hello, {name}!")""",
132 }
133 ]
134
135 # Before the most recent change
136 original_content = """def greet(name):
137 print(f"Hello, {name}!")
138
139greet("Alice")"""
140
141 # Current state: User just imported get_time_of_day
142 current_content = """from utils import get_time_of_day
143
144def greet(name):
145 print(f"Hello, {name}!")
146
147greet("Alice")"""
148
149 prompt = build_prompt(
150 context_files=context_files,
151 recent_diffs=recent_diffs,
152 file_path=file_path,
153 original_content=original_content,
154 current_content=current_content,
155 )
156
157 print("\n" + "=" * 80)
158 print("CURRENT CODE:")
159 print("=" * 80)
160 print(current_content)
161
162 print("\nGenerating prediction...")
163 start_time = time.time()
164 predicted_edit = generate(prompt)
165 end_time = time.time()
166
167 print("\n" + "=" * 80)
168 print("PREDICTED NEXT EDIT:")
169 print("=" * 80)
170 print(predicted_edit)
171
172 print("\n" + "=" * 80)
173 print(f"TIME TAKEN: {end_time - start_time:.2f} seconds")
174 print("=" * 80)
175
176 print("\n" + "=" * 80)
177 print("DIFF (what changed):")
178 print("=" * 80)
179
180 diff = difflib.unified_diff(
181 current_content.splitlines(keepends=True),
182 predicted_edit.splitlines(keepends=True),
183 fromfile=f"current/{file_path}",
184 tofile=f"updated/{file_path}",
185 lineterm=""
186 )
187 print("".join(diff))