Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

UN-3386 [FEAT] Add Prompt Studio HITL change indicator plugin slot#1930

Merged
vishnuszipstack merged 5 commits into
mainZipstack/unstract:mainfrom
UN-3386-prompt-studio-hitl-feedbackZipstack/unstract:UN-3386-prompt-studio-hitl-feedbackCopy head branch name to clipboard
May 19, 2026
Merged

UN-3386 [FEAT] Add Prompt Studio HITL change indicator plugin slot#1930
vishnuszipstack merged 5 commits into
mainZipstack/unstract:mainfrom
UN-3386-prompt-studio-hitl-feedbackZipstack/unstract:UN-3386-prompt-studio-hitl-feedbackCopy head branch name to clipboard

Conversation

@vishnuszipstack

@vishnuszipstack vishnuszipstack commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

What

  • Adds a dynamic-import slot in the Prompt Studio prompt-card Header for a new cloud-only PromptChangeIndicator plugin button.
  • Registers a new route :orgName/review/readonly/:documentId gated on a cloud-only ReadOnlyReviewPage plugin.
  • Both gates fall through silently when the plugin is absent (OSS builds remain untouched).

Why

  • Closes the loop between HITL reviewers and prompt authors: when a reviewer corrects a field in HITL, the prompt author should be able to see that signal back in Prompt Studio.
  • The feature lives in the cloud plugin, but the host (OSS) needs to expose the integration points so the indicator and the read-only audit page can be wired up.

How

  • frontend/src/components/custom-tools/prompt-card/Header.jsx: adds a try/catch dynamic import for plugins/prompt-change-indicator/PromptChangeIndicator, renders it (with promptDetails and toolDetails) between ExpandCardBtn and PromptRunBtnSps when present.
  • frontend/src/routes/useMainAppRoutes.js: adds a parallel try/catch dynamic import for plugins/prompt-change-indicator/ReadOnlyReviewPage, registers review/readonly/:documentId inside the existing ReviewLayout group when present.

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

  • No. The new code paths are guarded by if (PluginName) { ... } and the imports are inside try/catch. When the cloud plugin is absent (OSS), both blocks short-circuit and the UI is identical to before. The route addition lives inside the existing ReviewLayout && ManualReviewPage block so it can never override an existing route.

Database Migrations

  • None.

Env Config

  • None.

Relevant Docs

  • N/A

Related Issues or PRs

  • UN-3386
  • Companion (plugin implementation): Zipstack/unstract-cloud#1464 — merge this OSS PR first or together so the cloud plugin has its host hooks.
  • Depends on (server-side, separate work): UN-2128 for per-field tool/prompt attribution on HITLChangeLog rows.

Dependencies Versions

  • None.

Notes on Testing

  • OSS-only build (no cloud plugins): start npm start, open Prompt Studio — no indicator button, no console errors, no broken routes.
  • Hit /<orgName>/review/readonly/anything in OSS — should fall through (route only registers when plugin loads).
  • With cloud plugin synced into frontend/src/plugins/prompt-change-indicator/: indicator renders next to each prompt header and the readonly route works.

Screenshots

N/A

Checklist

I have read and understood the Contribution Guidelines.

🤖 Generated with Claude Code

Wires up the host-side hooks for the prompt-change-indicator plugin
(implementation lives in unstract-cloud): a dynamic-import slot in
the prompt card Header for the indicator button, and a route at
:orgName/review/readonly/:documentId for the read-only audit view.
Both gates fall through gracefully when the plugin is absent (OSS).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 52f4301c-2ca8-4971-b8d6-032631b71048

📥 Commits

Reviewing files that changed from the base of the PR and between 3d02972 and 8265e38.

📒 Files selected for processing (2)
  • frontend/src/components/custom-tools/prompt-card/Header.jsx
  • frontend/src/routes/useMainAppRoutes.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/components/custom-tools/prompt-card/Header.jsx
  • frontend/src/routes/useMainAppRoutes.js

