Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,018 changes: 1,009 additions & 1,009 deletions backend/uv.lock

Large diffs are not rendered by default.

38 changes: 19 additions & 19 deletions docker/scripts/uv-lock-gen/uv-lock.sh
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
#!/bin/bash
set -o pipefail

# Extract local path dependencies from [tool.uv.sources] in a pyproject.toml.
# Returns resolved pyproject.toml paths for each local dependency.
# Resolved pyproject.toml paths for a directory's local path dependencies.
# The lockfile is read as well as the pyproject: it records the whole resolved
# graph, so a change further down it (sdk1 -> connectors) is still seen, while
# the pyproject covers a dependency added but not yet locked.
get_local_dep_pyprojects() {
local dir="$1"
local file_path="$dir/pyproject.toml"

grep -A1 'path\s*=' "$file_path" 2>/dev/null \
| grep -oP 'path\s*=\s*"\K[^"]+' \
| while read -r rel_path; do
# Resolve relative to the service directory
local dep_pyproject
if [[ "$dir" == "." ]]; then
dep_pyproject="$rel_path/pyproject.toml"
else
dep_pyproject="$dir/$rel_path/pyproject.toml"
fi
# Normalize the path
dep_pyproject=$(realpath --relative-to=. "$dep_pyproject" 2>/dev/null || echo "$dep_pyproject")
if [[ -f "$dep_pyproject" ]]; then
echo "$dep_pyproject"
fi
done
{
grep -oP 'path\s*=\s*"\K[^"]+' "$dir/pyproject.toml" 2>/dev/null
grep -oP 'source = \{ (editable|directory) = "\K[^"]+' "$dir/uv.lock" 2>/dev/null
} | while read -r rel_path; do
local dep_pyproject
dep_pyproject=$(realpath --relative-to=. "$dir/$rel_path/pyproject.toml" 2>/dev/null) || continue
if [[ -f "$dep_pyproject" ]]; then
echo "$dep_pyproject"
fi
done | sort -u
}

# Check if a directory's own pyproject.toml or any of its local
Expand Down Expand Up @@ -107,6 +102,11 @@ directories=(
"unstract/core"
"unstract/flags"
"unstract/connectors"
"unstract/sdk1"
"unstract/tool-registry"
"unstract/tool-sandbox"
"unstract/workflow-execution"
Comment thread
chandrasekharan-zipstack marked this conversation as resolved.
"tool-sidecar"
"workers"
)

