zodiac.toga.app

  1#  # # <!-- // /*  SPDX-License-Identifier: MPL-2.0*/ -->
  2#  # # <!-- // /*  d a r k s h a p e s */ -->
  3
  4import os
  5import asyncio
  6import requests
  7from requests.exceptions import ConnectionError, ConnectTimeout
  8from urllib3.exceptions import MaxRetryError, NewConnectionError
  9from typing import Callable
 10
 11import toga
 12import toga.app
 13from toga import Key
 14from toga.constants import Direction
 15from toga.style import Pack
 16
 17from zodiac.streams.model_stream import ModelStream
 18from zodiac.streams.task_stream import TaskStream
 19from zodiac.streams.token_stream import TokenStream
 20import platform
 21from dspy import Prediction, streamify, context as dspy_context, inspect_history
 22
 23OS_NAME = platform.system  # replace with config from sdbx later
 24
 25
 26class Interface(toga.App):
 27    formatted_units = [" ❖ chr", " ⟐ tok", ' " sec ']
 28    bg_graph = "#070708"
 29    bg_text = "#1B1B1B"  # "#1B1B1B"  # "#09090B"
 30    bg = bg_text
 31    bg_static = "#5D5E62"
 32    activity = "#8122C4"
 33
 34    static = Pack(color="#727378")
 35    fg_static = Pack(color="#8D8E94")
 36    scroll_buffer = 5000  # chunks required to scroll down
 37    graph_disabled = "http://localhost"
 38    graph_server = "http://127.0.0.1:8188"
 39    status_info = ("Connecting...", "Server?", "Ready.", "Done.", "No File.", "Read Failed.", "Attached.", "Copied.")
 40    _is_cancelled = False
 41
 42    async def ticker(self, widget: Callable, external: bool = False, **kwargs) -> toga.Widget:
 43        """Process and synthesize input data based on selected model.\n
 44        :param widget: The UI widget that triggered this action, typically used for state management.\n
 45        :type widget: toga.widgets
 46        :param external: Indicates whether the processing should be handled externally (e.g., via clipboard), defaults to False
 47        :type external: bool"""
 48        from zodiac.toga.signatures import ready_predictor
 49
 50        self.response_panel.value += f"{os.path.basename(self.registry_entry.model)} :\n"
 51        await self.token_stream.set_tokenizer(self.registry_entry)
 52        prompts = {}
 53        if self.message_panel.value:
 54            cache = False
 55            prompts.setdefault("text", self.message_panel.value)
 56        # prompts.setdefault("audio",[0]) if else []
 57        # prompts.setdefault("image",[]) if image": []
 58        if stream := self.output_types.value == "text":
 59            context_data, predictor_data = await ready_predictor(self.registry_entry, dspy_stream=stream, async_stream=stream, cache=cache)
 60            await self.stream_text(prompts, context_data, predictor_data)
 61        else:
 62            content = await self.generate_media(prompts, self.registry_entry)  # context_data, predictor_data)
 63            return widget
 64        return widget
 65
 66    async def stream_text(self, prompts, context_data, predictor_data):
 67        from zodiac.toga.signatures import Predictor
 68        from litellm.types.utils import ModelResponseStream  # StatusStreamingCallback
 69        from dspy.streaming import StatusMessage, StreamResponse
 70
 71        self.response_panel.scroll_to_bottom()
 72        with dspy_context(**context_data):
 73            self.program = streamify(Predictor(), **predictor_data)
 74            async for prediction in self.program(question=prompts["text"]):
 75                if isinstance(prediction, ModelResponseStream) and prediction["choices"][0]["delta"]["content"]:
 76                    self.response_panel.value += prediction["choices"][0]["delta"]["content"]
 77                elif isinstance(prediction, StreamResponse) or hasattr(prediction, "chunk"):
 78                    self.response_panel.value += str(prediction.chunk)
 79                elif isinstance(prediction, Prediction) or hasattr(prediction, "answer"):
 80                    self.response_panel.value += str(prediction.answer)
 81                elif isinstance(prediction, StatusMessage) or hasattr(prediction, "message"):
 82                    self.status_display.text = self.status_text_prefix + str(prediction.message)
 83        self.response_panel.value += "\n--\n\n"
 84        return prediction
 85
 86    async def generate_media(self, prompts, registry_entry) -> None:  # , predictor_data
 87        from nnll.tensor_pipe.construct_pipe import ConstructPipeline
 88        from nnll.tensor_pipe.inference import run_inference
 89        from zodiac.streams.class_stream import best_package
 90        from zodiac.providers.constants import MIR_DB
 91
 92        pkg_data = await best_package(pkg_data=registry_entry)
 93        print(pkg_data)
 94        constructor = ConstructPipeline()
 95        pipe_data = await constructor.create_pipeline(registry_entry, pkg_data, MIR_DB)
 96        content = await run_inference(pipe_data, prompts, out_type=self.output_types.value)
 97        return content
 98        # from zodiac.toga.signatures import Predictor
 99
