We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Improve phrase history mechanism
instead of this:

https://github.com/knausj85/knausj_talon/blob/3e57e0165257cf07b0e21880d44a91e79cb3ef16/code/history.py#L19-L29

consider something like this:

```py
def on_phrase(j):
    global history
    words = j.get('text')
    if words:
        text = ' '.join(words)
        history.append(text)
        history = history[-setting_command_history_size.get() :]
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `code/history.py`
Content:
```
1 from talon import imgui, Module, speech_system, actions, app
2 
3 # We keep command_history_size lines of history, but by default display only
4 # command_history_display of them.
5 mod = Module()
6 setting_command_history_size = mod.setting("command_history_size", int, default=50)
7 setting_command_history_display = mod.setting(
8     "command_history_display", int, default=10
9 )
10 
11 hist_more = False
12 history = []
13 
14 
15 def parse_phrase(word_list):
16     return " ".join(word.split("\\")[0] for word in word_list)
17 
18 
19 def on_phrase(j):
20     global history
21 
22     try:
23         val = parse_phrase(getattr(j["parsed"], "_unmapped", j["phrase"]))
24     except:
25         val = parse_phrase(j["phrase"])
26 
27     if val != "":
28         history.append(val)
29         history = history[-setting_command_history_size.get() :]
30 
31 
32 # todo: dynamic rect?
33 @imgui.open(y=0)
34 def gui(gui: imgui.GUI):
35     global history
36     gui.text("Command History")
37     gui.line()
38     text = (
39         history[:] if hist_more else history[-setting_command_history_display.get() :]
40     )
41     for line in text:
42         gui.text(line)
43 
44     gui.spacer()
45     if gui.button("Command history close"):
46         actions.user.history_disable()
47 
48 
49 speech_system.register("phrase", on_phrase)
50 
51 
52 @mod.action_class
53 class Actions:
54     def history_toggle():
55         """Toggles viewing the history"""
56         if gui.showing:
57             gui.hide()
58         else:
59             gui.show()
60 
61     def history_enable():
62         """Enables the history"""
63         gui.show()
64 
65     def history_disable():
66         """Disables the history"""
67         gui.hide()
68 
69     def history_clear():
70         """Clear the history"""
71         global history
72         history = []
73 
74     def history_more():
75         """Show more history"""
76         global hist_more
77         hist_more = True
78 
79     def history_less():
80         """Show less history"""
81         global hist_more
82         hist_more = False
83 
84     def history_get(number: int):
85         """returns the history entry at the specified index"""
86         num = (0 - number) - 1
87         return history[num]
88
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/code/history.py b/code/history.py
--- a/code/history.py
+++ b/code/history.py
@@ -1,3 +1,4 @@
+from typing import Optional
 from talon import imgui, Module, speech_system, actions, app
 
 # We keep command_history_size lines of history, but by default display only
@@ -12,20 +13,15 @@
 history = []
 
 
-def parse_phrase(word_list):
-    return " ".join(word.split("\\")[0] for word in word_list)
-
-
 def on_phrase(j):
     global history
 
-    try:
-        val = parse_phrase(getattr(j["parsed"], "_unmapped", j["phrase"]))
-    except:
-        val = parse_phrase(j["phrase"])
+    words = j.get('text')
+
+    text = actions.user.history_transform_phrase_text(words)
 
-    if val != "":
-        history.append(val)
+    if text is not None:
+        history.append(text)
         history = history[-setting_command_history_size.get() :]
 
 
@@ -85,3 +81,11 @@
         """returns the history entry at the specified index"""
         num = (0 - number) - 1
         return history[num]
+
+    def history_transform_phrase_text(words: list[str]) -> Optional[str]:
+        """Transforms phrase text for presentation in history. Return `None` to omit from history"""
+
+        if not actions.speech.enabled():
+            return None
+
+        return ' '.join(words) if words else None
\ No newline at end of file

