mindroot 9.3.0__py3-none-any.whl → 9.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mindroot/coreplugins/admin/__init__.py +3 -1
- mindroot/coreplugins/admin/agent_router.py +250 -7
- mindroot/coreplugins/admin/asset_manager.py +164 -0
- mindroot/coreplugins/admin/command_router.py +236 -1
- mindroot/coreplugins/admin/mcp_catalog_routes.py +156 -0
- mindroot/coreplugins/admin/mcp_publish_routes.py +450 -0
- mindroot/coreplugins/admin/mcp_registry_routes.py +495 -0
- mindroot/coreplugins/admin/mcp_routes.py +216 -0
- mindroot/coreplugins/admin/mod.py +62 -0
- mindroot/coreplugins/admin/oauth_callback_router.py +84 -0
- mindroot/coreplugins/admin/persona_handler.py +15 -6
- mindroot/coreplugins/admin/persona_router.py +158 -2
- mindroot/coreplugins/admin/plugin_manager.py +63 -0
- mindroot/coreplugins/admin/plugin_router_fixed.py +23 -0
- mindroot/coreplugins/admin/plugin_router_new_not_working.py +145 -0
- mindroot/coreplugins/admin/plugin_routes.py +114 -0
- mindroot/coreplugins/admin/registry_settings_routes.py +140 -0
- mindroot/coreplugins/admin/router.py +116 -15
- mindroot/coreplugins/admin/service_models.py +1 -1
- mindroot/coreplugins/admin/settings_router.py +1 -0
- mindroot/coreplugins/admin/static/css/admin-custom.css +357 -2
- mindroot/coreplugins/admin/static/css/dark.css +1 -0
- mindroot/coreplugins/admin/static/css/default.css +4 -0
- mindroot/coreplugins/admin/static/js/about-info.js +367 -0
- mindroot/coreplugins/admin/static/js/agent-form.js +83 -3
- mindroot/coreplugins/admin/static/js/api-key-script.js +307 -0
- mindroot/coreplugins/admin/static/js/mcp-manager.js +348 -0
- mindroot/coreplugins/admin/static/js/mcp-publisher.js +780 -0
- mindroot/coreplugins/admin/static/js/persona-editor.js +34 -5
- mindroot/coreplugins/admin/static/js/plugin-toggle.js +1 -1
- mindroot/coreplugins/admin/static/js/recommended-plugin-install.js +63 -0
- mindroot/coreplugins/admin/static/js/registry-auth-section.js +132 -0
- mindroot/coreplugins/admin/static/js/registry-manager-base.js +613 -0
- mindroot/coreplugins/admin/static/js/registry-manager-old.js +385 -0
- mindroot/coreplugins/admin/static/js/registry-manager-publish-old-delete.js +166 -0
- mindroot/coreplugins/admin/static/js/registry-manager.js +351 -0
- mindroot/coreplugins/admin/static/js/registry-publish-section.js +377 -0
- mindroot/coreplugins/admin/static/js/registry-search-section.js +400 -0
- mindroot/coreplugins/admin/static/js/registry-search-section.js.bak +3 -0
- mindroot/coreplugins/admin/static/js/registry-settings.js +69 -0
- mindroot/coreplugins/admin/static/js/registry-shared-services.js +857 -0
- mindroot/coreplugins/admin/static/js/registry-simple-sections.js +85 -0
- mindroot/coreplugins/admin/static/js/secure-widget-manager.js +438 -0
- mindroot/coreplugins/admin/static/logo.png +0 -0
- mindroot/coreplugins/admin/templates/admin.jinja2 +275 -110
- mindroot/coreplugins/agent/Assistant/agent.json +27 -11
- mindroot/coreplugins/agent/agent.py +2 -2
- mindroot/coreplugins/agent/command_parser.py +25 -10
- mindroot/coreplugins/agent/templates/system.jinja2 +0 -12
- mindroot/coreplugins/chat/__init__.py +4 -1
- mindroot/coreplugins/chat/router.py +132 -20
- mindroot/coreplugins/chat/router_dedup_patch.py +20 -0
- mindroot/coreplugins/chat/services.py +31 -1
- mindroot/coreplugins/chat/static/css/action-fix.css +32 -0
- mindroot/coreplugins/chat/static/css/admin-custom.css +5 -3
- mindroot/coreplugins/chat/static/css/dark.css +24 -3
- mindroot/coreplugins/chat/static/css/default.css +24 -3
- mindroot/coreplugins/chat/static/css/main.css +1 -0
- mindroot/coreplugins/chat/static/js/action.js +137 -60
- mindroot/coreplugins/chat/static/js/chat-history.js +3 -0
- mindroot/coreplugins/chat/static/js/chat.js +59 -16
- mindroot/coreplugins/chat/static/js/chat.js.diff +221 -0
- mindroot/coreplugins/chat/static/js/chatform.js +2 -2
- mindroot/coreplugins/chat/static/site.webmanifest +1 -1
- mindroot/coreplugins/chat/templates/chat.jinja2 +3 -3
- mindroot/coreplugins/chat/widget_manager.py +139 -0
- mindroot/coreplugins/chat/widget_routes.py +287 -0
- mindroot/coreplugins/check_list/inject/admin.jinja2 +1 -1
- mindroot/coreplugins/email/__init__.py +2 -0
- mindroot/coreplugins/email/email_provider.py +2 -2
- mindroot/coreplugins/email/mod.py +100 -0
- mindroot/coreplugins/email/services.py +5 -3
- mindroot/coreplugins/email/smtp_handler.py +9 -3
- mindroot/coreplugins/email/test_email_service.py +75 -0
- mindroot/coreplugins/env_manager/mod.py +61 -25
- mindroot/coreplugins/home/router.py +37 -2
- mindroot/coreplugins/home/static/imgs/logo.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo.png.bak +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal2.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal_detailed.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal_python.png +0 -0
- mindroot/coreplugins/home/templates/home.jinja2 +15 -6
- mindroot/coreplugins/index/indices/default/index.json +6 -6
- mindroot/coreplugins/jwt_auth/middleware.py +47 -2
- mindroot/coreplugins/jwt_auth/mod.py +40 -17
- mindroot/coreplugins/l8n/__init__.py +6 -0
- mindroot/coreplugins/l8n/debug_loader.py +85 -0
- mindroot/coreplugins/l8n/debug_middleware.py +74 -0
- mindroot/coreplugins/l8n/l8n_constants.py +19 -0
- mindroot/coreplugins/l8n/language_detection.py +183 -0
- mindroot/coreplugins/l8n/middleware.py +151 -0
- mindroot/coreplugins/l8n/mod.py +277 -0
- mindroot/coreplugins/l8n/monkey_patch_to_delete.py +186 -0
- mindroot/coreplugins/l8n/test_enhanced.py +298 -0
- mindroot/coreplugins/l8n/test_l8n.py +95 -0
- mindroot/coreplugins/l8n/test_l8n_standalone.py +251 -0
- mindroot/coreplugins/l8n/test_middleware.py +272 -0
- mindroot/coreplugins/l8n/utils.py +232 -0
- mindroot/coreplugins/mcp_/__init__.py +14 -0
- mindroot/coreplugins/mcp_/catalog_commands.py +328 -0
- mindroot/coreplugins/mcp_/catalog_manager.py +263 -0
- mindroot/coreplugins/mcp_/dynamic_commands.py +154 -0
- mindroot/coreplugins/mcp_/mcp_manager.py +1031 -0
- mindroot/coreplugins/mcp_/mod.py +367 -0
- mindroot/coreplugins/mcp_/oauth_storage.py +144 -0
- mindroot/coreplugins/mcp_/server_installer.py +79 -0
- mindroot/coreplugins/mcp_/setup.py +26 -0
- mindroot/coreplugins/mcp_/test_dynamic_commands.py +134 -0
- mindroot/coreplugins/mcp_/testmcpclient.py +92 -0
- mindroot/coreplugins/persona/mod.py +12 -7
- mindroot/coreplugins/signup/templates/signup.jinja2 +1 -1
- mindroot/coreplugins/subscriptions/__init__.py +1 -0
- mindroot/coreplugins/subscriptions/mod.py +14 -3
- mindroot/coreplugins/subscriptions/router.py +3 -0
- mindroot/coreplugins/user_service/__init__.py +1 -2
- mindroot/coreplugins/user_service/admin_init.py +1 -0
- mindroot/coreplugins/user_service/email_service.py +72 -17
- mindroot/coreplugins/user_service/mod.py +10 -2
- mindroot/coreplugins/user_service/router.py +2 -0
- mindroot/lib/auth/api_key.py +28 -0
- mindroot/lib/cli/plugins.py +94 -0
- mindroot/lib/plugins/default_plugin_manifest.json +20 -0
- mindroot/lib/plugins/installation.py +5 -5
- mindroot/lib/plugins/l8n_static_handler.py +225 -0
- mindroot/lib/plugins/loader.py +33 -3
- mindroot/lib/plugins/loader_with_l8n.py +281 -0
- mindroot/lib/plugins/manifest.py +236 -24
- mindroot/lib/providers/commands.py +3 -1
- mindroot/lib/route_decorators.py +5 -5
- mindroot/lib/templates.py +183 -11
- mindroot/lib/utils/merge_arrays.py +1 -1
- mindroot/migrate.py +39 -20
- mindroot/registry/data_access.py +1 -1
- mindroot/server.py +42 -13
- mindroot/server_missing_normal_args.py +197 -0
- mindroot/server_prev.py +173 -0
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/METADATA +7 -2
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/RECORD +144 -112
- mindroot/coreplugins/admin/static/favicon/about.txt +0 -6
- mindroot/coreplugins/admin/static/favicon/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/admin/static/favicon/apple-touch-icon.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon-16x16.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon-32x32.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon.ico +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/about.txt +0 -6
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon.ico +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/site.webmanifest +0 -1
- mindroot/coreplugins/admin/static/favicon/logo.png +0 -0
- mindroot/coreplugins/admin/static/favicon/site.webmanifest +0 -1
- mindroot/coreplugins/admin/static/js/backup/agent-editor.js +0 -186
- mindroot/coreplugins/admin/static/js/backup/agent-form.js +0 -1133
- mindroot/coreplugins/admin/static/js/backup/agent-list.js +0 -94
- mindroot/coreplugins/chat/static/favicon/about.txt +0 -6
- mindroot/coreplugins/chat/static/favicon/android-chrome-192x192.png +0 -0
- mindroot/coreplugins/chat/static/favicon/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/chat/static/favicon/apple-touch-icon.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon-16x16.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon-32x32.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon.ico +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/about.txt +0 -6
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon.ico +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/site.webmanifest +0 -1
- mindroot/coreplugins/chat/static/favicon/logo.png +0 -0
- mindroot/coreplugins/chat/static/favicon/site.webmanifest +0 -1
- mindroot/coreplugins/index/default.json +0 -76
- mindroot/coreplugins/user_service/file_trigger_service.py +0 -12
- mindroot/coreplugins/user_service/hooks.py +0 -23
- /mindroot/coreplugins/{admin/static/favicon/android-chrome-192x192.png → home/static/imgs/backuplogo.png} +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/WHEEL +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/entry_points.txt +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/licenses/LICENSE +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
# This file is required to make Python treat the directory as a package.
|
|
2
2
|
from .mod import *
|
|
3
3
|
from .services import *
|
|
4
4
|
from .commands import *
|
|
5
|
+
|
|
6
|
+
# Import widget manager to ensure it's loaded
|
|
7
|
+
from .widget_manager import widget_manager
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from fastapi import APIRouter, HTTPException, Request, Response, Depends
|
|
2
|
-
from fastapi.responses import HTMLResponse, RedirectResponse
|
|
1
|
+
from fastapi import APIRouter, HTTPException, Request, Response, Depends, Query
|
|
2
|
+
from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
|
|
3
3
|
from fastapi import File, UploadFile, Form
|
|
4
4
|
from sse_starlette.sse import EventSourceResponse
|
|
5
5
|
from .models import MessageParts
|
|
@@ -22,6 +22,7 @@ import json
|
|
|
22
22
|
from lib.chatcontext import ChatContext
|
|
23
23
|
import shutil
|
|
24
24
|
from pydantic import BaseModel
|
|
25
|
+
from lib.auth.api_key import verify_api_key
|
|
25
26
|
|
|
26
27
|
router = APIRouter()
|
|
27
28
|
|
|
@@ -52,20 +53,38 @@ async def context1(request: Request, log_id: str):
|
|
|
52
53
|
print(context)
|
|
53
54
|
return "ok"
|
|
54
55
|
|
|
55
|
-
@router.get("/context2/{log_id}")
|
|
56
|
-
async def context2(request: Request, log_id: str):
|
|
57
|
-
user = request.state.user.username
|
|
58
|
-
context = await get_context(log_id, user)
|
|
59
|
-
print(context)
|
|
60
|
-
return "ok"
|
|
61
56
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
# need to serve persona images from ./personas/local/[persona_path]/avatar.png
|
|
58
|
+
@router.get("/chat/personas/{persona_path:path}/avatar.png")
|
|
59
|
+
async def get_persona_avatar(persona_path: str):
|
|
60
|
+
# Check if this is a registry persona with deduplicated assets
|
|
61
|
+
if persona_path.startswith("registry/"):
|
|
62
|
+
persona_json_path = f"personas/{persona_path}/persona.json"
|
|
63
|
+
if os.path.exists(persona_json_path):
|
|
64
|
+
try:
|
|
65
|
+
with open(persona_json_path, "r") as f:
|
|
66
|
+
persona_data = json.load(f)
|
|
67
|
+
|
|
68
|
+
# Check if persona has asset hashes (deduplicated storage)
|
|
69
|
+
asset_hashes = persona_data.get("asset_hashes", {})
|
|
70
|
+
if "avatar" in asset_hashes:
|
|
71
|
+
# Redirect to deduplicated asset endpoint
|
|
72
|
+
return RedirectResponse(f"/assets/{asset_hashes['avatar']}")
|
|
73
|
+
except Exception as e:
|
|
74
|
+
print(f"Error checking for deduplicated assets: {e}")
|
|
75
|
+
|
|
76
|
+
# Handle registry personas: registry/owner/name
|
|
77
|
+
if persona_path.startswith('registry/'):
|
|
78
|
+
file_path = f"personas/{persona_path}/avatar.png"
|
|
79
|
+
else:
|
|
80
|
+
# Legacy support: check local first, then shared
|
|
81
|
+
file_path = f"personas/local/{persona_path}/avatar.png"
|
|
82
|
+
if not os.path.exists(file_path):
|
|
83
|
+
file_path = f"personas/registry/{persona_path}/avatar.png"
|
|
84
|
+
|
|
67
85
|
if not os.path.exists(file_path):
|
|
68
|
-
|
|
86
|
+
resolved = os.path.realpath(file_path)
|
|
87
|
+
return {"error": "File not found: " + resolved}
|
|
69
88
|
|
|
70
89
|
with open(file_path, "rb") as f:
|
|
71
90
|
image_bytes = f.read()
|
|
@@ -79,6 +98,48 @@ async def get_persona_avatar(persona_name: str):
|
|
|
79
98
|
}
|
|
80
99
|
)
|
|
81
100
|
|
|
101
|
+
@router.get("/chat/personas/{persona_path:path}/faceref.png")
|
|
102
|
+
async def get_persona_faceref(persona_path: str):
|
|
103
|
+
# Check if this is a registry persona with deduplicated assets
|
|
104
|
+
if persona_path.startswith("registry/"):
|
|
105
|
+
persona_json_path = f"personas/{persona_path}/persona.json"
|
|
106
|
+
if os.path.exists(persona_json_path):
|
|
107
|
+
try:
|
|
108
|
+
with open(persona_json_path, "r") as f:
|
|
109
|
+
persona_data = json.load(f)
|
|
110
|
+
|
|
111
|
+
# Check if persona has asset hashes (deduplicated storage)
|
|
112
|
+
asset_hashes = persona_data.get("asset_hashes", {})
|
|
113
|
+
if "faceref" in asset_hashes:
|
|
114
|
+
# Redirect to deduplicated asset endpoint
|
|
115
|
+
return RedirectResponse(f"/assets/{asset_hashes['faceref']}")
|
|
116
|
+
except Exception as e:
|
|
117
|
+
print(f"Error checking for deduplicated assets: {e}")
|
|
118
|
+
|
|
119
|
+
# Handle registry personas: registry/owner/name
|
|
120
|
+
if persona_path.startswith('registry/'):
|
|
121
|
+
file_path = f"personas/{persona_path}/faceref.png"
|
|
122
|
+
else:
|
|
123
|
+
# Legacy support: check local first, then shared
|
|
124
|
+
file_path = f"personas/local/{persona_path}/faceref.png"
|
|
125
|
+
if not os.path.exists(file_path):
|
|
126
|
+
file_path = f"personas/registry/{persona_path}/faceref.png"
|
|
127
|
+
|
|
128
|
+
if not os.path.exists(file_path):
|
|
129
|
+
# Fallback to avatar if faceref doesn't exist
|
|
130
|
+
return RedirectResponse(f"/chat/personas/{persona_path}/avatar.png")
|
|
131
|
+
|
|
132
|
+
with open(file_path, "rb") as f:
|
|
133
|
+
image_bytes = f.read()
|
|
134
|
+
|
|
135
|
+
return Response(
|
|
136
|
+
content=image_bytes,
|
|
137
|
+
media_type="image/png",
|
|
138
|
+
headers={
|
|
139
|
+
"Cache-Control": "max-age=3600",
|
|
140
|
+
"Content-Disposition": "inline; filename=faceref.png"
|
|
141
|
+
}
|
|
142
|
+
)
|
|
82
143
|
|
|
83
144
|
@router.get("/chat/{log_id}/events")
|
|
84
145
|
async def chat_events(log_id: str):
|
|
@@ -103,8 +164,26 @@ async def send_message(request: Request, log_id: str, message_parts: List[Messag
|
|
|
103
164
|
return {"status": "ok", "task_id": task_id}
|
|
104
165
|
|
|
105
166
|
@router.get("/agent/{agent_name}", response_class=HTMLResponse)
|
|
106
|
-
async def get_chat_html(request: Request, agent_name: str):
|
|
107
|
-
|
|
167
|
+
async def get_chat_html(request: Request, agent_name: str, api_key: str = Query(None), embed: bool = Query(False)):
|
|
168
|
+
# Handle API key authentication if provided
|
|
169
|
+
if api_key:
|
|
170
|
+
try:
|
|
171
|
+
user_data = await verify_api_key(api_key)
|
|
172
|
+
if not user_data:
|
|
173
|
+
raise HTTPException(status_code=401, detail="Invalid API key")
|
|
174
|
+
# Create a mock user object for API key users
|
|
175
|
+
class MockUser:
|
|
176
|
+
def __init__(self, username):
|
|
177
|
+
self.username = username
|
|
178
|
+
user = MockUser(user_data['username'])
|
|
179
|
+
except Exception as e:
|
|
180
|
+
raise HTTPException(status_code=401, detail="Invalid API key")
|
|
181
|
+
else:
|
|
182
|
+
# Use regular authentication
|
|
183
|
+
if not hasattr(request.state, "user"):
|
|
184
|
+
return RedirectResponse("/login")
|
|
185
|
+
user = request.state.user
|
|
186
|
+
|
|
108
187
|
log_id = nanoid.generate()
|
|
109
188
|
plugins = list_enabled()
|
|
110
189
|
print("Init chat with user", user)
|
|
@@ -119,9 +198,28 @@ async def get_chat_html(request: Request, agent_name: str):
|
|
|
119
198
|
debug_box("Access token saved to session file")
|
|
120
199
|
else:
|
|
121
200
|
debug_box("No access token found in request state")
|
|
122
|
-
|
|
201
|
+
|
|
202
|
+
# If embed mode is requested, redirect to embed session
|
|
203
|
+
if embed:
|
|
204
|
+
return RedirectResponse(f"/session/{agent_name}/{log_id}?embed=true")
|
|
205
|
+
|
|
206
|
+
# Regular redirect
|
|
123
207
|
return RedirectResponse(f"/session/{agent_name}/{log_id}")
|
|
124
208
|
|
|
209
|
+
@router.get("/makesession/{agent_name}")
|
|
210
|
+
async def make_session(request: Request, agent_name: str):
|
|
211
|
+
"""
|
|
212
|
+
Create a new chat session for the specified agent.
|
|
213
|
+
Returns a redirect to the chat session page.
|
|
214
|
+
"""
|
|
215
|
+
if not hasattr(request.state, "user"):
|
|
216
|
+
return RedirectResponse("/login")
|
|
217
|
+
user = request.state.user
|
|
218
|
+
log_id = nanoid.generate()
|
|
219
|
+
|
|
220
|
+
await init_chat_session(user, agent_name, log_id)
|
|
221
|
+
return JSONResponse({ "log_id": log_id })
|
|
222
|
+
|
|
125
223
|
@router.get("/history/{agent_name}/{log_id}")
|
|
126
224
|
async def chat_history(request: Request, agent_name: str, log_id: str):
|
|
127
225
|
user = request.state.user.username
|
|
@@ -137,7 +235,8 @@ async def chat_history(request: Request, agent_name: str, log_id: str):
|
|
|
137
235
|
return history
|
|
138
236
|
|
|
139
237
|
@router.get("/session/{agent_name}/{log_id}")
|
|
140
|
-
async def
|
|
238
|
+
async def chat_session(request: Request, agent_name: str, log_id: str, embed: bool = Query(False)):
|
|
239
|
+
# Check authentication (API key or regular user)
|
|
141
240
|
plugins = list_enabled()
|
|
142
241
|
if not hasattr(request.state, "user"):
|
|
143
242
|
return RedirectResponse("/login")
|
|
@@ -155,6 +254,10 @@ async def chat_history(request: Request, agent_name: str, log_id: str):
|
|
|
155
254
|
|
|
156
255
|
if auth_token is not None:
|
|
157
256
|
chat_data["access_token"] = auth_token
|
|
257
|
+
|
|
258
|
+
# Add embed mode flag
|
|
259
|
+
if embed:
|
|
260
|
+
chat_data["embed_mode"] = True
|
|
158
261
|
|
|
159
262
|
html = await render('chat', chat_data)
|
|
160
263
|
return HTMLResponse(html)
|
|
@@ -241,6 +344,7 @@ async def get_token_count(request: Request, log_id: str):
|
|
|
241
344
|
|
|
242
345
|
if token_counts is None:
|
|
243
346
|
return {"status": "error", "message": f"Chat log with ID {log_id} not found"}
|
|
347
|
+
|
|
244
348
|
|
|
245
349
|
return {"status": "ok", "token_counts": token_counts}
|
|
246
350
|
|
|
@@ -290,9 +394,9 @@ async def delete_chat_session(request: Request, log_id: str, user=Depends(requir
|
|
|
290
394
|
|
|
291
395
|
|
|
292
396
|
@router.get("/chat/{log_id}/tokens")
|
|
293
|
-
async def
|
|
397
|
+
async def get_token_count_alt(request: Request, log_id: str):
|
|
294
398
|
"""
|
|
295
|
-
|
|
399
|
+
Alternative token count endpoint using token_counter module.
|
|
296
400
|
|
|
297
401
|
Parameters:
|
|
298
402
|
- log_id: The log ID to count tokens for
|
|
@@ -306,5 +410,13 @@ async def get_token_count(request: Request, log_id: str):
|
|
|
306
410
|
|
|
307
411
|
if token_counts is None:
|
|
308
412
|
return {"status": "error", "message": f"Chat log with ID {log_id} not found"}
|
|
413
|
+
|
|
309
414
|
|
|
310
415
|
return {"status": "ok", "token_counts": token_counts}
|
|
416
|
+
|
|
417
|
+
# Include widget routes
|
|
418
|
+
try:
|
|
419
|
+
from .widget_routes import router as widget_router
|
|
420
|
+
router.include_router(widget_router)
|
|
421
|
+
except ImportError as e:
|
|
422
|
+
print(f"Warning: Could not load widget routes: {e}")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Patch for chat router to add deduplication support
|
|
2
|
+
# This should be integrated into the main router.py file
|
|
3
|
+
|
|
4
|
+
# Add this code to the get_persona_avatar function after line 59:
|
|
5
|
+
|
|
6
|
+
# Check if this is a registry persona with deduplicated assets
|
|
7
|
+
if persona_path.startswith('registry/'):
|
|
8
|
+
persona_json_path = f"personas/{persona_path}/persona.json"
|
|
9
|
+
if os.path.exists(persona_json_path):
|
|
10
|
+
try:
|
|
11
|
+
with open(persona_json_path, 'r') as f:
|
|
12
|
+
persona_data = json.load(f)
|
|
13
|
+
|
|
14
|
+
# Check if persona has asset hashes (deduplicated storage)
|
|
15
|
+
asset_hashes = persona_data.get('asset_hashes', {})
|
|
16
|
+
if 'avatar' in asset_hashes:
|
|
17
|
+
# Redirect to deduplicated asset endpoint
|
|
18
|
+
return RedirectResponse(f"/assets/{asset_hashes['avatar']}")
|
|
19
|
+
except Exception as e:
|
|
20
|
+
print(f"Error checking for deduplicated assets: {e}")
|
|
@@ -23,6 +23,36 @@ import base64
|
|
|
23
23
|
import nanoid
|
|
24
24
|
sse_clients = {}
|
|
25
25
|
|
|
26
|
+
@service()
|
|
27
|
+
async def prompt(model: str, instructions: str, temperature=0, max_tokens=400, json=False, context=None):
|
|
28
|
+
messages = [
|
|
29
|
+
{ "role": "system",
|
|
30
|
+
"content": "Respond to prompt with no extraneous commentary."
|
|
31
|
+
},
|
|
32
|
+
{ "role": "user",
|
|
33
|
+
"content": instructions
|
|
34
|
+
}]
|
|
35
|
+
|
|
36
|
+
stream = await context.stream_chat(model, temperature=temperature,
|
|
37
|
+
max_tokens=max_tokens,
|
|
38
|
+
messages=messages,
|
|
39
|
+
json=False,
|
|
40
|
+
context=context)
|
|
41
|
+
text = ""
|
|
42
|
+
if os.environ.get("AH_DEBUG") == "True":
|
|
43
|
+
print("Prompting, instructions ", instructions)
|
|
44
|
+
async for chunk in stream:
|
|
45
|
+
#print("Chunk received: ", chunk)
|
|
46
|
+
if chunk is None or chunk == "":
|
|
47
|
+
continue
|
|
48
|
+
else:
|
|
49
|
+
text += chunk
|
|
50
|
+
if os.environ.get("AH_DEBUG") == "True":
|
|
51
|
+
print(chunk, end='', flush=True)
|
|
52
|
+
|
|
53
|
+
return text
|
|
54
|
+
|
|
55
|
+
|
|
26
56
|
def results_text(results):
|
|
27
57
|
text = ""
|
|
28
58
|
for result in results:
|
|
@@ -304,7 +334,7 @@ async def send_message_to_agent(session_id: str, message: str | List[MessagePart
|
|
|
304
334
|
actual_results = False
|
|
305
335
|
await asyncio.sleep(0.001)
|
|
306
336
|
for result in results:
|
|
307
|
-
if result['result'] is not None:
|
|
337
|
+
if 'result' in result and result['result'] is not None:
|
|
308
338
|
if result['result'] == 'continue':
|
|
309
339
|
out_results.append(result)
|
|
310
340
|
continue_processing = True
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* Action component full width fix - ONLY target action components */
|
|
2
|
+
action-component {
|
|
3
|
+
display: block !important;
|
|
4
|
+
width: 100% !important;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
action-component .action-details {
|
|
8
|
+
width: 100% !important;
|
|
9
|
+
display: block !important;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
action-component .action-details summary {
|
|
13
|
+
width: 100% !important;
|
|
14
|
+
display: block !important;
|
|
15
|
+
box-sizing: border-box !important;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* Action summary styling - brighter text */
|
|
19
|
+
action-component .action-summary {
|
|
20
|
+
background: #333 !important;
|
|
21
|
+
color: #f0f0f0 !important;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
action-component .param-preview {
|
|
25
|
+
color: #ddd !important;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
action-component .fn_name {
|
|
29
|
+
color: #f0f0f0 !important;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* DO NOT TOUCH CHAT MESSAGE ALIGNMENT - Let default.css handle it */
|
|
@@ -15,11 +15,12 @@ body {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
details {
|
|
18
|
-
background:
|
|
18
|
+
background: #fff;
|
|
19
19
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
20
20
|
border-radius: 8px;
|
|
21
21
|
margin-bottom: 20px;
|
|
22
22
|
overflow: hidden;
|
|
23
|
+
width: 100%;
|
|
23
24
|
transition: all 0.3s ease;
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -29,7 +30,7 @@ details[open] {
|
|
|
29
30
|
|
|
30
31
|
summary {
|
|
31
32
|
padding: 15px 20px;
|
|
32
|
-
background:
|
|
33
|
+
background: #222;
|
|
33
34
|
color: #f0f0f0;
|
|
34
35
|
cursor: pointer;
|
|
35
36
|
transition: background 0.3s ease;
|
|
@@ -42,7 +43,8 @@ summary:hover {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
details[open] summary {
|
|
45
|
-
background: rgb(25, 25, 50);
|
|
46
|
+
/* background: rgb(25, 25, 50); */
|
|
47
|
+
background: #222;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
.details-content {
|
|
@@ -3,7 +3,7 @@ html, body {
|
|
|
3
3
|
color: #f0f0f0;
|
|
4
4
|
padding: 5px 5px;
|
|
5
5
|
font-family: ui-sans-serif, -apple-system, system-ui, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, Helvetica, "Apple Color Emoji", Arial, "Segoe UI Emoji", "Segoe UI Symbol";
|
|
6
|
-
|
|
6
|
+
font-size: 18px;
|
|
7
7
|
display: flex;
|
|
8
8
|
line-height: 1.5;
|
|
9
9
|
flex-direction: column;
|
|
@@ -89,8 +89,10 @@ chat-form {
|
|
|
89
89
|
width: 100%;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
|
|
92
93
|
chat-message {
|
|
93
|
-
max-width: 69%;
|
|
94
|
+
/* max-width: 69%; */
|
|
95
|
+
width: 100%;
|
|
94
96
|
padding: 4px 8px;
|
|
95
97
|
margin: 2px 0;
|
|
96
98
|
display: block;
|
|
@@ -127,6 +129,15 @@ chat-message:first-of-type .outer-msg.without-avatar {
|
|
|
127
129
|
background-color: transparent;
|
|
128
130
|
}
|
|
129
131
|
|
|
132
|
+
.outer-msg.user {
|
|
133
|
+
flex-direction: column;
|
|
134
|
+
align-items: flex-end;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.message:has(.action-summary) {
|
|
138
|
+
width: 100%;
|
|
139
|
+
}
|
|
140
|
+
|
|
130
141
|
.user {
|
|
131
142
|
align-self: flex-end;
|
|
132
143
|
}
|
|
@@ -146,6 +157,7 @@ chat-message:first-of-type .outer-msg.without-avatar {
|
|
|
146
157
|
/* background-color: #080808; */
|
|
147
158
|
border: 1px solid #181818;
|
|
148
159
|
border-radius: 30px;
|
|
160
|
+
width: 80%;
|
|
149
161
|
}
|
|
150
162
|
|
|
151
163
|
.msg-ai:first-child {
|
|
@@ -745,7 +757,16 @@ button:hover {
|
|
|
745
757
|
}
|
|
746
758
|
|
|
747
759
|
.param_name { font-weight: bold; }
|
|
748
|
-
.param_value { color:
|
|
760
|
+
.param_value { color: #ccc; }
|
|
761
|
+
|
|
762
|
+
summary {
|
|
763
|
+
border-radius: 8px;
|
|
764
|
+
color: white;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
details {
|
|
768
|
+
width: 100%;
|
|
769
|
+
}
|
|
749
770
|
|
|
750
771
|
.fn_result, .code-result {
|
|
751
772
|
white-space: normal !important;
|
|
@@ -3,7 +3,7 @@ html, body {
|
|
|
3
3
|
color: #f0f0f0;
|
|
4
4
|
padding: 5px 5px;
|
|
5
5
|
font-family: ui-sans-serif, -apple-system, system-ui, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, Helvetica, "Apple Color Emoji", Arial, "Segoe UI Emoji", "Segoe UI Symbol";
|
|
6
|
-
|
|
6
|
+
font-size: 18px;
|
|
7
7
|
display: flex;
|
|
8
8
|
line-height: 1.5;
|
|
9
9
|
flex-direction: column;
|
|
@@ -89,8 +89,10 @@ chat-form {
|
|
|
89
89
|
width: 100%;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
|
|
92
93
|
chat-message {
|
|
93
|
-
max-width: 69%;
|
|
94
|
+
/* max-width: 69%; */
|
|
95
|
+
width: 100%;
|
|
94
96
|
padding: 4px 8px;
|
|
95
97
|
margin: 2px 0;
|
|
96
98
|
display: block;
|
|
@@ -127,6 +129,15 @@ chat-message:first-of-type .outer-msg.without-avatar {
|
|
|
127
129
|
background-color: transparent;
|
|
128
130
|
}
|
|
129
131
|
|
|
132
|
+
.outer-msg.user {
|
|
133
|
+
flex-direction: column;
|
|
134
|
+
align-items: flex-end;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.message:has(.action-summary) {
|
|
138
|
+
width: 100%;
|
|
139
|
+
}
|
|
140
|
+
|
|
130
141
|
.user {
|
|
131
142
|
align-self: flex-end;
|
|
132
143
|
}
|
|
@@ -146,6 +157,7 @@ chat-message:first-of-type .outer-msg.without-avatar {
|
|
|
146
157
|
/* background-color: #080808; */
|
|
147
158
|
border: 1px solid #181818;
|
|
148
159
|
border-radius: 30px;
|
|
160
|
+
width: 80%;
|
|
149
161
|
}
|
|
150
162
|
|
|
151
163
|
.msg-ai:first-child {
|
|
@@ -745,7 +757,16 @@ button:hover {
|
|
|
745
757
|
}
|
|
746
758
|
|
|
747
759
|
.param_name { font-weight: bold; }
|
|
748
|
-
.param_value { color:
|
|
760
|
+
.param_value { color: #ccc; }
|
|
761
|
+
|
|
762
|
+
summary {
|
|
763
|
+
border-radius: 8px;
|
|
764
|
+
color: white;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
details {
|
|
768
|
+
width: 100%;
|
|
769
|
+
}
|
|
749
770
|
|
|
750
771
|
.fn_result, .code-result {
|
|
751
772
|
white-space: normal !important;
|