Parse the intermidate prompt template, and wrap it with meta template if applicable. When the meta template is set and the input is a PromptList, the return value will be a PromptList containing the full conversation history. Each item looks like: .. code-block:: pyt
(self, prompt_template: PromptType,
mode: str)
| 191 | self.roles[item['role']] = item.copy() |
| 192 | |
| 193 | def parse_template(self, prompt_template: PromptType, |
| 194 | mode: str) -> PromptType: |
| 195 | """Parse the intermidate prompt template, and wrap it with meta |
| 196 | template if applicable. When the meta template is set and the input is |
| 197 | a PromptList, the return value will be a PromptList containing the full |
| 198 | conversation history. Each item looks like: |
| 199 | |
| 200 | .. code-block:: python |
| 201 | |
| 202 | {'role': 'user', 'prompt': '...'}). |
| 203 | |
| 204 | Args: |
| 205 | prompt_template (List[PromptType]): An intermidate prompt |
| 206 | template (potentially before being wrapped by meta template). |
| 207 | mode (str): Parsing mode. Choices are 'ppl' and 'gen'. |
| 208 | |
| 209 | Returns: |
| 210 | List[PromptType]: The finalized prompt or a conversation. |
| 211 | """ |
| 212 | assert isinstance(prompt_template, (str, list, PromptList, tuple)) |
| 213 | |
| 214 | if not isinstance(prompt_template, (str, PromptList)): |
| 215 | return [self.parse_template(p, mode=mode) for p in prompt_template] |
| 216 | |
| 217 | assert mode in ['ppl', 'gen'] |
| 218 | if isinstance(prompt_template, str): |
| 219 | return prompt_template |
| 220 | if self.meta_template: |
| 221 | |
| 222 | prompt = PromptList() |
| 223 | # Whether to keep generating the prompt |
| 224 | generate = True |
| 225 | |
| 226 | section_stack = [] # stores tuples: (section_name, start_idx) |
| 227 | |
| 228 | for i, item in enumerate(prompt_template): |
| 229 | if not generate: |
| 230 | break |
| 231 | if isinstance(item, str): |
| 232 | if item.strip(): |
| 233 | # TODO: logger |
| 234 | warnings.warn('Non-empty string in prompt template ' |
| 235 | 'will be ignored in API models.') |
| 236 | elif isinstance(item, dict) and 'section' in item: |
| 237 | if item['pos'] == 'end': |
| 238 | section_name, start_idx = section_stack.pop(-1) |
| 239 | assert section_name == item['section'] |
| 240 | if section_name in ['round', 'ice']: |
| 241 | dialogue = prompt_template[start_idx:i] |
| 242 | round_ranges = self._split_rounds( |
| 243 | dialogue, self.meta_template['round']) |
| 244 | # Consider inserting multiple round examples into |
| 245 | # template |
| 246 | for i in range(len(round_ranges) - 1): |
| 247 | start = round_ranges[i] |
| 248 | end = round_ranges[i + 1] |
| 249 | round_template = dialogue[start:end] |
| 250 | role_dict = self._update_role_dict( |