Squashed commit of the following:

commit 8ec3b24696
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Sun Dec 8 00:17:02 2024 +0100

    keyboard input tool

commit a76a302f3f
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Sat Dec 7 23:28:03 2024 +0100

    solutions cleanup

commit 884007cdb0
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Sat Dec 7 21:51:14 2024 +0100

    console print edits for docker

commit 927c234d69
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Sat Dec 7 20:40:28 2024 +0100

    openai azure model func name fix

commit 53a46288f9
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Dec 6 15:17:58 2024 +0100

    mistral fix, error text output

commit 6aa37744fc
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Dec 6 14:58:10 2024 +0100

    toast fix

commit f0be03ea77
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Dec 6 14:33:28 2024 +0100

    toast errors

commit 8434682812
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Dec 6 11:30:34 2024 +0100

    warnings cleanup

commit 2b94af895d
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Dec 6 10:54:06 2024 +0100

    Preload fix

commit 7f270d4a14
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Dec 6 09:44:13 2024 +0100

    Server startup log msg

commit f9c9b5c933
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Dec 6 07:50:15 2024 +0100

    Update run_ui.py

commit f3ca7e0742
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Dec 6 06:21:14 2024 +0100

    Update run_ui.py

commit 21975c5a7c
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Thu Dec 5 20:45:51 2024 +0100

    local models docker url

commit f0a8b07c4f
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Thu Dec 5 16:40:49 2024 +0100

    Server addr notice

commit 656612726a
Merge: 49594fe 7c2866c
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Thu Dec 5 16:11:23 2024 +0100

    Merge pull request #260 from 3clyp50/development

    fix: toast handling, mobile breakpoint

commit 7c2866ca61
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Wed Dec 4 19:37:50 2024 +0100

    fix: toast handling, mobile breakpoint

    `toast.css` and `index.js`
    - fixed toasts disappearing right after showing
    - simplified toast animation

    `index.css`
    - set 2ⁿᵈ mobile breakpoint at 640px

commit 49594fe6ec
Merge: f697754 70b1fa3
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Wed Dec 4 10:39:58 2024 +0100

    Merge pull request #259 from 3clyp50/development

    CSS refactor and toasts

commit 70b1fa385a
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Wed Dec 4 02:17:50 2024 +0100

    refactor: css, style: toasts, fix: z-index

    - organized structure
    - consolidated selectors and states
    - shorthand everywhere

    - modern toasts
    - bigger action buttons for mobile

commit f6977546c1
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Dec 3 22:42:36 2024 +0100

    call subordinate fix

commit fbe47ac03e
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Dec 3 21:19:03 2024 +0100

    Minor fixes

commit 961dbc405a
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Dec 3 21:10:45 2024 +0100

    restart

commit 357909c16a
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Dec 3 19:41:29 2024 +0100

    whisper remote preload

commit e0b0b6f636
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Dec 3 17:39:56 2024 +0100

    nudge

commit 9fae02b2a5
Merge: 0ebc142 fedf2d4
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Tue Dec 3 14:57:18 2024 +0100

    Merge pull request #256 from 3clyp50/development

    feature: copy text button, nudge & fix: various styles

commit 0ebc142124
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Dec 3 14:56:33 2024 +0100

    ssh connection retry

commit deae13d383
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Dec 3 14:38:57 2024 +0100

    root pass fix

commit 9109fcbf60
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Dec 3 14:28:53 2024 +0100

    root password change fix

commit 46689d6477
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Dec 3 14:22:18 2024 +0100

    RFC & SSH exchange for development

commit fedf2d4bdc
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Tue Dec 3 04:03:14 2024 +0100

    feature: copy text button, nudge & fix: various styles

    - Copy button for all messages
    - Nudge button front-end
    - Fixed various non-styled light mode elements

    to do -> css cleanup and whisper loading

commit 19f50d6d95
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Sun Dec 1 20:50:17 2024 +0100

    attachments, files, prompt extras, prompt caching, refactors, cleanups

commit c99b1a47d4
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Nov 29 08:55:27 2024 +0100

    Alpine fix version, STT fixes

commit 81e653ba2d
Merge: 857f8b6 89b8483
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Thu Nov 28 23:08:09 2024 +0100

    Merge pull request #255 from 3clyp50/development

    feature: speech to text settings

commit 857f8b6d82
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Thu Nov 28 23:05:17 2024 +0100

    download and remove folders in browser