Summary by CodeRabbit

  • New Features

    • Added a read-only review page for prompts accessible via a new route.
    • Integrated an optional prompt change indicator that appears when available.
  • Improvements

    • Improved handling for optional components to prevent build interruptions.
    • Added safeguards and warnings to avoid silent non-registration of review pages.

Walkthrough

Header and routing now optionally load a prompt-change plugin via cloud-only dynamic imports: Header conditionally renders a PromptChangeIndicator, and the route tree conditionally registers a read-only review page under ReviewLayout when the plugin is available.

Changes

Cohort / File(s) Summary
Optional Plugin UI Integration
frontend/src/components/custom-tools/prompt-card/Header.jsx
Performs a cloud-only dynamic import of PromptChangeIndicator, swallows missing-plugin errors so build continues, and conditionally renders the indicator passing promptDetails and details (as toolDetails) alongside the expand card button.
Dynamic Route Registration
frontend/src/routes/useMainAppRoutes.js
Adds lazy/dynamic import for a prompt-change-indicator ReadOnlyReviewPage. Handles import failures by distinguishing expected "module missing" vs unexpected errors, warns if the readonly component exists without ReviewLayout, and conditionally registers review/readonly/:documentId under the ReviewLayout subtree when present.

Sequence Diagram(s)

sequenceDiagram
  participant AppRouter as App Router
  participant Importer as Dynamic Importer
  participant Plugin as ReadOnlyReviewPlugin
  participant ReviewLayout as ReviewLayout
  AppRouter->>Importer: attempt import "prompt-change-indicator"
  alt import succeeds
    Importer->>Plugin: load module
    Plugin-->>Importer: module exported
    Importer-->>AppRouter: register route `review/readonly/:documentId`
    AppRouter->>ReviewLayout: mount nested route when visited
    ReviewLayout->>Plugin: render ReadOnlyReviewPage
  else module missing
    Importer-->>AppRouter: swallow missing-plugin error (no route registered)
  else unexpected error
    Importer-->>AppRouter: console.error and do not register route
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main feature: adding a plugin slot for a Prompt Studio HITL change indicator, with the ticket reference providing context.
Description check ✅ Passed The description comprehensively covers all required template sections: What, Why, How, backward compatibility assessment, database/env changes, related issues, testing notes, and the contribution checklist.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch UN-3386-prompt-studio-hitl-feedback

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR exposes two plugin integration points in the OSS host for a cloud-only HITL change-indicator feature: a PromptChangeIndicator slot in the prompt-card Header and a ReadOnlyReviewPage route under the existing ReviewLayout group. Both additions are gated behind try/catch dynamic imports and conditional rendering, so OSS builds are unaffected.

  • Header.jsx: dynamically imports PromptChangeIndicator and renders it (passing promptDetails and details as toolDetails) between ExpandCardBtn and PromptRunBtnSps; falls back to nothing when the plugin is absent.
  • useMainAppRoutes.js: adds a ReadOnlyReviewPage import with improved error surfacing (distinguishes MODULE_NOT_FOUND from real failures), a console.warn guard when the plugin loads without ReviewLayout, and a review/readonly/:documentId route nested inside the existing ReviewLayout && ManualReviewPage block.

Confidence Score: 5/5

Safe to merge — both integration points are fully guarded by try/catch and conditional rendering, leaving OSS builds completely unaffected.

All new code paths are unreachable in OSS builds. The route addition is nested inside the existing ReviewLayout/ManualReviewPage guard and cannot override any existing route. The only notable gap is that the PromptChangeIndicator import silently swallows all errors while the paired ReadOnlyReviewPage import has better error surfacing — but this is consistent with other plugin imports in Header.jsx and does not affect correctness.

No files require special attention; both changed files follow existing codebase conventions and the new code is well-isolated.

Important Files Changed

