Views
No views yet
<DONE>. Pretrained on 2B tokens (70% Flutter/Dart code, 30% English text), then fine-tuned on 50M tokens of step-sequence examples (bbidpa/flutter-diff-steps-v1).1from transformers import AutoModelForCausalLM, AutoTokenizer
2import torch
3
4REPO = "bbidpa/Rainbow-Pony-100m-Flutter-steps"
5DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
6
7tokenizer = AutoTokenizer.from_pretrained(REPO)
8tokenizer.bos_id = tokenizer.bos_token_id
9tokenizer.eos_id = tokenizer.eos_token_id
10tokenizer.pad_id = tokenizer.pad_token_id
11tokenizer.unk_id = tokenizer.unk_token_id
12tokenizer.sep_id = tokenizer.convert_tokens_to_ids("<sep>")
13
14model = AutoModelForCausalLM.from_pretrained(REPO, trust_remote_code=True).to(DEVICE).eval()-direct model, but here <HISTORY> is the whole point — it accumulates prior <ACTION> entries as the loop progresses, and <CODE> reflects the file's state after those prior steps:<GOAL>
Add TextEditingControllers for the email and password fields, connect them to their respective TextFields, implement a _submit method that displays the entered email and password length in a SnackBar, and add spacing above the login button.
</GOAL>
<CODE>
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: Scaffold(body: Center(child: EmailInputForm()))));
</CODE>
<HISTORY>
<ACTION><TYPE>add_widget</TYPE><DESC>Add a SizedBox widget for vertical spacing.</DESC></ACTION>
</HISTORY>
<OUTPUT><ACTION><TYPE>...</TYPE><DESC>...</DESC></ACTION>
<CHANGES>
<HUNK>
<SEARCH>
...
</SEARCH>
<REPLACE>
...
</REPLACE>
</HUNK>
</CHANGES><DONE></DONE> on the final step.1def render_step_prompt_from_data(
2 goal: str,
3 code: str = "",
4 history: list[dict] | None = None,
5 action_type: str = "",
6 action_desc: str = "",
7 changes: list[dict] | None = None,
8 is_last_step: bool = False,
9 include_output: bool = False,
10) -> str:
11 history = history or []
12 changes = changes or []
13 history_text = "\n".join(
14 f"<ACTION><TYPE>{h['type']}</TYPE><DESC>{h['desc']}</DESC></ACTION>"
15 for h in history
16 )
17 text = f"""<GOAL>
18{goal}
19</GOAL>
20
21<CODE>
22{code}
23</CODE>
24
25<HISTORY>
26{history_text}
27</HISTORY>
28
29<OUTPUT>
30"""
31 if include_output:
32 hunks = "\n".join(
33 f"<HUNK>\n<SEARCH>\n{h['search']}\n</SEARCH>\n<REPLACE>\n{h['replace']}\n</REPLACE>\n</HUNK>"
34 for h in changes
35 )
36 output = f"<ACTION><TYPE>{action_type}</TYPE><DESC>{action_desc}</DESC></ACTION>\n<CHANGES>\n{hunks}\n</CHANGES>"
37 if is_last_step:
38 output += "\n<DONE></DONE>"
39 text += output + "\n</OUTPUT>"
40 return text
41
42
43def generate_output(model, tokenizer, device, prompt, max_new_tokens=300, **generate_kwargs):
44 prompt_ids = tokenizer.encode(prompt, add_special_tokens=False)
45 idx = torch.tensor([[tokenizer.bos_id] + prompt_ids], dtype=torch.long).to(device)
46 generated = model.generate(idx, max_new_tokens=max_new_tokens, eos_id=tokenizer.eos_id, **generate_kwargs)
47 text = tokenizer.decode(generated[0].tolist(), skip_special_tokens=False)
48 return text.split("<OUTPUT>")[-1].split("</OUTPUT>")[0].strip()<DONE>, the meaningful way to run it is the multi-step loop (parses each step's <ACTION>/<CHANGES>, applies the diff, appends to history, and continues):1result = run_step_sequence(
2 model, tokenizer, DEVICE,
3 goal="Write a widget that displays a select button with months in it",
4 code="",
5 history=[],
6 max_steps=20,
7 max_new_tokens=300,
8)
9print(result["final_code"])
10print(result["stop_reason"])run_step_sequence depends on a few more helpers (generate_output_data, parse_generated_output, apply_edit/apply_edit_with_fallback) that parse the tag-structured output and apply each hunk — see finetune_utils.py for the full implementation.[step 1] add_import: Add the import statement for flutter/material.dart (1 hunk)
[step 1] code:
import 'package:flutter/material.dart';
-------------------------------------------
[step 2] add_class: Add the DatePicker class declaration with its createState method. (1 hunk)
[step 2] code:
import 'package:flutter/material.dart';
class DatePicker extends StatefulWidget {
@override
_DatePickerState createState() => _DatePickerState();
}
-------------------------------------------
[step 3] add_class: Add the _DatePickerState class with an empty body. (1 hunk)
[step 3] code:
import 'package:flutter/material.dart';
class DatePicker extends StatefulWidget {
@override
_DatePickerState createState() => _DatePickerState();
}
class _DatePickerState extends State<DatePicker> {
}
-------------------------------------------
[step 4] add_method: Add the build method with a Column widget returning empty children list. (1 hunk)
[step 4] code:
import 'package:flutter/material.dart';
class DatePicker extends StatefulWidget {
@override
_DatePickerState createState() => _DatePickerState();
}
class _DatePickerState extends State<DatePicker> {
@override
Widget build(BuildContext context) {
return Column(
children: [],
);
}
}
-------------------------------------------
[step 5] add_widget: Add a Row widget with mainAxisAlignment and empty children list inside the Column's children list. (1 hunk)
[step 5] code:
import 'package:flutter/material.dart';
class DatePicker extends StatefulWidget {
@override
_DatePickerState createState() => _DatePickerState();
}
class _DatePickerState extends State<DatePicker> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
],
),
],
);
}
}
-------------------------------------------
[step 6] hunk 1/1 SEARCH matched 2 times -- using last occurrence
FALLBACK
[step 6] add_widget: Add the ElevatedButton widget with onPressed and child Text('Select Date') inside the Row's children list. (1 hunk)
[step 6] code:
import 'package:flutter/material.dart';
class DatePicker extends StatefulWidget {
@override
_DatePickerState createState() => _DatePickerState();
}
class _DatePickerState extends State<DatePicker> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
],
),
],
);
}
}
-------------------------------------------
[step 7] hunk 1/1 SEARCH matched 4 times -- using last occurrence
FALLBACK
[step 7] add_widget: Add the last ElevatedButton widget with onPressed and child Text('Select Date') to the Row's children list. (1 hunk)
[step 7] code:
import 'package:flutter/material.dart';
class DatePicker extends StatefulWidget {
@override
_DatePickerState createState() => _DatePickerState();
}
class _DatePickerState extends State<DatePicker> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
],
),
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
],
);
}
}
-------------------------------------------
[step 8] hunk 1/1 SEARCH matched 2 times -- using last occurrence
FALLBACK
[step 8] add_widget: Add the SizedBox(height: 10) widget between the ElevatedButton and the Text widgets in the Row. (1 hunk)
[step 8] code:
import 'package:flutter/material.dart';
class DatePicker extends StatefulWidget {
@override
_DatePickerState createState() => _DatePickerState();
}
class _DatePickerState extends State<DatePicker> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
],
),
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
SizedBox(height: 10),
],
);
}
}
-------------------------------------------
[step 9] add_method: Add the _selectDate method with date picker logic. (1 hunk)
[step 9] code:
import 'package:flutter/material.dart';
class DatePicker extends StatefulWidget {
@override
_DatePickerState createState() => _DatePickerState();
}
class _DatePickerState extends State<DatePicker> {
void _selectDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2100),
);
if (picked != null) {
setState(() {
// _selectedDate = picked;
});
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
],
),
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
SizedBox(height: 10),
],
);
}
}
-------------------------------------------
[step 10] add_field: Add the field '_selectedDate' to the state class. (1 hunk)
[step 10] code:
import 'package:flutter/material.dart';
class DatePicker extends StatefulWidget {
@override
_DatePickerState createState() => _DatePickerState();
}
class _DatePickerState extends State<DatePicker> {
DateTime? _selectedDate;
void _selectDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2100),
);
if (picked != null) {
setState(() {
// _selectedDate = picked;
});
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
],
),
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
SizedBox(height: 10),
],
);
}
}
-------------------------------------------
FALLBACK
[step 11] add_field: Add the field '_monthController' declaration line.
[step 11] APPLY FAILED on hunk 3/4 -- Search must match exactly once, got 0: '// _selectedDate = picked;'
[step 11] all generated hunks this step:
hunk 1
SEARCH:
class _DatePickerState extends State<DatePicker> {
REPLACE:
class _DatePickerState extends State<DatePicker> {
final _monthController = TextEditingController();
hunk 2
SEARCH:
// _selectedDate = picked;
REPLACE:
_selectedDate = picked;
hunk 3 <-- FAILED
SEARCH:
// _selectedDate = picked;
REPLACE:
_selectedDate = picked;
hunk 4
SEARCH:
onPressed: () => _selectDate(context),
child: Text('Select Date'),
REPLACE:
onPressed: () => _selectDate(context),
child: Text(_monthController.text),
[step 11] code the failed SEARCH was matched against:
import 'package:flutter/material.dart';
class DatePicker extends StatefulWidget {
@override
_DatePickerState createState() => _DatePickerState();
}
class _DatePickerState extends State<DatePicker> {
final _monthController = TextEditingController();
DateTime? _selectedDate;
void _selectDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2100),
);
if (picked != null) {
setState(() {
_selectedDate = picked;
});
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
],
),
ElevatedButton(
onPressed: () => _selectDate(context),
child: Text('Select Date'),
),
SizedBox(height: 10),
],
);
}
}
| Architecture | 100M-parameter decoder-only transformer, trained from scratch |
| Pretraining | 2B tokens (70% Flutter/Dart code, 30% English text) |
| Fine-tuning | 50M tokens, multi-step goal → history → diff sequences |
| Tokenizer | Custom 16k-vocab BPE + structural special tokens |