BIG PYTHON REFACTOR

Python scripts moved out of python/ folder to root to be unified with plugins

+ frontend extension around api calls
This commit is contained in:
frdel 2026-03-05 17:28:11 +01:00
parent f94b7d742c
commit d02dda3667
326 changed files with 1096 additions and 862 deletions

View file

@ -105,8 +105,8 @@ Key Files:
## Development Patterns & Conventions ## Development Patterns & Conventions
### Backend (Python) ### Backend (Python)
- Context Access: Use from agent import AgentContext, AgentContextType (not python.helpers.context). - Context Access: Use from agent import AgentContext, AgentContextType (not helpers.context).
- Communication: Use mq from python.helpers.messages to log proactive UI messages: - Communication: Use mq from helpers.messages to log proactive UI messages:
mq.log_user_message(context.id, "Message", source="Plugin") mq.log_user_message(context.id, "Message", source="Plugin")
- API Handlers: Derive from ApiHandler in python/helpers/api.py. - API Handlers: Derive from ApiHandler in python/helpers/api.py.
- Extensions: Use the extension framework in python/helpers/extension.py for lifecycle hooks. - Extensions: Use the extension framework in python/helpers/extension.py for lifecycle hooks.
@ -164,7 +164,7 @@ Key Files:
### API Handler (Good) ### API Handler (Good)
```python ```python
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
class MyHandler(ApiHandler): class MyHandler(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response: async def process(self, input: dict, request: Request) -> dict | Response:
@ -186,7 +186,7 @@ export const store = createStore("myStore", {
### Tool Definition (Good) ### Tool Definition (Good)
```python ```python
from python.helpers.tool import Tool, ToolResult from helpers.tool import Tool, ToolResult
class MyTool(Tool): class MyTool(Tool):
async def execute(self, arg1: str): async def execute(self, arg1: str):

View file

@ -7,7 +7,7 @@ from typing import Any, Awaitable, Coroutine, Dict, Literal
from enum import Enum from enum import Enum
import models import models
from python.helpers import ( from helpers import (
extract_tools, extract_tools,
files, files,
errors, errors,
@ -17,22 +17,21 @@ from python.helpers import (
dirty_json, dirty_json,
subagents, subagents,
) )
from python.helpers import extension from helpers import extension
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
from langchain_core.prompts import ( from langchain_core.prompts import (
ChatPromptTemplate, ChatPromptTemplate,
) )
from langchain_core.messages import SystemMessage, BaseMessage from langchain_core.messages import SystemMessage, BaseMessage
import python.helpers.log as Log import helpers.log as Log
from python.helpers.dirty_json import DirtyJson from helpers.dirty_json import DirtyJson
from python.helpers.defer import DeferredTask from helpers.defer import DeferredTask
from typing import Callable from typing import Callable
from python.helpers.localization import Localization from helpers.localization import Localization
from python.helpers.extension import call_extensions, extensible from helpers.extension import call_extensions, extensible
from python.helpers.errors import RepairableException, InterventionException, HandledException from helpers.errors import RepairableException, InterventionException, HandledException
class AgentContextType(Enum): class AgentContextType(Enum):
USER = "user" USER = "user"
@ -147,7 +146,7 @@ class AgentContext:
@classmethod @classmethod
def get_notification_manager(cls): def get_notification_manager(cls):
if cls._notification_manager is None: if cls._notification_manager is None:
from python.helpers.notification import NotificationManager # type: ignore from helpers.notification import NotificationManager # type: ignore
cls._notification_manager = NotificationManager() cls._notification_manager = NotificationManager()
return cls._notification_manager return cls._notification_manager
@ -177,7 +176,7 @@ class AgentContext:
# recursive is not used now, prepared for context hierarchy # recursive is not used now, prepared for context hierarchy
self.output_data[key] = value self.output_data[key] = value
@extensible # @extensible
def output(self): def output(self):
return { return {
"id": self.id, "id": self.id,
@ -859,7 +858,7 @@ class Agent:
# Try getting tool from MCP first # Try getting tool from MCP first
try: try:
import python.helpers.mcp_handler as mcp_helper import helpers.mcp_handler as mcp_helper
mcp_tool_candidate = mcp_helper.MCPConfig.get_instance().get_tool( mcp_tool_candidate = mcp_helper.MCPConfig.get_instance().get_tool(
self, tool_name self, tool_name
@ -969,13 +968,13 @@ class Agent:
loop_data: LoopData | None, loop_data: LoopData | None,
**kwargs, **kwargs,
): ):
from python.tools.unknown import Unknown from tools.unknown import Unknown
from python.helpers.tool import Tool from helpers.tool import Tool
classes = [] classes = []
# search for tools in agent's folder hierarchy # search for tools in agent's folder hierarchy
paths = subagents.get_paths(self, "tools", name + ".py", default_root="python") paths = subagents.get_paths(self, "tools", name + ".py")
for path in paths: for path in paths:
try: try:

View file

@ -1,4 +1,4 @@
from python.helpers.extension import Extension from helpers.extension import Extension
# this is an example extension that renames the current agent when initialized # this is an example extension that renames the current agent when initialized
# see /extensions folder for all available extension points # see /extensions folder for all available extension points

View file

@ -1,4 +1,4 @@
from python.helpers.tool import Tool, Response from helpers.tool import Tool, Response
# this is an example tool class # this is an example tool class
# don't forget to include instructions in the system prompt by creating # don't forget to include instructions in the system prompt by creating

View file

@ -1,4 +1,4 @@
from python.helpers.tool import Tool, Response from helpers.tool import Tool, Response
# example of a tool redefinition # example of a tool redefinition
# the original response tool is in python/tools/response.py # the original response tool is in python/tools/response.py

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers import subagents from helpers import subagents
class Agents(ApiHandler): class Agents(ApiHandler):

View file

@ -1,8 +1,8 @@
import base64 import base64
import os import os
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import files from helpers import files
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
import json import json

View file

@ -1,5 +1,5 @@
from agent import AgentContext from agent import AgentContext
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
class ApiLogGet(ApiHandler): class ApiLogGet(ApiHandler):

View file

@ -2,11 +2,11 @@ import base64
import os import os
from datetime import datetime, timedelta from datetime import datetime, timedelta
from agent import AgentContext, UserMessage, AgentContextType from agent import AgentContext, UserMessage, AgentContextType
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import files, projects from helpers import files, projects
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
from python.helpers.projects import activate_project from helpers.projects import activate_project
from python.helpers.security import safe_filename from helpers.security import safe_filename
from initialize import initialize_agent from initialize import initialize_agent
import threading import threading

View file

@ -1,7 +1,7 @@
from agent import AgentContext from agent import AgentContext
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
from python.helpers import persist_chat from helpers import persist_chat
import json import json

View file

@ -1,7 +1,7 @@
from agent import AgentContext from agent import AgentContext
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers.persist_chat import remove_chat from helpers.persist_chat import remove_chat
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
import json import json

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response, send_file from helpers.api import ApiHandler, Request, Response, send_file
from python.helpers.backup import BackupService from helpers.backup import BackupService
from python.helpers.persist_chat import save_tmp_chats from helpers.persist_chat import save_tmp_chats
class BackupCreate(ApiHandler): class BackupCreate(ApiHandler):

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers.backup import BackupService from helpers.backup import BackupService
class BackupGetDefaults(ApiHandler): class BackupGetDefaults(ApiHandler):

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers.backup import BackupService from helpers.backup import BackupService
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers.backup import BackupService from helpers.backup import BackupService
from typing import Dict, Any from typing import Dict, Any

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
from python.helpers.backup import BackupService from helpers.backup import BackupService
from python.helpers.persist_chat import load_tmp_chats from helpers.persist_chat import load_tmp_chats
import json import json

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
from python.helpers.backup import BackupService from helpers.backup import BackupService
import json import json

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers.backup import BackupService from helpers.backup import BackupService
class BackupTest(ApiHandler): class BackupTest(ApiHandler):

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers.extension import call_extensions from helpers.extension import call_extensions
class GetBanners(ApiHandler): class GetBanners(ApiHandler):

35
api/cache_reset.py Normal file
View file

@ -0,0 +1,35 @@
from helpers.api import ApiHandler, Request, Response
from helpers import cache
class CacheReset(ApiHandler):
@classmethod
def requires_auth(cls) -> bool:
return False
@classmethod
def requires_csrf(cls) -> bool:
return False
@classmethod
def requires_api_key(cls) -> bool:
return False
@classmethod
def requires_loopback(cls) -> bool:
return True
@classmethod
def get_methods(cls) -> list[str]:
return ["GET", "POST"]
async def process(self, input: dict, request: Request) -> dict | Response:
areas = input.get("areas", [])
if not areas:
cache.clear_all()
else:
for area in areas:
cache.clear(area)
return {"ok": True}

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from python.helpers import settings, projects, guids from helpers import settings, projects, guids
from agent import AgentContext from agent import AgentContext
@ -26,7 +26,7 @@ class CreateChat(ApiHandler):
new_context.set_output_data(projects.CONTEXT_DATA_KEY_PROJECT, current_data_2) new_context.set_output_data(projects.CONTEXT_DATA_KEY_PROJECT, current_data_2)
# New context should appear in other tabs' chat lists via state_push. # New context should appear in other tabs' chat lists via state_push.
from python.helpers.state_monitor_integration import mark_dirty_all from helpers.state_monitor_integration import mark_dirty_all
mark_dirty_all(reason="api.chat_create.CreateChat") mark_dirty_all(reason="api.chat_create.CreateChat")
return { return {

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from python.helpers import persist_chat from helpers import persist_chat
class ExportChat(ApiHandler): class ExportChat(ApiHandler):
async def process(self, input: Input, request: Request) -> Output: async def process(self, input: Input, request: Request) -> Output:

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import files, projects, settings from helpers import files, projects, settings
class GetChatFilesPath(ApiHandler): class GetChatFilesPath(ApiHandler):

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from python.helpers import persist_chat from helpers import persist_chat
class LoadChats(ApiHandler): class LoadChats(ApiHandler):
async def process(self, input: Input, request: Request) -> Output: async def process(self, input: Input, request: Request) -> Output:

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from agent import AgentContext from agent import AgentContext
from python.helpers import persist_chat from helpers import persist_chat
from python.helpers.task_scheduler import TaskScheduler from helpers.task_scheduler import TaskScheduler
class RemoveChat(ApiHandler): class RemoveChat(ApiHandler):
@ -26,7 +26,7 @@ class RemoveChat(ApiHandler):
await scheduler.remove_task_by_uuid(task.uuid) await scheduler.remove_task_by_uuid(task.uuid)
# Context removal affects global chat/task lists in all tabs. # Context removal affects global chat/task lists in all tabs.
from python.helpers.state_monitor_integration import mark_dirty_all from helpers.state_monitor_integration import mark_dirty_all
mark_dirty_all(reason="api.chat_remove.RemoveChat") mark_dirty_all(reason="api.chat_remove.RemoveChat")
return { return {

View file

@ -1,8 +1,8 @@
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from python.helpers import persist_chat from helpers import persist_chat
from python.helpers.task_scheduler import TaskScheduler from helpers.task_scheduler import TaskScheduler
class Reset(ApiHandler): class Reset(ApiHandler):
@ -19,7 +19,7 @@ class Reset(ApiHandler):
persist_chat.remove_msg_files(ctxid) persist_chat.remove_msg_files(ctxid)
# Reset updates context metadata (log guid/version) and must refresh other tabs' lists. # Reset updates context metadata (log guid/version) and must refresh other tabs' lists.
from python.helpers.state_monitor_integration import mark_dirty_all from helpers.state_monitor_integration import mark_dirty_all
mark_dirty_all(reason="api.chat_reset.Reset") mark_dirty_all(reason="api.chat_reset.Reset")
return { return {

View file

@ -1,6 +1,6 @@
import secrets import secrets
from urllib.parse import urlparse from urllib.parse import urlparse
from python.helpers.api import ( from helpers.api import (
ApiHandler, ApiHandler,
Input, Input,
Output, Output,
@ -8,7 +8,7 @@ from python.helpers.api import (
Response, Response,
session, session,
) )
from python.helpers import runtime, dotenv, login from helpers import runtime, dotenv, login
import fnmatch import fnmatch
ALLOWED_ORIGINS_KEY = "ALLOWED_ORIGINS" ALLOWED_ORIGINS_KEY = "ALLOWED_ORIGINS"
@ -104,7 +104,7 @@ class GetCsrfToken(ApiHandler):
# always allow tunnel url if running # always allow tunnel url if running
try: try:
from python.api.tunnel_proxy import process as tunnel_api_process from api.tunnel_proxy import process as tunnel_api_process
tunnel = await tunnel_api_process({"action": "get"}) tunnel = await tunnel_api_process({"action": "get"})
if tunnel and isinstance(tunnel, dict) and tunnel["success"]: if tunnel and isinstance(tunnel, dict) and tunnel["success"]:

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from python.helpers import tokens from helpers import tokens
class GetCtxWindow(ApiHandler): class GetCtxWindow(ApiHandler):

View file

@ -1,9 +1,9 @@
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from python.helpers.file_browser import FileBrowser from helpers.file_browser import FileBrowser
from python.helpers import files, runtime from helpers import files, runtime
from python.api import get_work_dir_files from api import get_work_dir_files
class DeleteWorkDirFile(ApiHandler): class DeleteWorkDirFile(ApiHandler):

View file

@ -4,9 +4,9 @@ import mimetypes
import os import os
from flask import Response from flask import Response
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers import files, runtime from helpers import files, runtime
from python.api import file_info from api import file_info
from urllib.parse import quote from urllib.parse import quote

View file

@ -1,9 +1,9 @@
import mimetypes import mimetypes
import os import os
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers.file_browser import FileBrowser from helpers.file_browser import FileBrowser
from python.helpers import runtime, files from helpers import runtime, files
MAX_EDIT_FILE_SIZE = 1024 * 1024 MAX_EDIT_FILE_SIZE = 1024 * 1024
BINARY_SAMPLE_SIZE = 10 * 1024 BINARY_SAMPLE_SIZE = 10 * 1024

View file

@ -1,6 +1,6 @@
import os import os
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from python.helpers import files, runtime from helpers import files, runtime
from typing import TypedDict from typing import TypedDict
class FileInfoApi(ApiHandler): class FileInfoApi(ApiHandler):

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers.file_browser import FileBrowser from helpers.file_browser import FileBrowser
from python.helpers import runtime, files from helpers import runtime, files
class GetWorkDirFiles(ApiHandler): class GetWorkDirFiles(ApiHandler):

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import errors, git from helpers import errors, git
class HealthCheck(ApiHandler): class HealthCheck(ApiHandler):

View file

@ -1,4 +1,4 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
class GetHistory(ApiHandler): class GetHistory(ApiHandler):

View file

@ -1,7 +1,7 @@
import base64 import base64
import os import os
from python.helpers.api import ApiHandler, Request, Response, send_file from helpers.api import ApiHandler, Request, Response, send_file
from python.helpers import files, runtime from helpers import files, runtime
import io import io
from mimetypes import guess_type from mimetypes import guess_type

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import plugins from helpers import extension
class LoadWebuiExtensions(ApiHandler): class LoadWebuiExtensions(ApiHandler):
@ -15,6 +15,6 @@ class LoadWebuiExtensions(ApiHandler):
if not extension_point: if not extension_point:
return Response(status=400, response="Missing extension_point") return Response(status=400, response="Missing extension_point")
exts = plugins.get_webui_extensions(agent=None, extension_point=extension_point, filters=filters) exts = extension.get_webui_extensions(agent=None, extension_point=extension_point, filters=filters)
return {"extensions": exts or []} return {"extensions": exts or []}

View file

@ -1,4 +1,4 @@
from python.helpers.api import ApiHandler, Request, session from helpers.api import ApiHandler, Request, session
class ApiLogout(ApiHandler): class ApiLogout(ApiHandler):

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from typing import Any from typing import Any
from python.helpers.mcp_handler import MCPConfig from helpers.mcp_handler import MCPConfig
class McpServerGetDetail(ApiHandler): class McpServerGetDetail(ApiHandler):

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from typing import Any from typing import Any
from python.helpers.mcp_handler import MCPConfig from helpers.mcp_handler import MCPConfig
class McpServerGetLog(ApiHandler): class McpServerGetLog(ApiHandler):

View file

@ -1,10 +1,10 @@
import time import time
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from typing import Any from typing import Any
from python.helpers.mcp_handler import MCPConfig from helpers.mcp_handler import MCPConfig
from python.helpers.settings import set_settings_delta from helpers.settings import set_settings_delta
class McpServersApply(ApiHandler): class McpServersApply(ApiHandler):

View file

@ -1,8 +1,8 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from typing import Any from typing import Any
from python.helpers.mcp_handler import MCPConfig from helpers.mcp_handler import MCPConfig
class McpServersStatuss(ApiHandler): class McpServersStatuss(ApiHandler):

View file

@ -1,10 +1,10 @@
from agent import AgentContext, UserMessage from agent import AgentContext, UserMessage
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import files, extension, message_queue as mq from helpers import files, extension, message_queue as mq
import os import os
from python.helpers.security import safe_filename from helpers.security import safe_filename
from python.helpers.defer import DeferredTask from helpers.defer import DeferredTask
class Message(ApiHandler): class Message(ApiHandler):

View file

@ -1,6 +1,6 @@
from agent import AgentContext from agent import AgentContext
from python.helpers.defer import DeferredTask from helpers.defer import DeferredTask
from python.api.message import Message from api.message import Message
class MessageAsync(Message): class MessageAsync(Message):

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import message_queue as mq from helpers import message_queue as mq
from agent import AgentContext from agent import AgentContext
from python.helpers.state_monitor_integration import mark_dirty_for_context from helpers.state_monitor_integration import mark_dirty_for_context
class MessageQueueAdd(ApiHandler): class MessageQueueAdd(ApiHandler):

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import message_queue as mq from helpers import message_queue as mq
from agent import AgentContext from agent import AgentContext
from python.helpers.state_monitor_integration import mark_dirty_for_context from helpers.state_monitor_integration import mark_dirty_for_context
class MessageQueueRemove(ApiHandler): class MessageQueueRemove(ApiHandler):
"""Remove message(s) from queue.""" """Remove message(s) from queue."""

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import message_queue as mq from helpers import message_queue as mq
from agent import AgentContext from agent import AgentContext
from python.helpers.state_monitor_integration import mark_dirty_for_context from helpers.state_monitor_integration import mark_dirty_for_context
class MessageQueueSend(ApiHandler): class MessageQueueSend(ApiHandler):
"""Send queued message(s) immediately.""" """Send queued message(s) immediately."""

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler from helpers.api import ApiHandler
from flask import Request, Response from flask import Request, Response
from python.helpers.notification import NotificationManager, NotificationPriority, NotificationType from helpers.notification import NotificationManager, NotificationPriority, NotificationType
class NotificationCreate(ApiHandler): class NotificationCreate(ApiHandler):

View file

@ -1,4 +1,4 @@
from python.helpers.api import ApiHandler from helpers.api import ApiHandler
from flask import Request, Response from flask import Request, Response
from agent import AgentContext from agent import AgentContext

View file

@ -1,4 +1,4 @@
from python.helpers.api import ApiHandler from helpers.api import ApiHandler
from flask import Request, Response from flask import Request, Response
from agent import AgentContext from agent import AgentContext

View file

@ -1,4 +1,4 @@
from python.helpers.api import ApiHandler from helpers.api import ApiHandler
from flask import Request, Response from flask import Request, Response
from agent import AgentContext from agent import AgentContext

View file

@ -1,4 +1,4 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
class Nudge(ApiHandler): class Nudge(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response: async def process(self, input: dict, request: Request) -> dict | Response:

View file

@ -1,4 +1,4 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
class Pause(ApiHandler): class Pause(ApiHandler):

View file

@ -4,8 +4,8 @@ import subprocess
import sys import sys
from datetime import datetime, timezone from datetime import datetime, timezone
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import plugins, files from helpers import plugins, files
class Plugins(ApiHandler): class Plugins(ApiHandler):

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers import plugins from helpers import plugins
class PluginsList(ApiHandler): class PluginsList(ApiHandler):
async def process(self, input: Input, request: Request) -> Output: async def process(self, input: Input, request: Request) -> Output:

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers.state_snapshot import build_snapshot from helpers.state_snapshot import build_snapshot
class Poll(ApiHandler): class Poll(ApiHandler):

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from python.helpers import projects from helpers import projects
from python.helpers.notification import NotificationManager, NotificationType, NotificationPriority from helpers.notification import NotificationManager, NotificationType, NotificationPriority
class Projects(ApiHandler): class Projects(ApiHandler):

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers.file_browser import FileBrowser from helpers.file_browser import FileBrowser
from python.helpers import runtime from helpers import runtime
from python.api import get_work_dir_files from api import get_work_dir_files
class RenameWorkDirFile(ApiHandler): class RenameWorkDirFile(ApiHandler):

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import process from helpers import process
class Restart(ApiHandler): class Restart(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response: async def process(self, input: dict, request: Request) -> dict | Response:

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import runtime from helpers import runtime
class RFC(ApiHandler): class RFC(ApiHandler):

View file

@ -1,11 +1,11 @@
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers.task_scheduler import ( from helpers.task_scheduler import (
TaskScheduler, ScheduledTask, AdHocTask, PlannedTask, TaskSchedule, TaskScheduler, ScheduledTask, AdHocTask, PlannedTask, TaskSchedule,
serialize_task, parse_task_schedule, parse_task_plan, TaskType serialize_task, parse_task_schedule, parse_task_plan, TaskType
) )
from python.helpers.projects import load_basic_project_data from helpers.projects import load_basic_project_data
from python.helpers.localization import Localization from helpers.localization import Localization
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
import random import random

View file

@ -1,8 +1,8 @@
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers.task_scheduler import TaskScheduler, TaskState from helpers.task_scheduler import TaskScheduler, TaskState
from python.helpers.localization import Localization from helpers.localization import Localization
from agent import AgentContext from agent import AgentContext
from python.helpers import persist_chat from helpers import persist_chat
class SchedulerTaskDelete(ApiHandler): class SchedulerTaskDelete(ApiHandler):

View file

@ -1,7 +1,7 @@
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers.task_scheduler import TaskScheduler, TaskState from helpers.task_scheduler import TaskScheduler, TaskState
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
from python.helpers.localization import Localization from helpers.localization import Localization
class SchedulerTaskRun(ApiHandler): class SchedulerTaskRun(ApiHandler):

View file

@ -1,9 +1,9 @@
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers.task_scheduler import ( from helpers.task_scheduler import (
TaskScheduler, ScheduledTask, AdHocTask, PlannedTask, TaskState, TaskScheduler, ScheduledTask, AdHocTask, PlannedTask, TaskState,
serialize_task, parse_task_schedule, parse_task_plan serialize_task, parse_task_schedule, parse_task_plan
) )
from python.helpers.localization import Localization from helpers.localization import Localization
class SchedulerTaskUpdate(ApiHandler): class SchedulerTaskUpdate(ApiHandler):

View file

@ -1,8 +1,8 @@
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers.task_scheduler import TaskScheduler from helpers.task_scheduler import TaskScheduler
import traceback import traceback
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
from python.helpers.localization import Localization from helpers.localization import Localization
class SchedulerTasksList(ApiHandler): class SchedulerTasksList(ApiHandler):

View file

@ -1,9 +1,9 @@
from datetime import datetime from datetime import datetime
from python.helpers.api import ApiHandler, Input, Output, Request from helpers.api import ApiHandler, Input, Output, Request
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
from python.helpers.task_scheduler import TaskScheduler from helpers.task_scheduler import TaskScheduler
from python.helpers.localization import Localization from helpers.localization import Localization
class SchedulerTick(ApiHandler): class SchedulerTick(ApiHandler):

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import settings from helpers import settings
class GetSettings(ApiHandler): class GetSettings(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response: async def process(self, input: dict, request: Request) -> dict | Response:

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import settings from helpers import settings
from typing import Any from typing import Any

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import file_tree, files from helpers import file_tree, files
class SettingsWorkdirFileStructure(ApiHandler): class SettingsWorkdirFileStructure(ApiHandler):

View file

@ -1,5 +1,5 @@
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from python.helpers import runtime, skills, projects, files from helpers import runtime, skills, projects, files
class Skills(ApiHandler): class Skills(ApiHandler):

View file

@ -5,9 +5,9 @@ import time
import uuid import uuid
from pathlib import Path from pathlib import Path
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import files from helpers import files
from python.helpers.skills_import import import_skills from helpers.skills_import import import_skills
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename

View file

@ -5,9 +5,9 @@ import time
import uuid import uuid
from pathlib import Path from pathlib import Path
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import files from helpers import files
from python.helpers.skills_import import import_skills from helpers.skills_import import import_skills
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename

View file

@ -1,9 +1,9 @@
from python.helpers.api import ApiHandler, Input, Output, Request, Response from helpers.api import ApiHandler, Input, Output, Request, Response
from python.helpers import subagents from helpers import subagents
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from python.helpers import projects from helpers import projects
class Subagents(ApiHandler): class Subagents(ApiHandler):
async def process(self, input: Input, request: Request) -> Output: async def process(self, input: Input, request: Request) -> Output:

View file

@ -1,8 +1,8 @@
# api/synthesize.py # api/synthesize.py
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import runtime, settings, kokoro_tts from helpers import runtime, settings, kokoro_tts
class Synthesize(ApiHandler): class Synthesize(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response: async def process(self, input: dict, request: Request) -> dict | Response:

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import runtime, settings, whisper from helpers import runtime, settings, whisper
class Transcribe(ApiHandler): class Transcribe(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response: async def process(self, input: dict, request: Request) -> dict | Response:

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import runtime from helpers import runtime
from python.helpers.tunnel_manager import TunnelManager from helpers.tunnel_manager import TunnelManager
class Tunnel(ApiHandler): class Tunnel(ApiHandler):
async def process(self, input: dict, request: Request) -> dict | Response: async def process(self, input: dict, request: Request) -> dict | Response:

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import dotenv, runtime from helpers import dotenv, runtime
from python.helpers.tunnel_manager import TunnelManager from helpers.tunnel_manager import TunnelManager
import requests import requests
@ -34,5 +34,5 @@ async def process(input: dict) -> dict | Response:
return {"error": str(e)} return {"error": str(e)}
else: else:
# forward to API handler directly # forward to API handler directly
from python.api.tunnel import process as local_process from api.tunnel import process as local_process
return await local_process(input) return await local_process(input)

View file

@ -1,6 +1,6 @@
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers import files from helpers import files
from python.helpers.security import safe_filename from helpers.security import safe_filename
class UploadFile(ApiHandler): class UploadFile(ApiHandler):

View file

@ -1,9 +1,9 @@
import base64 import base64
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
from python.helpers.api import ApiHandler, Request, Response from helpers.api import ApiHandler, Request, Response
from python.helpers.file_browser import FileBrowser from helpers.file_browser import FileBrowser
from python.helpers import files, runtime from helpers import files, runtime
from python.api import get_work_dir_files from api import get_work_dir_files
import os import os

View file

@ -37,16 +37,16 @@ Skills you create here can be used in any of these platforms!
```bash ```bash
# Create a new skill interactively # Create a new skill interactively
python -m python.helpers.skills_cli create my-skill-name python -m helpers.skills_cli create my-skill-name
# List all available skills # List all available skills
python -m python.helpers.skills_cli list python -m helpers.skills_cli list
# Validate a skill # Validate a skill
python -m python.helpers.skills_cli validate my-skill-name python -m helpers.skills_cli validate my-skill-name
# Search skills # Search skills
python -m python.helpers.skills_cli search "keyword" python -m helpers.skills_cli search "keyword"
``` ```
### Manual Creation ### Manual Creation
@ -161,7 +161,7 @@ Ask yourself:
```bash ```bash
# Using CLI # Using CLI
python -m python.helpers.skills_cli create my-awesome-skill python -m helpers.skills_cli create my-awesome-skill
# Or manually # Or manually
mkdir -p usr/skills/my-awesome-skill mkdir -p usr/skills/my-awesome-skill
@ -225,7 +225,7 @@ This skill includes helper scripts:
```bash ```bash
# Validate the skill # Validate the skill
python -m python.helpers.skills_cli validate my-awesome-skill python -m helpers.skills_cli validate my-awesome-skill
# Test in Agent Zero # Test in Agent Zero
# Start the agent and ask it to perform the task your skill handles # Start the agent and ask it to perform the task your skill handles
@ -281,7 +281,7 @@ One skill = one expertise area. If your skill is getting too long, split it:
1. **Validate Structure:** 1. **Validate Structure:**
```bash ```bash
python -m python.helpers.skills_cli validate my-skill python -m helpers.skills_cli validate my-skill
``` ```
2. **Test Semantic Recall:** 2. **Test Semantic Recall:**
@ -304,7 +304,7 @@ One skill = one expertise area. If your skill is getting too long, split it:
2. **Create Your Skill:** 2. **Create Your Skill:**
```bash ```bash
python -m python.helpers.skills_cli create my-skill python -m helpers.skills_cli create my-skill
# Edit usr/skills/my-skill/SKILL.md # Edit usr/skills/my-skill/SKILL.md
``` ```

View file

@ -48,7 +48,7 @@ To create a custom extension:
```python ```python
# File: /agents/_example/extensions/agent_init/_10_example_extension.py # File: /agents/_example/extensions/agent_init/_10_example_extension.py
from python.helpers.extension import Extension from helpers.extension import Extension
class ExampleExtension(Extension): class ExampleExtension(Extension):
async def execute(self, **kwargs): async def execute(self, **kwargs):
@ -80,7 +80,7 @@ When a tool with the same name is requested, Agent Zero first checks for its exi
```python ```python
# File: /agents/_example/tools/response.py # File: /agents/_example/tools/response.py
from python.helpers.tool import Tool, Response from helpers.tool import Tool, Response
# example of a tool redefinition # example of a tool redefinition
# the original response tool is in python/tools/response.py # the original response tool is in python/tools/response.py
@ -145,8 +145,8 @@ When a prompt file is processed, Agent Zero automatically looks for a correspond
If you have a prompt file `agent.system.tools.md`, you can create `agent.system.tools.py` alongside it: If you have a prompt file `agent.system.tools.md`, you can create `agent.system.tools.py` alongside it:
```python ```python
from python.helpers.files import VariablesPlugin from helpers.files import VariablesPlugin
from python.helpers import files from helpers import files
class Tools(VariablesPlugin): class Tools(VariablesPlugin):
def get_variables(self, file: str, backup_dirs: list[str] | None = None) -> dict[str, Any]: def get_variables(self, file: str, backup_dirs: list[str] | None = None) -> dict[str, Any]:

View file

@ -10,7 +10,7 @@ Quick guide for using the notification system in Agent Zero.
Use `AgentNotification` helper methods anywhere in your Python code: Use `AgentNotification` helper methods anywhere in your Python code:
```python ```python
from python.helpers.notification import AgentNotification from helpers.notification import AgentNotification
# Basic notifications # Basic notifications
AgentNotification.info("Operation completed") AgentNotification.info("Operation completed")

View file

@ -146,7 +146,7 @@ Handlers are discovered deterministically from `python/websocket_handlers/`:
Create handler modules under the appropriate namespace entry and inherit from `WebSocketHandler`. Create handler modules under the appropriate namespace entry and inherit from `WebSocketHandler`.
```python ```python
from python.helpers.websocket import WebSocketHandler from helpers.websocket import WebSocketHandler
class DashboardHandler(WebSocketHandler): class DashboardHandler(WebSocketHandler):
@classmethod @classmethod

View file

@ -1,10 +1,10 @@
from datetime import datetime, timezone from datetime import datetime, timezone
from python.helpers.extension import Extension from helpers.extension import Extension
from agent import LoopData from agent import LoopData
from python.helpers.localization import Localization from helpers.localization import Localization
from python.helpers.errors import InterventionException from helpers.errors import InterventionException
from python.helpers import errors from helpers import errors
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
class HandleInterventionException(Extension): class HandleInterventionException(Extension):

View file

@ -1,10 +1,10 @@
from datetime import datetime, timezone from datetime import datetime, timezone
from python.helpers.extension import Extension from helpers.extension import Extension
from agent import LoopData from agent import LoopData
from python.helpers.localization import Localization from helpers.localization import Localization
from python.helpers.errors import RepairableException from helpers.errors import RepairableException
from python.helpers import errors from helpers import errors
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
class HandleRepairableException(Extension): class HandleRepairableException(Extension):

View file

@ -1,10 +1,10 @@
import asyncio import asyncio
from python.helpers.extension import Extension from helpers.extension import Extension
from python.helpers.print_style import PrintStyle from helpers.print_style import PrintStyle
from python.helpers import errors from helpers import errors
from python.helpers.errors import HandledException from helpers.errors import HandledException
class HandleCriticalException(Extension): class HandleCriticalException(Extension):

View file

@ -1,6 +1,6 @@
import json import json
from agent import LoopData from agent import LoopData
from python.helpers.extension import Extension from helpers.extension import Extension
class InitialMessage(Extension): class InitialMessage(Extension):
@ -10,6 +10,8 @@ class InitialMessage(Extension):
Add an initial greeting message when first user message is processed. Add an initial greeting message when first user message is processed.
Called only once per session via _process_chain method. Called only once per session via _process_chain method.
""" """
if not self.agent:
return
# Only add initial message for main agent (A0), not subordinate agents # Only add initial message for main agent (A0), not subordinate agents
if self.agent.number != 0: if self.agent.number != 0:

View file

@ -1,6 +1,6 @@
from initialize import initialize_agent from initialize import initialize_agent
from python.helpers import dirty_json, files, subagents, projects from helpers import dirty_json, files, subagents, projects
from python.helpers.extension import Extension from helpers.extension import Extension
class LoadProfileSettings(Extension): class LoadProfileSettings(Extension):

View file

@ -1,5 +1,5 @@
from python.helpers.extension import Extension from helpers.extension import Extension
from python.helpers import dotenv from helpers import dotenv
import re import re

View file

@ -1,5 +1,5 @@
from python.helpers.extension import Extension from helpers.extension import Extension
from python.helpers import settings as settings_helper from helpers import settings as settings_helper
import models import models

View file

@ -1,4 +1,4 @@
from python.helpers.extension import Extension from helpers.extension import Extension
import os import os
import psutil import psutil

View file

@ -1,15 +1,18 @@
from python.helpers import persist_chat, tokens from helpers import persist_chat, tokens
from python.helpers.extension import Extension from helpers.extension import Extension
from agent import LoopData from agent import LoopData
import asyncio import asyncio
from python.helpers.log import LogItem from helpers.log import LogItem
from python.helpers import log from helpers import log
import math import math
class LogForStream(Extension): class LogForStream(Extension):
async def execute(self, loop_data: LoopData = LoopData(), text: str = "", **kwargs): async def execute(self, loop_data: LoopData = LoopData(), text: str = "", **kwargs):
if not self.agent:
return
# create log message and store it in loop data temporary params # create log message and store it in loop data temporary params
if "log_item_generating" not in loop_data.params_temporary: if "log_item_generating" not in loop_data.params_temporary:
loop_data.params_temporary["log_item_generating"] = ( loop_data.params_temporary["log_item_generating"] = (

View file

@ -1,10 +1,13 @@
from python.helpers.extension import Extension from helpers.extension import Extension
from python.helpers.secrets import get_secrets_manager from helpers.secrets import get_secrets_manager
class MaskErrorSecrets(Extension): class MaskErrorSecrets(Extension):
async def execute(self, **kwargs): async def execute(self, **kwargs):
if not self.agent:
return
# Get error data from kwargs # Get error data from kwargs
msg = kwargs.get("msg") msg = kwargs.get("msg")
if not msg: if not msg:

View file

@ -1,10 +1,13 @@
from python.helpers.extension import Extension from helpers.extension import Extension
from python.helpers.secrets import get_secrets_manager from helpers.secrets import get_secrets_manager
class MaskHistoryContent(Extension): class MaskHistoryContent(Extension):
async def execute(self, **kwargs): async def execute(self, **kwargs):
if not self.agent:
return
# Get content data from kwargs # Get content data from kwargs
content_data = kwargs.get("content_data") content_data = kwargs.get("content_data")
if not content_data: if not content_data:

Some files were not shown because too many files have changed in this diff Show more