Expand Down
1,554 changes: 777 additions & 777 deletions platform-service/uv.lock

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions unstract/connectors/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1,232 changes: 616 additions & 616 deletions unstract/filesystem/uv.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion unstract/sdk1/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ dependencies = [
"pdfplumber>=0.11.2",
"redis>=5.2.1",
# # LLMWhisperer client
"llmwhisperer-client>=2.6.2",
"llmwhisperer-client>=2.8.1",
# # Core utilities (Redis Sentinel-aware client factory, etc.)
"unstract-core",
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ class OutputModes(Enum):
TEXT = "text"


class LineSplitterStrategies(Enum):
LEFT_PRIORITY = "left-priority"
MID_PRIORITY = "mid-priority"
RIGHT_PRIORITY = "right-priority"


class HTTPMethod(Enum):
GET = "GET"
POST = "POST"
Expand Down Expand Up @@ -60,12 +66,14 @@ class WhispererConfig:
MEDIAN_FILTER_SIZE = "median_filter_size"
GAUSSIAN_BLUR_RADIUS = "gaussian_blur_radius"
LINE_SPLITTER_TOLERANCE = "line_splitter_tolerance"
LINE_SPLITTER_STRATEGY = "line_spitter_strategy"
LINE_SPLITTER_STRATEGY = "line_splitter_strategy"
HORIZONTAL_STRETCH_FACTOR = "horizontal_stretch_factor"
PAGES_TO_EXTRACT = "pages_to_extract"
MARK_VERTICAL_LINES = "mark_vertical_lines"
MARK_HORIZONTAL_LINES = "mark_horizontal_lines"
# Misspelling retained: correcting the JSON schema key means migrating saved configs
PAGE_SEPARATOR = "page_seperator"
PAGE_SEPARATOR_PARAM = "page_separator"
URL_IN_POST = "url_in_post"
TAG = "tag"
USE_WEBHOOK = "use_webhook"
Expand All @@ -78,6 +86,7 @@ class WhispererConfig:
INCLUDE_LINE_CONFIDENCE = "include_line_confidence"
EXTRACT_ALL_LINES = "extract_all_lines"
LINES = "lines"
FILE_NAME = "file_name"


class WhisperStatus:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from unstract.sdk1.adapters.utils import AdapterUtils
from unstract.sdk1.adapters.x2text.constants import X2TextConstants
from unstract.sdk1.adapters.x2text.llm_whisperer_v2.src.constants import (
LineSplitterStrategies,
Modes,
OutputModes,
WhispererConfig,
Expand Down Expand Up @@ -171,6 +172,20 @@ def get_whisperer_params(
Returns:
dict[str, Any]: Query params
"""
line_splitter_strategy = config.get(
WhispererConfig.LINE_SPLITTER_STRATEGY,
WhispererDefaults.LINE_SPLITTER_STRATEGY,
)
# This setting was never sent to the service, so stored values were never
# validated. The service rejects an unknown strategy with a 400.
if line_splitter_strategy not in {s.value for s in LineSplitterStrategies}:
logger.warning(
"Unsupported line splitter strategy '%s', falling back to '%s'",
line_splitter_strategy,
WhispererDefaults.LINE_SPLITTER_STRATEGY,
)
line_splitter_strategy = WhispererDefaults.LINE_SPLITTER_STRATEGY

params = {
WhispererConfig.MODE: config.get(WhispererConfig.MODE, Modes.FORM.value),
WhispererConfig.OUTPUT_MODE: config.get(
Expand All @@ -180,10 +195,7 @@ def get_whisperer_params(
WhispererConfig.LINE_SPLITTER_TOLERANCE,
WhispererDefaults.LINE_SPLITTER_TOLERANCE,
),
WhispererConfig.LINE_SPLITTER_STRATEGY: config.get(
WhispererConfig.LINE_SPLITTER_STRATEGY,
WhispererDefaults.LINE_SPLITTER_STRATEGY,
),
WhispererConfig.LINE_SPLITTER_STRATEGY: line_splitter_strategy,
WhispererConfig.HORIZONTAL_STRETCH_FACTOR: config.get(
WhispererConfig.HORIZONTAL_STRETCH_FACTOR,
WhispererDefaults.HORIZONTAL_STRETCH_FACTOR,
Expand All @@ -200,7 +212,7 @@ def get_whisperer_params(
WhispererConfig.MARK_HORIZONTAL_LINES,
WhispererDefaults.MARK_HORIZONTAL_LINES,
),
WhispererConfig.PAGE_SEPARATOR: config.get(
WhispererConfig.PAGE_SEPARATOR_PARAM: config.get(
WhispererConfig.PAGE_SEPARATOR,
WhispererDefaults.PAGE_SEPARATOR,
),
Expand Down Expand Up @@ -260,6 +272,8 @@ def send_whisper_request(
params = LLMWhispererHelper.get_whisperer_params(
config=config, extra_params=extra_params
)
# Recorded against the extraction for cross referencing in usage reports
params[WhispererConfig.FILE_NAME] = Path(input_file_path).name
response: requests.Response
try:
input_file_data = BytesIO(fs.read(path=input_file_path, mode="rb"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"line_splitter_strategy": {
"type": "string",
"title": "Line Splitter Strategy",
"enum": ["left-priority", "mid-priority", "right-priority"],
"default":"left-priority",
"description": "An advanced option for customizing the line splitting process."
},
Expand Down
49 changes: 49 additions & 0 deletions unstract/sdk1/tests/test_llm_whisperer_v2_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""Tests for the query params the LLMWhisperer V2 adapter sends."""

import pytest
from unstract.sdk1.adapters.x2text.llm_whisperer_v2.src.dto import (
WhispererRequestParams,
)
from unstract.sdk1.adapters.x2text.llm_whisperer_v2.src.helper import LLMWhispererHelper


def _params(config: dict) -> dict:
return LLMWhispererHelper.get_whisperer_params(
config=config, extra_params=WhispererRequestParams()
)


def test_line_splitter_strategy_from_config() -> None:
"""The key stored by the adapter's JSON schema is the one that is read."""
params = _params({"line_splitter_strategy": "right-priority"})

assert params["line_splitter_strategy"] == "right-priority"


@pytest.mark.parametrize("strategy", ["left-priority", "mid-priority", "right-priority"])
def test_supported_line_splitter_strategies_pass_through(strategy: str) -> None:
"""Every value the service accepts reaches it unchanged."""
params = _params({"line_splitter_strategy": strategy})

assert params["line_splitter_strategy"] == strategy


@pytest.mark.parametrize(
"stored", ["", " ", "left_priority", "LEFT-PRIORITY", "nonsense"]
)
def test_unsupported_line_splitter_strategy_falls_back(
stored: str, caplog: pytest.LogCaptureFixture
) -> None:
"""A stored value the service would reject keeps the previous behaviour."""
params = _params({"line_splitter_strategy": stored})

assert params["line_splitter_strategy"] == "left-priority"
assert "Unsupported line splitter strategy" in caplog.text


def test_page_separator_read_under_legacy_config_key() -> None:
"""Existing configs store the misspelled key but the client kwarg is correct."""
params = _params({"page_seperator": "<<< {{page_no}} >>>"})

assert params["page_separator"] == "<<< {{page_no}} >>>"
assert "page_seperator" not in params
8 changes: 4 additions & 4 deletions unstract/sdk1/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions unstract/tool-registry/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions unstract/workflow-execution/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading