Skip to content

Tags: Zipstack/unstract

Tags

v0.160.1

Toggle v0.160.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
UN-3318 [FEAT] Platform API key post-merge fixes (#1863)

* UN-3318 [FEAT] Platform API key implementation

- Change API keys from user-scoped to org-scoped (all admins see all keys)
- Add IsOrganizationAdmin permission — only admins can manage keys
- Create dedicated service account (is_service_account) per key for bearer auth
- Auto-add key owner as shared_users co-owner on resources created via API key
- Filter service accounts from member listings and shared_users serializers
- Admin-gate frontend route and nav item for Platform API Keys
- Add "Created By" column to API keys table

* [FIX] Add optional chaining for socket event handlers in SocketMessages

* [FIX] Add platform_api URLs to main URL configuration

* UN-3318 [FEAT] Platform API key enhancements and prompt sync endpoint

- Add ownership transfer on key deletion (service account -> key creator)
- Fix service account email to not expose key ID (use name-slug format)
- Add retrieve endpoint for fetching full API key (copy-to-clipboard)
- Revert service account filtering from serializers (show in user lists)
- Add POST /prompt-studio/<id>/sync-prompts/ for cross-env prompt sync
- Fix export_tool crash when user_id not provided (set(None) error)
- Update copy button UX: icon after key text, fetch real key from backend
- Fix worker script shebang for macOS bash compatibility

* UN-3318 [FIX] Move platform API keys route outside RequireAdmin gate

* UN-3318 [FIX] Address PR review feedback

- Return 401 instead of 500 for unconfigured API key api_user
- Wrap get_response in try/finally for StateStore cleanup
- Add max_length=512 to description CharField in serializer
- Include forward slash in validation error message
- Fix useEffect deps for fetchKeys (guard on orgId, add fetchKeys dep)
- Remove redundant ModuleNotFoundError from except clause

* UN-3318 [FIX] Add pre_delete signal for service account cleanup

Move service account cleanup from view to pre_delete signal so it
fires on all deletion paths (admin, cascade, scripts), not just the
API view.

* UN-3318 [FIX] Simplify service account email to key-name@platform.internal

Use key name directly for email without UUID suffix. Username retains
UUID prefix for global uniqueness. Cross-org isolation is handled by
the org-scoped manager mixin on OrganizationMember.

* UN-3318 [FEAT] Add read/read_write permission on API keys and bypass owner checks for service accounts

- Add permission field (read/read_write) to PlatformApiKey model
- Enforce in middleware: block DELETE, block writes for read-only keys
- Bypass for_user owner/shared checks for service accounts (all 7 managers)
- Bypass object-level permissions (IsOwner, IsOwnerOrSharedUser, etc.)
- Hide service accounts from member listings and shared_users serializers
- Add permission column, select in create/edit modals on frontend

* UN-3318 [FIX] Merge implicitly concatenated string in db_comment

* UN-3318 [FIX] Regenerate platform_api migrations (squash permission into initial)

* Revert unintended shebang change in workers/run-worker.sh

* Fix route gating: move platform-api-keys inside RequireAdmin, restore triad position

* Add UniqueTogetherValidator for platform API key name+org uniqueness

DRF doesn't auto-validate UniqueConstraint from Meta.constraints
(unlike unique_together), so duplicate names would cause a 500
IntegrityError. Adding explicit validator returns a clean 400.

* Fix name uniqueness validation to use manual check instead of UniqueTogetherValidator

UniqueTogetherValidator requires all fields in serializer data, but
organization is set at model layer via DefaultOrganizationMixin.save().
Use validate_name with UserContext.get_organization() instead.

* Use accessible Button element for API key copy action

Replace clickable div with Ant Design Button (type=text) for keyboard
accessibility and proper ARIA semantics.

* Fix Greptile review issues: atomicity, email collision, model scan scope

- Wrap create_api_user_for_key in transaction.atomic() to prevent
  orphaned service accounts on partial failure
- Wrap sync_prompts delete+recreate in transaction.atomic() to prevent
  data loss if import_prompts fails after delete
- Add uid fragment to service account email to prevent collision across
  orgs with same key name
- Scope transfer_ownership to business app labels only instead of
  scanning all Django models (avoids system/third-party model queries)
- Fix frontend SAFE_TEXT_MESSAGE to include forward slashes

* Fix code review issues: cross-org leak, signal safety, email sanitization

- WorkflowExecutionManager: scope service account queryset by org via
  workflow__organization to prevent cross-org data leak
- pre_delete signal: wrap in try/except so cleanup failures don't block
  key deletion (orphaned accounts logged instead)
- Email sanitization: strip non-alphanumeric chars from key name before
  using in email to comply with RFC 5321
- Move uuid/re imports to top of services.py
- Add exception logging to IsOrganizationAdmin permission class

* Address human reviewer feedback: middleware, serializer, error messages

- Move DELETE check before DB lookup in bearer auth middleware
- Improve error message for missing service account (actionable)
- Include max count in KeyCountExceeded error message
- Move key count validation from view to serializer
- Add TODO for key hashing on model
- Remove unused imports from views.py

* Remove platform API key count limit and related constants/exceptions

The limit was an arbitrary safety net attracting unnecessary review
discussion. No rate limiting needed at this stage.

* Reduce cognitive complexity in transfer_ownership to satisfy SonarCloud

Extract per-model logic into _transfer_model_ownership helper to reduce
nesting depth and bring cognitive complexity from 21 to within the
allowed threshold of 15.

* Use serializer for sync_prompts validation, remove manual error handling

Add SyncPromptsSerializer to validate request body with DictField and
required keys check. Remove try/except blocks from sync_prompts view
to let DRF middleware handle errors consistently.

* Add type hints to services.py and use constants for HTTP methods

- Add type annotations to all public functions in platform_api/services.py
- Add RequestMethod constants class with SAFE_METHODS frozenset
- Use RequestMethod and ApiKeyPermission enum in bearer auth middleware
  instead of hardcoded strings

* Address code review: transactions, retrieve masking, permission hardening

- Wrap create() in transaction.atomic() so key + service account are
  atomic (no orphaned keys if service account creation fails)
- Wrap transfer_ownership and delete_api_user_for_key in
  transaction.atomic() to prevent partial ownership transfers
- Use masked serializer for retrieve() — plaintext key only shown at
  create and rotate
- Use save(update_fields=) in rotate() for efficiency
- Use _meta.get_fields() instead of hasattr() for Django field detection
- Narrow service account permission bypass to SAFE_METHODS only in
  IsOwner, IsOwnerOrSharedUser, IsOwnerOrSharedUserOrSharedToOrg

* Fix handleCopyKey to use masked value from list data

The retrieve endpoint now returns masked keys, so the copy button
should use the already-available masked value from the record instead
of making a redundant API call.

* Revert retrieve masking — full key needed for copy-to-clipboard

The retrieve endpoint must return the full key since handleCopyKey
relies on it. Key hashing (show plaintext only at create/rotate)
should be done as a separate cross-cutting change with APIDeployment.

* Fix NoneType error when created_by is NULL in prompt studio serializer

Handle NULL created_by in CustomToolSerializer.to_representation to
prevent AttributeError on projects where the creator has been deleted.

* Make API key name immutable after creation

Name is used to derive the service account username/email, so it
should not be editable. Remove name from update serializer and
show it as disabled in the edit modal.

* Fix ownership transfer on API key deletion and prompt studio bugs

- Use _base_manager to bypass DefaultOrganizationManagerMixin in
  transfer_ownership (org context unavailable during signal paths)
- Dynamically discover all User FK/M2M fields instead of hardcoding
  created_by/modified_by (fixes missed workflow_owner transfer)
- Move created_by_email assignment before early return in prompt studio
  serializer so new projects without prompts show the owner
- Add trailing slash to prompt studio share PATCH URL

* Fix workflow_manager app_label in transfer ownership scan

The app_label for the Workflow model is "workflow_v2" (derived from
AppConfig.name = "workflow_manager.workflow_v2"), not "workflow_manager".
This caused transfer_ownership to skip workflows entirely, leaving
created_by/workflow_owner NULL after service account deletion.

* Allow service account write access and auto-share imported tools

- Broaden service account permission bypass from SAFE_METHODS only to
  all non-DELETE methods (DELETE already blocked at middleware layer)
- Auto-add API key owner to shared_users when service account creates
  tools via import/sync backup, so they appear in the admin's UI

* Add logger.warning for missing PlatformApiKey during tool import

* Update backend/permissions/permission.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>

* Improve observability: log warning when created_by is null, expand docstring

* Fix UserSessionUtils.get_organization_id for Bearer token requests

When authenticated via Platform API Key (Bearer token), there is no
session, so get_organization_id returned None. This caused TypeError
in file upload and other endpoints that build paths using org_id.

Fall back to request.organization_id (set by OrganizationMiddleware
from the URL) when a platform_api_key is present on the request.

* Fix stale session edge case in UserSessionUtils, use user.id in logs

- Unconditionally return URL org_id for Bearer token requests,
  ignoring any stale session cookie that may also be present
- Use user.id instead of user.username in warning logs to avoid PII

---------

Signed-off-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>
Co-authored-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

v0.160.0

Toggle v0.160.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
UN-3318 [FEAT] Platform API key implementation (#1860)

* UN-3318 [FEAT] Platform API key implementation

- Change API keys from user-scoped to org-scoped (all admins see all keys)
- Add IsOrganizationAdmin permission — only admins can manage keys
- Create dedicated service account (is_service_account) per key for bearer auth
- Auto-add key owner as shared_users co-owner on resources created via API key
- Filter service accounts from member listings and shared_users serializers
- Admin-gate frontend route and nav item for Platform API Keys
- Add "Created By" column to API keys table

* [FIX] Add optional chaining for socket event handlers in SocketMessages

* [FIX] Add platform_api URLs to main URL configuration

* UN-3318 [FEAT] Platform API key enhancements and prompt sync endpoint

- Add ownership transfer on key deletion (service account -> key creator)
- Fix service account email to not expose key ID (use name-slug format)
- Add retrieve endpoint for fetching full API key (copy-to-clipboard)
- Revert service account filtering from serializers (show in user lists)
- Add POST /prompt-studio/<id>/sync-prompts/ for cross-env prompt sync
- Fix export_tool crash when user_id not provided (set(None) error)
- Update copy button UX: icon after key text, fetch real key from backend
- Fix worker script shebang for macOS bash compatibility

* UN-3318 [FIX] Move platform API keys route outside RequireAdmin gate

* UN-3318 [FIX] Address PR review feedback

- Return 401 instead of 500 for unconfigured API key api_user
- Wrap get_response in try/finally for StateStore cleanup
- Add max_length=512 to description CharField in serializer
- Include forward slash in validation error message
- Fix useEffect deps for fetchKeys (guard on orgId, add fetchKeys dep)
- Remove redundant ModuleNotFoundError from except clause

* UN-3318 [FIX] Add pre_delete signal for service account cleanup

Move service account cleanup from view to pre_delete signal so it
fires on all deletion paths (admin, cascade, scripts), not just the
API view.

* UN-3318 [FIX] Simplify service account email to key-name@platform.internal

Use key name directly for email without UUID suffix. Username retains
UUID prefix for global uniqueness. Cross-org isolation is handled by
the org-scoped manager mixin on OrganizationMember.

* UN-3318 [FEAT] Add read/read_write permission on API keys and bypass owner checks for service accounts

- Add permission field (read/read_write) to PlatformApiKey model
- Enforce in middleware: block DELETE, block writes for read-only keys
- Bypass for_user owner/shared checks for service accounts (all 7 managers)
- Bypass object-level permissions (IsOwner, IsOwnerOrSharedUser, etc.)
- Hide service accounts from member listings and shared_users serializers
- Add permission column, select in create/edit modals on frontend

* UN-3318 [FIX] Merge implicitly concatenated string in db_comment

* UN-3318 [FIX] Regenerate platform_api migrations (squash permission into initial)

* Revert unintended shebang change in workers/run-worker.sh

* Fix route gating: move platform-api-keys inside RequireAdmin, restore triad position

* Add UniqueTogetherValidator for platform API key name+org uniqueness

DRF doesn't auto-validate UniqueConstraint from Meta.constraints
(unlike unique_together), so duplicate names would cause a 500
IntegrityError. Adding explicit validator returns a clean 400.

* Fix name uniqueness validation to use manual check instead of UniqueTogetherValidator

UniqueTogetherValidator requires all fields in serializer data, but
organization is set at model layer via DefaultOrganizationMixin.save().
Use validate_name with UserContext.get_organization() instead.

* Use accessible Button element for API key copy action

Replace clickable div with Ant Design Button (type=text) for keyboard
accessibility and proper ARIA semantics.

* Fix Greptile review issues: atomicity, email collision, model scan scope

- Wrap create_api_user_for_key in transaction.atomic() to prevent
  orphaned service accounts on partial failure
- Wrap sync_prompts delete+recreate in transaction.atomic() to prevent
  data loss if import_prompts fails after delete
- Add uid fragment to service account email to prevent collision across
  orgs with same key name
- Scope transfer_ownership to business app labels only instead of
  scanning all Django models (avoids system/third-party model queries)
- Fix frontend SAFE_TEXT_MESSAGE to include forward slashes

* Fix code review issues: cross-org leak, signal safety, email sanitization

- WorkflowExecutionManager: scope service account queryset by org via
  workflow__organization to prevent cross-org data leak
- pre_delete signal: wrap in try/except so cleanup failures don't block
  key deletion (orphaned accounts logged instead)
- Email sanitization: strip non-alphanumeric chars from key name before
  using in email to comply with RFC 5321
- Move uuid/re imports to top of services.py
- Add exception logging to IsOrganizationAdmin permission class

* Address human reviewer feedback: middleware, serializer, error messages

- Move DELETE check before DB lookup in bearer auth middleware
- Improve error message for missing service account (actionable)
- Include max count in KeyCountExceeded error message
- Move key count validation from view to serializer
- Add TODO for key hashing on model
- Remove unused imports from views.py

* Remove platform API key count limit and related constants/exceptions

The limit was an arbitrary safety net attracting unnecessary review
discussion. No rate limiting needed at this stage.

* Reduce cognitive complexity in transfer_ownership to satisfy SonarCloud

Extract per-model logic into _transfer_model_ownership helper to reduce
nesting depth and bring cognitive complexity from 21 to within the
allowed threshold of 15.

* Use serializer for sync_prompts validation, remove manual error handling

Add SyncPromptsSerializer to validate request body with DictField and
required keys check. Remove try/except blocks from sync_prompts view
to let DRF middleware handle errors consistently.

* Add type hints to services.py and use constants for HTTP methods

- Add type annotations to all public functions in platform_api/services.py
- Add RequestMethod constants class with SAFE_METHODS frozenset
- Use RequestMethod and ApiKeyPermission enum in bearer auth middleware
  instead of hardcoded strings

* Address code review: transactions, retrieve masking, permission hardening

- Wrap create() in transaction.atomic() so key + service account are
  atomic (no orphaned keys if service account creation fails)
- Wrap transfer_ownership and delete_api_user_for_key in
  transaction.atomic() to prevent partial ownership transfers
- Use masked serializer for retrieve() — plaintext key only shown at
  create and rotate
- Use save(update_fields=) in rotate() for efficiency
- Use _meta.get_fields() instead of hasattr() for Django field detection
- Narrow service account permission bypass to SAFE_METHODS only in
  IsOwner, IsOwnerOrSharedUser, IsOwnerOrSharedUserOrSharedToOrg

* Fix handleCopyKey to use masked value from list data

The retrieve endpoint now returns masked keys, so the copy button
should use the already-available masked value from the record instead
of making a redundant API call.

* Revert retrieve masking — full key needed for copy-to-clipboard

The retrieve endpoint must return the full key since handleCopyKey
relies on it. Key hashing (show plaintext only at create/rotate)
should be done as a separate cross-cutting change with APIDeployment.

* Fix NoneType error when created_by is NULL in prompt studio serializer

Handle NULL created_by in CustomToolSerializer.to_representation to
prevent AttributeError on projects where the creator has been deleted.

* Make API key name immutable after creation

Name is used to derive the service account username/email, so it
should not be editable. Remove name from update serializer and
show it as disabled in the edit modal.

* Fix ownership transfer on API key deletion and prompt studio bugs

- Use _base_manager to bypass DefaultOrganizationManagerMixin in
  transfer_ownership (org context unavailable during signal paths)
- Dynamically discover all User FK/M2M fields instead of hardcoding
  created_by/modified_by (fixes missed workflow_owner transfer)
- Move created_by_email assignment before early return in prompt studio
  serializer so new projects without prompts show the owner
- Add trailing slash to prompt studio share PATCH URL

* Fix workflow_manager app_label in transfer ownership scan

The app_label for the Workflow model is "workflow_v2" (derived from
AppConfig.name = "workflow_manager.workflow_v2"), not "workflow_manager".
This caused transfer_ownership to skip workflows entirely, leaving
created_by/workflow_owner NULL after service account deletion.

v0.159.6

Toggle v0.159.6's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
UN-3334 [FIX] Fix profile dropdown menu items alignment (#1861)

* UN-3334 [FIX] Fix profile dropdown menu items center-aligned instead of left-aligned

Ant Design 5.13 Button type="text" introduced justify-content: center,
overriding the default flex-start alignment in the profile dropdown menu.
Add explicit justify-content: flex-start to .logout-button and ensure
plugin-rendered menu items are also left-aligned via .ant-dropdown-menu-title-content.

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

* Add flex-start to menu-title-content for plugin flex items

Address review feedback: text-align alone won't override
justify-content on flex children. Making the wrapper itself
a flex container with justify-content: flex-start ensures
plugin items using antd Button are also left-aligned.

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

* UN-3334 [FIX] Fix biome CSS formatting for TopNavBar selector

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: vishnuszipstack <vishnu@zipstack.com>

v0.159.5

Toggle v0.159.5's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[FIX] Redis Sentinel support for tool containers and sidecars (#1858)

* [FIX] Fix Redis Sentinel crash in MetricsMixin (prompt-service)

MetricsMixin was creating a raw StrictRedis client using REDIS_HOST/PORT
directly, which in Sentinel HA mode points to the Sentinel process (port
26379). Sentinel doesn't support the SELECT command, causing
ResponseError on every /answer-prompt call.

- Replace StrictRedis with create_redis_client() from unstract-core
  which handles Sentinel discovery via master_for()
- Add unstract-core as sdk1 dependency (all services using sdk1 already
  depend on core, so zero new transitive deps)
- Add error handling around set_start_time() and collect_metrics() so
  Redis failures degrade gracefully instead of crashing requests
- Add missing COPY for unstract/core in tool Dockerfiles (classifier,
  structure, text_extractor) since sdk1 now depends on core

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

* Commit uv.lock changes

* [FIX] Add unstract-core to tool requirements.txt for pip resolution

Tool Dockerfiles (classifier, text_extractor, structure) use pip, not
uv. Since sdk1 now depends on unstract-core (which isn't on PyPI),
pip can't resolve it via [tool.uv.sources]. Adding explicit editable
install of core before sdk1 ensures pip finds it locally.

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

* [REFACTOR] DRY Redis client creation in worker cache modules

Worker cache modules (cache_backends.py, cache_utils.py) duplicated
sentinel/standalone branching logic for Redis client creation. Both
now use create_redis_client() from unstract-core as the single entry
point, which already handles mode detection internally.

- Add SSL support (ssl, ssl_cert_reqs) to create_redis_client() via
  env vars ({prefix}SSL, {prefix}SSL_CERT_REQS), disabled by default
- Remove if-sentinel-else-standalone branching in cache_backends.py
  and cache_utils.py — replaced with single create_redis_client() call
- Remove unused os and redis imports from simplified modules

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

* [FIX] Pass Redis Sentinel env vars to tool and sidecar containers

The runner was not forwarding REDIS_SENTINEL_MODE and
REDIS_SENTINEL_MASTER_NAME to tool containers and sidecars, causing the
sidecar to connect in standalone mode to the Sentinel port (26379) and
fail on all data commands (HGETALL, SETEX).

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

* [FIX] Bump tool versions for Redis Sentinel compatibility (#1859)

Patch bump for tools that depend on unstract-core's updated
Redis client with Sentinel support:
- classifier: 0.0.76 -> 0.0.77
- structure: 0.0.97 -> 0.0.98
- text_extractor: 0.0.72 -> 0.0.73

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

---------

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

v0.159.4

Toggle v0.159.4's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[FIX] Fix Redis Sentinel crash in MetricsMixin (#1856)

* [FIX] Fix Redis Sentinel crash in MetricsMixin (prompt-service)

MetricsMixin was creating a raw StrictRedis client using REDIS_HOST/PORT
directly, which in Sentinel HA mode points to the Sentinel process (port
26379). Sentinel doesn't support the SELECT command, causing
ResponseError on every /answer-prompt call.

- Replace StrictRedis with create_redis_client() from unstract-core
  which handles Sentinel discovery via master_for()
- Add unstract-core as sdk1 dependency (all services using sdk1 already
  depend on core, so zero new transitive deps)
- Add error handling around set_start_time() and collect_metrics() so
  Redis failures degrade gracefully instead of crashing requests
- Add missing COPY for unstract/core in tool Dockerfiles (classifier,
  structure, text_extractor) since sdk1 now depends on core

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

* Commit uv.lock changes

* [FIX] Add unstract-core to tool requirements.txt for pip resolution

Tool Dockerfiles (classifier, text_extractor, structure) use pip, not
uv. Since sdk1 now depends on unstract-core (which isn't on PyPI),
pip can't resolve it via [tool.uv.sources]. Adding explicit editable
install of core before sdk1 ensures pip finds it locally.

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

* [REFACTOR] DRY Redis client creation in worker cache modules (#1857)

Worker cache modules (cache_backends.py, cache_utils.py) duplicated
sentinel/standalone branching logic for Redis client creation. Both
now use create_redis_client() from unstract-core as the single entry
point, which already handles mode detection internally.

- Add SSL support (ssl, ssl_cert_reqs) to create_redis_client() via
  env vars ({prefix}SSL, {prefix}SSL_CERT_REQS), disabled by default
- Remove if-sentinel-else-standalone branching in cache_backends.py
  and cache_utils.py — replaced with single create_redis_client() call
- Remove unused os and redis imports from simplified modules

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

---------

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

v0.159.3

Toggle v0.159.3's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[FIX] Add missing SentinelConnectionFactory for Redis Sentinel cache (#…

…1855)

[FIX] Add missing SentinelConnectionFactory for Django Redis Sentinel cache

PR #1854 added CONNECTION_POOL_CLASS but missed CONNECTION_FACTORY,
causing the default ConnectionFactory to create SentinelConnectionPool
via from_url() without the required service_name and sentinel_manager
arguments — crashing migrations at import time.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

v0.159.2

Toggle v0.159.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[FIX] Fix Redis Sentinel HA crashes in backend and celery services (#…

…1854)

* [FIX] Fix Redis Sentinel HA crashes in backend and celery services

Fix two bugs introduced in PR #1838 that cause CrashLoopBackOff in Sentinel mode:

1. log_events.py: Nest transport_options under connection_options for KombuManager
   - KombuManager doesn't accept transport_options directly
   - connection_options gets unpacked into kombu.Connection() which accepts transport_options

2. base.py: Add missing CONNECTION_POOL_CLASS for Django CACHES in Sentinel mode
   - SentinelClient.connect() requires CONNECTION_POOL_CLASS set to SentinelConnectionPool
   - Affects celery-beat and worker-metrics services

Both fixes are isolated to if REDIS_SENTINEL_MODE: branch.
Standalone Redis mode is unaffected.

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

* [FIX] Nest transport_options under connection_options in worker log consumer

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Gayathri <142381512+gaya3-zipstack@users.noreply.github.com>

v0.159.1

Toggle v0.159.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[FIX] Adding prompt files to the build for Agentic prompt Studio (#1853)

* Fix for missing Prompt files

Signed-off-by: harini-venkataraman <115449948+harini-venkataraman@users.noreply.github.com>

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

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

---------

Signed-off-by: harini-venkataraman <115449948+harini-venkataraman@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

v0.159.0

Toggle v0.159.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
UN-3320 [FIX] Show days in TTL time display instead of only hours (#1847

)

* [FIX] Show days in TTL time display instead of only hours

The formatTimeDisplay helper was computing hours from total seconds
without extracting days first, resulting in large hour values like
"2011h 45m" instead of "83d 19h 45m".

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

* [FEAT] Add batch_resolve_user_ids utility for user display info

Generic utility to batch resolve stringified user PKs to display names
and emails in a single query. Used by HITL manual review for resolving
reviewer/approver IDs.

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

* Update backend/utils/user_utils.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>

* Update backend/utils/user_utils.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>

* Revert type hints added without import (df285b5)

Reverts the Iterable[str] type annotation that was added without
importing Iterable, which broke the pre-commit check.

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

* [FIX] Address PR review comments on batch_resolve_user_ids

- Add type annotations (Iterable[str] param, dict return type)
- Clarify docstring that unresolved PKs are omitted
- Coerce user.email None to empty string
- Fix early-return guard for generator inputs
- Prefer get_full_name() for display names

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

---------

Signed-off-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Chandrasekharan M <117059509+chandrasekharan-zipstack@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Chandrasekharan M <chandrasekharan@zipstack.com>

v0.158.4

Toggle v0.158.4's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[FIX] Azure AI schema filename mismatch (#1846)

[FIX] Rename Azure AI schema file to match get_provider() return value

Schema file was named azure_ai_foundry.json but get_provider() returns
'azure_ai'. The base class get_json_schema() uses get_provider() to
construct the schema path, so it looked for azure_ai.json (non-existent),
causing FileNotFoundError that crashed /supported_adapters/ endpoint
with 500 error and broke all adapter icon loading.

Rename to azure_ai.json to match get_provider() and fix adapter list
rendering on settings pages.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>