ws-bom-robot-app 0.0.84__tar.gz → 0.0.85__tar.gz

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.
Files changed (83) hide show
  1. {ws_bom_robot_app-0.0.84/ws_bom_robot_app.egg-info → ws_bom_robot_app-0.0.85}/PKG-INFO +1 -1
  2. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/setup.py +1 -1
  3. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/cron_manager.py +3 -3
  4. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/utils/cleanup.py +1 -1
  5. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/loader/base.py +35 -0
  6. ws_bom_robot_app-0.0.85/ws_bom_robot_app/main.py +156 -0
  7. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/subprocess_runner.py +3 -0
  8. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/util.py +6 -0
  9. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85/ws_bom_robot_app.egg-info}/PKG-INFO +1 -1
  10. ws_bom_robot_app-0.0.84/ws_bom_robot_app/main.py +0 -157
  11. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/MANIFEST.in +0 -0
  12. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/README.md +0 -0
  13. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/pyproject.toml +0 -0
  14. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/requirements.txt +0 -0
  15. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/setup.cfg +0 -0
  16. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/__init__.py +0 -0
  17. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/auth.py +0 -0
  18. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/config.py +0 -0
  19. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/__init__.py +0 -0
  20. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/agent_context.py +0 -0
  21. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/agent_description.py +0 -0
  22. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/agent_handler.py +0 -0
  23. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/agent_lcel.py +0 -0
  24. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/api.py +0 -0
  25. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/defaut_prompt.py +0 -0
  26. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/feedbacks/__init__.py +0 -0
  27. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/feedbacks/feedback_manager.py +0 -0
  28. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/main.py +0 -0
  29. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/models/__init__.py +0 -0
  30. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/models/api.py +0 -0
  31. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/models/base.py +0 -0
  32. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/models/feedback.py +0 -0
  33. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/models/kb.py +0 -0
  34. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/nebuly_handler.py +0 -0
  35. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/providers/__init__.py +0 -0
  36. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/providers/llm_manager.py +0 -0
  37. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/tools/__init__.py +0 -0
  38. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/tools/models/__init__.py +0 -0
  39. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/tools/models/main.py +0 -0
  40. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/tools/tool_builder.py +0 -0
  41. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/tools/tool_manager.py +0 -0
  42. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/tools/utils.py +0 -0
  43. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/utils/__init__.py +0 -0
  44. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/utils/agent.py +0 -0
  45. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/utils/chunker.py +0 -0
  46. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/utils/cms.py +0 -0
  47. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/utils/download.py +0 -0
  48. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/utils/print.py +0 -0
  49. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/utils/secrets.py +0 -0
  50. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/utils/webhooks.py +0 -0
  51. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/__init__.py +0 -0
  52. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/db/__init__.py +0 -0
  53. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/db/base.py +0 -0
  54. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/db/chroma.py +0 -0
  55. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/db/faiss.py +0 -0
  56. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/db/manager.py +0 -0
  57. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/db/qdrant.py +0 -0
  58. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/generator.py +0 -0
  59. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/__init__.py +0 -0
  60. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/azure.py +0 -0
  61. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/base.py +0 -0
  62. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/confluence.py +0 -0
  63. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/dropbox.py +0 -0
  64. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/gcs.py +0 -0
  65. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/github.py +0 -0
  66. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/googledrive.py +0 -0
  67. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/jira.py +0 -0
  68. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/manager.py +0 -0
  69. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/s3.py +0 -0
  70. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/sftp.py +0 -0
  71. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/sharepoint.py +0 -0
  72. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/shopify.py +0 -0
  73. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/sitemap.py +0 -0
  74. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/slack.py +0 -0
  75. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/integration/thron.py +0 -0
  76. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/loader/__init__.py +0 -0
  77. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/loader/docling.py +0 -0
  78. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/llm/vector_store/loader/json_loader.py +0 -0
  79. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app/task_manager.py +0 -0
  80. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app.egg-info/SOURCES.txt +0 -0
  81. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app.egg-info/dependency_links.txt +0 -0
  82. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app.egg-info/requires.txt +0 -0
  83. {ws_bom_robot_app-0.0.84 → ws_bom_robot_app-0.0.85}/ws_bom_robot_app.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ws_bom_robot_app