100        # return prediction
101
102    async def halt(self, widget, **kwargs) -> None:
103        """Stop processing prompt\n
104        :param widget: The calling widget object"""
105        if not self.program.done():
106            import gc
107
108            del self.program
109            gc.collect()
110            self.status_display.text = self.status_text_prefix + "Cancelled."
111
112    async def empty_prompt(self, widget, **kwargs) -> None:
113        """Clears the prompt input area.
114        :param widget: Triggering widget"""
115        self.message_panel.value = ""
116
117    async def copy_reply(self, widget, **kwargs) -> None:
118        """Push the reply into the clipboard
119        :param widget: Triggering widget"""
120        import pyperclip
121
122        pyperclip.copy(self.response_panel.value)
123        self.status_display.text = self.status_text_prefix + self.status_info[7]
124
125    async def attach_file(self, widget, **kwargs) -> None:
126        """Attaches a file's contents to the prompt area.
127        :param widget: Triggering widget"""
128        import json
129
130        try:
131            file_path_named = await self.main_window.dialog(toga.OpenFileDialog(title="Attach a file to the prompt"))
132            self.status_display.text = f"Read. {file_path_named}"
133            if file_path_named is not None:
134                from nnll.metadata.json_io import read_json_file
135
136                file_contents = read_json_file(file_path_named)
137                self.message_panel.scroll_to_bottom()
138                self.message_panel.value = json.dumps(file_contents)
139                self.status_display.text = self.status_text_prefix + self.status_info[6]
140            else:
141                self.status_display.text = self.status_text_prefix + self.status_info[4]
142        except (ValueError, json.JSONDecodeError):
143            self.status_display.text = self.status_text_prefix + self.status_info[5]
144
145    async def reset_position(self, widget, **kwargs) -> None:
146        """Scrolls text panel to bottom after content update.
147        :param widget: text panel widget
148        """
149        setattr(self, "position_counter", getattr(self, "position_counter", 0) + 1)
150        if max(self.scroll_buffer, self.position_counter) >= self.scroll_buffer:
151            self.position_counter = 0
152            widget.scroll_to_bottom()
153
154    async def on_select_handler(self, widget, **kwargs) -> None:
155        """React to input/output choice\n
156        :param widget: The widget that triggered the event."""
157        selection = widget.value
158        if self.model_stream._graph.registry_entries is not None:
159            self.registry_entry = next(iter(registry["entry"] for registry in self.model_stream._graph.registry_entries if selection in registry["entry"].model))
160            await self.populate_task_stack()
161            await self.token_stream.set_tokenizer(self.registry_entry)
162        else:
163            self.registry_entry = "No model..."
164
165    async def model_graph(self):
166        """Builds the model graph."""
167        await self.model_stream.model_graph()
168
169    async def token_estimate(self, widget, **kwargs) -> None:
170        """Updates character and token count based on user input.
171        :param widget: Input widget providing text"""
172        token_count, character_count = await self.token_stream.token_count(message=self.message_panel.value)
173        self.character_stats.text = "{:02}".format(character_count) + "".join(self.formatted_units[0])
174        self.token_stats.text = "{:02}".format(token_count) + "".join(self.formatted_units[1])
175        self.time_stats.text = "{:02}".format(0.0) + "".join(self.formatted_units[2])
176
177    async def populate_in_types(self) -> None:
178        """Builds the input types selection."""
179        in_edge_names = await self.model_stream.show_edges()
180        self.input_types.items = in_edge_names
181
182    async def populate_out_types(self) -> None:
183        """Builds the output types selection."""
184        out_edges = await self.model_stream.show_edges(target=True)
185        self.output_types.items = out_edges
186
187    async def populate_model_stack(self, widget: toga.Widget = None, **kwargs) -> None:
188        """Builds the model stack selection dropdown."""
189
190        await self.model_stream.clear()
191        if self.input_types.value and self.output_types.value:
192            models = await self.model_stream.trace_models(self.input_types.value, self.output_types.value)
193            self.model_stack.items = models  # [model[0][:20] for model in models if len(model[0]) > 20]
194            await self.token_estimate(widget=self.message_panel)
195
196    async def populate_task_stack(self, widget: toga.Widget = None, **kwargs) -> None:
197        """Builds the task stack selection dropdown."""
198        selection = self.model_stack.value
199        if self.model_stream._graph.registry_entries:
200            registry_entry = next(
201                iter(
202                    registry["entry"]  # formatting
203                    for registry in self.model_stream._graph.registry_entries  # formatting
204                    if selection in registry["entry"].model
205                )
206            )
207        else:
208            registry_entry = "No models..."
209        await self.task_stream.set_filter_type(self.input_types.value, self.output_types.value)
210        if registry_entry and not isinstance(registry_entry, str):
211            tasks = await self.task_stream.filter_tasks(registry_entry)
212        else:
213            tasks = ""
214
215        self.task_stack.items = tasks
216
217    async def switch_tabs(self, widget: toga.Widget = None, **kwargs) -> None:
218        """Switches between text and graph tabs.
219        :param widget: The triggering widget (optional), defaults to None"""
220        self.browser_panel.evaluate_javascript("location.reload();")
221        self.bg = self.bg_graph if self.bg == self.bg_text else self.bg_text
222        self.final_layout.style.background_color = self.bg
223        self.final_layout.refresh()
224        self.status_display.text += self.status_info[0]
225        await self.ping_server(widget=self.status_display)
226
227    async def ping_server(self, widget: toga.Widget, **kwargs) -> toga.Widget:
228        self.browser_panel.url = self.graph_server
229        try:
230            request = requests.get(self.graph_server, timeout=(3, 3))
231            if request is not None:
232                if hasattr(request, "status_code"):
233                    status = request.status_code
234                if (hasattr(request, "ok") and request.ok) or (hasattr(request, "reason") and request.reason == "OK"):
235                    await self.active_server()
236                elif hasattr(request, "json"):
237                    status = request.json()
238                    if status.get("result") == "OK":
239                        await self.active_server()
240                else:
241                    self.browser_panel.url = self.graph_disabled
242                    await self.active_server(False)
243            else:
244                self.browser_panel.url = self.graph_disabled
245                await self.active_server(False)
246        except (ConnectTimeout, ConnectionError, ConnectionRefusedError, MaxRetryError, NewConnectionError, OSError):
247            await self.active_server(False)
248            pass
249        return widget
250
251    async def active_server(self, enabled: bool = True):
252        if not enabled:
253            status_info = self.status_info[1]
254            self.browser_panel.url = self.graph_disabled
255        else:
256            status_info = self.status_info[2]
257            self.browser_panel.url = self.graph_server
258        for info in self.status_info:
259            self.status_display.text = self.status_display.text.replace(info, "")
260        self.status_display.text += status_info
261
262    def initialize_inputs(self):
263        """Initializes UI elements for input handling."""
264        self.character_stats = toga.Label("{:02}".format(0) + "".join(self.formatted_units[0]), **self.fg_static)
265        self.token_stats = toga.Label("{:02}".format(0) + "".join(self.formatted_units[1]), **self.fg_static)
266        self.time_stats = toga.Label("{:02}".format(0.0) + "".join(self.formatted_units[2]), **self.fg_static)
267        self.input_types = toga.Selection(items=[], on_change=self.populate_model_stack)
268        self.output_types = toga.Selection(items=[], on_change=self.populate_model_stack)
269        self.model_stack = toga.Selection(items=[], on_change=self.on_select_handler)
270        self.task_stack = toga.Selection(items=[], style=Pack(align_items="end"))
271        self.message_panel = toga.MultilineTextInput(placeholder="Prompt", on_change=self.token_estimate, style=Pack(flex=0.66, margin=10))
272        self.browser_panel = toga.WebView(url=self.graph_server, id="Graph ")
273        self.audio_panel = toga.Canvas()
274        self.response_panel = toga.MultilineTextInput(readonly=True, placeholder="Response", style=Pack(flex=5), on_change=self.reset_position)
275
276    def initialize_static(self) -> None:
277        """Create the main input fields"""
278
279        status_bar = toga.Row(
280            children=[
281                toga.Column(
282                    children=[
283                        toga.Row(
284                            children=[self.input_types, toga.Label("➾"), self.output_types, self.task_stack],
285                            style=Pack(align_items="end", gap=5),
286                        ),
287                        toga.Row(
288                            children=[self.model_stack, toga.Label("↪︎")],  # , live_stats
289                            style=Pack(align_items="end", text_direction="rtl", gap=5),
290                        ),
291                    ],
292                    style=Pack(vertical_align_items="center", gap=5, justify_content="end", align_items="end"),
293                ),
294                toga.Row(
295                    children=[
296                        toga.Column(children=[self.character_stats, self.token_stats, self.time_stats]),
297                        toga.Column(
298                            children=[
299                                toga.Button("▶︎", on_press=self.ticker, style=Pack(width=30, height=20, font_size="12")),
300                                toga.Button("⧉", on_press=self.copy_reply, style=Pack(width=30, height=20, font_size=15, vertical_align_items="start")),
301                            ],
302                            style=Pack(gap=5),
303                        ),
304                        toga.Column(
305                            children=[
306                                toga.Button(
307                                    """📎
308                                _""",
309                                    on_press=self.attach_file,
310                                    style=Pack(width=30, height=20, font_size="10", align_items="start", justify_content="start"),
311                                ),
312                                toga.Button("⌫", on_press=self.empty_prompt, style=Pack(width=30, height=20, font_size="14")),
313                            ],
314                            style=Pack(font_size="15", gap=5),
315                        ),
316                    ],
317                    style=Pack(vertical_align_items="center", gap=5, justify_content="start", align_items="start"),
318                ),
319            ],
320            style=Pack(margin=10, gap=5, vertical_align_items="center", justify_content="start", align_items="start"),
321        )
322        self.status_log = toga.Label(f"{inspect_history()}")  # show llm history
323        self.status_tab = toga.OptionItem(text="|  Connecting...", content=self.status_log, enabled=False)
324        # self.response_array = toga.Box(children=[self.response_panel], style=Pack(flex=1))
325        # self.endless_response = toga.ScrollContainer(content=self.response_array)
326        resize_area = toga.SplitContainer(
327            content=[
328                toga.OptionContainer(
329                    content=[
330                        ("Output", self.response_panel),
331                        ("Graph", self.browser_panel),
332                        self.status_tab,
333                    ],
334                    on_select=self.switch_tabs,
335                    style=Pack(background_color="#000000", flex=2),
336                    id="tab_panel",
337                ),
338                toga.Row(
339                    children=[
340                        toga.Column(justify_content="start", style=Pack(flex=0.33)),
341                        toga.Box(children=[self.message_panel], style=Pack(flex=1)),
342                        toga.Column(style=Pack(flex=0.33, justify_content="start")),
343                    ]
344                ),
345            ],
346            direction=Direction.HORIZONTAL,
347            style=Pack(flex=3),
348        )
349
350        self.final_layout = toga.Column(children=[status_bar, resize_area], style=Pack(background_color=self.bg_text, flex=1))
351
352    def initialize_layout(self) -> None:
353        """Create the layout of the application."""
354        self.main_window.content = self.final_layout
355
356    def startup(self) -> None:
357        """Startup Logic. Initialize widgets and layout, then asynchronous tasks for populating datagets"""
358        self.main_window = toga.MainWindow()
359        self.model_stream = ModelStream()
360        self.task_stream = TaskStream()
361        self.token_stream = TokenStream()
362        self.token_stream = TokenStream()
363
364        start = toga.Command(
365            self.ticker,
366            text="Start",
367            tooltip="Run the current available prompts.",
368            shortcut=Key.MOD_1 + Key.ENTER,
369            group=toga.Group.APP,
370            section=-1,
371        )
372        attach = toga.Command.standard(
373            self,
374            toga.Command.OPEN,
375            text="Attach File...",
376            tooltip="Attach a file to the prompt.",
377            shortcut=Key.MOD_1 + Key.O,
378            action=self.attach_file,
379            group=toga.Group.APP,
380            section=0,
381        )
382        copy_reply = toga.Command(
383            self.copy_reply,
384            text="Copy Response",
385            tooltip="Copy the response provided by the system",
386            group=toga.Group.APP,
387            section=0,
388        )
389        clear = toga.Command(
390            self.empty_prompt,
391            text="Clear Prompt",
392            tooltip="Empty the user prompt field.",
393            shortcut=Key.MOD_3 + Key.BACKSPACE,
394            group=toga.Group.APP,
395            section=1,
396        )
397        stop = toga.Command(
398            self.halt,
399            text="Stop",
400            tooltip="Cancel the current sequence generation.",
401            shortcut=Key.MOD_1 + Key.ESCAPE,  #
402            group=toga.Group.APP,
403            section=1,
404        )
405        self.commands.add(start, attach, copy_reply, clear, stop)
406
407        self.initialize_inputs()
408        self.initialize_static()
409        self.initialize_layout()
410        asyncio.create_task(self.model_graph())
411        asyncio.create_task(self.token_estimate(self))
412        asyncio.create_task(self.populate_in_types())
413        asyncio.create_task(self.populate_out_types())
414        asyncio.create_task(self.populate_model_stack())
415        asyncio.create_task(self.populate_task_stack())
416        self.main_window.show()
417        self.status_display = self.status_tab
418        self.bg = self.bg_graph
419        self.status_text_prefix = "|  "
420
421        asyncio.create_task(self.switch_tabs())
422
423
424def main(url: str = "http://127.0.0.1:8188"):
425    """The entry point for the application."""
426    app = Interface(
427        formal_name="Shadowbox",
428        app_id="org.darkshapes.shadowbox",
429        app_name="sdbx",
430        author="Darkshapes",
431        home_page="https://darkshapes.org",
432        description=" A generative AI instrument. ",
433    )
434
435    app.icon = toga.Icon(path="resources/anomaly_128x")
436    try:
437        app.main_loop()
438    except Exception as error_log:
439        print(error_log)
def OS_NAME():
1067def system():
1068
1069    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.
1070
1071        An empty string is returned if the value cannot be determined.
1072
1073    """
1074    return uname().system

Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.

An empty string is returned if the value cannot be determined.

class Interface(toga.app.App):
 27class Interface(toga.App):
 28    formatted_units = [" ❖ chr", " ⟐ tok", ' " sec ']
 29    bg_graph = "#070708"
 30    bg_text = "#1B1B1B"  # "#1B1B1B"  # "#09090B"
 31    bg = bg_text
 32    bg_static = "#5D5E62"
 33    activity = "#8122C4"
 34
 35    static = Pack(color="#727378")
 36    fg_static = Pack(color="#8D8E94")
 37    scroll_buffer = 5000  # chunks required to scroll down
 38    graph_disabled = "http://localhost"
 39    graph_server = "http://127.0.0.1:8188"
 40    status_info = ("Connecting...", "Server?", "Ready.", "Done.", "No File.", "Read Failed.", "Attached.", "Copied.")
 41    _is_cancelled = False
 42
 43    async def ticker(self, widget: Callable, external: bool = False, **kwargs) -> toga.Widget:
 44        """Process and synthesize input data based on selected model.\n
 45        :param widget: The UI widget that triggered this action, typically used for state management.\n
 46        :type widget: toga.widgets
 47        :param external: Indicates whether the processing should be handled externally (e.g., via clipboard), defaults to False
 48        :type external: bool"""
 49        from zodiac.toga.signatures import ready_predictor
 50
 51        self.response_panel.value += f"{os.path.basename(self.registry_entry.model)} :\n"
 52        await self.token_stream.set_tokenizer(self.registry_entry)
 53        prompts = {}
 54        if self.message_panel.value:
 55            cache = False
 56            prompts.setdefault("text", self.message_panel.value)
 57        # prompts.setdefault("audio",[0]) if else []
 58        # prompts.setdefault("image",[]) if image": []
 59        if stream := self.output_types.value == "text":
 60            context_data, predictor_data = await ready_predictor(self.registry_entry, dspy_stream=stream, async_stream=stream, cache=cache)
 61            await self.stream_text(prompts, context_data, predictor_data)
 62        else:
 63            content = await self.generate_media(prompts, self.registry_entry)  # context_data, predictor_data)
 64            return widget
 65        return widget
 66
 67    async def stream_text(self, prompts, context_data, predictor_data):
 68        from zodiac.toga.signatures import Predictor
 69        from litellm.types.utils import ModelResponseStream  # StatusStreamingCallback
 70        from dspy.streaming import StatusMessage, StreamResponse
 71
 72        self.response_panel.scroll_to_bottom()
 73        with dspy_context(**context_data):
 74            self.program = streamify(Predictor(), **predictor_data)
 75            async for prediction in self.program(question=prompts["text"]):
 76                if isinstance(prediction, ModelResponseStream) and prediction["choices"][0]["delta"]["content"]:
 77                    self.response_panel.value += prediction["choices"][0]["delta"]["content"]
 78                elif isinstance(prediction, StreamResponse) or hasattr(prediction, "chunk"):
 79                    self.response_panel.value += str(prediction.chunk)
 80                elif isinstance(prediction, Prediction) or hasattr(prediction, "answer"):
 81                    self.response_panel.value += str(prediction.answer)
 82                elif isinstance(prediction, StatusMessage) or hasattr(prediction, "message"):
 83                    self.status_display.text = self.status_text_prefix + str(prediction.message)
 84        self.response_panel.value += "\n--\n\n"
 85        return prediction
 86
 87    async def generate_media(self, prompts, registry_entry) -> None:  # , predictor_data
 88        from nnll.tensor_pipe.construct_pipe import ConstructPipeline
 89        from nnll.tensor_pipe.inference import run_inference
 90        from zodiac.streams.class_stream import best_package
 91        from zodiac.providers.constants import MIR_DB
 92
 93        pkg_data = await best_package(pkg_data=registry_entry)
 94        print(pkg_data)
 95        constructor = ConstructPipeline()
 96        pipe_data = await constructor.create_pipeline(registry_entry, pkg_data, MIR_DB)
 97        content = await run_inference(pipe_data, prompts, out_type=self.output_types.value)
 98        return content
 99        # from zodiac.toga.signatures import Predictor
100
101        # return prediction
102
103    async def halt(self, widget, **kwargs) -> None:
104        """Stop processing prompt\n
105        :param widget: The calling widget object"""
106        if not self.program.done():
107            import gc
108
109            del self.program
110            gc.collect()
111            self.status_display.text = self.status_text_prefix + "Cancelled."
112
113    async def empty_prompt(self, widget, **kwargs) -> None:
114        """Clears the prompt input area.
115        :param widget: Triggering widget"""
116        self.message_panel.value = ""
117
118    async def copy_reply(self, widget, **kwargs) -> None:
119        """Push the reply into the clipboard
120        :param widget: Triggering widget"""
121        import pyperclip
122
123        pyperclip.copy(self.response_panel.value)
124        self.status_display.text = self.status_text_prefix + self.status_info[7]
125
126    async def attach_file(self, widget, **kwargs) -> None:
127        """Attaches a file's contents to the prompt area.
128        :param widget: Triggering widget"""
129        import json
130
131        try:
132            file_path_named = await self.main_window.dialog(toga.OpenFileDialog(title="Attach a file to the prompt"))
133            self.status_display.text = f"Read. {file_path_named}"
134            if file_path_named is not None:
135                from nnll.metadata.json_io import read_json_file
136
137                file_contents = read_json_file(file_path_named)
138                self.message_panel.scroll_to_bottom()
139                self.message_panel.value = json.dumps(file_contents)
140                self.status_display.text = self.status_text_prefix + self.status_info[6]
141            else:
142                self.status_display.text = self.status_text_prefix + self.status_info[4]
143        except (ValueError, json.JSONDecodeError):
144            self.status_display.text = self.status_text_prefix + self.status_info[5]
145
146    async def reset_position(self, widget, **kwargs) -> None:
147        """Scrolls text panel to bottom after content update.
148        :param widget: text panel widget
149        """
150        setattr(self, "position_counter", getattr(self, "position_counter", 0) + 1)
151        if max(self.scroll_buffer, self.position_counter) >= self.scroll_buffer:
152            self.position_counter = 0
153            widget.scroll_to_bottom()
154
155    async def on_select_handler(self, widget, **kwargs) -> None:
156        """React to input/output choice\n
157        :param widget: The widget that triggered the event."""
158        selection = widget.value
159        if self.model_stream._graph.registry_entries is not None:
160            self.registry_entry = next(iter(registry["entry"] for registry in self.model_stream._graph.registry_entries if selection in registry["entry"].model))
161            await self.populate_task_stack()
162            await self.token_stream.set_tokenizer(self.registry_entry)
163        else:
164            self.registry_entry = "No model..."
165
166    async def model_graph(self):
167        """Builds the model graph."""
168        await self.model_stream.model_graph()
169
170    async def token_estimate(self, widget, **kwargs) -> None:
171        """Updates character and token count based on user input.
172        :param widget: Input widget providing text"""
173        token_count, character_count = await self.token_stream.token_count(message=self.message_panel.value)
174        self.character_stats.text = "{:02}".format(character_count) + "".join(self.formatted_units[0])
175        self.token_stats.text = "{:02}".format(token_count) + "".join(self.formatted_units[1])
176        self.time_stats.text = "{:02}".format(0.0) + "".join(self.formatted_units[2])
177
178    async def populate_in_types(self) -> None:
179        """Builds the input types selection."""
180        in_edge_names = await self.model_stream.show_edges()
181        self.input_types.items = in_edge_names
182
183    async def populate_out_types(self) -> None:
184        """Builds the output types selection."""
185        out_edges = await self.model_stream.show_edges(target=True)
186        self.output_types.items = out_edges
187
188    async def populate_model_stack(self, widget: toga.Widget = None, **kwargs) -> None:
189        """Builds the model stack selection dropdown."""
190
191        await self.model_stream.clear()
192        if self.input_types.value and self.output_types.value:
193            models = await self.model_stream.trace_models(self.input_types.value, self.output_types.value)
194            self.model_stack.items = models  # [model[0][:20] for model in models if len(model[0]) > 20]
195            await self.token_estimate(widget=self.message_panel)
196
197    async def populate_task_stack(self, widget: toga.Widget = None, **kwargs) -> None:
198        """Builds the task stack selection dropdown."""
199        selection = self.model_stack.value
200        if self.model_stream._graph.registry_entries:
201            registry_entry = next(
202                iter(
203                    registry["entry"]  # formatting
204                    for registry in self.model_stream._graph.registry_entries  # formatting
205                    if selection in registry["entry"].model
206                )
207            )
208        else:
209            registry_entry = "No models..."
210        await self.task_stream.set_filter_type(self.input_types.value, self.output_types.value)
211        if registry_entry and not isinstance(registry_entry, str):
212            tasks = await self.task_stream.filter_tasks(registry_entry)
213        else:
214            tasks = ""
215
216        self.task_stack.items = tasks
217
218    async def switch_tabs(self, widget: toga.Widget = None, **kwargs) -> None:
219        """Switches between text and graph tabs.
220        :param widget: The triggering widget (optional), defaults to None"""
221        self.browser_panel.evaluate_javascript("location.reload();")
222        self.bg = self.bg_graph if self.bg == self.bg_text else self.bg_text
223        self.final_layout.style.background_color = self.bg
224        self.final_layout.refresh()
225        self.status_display.text += self.status_info[0]
226        await self.ping_server(widget=self.status_display)
227
228    async def ping_server(self, widget: toga.Widget, **kwargs) -> toga.Widget:
229        self.browser_panel.url = self.graph_server
230        try:
231            request = requests.get(self.graph_server, timeout=(3, 3))
232            if request is not None:
233                if hasattr(request, "status_code"):
234                    status = request.status_code
235                if (hasattr(request, "ok") and request.ok) or (hasattr(request, "reason") and request.reason == "OK"):
236                    await self.active_server()
237                elif hasattr(request, "json"):
238                    status = request.json()
239                    if status.get("result") == "OK":
240                        await self.active_server()
241                else:
242                    self.browser_panel.url = self.graph_disabled
243                    await self.active_server(False)
244            else:
245                self.browser_panel.url = self.graph_disabled
246                await self.active_server(False)
247        except (ConnectTimeout, ConnectionError, ConnectionRefusedError, MaxRetryError, NewConnectionError, OSError):
248            await self.active_server(False)
249            pass
250        return widget
251
252    async def active_server(self, enabled: bool = True):
253        if not enabled:
254            status_info = self.status_info[1]
255            self.browser_panel.url = self.graph_disabled
256        else:
257            status_info = self.status_info[2]
258            self.browser_panel.url = self.graph_server
259        for info in self.status_info:
260            self.status_display.text = self.status_display.text.replace(info, "")
261        self.status_display.text += status_info
262
263    def initialize_inputs(self):
264        """Initializes UI elements for input handling."""
265        self.character_stats = toga.Label("{:02}".format(0) + "".join(self.formatted_units[0]), **self.fg_static)
266        self.token_stats = toga.Label("{:02}".format(0) + "".join(self.formatted_units[1]), **self.fg_static)
267        self.time_stats = toga.Label("{:02}".format(0.0) + "".join(self.formatted_units[2]), **self.fg_static)
268        self.input_types = toga.Selection(items=[], on_change=self.populate_model_stack)
269        self.output_types = toga.Selection(items=[], on_change=self.populate_model_stack)
270        self.model_stack = toga.Selection(items=[], on_change=self.on_select_handler)
271        self.task_stack = toga.Selection(items=[], style=Pack(align_items="end"))
272        self.message_panel = toga.MultilineTextInput(placeholder="Prompt", on_change=self.token_estimate, style=Pack(flex=0.66, margin=10))
273        self.browser_panel = toga.WebView(url=self.graph_server, id="Graph ")
274        self.audio_panel = toga.Canvas()
275        self.response_panel = toga.MultilineTextInput(readonly=True, placeholder="Response", style=Pack(flex=5), on_change=self.reset_position)
276
277    def initialize_static(self) -> None:
278        """Create the main input fields"""
279
280        status_bar = toga.Row(
281            children=[
282                toga.Column(
283                    children=[
284                        toga.Row(
285                            children=[self.input_types, toga.Label("➾"), self.output_types, self.task_stack],
286                            style=Pack(align_items="end", gap=5),
287                        ),
288                        toga.Row(
289                            children=[self.model_stack, toga.Label("↪︎")],  # , live_stats
290                            style=Pack(align_items="end", text_direction="rtl", gap=5),
291                        ),
292                    ],
293                    style=Pack(vertical_align_items="center", gap=5, justify_content="end", align_items="end"),
294                ),
295                toga.Row(
296                    children=[
297                        toga.Column(children=[self.character_stats, self.token_stats, self.time_stats]),
298                        toga.Column(
299                            children=[
300                                toga.Button("▶︎", on_press=self.ticker, style=Pack(width=30, height=20, font_size="12")),
301                                toga.Button("⧉", on_press=self.copy_reply, style=Pack(width=30, height=20, font_size=15, vertical_align_items="start")),
302                            ],
303                            style=Pack(gap=5),
304                        ),
305                        toga.Column(
306                            children=[
307                                toga.Button(
308                                    """📎
309                                _""",
310                                    on_press=self.attach_file,
311                                    style=Pack(width=30, height=20, font_size="10", align_items="start", justify_content="start"),
312                                ),
313                                toga.Button("⌫", on_press=self.empty_prompt, style=Pack(width=30, height=20, font_size="14")),
314                            ],
315                            style=Pack(font_size="15", gap=5),
316                        ),
317                    ],
318                    style=Pack(vertical_align_items="center", gap=5, justify_content="start", align_items="start"),
319                ),
320            ],
321            style=Pack(margin=10, gap=5, vertical_align_items="center", justify_content="start", align_items="start"),
322        )
323        self.status_log = toga.Label(f"{inspect_history()}")  # show llm history
324        self.status_tab = toga.OptionItem(text="|  Connecting...", content=self.status_log, enabled=False)
325        # self.response_array = toga.Box(children=[self.response_panel], style=Pack(flex=1))
326        # self.endless_response = toga.ScrollContainer(content=self.response_array)
327        resize_area = toga.SplitContainer(
328            content=[
329                toga.OptionContainer(
330                    content=[
331                        ("Output", self.response_panel),
332                        ("Graph", self.browser_panel),
333                        self.status_tab,
334                    ],
335                    on_select=self.switch_tabs,
336                    style=Pack(background_color="#000000", flex=2),
337                    id="tab_panel",
338                ),
339                toga.Row(
340                    children=[
341                        toga.Column(justify_content="start", style=Pack(flex=0.33)),
342                        toga.Box(children=[self.message_panel], style=Pack(flex=1)),
343                        toga.Column(style=Pack(flex=0.33, justify_content="start")),
344                    ]
345                ),
346            ],
347            direction=Direction.HORIZONTAL,
348            style=Pack(flex=3),
349        )
350
351        self.final_layout = toga.Column(children=[status_bar, resize_area], style=Pack(background_color=self.bg_text, flex=1))
352
353    def initialize_layout(self) -> None:
354        """Create the layout of the application."""
355        self.main_window.content = self.final_layout
356
357    def startup(self) -> None:
358        """Startup Logic. Initialize widgets and layout, then asynchronous tasks for populating datagets"""
359        self.main_window = toga.MainWindow()
360        self.model_stream = ModelStream()
361        self.task_stream = TaskStream()
362        self.token_stream = TokenStream()
363        self.token_stream = TokenStream()
364
365        start = toga.Command(
366            self.ticker,
367            text="Start",
368            tooltip="Run the current available prompts.",
369            shortcut=Key.MOD_1 + Key.ENTER,
370            group=toga.Group.APP,
371            section=-1,
372        )
373        attach = toga.Command.standard(
374            self,
375            toga.Command.OPEN,
376            text="Attach File...",
377            tooltip="Attach a file to the prompt.",
378            shortcut=Key.MOD_1 + Key.O,
379            action=self.attach_file,
380            group=toga.Group.APP,
381            section=0,
382        )
383        copy_reply = toga.Command(
384            self.copy_reply,
385            text="Copy Response",
386            tooltip="Copy the response provided by the system",
387            group=toga.Group.APP,
388            section=0,
389        )
390        clear = toga.Command(
391            self.empty_prompt,
392            text="Clear Prompt",
393            tooltip="Empty the user prompt field.",
394            shortcut=Key.MOD_3 + Key.BACKSPACE,
395            group=toga.Group.APP,
396            section=1,
397        )
398        stop = toga.Command(
399            self.halt,
400            text="Stop",
401            tooltip="Cancel the current sequence generation.",
402            shortcut=Key.MOD_1 + Key.ESCAPE,  #
403            group=toga.Group.APP,
404            section=1,
405        )
406        self.commands.add(start, attach, copy_reply, clear, stop)
407
408        self.initialize_inputs()
409        self.initialize_static()
410        self.initialize_layout()
411        asyncio.create_task(self.model_graph())
412        asyncio.create_task(self.token_estimate(self))
413        asyncio.create_task(self.populate_in_types())
414        asyncio.create_task(self.populate_out_types())
415        asyncio.create_task(self.populate_model_stack())
416        asyncio.create_task(self.populate_task_stack())
417        self.main_window.show()
418        self.status_display = self.status_tab
419        self.bg = self.bg_graph
420        self.status_text_prefix = "|  "
421
422        asyncio.create_task(self.switch_tabs())
formatted_units = [' ❖ chr', ' ⟐ tok', ' " sec ']
bg_graph = '#070708'
bg_text = '#1B1B1B'
bg = '#1B1B1B'
bg_static = '#5D5E62'
activity = '#8122C4'
static = Pack(color=rgb(114, 115, 120, 1.0))
fg_static = Pack(color=rgb(141, 142, 148, 1.0))
scroll_buffer = 5000
graph_disabled = 'http://localhost'
graph_server = 'http://127.0.0.1:8188'
status_info = ('Connecting...', 'Server?', 'Ready.', 'Done.', 'No File.', 'Read Failed.', 'Attached.', 'Copied.')
async def ticker( self, widget: Callable, external: bool = False, **kwargs) -> toga.widgets.base.Widget:
43    async def ticker(self, widget: Callable, external: bool = False, **kwargs) -> toga.Widget:
44        """Process and synthesize input data based on selected model.\n
45        :param widget: The UI widget that triggered this action, typically used for state management.\n
46        :type widget: toga.widgets
47        :param external: Indicates whether the processing should be handled externally (e.g., via clipboard), defaults to False
48        :type external: bool"""
49        from zodiac.toga.signatures import ready_predictor
50
51        self.response_panel.value += f"{os.path.basename(self.registry_entry.model)} :\n"
52        await self.token_stream.set_tokenizer(self.registry_entry)
53        prompts = {}
54        if self.message_panel.value:
55            cache = False
56            prompts.setdefault("text", self.message_panel.value)
57        # prompts.setdefault("audio",[0]) if else []
58        # prompts.setdefault("image",[]) if image": []
59        if stream := self.output_types.value == "text":
60            context_data, predictor_data = await ready_predictor(self.registry_entry, dspy_stream=stream, async_stream=stream, cache=cache)
61            await self.stream_text(prompts, context_data, predictor_data)
62        else:
63            content = await self.generate_media(prompts, self.registry_entry)  # context_data, predictor_data)
64            return widget
65        return widget

Process and synthesize input data based on selected model.

Parameters
  • widget: The UI widget that triggered this action, typically used for state management.

  • external: Indicates whether the processing should be handled externally (e.g., via clipboard), defaults to False

async def stream_text(self, prompts, context_data, predictor_data):
67    async def stream_text(self, prompts, context_data, predictor_data):
68        from zodiac.toga.signatures import Predictor
69        from litellm.types.utils import ModelResponseStream  # StatusStreamingCallback
70        from dspy.streaming import StatusMessage, StreamResponse
71
72        self.response_panel.scroll_to_bottom()
73        with dspy_context(**context_data):
74            self.program = streamify(Predictor(), **predictor_data)
75            async for prediction in self.program(question=prompts["text"]):
76                if isinstance(prediction, ModelResponseStream) and prediction["choices"][0]["delta"]["content"]:
77                    self.response_panel.value += prediction["choices"][0]["delta"]["content"]
78                elif isinstance(prediction, StreamResponse) or hasattr(prediction, "chunk"):
79                    self.response_panel.value += str(prediction.chunk)
80                elif isinstance(prediction, Prediction) or hasattr(prediction, "answer"):
81                    self.response_panel.value += str(prediction.answer)
82                elif isinstance(prediction, StatusMessage) or hasattr(prediction, "message"):
83                    self.status_display.text = self.status_text_prefix + str(prediction.message)
84        self.response_panel.value += "\n--\n\n"
85        return prediction
async def generate_media(self, prompts, registry_entry) -> None:
 87    async def generate_media(self, prompts, registry_entry) -> None:  # , predictor_data
 88        from nnll.tensor_pipe.construct_pipe import ConstructPipeline
 89        from nnll.tensor_pipe.inference import run_inference
 90        from zodiac.streams.class_stream import best_package
 91        from zodiac.providers.constants import MIR_DB
 92
 93        pkg_data = await best_package(pkg_data=registry_entry)
 94        print(pkg_data)
 95        constructor = ConstructPipeline()
 96        pipe_data = await constructor.create_pipeline(registry_entry, pkg_data, MIR_DB)
 97        content = await run_inference(pipe_data, prompts, out_type=self.output_types.value)
 98        return content
 99        # from zodiac.toga.signatures import Predictor
100
101        # return prediction
async def halt(self, widget, **kwargs) -> None:
103    async def halt(self, widget, **kwargs) -> None:
104        """Stop processing prompt\n
105        :param widget: The calling widget object"""
106        if not self.program.done():
107            import gc
108
109            del self.program
110            gc.collect()
111            self.status_display.text = self.status_text_prefix + "Cancelled."

Stop processing prompt

Parameters
  • widget: The calling widget object
async def empty_prompt(self, widget, **kwargs) -> None:
113    async def empty_prompt(self, widget, **kwargs) -> None:
114        """Clears the prompt input area.
115        :param widget: Triggering widget"""
116        self.message_panel.value = ""

Clears the prompt input area.

Parameters
  • widget: Triggering widget
async def copy_reply(self, widget, **kwargs) -> None:
118    async def copy_reply(self, widget, **kwargs) -> None:
119        """Push the reply into the clipboard
120        :param widget: Triggering widget"""
121        import pyperclip
122
123        pyperclip.copy(self.response_panel.value)
124        self.status_display.text = self.status_text_prefix + self.status_info[7]

Push the reply into the clipboard

Parameters
  • widget: Triggering widget
async def attach_file(self, widget, **kwargs) -> None:
126    async def attach_file(self, widget, **kwargs) -> None:
127        """Attaches a file's contents to the prompt area.
128        :param widget: Triggering widget"""
129        import json
130
131        try:
132            file_path_named = await self.main_window.dialog(toga.OpenFileDialog(title="Attach a file to the prompt"))
133            self.status_display.text = f"Read. {file_path_named}"
134            if file_path_named is not None:
135                from nnll.metadata.json_io import read_json_file
136
137                file_contents = read_json_file(file_path_named)
138                self.message_panel.scroll_to_bottom()
139                self.message_panel.value = json.dumps(file_contents)
140                self.status_display.text = self.status_text_prefix + self.status_info[6]
141            else:
142                self.status_display.text = self.status_text_prefix + self.status_info[4]
143        except (ValueError, json.JSONDecodeError):
144            self.status_display.text = self.status_text_prefix + self.status_info[5]

Attaches a file's contents to the prompt area.

Parameters
  • widget: Triggering widget
async def reset_position(self, widget, **kwargs) -> None:
146    async def reset_position(self, widget, **kwargs) -> None:
147        """Scrolls text panel to bottom after content update.
148        :param widget: text panel widget
149        """
150        setattr(self, "position_counter", getattr(self, "position_counter", 0) + 1)
151        if max(self.scroll_buffer, self.position_counter) >= self.scroll_buffer:
152            self.position_counter = 0
153            widget.scroll_to_bottom()

Scrolls text panel to bottom after content update.

Parameters
  • widget: text panel widget
async def on_select_handler(self, widget, **kwargs) -> None:
155    async def on_select_handler(self, widget, **kwargs) -> None:
156        """React to input/output choice\n
157        :param widget: The widget that triggered the event."""
158        selection = widget.value
159        if self.model_stream._graph.registry_entries is not None:
160            self.registry_entry = next(iter(registry["entry"] for registry in self.model_stream._graph.registry_entries if selection in registry["entry"].model))
161            await self.populate_task_stack()
162            await self.token_stream.set_tokenizer(self.registry_entry)
163        else:
164            self.registry_entry = "No model..."

React to input/output choice

Parameters
  • widget: The widget that triggered the event.
async def model_graph(self):
166    async def model_graph(self):
167        """Builds the model graph."""
168        await self.model_stream.model_graph()

Builds the model graph.

async def token_estimate(self, widget, **kwargs) -> None:
170    async def token_estimate(self, widget, **kwargs) -> None:
171        """Updates character and token count based on user input.
172        :param widget: Input widget providing text"""
173        token_count, character_count = await self.token_stream.token_count(message=self.message_panel.value)
174        self.character_stats.text = "{:02}".format(character_count) + "".join(self.formatted_units[0])
175        self.token_stats.text = "{:02}".format(token_count) + "".join(self.formatted_units[1])
176        self.time_stats.text = "{:02}".format(0.0) + "".join(self.formatted_units[2])

Updates character and token count based on user input.

Parameters
  • widget: Input widget providing text
async def populate_in_types(self) -> None:
178    async def populate_in_types(self) -> None:
179        """Builds the input types selection."""
180        in_edge_names = await self.model_stream.show_edges()
181        self.input_types.items = in_edge_names

Builds the input types selection.

async def populate_out_types(self) -> None:
183    async def populate_out_types(self) -> None:
184        """Builds the output types selection."""
185        out_edges = await self.model_stream.show_edges(target=True)
186        self.output_types.items = out_edges

Builds the output types selection.

async def populate_model_stack(self, widget: toga.widgets.base.Widget = None, **kwargs) -> None:
188    async def populate_model_stack(self, widget: toga.Widget = None, **kwargs) -> None:
189        """Builds the model stack selection dropdown."""
190
191        await self.model_stream.clear()
192        if self.input_types.value and self.output_types.value:
193            models = await self.model_stream.trace_models(self.input_types.value, self.output_types.value)
194            self.model_stack.items = models  # [model[0][:20] for model in models if len(model[0]) > 20]
195            await self.token_estimate(widget=self.message_panel)

Builds the model stack selection dropdown.

async def populate_task_stack(self, widget: toga.widgets.base.Widget = None, **kwargs) -> None:
197    async def populate_task_stack(self, widget: toga.Widget = None, **kwargs) -> None:
198        """Builds the task stack selection dropdown."""
199        selection = self.model_stack.value
200        if self.model_stream._graph.registry_entries:
201            registry_entry = next(
202                iter(
203                    registry["entry"]  # formatting
204                    for registry in self.model_stream._graph.registry_entries  # formatting
205                    if selection in registry["entry"].model
206                )
207            )
208        else:
209            registry_entry = "No models..."
210        await self.task_stream.set_filter_type(self.input_types.value, self.output_types.value)
211        if registry_entry and not isinstance(registry_entry, str):
212            tasks = await self.task_stream.filter_tasks(registry_entry)
213        else:
214            tasks = ""
215
216        self.task_stack.items = tasks

Builds the task stack selection dropdown.

async def switch_tabs(self, widget: toga.widgets.base.Widget = None, **kwargs) -> None:
218    async def switch_tabs(self, widget: toga.Widget = None, **kwargs) -> None:
219        """Switches between text and graph tabs.
220        :param widget: The triggering widget (optional), defaults to None"""
221        self.browser_panel.evaluate_javascript("location.reload();")
222        self.bg = self.bg_graph if self.bg == self.bg_text else self.bg_text
223        self.final_layout.style.background_color = self.bg
224        self.final_layout.refresh()
225        self.status_display.text += self.status_info[0]
226        await self.ping_server(widget=self.status_display)

Switches between text and graph tabs.

Parameters
  • widget: The triggering widget (optional), defaults to None
async def ping_server( self, widget: toga.widgets.base.Widget, **kwargs) -> toga.widgets.base.Widget:
228    async def ping_server(self, widget: toga.Widget, **kwargs) -> toga.Widget:
229        self.browser_panel.url = self.graph_server
230        try:
231            request = requests.get(self.graph_server, timeout=(3, 3))
232            if request is not None:
233                if hasattr(request, "status_code"):
234                    status = request.status_code
235                if (hasattr(request, "ok") and request.ok) or (hasattr(request, "reason") and request.reason == "OK"):
236                    await self.active_server()
237                elif hasattr(request, "json"):
238                    status = request.json()
239                    if status.get("result") == "OK":
240                        await self.active_server()
241                else:
242                    self.browser_panel.url = self.graph_disabled
243                    await self.active_server(False)
244            else:
245                self.browser_panel.url = self.graph_disabled
246                await self.active_server(False)
247        except (ConnectTimeout, ConnectionError, ConnectionRefusedError, MaxRetryError, NewConnectionError, OSError):
248            await self.active_server(False)
249            pass
250        return widget
async def active_server(self, enabled: bool = True):
252    async def active_server(self, enabled: bool = True):
253        if not enabled:
254            status_info = self.status_info[1]
255            self.browser_panel.url = self.graph_disabled
256        else:
257            status_info = self.status_info[2]
258            self.browser_panel.url = self.graph_server
259        for info in self.status_info:
260            self.status_display.text = self.status_display.text.replace(info, "")
261        self.status_display.text += status_info
def initialize_inputs(self):
263    def initialize_inputs(self):
264        """Initializes UI elements for input handling."""
265        self.character_stats = toga.Label("{:02}".format(0) + "".join(self.formatted_units[0]), **self.fg_static)
266        self.token_stats = toga.Label("{:02}".format(0) + "".join(self.formatted_units[1]), **self.fg_static)
267        self.time_stats = toga.Label("{:02}".format(0.0) + "".join(self.formatted_units[2]), **self.fg_static)
268        self.input_types = toga.Selection(items=[], on_change=self.populate_model_stack)
269        self.output_types = toga.Selection(items=[], on_change=self.populate_model_stack)
270        self.model_stack = toga.Selection(items=[], on_change=self.on_select_handler)
271        self.task_stack = toga.Selection(items=[], style=Pack(align_items="end"))
272        self.message_panel = toga.MultilineTextInput(placeholder="Prompt", on_change=self.token_estimate, style=Pack(flex=0.66, margin=10))
273        self.browser_panel = toga.WebView(url=self.graph_server, id="Graph ")
274        self.audio_panel = toga.Canvas()
275        self.response_panel = toga.MultilineTextInput(readonly=True, placeholder="Response", style=Pack(flex=5), on_change=self.reset_position)

Initializes UI elements for input handling.

def initialize_static(self) -> None:
277    def initialize_static(self) -> None:
278        """Create the main input fields"""
279
280        status_bar = toga.Row(
281            children=[
282                toga.Column(
283                    children=[
284                        toga.Row(
285                            children=[self.input_types, toga.Label("➾"), self.output_types, self.task_stack],
286                            style=Pack(align_items="end", gap=5),
287                        ),
288                        toga.Row(
289                            children=[self.model_stack, toga.Label("↪︎")],  # , live_stats
290                            style=Pack(align_items="end", text_direction="rtl", gap=5),
291                        ),
292                    ],
293                    style=Pack(vertical_align_items="center", gap=5, justify_content="end", align_items="end"),
294                ),
295                toga.Row(
296                    children=[
297                        toga.Column(children=[self.character_stats, self.token_stats, self.time_stats]),
298                        toga.Column(
299                            children=[
300                                toga.Button("▶︎", on_press=self.ticker, style=Pack(width=30, height=20, font_size="12")),
301                                toga.Button("⧉", on_press=self.copy_reply, style=Pack(width=30, height=20, font_size=15, vertical_align_items="start")),
302                            ],
303                            style=Pack(gap=5),
304                        ),
305                        toga.Column(
306                            children=[
307                                toga.Button(
308                                    """📎
309                                _""",
310                                    on_press=self.attach_file,
311                                    style=Pack(width=30, height=20, font_size="10", align_items="start", justify_content="start"),
312                                ),
313                                toga.Button("⌫", on_press=self.empty_prompt, style=Pack(width=30, height=20, font_size="14")),
314                            ],
315                            style=Pack(font_size="15", gap=5),
316                        ),
317                    ],
318                    style=Pack(vertical_align_items="center", gap=5, justify_content="start", align_items="start"),
319                ),
320            ],
321            style=Pack(margin=10, gap=5, vertical_align_items="center", justify_content="start", align_items="start"),
322        )
323        self.status_log = toga.Label(f"{inspect_history()}")  # show llm history
324        self.status_tab = toga.OptionItem(text="|  Connecting...", content=self.status_log, enabled=False)
325        # self.response_array = toga.Box(children=[self.response_panel], style=Pack(flex=1))
326        # self.endless_response = toga.ScrollContainer(content=self.response_array)
327        resize_area = toga.SplitContainer(
328            content=[
329                toga.OptionContainer(
330                    content=[
331                        ("Output", self.response_panel),
332                        ("Graph", self.browser_panel),
333                        self.status_tab,
334                    ],
335                    on_select=self.switch_tabs,
336                    style=Pack(background_color="#000000", flex=2),
337                    id="tab_panel",
338                ),
339                toga.Row(
340                    children=[
341                        toga.Column(justify_content="start", style=Pack(flex=0.33)),
342                        toga.Box(children=[self.message_panel], style=Pack(flex=1)),
343                        toga.Column(style=Pack(flex=0.33, justify_content="start")),
344                    ]
345                ),
346            ],
347            direction=Direction.HORIZONTAL,
348            style=Pack(flex=3),
349        )
350
351        self.final_layout = toga.Column(children=[status_bar, resize_area], style=Pack(background_color=self.bg_text, flex=1))

Create the main input fields

def initialize_layout(self) -> None:
353    def initialize_layout(self) -> None:
354        """Create the layout of the application."""
355        self.main_window.content = self.final_layout

Create the layout of the application.

def startup(self) -> None:
357    def startup(self) -> None:
358        """Startup Logic. Initialize widgets and layout, then asynchronous tasks for populating datagets"""
359        self.main_window = toga.MainWindow()
360        self.model_stream = ModelStream()
361        self.task_stream = TaskStream()
362        self.token_stream = TokenStream()
363        self.token_stream = TokenStream()
364
365        start = toga.Command(
366            self.ticker,
367            text="Start",
368            tooltip="Run the current available prompts.",
369            shortcut=Key.MOD_1 + Key.ENTER,
370            group=toga.Group.APP,
371            section=-1,
372        )
373        attach = toga.Command.standard(
374            self,
375            toga.Command.OPEN,
376            text="Attach File...",
377            tooltip="Attach a file to the prompt.",
378            shortcut=Key.MOD_1 + Key.O,
379            action=self.attach_file,
380            group=toga.Group.APP,
381            section=0,
382        )
383        copy_reply = toga.Command(
384            self.copy_reply,
385            text="Copy Response",
386            tooltip="Copy the response provided by the system",
387            group=toga.Group.APP,
388            section=0,
389        )
390        clear = toga.Command(
391            self.empty_prompt,
392            text="Clear Prompt",
393            tooltip="Empty the user prompt field.",
394            shortcut=Key.MOD_3 + Key.BACKSPACE,
395            group=toga.Group.APP,
396            section=1,
397        )
398        stop = toga.Command(
399            self.halt,
400            text="Stop",
401            tooltip="Cancel the current sequence generation.",
402            shortcut=Key.MOD_1 + Key.ESCAPE,  #
403            group=toga.Group.APP,
404            section=1,
405        )
406        self.commands.add(start, attach, copy_reply, clear, stop)
407
408        self.initialize_inputs()
409        self.initialize_static()
410        self.initialize_layout()
411        asyncio.create_task(self.model_graph())
412        asyncio.create_task(self.token_estimate(self))
413        asyncio.create_task(self.populate_in_types())
414        asyncio.create_task(self.populate_out_types())
415        asyncio.create_task(self.populate_model_stack())
416        asyncio.create_task(self.populate_task_stack())
417        self.main_window.show()
418        self.status_display = self.status_tab
419        self.bg = self.bg_graph
420        self.status_text_prefix = "|  "
421
422        asyncio.create_task(self.switch_tabs())

Startup Logic. Initialize widgets and layout, then asynchronous tasks for populating datagets

def main(url: str = 'http://127.0.0.1:8188'):
425def main(url: str = "http://127.0.0.1:8188"):
426    """The entry point for the application."""
427    app = Interface(
428        formal_name="Shadowbox",
429        app_id="org.darkshapes.shadowbox",
430        app_name="sdbx",
431        author="Darkshapes",
432        home_page="https://darkshapes.org",
433        description=" A generative AI instrument. ",
434    )
435
436    app.icon = toga.Icon(path="resources/anomaly_128x")
437    try:
438        app.main_loop()
439    except Exception as error_log:
440        print(error_log)

The entry point for the application.