From d2ae867ed160892225103c9dc73aa13051336d66 Mon Sep 17 00:00:00 2001 From: kirtimanmishrazipstack Date: Fri, 5 Sep 2025 19:05:17 +0530 Subject: [PATCH 1/8] sidecar implementation sigterm --- .../unstract/tool_sidecar/log_processor.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py index 86ade0cd72..a2ade732d0 100644 --- a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py +++ b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py @@ -7,6 +7,7 @@ import json import logging import os +import signal import time from datetime import UTC, datetime from typing import Any @@ -25,6 +26,17 @@ logger = logging.getLogger(__name__) +# Global shutdown flag for graceful termination +_shutdown_requested = False + + +def signal_handler(signum, frame): + """Handle shutdown signals gracefully.""" + global _shutdown_requested + signal_name = signal.Signals(signum).name + logger.info(f"Received {signal_name}, initiating graceful shutdown...") + _shutdown_requested = True + class LogProcessor: def __init__( @@ -210,7 +222,9 @@ def is_valid_log_type(self, log_type: str | None) -> bool: def monitor_logs(self) -> None: """Main loop to monitor log file for new content and completion signals. Uses file polling with position tracking to efficiently read new lines. + Handles graceful shutdown via SIGTERM. """ + global _shutdown_requested logger.info("Starting log monitoring...") if not self.wait_for_log_file(): raise TimeoutError("Log file was not created within timeout period") @@ -218,6 +232,12 @@ def monitor_logs(self) -> None: # Monitor the file for new content with open(self.log_path) as f: while True: + # Check for shutdown signal + if _shutdown_requested: + logger.info("Shutdown requested, performing final log collection...") + self._final_log_collection(f) + break + # Remember current position where = f.tell() line = f.readline() @@ -241,11 +261,43 @@ def monitor_logs(self) -> None: logger.info("Completion signal received") break + logger.info("Log monitoring completed") + + def _final_log_collection(self, file_handle) -> None: + """Perform final collection of any remaining logs before shutdown.""" + logger.info("Performing final log collection...") + + # Give main container brief moment to write final logs + time.sleep(0.2) + + lines_collected = 0 + + # Read any remaining lines in the file + while True: + line = file_handle.readline() + if not line: + break + + lines_collected += 1 + log_line = self.process_log_line(line.strip()) + + if log_line.is_terminated: + logger.info("Found completion signal during final collection") + + logger.info( + f"Final log collection completed, processed {lines_collected} remaining lines" + ) + def main(): """Main entry point for the sidecar container. Sets up the log processor with environment variables and starts monitoring. """ + # Set up signal handlers for graceful shutdown + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + logger.info("Signal handlers registered for graceful shutdown") + # Get configuration from environment log_path = os.getenv(Env.LOG_PATH, "/shared/logs/logs.txt") redis_host = os.getenv(Env.REDIS_HOST) From c1567e92ffacf2d751ddb28790c2cd5ff265c0ff Mon Sep 17 00:00:00 2001 From: kirtimanmishrazipstack Date: Mon, 8 Dec 2025 22:02:27 +0530 Subject: [PATCH 2/8] sigterm tested in local for tool shutdown --- .../unstract/tool_sidecar/log_processor.py | 52 +++---------------- .../sdk1/src/unstract/sdk1/tool/entrypoint.py | 18 +++++++ 2 files changed, 26 insertions(+), 44 deletions(-) diff --git a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py index a2ade732d0..1b93d54f81 100644 --- a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py +++ b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py @@ -9,6 +9,7 @@ import os import signal import time +import types from datetime import UTC, datetime from typing import Any @@ -26,16 +27,13 @@ logger = logging.getLogger(__name__) -# Global shutdown flag for graceful termination -_shutdown_requested = False - -def signal_handler(signum, frame): +def _signal_handler(signum: int, _frame: types.FrameType | None): """Handle shutdown signals gracefully.""" - global _shutdown_requested - signal_name = signal.Signals(signum).name - logger.info(f"Received {signal_name}, initiating graceful shutdown...") - _shutdown_requested = True + sig = signal.Signals(signum) + signal_name = sig.name + logger.warning(f"RECEIVED SIGNAL: {signal_name}") + logger.warning("Initiating graceful shutdown...") class LogProcessor: @@ -224,20 +222,12 @@ def monitor_logs(self) -> None: Uses file polling with position tracking to efficiently read new lines. Handles graceful shutdown via SIGTERM. """ - global _shutdown_requested - logger.info("Starting log monitoring...") if not self.wait_for_log_file(): raise TimeoutError("Log file was not created within timeout period") # Monitor the file for new content with open(self.log_path) as f: while True: - # Check for shutdown signal - if _shutdown_requested: - logger.info("Shutdown requested, performing final log collection...") - self._final_log_collection(f) - break - # Remember current position where = f.tell() line = f.readline() @@ -263,40 +253,14 @@ def monitor_logs(self) -> None: logger.info("Log monitoring completed") - def _final_log_collection(self, file_handle) -> None: - """Perform final collection of any remaining logs before shutdown.""" - logger.info("Performing final log collection...") - - # Give main container brief moment to write final logs - time.sleep(0.2) - - lines_collected = 0 - - # Read any remaining lines in the file - while True: - line = file_handle.readline() - if not line: - break - - lines_collected += 1 - log_line = self.process_log_line(line.strip()) - - if log_line.is_terminated: - logger.info("Found completion signal during final collection") - - logger.info( - f"Final log collection completed, processed {lines_collected} remaining lines" - ) - def main(): """Main entry point for the sidecar container. Sets up the log processor with environment variables and starts monitoring. """ # Set up signal handlers for graceful shutdown - signal.signal(signal.SIGTERM, signal_handler) - signal.signal(signal.SIGINT, signal_handler) - logger.info("Signal handlers registered for graceful shutdown") + signal.signal(signal.SIGTERM, _signal_handler) + signal.signal(signal.SIGINT, _signal_handler) # Get configuration from environment log_path = os.getenv(Env.LOG_PATH, "/shared/logs/logs.txt") diff --git a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py index 831be97d06..a5d1837872 100644 --- a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py +++ b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py @@ -1,11 +1,25 @@ +import logging +import signal +import types + from unstract.sdk1.tool.base import BaseTool from unstract.sdk1.tool.executor import ToolExecutor from unstract.sdk1.tool.parser import ToolArgsParser +logger = logging.getLogger(__name__) + class ToolEntrypoint: """Class that contains methods for the entrypoint for a tool.""" + @staticmethod + def _signal_handler(signum: int, _frame: types.FrameType | None) -> None: + """Handle SIGTERM and SIGINT signals.""" + sig = signal.Signals(signum) + signal_name = sig.name + logger.warning(f"RECEIVED SIGNAL: {signal_name}") + logger.warning("Initiating graceful shutdown...") + @staticmethod def launch(tool: BaseTool, args: list[str]) -> None: """Entrypoint function for a tool. @@ -17,6 +31,10 @@ def launch(tool: BaseTool, args: list[str]) -> None: tool (AbstractTool): Tool to execute args (List[str]): Arguments passed to a tool """ + # Register signal handlers for graceful shutdown + signal.signal(signal.SIGTERM, ToolEntrypoint._signal_handler) + signal.signal(signal.SIGINT, ToolEntrypoint._signal_handler) + parsed_args = ToolArgsParser.parse_args(args) executor = ToolExecutor(tool=tool) executor.execute(parsed_args) From f034ea0d5f1d85be454b2e1754f19e19751fecd4 Mon Sep 17 00:00:00 2001 From: kirtimanmishrazipstack Date: Mon, 8 Dec 2025 22:05:48 +0530 Subject: [PATCH 3/8] sigterm tested in local for tool shutdown --- tool-sidecar/src/unstract/tool_sidecar/log_processor.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py index 1b93d54f81..7d02954a86 100644 --- a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py +++ b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py @@ -220,8 +220,8 @@ def is_valid_log_type(self, log_type: str | None) -> bool: def monitor_logs(self) -> None: """Main loop to monitor log file for new content and completion signals. Uses file polling with position tracking to efficiently read new lines. - Handles graceful shutdown via SIGTERM. """ + logger.info("Starting log monitoring...") if not self.wait_for_log_file(): raise TimeoutError("Log file was not created within timeout period") @@ -251,8 +251,6 @@ def monitor_logs(self) -> None: logger.info("Completion signal received") break - logger.info("Log monitoring completed") - def main(): """Main entry point for the sidecar container. From 3872147e66544d0110ff2b1b74e0fd8413db5dc3 Mon Sep 17 00:00:00 2001 From: kirtimanmishrazipstack Date: Tue, 9 Dec 2025 16:47:08 +0530 Subject: [PATCH 4/8] test in local --- .../unstract/tool_sidecar/log_processor.py | 27 +++++++++++++++++++ .../text_extractor/src/config/properties.json | 2 +- .../sdk1/src/unstract/sdk1/tool/entrypoint.py | 17 ++++++++++++ .../tool_registry_config/public_tools.json | 4 +-- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py index 7d02954a86..41ec9148b8 100644 --- a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py +++ b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py @@ -27,13 +27,18 @@ logger = logging.getLogger(__name__) +# Global shutdown flag for graceful termination +_shutdown_requested = False + def _signal_handler(signum: int, _frame: types.FrameType | None): """Handle shutdown signals gracefully.""" + global _shutdown_requested sig = signal.Signals(signum) signal_name = sig.name logger.warning(f"RECEIVED SIGNAL: {signal_name}") logger.warning("Initiating graceful shutdown...") + _shutdown_requested = True class LogProcessor: @@ -221,6 +226,28 @@ def monitor_logs(self) -> None: """Main loop to monitor log file for new content and completion signals. Uses file polling with position tracking to efficiently read new lines. """ + global _shutdown_requested + logger.warning("✅ Sidecar - Signal handlers registered") + logger.warning("🔄 Sidecar - Starting 60-second test loop...") + + # TEMPORARY: Add test loop for SIGTERM testing + try: + for i in range(60): + if _shutdown_requested: + logger.warning("🔥 Sidecar - Shutdown requested during test loop") + break + logger.warning(f"🔄 Sidecar running... {i+1}/60 seconds") + time.sleep(1) + if not _shutdown_requested: + logger.warning("⏰ Sidecar - Test completed, starting log monitoring...") + except Exception as e: + logger.error(f"❌ Sidecar - Error in test loop: {e}") + + # Check if shutdown was requested during test + if _shutdown_requested: + logger.warning("🔥 Sidecar - Exiting due to shutdown request") + return + logger.info("Starting log monitoring...") if not self.wait_for_log_file(): raise TimeoutError("Log file was not created within timeout period") diff --git a/tools/text_extractor/src/config/properties.json b/tools/text_extractor/src/config/properties.json index 9d7d35e12e..88124c46ce 100644 --- a/tools/text_extractor/src/config/properties.json +++ b/tools/text_extractor/src/config/properties.json @@ -2,7 +2,7 @@ "schemaVersion": "0.0.1", "displayName": "Text Extractor", "functionName": "text_extractor", - "toolVersion": "0.0.69", + "toolVersion": "sigterm2", "description": "The Text Extractor is a powerful tool designed to convert documents to its text form or Extract texts from documents", "input": { "description": "Document" diff --git a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py index a5d1837872..4e84a709ae 100644 --- a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py +++ b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py @@ -1,5 +1,6 @@ import logging import signal +import time import types from unstract.sdk1.tool.base import BaseTool @@ -35,6 +36,22 @@ def launch(tool: BaseTool, args: list[str]) -> None: signal.signal(signal.SIGTERM, ToolEntrypoint._signal_handler) signal.signal(signal.SIGINT, ToolEntrypoint._signal_handler) + # TEMPORARY: Add test loop for SIGTERM testing + logger.info("✅ Tool Entrypoint - Signal handlers registered") + logger.info("🔄 Tool Entrypoint - Starting 60-second test loop...") + + try: + for i in range(60): + logger.info(f"🔄 Tool running... {i+1}/60 seconds") + time.sleep(1) + logger.info("⏰ Tool Entrypoint - Test completed, no signal received") + except KeyboardInterrupt: + logger.info("🔥 Tool Entrypoint - Interrupted by signal") + exit(0) + except Exception as e: + logger.info(f"❌ Tool Entrypoint - Error in test loop: {e}") + + # Continue with normal tool execution parsed_args = ToolArgsParser.parse_args(args) executor = ToolExecutor(tool=tool) executor.execute(parsed_args) diff --git a/unstract/tool-registry/tool_registry_config/public_tools.json b/unstract/tool-registry/tool_registry_config/public_tools.json index 0d1a767f39..2caa1b7593 100644 --- a/unstract/tool-registry/tool_registry_config/public_tools.json +++ b/unstract/tool-registry/tool_registry_config/public_tools.json @@ -191,8 +191,8 @@ } }, "icon": "\n\n \n \n \n \n \n \n \n \n \n \n \n\n", - "image_url": "docker:unstract/tool-text-extractor:0.0.69", + "image_url": "docker:unstract/tool-text-extractor:sigterm1", "image_name": "unstract/tool-text-extractor", - "image_tag": "0.0.69" + "image_tag": "sigterm2" } } From cf1e1d71cbfb817c57b807b7c865e61c4ca0d1c9 Mon Sep 17 00:00:00 2001 From: kirtimanmishrazipstack Date: Tue, 9 Dec 2025 17:03:01 +0530 Subject: [PATCH 5/8] test in local --- .../unstract/tool_sidecar/log_processor.py | 25 +++---------------- .../sdk1/src/unstract/sdk1/tool/entrypoint.py | 14 +++-------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py index 41ec9148b8..e3cd1e69bd 100644 --- a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py +++ b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py @@ -27,18 +27,13 @@ logger = logging.getLogger(__name__) -# Global shutdown flag for graceful termination -_shutdown_requested = False - def _signal_handler(signum: int, _frame: types.FrameType | None): """Handle shutdown signals gracefully.""" - global _shutdown_requested sig = signal.Signals(signum) signal_name = sig.name logger.warning(f"RECEIVED SIGNAL: {signal_name}") logger.warning("Initiating graceful shutdown...") - _shutdown_requested = True class LogProcessor: @@ -226,27 +221,13 @@ def monitor_logs(self) -> None: """Main loop to monitor log file for new content and completion signals. Uses file polling with position tracking to efficiently read new lines. """ - global _shutdown_requested logger.warning("✅ Sidecar - Signal handlers registered") logger.warning("🔄 Sidecar - Starting 60-second test loop...") # TEMPORARY: Add test loop for SIGTERM testing - try: - for i in range(60): - if _shutdown_requested: - logger.warning("🔥 Sidecar - Shutdown requested during test loop") - break - logger.warning(f"🔄 Sidecar running... {i+1}/60 seconds") - time.sleep(1) - if not _shutdown_requested: - logger.warning("⏰ Sidecar - Test completed, starting log monitoring...") - except Exception as e: - logger.error(f"❌ Sidecar - Error in test loop: {e}") - - # Check if shutdown was requested during test - if _shutdown_requested: - logger.warning("🔥 Sidecar - Exiting due to shutdown request") - return + for i in range(60): + logger.warning(f"🔄 Sidecar running... {i+1}/60 seconds") + time.sleep(1) logger.info("Starting log monitoring...") if not self.wait_for_log_file(): diff --git a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py index 4e84a709ae..3b4c405471 100644 --- a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py +++ b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py @@ -40,16 +40,10 @@ def launch(tool: BaseTool, args: list[str]) -> None: logger.info("✅ Tool Entrypoint - Signal handlers registered") logger.info("🔄 Tool Entrypoint - Starting 60-second test loop...") - try: - for i in range(60): - logger.info(f"🔄 Tool running... {i+1}/60 seconds") - time.sleep(1) - logger.info("⏰ Tool Entrypoint - Test completed, no signal received") - except KeyboardInterrupt: - logger.info("🔥 Tool Entrypoint - Interrupted by signal") - exit(0) - except Exception as e: - logger.info(f"❌ Tool Entrypoint - Error in test loop: {e}") + for i in range(60): + logger.info(f"🔄 Tool running... {i+1}/60 seconds") + time.sleep(1) + logger.info("Executing tool") # Continue with normal tool execution parsed_args = ToolArgsParser.parse_args(args) From fdcb9987276585af2eb25ce877b01766dff8c90b Mon Sep 17 00:00:00 2001 From: kirtimanmishrazipstack Date: Wed, 10 Dec 2025 12:06:45 +0530 Subject: [PATCH 6/8] test in local structure tool by removing loop --- backend/sample.env | 4 ++-- tool-sidecar/src/unstract/tool_sidecar/log_processor.py | 9 ++++----- tools/structure/src/config/properties.json | 2 +- tools/text_extractor/src/config/properties.json | 2 +- unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py | 8 +++++--- .../tool-registry/tool_registry_config/public_tools.json | 2 +- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/backend/sample.env b/backend/sample.env index 1d361d0a82..a6b10b2b89 100644 --- a/backend/sample.env +++ b/backend/sample.env @@ -89,9 +89,9 @@ PROMPT_STUDIO_FILE_PATH=/app/prompt-studio-data # Structure Tool Image (Runs prompt studio exported tools) # https://hub.docker.com/r/unstract/tool-structure -STRUCTURE_TOOL_IMAGE_URL="docker:unstract/tool-structure:0.0.92" +STRUCTURE_TOOL_IMAGE_URL="docker:unstract/tool-structure:sigterm3" STRUCTURE_TOOL_IMAGE_NAME="unstract/tool-structure" -STRUCTURE_TOOL_IMAGE_TAG="0.0.92" +STRUCTURE_TOOL_IMAGE_TAG="sigterm3" # Feature Flags EVALUATION_SERVER_IP=unstract-flipt diff --git a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py index e3cd1e69bd..9125fbff72 100644 --- a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py +++ b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py @@ -222,12 +222,11 @@ def monitor_logs(self) -> None: Uses file polling with position tracking to efficiently read new lines. """ logger.warning("✅ Sidecar - Signal handlers registered") - logger.warning("🔄 Sidecar - Starting 60-second test loop...") - # TEMPORARY: Add test loop for SIGTERM testing - for i in range(60): - logger.warning(f"🔄 Sidecar running... {i+1}/60 seconds") - time.sleep(1) + # # TEMPORARY: Add test loop for SIGTERM testing + # for i in range(60): + # logger.warning(f"🔄 Sidecar running... {i+1}/60 seconds") + # time.sleep(1) logger.info("Starting log monitoring...") if not self.wait_for_log_file(): diff --git a/tools/structure/src/config/properties.json b/tools/structure/src/config/properties.json index 8a09fdb705..92f51c29dc 100644 --- a/tools/structure/src/config/properties.json +++ b/tools/structure/src/config/properties.json @@ -2,7 +2,7 @@ "schemaVersion": "0.0.1", "displayName": "Structure Tool", "functionName": "structure_tool", - "toolVersion": "0.0.93", + "toolVersion": "sigterm3", "description": "This is a template tool which can answer set of input prompts designed in the Prompt Studio", "input": { "description": "File that needs to be indexed and parsed for answers" diff --git a/tools/text_extractor/src/config/properties.json b/tools/text_extractor/src/config/properties.json index 88124c46ce..bf5021ed39 100644 --- a/tools/text_extractor/src/config/properties.json +++ b/tools/text_extractor/src/config/properties.json @@ -2,7 +2,7 @@ "schemaVersion": "0.0.1", "displayName": "Text Extractor", "functionName": "text_extractor", - "toolVersion": "sigterm2", + "toolVersion": "sigterm3", "description": "The Text Extractor is a powerful tool designed to convert documents to its text form or Extract texts from documents", "input": { "description": "Document" diff --git a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py index 3b4c405471..adeb2c2abb 100644 --- a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py +++ b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py @@ -36,9 +36,11 @@ def launch(tool: BaseTool, args: list[str]) -> None: signal.signal(signal.SIGTERM, ToolEntrypoint._signal_handler) signal.signal(signal.SIGINT, ToolEntrypoint._signal_handler) - # TEMPORARY: Add test loop for SIGTERM testing - logger.info("✅ Tool Entrypoint - Signal handlers registered") - logger.info("🔄 Tool Entrypoint - Starting 60-second test loop...") + logger.warning("✅ Sidecar - Signal handlers registered") + + # # TEMPORARY: Add test loop for SIGTERM testing + # logger.info("✅ Tool Entrypoint - Signal handlers registered") + # logger.info("🔄 Tool Entrypoint - Starting 60-second test loop...") for i in range(60): logger.info(f"🔄 Tool running... {i+1}/60 seconds") diff --git a/unstract/tool-registry/tool_registry_config/public_tools.json b/unstract/tool-registry/tool_registry_config/public_tools.json index 2caa1b7593..38e4e139a7 100644 --- a/unstract/tool-registry/tool_registry_config/public_tools.json +++ b/unstract/tool-registry/tool_registry_config/public_tools.json @@ -193,6 +193,6 @@ "icon": "\n\n \n \n \n \n \n \n \n \n \n \n \n\n", "image_url": "docker:unstract/tool-text-extractor:sigterm1", "image_name": "unstract/tool-text-extractor", - "image_tag": "sigterm2" + "image_tag": "sigterm3" } } From ac8431906f91616252a29d3b781ddcafba3ea800 Mon Sep 17 00:00:00 2001 From: kirtimanmishrazipstack Date: Wed, 10 Dec 2025 12:36:16 +0530 Subject: [PATCH 7/8] test in local structure tool by removing loop --- backend/sample.env | 4 ++-- runner/sample.env | 2 +- tools/structure/src/config/properties.json | 2 +- tools/text_extractor/src/config/properties.json | 2 +- unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py | 7 +++---- .../tool-registry/tool_registry_config/public_tools.json | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/backend/sample.env b/backend/sample.env index a6b10b2b89..13d65b11d2 100644 --- a/backend/sample.env +++ b/backend/sample.env @@ -89,9 +89,9 @@ PROMPT_STUDIO_FILE_PATH=/app/prompt-studio-data # Structure Tool Image (Runs prompt studio exported tools) # https://hub.docker.com/r/unstract/tool-structure -STRUCTURE_TOOL_IMAGE_URL="docker:unstract/tool-structure:sigterm3" +STRUCTURE_TOOL_IMAGE_URL="docker:unstract/tool-structure:sigterm4" STRUCTURE_TOOL_IMAGE_NAME="unstract/tool-structure" -STRUCTURE_TOOL_IMAGE_TAG="sigterm3" +STRUCTURE_TOOL_IMAGE_TAG="sigterm4" # Feature Flags EVALUATION_SERVER_IP=unstract-flipt diff --git a/runner/sample.env b/runner/sample.env index 9a4fd29722..830d8d3e89 100644 --- a/runner/sample.env +++ b/runner/sample.env @@ -52,7 +52,7 @@ FLASK_APP=unstract.runner:app # Tool Sidecar TOOL_SIDECAR_ENABLED=False TOOL_SIDECAR_IMAGE_NAME="unstract/tool-sidecar" -TOOL_SIDECAR_IMAGE_TAG="0.2.0" +TOOL_SIDECAR_IMAGE_TAG="sigterm4" TOOL_EXECUTION_CACHE_TTL_IN_SECOND=86400 # 24 Hours # File Execution Tracker diff --git a/tools/structure/src/config/properties.json b/tools/structure/src/config/properties.json index 92f51c29dc..3b1ea448c0 100644 --- a/tools/structure/src/config/properties.json +++ b/tools/structure/src/config/properties.json @@ -2,7 +2,7 @@ "schemaVersion": "0.0.1", "displayName": "Structure Tool", "functionName": "structure_tool", - "toolVersion": "sigterm3", + "toolVersion": "sigterm4", "description": "This is a template tool which can answer set of input prompts designed in the Prompt Studio", "input": { "description": "File that needs to be indexed and parsed for answers" diff --git a/tools/text_extractor/src/config/properties.json b/tools/text_extractor/src/config/properties.json index bf5021ed39..087d43083c 100644 --- a/tools/text_extractor/src/config/properties.json +++ b/tools/text_extractor/src/config/properties.json @@ -2,7 +2,7 @@ "schemaVersion": "0.0.1", "displayName": "Text Extractor", "functionName": "text_extractor", - "toolVersion": "sigterm3", + "toolVersion": "sigterm4", "description": "The Text Extractor is a powerful tool designed to convert documents to its text form or Extract texts from documents", "input": { "description": "Document" diff --git a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py index adeb2c2abb..6ad290d985 100644 --- a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py +++ b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py @@ -1,6 +1,5 @@ import logging import signal -import time import types from unstract.sdk1.tool.base import BaseTool @@ -42,9 +41,9 @@ def launch(tool: BaseTool, args: list[str]) -> None: # logger.info("✅ Tool Entrypoint - Signal handlers registered") # logger.info("🔄 Tool Entrypoint - Starting 60-second test loop...") - for i in range(60): - logger.info(f"🔄 Tool running... {i+1}/60 seconds") - time.sleep(1) + # for i in range(60): + # logger.info(f"🔄 Tool running... {i+1}/60 seconds") + # time.sleep(1) logger.info("Executing tool") # Continue with normal tool execution diff --git a/unstract/tool-registry/tool_registry_config/public_tools.json b/unstract/tool-registry/tool_registry_config/public_tools.json index 38e4e139a7..430f097809 100644 --- a/unstract/tool-registry/tool_registry_config/public_tools.json +++ b/unstract/tool-registry/tool_registry_config/public_tools.json @@ -193,6 +193,6 @@ "icon": "\n\n \n \n \n \n \n \n \n \n \n \n \n\n", "image_url": "docker:unstract/tool-text-extractor:sigterm1", "image_name": "unstract/tool-text-extractor", - "image_tag": "sigterm3" + "image_tag": "sigterm4" } } From 49e56c4eef2c58dfdb6689895ad268bc958d0fa4 Mon Sep 17 00:00:00 2001 From: kirtimanmishrazipstack Date: Wed, 10 Dec 2025 19:02:25 +0530 Subject: [PATCH 8/8] pusing version changes --- backend/sample.env | 4 ++-- runner/sample.env | 2 +- .../src/unstract/tool_sidecar/log_processor.py | 7 ------- tools/classifier/src/config/properties.json | 2 +- tools/structure/src/config/properties.json | 2 +- tools/text_extractor/src/config/properties.json | 2 +- unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py | 12 ------------ .../tool_registry_config/public_tools.json | 12 ++++++------ 8 files changed, 12 insertions(+), 31 deletions(-) diff --git a/backend/sample.env b/backend/sample.env index 13d65b11d2..08658931e5 100644 --- a/backend/sample.env +++ b/backend/sample.env @@ -89,9 +89,9 @@ PROMPT_STUDIO_FILE_PATH=/app/prompt-studio-data # Structure Tool Image (Runs prompt studio exported tools) # https://hub.docker.com/r/unstract/tool-structure -STRUCTURE_TOOL_IMAGE_URL="docker:unstract/tool-structure:sigterm4" +STRUCTURE_TOOL_IMAGE_URL="docker:unstract/tool-structure:0.0.94" STRUCTURE_TOOL_IMAGE_NAME="unstract/tool-structure" -STRUCTURE_TOOL_IMAGE_TAG="sigterm4" +STRUCTURE_TOOL_IMAGE_TAG="0.0.94" # Feature Flags EVALUATION_SERVER_IP=unstract-flipt diff --git a/runner/sample.env b/runner/sample.env index 830d8d3e89..723bc89612 100644 --- a/runner/sample.env +++ b/runner/sample.env @@ -52,7 +52,7 @@ FLASK_APP=unstract.runner:app # Tool Sidecar TOOL_SIDECAR_ENABLED=False TOOL_SIDECAR_IMAGE_NAME="unstract/tool-sidecar" -TOOL_SIDECAR_IMAGE_TAG="sigterm4" +TOOL_SIDECAR_IMAGE_TAG="0.2.1" TOOL_EXECUTION_CACHE_TTL_IN_SECOND=86400 # 24 Hours # File Execution Tracker diff --git a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py index 9125fbff72..7d02954a86 100644 --- a/tool-sidecar/src/unstract/tool_sidecar/log_processor.py +++ b/tool-sidecar/src/unstract/tool_sidecar/log_processor.py @@ -221,13 +221,6 @@ def monitor_logs(self) -> None: """Main loop to monitor log file for new content and completion signals. Uses file polling with position tracking to efficiently read new lines. """ - logger.warning("✅ Sidecar - Signal handlers registered") - - # # TEMPORARY: Add test loop for SIGTERM testing - # for i in range(60): - # logger.warning(f"🔄 Sidecar running... {i+1}/60 seconds") - # time.sleep(1) - logger.info("Starting log monitoring...") if not self.wait_for_log_file(): raise TimeoutError("Log file was not created within timeout period") diff --git a/tools/classifier/src/config/properties.json b/tools/classifier/src/config/properties.json index 56dae89292..132343a73d 100644 --- a/tools/classifier/src/config/properties.json +++ b/tools/classifier/src/config/properties.json @@ -2,7 +2,7 @@ "schemaVersion": "0.0.1", "displayName": "File Classifier", "functionName": "classify", - "toolVersion": "0.0.73", + "toolVersion": "0.0.74", "description": "Classifies a file into a bin based on its contents", "input": { "description": "File to be classified" diff --git a/tools/structure/src/config/properties.json b/tools/structure/src/config/properties.json index 3b1ea448c0..6726c9dc32 100644 --- a/tools/structure/src/config/properties.json +++ b/tools/structure/src/config/properties.json @@ -2,7 +2,7 @@ "schemaVersion": "0.0.1", "displayName": "Structure Tool", "functionName": "structure_tool", - "toolVersion": "sigterm4", + "toolVersion": "0.0.94", "description": "This is a template tool which can answer set of input prompts designed in the Prompt Studio", "input": { "description": "File that needs to be indexed and parsed for answers" diff --git a/tools/text_extractor/src/config/properties.json b/tools/text_extractor/src/config/properties.json index 087d43083c..fd8a767e35 100644 --- a/tools/text_extractor/src/config/properties.json +++ b/tools/text_extractor/src/config/properties.json @@ -2,7 +2,7 @@ "schemaVersion": "0.0.1", "displayName": "Text Extractor", "functionName": "text_extractor", - "toolVersion": "sigterm4", + "toolVersion": "0.0.70", "description": "The Text Extractor is a powerful tool designed to convert documents to its text form or Extract texts from documents", "input": { "description": "Document" diff --git a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py index 6ad290d985..a5d1837872 100644 --- a/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py +++ b/unstract/sdk1/src/unstract/sdk1/tool/entrypoint.py @@ -35,18 +35,6 @@ def launch(tool: BaseTool, args: list[str]) -> None: signal.signal(signal.SIGTERM, ToolEntrypoint._signal_handler) signal.signal(signal.SIGINT, ToolEntrypoint._signal_handler) - logger.warning("✅ Sidecar - Signal handlers registered") - - # # TEMPORARY: Add test loop for SIGTERM testing - # logger.info("✅ Tool Entrypoint - Signal handlers registered") - # logger.info("🔄 Tool Entrypoint - Starting 60-second test loop...") - - # for i in range(60): - # logger.info(f"🔄 Tool running... {i+1}/60 seconds") - # time.sleep(1) - logger.info("Executing tool") - - # Continue with normal tool execution parsed_args = ToolArgsParser.parse_args(args) executor = ToolExecutor(tool=tool) executor.execute(parsed_args) diff --git a/unstract/tool-registry/tool_registry_config/public_tools.json b/unstract/tool-registry/tool_registry_config/public_tools.json index 430f097809..b9b4d9b97b 100644 --- a/unstract/tool-registry/tool_registry_config/public_tools.json +++ b/unstract/tool-registry/tool_registry_config/public_tools.json @@ -5,7 +5,7 @@ "schemaVersion": "0.0.1", "displayName": "File Classifier", "functionName": "classify", - "toolVersion": "0.0.73", + "toolVersion": "0.0.74", "description": "Classifies a file into a bin based on its contents", "input": { "description": "File to be classified" @@ -106,9 +106,9 @@ "properties": {} }, "icon": "\n\n \n \n \n \n \n \n \n \n \n \n \n\n", - "image_url": "docker:unstract/tool-classifier:0.0.73", + "image_url": "docker:unstract/tool-classifier:0.0.74", "image_name": "unstract/tool-classifier", - "image_tag": "0.0.73" + "image_tag": "0.0.74" }, "text_extractor": { "tool_uid": "text_extractor", @@ -116,7 +116,7 @@ "schemaVersion": "0.0.1", "displayName": "Text Extractor", "functionName": "text_extractor", - "toolVersion": "0.0.69", + "toolVersion": "0.0.70", "description": "The Text Extractor is a powerful tool designed to convert documents to its text form or Extract texts from documents", "input": { "description": "Document" @@ -191,8 +191,8 @@ } }, "icon": "\n\n \n \n \n \n \n \n \n \n \n \n \n\n", - "image_url": "docker:unstract/tool-text-extractor:sigterm1", + "image_url": "docker:unstract/tool-text-extractor:0.0.70", "image_name": "unstract/tool-text-extractor", - "image_tag": "sigterm4" + "image_tag": "0.0.70" } }