1"""SFT training format converters for ll-messages --sft-format output."""

2

3 from __future__ import annotations

4

5

6 def to_chatml(turns: list[tuple[str, str]]) -> dict:

7 """Convert conversation turns to ChatML format.

8

9 Args:

10 turns: List of (role, content) pairs where role is "user" or "assistant"

11

12 Returns:

13 Dict with "messages" list of {"role": ..., "content": ...} objects

14 """

15 return {"messages": [{"role": role, "content": content} for role, content in turns]}

16

17

18 def to_alpaca(turns: list[tuple[str, str]]) -> dict:

19 """Convert conversation turns to Alpaca format.

20

21 Maps the first user turn to "instruction", all subsequent user turns to "input",

22 and the last assistant turn to "output".

23

24 Args:

25 turns: List of (role, content) pairs where role is "user" or "assistant"

26

27 Returns:

28 Dict with "instruction", "input", and "output" keys

29 """

30 user_turns = [content for role, content in turns if role == "user"]

31 assistant_turns = [content for role, content in turns if role == "assistant"]

32

33 instruction = user_turns[0] if user_turns else ""

34 input_text = "\n\n".join(user_turns[1:]) if len(user_turns) > 1 else ""

35 output = assistant_turns[-1] if assistant_turns else ""

36

37 return {"instruction": instruction, "input": input_text, "output": output}

38

39

40 def to_sharegpt(turns: list[tuple[str, str]]) -> dict:

41 """Convert conversation turns to ShareGPT format.

42

43 Maps "user" role to "human" and "assistant" role to "gpt".

44

45 Args:

46 turns: List of (role, content) pairs where role is "user" or "assistant"

47

48 Returns:

49 Dict with "conversations" list of {"from": ..., "value": ...} objects

50 """

51 role_map = {"user": "human", "assistant": "gpt"}

52 return {

53 "conversations": [

54 {"from": role_map.get(role, role), "value": content} for role, content in turns

55 ]

56 }