3
- Version: 0.0.84
3
+ Version: 0.0.85
4
4
  Summary: A FastAPI application serving ws bom/robot/llm platform ai.
5
5
  Home-page: https://github.com/websolutespa/bom
6
6
  Author: Websolute Spa
@@ -4,7 +4,7 @@ _requirements = [line.split('#')[0].strip() for line in open("requirements.txt")
4
4
 
5
5
  setup(
6
6
  name="ws_bom_robot_app",
7
- version="0.0.84",
7
+ version="0.0.85",
8
8
  description="A FastAPI application serving ws bom/robot/llm platform ai.",
9
9
  long_description=open("README.md", encoding='utf-8').read(),
10
10
  long_description_content_type="text/markdown",
@@ -56,9 +56,9 @@ class Job:
56
56
 
57
57
  class CronManager:
58
58
  _list_default = [
59
- Job('cleanup-task-history',task_cleanup_history, interval=5 * 60),
60
- Job('cleanup-kb-data',kb_cleanup_data_file, interval=180 * 60),
61
- Job('cleanup-chat-attachment',chat_cleanup_attachment, interval=120 * 60),
59
+ Job('cleanup-task-history',task_cleanup_history, interval=4 * 60 * 60),
60
+ Job('cleanup-kb-data',kb_cleanup_data_file, interval=8 * 60 * 60),
61
+ Job('cleanup-chat-attachment',chat_cleanup_attachment, interval=6 * 60 * 60),
62
62
  ]
63
63
  def __get_jobstore_strategy(self) -> JobstoreStrategy:
64
64
  if config.robot_cron_strategy == 'memory':
@@ -1,7 +1,6 @@
1
1
  import os, logging
2
2
  from ws_bom_robot_app.config import config
3
3
  from datetime import datetime, timedelta
4
- from ws_bom_robot_app.task_manager import task_manager
5
4
 
6
5
  def _cleanup_data_file(folders: list[str], retention: float) -> dict:
7
6
  """
@@ -78,4 +77,5 @@ def task_cleanup_history() -> None:
78
77
  """
79
78
  clean up task queue
80
79
  """
80
+ from ws_bom_robot_app.task_manager import task_manager
81
81
  task_manager.cleanup_task()
@@ -113,6 +113,38 @@ class Loader():
113
113
 
114
114
  #@timer
115
115
  async def load(self) -> list[Document]:
116
+ #region log
117
+ import warnings
118
+ warnings.filterwarnings("ignore", message=".*pin_memory.*no accelerator is found.*")
119
+ log_msg_to_ignore = [
120
+ "Going to convert document batch...",
121
+ "Initializing pipeline for",
122
+ "Accelerator device:",
123
+ "detected formats:",
124
+ ]
125
+ class MessageFilter(logging.Filter):
126
+ def __init__(self, patterns):
127
+ super().__init__()
128
+ self.log_msg_to_ignore = patterns
129
+
130
+ def filter(self, record):
131
+ for pattern in self.log_msg_to_ignore:
132
+ if pattern in record.getMessage():
133
+ return False
134
+ return True
135
+ message_filter = MessageFilter(log_msg_to_ignore)
136
+ loggers_to_filter = [
137
+ 'docling',
138
+ 'docling.document_converter',
139
+ 'docling.datamodel',
140
+ 'docling.datamodel.document',
141
+ 'docling.utils.accelerator_utils',
142
+ 'unstructured'
143
+ ]
144
+ for logger_name in loggers_to_filter:
145
+ logging.getLogger(logger_name).addFilter(message_filter)
146
+ #endregion log
147
+
116
148
  MAX_RETRIES = 3
117
149
  loaders: MergedDataLoader = MergedDataLoader(self.__directory_loader())
118
150
  try:
@@ -132,5 +164,8 @@ class Loader():
132
164
  finally:
133
165
  del _documents
134
166
  finally:
167
+ # Remove logging filters
168
+ for logger_name in loggers_to_filter:
169
+ logging.getLogger(logger_name).removeFilter(message_filter)
135
170
  del loaders
136
171
  gc.collect()
@@ -0,0 +1,156 @@
1
+ import datetime
2
+ from fastapi import FastAPI
3
+ from ws_bom_robot_app.util import is_app_subprocess
4
+ _uptime = datetime.datetime.now()
5
+ app = FastAPI(redoc_url=None,docs_url=None,openapi_url=None)
6
+
7
+ if not is_app_subprocess():
8
+ import platform
9
+ from fastapi.responses import FileResponse
10
+ import os, sys
11
+ from fastapi import Depends
12
+ from fastapi.openapi.docs import get_swagger_ui_html, get_redoc_html
13
+ from fastapi.openapi.utils import get_openapi
14
+ from ws_bom_robot_app.auth import authenticate
15
+ from ws_bom_robot_app.config import config
16
+ from ws_bom_robot_app.util import _log
17
+ from ws_bom_robot_app.llm.api import router as llm
18
+ from ws_bom_robot_app.task_manager import router as task
19
+ from ws_bom_robot_app.cron_manager import (
20
+ router as cron,
21
+ cron_manager)
22
+ cron_manager.start()
23
+ app.include_router(llm,dependencies=[Depends(authenticate)])
24
+ app.include_router(task,dependencies=[Depends(authenticate)])
25
+ app.include_router(cron,dependencies=[Depends(authenticate)])
26
+
27
+ @app.get("/")
28
+ async def root():
29
+ return health()
30
+ @app.get("/favicon.ico")
31
+ async def favicon():
32
+ return FileResponse("./favicon.ico")
33
+
34
+ @app.get("/docs", include_in_schema=False)
35
+ async def get_swagger_documentation(authenticate: bool = Depends(authenticate)):
36
+ return get_swagger_ui_html(openapi_url="/openapi.json", title="docs")
37
+ @app.get("/redoc", include_in_schema=False)
38
+ async def get_redoc_documentation(authenticate: bool = Depends(authenticate)):
39
+ return get_redoc_html(openapi_url="/openapi.json", title="docs")
40
+ @app.get("/openapi.json", include_in_schema=False)
41
+ async def openapi(authenticate: bool = Depends(authenticate)):
42
+ return get_openapi(title=app.title, version=app.version, routes=app.routes)
43
+
44
+ @app.get("/api/health",tags=["diag"])
45
+ def health():
46
+ return {"status": "ok"}
47
+ def __get_size(bytes, suffix="B"):
48
+ """
49
+ Scale bytes to its proper format
50
+ e.g:
51
+ 1253656 => '1.20MB'
52
+ 1253656678 => '1.17GB'
53
+ """
54
+ factor = 1024
55
+ for unit in ["", "K", "M", "G", "T", "P"]:
56
+ if bytes < factor:
57
+ return f"{bytes:.2f}{unit}{suffix}"
58
+ bytes /= factor
59
+ def __get_disk_info():
60
+ import psutil
61
+ partitions = psutil.disk_partitions()
62
+ _disks:list = []
63
+ for partition in partitions:
64
+ device = partition.device
65
+ mountpoint = partition.mountpoint
66
+ fstype = partition.fstype
67
+ try:
68
+ usage = psutil.disk_usage(mountpoint)
69
+ except PermissionError:
70
+ continue
71
+ total = __get_size(usage.total)
72
+ used = __get_size(usage.used)
73
+ free = __get_size(usage.free)
74
+ percent = f"{usage.percent}%"
75
+ _disks.append({"device": device, "mountpoint": mountpoint, "fstype": fstype, "total": total, "used": used, "free": free, "percent": percent})
76
+ return _disks
77
+ @app.get("/api/diag",tags=["diag"])
78
+ def diag(authenticate: bool = Depends(authenticate)):
79
+ import importlib,psutil
80
+ from ws_bom_robot_app.llm.providers.llm_manager import LlmManager as wsllm
81
+ from ws_bom_robot_app.llm.vector_store.db.manager import VectorDbManager as wsdb
82
+ from ws_bom_robot_app.llm.vector_store.loader.base import Loader as wsldr
83
+ from ws_bom_robot_app.llm.vector_store.integration.manager import IntegrationManager as wsim
84
+ from ws_bom_robot_app.llm.tools.tool_manager import ToolManager as wstm
85
+ from ws_bom_robot_app.llm.agent_description import AgentDescriptor as wsad
86
+
87
+ svmem = psutil.virtual_memory()
88
+ swap = psutil.swap_memory()
89
+ try:
90
+ ws_bom_robot_app_version = importlib.metadata.version("ws_bom_robot_app")
91
+ except:
92
+ ws_bom_robot_app_version = "unknown"
93
+ peer_process_ids = [c.pid for c in psutil.Process(os.getppid()).children()] if config.runtime_options().is_multi_process else None
94
+ return {
95
+ "status":"ok",
96
+ "uptime": {'from':_uptime,'elapsed':str(datetime.datetime.now()-_uptime)},
97
+ "system": {
98
+ "platform": {
99
+ "node": platform.node(),
100
+ "system": platform.system(),
101
+ "platform": platform.platform(),
102
+ "version": platform.version(),
103
+ "type": platform.machine(),
104
+ "processor": platform.processor(),
105
+ "architecture": platform.architecture()
106
+ },
107
+ "cpu": {
108
+ "physical_core": psutil.cpu_count(logical=False),
109
+ "total_core": psutil.cpu_count(logical=True),
110
+ "load": f"{psutil.cpu_percent(interval=1)}%"
111
+ },
112
+ "memory": {
113
+ "total": f"{__get_size(svmem.total)}",
114
+ "available": f"{__get_size(svmem.available)}",
115
+ "used": f"{__get_size(svmem.used)}",
116
+ "free": f"{__get_size(svmem.free)}",
117
+ "percent": f"{svmem.percent}%"
118
+ },
119
+ "swap": {
120
+ "total": f"{__get_size(swap.total)}",
121
+ "used": f"{__get_size(swap.used)}",
122
+ "free": f"{__get_size(swap.free)}",
123
+ "percent": f"{swap.percent}%"
124
+ },
125
+ "disk": __get_disk_info(),
126
+ "sys": {
127
+ "version": sys.version,
128
+ "platform": sys.platform,
129
+ "executable": sys.executable,
130
+ "args": {k: arg for k, arg in enumerate(sys.argv)}
131
+ },
132
+ "os": {
133
+ "ppid": os.getppid(),
134
+ "pid": os.getpid(),
135
+ "pids": peer_process_ids,
136
+ "cwd": os.getcwd(),
137
+ "ws_bom_robot_app": ws_bom_robot_app_version,
138
+ "env": os.environ,
139
+ },
140
+ },
141
+ "config":config,
142
+ "runtime":config.runtime_options(),
143
+ "extension": {
144
+ "provider":({item[0]: type(item[1]).__name__} for item in wsllm._list.items()),
145
+ "db":({item[0]: type(item[1]).__name__} for item in wsdb._list.items()),
146
+ "loader": ({item[0]: item[1].loader.__name__ if item[1] else None} for item in sorted(wsldr._list.items(), key=lambda x: x[0]) if item[1]),
147
+ "integration":({item[0]: type(item[1]).__name__} for item in wsim._list.items()),
148
+ "tool": ({item[0]: item[1].function.__name__} for item in wstm._list.items()),
149
+ "agent":({item[0]: type(item[1]).__name__} for item in wsad._list.items())
150
+ }
151
+ }
152
+ @app.post("/diag/reload",tags=["diag"])
153
+ def reset(authenticate: bool = Depends(authenticate)):
154
+ _log.info("restart server")
155
+ with open(".reloadfile","w") as f:
156
+ f.write("")
@@ -12,6 +12,9 @@ def _worker_run_pickled(serialized_task: bytes, conn: Connection):
12
12
  capture return value or exception and send back via conn.send((ok_flag, payload_serialized)).
13
13
  This runs in a separate process and must be top-level for multiprocessing.
14
14
  """
15
+ import os
16
+ # mark as a subprocess
17
+ os.environ['IS_ROBOT_APP_SUBPROCESS'] = 'true'
15
18
  try:
16
19
  if _pickler is None:
17
20
  raise RuntimeError("No pickler available in worker process.")
@@ -22,6 +22,12 @@ def logger_instance(name: str) -> logging.Logger:
22
22
  _log: logging.Logger = locals().get("_loc", logger_instance(__name__))
23
23
  #endregion
24
24
 
25
+ #region task
26
+ def is_app_subprocess():
27
+ """Check if we're running a task in a subprocess."""
28
+ return os.environ.get('IS_ROBOT_APP_SUBPROCESS', '').lower() == 'true'
29
+ #endregion
30
+
25
31
  #region cache
26
32
  _cache = {}
27
33
  _cache_timestamps = {}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ws_bom_robot_app
3
- Version: 0.0.84
3
+ Version: 0.0.85
4
4
  Summary: A FastAPI application serving ws bom/robot/llm platform ai.
5
5
  Home-page: https://github.com/websolutespa/bom
6
6
  Author: Websolute Spa
@@ -1,157 +0,0 @@
1
- import datetime
2
- import platform
3
- from fastapi.responses import FileResponse
4
- import uvicorn, os, sys
5
- from fastapi import FastAPI, Depends
6
- from fastapi.openapi.docs import get_swagger_ui_html, get_redoc_html
7
- from fastapi.openapi.utils import get_openapi
8
- from ws_bom_robot_app.auth import authenticate
9
- from ws_bom_robot_app.config import config
10
- from ws_bom_robot_app.llm.api import router as llm
11
- from ws_bom_robot_app.task_manager import router as task
12
- from ws_bom_robot_app.cron_manager import (
13
- router as cron,
14
- cron_manager)
15
- from ws_bom_robot_app.util import _log
16
-
17
- _uptime = datetime.datetime.now()
18
- cron_manager.start()
19
- app = FastAPI(redoc_url=None,docs_url=None,openapi_url=None)
20
- app.include_router(llm,dependencies=[Depends(authenticate)])
21
- app.include_router(task,dependencies=[Depends(authenticate)])
22
- app.include_router(cron,dependencies=[Depends(authenticate)])
23
-
24
- @app.get("/")
25
- async def root():
26
- return health()
27
- @app.get("/favicon.ico")
28
- async def favicon():
29
- return FileResponse("./favicon.ico")
30
-
31
- @app.get("/docs", include_in_schema=False)
32
- async def get_swagger_documentation(authenticate: bool = Depends(authenticate)):
33
- return get_swagger_ui_html(openapi_url="/openapi.json", title="docs")
34
- @app.get("/redoc", include_in_schema=False)
35
- async def get_redoc_documentation(authenticate: bool = Depends(authenticate)):
36
- return get_redoc_html(openapi_url="/openapi.json", title="docs")
37
- @app.get("/openapi.json", include_in_schema=False)
38
- async def openapi(authenticate: bool = Depends(authenticate)):
39
- return get_openapi(title=app.title, version=app.version, routes=app.routes)
40
-
41
- @app.get("/api/health",tags=["diag"])
42
- def health():
43
- return {"status": "ok"}
44
- def __get_size(bytes, suffix="B"):
45
- """
46
- Scale bytes to its proper format
47
- e.g:
48
- 1253656 => '1.20MB'
49
- 1253656678 => '1.17GB'
50
- """
51
- factor = 1024
52
- for unit in ["", "K", "M", "G", "T", "P"]:
53
- if bytes < factor:
54
- return f"{bytes:.2f}{unit}{suffix}"
55
- bytes /= factor
56
- def __get_disk_info():
57
- import psutil
58
- partitions = psutil.disk_partitions()
59
- _disks:list = []
60
- for partition in partitions:
61
- device = partition.device
62
- mountpoint = partition.mountpoint
63
- fstype = partition.fstype
64
- try:
65
- usage = psutil.disk_usage(mountpoint)
66
- except PermissionError:
67
- continue
68
- total = __get_size(usage.total)
69
- used = __get_size(usage.used)
70
- free = __get_size(usage.free)
71
- percent = f"{usage.percent}%"
72
- _disks.append({"device": device, "mountpoint": mountpoint, "fstype": fstype, "total": total, "used": used, "free": free, "percent": percent})
73
- return _disks
74
- @app.get("/api/diag",tags=["diag"])
75
- def diag(authenticate: bool = Depends(authenticate)):
76
- import importlib,psutil
77
- from ws_bom_robot_app.llm.providers.llm_manager import LlmManager as wsllm
78
- from ws_bom_robot_app.llm.vector_store.db.manager import VectorDbManager as wsdb
79
- from ws_bom_robot_app.llm.vector_store.loader.base import Loader as wsldr
80
- from ws_bom_robot_app.llm.vector_store.integration.manager import IntegrationManager as wsim
81
- from ws_bom_robot_app.llm.tools.tool_manager import ToolManager as wstm
82
- from ws_bom_robot_app.llm.agent_description import AgentDescriptor as wsad
83
-
84
- svmem = psutil.virtual_memory()
85
- swap = psutil.swap_memory()
86
- try:
87
- ws_bom_robot_app_version = importlib.metadata.version("ws_bom_robot_app")
88
- except:
89
- ws_bom_robot_app_version = "unknown"
90
- peer_process_ids = [c.pid for c in psutil.Process(os.getppid()).children()] if config.runtime_options().is_multi_process else None
91
- return {
92
- "status":"ok",
93
- "uptime": {'from':_uptime,'elapsed':str(datetime.datetime.now()-_uptime)},
94
- "system": {
95
- "platform": {
96
- "node": platform.node(),
97
- "system": platform.system(),
98
- "platform": platform.platform(),
99
- "version": platform.version(),
100
- "type": platform.machine(),
101
- "processor": platform.processor(),
102
- "architecture": platform.architecture()
103
- },
104
- "cpu": {
105
- "physical_core": psutil.cpu_count(logical=False),
106
- "total_core": psutil.cpu_count(logical=True),
107
- "load": f"{psutil.cpu_percent(interval=1)}%"
108
- },
109
- "memory": {
110
- "total": f"{__get_size(svmem.total)}",
111
- "available": f"{__get_size(svmem.available)}",
112
- "used": f"{__get_size(svmem.used)}",
113
- "free": f"{__get_size(svmem.free)}",
114
- "percent": f"{svmem.percent}%"
115
- },
116
- "swap": {
117
- "total": f"{__get_size(swap.total)}",
118
- "used": f"{__get_size(swap.used)}",
119
- "free": f"{__get_size(swap.free)}",
120
- "percent": f"{swap.percent}%"
121
- },
122
- "disk": __get_disk_info(),
123
- "sys": {
124
- "version": sys.version,
125
- "platform": sys.platform,
126
- "executable": sys.executable,
127
- "args": {k: arg for k, arg in enumerate(sys.argv)}
128
- },
129
- "os": {
130
- "ppid": os.getppid(),
131
- "pid": os.getpid(),
132
- "pids": peer_process_ids,
133
- "cwd": os.getcwd(),
134
- "ws_bom_robot_app": ws_bom_robot_app_version,
135
- "env": os.environ,
136
- },
137
- },
138
- "config":config,
139
- "runtime":config.runtime_options(),
140
- "extension": {
141
- "provider":({item[0]: type(item[1]).__name__} for item in wsllm._list.items()),
142
- "db":({item[0]: type(item[1]).__name__} for item in wsdb._list.items()),
143
- "loader": ({item[0]: item[1].loader.__name__ if item[1] else None} for item in sorted(wsldr._list.items(), key=lambda x: x[0]) if item[1]),
144
- "integration":({item[0]: type(item[1]).__name__} for item in wsim._list.items()),
145
- "tool": ({item[0]: item[1].function.__name__} for item in wstm._list.items()),
146
- "agent":({item[0]: type(item[1]).__name__} for item in wsad._list.items())
147
- }
148
- }
149
- @app.post("/diag/reload",tags=["diag"])
150
- def reset(authenticate: bool = Depends(authenticate)):
151
- _log.info("restart server")
152
- with open(".reloadfile","w") as f:
153
- f.write("")
154
-
155
- # Start the FastAPI server
156
- if __name__ == "__main__":
157
- uvicorn.run(app, host="0.0.0.0", port=6001, env_file="../.env", reload=True, log_level="debug")