commit 89b848312b
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Thu Nov 28 16:07:50 2024 +0100

    feature: speech to text settings

    - initial commit: voice settings

    - Settings section for STT

commit b3a27bb442
Merge: 5e8d6b1 bb980ea
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Thu Nov 28 08:39:01 2024 +0100

    Merge pull request #254 from 3clyp50/development

    fix: file browser bugs + final ui polishing

commit bb980ea6b9
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Thu Nov 28 01:13:56 2024 +0100

    fix: file browser deletion bug + parent directory

    Underscore matters!
    - fixed both bugs for the browser

    Extra:
    - style for toasts

    quickfix generic modals

commit f0126a6ef8
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Wed Nov 27 23:44:20 2024 +0100

    style: polishing and consistency

commit 5e8d6b1c7d
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Wed Nov 27 22:16:13 2024 +0100

    Minor fixes

commit 184f8dcf53
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Wed Nov 27 22:05:23 2024 +0100

    Pause button fix

commit 969f142af1
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Wed Nov 27 22:01:06 2024 +0100

    RFC fix, history bugfixes

commit 733b8de516
Merge: f2057d3 6a83e79
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Wed Nov 27 20:57:15 2024 +0100

    Merge branch 'pr/253' into development

commit 6a83e79d5a
Author: Alessandro <real.eclypso@gmail.com>
Date:   Wed Nov 27 20:41:53 2024 +0100

    fix: bigger modals

commit f2057d3901
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Wed Nov 27 17:30:19 2024 +0100

    Squashed commit of the following:

    commit e626817332
    Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
    Date:   Wed Nov 27 12:51:22 2024 +0100

        refactor: modals css

        Modals now get the base styles from modals.css, with any spec in the individual files (settings.css, file_manager.css, ecc).

    commit 306db0ca39
    Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
    Date:   Wed Nov 27 03:17:20 2024 +0100

        style: new action buttons + ghost buttons

        Updated styles for buttons, switches, and overall UI graphic improvement

    commit c95a379bb5
    Author: Alessandro <real.eclypso@gmail.com>
    Date:   Tue Nov 26 20:17:18 2024 +0100

        fix: status-icon

    commit eddafa8798
    Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
    Date:   Fri Nov 22 01:28:04 2024 +0100

        cleanup: webui folder cleanup (history)

        cleanup: webui sidebar, icons, modals

commit e626817332
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Wed Nov 27 12:51:22 2024 +0100

    refactor: modals css

    Modals now get the base styles from modals.css, with any spec in the individual files (settings.css, file_manager.css, ecc).

commit 306db0ca39
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Wed Nov 27 03:17:20 2024 +0100

    style: new action buttons + ghost buttons

    Updated styles for buttons, switches, and overall UI graphic improvement

commit c95a379bb5
Author: Alessandro <real.eclypso@gmail.com>
Date:   Tue Nov 26 20:17:18 2024 +0100

    fix: status-icon

commit eddafa8798
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Fri Nov 22 01:28:04 2024 +0100

    cleanup: webui folder cleanup (history)

    cleanup: webui sidebar, icons, modals

commit 22ecfd660c
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 25 22:14:17 2024 +0100

    intervention message fix

commit ea9c8bf63b
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 25 20:48:52 2024 +0100

    minor context window fixes

commit 489ca317c5
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 25 19:01:01 2024 +0100

    settings auth fix

commit a0ff118ad1
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 25 17:39:42 2024 +0100

    Context window management, work in progress

commit c0947e30c7
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Thu Nov 21 18:47:40 2024 +0100

    API separation

commit 8db8d3fa18
Merge: 5034892 0735bb9
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Thu Nov 21 15:29:20 2024 +0100

    Merge pull request #249 from 3clyp50/development

    feature: work_dir file manager

commit 0735bb9ae8
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Thu Nov 21 11:28:56 2024 +0100

    fix: SVG optimization

    Thanks SVGO!

    removal: settings.svg (not used)

commit 9c968ba1cf
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Thu Nov 21 10:58:20 2024 +0100

    feature: work_dir file manager

    Implemented the file browser for work_dir, we need to:
    - move endpoints away from run_ui.py
    - make the "Up" (parent dir) button work

    Extra:
    - Now when under 768px in width, you can touch outside of the sidebar to collapse it.

commit 50348926df
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 19 21:56:50 2024 +0100

    version info fix

commit 040de30ef2
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 19 21:21:47 2024 +0100

    removed bundles, tests

commit 020c16ef86
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 19 20:46:08 2024 +0100

    git+docker improvements

    version, build branch

commit 06260ed4a6
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 19 13:11:54 2024 +0100

    searxng fix, ui animation

commit 41dc7ae146
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 19 11:05:33 2024 +0100

    Nodejs eval require path fix

commit 970db9adc9
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 19 10:37:49 2024 +0100

    Whisper fix

commit f59ac2b485
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 19 09:34:00 2024 +0100

    docker /a0 mount fix

commit c7046fa97b
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 19 00:43:15 2024 +0100

    docker volume map fix

commit 0ce8344f0b
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 19 00:23:08 2024 +0100

    dockerfile, compose, smart cache

commit bad3951646
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 18 21:41:39 2024 +0100

    RFC error messages

commit 05cbaa0f4d
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 18 21:16:50 2024 +0100

    RFC password

    RFC password protection work in progress

commit 9d1d2be897
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 18 16:18:31 2024 +0100

    Dockerfile updates

commit a7a40ac18f
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 18 10:50:24 2024 +0100

    dotenv fix, knowledge tool fic

commit ba3422d452
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 18 09:01:23 2024 +0100

    dotenv fix, gitignore update

commit 9c7339042f
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Sun Nov 17 23:12:19 2024 +0100

    Squashed commit of the following:

    commit b05d44bb4bc9e07cfc0b584ab39e8624bae771fb
    Author: frdel <38891707+frdel@users.noreply.github.com>
    Date:   Sun Nov 17 23:12:00 2024 +0100

        searxng, RFC, docker runtime

    commit c90fd4026e644d22e6c7dc29639c85eee6026828
    Author: frdel <38891707+frdel@users.noreply.github.com>
    Date:   Sat Nov 16 21:21:49 2024 +0100

        Remote function calling

    commit f71d45ec7dbff4e2d3209f0efe97804f6e602fe7
    Author: frdel <38891707+frdel@users.noreply.github.com>
    Date:   Fri Nov 15 13:13:09 2024 +0100

        Fix for bool arg parsing

    commit 936768d1d8efc9060494334b87f400c933d78048
    Author: frdel <38891707+frdel@users.noreply.github.com>
    Date:   Fri Nov 15 13:01:28 2024 +0100

        Dynamic runtime args parsing

    commit 00c915fc6c1f8f00f8176fbf5b77af32fa312d18
    Author: frdel <38891707+frdel@users.noreply.github.com>
    Date:   Fri Nov 15 12:13:58 2024 +0100

        API key fix

    commit 504a7f91789caa16578af8bae9b7936a9d7fbbb7
    Author: frdel <38891707+frdel@users.noreply.github.com>
    Date:   Fri Nov 15 11:59:41 2024 +0100

        API keys JIT loading

    commit 5678a2fce2d333454bb1a2e94ca2b5916d321b41
    Author: frdel <38891707+frdel@users.noreply.github.com>
    Date:   Fri Nov 15 11:27:12 2024 +0100

        Update dotenv.py

commit e469f6d7ba
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Nov 15 09:57:49 2024 +0100

    Docker runtime preload

commit 66f1ab7baf
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Fri Nov 15 09:49:23 2024 +0100

    Docker runtime - SSH, runtime args

commit 02cb41b2fd
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Thu Nov 14 21:49:45 2024 +0100

    WIP: docker runtime

commit b33b48057d
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Thu Nov 14 21:28:14 2024 +0100

    WIP: docker runtime

commit 7fc17b39c5
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Thu Nov 14 20:27:43 2024 +0100

    Docker runtime in progress

    work in progress
    container manager script
    runtime image with autostart

commit 2bf24b76d9
Merge: 92d94b4 a57f0c1
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 12 15:38:30 2024 +0100

    Merge pull request #239 from 3clyp50/development

    feature: attachments preview and sending (file, code, imgs)

commit a57f0c1198
Author: Alessandro <real.eclypso@gmail.com>
Date:   Tue Nov 12 15:02:25 2024 +0100

    feature: attachments preview and sending (file, code, imgs)

commit 92d94b4d86
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Sun Nov 10 23:44:15 2024 +0100

    TTS prototype

    TTS with default browser API

commit 1a91334a42
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Sun Nov 10 20:57:49 2024 +0100

    STT continued

    Dialogue mode and state managed for STT

commit 22f1a2b744
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Sun Nov 10 14:25:20 2024 +0100

    speech recognition prototype

    using xenova web only tts

commit a0b042cfb2
Merge: 22db39f 82ca0d8
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Sun Nov 10 08:52:32 2024 +0100

    Merge pull request #235 from 3clyp50/development

    feature: openai-whisper voice input

commit 22db39f731
Merge: d39beba 2b1aa09
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Sun Nov 10 08:52:15 2024 +0100

    Merge pull request #236 from linuztx/development

    Add Free Cloudflare Tunnel Support for Remote Access

commit 2b1aa09840
Author: linuztx <linuztx@gmail.com>
Date:   Sun Nov 10 14:56:52 2024 +0800

    Add auto-downloading cloudflared tunnel manager

commit cca85d7f5d
Author: linuztx <linuztx@gmail.com>
Date:   Sun Nov 10 14:54:52 2024 +0800

    Integrate Cloudflare tunnel support in web UI

commit 433f44522c
Author: linuztx <linuztx@gmail.com>
Date:   Sun Nov 10 14:54:19 2024 +0800

    Add USE_CLOUDFLARE environment variable

commit d94c3b0467
Author: linuztx <linuztx@gmail.com>
Date:   Sun Nov 10 14:53:45 2024 +0800

    Cloudflared binaries

commit 451fdb08c4
Author: linuztx <linuztx@gmail.com>
Date:   Sun Nov 10 14:52:24 2024 +0800

    Add bin directory for cloudflared downloads

commit 82ca0d800a
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Sun Nov 10 00:37:41 2024 +0100

    feature: openai-whisper voice input

    This also reverts commit 92a904d4411a203c482bc1231dee1438d7279b62.

commit 3c6a5bee64
Author: Alessandro <real.eclypso@gmail.com>
Date:   Fri Nov 8 01:46:29 2024 +0100

    feature: attachment setup

    missing
    - double user message when sending imgs
    - base 64 images implementation

    fix: fonts consistency

commit d39beba374
Merge: 2eb497c 9d6b769
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Thu Nov 7 08:31:52 2024 +0100

    Merge pull request #234 from 3clyp50/development

    UI Knowledge import, attachments, voice input and scroll fix

commit 9d6b769dc2
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Thu Nov 7 05:40:40 2024 +0100

    UI Knowledge import

    missing
    - image attachment
    - work_dir browser (backend implemented, WIP)
    - WHISPER (hurry up)

commit 3c40c86d07
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Thu Nov 7 03:40:06 2024 +0100

    Revert index.js scrolling logic + css infinite scroll fix

commit d84469dff6
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Wed Nov 6 11:17:56 2024 +0100

    Mic js and embedding menu + styles

commit 2eb497c8d2
Merge: ef1cdac 21933bc
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 5 21:33:32 2024 +0100

    Merge pull request #233 from 3clyp50/development

    Animation, KaTeX fix and mobile improvements

commit 21933bce2f
Author: Alessandro <real.eclypso@gmail.com>
Date:   Tue Nov 5 21:07:50 2024 +0100

    KaTeX fix and mobile improvements

commit ef1cdacea2
Merge: 9626c04 553f7bf
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Tue Nov 5 17:54:14 2024 +0100

    Merge pull request #232 from 3clyp50/development

    LaTeX, old browser support, new buttons and attachments

commit 553f7bf039
Merge: fc03a79 9626c04
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Tue Nov 5 14:48:53 2024 +0100

    Merge remote-tracking branch 'upstream/development' into development

commit fc03a7922e
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Tue Nov 5 00:59:25 2024 +0100

    Browsers support, new text buttons + attachments

    - Firefox/old browsers support and new text buttons + attachments
    - LaTeX support!

commit 9626c044d5
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 4 22:55:56 2024 +0100

    UI and settings merge

commit 255baf0780
Merge: 1c026ee 61b5b83
Author: Jan Tomášek <38891707+frdel@users.noreply.github.com>
Date:   Mon Nov 4 22:26:57 2024 +0100

    Merge pull request #229 from 3clyp50/development

    UI update

commit 61b5b8389a
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Mon Nov 4 22:26:07 2024 +0100

    other things + Embedding Model selection