Filename Overview
frontend/src/components/custom-tools/prompt-card/Header.jsx Adds a dynamic-import plugin slot for PromptChangeIndicator, rendered between ExpandCardBtn and PromptRunBtnSps. Error handling in the catch block is silent (consistent with other plugins in this file but less thorough than the paired ReadOnlyReviewPage import).
frontend/src/routes/useMainAppRoutes.js Adds ReadOnlyReviewPage dynamic import with proper MODULE_NOT_FOUND detection and console.error for unexpected failures, a console.warn guard when the plugin loads without ReviewLayout, and the route nested correctly inside the existing ReviewLayout/ManualReviewPage block.

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
frontend/src/components/custom-tools/prompt-card/Header.jsx:44-52
**Silent catch swallows real plugin errors**

The `PromptChangeIndicator` import catches every error silently, including syntax errors and runtime failures inside the plugin. The companion `ReadOnlyReviewPage` import in `useMainAppRoutes.js` was improved (after a prior review round) to distinguish `MODULE_NOT_FOUND` (expected in OSS) from real failures and emit a `console.error` for the latter. If the cloud plugin ships with a broken `PromptChangeIndicator.jsx`, the button will simply never appear and there will be no console signal — making the failure invisible to the developer.

Reviews (4): Last reviewed commit: "Merge branch 'main' into UN-3386-prompt-..." | Re-trigger Greptile

Comment thread frontend/src/routes/useMainAppRoutes.js
@vishnuszipstack vishnuszipstack marked this pull request as draft April 27, 2026 09:00
vishnuszipstack and others added 2 commits April 27, 2026 14:34
Addresses review feedback: the readonly route nests inside ReviewLayout
(manual-review plugin), so a deployment that ships prompt-change-indicator
without manual-review would silently fail to register the route. Log a
console.warn in that case to make the misconfiguration discoverable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bare catch in the prompt-change-indicator dynamic import was swallowing
syntax/runtime errors in the plugin file alongside the expected
"plugin missing in OSS" case. Detect the missing-module messages
explicitly and console.error anything else so a broken cloud plugin
no longer disables the readonly route silently.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vishnuszipstack vishnuszipstack marked this pull request as ready for review April 27, 2026 09:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
frontend/src/routes/useMainAppRoutes.js (1)

115-136: Module-missing heuristic risks false positives and Header.jsx has inconsistent error handling.

The "Failed to fetch dynamically imported module" message is emitted by Vite for both genuinely missing modules and transitive dependency failures (e.g., chunk 404, network blips, sub-import typos). This means the current check silently swallows errors that should be surfaced — the exact failure mode the improved error handling was meant to prevent. Consider tightening the check to include the plugin path substring, or rely solely on err?.code === "MODULE_NOT_FOUND".

Additionally, frontend/src/components/custom-tools/prompt-card/Header.jsx (lines 42–49) uses a bare catch {} for the same prompt-change-indicator plugin. This creates an inconsistency: a broken cloud build surfaces an error here but silently disappears in the header, contradicting the PR goal of failing loudly for broken plugins.

🔧 Optional: tighten the missing-module check
   const msg = err?.message || "";
   const isModuleMissing =
     err?.code === "MODULE_NOT_FOUND" ||
-    msg.includes("Failed to fetch dynamically imported module") ||
-    msg.includes("Cannot find module");
+    msg.includes("Cannot find module") ||
+    (msg.includes("Failed to fetch dynamically imported module") &&
+      msg.includes("prompt-change-indicator/ReadOnlyReviewPage"));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/routes/useMainAppRoutes.js` around lines 115 - 136, The
dynamic-import error handling in useMainAppRoutes.js around the
ReadOnlyReviewPage import is too permissive and can hide runtime or transitive
dependency failures; tighten the missing-module heuristic by checking err?.code
=== "MODULE_NOT_FOUND" or by additionally verifying the error message contains
the plugin path substring ("prompt-change-indicator/ReadOnlyReviewPage") before
treating it as a harmless missing-module case, and log/throw all other errors;
also make Header.jsx's bare catch (in the prompt-change-indicator import there)
consistent by replacing the empty catch with the same tightened heuristic and
error-logging behavior so unexpected plugin failures are surfaced uniformly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@frontend/src/routes/useMainAppRoutes.js`:
- Around line 115-136: The dynamic-import error handling in useMainAppRoutes.js
around the ReadOnlyReviewPage import is too permissive and can hide runtime or
transitive dependency failures; tighten the missing-module heuristic by checking
err?.code === "MODULE_NOT_FOUND" or by additionally verifying the error message
contains the plugin path substring
("prompt-change-indicator/ReadOnlyReviewPage") before treating it as a harmless
missing-module case, and log/throw all other errors; also make Header.jsx's bare
catch (in the prompt-change-indicator import there) consistent by replacing the
empty catch with the same tightened heuristic and error-logging behavior so
unexpected plugin failures are surfaced uniformly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2f482928-5b1e-48a0-a0d5-a2d4b16c27b8

