mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-05-07 17:22:09 +00:00
commit9d4e1b68b2Author: frdel <38891707+frdel@users.noreply.github.com> Date: Sun Dec 15 18:01:51 2024 +0100 ctx window popup fix, default settings fix commit9ef3208565Author: frdel <38891707+frdel@users.noreply.github.com> Date: Sun Dec 15 14:55:53 2024 +0100 models, settings, initializer refactor Rate limiter fix Models initialized JIT Model call wrappers for agent Message compression fix Log progress update Settings frontend numeric fields commitf7b3e2540cAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Sun Dec 8 19:42:17 2024 +0100 knowledge import/reload commit4e028a3ce4Author: frdel <38891707+frdel@users.noreply.github.com> Date: Sun Dec 8 11:28:47 2024 +0100 Memory recall speedup commit8ec3b24696Author: frdel <38891707+frdel@users.noreply.github.com> Date: Sun Dec 8 00:17:02 2024 +0100 keyboard input tool commita76a302f3fAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Sat Dec 7 23:28:03 2024 +0100 solutions cleanup commit884007cdb0Author: frdel <38891707+frdel@users.noreply.github.com> Date: Sat Dec 7 21:51:14 2024 +0100 console print edits for docker commit927c234d69Author: frdel <38891707+frdel@users.noreply.github.com> Date: Sat Dec 7 20:40:28 2024 +0100 openai azure model func name fix commit53a46288f9Author: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Dec 6 15:17:58 2024 +0100 mistral fix, error text output commit6aa37744fcAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Dec 6 14:58:10 2024 +0100 toast fix commitf0be03ea77Author: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Dec 6 14:33:28 2024 +0100 toast errors commit8434682812Author: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Dec 6 11:30:34 2024 +0100 warnings cleanup commit2b94af895dAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Dec 6 10:54:06 2024 +0100 Preload fix commit7f270d4a14Author: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Dec 6 09:44:13 2024 +0100 Server startup log msg commitf9c9b5c933Author: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Dec 6 07:50:15 2024 +0100 Update run_ui.py commitf3ca7e0742Author: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Dec 6 06:21:14 2024 +0100 Update run_ui.py commit21975c5a7cAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Thu Dec 5 20:45:51 2024 +0100 local models docker url commitf0a8b07c4fAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Thu Dec 5 16:40:49 2024 +0100 Server addr notice commit656612726aMerge:49594fe7c2866cAuthor: 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 commit7c2866ca61Author: 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 commit49594fe6ecMerge:f69775470b1fa3Author: 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 commit70b1fa385aAuthor: 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 commitf6977546c1Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Dec 3 22:42:36 2024 +0100 call subordinate fix commitfbe47ac03eAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Dec 3 21:19:03 2024 +0100 Minor fixes commit961dbc405aAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Dec 3 21:10:45 2024 +0100 restart commit357909c16aAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Dec 3 19:41:29 2024 +0100 whisper remote preload commite0b0b6f636Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Dec 3 17:39:56 2024 +0100 nudge commit9fae02b2a5Merge:0ebc142fedf2d4Author: 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 commit0ebc142124Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Dec 3 14:56:33 2024 +0100 ssh connection retry commitdeae13d383Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Dec 3 14:38:57 2024 +0100 root pass fix commit9109fcbf60Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Dec 3 14:28:53 2024 +0100 root password change fix commit46689d6477Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Dec 3 14:22:18 2024 +0100 RFC & SSH exchange for development commitfedf2d4bdcAuthor: 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 commit19f50d6d95Author: frdel <38891707+frdel@users.noreply.github.com> Date: Sun Dec 1 20:50:17 2024 +0100 attachments, files, prompt extras, prompt caching, refactors, cleanups commitc99b1a47d4Author: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Nov 29 08:55:27 2024 +0100 Alpine fix version, STT fixes commit81e653ba2dMerge:857f8b689b8483Author: 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 commit857f8b6d82Author: frdel <38891707+frdel@users.noreply.github.com> Date: Thu Nov 28 23:05:17 2024 +0100 download and remove folders in browser commit89b848312bAuthor: 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 commitb3a27bb442Merge:5e8d6b1bb980eaAuthor: 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 commitbb980ea6b9Author: 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 commitf0126a6ef8Author: Alessandro <155005371+3clyp50@users.noreply.github.com> Date: Wed Nov 27 23:44:20 2024 +0100 style: polishing and consistency commit5e8d6b1c7dAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Wed Nov 27 22:16:13 2024 +0100 Minor fixes commit184f8dcf53Author: frdel <38891707+frdel@users.noreply.github.com> Date: Wed Nov 27 22:05:23 2024 +0100 Pause button fix commit969f142af1Author: frdel <38891707+frdel@users.noreply.github.com> Date: Wed Nov 27 22:01:06 2024 +0100 RFC fix, history bugfixes commit733b8de516Merge:f2057d36a83e79Author: frdel <38891707+frdel@users.noreply.github.com> Date: Wed Nov 27 20:57:15 2024 +0100 Merge branch 'pr/253' into development commit6a83e79d5aAuthor: Alessandro <real.eclypso@gmail.com> Date: Wed Nov 27 20:41:53 2024 +0100 fix: bigger modals commitf2057d3901Author: frdel <38891707+frdel@users.noreply.github.com> Date: Wed Nov 27 17:30:19 2024 +0100 Squashed commit of the following: commite626817332Author: 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). commit306db0ca39Author: 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 commitc95a379bb5Author: Alessandro <real.eclypso@gmail.com> Date: Tue Nov 26 20:17:18 2024 +0100 fix: status-icon commiteddafa8798Author: 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 commite626817332Author: 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). commit306db0ca39Author: 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 commitc95a379bb5Author: Alessandro <real.eclypso@gmail.com> Date: Tue Nov 26 20:17:18 2024 +0100 fix: status-icon commiteddafa8798Author: 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 commit22ecfd660cAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Mon Nov 25 22:14:17 2024 +0100 intervention message fix commitea9c8bf63bAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Mon Nov 25 20:48:52 2024 +0100 minor context window fixes commit489ca317c5Author: frdel <38891707+frdel@users.noreply.github.com> Date: Mon Nov 25 19:01:01 2024 +0100 settings auth fix commita0ff118ad1Author: frdel <38891707+frdel@users.noreply.github.com> Date: Mon Nov 25 17:39:42 2024 +0100 Context window management, work in progress commitc0947e30c7Author: frdel <38891707+frdel@users.noreply.github.com> Date: Thu Nov 21 18:47:40 2024 +0100 API separation commit8db8d3fa18Merge:50348920735bb9Author: 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 commit0735bb9ae8Author: 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) commit9c968ba1cfAuthor: 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. commit50348926dfAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Nov 19 21:56:50 2024 +0100 version info fix commit040de30ef2Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Nov 19 21:21:47 2024 +0100 removed bundles, tests commit020c16ef86Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Nov 19 20:46:08 2024 +0100 git+docker improvements version, build branch commit06260ed4a6Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Nov 19 13:11:54 2024 +0100 searxng fix, ui animation commit41dc7ae146Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Nov 19 11:05:33 2024 +0100 Nodejs eval require path fix commit970db9adc9Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Nov 19 10:37:49 2024 +0100 Whisper fix commitf59ac2b485Author: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Nov 19 09:34:00 2024 +0100 docker /a0 mount fix commitc7046fa97bAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Nov 19 00:43:15 2024 +0100 docker volume map fix commit0ce8344f0bAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Nov 19 00:23:08 2024 +0100 dockerfile, compose, smart cache commitbad3951646Author: frdel <38891707+frdel@users.noreply.github.com> Date: Mon Nov 18 21:41:39 2024 +0100 RFC error messages commit05cbaa0f4dAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Mon Nov 18 21:16:50 2024 +0100 RFC password RFC password protection work in progress commit9d1d2be897Author: frdel <38891707+frdel@users.noreply.github.com> Date: Mon Nov 18 16:18:31 2024 +0100 Dockerfile updates commita7a40ac18fAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Mon Nov 18 10:50:24 2024 +0100 dotenv fix, knowledge tool fic commitba3422d452Author: frdel <38891707+frdel@users.noreply.github.com> Date: Mon Nov 18 09:01:23 2024 +0100 dotenv fix, gitignore update commit9c7339042fAuthor: 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 commite469f6d7baAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Nov 15 09:57:49 2024 +0100 Docker runtime preload commit66f1ab7bafAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Fri Nov 15 09:49:23 2024 +0100 Docker runtime - SSH, runtime args commit02cb41b2fdAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Thu Nov 14 21:49:45 2024 +0100 WIP: docker runtime commitb33b48057dAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Thu Nov 14 21:28:14 2024 +0100 WIP: docker runtime commit7fc17b39c5Author: 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 commit2bf24b76d9Merge:92d94b4a57f0c1Author: 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) commita57f0c1198Author: Alessandro <real.eclypso@gmail.com> Date: Tue Nov 12 15:02:25 2024 +0100 feature: attachments preview and sending (file, code, imgs) commit92d94b4d86Author: frdel <38891707+frdel@users.noreply.github.com> Date: Sun Nov 10 23:44:15 2024 +0100 TTS prototype TTS with default browser API commit1a91334a42Author: 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 commit22f1a2b744Author: frdel <38891707+frdel@users.noreply.github.com> Date: Sun Nov 10 14:25:20 2024 +0100 speech recognition prototype using xenova web only tts commita0b042cfb2Merge:22db39f82ca0d8Author: 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 commit22db39f731Merge:d39beba2b1aa09Author: 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 commit2b1aa09840Author: linuztx <linuztx@gmail.com> Date: Sun Nov 10 14:56:52 2024 +0800 Add auto-downloading cloudflared tunnel manager commitcca85d7f5dAuthor: linuztx <linuztx@gmail.com> Date: Sun Nov 10 14:54:52 2024 +0800 Integrate Cloudflare tunnel support in web UI commit433f44522cAuthor: linuztx <linuztx@gmail.com> Date: Sun Nov 10 14:54:19 2024 +0800 Add USE_CLOUDFLARE environment variable commitd94c3b0467Author: linuztx <linuztx@gmail.com> Date: Sun Nov 10 14:53:45 2024 +0800 Cloudflared binaries commit451fdb08c4Author: linuztx <linuztx@gmail.com> Date: Sun Nov 10 14:52:24 2024 +0800 Add bin directory for cloudflared downloads commit82ca0d800aAuthor: 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. commit3c6a5bee64Author: 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 commitd39beba374Merge:2eb497c9d6b769Author: 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 commit9d6b769dc2Author: 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) commit3c40c86d07Author: 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 commitd84469dff6Author: Alessandro <155005371+3clyp50@users.noreply.github.com> Date: Wed Nov 6 11:17:56 2024 +0100 Mic js and embedding menu + styles commit2eb497c8d2Merge:ef1cdac21933bcAuthor: 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 commit21933bce2fAuthor: Alessandro <real.eclypso@gmail.com> Date: Tue Nov 5 21:07:50 2024 +0100 KaTeX fix and mobile improvements commitef1cdacea2Merge:9626c04553f7bfAuthor: 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 commit553f7bf039Merge:fc03a799626c04Author: Alessandro <155005371+3clyp50@users.noreply.github.com> Date: Tue Nov 5 14:48:53 2024 +0100 Merge remote-tracking branch 'upstream/development' into development commitfc03a7922eAuthor: 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! commit9626c044d5Author: frdel <38891707+frdel@users.noreply.github.com> Date: Mon Nov 4 22:55:56 2024 +0100 UI and settings merge commit255baf0780Merge:1c026ee61b5b83Author: 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 commit61b5b8389aAuthor: Alessandro <155005371+3clyp50@users.noreply.github.com> Date: Mon Nov 4 22:26:07 2024 +0100 other things + Embedding Model selection commit6ff3df03deAuthor: Alessandro <real.eclypso@gmail.com> Date: Mon Nov 4 21:06:48 2024 +0100 toast! commite6ac772a2eAuthor: Alessandro <real.eclypso@gmail.com> Date: Mon Nov 4 20:58:55 2024 +0100 Mobile and UX update commit1a0ceebcafAuthor: Alessandro <155005371+3clyp50@users.noreply.github.com> Date: Mon Nov 4 15:18:06 2024 +0100 Modal styling WIP commitf28a05d739Author: 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 commit1c026ee75fAuthor: frdel <38891707+frdel@users.noreply.github.com> Date: Tue Oct 29 19:39:54 2024 +0100 Behaviour prompt Prototype of adjustable behaviour system prompt commita5d671904dAuthor: 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
468 lines
14 KiB
Python
468 lines
14 KiB
Python
from abc import abstractmethod
|
|
import asyncio
|
|
from collections import OrderedDict
|
|
import json
|
|
import math
|
|
from typing import Coroutine, Literal, TypedDict, cast
|
|
from python.helpers import messages, tokens, settings, call_llm
|
|
from enum import Enum
|
|
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
|
|
|
|
BULK_MERGE_COUNT = 3
|
|
TOPICS_KEEP_COUNT = 3
|
|
CURRENT_TOPIC_RATIO = 0.5
|
|
HISTORY_TOPIC_RATIO = 0.3
|
|
HISTORY_BULK_RATIO = 0.2
|
|
TOPIC_COMPRESS_RATIO = 0.65
|
|
LARGE_MESSAGE_TO_TOPIC_RATIO = 0.25
|
|
|
|
MessageContent = (
|
|
list["MessageContent"]
|
|
| OrderedDict[str, "MessageContent"]
|
|
| list[OrderedDict[str, "MessageContent"]]
|
|
| str
|
|
| list[str]
|
|
)
|
|
|
|
|
|
class OutputMessage(TypedDict):
|
|
ai: bool
|
|
content: MessageContent
|
|
|
|
|
|
class Record:
|
|
def __init__(self):
|
|
pass
|
|
|
|
def get_tokens(self) -> int:
|
|
out = self.output_text()
|
|
return tokens.approximate_tokens(out)
|
|
|
|
@abstractmethod
|
|
async def compress(self) -> bool:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def output(self) -> list[OutputMessage]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def summarize(self) -> str:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def to_dict(self) -> dict:
|
|
pass
|
|
|
|
@staticmethod
|
|
def from_dict(data: dict, history: "History"):
|
|
cls = data["_cls"]
|
|
return globals()[cls].from_dict(data, history=history)
|
|
|
|
def output_langchain(self):
|
|
return output_langchain(self.output())
|
|
|
|
def output_text(self, human_label="user", ai_label="ai"):
|
|
return output_text(self.output(), ai_label, human_label)
|
|
|
|
|
|
class Message(Record):
|
|
def __init__(self, ai: bool, content: MessageContent):
|
|
self.ai = ai
|
|
self.content = content
|
|
self.summary: MessageContent = ""
|
|
|
|
async def compress(self):
|
|
return False
|
|
|
|
def output(self):
|
|
return [OutputMessage(ai=self.ai, content=self.summary or self.content)]
|
|
|
|
def output_langchain(self):
|
|
return output_langchain(self.output())
|
|
|
|
def output_text(self, human_label="user", ai_label="ai"):
|
|
return output_text(self.output(), ai_label, human_label)
|
|
|
|
def to_dict(self):
|
|
return {
|
|
"_cls": "Message",
|
|
"ai": self.ai,
|
|
"content": self.content,
|
|
"summary": self.summary,
|
|
}
|
|
|
|
@staticmethod
|
|
def from_dict(data: dict, history: "History"):
|
|
msg = Message(ai=data["ai"], content=data.get("content", "Content lost"))
|
|
msg.summary = data.get("summary", "")
|
|
return msg
|
|
|
|
|
|
class Topic(Record):
|
|
def __init__(self, history: "History"):
|
|
self.history = history
|
|
self.summary: str = ""
|
|
self.messages: list[Message] = []
|
|
|
|
def add_message(self, ai: bool, content: MessageContent):
|
|
msg = Message(ai=ai, content=content)
|
|
self.messages.append(msg)
|
|
return msg
|
|
|
|
def output(self) -> list[OutputMessage]:
|
|
if self.summary:
|
|
return [OutputMessage(ai=False, content=self.summary)]
|
|
else:
|
|
msgs = [m for r in self.messages for m in r.output()]
|
|
return group_outputs_abab(msgs)
|
|
|
|
async def summarize(self):
|
|
self.summary = await self.summarize_messages(self.messages)
|
|
return self.summary
|
|
|
|
async def compress_large_messages(self) -> bool:
|
|
set = settings.get_settings()
|
|
msg_max_size = (
|
|
set["chat_model_ctx_length"]
|
|
* set["chat_model_ctx_history"]
|
|
* HISTORY_TOPIC_RATIO
|
|
* LARGE_MESSAGE_TO_TOPIC_RATIO
|
|
)
|
|
large_msgs = []
|
|
for m in (m for m in self.messages if not m.summary):
|
|
out = m.output()
|
|
text = output_text(out)
|
|
tok = tokens.approximate_tokens(text)
|
|
leng = len(text)
|
|
if tok > msg_max_size:
|
|
large_msgs.append((m, tok, leng, out))
|
|
large_msgs.sort(key=lambda x: x[1], reverse=True)
|
|
for msg, tok, leng, out in large_msgs:
|
|
trim_to_chars = leng * (msg_max_size / tok)
|
|
trunc = messages.truncate_dict_by_ratio(
|
|
self.history.agent,
|
|
out[0]["content"],
|
|
trim_to_chars * 1.15,
|
|
trim_to_chars * 0.85,
|
|
)
|
|
msg.summary = trunc
|
|
|
|
return True
|
|
return False
|
|
|
|
async def compress(self) -> bool:
|
|
compress = await self.compress_large_messages()
|
|
if not compress:
|
|
compress = await self.compress_attention()
|
|
return compress
|
|
|
|
async def compress_attention(self) -> bool:
|
|
|
|
if len(self.messages) > 2:
|
|
cnt_to_sum = math.ceil((len(self.messages) - 2) * TOPIC_COMPRESS_RATIO)
|
|
msg_to_sum = self.messages[1 : cnt_to_sum + 1]
|
|
summary = await self.summarize_messages(msg_to_sum)
|
|
sum_msg_content = self.history.agent.parse_prompt(
|
|
"fw.msg_summary.md", summary=summary
|
|
)
|
|
sum_msg = Message(False, sum_msg_content)
|
|
self.messages[1 : cnt_to_sum + 1] = [sum_msg]
|
|
return True
|
|
return False
|
|
|
|
async def summarize_messages(self, messages: list[Message]):
|
|
msg_txt = [m.output_text() for m in messages]
|
|
summary = await self.history.agent.call_utility_model(
|
|
system=self.history.agent.read_prompt("fw.topic_summary.sys.md"),
|
|
message=self.history.agent.read_prompt(
|
|
"fw.topic_summary.msg.md", content=msg_txt
|
|
),
|
|
)
|
|
return summary
|
|
|
|
def to_dict(self):
|
|
return {
|
|
"_cls": "Topic",
|
|
"summary": self.summary,
|
|
"messages": [m.to_dict() for m in self.messages],
|
|
}
|
|
|
|
@staticmethod
|
|
def from_dict(data: dict, history: "History"):
|
|
topic = Topic(history=history)
|
|
topic.summary = data["summary"]
|
|
topic.messages = [
|
|
Message.from_dict(m, history=history) for m in data["messages"]
|
|
]
|
|
return topic
|
|
|
|
|
|
class Bulk(Record):
|
|
def __init__(self, history: "History"):
|
|
self.history = history
|
|
self.summary: str = ""
|
|
self.records: list[Record] = []
|
|
|
|
def output(
|
|
self, human_label: str = "user", ai_label: str = "ai"
|
|
) -> list[OutputMessage]:
|
|
if self.summary:
|
|
return [OutputMessage(ai=False, content=self.summary)]
|
|
else:
|
|
msgs = [m for r in self.records for m in r.output()]
|
|
return group_outputs_abab(msgs)
|
|
|
|
async def compress(self):
|
|
return False
|
|
|
|
async def summarize(self):
|
|
self.summary = await self.history.agent.call_utility_model(
|
|
system=self.history.agent.read_prompt("fw.topic_summary.sys.md"),
|
|
message=self.history.agent.read_prompt(
|
|
"fw.topic_summary.msg.md", content=self.output_text()
|
|
),
|
|
)
|
|
return self.summary
|
|
|
|
def to_dict(self):
|
|
return {
|
|
"_cls": "Bulk",
|
|
"summary": self.summary,
|
|
"records": [r.to_dict() for r in self.records],
|
|
}
|
|
|
|
@staticmethod
|
|
def from_dict(data: dict, history: "History"):
|
|
bulk = Bulk(history=history)
|
|
bulk.summary = data["summary"]
|
|
cls = data["_cls"]
|
|
bulk.records = [Record.from_dict(r, history=history) for r in data["records"]]
|
|
return bulk
|
|
|
|
|
|
class History(Record):
|
|
def __init__(self, agent):
|
|
from agent import Agent
|
|
|
|
self.bulks: list[Bulk] = []
|
|
self.topics: list[Topic] = []
|
|
self.current = Topic(history=self)
|
|
self.agent: Agent = agent
|
|
|
|
def is_over_limit(self):
|
|
limit = get_ctx_size_for_history()
|
|
total = self.get_tokens()
|
|
return total > limit
|
|
|
|
def get_bulks_tokens(self) -> int:
|
|
return sum(record.get_tokens() for record in self.bulks)
|
|
|
|
def get_topics_tokens(self) -> int:
|
|
return sum(record.get_tokens() for record in self.topics)
|
|
|
|
def get_current_topic_tokens(self) -> int:
|
|
return self.current.get_tokens()
|
|
|
|
def get_tokens(self) -> int:
|
|
return (
|
|
self.get_bulks_tokens()
|
|
+ self.get_topics_tokens()
|
|
+ self.get_current_topic_tokens()
|
|
)
|
|
|
|
def add_message(self, ai: bool, content: MessageContent):
|
|
return self.current.add_message(ai, content=content)
|
|
|
|
def new_topic(self):
|
|
if self.current.messages:
|
|
self.topics.append(self.current)
|
|
self.current = Topic(history=self)
|
|
|
|
def output(self) -> list[OutputMessage]:
|
|
result: list[OutputMessage] = []
|
|
result += [m for b in self.bulks for m in b.output()]
|
|
result += [m for t in self.topics for m in t.output()]
|
|
result += self.current.output()
|
|
result = group_outputs_abab(result)
|
|
return result
|
|
|
|
@staticmethod
|
|
def from_dict(data: dict, history: "History"):
|
|
history.bulks = [Bulk.from_dict(b, history=history) for b in data["bulks"]]
|
|
history.topics = [Topic.from_dict(t, history=history) for t in data["topics"]]
|
|
history.current = Topic.from_dict(data["current"], history=history)
|
|
return history
|
|
|
|
def to_dict(self):
|
|
return {
|
|
"_cls": "History",
|
|
"bulks": [b.to_dict() for b in self.bulks],
|
|
"topics": [t.to_dict() for t in self.topics],
|
|
"current": self.current.to_dict(),
|
|
}
|
|
|
|
def serialize(self):
|
|
data = self.to_dict()
|
|
return json.dumps(data)
|
|
|
|
async def compress(self):
|
|
compressed = False
|
|
while True:
|
|
curr, hist, bulk = (
|
|
self.get_current_topic_tokens(),
|
|
self.get_topics_tokens(),
|
|
self.get_bulks_tokens(),
|
|
)
|
|
total = get_ctx_size_for_history()
|
|
ratios = [
|
|
(curr, CURRENT_TOPIC_RATIO, "current_topic"),
|
|
(hist, HISTORY_TOPIC_RATIO, "history_topic"),
|
|
(bulk, HISTORY_BULK_RATIO, "history_bulk"),
|
|
]
|
|
ratios = sorted(ratios, key=lambda x: (x[0] / total) / x[1], reverse=True)
|
|
compressed_part = False
|
|
for ratio in ratios:
|
|
if ratio[0] > ratio[1] * total:
|
|
over_part = ratio[2]
|
|
if over_part == "current_topic":
|
|
compressed_part = await self.current.compress()
|
|
elif over_part == "history_topic":
|
|
compressed_part = await self.compress_topics()
|
|
else:
|
|
compressed_part = await self.compress_bulks()
|
|
if compressed_part:
|
|
break
|
|
|
|
if compressed_part:
|
|
compressed = True
|
|
continue
|
|
else:
|
|
return compressed
|
|
|
|
async def compress_topics(self) -> bool:
|
|
# summarize topics one by one
|
|
for topic in self.topics:
|
|
if not topic.summary:
|
|
await topic.summarize()
|
|
return True
|
|
|
|
# move oldest topic to bulks and summarize
|
|
for topic in self.topics:
|
|
bulk = Bulk(history=self)
|
|
bulk.records.append(topic)
|
|
if topic.summary:
|
|
bulk.summary = topic.summary
|
|
else:
|
|
await bulk.summarize()
|
|
self.bulks.append(bulk)
|
|
self.topics.remove(topic)
|
|
return True
|
|
|
|
async def compress_bulks(self):
|
|
# merge bulks if possible
|
|
compressed = await self.merge_bulks_by(BULK_MERGE_COUNT)
|
|
# remove oldest bulk if necessary
|
|
if not compressed:
|
|
self.bulks.pop(0)
|
|
return compressed
|
|
|
|
async def merge_bulks_by(self, count: int):
|
|
if len(self.bulks) > 0:
|
|
return False
|
|
bulks = await asyncio.gather(
|
|
*[
|
|
self.merge_bulks(self.bulks[i : i + count])
|
|
for i in range(0, len(self.bulks), count)
|
|
]
|
|
)
|
|
self.bulks = bulks
|
|
return True
|
|
|
|
async def merge_bulks(self, bulks: list[Bulk]) -> Bulk:
|
|
bulk = Bulk(history=self)
|
|
bulk.records = cast(list[Record], bulks)
|
|
await bulk.summarize()
|
|
return bulk
|
|
|
|
|
|
def deserialize_history(json_data: str, agent) -> History:
|
|
history = History(agent=agent)
|
|
if json_data:
|
|
data = json.loads(json_data)
|
|
history = History.from_dict(data, history=history)
|
|
return history
|
|
|
|
|
|
def get_ctx_size_for_history() -> int:
|
|
set = settings.get_settings()
|
|
return int(set["chat_model_ctx_length"] * set["chat_model_ctx_history"])
|
|
|
|
|
|
def serialize_output(output: OutputMessage, ai_label="ai", human_label="human"):
|
|
return f'{ai_label if output["ai"] else human_label}: {serialize_content(output["content"])}'
|
|
|
|
|
|
def serialize_content(content: MessageContent) -> str:
|
|
if isinstance(content, str):
|
|
return content
|
|
try:
|
|
return json.dumps(content)
|
|
except Exception as e:
|
|
raise e
|
|
|
|
|
|
def group_outputs_abab(outputs: list[OutputMessage]) -> list[OutputMessage]:
|
|
result = []
|
|
for out in outputs:
|
|
if result and result[-1]["ai"] == out["ai"]:
|
|
result[-1] = OutputMessage(
|
|
ai=result[-1]["ai"],
|
|
content=merge_outputs(result[-1]["content"], out["content"]),
|
|
)
|
|
else:
|
|
result.append(out)
|
|
return result
|
|
|
|
|
|
def output_langchain(messages: list[OutputMessage]):
|
|
result = []
|
|
for m in messages:
|
|
if m["ai"]:
|
|
result.append(AIMessage(content=serialize_content(m["content"])))
|
|
else:
|
|
result.append(HumanMessage(content=serialize_content(m["content"])))
|
|
return result
|
|
|
|
|
|
def output_text(messages: list[OutputMessage], ai_label="ai", human_label="human"):
|
|
return "\n".join(serialize_output(o, ai_label, human_label) for o in messages)
|
|
|
|
|
|
def merge_outputs(a: MessageContent, b: MessageContent) -> MessageContent:
|
|
if not isinstance(a, list):
|
|
a = [a]
|
|
if not isinstance(b, list):
|
|
b = [b]
|
|
return a + b # type: ignore
|
|
# return merge_properties(a, b)
|
|
|
|
|
|
def merge_properties(a: MessageContent, b: MessageContent) -> MessageContent:
|
|
if isinstance(a, list):
|
|
if isinstance(b, list):
|
|
return a + b # type: ignore
|
|
else:
|
|
return a + [b]
|
|
elif isinstance(b, list):
|
|
return [a] + b # type: ignore
|
|
elif isinstance(a, dict) and isinstance(b, dict):
|
|
for key, value in b.items():
|
|
if key in a:
|
|
a[key] = merge_properties(a[key], value)
|
|
else:
|
|
a[key] = value
|
|
return a
|
|
elif isinstance(a, str) and isinstance(b, str):
|
|
return a + b
|
|
raise ValueError(f"Cannot merge {a} and {b}")
|