Tags: Zipstack/unstract
Tags
[MISC] Fail rig groups that inherit an unrelated pytest config; skip … …order-dependent connector tests (#2205) * [FIX] Reject rig groups that inherit an unrelated project's pytest config `cd workdir && pytest` does not pin config to workdir — pytest walks up until it finds one. A group whose workdir is a nested project without its own config therefore silently adopts its parent's addopts (coverage targets, --strict-config) and fails for reasons unrelated to its tests. The failure is opaque: a usage error, or zero tests collected. Resolve the config file the same way pytest does and fail the group up front with a message naming the offending file and the fix. Inheriting the repo-root config stays allowed — that is the normal monorepo case, and two groups rely on it today. Verified against all 18 existing pytest groups: none are rejected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * [FIX] Skip order-dependent destination-connector and SharePoint tests These tests share a fixed table (or remote path) across test methods with no working teardown — several tearDown bodies are a bare `pass` with the drop statements commented out. Results therefore depend on execution order, and the SharePoint read test consumes what the write test leaves behind. They are inert today only because the credentials they need are not provisioned, so the breakage would surface as a surprise the moment someone adds them. Skip explicitly, with the reason stated, so enabling credentials is a deliberate step rather than an accident. The postgres variant is deliberately untouched — it runs today and is being fixed rather than skipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [FIX] Run the workers integration lane against the rig's Postgres The lane reported 141 tests, 141 skipped: the rig provisions a testcontainers Postgres and exports DB_*, but the workers fixtures read TEST_DB_* and so fell back to the dev-compose defaults, and nothing ever applied the pg_queue schema. Mirror the provisioned DB_* onto TEST_DB_* for groups requiring postgres (defaulting DB_SCHEMA to public — a bare container has no other schema), and apply defaults.postgres_migrate once after the container is up and before any group runs. Schema is a property of the database rather than of a group, and guarding on the provisioned URL keeps it a no-op under the compose runtime, where the platform's own backend migrates on start. Django migrate rather than DDL in a fixture: the lane asserts against the real generated CheckConstraint, which hand-written DDL would render self-referential. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [MISC] Tighten rig DB-wiring comments Concise, generic WHY-only; drop stale-prone references to specific function names and test lists. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [FIX] Skip the pre-group migration when no group needs Postgres The testcontainers runtime provisions the full infra set, so a connector-only run would still trigger the backend migration and could be aborted by an unrelated migration failure. Gate on a runnable group actually declaring a Postgres requirement. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [FIX] Seed last_progress_at in pg_barrier_state test inserts The column is NOT NULL with only a Python-level default, so raw-SQL seeds that omit it hit a NotNullViolation once the tests run against a real migrated database. Add now() to the four barrier seed inserts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [FIX] Isolate the pg_queue suite per xdist worker via its own schema This is the only suite that opens a raw psycopg2 connection, so it bypasses pytest-django's per-worker test database. Under xdist every worker shared one physical table, and the reaper/sweeper paths scan all rows — so a whole-table assertion in one worker saw another worker's rows. Give each worker its own schema (cloned from the rig-migrated public via LIKE ... INCLUDING ALL, the tables have no cross-table FKs) and truncate between tests, since a raw connection carries committed rows forward with no rollback. Cuts the lane from 35 failures to 0 at serial and -n2. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [FIX] Pin schema-env fixture after the os.environ reset The rig injects TEST_DB_SCHEMA=public into the group env, which conftest captures into the pristine baseline that _restore_os_environ restores around every test. _pg_worker_schema_env sets the per-worker schema (test_gwN), but with no dependency edge the two same-scope autouse fixtures ordered only by coincidence — in CI _restore_os_environ ran last and clobbered the schema back to public, so every xdist worker shared the one public table and the barrier / reaper whole-table DELETEs wiped each other's in-flight rows (6 integration failures). Depend on _restore_os_environ explicitly so the schema env is set after the reset and survives into the test body. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [MISC] Address CodeRabbit review nits - README: document the actual defaults-level key (postgres_migrate), not migrate - test_cli: isolate REPO_ROOT via monkeypatch so the walk stays in tmp_path - test_groups: escape the regex dot in pytest.raises match= (RUF043) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [FIX] Address PK review on rig config guardrail + PG schema fixtures - conftest: derive base PG schema from TEST_DB_SCHEMA/DB_SCHEMA (not literal public) so a local `pytest -m integration` finds tables migrated into `unstract`; clone per-worker schema from that base. - conftest: gate the per-test schema-env/truncate fixture on the integration marker + PG reachability so the DB-free unit lane no longer opens a connection (and pays retry-sleep) before every test, nor mutates DB_SCHEMA. - cli: config-isolation guardrail resolves from the paths' common ancestor (what pytest actually does), catching a nested project whose paths reach past the workdir; match config sections at line start; run the guardrail in `validate` too; broaden the fix hint to pytest.ini when no pyproject exists. - cli: layer the provisioned connection over postgres_migrate spec.env so a stray DB_HOST/DB_NAME can't redirect migrations; TEST_DB_* mirror uses setdefault to respect a group's escape hatch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [TEST] Isolate destination-connector test table per xdist worker Under rig parallelism, sibling test methods in this TestCase all wrote to a single `output_3` table; a concurrent worker's row could win the `ORDER BY created_at DESC LIMIT 1` read and fail the data assertion with a null column. Give each worker its own table so the reads can't collide. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [FIX] Harden per-worker schema clone (parameterized identifiers, fresh drop) Address CodeRabbit: build the schema/table DDL via psycopg2.sql identifiers instead of f-strings, and DROP the per-worker schema before recreating so a reused local DB doesn't keep a stale clone whose table definitions have since changed (CREATE IF NOT EXISTS would silently no-op). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[FIX] Propagate all *_cls/*_class plugin metadata fields in PluginMan… …ager (#2201) * [FIX] Propagate all *_cls/*_class plugin metadata fields, not a hardcoded 3 PluginManager.load_plugins() only copied entrypoint_cls, exception_cls, and service_class from a plugin's metadata into the registered plugin dict. The verticals_usage plugin (which feeds API deployment usage into the API Hub subscription dashboard) also defines headers_cache_class, which was silently dropped, causing every plugin["headers_cache_class"] lookup in api_hub_usage_utils.py to raise KeyError - swallowed by broad except blocks - so API hub headers were never cached and usage never reached the verticals.subscription_usage table. * [FIX] Guard non-string metadata keys and add review-flagged test coverage - key.endswith() on a non-string metadata key raised AttributeError, uncaught by the surrounding except KeyError, crashing load_plugins() for every plugin process-wide (CodeRabbit). - Hoist the _cls/_class suffix tuple to a module constant and trim the comment so it doesn't reference one enterprise plugin's field name. - Note that the `key not in plugin_data` guard is purely defensive today. - Add tests locking in that a *_class field propagates by name even when its value is None, and that is_active=False also skips loading. --------- Co-authored-by: Athul <89829560+athul-rs@users.noreply.github.com>
UN-3636 [PERF] Stop the test rig wasting CPU and hashing time (#2195) * UN-3636 [FEAT] Merge overlay manifests via UNSTRACT_RIG_EXTRA_MANIFESTS load_groups() now merges extra group manifests listed in the env var (os.pathsep-separated, REPO_ROOT-relative) onto the base tests/groups.yaml before validation, so cross-manifest depends_on and the platform-gate invariant are checked over the union. Name collisions are an error. Lets a downstream repo (the cloud build) contribute its own test groups by copying a groups.cloud.yaml into the merged tree, without editing the OSS manifest. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [FIX] Skip org lookup when no org in context UserContext.get_organization() ran Organization.objects.get() even with no org id in StateStore (import time, or management commands with no request), catching only DoesNotExist/ProgrammingError — a DB-less/unmigrated setup hit an uncaught OperationalError. Short-circuit when there's no org id: no query, so serializers/managers that reference org-scoped querysets at class-def can be imported during DB-free test collection. * UN-3636 [FIX] Scope overlay manifests to the default manifest Address review feedback on the UNSTRACT_RIG_EXTRA_MANIFESTS overlay: - Overlays now apply only when loading the default manifest, so an explicit `load_groups(path)` (test fixture, ad-hoc manifest) can no longer absorb a downstream repo's ambient overlay. - `_merge_manifest` returns the merged defaults so an overlay can rename `platform_gate_group` instead of having it silently ignored. - A bad path in the env var raises a ValueError naming the variable rather than a bare FileNotFoundError/IsADirectoryError. - Extract `_load_manifest_dict` to single-source manifest parsing and its error message. - Tests: drive the real default-manifest path; cover overlay isolation, overlay defaults, malformed overlay, and a missing overlay path. - Pin the truthy branch of UserContext.get_organization so inverting the guard can't pass unnoticed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [FIX] Stop re-running cross-tier deps in every tier leg `--tier X` expanded each selected group's `depends_on` transitively, with no tier bound. `integration-workflow-execution` and `e2e-smoke` both declare `depends_on: [unit-sdk1, unit-workers]`, so those two unit groups ran again in the integration leg and a third time in the e2e leg. Tiers run as separate CI legs and the unit leg already covers them, so dep expansion is now bounded to the requested tier. Explicitly named groups are never dropped, and intra-tier deps (e2e-smoke -> e2e-login) still expand and order as before. Unrun deps do not weaken gating: `blocked_by` intersects with groups that failed in the same run. Measured on the last main run: ~88s of unit-workers and ~48s of unit-sdk1 re-executed per run. On the cloud CI runner the same duplication costs ~350s. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [MISC] Drop the ENVIRONMENT gate on the LLM mock (#2191) * UN-3636 [FIX] Drop the ENVIRONMENT gate on the LLM mock It did not defend the case it was added for. The threat was a worker env block copied out of the test overlay into a real deployment, but the gate was written into that same block, so a copy carries it. Base compose also sets ENVIRONMENT=development on both workers that run the injection, so any deployment derived from it satisfied the gate regardless. That left one real case -- the mock var set alone somewhere that sets no ENVIRONMENT at all -- which holds by accident rather than design, in exchange for depending on a variable nothing else in the codebase reads. What actually guards the hatch is unchanged: it is off unless someone sets UNSTRACT_LLM_MOCK_RESPONSE, and it warns once per process while active. Making mocked spend distinguishable downstream is the defence worth having, and it belongs on the usage record rather than in a config check. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * UN-3636 [MISC] Drop the unread ENVIRONMENT variable from compose Nothing reads it: no service, worker, frontend or plugin looks the variable up, and the one consumer it ever had — the LLM mock gate — was removed in the previous commit. Dropping it everywhere keeps a dead knob from looking load-bearing to the next reader. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ryg9chVDJQggCybpq3YoY3 --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * UN-3636 [MISC] Tighten code comments Drop lines that restate the code, trim session-specific detail, and merge comments that duplicated each other across a module and its test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [FIX] Gate overlay merging on an omitted path, not its value `load_groups(DEFAULT_MANIFEST)` merged overlays even though the caller named a manifest explicitly, because the check compared path values. Path equality is also spelling-sensitive, so the same file relative and absolute behaved differently. Key on `path is None` instead: an explicit path loads exactly what it names. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ryg9chVDJQggCybpq3YoY3 * UN-3636 [FIX] Stop ide_prompt_complete tests from hitting the network TestIdePromptComplete drives the full success path, which reaches client_plugin_registry.get_client_plugin("subscription_usage"). In OSS no such plugin is installed, so the lookup returns None instantly. In a tree with the cloud plugins copied in, it resolves to a real plugin that POSTs to the backend; with no backend running the call only fails after a multi-second connect timeout, and _track_subscription_usage swallows the error so the tests still pass. That accounted for ~190s of the cloud unit-workers run. The file already declared _PATCH_GET_PLUGIN but never applied it outside the dedicated subscription-usage classes. Apply it as a class-scoped fixture so the lookup is pinned to the OSS answer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [PERF] Stop the test rig wasting CPU and hashing time Three independent wins measured on the cloud-merged tree: - `-n auto` collapsed to a single worker on any group shipping psutil, because xdist prefers physical cores there. Resolve the count in the rig instead, capped at 8 to avoid contending on the test database. - `--no-migrations` builds the schema from the models rather than replaying the full migration history once per xdist worker. - Test fixtures were paying 600k-iteration PBKDF2 per seeded user. integration-backend fell from 163s to ~52s with an identical result set. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [TEST] Cut rig CI overhead and unblock unit-workers-cloud Second performance pass on the test rig: - unit-workers-cloud ran zero tests: its group `PYTHONPATH` overwrote the rig-injected plugin dir, so `-p rig_critical_path` failed to import. Merge the two instead of letting env.update clobber it. - Drop `-s` from backend addopts — it disabled capture and flooded the log. - Persist uv's cache across runs via setup-uv enable-cache, so per-group `uv sync` links from cache instead of refetching. - No-op the real backoff sleeps in the sdk retry tests (~7s -> ~1s); no test asserts on elapsed time. - TestCleanupTasks needs no transaction semantics; TestCase over TransactionTestCase drops the per-test truncate-and-reseed. - Reject a non-mapping `groups:` manifest instead of crashing later. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnLaN45ShBbcCXWZkqCThz * UN-3636 [MISC] Drop stale-prone CI comments --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[MISC] Update OpenRouter adapter logo to refreshed brand mark and add… …ed padding to Mistral logo (#2186) * [FIX] Update OpenRouter adapter logo to refreshed brand mark OpenRouter refreshed its brand; the old grey routing-arrows mark is retired. Replaces the adapter icon with the new glyph (rendered from the official brand SVG), keeping the same 512x512 transparent PNG. Ref: https://openrouter.ai/blog/announcements/brand-refresh/ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L549habQ6K2m1ACJ7DwtsE * [FIX] Re-pad Mistral adapter logo for consistent margins The Mistral pixel-M icon ran edge-to-edge with no horizontal padding, inconsistent with the other adapter icons. Re-center the mark on the 512x512 transparent canvas with even margins. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L549habQ6K2m1ACJ7DwtsE --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
UN-3741 [FIX] Show created/modified metadata on adapter and Prompt St… …udio list pages (#2182) * UN-3741 [FEAT] Show created/modified metadata on adapter and Prompt Studio list pages Adds an 'Updated <relative time>' hint plus an info icon with hover tooltip (created at, last modified, model / prompt count when present) to the shared ListView widget used by the adapter and Prompt Studio list pages. Backend: expose created_at/modified_at on AdapterListSerializer, and surface the latest prompt modified_at on the Prompt Studio list — prompt edits never touch the CustomTool row, so its own modified_at understates activity. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UN-3741 [MISC] Vertically center list-row metadata and even out spacing Restructure ListView rows into three vertically-centered columns (title+description, owner+updated, actions) so the metadata cluster centers against the whole entry instead of hugging the title line. Consistent flex gaps replace the old width-percentage layout; row padding bumped for breathing room. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UN-3741 [MISC] Cap list description width for uniform rows Full text remains available via the ellipsis tooltip. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UN-3741 [MISC] Address review feedback: pin test timestamp, guard deprecated actions - Pin the prompt's modified_at to a known future instant in the list test so back-to-back creates can't tie on coarse clocks (Greptile P2) - Block edit/share click handlers on deprecated items to match their disabled styling (CodeRabbit) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UN-3741 [FIX] Address review: bump tool modified_at at source, opt-in Updated label Backend — maintain modified_at at the source instead of deriving it (review: derived max could travel backwards on prompt delete, and gave the same field two meanings across list/detail while breaking ?ordering=modified_at): - ToolStudioPrompt.save()/delete() now bump the parent CustomTool row; the list subquery annotation and SerializerMethodField are gone, so the plain field is honest, identical on every endpoint, and orderable - Tests pin create/edit/delete bumps, cross-tool isolation, and the promptless-project case; adapter list endpoint gains coverage (timestamps present, rename bumps modified_at, created_at stable) Frontend — the Updated label is now explicit opt-in (showModified), passed only by the adapter and Prompt Studio lists; Workflows and Connectors no longer inherit a misleading value by field presence: - New timeAgo helper (strict ISO parse, clamped to now) replaces raw moment usage: malformed input hides the label instead of rendering "Invalid date" - Meta column no longer swallows row clicks; titles ellipsize like descriptions; tooltip fields use one presence convention (!= null) and build lazily; centered prop wired into the row Flex (dead CSS removed); updateList merges PATCH responses so list-only fields survive edits; new CSS classes renamed to the widget's list-view-* prefix; two misleading CSS comments corrected Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UN-3741 [FIX] Bump tool on prompt-clearing sync — QuerySet.delete bypasses model delete sync_prompts clears existing prompts with a queryset delete, which never calls ToolStudioPrompt.delete() — so a prompts-clearing sync with no tool-settings payload left the parent's modified_at stale, violating the invariant the parent-bump establishes (Greptile). The sync now bumps the tool explicitly when rows were deleted; pinned by a test that runs a clearing sync and asserts the bump. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UN-3741 [FIX] Harden parent bump: org-scope bypass, honest deleted count, scoped claim - _touch_tool and the sync bump now use CustomTool._base_manager: the org-scoped default manager reads a thread-local and would silently match zero rows outside request context; delete() collapsed onto _touch_tool (the FK attname survives super().delete()) so the two paths can't drift - sync_prompts reports the per-model prompt count, not the cascade total that dragged PromptStudioOutputManager rows into "prompts_deleted"; the sync test fixture now carries an output row so the assertion discriminates - List-queryset comment scopes the invariant honestly: only prompt writes bump; ProfileManager/DocumentManager and queryset-level prompt writes are tracked as UN-3759 Review: PR #2182 round 3 (Jaseem) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UN-3741 [MISC] Make code comments concise and tracker-independent Ticket references belong in commits and PRs, not code — they mean nothing to OSS contributors. Comments and test docstrings now state the behavior generically; the ProfileManager/DocumentManager bump gap stays documented in the list-queryset comment without the tracker pointer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
UN-3636 [MISC] enable the unit-workers rig group and de-flake its sui… …te (#2176) * UN-3636 [FIX] enable the unit-workers rig group and de-flake its suite The unit-workers group filtered `markers: "unit"`, but no worker test carries that marker, so it collected zero tests and silently never ran in CI. Switch to the negative filter the other unit groups use so the 734 worker tests actually run. Enabling collection surfaced pre-existing debt (the suite was never CI-gated): - Test isolation: worker Celery apps build a live-Postgres result backend from ambient DB_*/CELERY_BACKEND_DB_*, and building an app hijacks `current_app`. Both leaked across tests under xdist (psycopg2 connection errors, task `NotRegistered`). Fixed in conftest: strip the DB env before any app import, and pin celery's finalized default app as current around each test. - Stale assertions (prod drifted, tests never caught it): ExecutorToolShim / _run_agentic_extraction gained args; index result now carries usage_records; the highlight-disabled test over-asserted "plugin loader untouched" when lookup-enrichment is queried unconditionally (returns None in OSS). - Dropped tautological enum-existence tests that just mirror the source enum. - Renamed the cryptic test_sanity_phase6* / test_phaseN* files to intent-revealing names. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019EN8hh518CbCVMP3BHTVmG * UN-3636 [DEV] tighten test-rig group comments to concise, generic WHY Drop stale-prone specifics (function names, file:line refs, vendor lists, class names) from groups.yaml comments; keep the WHY. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019EN8hh518CbCVMP3BHTVmG * UN-3636 [DEV] address review: real log_component tests, tighten assertions - Replace the log_component replica (copied tasks.py if/elif, drifted so the ide_index case asserted the opposite of production) with tests that drive the real execute_extraction, covering the two special-cased branches. - Match the highlight-plugin assertion on positional or kwarg calls so it can't pass vacuously if the call style changes. - Reword the unit-workers marker note: integration/slow worker tests are currently unrouted, not run "elsewhere". - Cross-reference the two workers conftests on the DB_* env they set vs strip. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019EN8hh518CbCVMP3BHTVmG * UN-3636 [DEV] fail the build on a non-optional group that collects nothing A zero-collect group returns pytest exit 5, which the rig treats as non-failing — so a broken marker or moved path silently reported green (the very way unit-workers stayed dormant). Gate on it: a non-optional pytest group that collects zero tests now fails the overall exit. Legit zero-collects are exempt: optional groups, hurl (its exit 5 means "no files"), and dev runs with a --marker/--paths override. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019EN8hh518CbCVMP3BHTVmG --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Athul <89829560+athul-rs@users.noreply.github.com>
UN-2742 [FIX] Show profile name instead of LLM name in Output Analyze… …r tabs (#2030) * UN-2742 Show profile name instead of LLM name in output tabs Profiles encode user intent (same model can differ by LLMWhisperer mode, chunking, etc.), so the profile name is the meaningful label when comparing outputs. The LLM model name stays available as a tooltip on each tab. Applies to the shared tab strip used by the Output Analyzer and the main combined-output view (JsonView), and the same pattern in OutputForDocModal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UN-2742: guarantee non-empty profile tab label and tooltip (review fix) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
UN-2190 [MISC] Auto-capture execution ID in the API deployment Postma… …n collection (#2031) * UN-2190 Auto-capture execution_id in API deployment Postman collection Add a post-response script to the 'Process document' request that stores message.execution_id into a collection variable, and point the 'Execution status' request's execution_id query param at that variable. Users no longer copy-paste execution IDs between requests (mirrors the LLMWhisperer collection's whisper_hash pattern). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UN-2190 Address review: guard non-JSON responses, scope variable to API deployments - Wrap pm.response.json() in try/catch so error pages (non-JSON) don't surface a Postman test error - Move collection variables behind APIBase.get_collection_variables() so Pipeline collections (no status request) stay variable-free Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * UN-2190 Expose execution_id in the API execution response The ExecutionResponse DTO carries execution_id but APIExecutionResponseSerializer dropped it, so the Postman capture script (and any API consumer) had to parse it out of status_api. Add it as a first-class response field; the collection script's message.execution_id lookup now matches the real payload. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Address review comments on Postman collection scripts - Capture script: add else branch that resets execution_id to the default sentinel and warns, so a stale id from a previous run is never silently reused when the execute response lacks the field. - PostmanItem.event: use field(default_factory=list) instead of the None/[] tri-state; to_dict() now strips empty (falsy) event blocks, preserving existing external behavior (pipeline items omit "event"). - Constrain closed enums: EventItem.listen -> Literal["prerequest", "test"], ScriptItem.type -> Literal["text/javascript"]. - Document the capture script's response-shape coupling and that it is Postman's "test" hook. - Drop unnecessary string forward-reference on get_collection_variables. - constants: derive STATUS_EXEC_ID_VARIABLE from EXEC_ID_VARIABLE_NAME so the two can't drift. - Add tests for the postman_collection package covering event strip/keep, pipeline vs api-deployment shape, shared-constant coupling across variable/URL/JS, and the unencoded {{execution_id}} status URL. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
[MISC] Preserve view function identity in platform-service auth middl… …eware (#2160) fix: preserve view function identity in platform-service auth middleware `authentication_middleware` returned an unwrapped closure, so every decorated view function's `__name__` was "wrapper". Flask derives an endpoint name from `__name__`, which meant: - Six routes carried a redundant `endpoint="..."` kwarg purely to dodge the resulting name collision. - `/usage`, the one authenticated route without that kwarg, registered as endpoint `platform.wrapper`. - Adding any new authenticated route without `endpoint=` would fail at import with "View function mapping is overwriting an existing endpoint function: platform.wrapper". Add `functools.wraps` and drop the now-redundant `endpoint=` kwargs. URL rules and methods are unchanged; only the internal Flask endpoint names change (`platform.wrapper` -> `platform.usage`). Nothing in the repo resolves routes via `url_for`, and callers reach platform-service over HTTP by path, so this is not externally observable. x2text-service's equivalent middleware already patched `wrapper.__name__` by hand; this brings platform-service in line. Also repair `tests/test_auth_middleware.py`, which imported `unstract.platform_service.main` (removed) and `get_account_from_bearer_token` (removed) and so broke collection of the entire platform-service suite. It now covers `validate_bearer_token` against a mocked cursor. Claude-Session: https://claude.ai/code/session_014gUmgQQ7xV73qn6kcB7mXG Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
UN-3699 [FIX] Fix runner DockerException with requests>=2.32 by bumpi… …ng docker-py to 7.1.0 (#2155) UN-3699 [FIX] Bump runner docker-py to 7.1.0 for requests>=2.32 compat docker-py 6.1.3 is incompatible with requests>=2.32: its UnixHTTPAdapter only overrides the old get_connection path, so requests 2.32+ (locked at 2.33.0 via unstract-core) routes the internal http+docker:// socket URL to urllib3, raising URLSchemeUnknown -> DockerException at DockerClient.from_env(). This breaks any runner image rebuilt from main on the Docker container-client path (cloud/k8s is unaffected — it never calls from_env). Bump docker to 7.1.0, which handles requests>=2.32. Leaves the org-wide requests==2.33.0 untouched (lowering it is unsatisfiable: workers and x2text-service require >=2.33.0). Runner uses only stable high-level docker APIs; websocket-client drops out as it is now an optional docker extra and the runner uses no websocket features. Verified: docker 7.1.0 + requests 2.33.0 -> DockerClient.from_env().ping() == True against a real socket. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PreviousNext