commit 6ff3df03de
Author: Alessandro <real.eclypso@gmail.com>
Date:   Mon Nov 4 21:06:48 2024 +0100

    toast!

commit e6ac772a2e
Author: Alessandro <real.eclypso@gmail.com>
Date:   Mon Nov 4 20:58:55 2024 +0100

    Mobile and UX update

commit 1a0ceebcaf
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Mon Nov 4 15:18:06 2024 +0100

    Modal styling WIP

commit f28a05d739
Author: Alessandro <155005371+3clyp50@users.noreply.github.com>
Date:   Wed Oct 23 00:18:59 2024 +0200

    Improved UI/UX in WebUI

    - Collapsible pref section 👍
    - Monospace font
    - UX focus on user feedback and accessibility
    - Mobile and input section QoL
    - Other minor refinements

commit 1c026ee75f
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Tue Oct 29 19:39:54 2024 +0100

    Behaviour prompt

    Prototype of adjustable behaviour system prompt

commit a5d671904d
Author: frdel <38891707+frdel@users.noreply.github.com>
Date:   Sun Oct 27 18:04:40 2024 +0100

    Settings prototype

    Settings modal window managed from python - work in progress
This commit is contained in:
frdel 2024-12-08 00:27:02 +01:00
parent ba2d5c7a67
commit 050c78a3d9
184 changed files with 10508 additions and 2494 deletions

18
python/api/chat_export.py Normal file
View file