📥 Commits

Reviewing files that changed from the base of the PR and between 200b2b5 and 3d02972.

📒 Files selected for processing (1)
  • frontend/src/routes/useMainAppRoutes.js

vishnuszipstack and others added 2 commits May 19, 2026 11:11
Resolve conflict in Header.jsx by keeping both plugin import blocks:
the prompt-change-indicator plugin (this branch) and the lookup-studio
plugins (main).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Frontend Lint Report (Biome)

All checks passed! No linting or formatting issues found.

@sonarqubecloud

Copy link
Copy Markdown

@vishnuszipstack vishnuszipstack merged commit ff5d121 into main May 19, 2026
8 checks passed
@vishnuszipstack vishnuszipstack deleted the UN-3386-prompt-studio-hitl-feedback branch May 19, 2026 09:09
harini-venkataraman pushed a commit that referenced this pull request May 21, 2026
…1930)

* UN-3386 [FEAT] Add Prompt Studio HITL change indicator plugin slot

Wires up the host-side hooks for the prompt-change-indicator plugin
(implementation lives in unstract-cloud): a dynamic-import slot in
the prompt card Header for the indicator button, and a route at
:orgName/review/readonly/:documentId for the read-only audit view.
Both gates fall through gracefully when the plugin is absent (OSS).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* UN-3386 [FIX] Warn when ReadOnlyReviewPage loads without ReviewLayout

Addresses review feedback: the readonly route nests inside ReviewLayout
(manual-review plugin), so a deployment that ships prompt-change-indicator
without manual-review would silently fail to register the route. Log a
console.warn in that case to make the misconfiguration discoverable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* UN-3386 [FIX] Surface real plugin import errors in route loader

Bare catch in the prompt-change-indicator dynamic import was swallowing
syntax/runtime errors in the plugin file alongside the expected
"plugin missing in OSS" case. Detect the missing-module messages
explicitly and console.error anything else so a broken cloud plugin
no longer disables the readonly route silently.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
harini-venkataraman added a commit that referenced this pull request Jun 29, 2026
)

* [MISC] Decommission prompt-service, old tools, and SDK1 prompt module (Phase 5)

Remove prompt-service source, Dockerfiles, and docker-compose entries.
Remove tools/classifier, tools/structure, tools/text_extractor directories.
Remove SDK1 prompt.py module and its tests.
Clean up PROMPT_HOST/PROMPT_PORT from backend settings, sample envs,
docker configs, and CI workflows. Remove prompt-service from uv-lock
scripts and production build workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* [MISC] Remove prompt-service from tox.ini env_list