{"golden_diff": "diff --git a/code/history.py b/code/history.py\n--- a/code/history.py\n+++ b/code/history.py\n@@ -1,3 +1,4 @@\n+from typing import Optional\n from talon import imgui, Module, speech_system, actions, app\n \n # We keep command_history_size lines of history, but by default display only\n@@ -12,20 +13,15 @@\n history = []\n \n \n-def parse_phrase(word_list):\n-    return \" \".join(word.split(\"\\\\\")[0] for word in word_list)\n-\n-\n def on_phrase(j):\n     global history\n \n-    try:\n-        val = parse_phrase(getattr(j[\"parsed\"], \"_unmapped\", j[\"phrase\"]))\n-    except:\n-        val = parse_phrase(j[\"phrase\"])\n+    words = j.get('text')\n+\n+    text = actions.user.history_transform_phrase_text(words)\n \n-    if val != \"\":\n-        history.append(val)\n+    if text is not None:\n+        history.append(text)\n         history = history[-setting_command_history_size.get() :]\n \n \n@@ -85,3 +81,11 @@\n         \"\"\"returns the history entry at the specified index\"\"\"\n         num = (0 - number) - 1\n         return history[num]\n+\n+    def history_transform_phrase_text(words: list[str]) -> Optional[str]:\n+        \"\"\"Transforms phrase text for presentation in history. Return `None` to omit from history\"\"\"\n+\n+        if not actions.speech.enabled():\n+            return None\n+\n+        return ' '.join(words) if words else None\n\\ No newline at end of file\n", "issue": "Improve phrase history mechanism\ninstead of this:\r\n\r\nhttps://github.com/knausj85/knausj_talon/blob/3e57e0165257cf07b0e21880d44a91e79cb3ef16/code/history.py#L19-L29\r\n\r\nconsider something like this:\r\n\r\n```py\r\ndef on_phrase(j):\r\n    global history\r\n    words = j.get('text')\r\n    if words:\r\n        text = ' '.join(words)\r\n        history.append(text)\r\n        history = history[-setting_command_history_size.get() :]\r\n```\n", "before_files": [{"content": "from talon import imgui, Module, speech_system, actions, app\n\n# We keep command_history_size lines of history, but by default display only\n# command_history_display of them.\nmod = Module()\nsetting_command_history_size = mod.setting(\"command_history_size\", int, default=50)\nsetting_command_history_display = mod.setting(\n    \"command_history_display\", int, default=10\n)\n\nhist_more = False\nhistory = []\n\n\ndef parse_phrase(word_list):\n    return \" \".join(word.split(\"\\\\\")[0] for word in word_list)\n\n\ndef on_phrase(j):\n    global history\n\n    try:\n        val = parse_phrase(getattr(j[\"parsed\"], \"_unmapped\", j[\"phrase\"]))\n    except:\n        val = parse_phrase(j[\"phrase\"])\n\n    if val != \"\":\n        history.append(val)\n        history = history[-setting_command_history_size.get() :]\n\n\n# todo: dynamic rect?\n@imgui.open(y=0)\ndef gui(gui: imgui.GUI):\n    global history\n    gui.text(\"Command History\")\n    gui.line()\n    text = (\n        history[:] if hist_more else history[-setting_command_history_display.get() :]\n    )\n    for line in text:\n        gui.text(line)\n\n    gui.spacer()\n    if gui.button(\"Command history close\"):\n        actions.user.history_disable()\n\n\nspeech_system.register(\"phrase\", on_phrase)\n\n\n@mod.action_class\nclass Actions:\n    def history_toggle():\n        \"\"\"Toggles viewing the history\"\"\"\n        if gui.showing:\n            gui.hide()\n        else:\n            gui.show()\n\n    def history_enable():\n        \"\"\"Enables the history\"\"\"\n        gui.show()\n\n    def history_disable():\n        \"\"\"Disables the history\"\"\"\n        gui.hide()\n\n    def history_clear():\n        \"\"\"Clear the history\"\"\"\n        global history\n        history = []\n\n    def history_more():\n        \"\"\"Show more history\"\"\"\n        global hist_more\n        hist_more = True\n\n    def history_less():\n        \"\"\"Show less history\"\"\"\n        global hist_more\n        hist_more = False\n\n    def history_get(number: int):\n        \"\"\"returns the history entry at the specified index\"\"\"\n        num = (0 - number) - 1\n        return history[num]\n", "path": "code/history.py"}], "after_files": [{"content": "from typing import Optional\nfrom talon import imgui, Module, speech_system, actions, app\n\n# We keep command_history_size lines of history, but by default display only\n# command_history_display of them.\nmod = Module()\nsetting_command_history_size = mod.setting(\"command_history_size\", int, default=50)\nsetting_command_history_display = mod.setting(\n    \"command_history_display\", int, default=10\n)\n\nhist_more = False\nhistory = []\n\n\ndef on_phrase(j):\n    global history\n\n    words = j.get('text')\n\n    text = actions.user.history_transform_phrase_text(words)\n\n    if text is not None:\n        history.append(text)\n        history = history[-setting_command_history_size.get() :]\n\n\n# todo: dynamic rect?\n@imgui.open(y=0)\ndef gui(gui: imgui.GUI):\n    global history\n    gui.text(\"Command History\")\n    gui.line()\n    text = (\n        history[:] if hist_more else history[-setting_command_history_display.get() :]\n    )\n    for line in text:\n        gui.text(line)\n\n    gui.spacer()\n    if gui.button(\"Command history close\"):\n        actions.user.history_disable()\n\n\nspeech_system.register(\"phrase\", on_phrase)\n\n\n@mod.action_class\nclass Actions:\n    def history_toggle():\n        \"\"\"Toggles viewing the history\"\"\"\n        if gui.showing:\n            gui.hide()\n        else:\n            gui.show()\n\n    def history_enable():\n        \"\"\"Enables the history\"\"\"\n        gui.show()\n\n    def history_disable():\n        \"\"\"Disables the history\"\"\"\n        gui.hide()\n\n    def history_clear():\n        \"\"\"Clear the history\"\"\"\n        global history\n        history = []\n\n    def history_more():\n        \"\"\"Show more history\"\"\"\n        global hist_more\n        hist_more = True\n\n    def history_less():\n        \"\"\"Show less history\"\"\"\n        global hist_more\n        hist_more = False\n\n    def history_get(number: int):\n        \"\"\"returns the history entry at the specified index\"\"\"\n        num = (0 - number) - 1\n        return history[num]\n\n    def history_transform_phrase_text(words: list[str]) -> Optional[str]:\n        \"\"\"Transforms phrase text for presentation in history. Return `None` to omit from history\"\"\"\n\n        if not actions.speech.enabled():\n            return None\n\n        return ' '.join(words) if words else None", "path": "code/history.py"}]}