@ -0,0 +1,18 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import persist_chat
class ExportChat(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
ctxid = input.get("ctxid", "")
if not ctxid:
raise Exception("No context id provided")
context = self.get_context(ctxid)
content = persist_chat.export_json_chat(context)
return {
"message": "Chats exported.",
"ctxid": context.id,
"content": content,
}

17
python/api/chat_load.py Normal file
View file

@ -0,0 +1,17 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import persist_chat
class LoadChats(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
chats = input.get("chats", [])
if not chats:
raise Exception("No chats provided")
ctxids = persist_chat.load_json_chats(chats)
return {
"message": "Chats loaded.",
"ctxids": ctxids,
}

18
python/api/chat_remove.py Normal file
View file

@ -0,0 +1,18 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from agent import AgentContext
from python.helpers import persist_chat
class RemoveChat(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
ctxid = input.get("context", "")
# context instance - get or create
AgentContext.remove(ctxid)
persist_chat.remove_chat(ctxid)
return {
"message": "Context removed.",
}

17
python/api/chat_reset.py Normal file
View file

@ -0,0 +1,17 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import persist_chat
class Reset(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
ctxid = input.get("context", "")
# context instance - get or create
context = self.get_context(ctxid)
context.reset()
persist_chat.save_tmp_chat(context)
return {
"message": "Agent restarted.",
}

View file

@ -0,0 +1,14 @@
from python.helpers import tokens
from python.helpers.api import ApiHandler
from flask import Request, Response
class GetCtxWindow(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
ctxid = input.get("context", [])
context = self.get_context(ctxid)
agent = context.streaming_agent or context.agent0
window = agent.get_data(agent.DATA_NAME_CTX_WINDOW)
size = tokens.approximate_tokens(window)
return {"content": window, "tokens": size}

View file

@ -0,0 +1,22 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers.file_browser import FileBrowser
from python.helpers import files
class DeleteWorkDirFile(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
file_path = input.get('path', '')
current_path = input.get('currentPath', '')
browser = FileBrowser()
if browser.delete_file(file_path):
# Get updated file list
result = browser.get_files(current_path)
return {
"data": result
}
else:
raise Exception("File not found or could not be deleted")

View file

@ -0,0 +1,29 @@
from python.helpers.api import ApiHandler
from flask import Request, Response, send_file
from python.helpers.file_browser import FileBrowser
from python.helpers import files
import os
class DownloadWorkDirFile(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
file_path = request.args.get("path", "")
if not file_path:
raise ValueError("No file path provided")
browser = FileBrowser()
full_path = browser.get_full_path(file_path, True)
if os.path.isdir(full_path):
zip_file = browser.zip_dir(full_path)
return send_file(
zip_file,
as_attachment=True,
download_name=f"{os.path.basename(file_path)}.zip",
)
if full_path:
return send_file(
full_path, as_attachment=True, download_name=os.path.basename(file_path)
)
raise Exception("File not found")

View file

@ -0,0 +1,19 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers.file_browser import FileBrowser
from python.helpers import files, runtime
class GetWorkDirFiles(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
current_path = request.args.get("path", "")
if current_path == "$WORK_DIR":
if runtime.is_development():
current_path = "work_dir"
else:
current_path = "root"
browser = FileBrowser()
result = browser.get_files(current_path)
return {"data": result}

10
python/api/health.py Normal file
View file

@ -0,0 +1,10 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import git
class HealthCheck(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
gitinfo = git.get_git_info()
return {"gitinfo": gitinfo}

17
python/api/history_get.py Normal file
View file

@ -0,0 +1,17 @@
from python.helpers import tokens
from python.helpers.api import ApiHandler
from flask import Request, Response
class GetHistory(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
ctxid = input.get("context", [])
context = self.get_context(ctxid)
agent = context.streaming_agent or context.agent0
history = agent.history.output()
size = tokens.approximate_tokens(agent.history.output_text())
return {
"history": history,
"tokens": size
}

View file

@ -0,0 +1,26 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers.file_browser import FileBrowser
from python.helpers import files
import os
from werkzeug.utils import secure_filename
class ImportKnowledge(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
if "files[]" not in request.files:
raise Exception("No files part")
file_list = request.files.getlist("files[]")
KNOWLEDGE_FOLDER = files.get_abs_path("knowledge/custom/main")
saved_filenames = []
for file in file_list:
if file:
filename = secure_filename(file.filename) # type: ignore
file.save(os.path.join(KNOWLEDGE_FOLDER, filename))
saved_filenames.append(filename)
return {"message": "Knowledge Imported", "filenames": saved_filenames}

88
python/api/message.py Normal file
View file

@ -0,0 +1,88 @@
from agent import AgentContext, UserMessage
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import files
import os
from werkzeug.utils import secure_filename
from python.helpers.defer import DeferredTask
from python.helpers.print_style import PrintStyle
class Message(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
task, context = await self.communicate(input=input, request=request)
return await self.respond(task, context)
async def respond(self, task: DeferredTask, context: AgentContext):
result = await task.result() # type: ignore
return {
"message": result,
"context": context.id,
}
async def communicate(self, input: dict, request: Request):
# Handle both JSON and multipart/form-data
if request.content_type.startswith("multipart/form-data"):
text = request.form.get("text", "")
ctxid = request.form.get("context", "")
message_id = request.form.get("message_id", None)
attachments = request.files.getlist("attachments")
attachment_paths = []
upload_folder_int = "/a0/tmp/uploads"
upload_folder_ext = files.get_abs_path("tmp/uploads")
if attachments:
os.makedirs(upload_folder_ext, exist_ok=True)
for attachment in attachments:
if attachment.filename is None:
continue
filename = secure_filename(attachment.filename)
save_path = files.get_abs_path(upload_folder_ext, filename)
attachment.save(save_path)
attachment_paths.append(os.path.join(upload_folder_int, filename))
else:
# Handle JSON request as before
input_data = request.get_json()
text = input_data.get("text", "")
ctxid = input_data.get("context", "")
message_id = input_data.get("message_id", None)
attachment_paths = []
# Now process the message
message = text
# Obtain agent context
context = self.get_context(ctxid)
# Store attachments in agent data
# context.agent0.set_data("attachments", attachment_paths)
# Prepare attachment filenames for logging
attachment_filenames = (
[os.path.basename(path) for path in attachment_paths]
if attachment_paths
else []
)
# Print to console and log
PrintStyle(
background_color="#6C3483", font_color="white", bold=True, padding=True
).print(f"User message:")
PrintStyle(font_color="white", padding=False).print(f"> {message}")
if attachment_filenames:
PrintStyle(font_color="white", padding=False).print("Attachments:")
for filename in attachment_filenames:
PrintStyle(font_color="white", padding=False).print(f"- {filename}")
# Log the message with message_id and attachments
context.log.log(
type="user",
heading="User message",
content=message,
kvps={"attachments": attachment_filenames},
id=message_id,
)
return context.communicate(UserMessage(message, attachment_paths)), context

View file

@ -0,0 +1,17 @@
from agent import AgentContext
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import files
import os
from werkzeug.utils import secure_filename
from python.helpers.defer import DeferredTask
from python.api.message import Message
class MessageAsync(Message):
async def respond(self, task: DeferredTask, context: AgentContext):
return {
"message": "Message received.",
"context": context.id,
}

21
python/api/nudge.py Normal file
View file

@ -0,0 +1,21 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import persist_chat
class Nudge(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
ctxid = input.get("ctxid", "")
if not ctxid:
raise Exception("No context id provided")
context = self.get_context(ctxid)
context.nudge()
msg = "Process reset, agent nudged."
context.log.log(type="info", content=msg)
return {
"message": msg,
"ctxid": context.id,
}

19
python/api/pause.py Normal file
View file

@ -0,0 +1,19 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
class Pause(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
# input data
paused = input.get("paused", False)
ctxid = input.get("context", "")
# context instance - get or create
context = self.get_context(ctxid)
context.paused = paused
return {
"message": "Agent paused." if paused else "Agent unpaused.",
"pause": paused,
}

39
python/api/poll.py Normal file
View file

@ -0,0 +1,39 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from agent import AgentContext
class Poll(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
ctxid = input.get("context", None)
from_no = input.get("log_from", 0)
# context instance - get or create
context = self.get_context(ctxid)
logs = context.log.output(start=from_no)
# loop AgentContext._contexts
ctxs = []
for ctx in AgentContext._contexts.values():
ctxs.append(
{
"id": ctx.id,
"no": ctx.no,
"log_guid": ctx.log.guid,
"log_version": len(ctx.log.updates),
"log_length": len(ctx.log.logs),
"paused": ctx.paused,
}
)
# data from this server
return {
"context": context.id,
"contexts": ctxs,
"logs": logs,
"log_guid": context.log.guid,
"log_version": len(context.log.updates),
"log_progress": context.log.progress,
"paused": context.paused,
}

9
python/api/restart.py Normal file
View file

@ -0,0 +1,9 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import process
class Restart(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
process.reload()
return Response(status=200)

9
python/api/rfc.py Normal file
View file

@ -0,0 +1,9 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import runtime
class RFC(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
result = await runtime.handle_rfc(input) # type: ignore
return result

View file

@ -0,0 +1,9 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import settings
class GetSettings(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
set = settings.convert_out(settings.get_settings())
return {"settings": set}

View file

@ -0,0 +1,11 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import settings
class SetSettings(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
set = settings.convert_in(input)
set = settings.set_settings(set)
return {"settings": set}

17
python/api/transcribe.py Normal file
View file

@ -0,0 +1,17 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import runtime, settings, whisper
class Transcribe(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
audio = input.get("audio")
ctxid = input.get("ctxid", "")
context = self.get_context(ctxid)
if await whisper.is_downloading():
context.log.log(type="info", content="Whisper model is currently being downloaded, please wait...")
set = settings.get_settings()
result = await whisper.transcribe(set["stt_model_size"], audio) # type: ignore
return result

27
python/api/upload.py Normal file
View file

@ -0,0 +1,27 @@
from python.helpers.api import ApiHandler
from flask import Request, Response
from python.helpers import files
from werkzeug.utils import secure_filename
class UploadFile(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
if "file" not in request.files:
raise Exception("No file part")
file_list = request.files.getlist("file") # Handle multiple files
saved_filenames = []
for file in file_list:
if file and self.allowed_file(file.filename): # Check file type
filename = secure_filename(file.filename) # type: ignore
file.save(files.get_abs_path("tmp/upload", filename))
saved_filenames.append(filename)
return {"filenames": saved_filenames} # Return saved filenames
def allowed_file(self,filename):
ALLOWED_EXTENSIONS = {"png", "jpg", "jpeg", "txt", "pdf", "csv", "html", "json", "md"}
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS

View file

@ -0,0 +1,33 @@
from python.helpers.api import ApiHandler
from flask import Request, Response, send_file
from python.helpers.file_browser import FileBrowser
from python.helpers import files
import os
class UploadWorkDirFiles(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response:
if "files[]" not in request.files:
raise Exception("No files uploaded")
current_path = request.form.get('path', '')
uploaded_files = request.files.getlist("files[]")
browser = FileBrowser()
successful, failed = browser.save_files(uploaded_files, current_path)
if not successful and failed:
raise Exception("All uploads failed")
result = browser.get_files(current_path)
return {
"message": "Files uploaded successfully" if not failed else "Some files failed to upload",
"data": result,
"successful": successful,
"failed": failed
}