The prompt-service directory was deleted in the prior commit but tox.ini
still referenced it, which would break CI test runs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* UN-2888 [FIX] Add hook for setting default triad for invited users (#1877)

* [FIX] Add hook for setting default adapters for invited users

Add setup_default_adapters_for_user() hook to AuthenticationService
and call it from set_user_organization() when an invited user joins
an existing organization. This allows the cloud plugin to set up
default triad adapters (LLM, embedding, vector DB, x2text) for
invited users, fixing silent failures in API deployment creation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update backend/account_v2/authentication_controller.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Praveen Kumar <praveen@zipstack.com>

* [FIX] Improve log message for setup_default_adapters_for_user

Address review comment: log user email and explain that default
adapters will not be set when the method is not implemented.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* [MISC] Rename Default Triad to Default LLM Profile in UI

Update display label from "Default Triad" to "Default LLM Profile"
in the page heading and side navigation menu.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: Praveen Kumar <praveen@zipstack.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Deepak K <89829542+Deepak-Kesavan@users.noreply.github.com>

* UN-3465 [FIX] Wrap set_user_organization in transaction.atomic (#1954)

* [FIX] Wrap set_user_organization in transaction.atomic

The new-org branch creates the org row, then calls frictionless onboarding
and the initial platform key. Failures mid-flow leave an orphan org with no
adapters or key, and subsequent logins skip onboarding entirely (gated on
new_organization). Atomic ensures the org rolls back on any failure so
retries get a clean fresh-org path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [MISC] Worktree skill — use --no-track to prevent accidental main pushes

Without --no-track, a later `git push -u origin <branch>` can be reported
by the server as also fast-forwarding main, landing commits on main.

* [FIX] Use logger.exception in authorization_callback

Preserves the traceback when the OAuth callback hits the safety-net
catch. Behaviour unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Athul <89829560+athul-rs@users.noreply.github.com>
Co-authored-by: vishnuszipstack <117254672+vishnuszipstack@users.noreply.github.com>

* UN-3386 [FEAT] Add Prompt Studio HITL change indicator plugin slot (#1930)

* UN-3386 [FEAT] Add Prompt Studio HITL change indicator plugin slot

Wires up the host-side hooks for the prompt-change-indicator plugin
(implementation lives in unstract-cloud): a dynamic-import slot in
the prompt card Header for the indicator button, and a route at
:orgName/review/readonly/:documentId for the read-only audit view.
Both gates fall through gracefully when the plugin is absent (OSS).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* UN-3386 [FIX] Warn when ReadOnlyReviewPage loads without ReviewLayout

Addresses review feedback: the readonly route nests inside ReviewLayout
(manual-review plugin), so a deployment that ships prompt-change-indicator
without manual-review would silently fail to register the route. Log a
console.warn in that case to make the misconfiguration discoverable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* UN-3386 [FIX] Surface real plugin import errors in route loader

Bare catch in the prompt-change-indicator dynamic import was swallowing
syntax/runtime errors in the plugin file alongside the expected
"plugin missing in OSS" case. Detect the missing-module messages
explicitly and console.error anything else so a broken cloud plugin
no longer disables the readonly route silently.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Add a dedicated OpenAI-compatible LLM adapter (#1895)

* Add OpenAI-compatible LLM adapter

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Address review feedback for custom OpenAI adapter

* Fix import formatting after rebase

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Address follow-up review comments for OpenAI-compatible adapter

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Refine OpenAI compatible adapter schema naming

* Reject empty model string in OpenAICompatibleLLMParameters

validate_model previously produced "custom_openai/" for an empty model,
surfacing as a confusing LiteLLM error at call time. Match the existing
GeminiLLMParameters.validate_model pattern: strip whitespace, raise
ValueError on empty input.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Revert SCHEMA_PATH plumbing; rename schema to custom_openai.json

Addresses Ritwik's review feedback. The new BaseAdapter.SCHEMA_PATH
class variable and the conditional branch in get_json_schema() are
unnecessary: OpenAICompatibleLLMAdapter.get_provider() returns
"custom_openai", and the default path resolution already builds
…/llm1/static/{get_provider()}.json. Renaming the schema file lets
the default lookup find it and keeps the base class untouched, which
is the convention every other adapter follows.

- Rename openai_compatible.json -> custom_openai.json
- Drop SCHEMA_PATH class var and the if-None branch from BaseAdapter
- Drop SCHEMA_PATH override (and unused os/ClassVar imports) from
  OpenAICompatibleLLMAdapter
- Update test_openai_compatible_schema_is_loadable to read schema via
  get_json_schema() instead of touching SCHEMA_PATH directly

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Hari John Kuriakose <hari@zipstack.com>
Co-authored-by: Chandrasekharan M <chandrasekharan@zipstack.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Athul <athul@zipstack.com>
Co-authored-by: Athul <89829560+athul-rs@users.noreply.github.com>
Co-authored-by: vishnuszipstack <117254672+vishnuszipstack@users.noreply.github.com>

* ReverseMerge: V0.163.4 hotfix (#1980)

* [HOTFIX] Use importlib.util.find_spec for pluggable worker discovery (#1918)

* [FIX] Use importlib.util.find_spec for pluggable worker discovery

_verify_pluggable_worker_exists() previously checked for the literal file
`pluggable_worker/<name>/worker.py` on disk, which breaks when the plugin
has been compiled to a .so (Nuitka, Cython, or any C extension) — the
module is perfectly importable but the pre-check rejects it because only
the .py extension is considered.

Replace the filesystem check with importlib.util.find_spec(), which is
Python's standard way to ask "is this module resolvable by the import
system?". It honors every registered finder — source .py, compiled .so,
bytecode .pyc, namespace packages, zipimports — so the function now
matches what its docstring claims: verifying the module can be loaded,
not that a specific file extension is present.

Behavior is preserved for existing deployments:
- Images with no `pluggable_worker/<name>/` subpackage → find_spec
  raises ModuleNotFoundError (ImportError subclass) → returns False.
- Images with source .py → find_spec resolves the .py → returns True.
- Images with compiled .so → find_spec resolves the .so → returns True.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [FIX] Handle ValueError from find_spec in pluggable worker verification

Greptile-flagged edge case: importlib.util.find_spec() can raise
ValueError (not just ImportError) when sys.modules has a partially
initialised module entry with __spec__ = None from a prior failed import.
Broaden the except to catch both.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [FIX] Resolve api-deployment worker directory from enum import path

worker.py:452 did worker_type.value.replace("-", "_") to derive the
on-disk dir name. All WorkerType enum values already use underscores,
so the replace was a no-op; for API_DEPLOYMENT whose dir is
"api-deployment" (hyphen), it resolved to "api_deployment" and the
os.path.exists() check failed. Boot then logged a spurious
"❌ Worker directory not found: /app/api_deployment" at ERROR level.

The task registration path (builder + celery autodiscover via
to_import_path) is unaffected, so this was purely log noise — but
noise at ERROR level that masks real failures in log scans.

Fix: derive the directory from the authoritative to_import_path()
which already handles the hyphen case (api_deployment -> api-deployment).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [HOTFIX] Add IAM Role / Instance Profile auth mode to AWS Bedrock adapter (#1944)

* [FEAT] Allow Bedrock to fall through to boto3's default credential chain

Match the S3/MinIO connector pattern: when AWS access keys are left blank
on the Bedrock LLM and embedding adapter forms, drop them from the kwargs
dict so boto3's default credential chain handles authentication. This
unlocks IAM role / instance profile / IRSA / AWS Profile scenarios on
hosts that already have ambient AWS credentials (e.g. EKS workers with
IRSA, EC2 with an instance profile).

- llm1/static/bedrock.json: clarify access-key descriptions to mention
  IRSA and instance profile (already non-required at v0.163.2 base).
- embedding1/static/bedrock.json: drop aws_access_key_id and
  aws_secret_access_key from top-level required; same description fix;
  expose aws_profile_name for parity with the LLM form.
- base1.py: AWSBedrockLLMParameters and AWSBedrockEmbeddingParameters
  now strip empty access-key values from the validated kwargs before
  returning, so empty strings don't override boto3's default chain.
  AWSBedrockEmbeddingParameters fields gain explicit None defaults
  and an aws_profile_name field.

Backward-compatible: existing adapters with access keys filled in
continue to work unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [FEAT] Add Authentication Type selector to Bedrock adapter form

Add an explicit `auth_type` selector with two options, making the auth
choice clear to users:

- "Access Keys" (default): existing flow, keys required
- "IAM Role / Instance Profile (on-prem AWS only)": no fields; relies on
  boto3's default credential chain (IRSA on EKS, task role on ECS,
  instance profile on EC2). Description on the selector explicitly notes
  this option is only for AWS-hosted Unstract deployments.

The form-only auth_type field is stripped before LiteLLM validation in
both AWSBedrockLLMParameters.validate() and AWSBedrockEmbeddingParameters.
validate(). Empty access keys continue to be stripped so boto3 falls
through to the default chain even when the access_keys arm is selected
without values (matches the S3/MinIO connector pattern).

Backward-compatible: legacy adapters without auth_type behave as
"Access Keys" mode (the default), and existing keys are forwarded
unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [REVIEW] Address Bedrock auth_type review feedback

Fixes the P0/P1 issues raised by greptile-apps and jaseemjaskp on
PR #1944.

Behaviour fixes:
- Stale-key leak in IAM Role mode: switching an existing adapter from
  Access Keys to IAM Role would carry truthy stored access keys through
  the strip-empty-only loop, so boto3 silently authenticated with the
  old long-lived credentials instead of falling through to the host's
  IRSA / instance-profile identity. Both LLM and embedding paths were
  affected.
- Silent acceptance of unknown auth_type: a typo (e.g. "access_key") or
  a malformed payload from a non-UI client passed through the dict
  comprehension untouched, with no enum guard.
- Cross-field validation gap: explicit Access Keys mode with blank or
  whitespace-only values silently fell through to the default
  credential chain instead of surfacing the misconfiguration.

Implementation:
- Add a module-level _resolve_bedrock_aws_credentials helper used by
  both AWSBedrockLLMParameters.validate() and AWSBedrock
  EmbeddingParameters.validate(), so the auth-type contract is
  expressed once.
  - Validates auth_type against an allowlist (None | "access_keys" |
    "iam_role"); raises ValueError on anything else.
  - iam_role: unconditionally drops aws_access_key_id and
    aws_secret_access_key.
  - access_keys (explicit): requires non-blank values; raises ValueError
    if either is empty or whitespace-only.
  - Legacy (auth_type absent): retains the lenient strip behaviour so
    pre-PR adapter configurations continue to deserialise unchanged.
- Restore aws_region_name as required (no `= None` default) on
  AWSBedrockEmbeddingParameters; only credentials may legitimately be
  absent.
- Drop the orphan aws_profile_name field from
  embedding1/static/bedrock.json: it was added for parity with the LLM
  form but lives outside the auth_type oneOf and contradicts the
  selector's "no further input" semantics. The LLM form already had
  aws_profile_name pre-PR and is left alone for backwards compatibility.

Tests:
- New tests/test_bedrock_adapter.py covers 15 cases across LLM and
  embedding adapters: legacy-no-auth-type, explicit access_keys with
  valid/blank/whitespace keys, iam_role with stale/no keys, unknown
  auth_type rejection, cross-field validation, and preservation of
  unrelated params (model_id, aws_profile_name, region, thinking).

Skipped (P2 nice-to-have):
- Comment-scope clarification, MinIO reference rewording,
  validate-mutates-caller'\''s-dict, and the LLM form description nit
  about aws_profile_name visibility. These don'\''t change behaviour
  and can be addressed in a follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* [HOTFIX] Bump litellm to 1.83.10 from PyPI to clear CVE-2026-42208 (#1976)

Hotfix for cloud v0.159.3 (OSS v0.163.4). Customer scanner flagged
litellm 1.82.3 for CVE-2026-42208 (SQL injection in litellm proxy auth
path, affects 1.81.16-1.83.6). We do not use litellm.proxy, but
vulnerability scanners flag the installed package regardless of which
code path is reachable.

Bump to 1.83.10 — the exact version recommended by the upstream advisory
(v1.83.10-stable) and the smallest jump that clears the CVE range while
keeping python-dotenv==1.0.1 compatible (1.83.14 would force bumping
python-dotenv across 7+ pyproject.toml files). Only tiktoken needed to
move 0.9 -> 0.12 to satisfy litellm's pin.

Switch source back to PyPI now that the PyPI quarantine is over,
reversing the temporary fork in #1873.

Cohere embed timeout patch: verified that
litellm/llms/cohere/embed/handler.py is byte-identical between v1.82.3,
v1.83.10-stable, and v1.83.14-stable (the timeout-not-forwarded bug
fixed in #1848 is still present upstream — BerriAI/litellm#14635 remains
OPEN). Version guard bumped 1.82.3 -> 1.83.10; 6/6 patch tests pass on
the new version, confirming the monkey-patch still binds correctly.

Other cleanup from #1873:
- Drop git apt-install from worker-unified and tool Dockerfiles (no
  git-sourced deps remain in any uv.lock)
- Bump tool versions: structure 0.0.100 -> 0.0.101,
  classifier 0.0.79 -> 0.0.80, text_extractor 0.0.75 -> 0.0.76

Note on root uv.lock churn: the v0.163.4 root uv.lock had a pre-existing
corruption (banks v2.4.1 entry pointing at banks-2.2.0 wheel) that
blocked incremental resolution. Regenerated from scratch.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [FIX] Align cohere patch docstring with version-guard semantics

Reviewer flagged that the docstring claimed the patch is "confirmed in
every release between 1.82.3 and 1.83.14-stable", but the guard at
_PATCHED_LITELLM_VERSION activates only on the exact pinned version. A
future maintainer reading the old text could reasonably expect bumping
to e.g. 1.83.11 to keep the fix active; in reality it silently turns
off.

Rewritten to reference _PATCHED_LITELLM_VERSION as the single source of
truth and to drop the rot-prone "as of 2026-05-20" calendar date.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* UN-3476 [FIX] Revert atomic wrap on set_user_organization (#1977)

The atomic wrap from #1954 uncommits the new org row when
frictionless_onboarding HTTP-calls the LLMW portal mid-transaction.
The portal runs on a separate DB session and under READ COMMITTED
cannot see the uncommitted row, so the call returns 400 and the
caller silently persists an adapter with an empty unstract_key.
Every new signup since 2026-05-19 09:47 UTC ships a broken
free-trial X2Text adapter (401 on first OCR).

Hotfix only — Phase 2 (UN-3476) restructures the function so the
atomic guarantee is reapplied around just the pure-DB writes, with
HTTP and non-DB side effects moved outside the transaction.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Restore text_extractor tool removed in Phase 5 decommission

The Phase 5 decommission commit removed classifier, structure,
text_extractor, and prompt-service. However, text_extractor is still
in active use by customers. This surgically restores only the
text_extractor tool while keeping the other decommissions in place.

- Restore tools/text_extractor/ directory (14 files from origin/main)
- Add tool-text_extractor back to docker-compose.build.yaml
- Add tool-text-extractor back to docker-tools-build-push.yaml workflow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Restore classifier tool removed in Phase 5 decommission

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove unit-prompt-service group from test rig manifest

The prompt-service directory was deleted in the decommission PR, but
the test rig groups.yaml still referenced it, causing CI to fail with
"workdir does not exist" during validate and integration steps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove deleted prompt-service and structure tool refs from bump script

prompt-service/ and tools/structure/ are deleted by this PR, so
remove their variables, reset_file calls, and the entire
update_structure_tool_version function from bump_sdk_v0_version.sh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix stale references from decommissioned components

- Fix tool-text_extractor image name to tool-text-extractor in
  docker-compose.build.yaml to match CI, registry, and cloud naming
- Remove stale tool-structure from run-platform.sh ignore list
- Drop prompt-service from is_retryable_error docstring in retry_utils.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Trigger CI re-run

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Signed-off-by: Praveen Kumar <praveen@zipstack.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Praveen Kumar <praveen@zipstack.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Deepak K <89829542+Deepak-Kesavan@users.noreply.github.com>
Co-authored-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>
Co-authored-by: Athul <89829560+athul-rs@users.noreply.github.com>
Co-authored-by: vishnuszipstack <117254672+vishnuszipstack@users.noreply.github.com>
Co-authored-by: jimmy <ziming_zhu2002@163.com>
Co-authored-by: Hari John Kuriakose <hari@zipstack.com>
Co-authored-by: Chandrasekharan M <chandrasekharan@zipstack.com>
Co-authored-by: Athul <athul@zipstack.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.