Skip to content

release: 0.38.0#111

Open
stainless-app[bot] wants to merge 34 commits intomainfrom
release-please--branches--main--changes--next
Open

release: 0.38.0#111
stainless-app[bot] wants to merge 34 commits intomainfrom
release-please--branches--main--changes--next

Conversation

@stainless-app
Copy link
Copy Markdown
Contributor

@stainless-app stainless-app Bot commented Apr 18, 2026

Automated Release PR

0.38.0 (2026-05-09)

Full Changelog: v0.37.0...v0.38.0

Features

Bug Fixes

  • client: add missing f-string prefix in file type error message (6dbd3ec)
  • use correct field name format for multipart file arrays (0f569cc)

Performance Improvements

  • client: optimize file structure copying in multipart requests (c28640c)

Chores

  • internal: more robust bootstrap script (d4a39dc)
  • internal: reformat pyproject.toml (19a83c3)
  • tests: bump steady to v0.22.1 (7d67d91)

This pull request is managed by Stainless's GitHub App.

The semver version number is based on included commit messages. Alternatively, you can manually set the version number in the title of this pull request.

For a better experience, it is recommended to use either rebase-merge or squash-merge when merging this pull request.

🔗 Stainless website
📚 Read the docs
🙋 Reach out for help or questions

@stainless-app
Copy link
Copy Markdown
Contributor Author

stainless-app Bot commented Apr 18, 2026

🧪 Testing

To try out this version of the SDK:

pip install 'https://pkg.stainless.com/s/hyperspell-python/6dbd3ecf89c76051dde508e759d15db97acc4141/hyperspell-0.37.0-py3-none-any.whl'

Expires at: Mon, 08 Jun 2026 04:06:56 GMT
Updated at: Sat, 09 May 2026 04:06:56 GMT

@canaries-inc
Copy link
Copy Markdown

canaries-inc Bot commented Apr 18, 2026

🐤 Canary Summary

This PR is a Python SDK release with no UI/UX changes affecting end users:

  • Version bump to 0.38.0 across all configuration files
  • Added date parameter to memories API for backend ranking/filtering
  • Updated API type definitions and test coverage
  • No user-facing UI components or changes present


View PR tests on Canary

@canaries-inc
Copy link
Copy Markdown

canaries-inc Bot commented Apr 18, 2026

🐤 Canary Proposed Tests

No testable user journeys found for this PR.

@entelligence-ai-pr-reviews
Copy link
Copy Markdown


Confidence Score: 5/5 - Safe to Merge

Safe to merge — this PR is a release bump to version 0.38.0 and the automated review found no issues across the reviewed files. No logic changes, security concerns, or correctness problems were identified, and there are no unresolved pre-existing comments to carry forward. The PR appears to be a standard version release with clean diffs.

Key Findings:

  • No review comments were generated by the automated analysis, indicating no detectable logic, security, or correctness issues in the changed files.
  • Zero critical, significant, or medium-severity issues were flagged by the heuristic analysis, consistent with a version bump or release preparation PR.
  • Coverage of 3/8 changed files leaves some files unreviewed, but for a release PR this is a low-risk gap — typically release commits touch changelogs, version files, and lock files which are low-risk by nature.

@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 8517aa7 to 9e83d93 Compare April 18, 2026 08:14
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 9e83d93 to d34485e Compare April 18, 2026 08:16
@entelligence-ai-pr-reviews
Copy link
Copy Markdown

entelligence-ai-pr-reviews Bot commented Apr 18, 2026

EntelligenceAI PR Summary

Releases v0.38.0 of the Hyperspell Python SDK with new integrations, API changes, and internal improvements.

  • Added granola, fathom, and linear as supported integration/source/provider types across all relevant models, resources, and type params
  • Introduced HYPERSPELL_CUSTOM_HEADERS env var support for injecting custom HTTP headers in both sync and async clients
  • Replaced deepcopy_minimal with the new path-aware deepcopy_with_paths utility in _files.py and updated memories.py accordingly
  • Added array_format parameter to extract_files for configurable multipart file field name serialization (brackets, indices, repeat, comma)
  • Refactored MemorySearchParams.effort from int to Literal['minimal','low','medium','high'] string enum
  • Added optional date param to memory.update and optional recency_half_life_days to memory.search options
  • Added requires_channel_selection to IntegrationListResponse and selected_count to ConnectionListResponse
  • Added folder_ancestors field to the shared Resource model
  • Relocated ArrayFormat/NestedFormat type aliases from _qs.py to _types.py
  • Bumped @stdy/cli from 0.20.2 to 0.22.1 in mock/test scripts; fixed unbound variable in bootstrap script

Confidence Score: 3/5 - Review Recommended

Likely safe but review recommended — this PR ships a well-scoped release (v0.38.0) adding granola, fathom, and linear integrations plus HYPERSPELL_CUSTOM_HEADERS env var support and the deepcopy_with_paths utility refactor, all of which appear to be straightforward extensions. However, a pre-existing unresolved concern in src/hyperspell/_utils/_utils.py around the flattened_key / _array_suffix interaction (L140-L151) remains open: when flattened_key is None and the format yields an empty string, the recursive call receives flattened_key="" instead of None, which is a correctness deviation that could silently produce malformed keys in certain serialization paths. That issue was not introduced by this PR but is still unresolved, and it touches a utility used broadly enough to warrant attention before shipping.

Key Findings:

  • The unresolved comment on _utils.py L140-L151 describes a real correctness issue: passing flattened_key="" (empty string) instead of None to the recursive call when _array_suffix returns "" for repeat/comma formats could produce keys with unexpected leading separators (e.g. .child instead of child), silently corrupting multipart form serialization for nested structures.
  • The deepcopy_with_paths refactor in _files.py and memories.py is a targeted internal improvement; without reviewing the full implementation of deepcopy_with_paths it is hard to confirm full correctness, and it was only partially covered (15/34 files reviewed), leaving some risk in the path-aware deep-copy logic.
  • Addition of HYPERSPELL_CUSTOM_HEADERS env var support is a common extension pattern and the approach (injecting headers in both sync/async clients) is standard, representing low risk if header parsing is not overly permissive.
  • New integration types (granola, fathom, linear) appear to be additive enum/literal expansions and model field additions — typically low-risk changes that compose well with existing validation patterns.
Files requiring special attention
  • src/hyperspell/_utils/_utils.py
  • src/hyperspell/_utils/_files.py
  • src/hyperspell/resources/memories.py

@entelligence-ai-pr-reviews
Copy link
Copy Markdown

Releases v0.38.0 with a new date field on the memories update endpoint and a targeted deep copy utility replacing the previous full-copy approach in multipart requests.

  • Added date: str | datetime | None parameter to sync/async memories.update() and MemoryUpdateParams
  • Introduced deepcopy_with_paths in src/hyperspell/_files.py for selective container deep copying along specified key paths
  • Removed deepcopy_minimal from src/hyperspell/_utils/_utils.py and its export from src/hyperspell/_utils/__init__.py
  • Updated src/hyperspell/resources/memories.py to use deepcopy_with_paths with ['file'] path in both sync and async upload methods
  • Added 8 new tests in tests/test_files.py covering deepcopy_with_paths and mutation-safety with extract_files
  • Removed tests/test_deepcopy.py along with the deprecated utility
  • Version bumped in pyproject.toml, _version.py, and .release-please-manifest.json; OpenAPI spec hash refreshed in .stats.yml

@entelligence-ai-pr-reviews
Copy link
Copy Markdown

Releases hyperspell v0.38.0 with an API enhancement, a deep copy performance improvement, and a test dependency update.

  • Added optional date field (Union[str, datetime], ISO 8601) to MemoryUpdateParams and sync/async update methods in memories.py
  • Replaced deepcopy_minimal (removed from _utils/_utils.py and _utils/__init__.py) with the new deepcopy_with_paths utility in _files.py, which shallow-copies only containers along specified key paths
  • Updated memories.py upload methods to use deepcopy_with_paths imported from _files instead of _utils
  • Bumped @stdy/cli from 0.20.2 to 0.22.1 in scripts/mock and scripts/test
  • Updated OpenAPI spec URL/hash in .stats.yml
  • Removed tests/test_deepcopy.py; added TestDeepcopyWithPaths tests in tests/test_files.py
  • Version bumped to 0.38.0 in pyproject.toml, _version.py, and .release-please-manifest.json

@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from d34485e to 7c5dc69 Compare April 22, 2026 18:30
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 7c5dc69 to 3aee06b Compare April 22, 2026 19:22
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 3aee06b to 4d6e79f Compare April 22, 2026 19:27
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 4d6e79f to 69f3e7d Compare April 22, 2026 19:39
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 69f3e7d to 2b93798 Compare April 22, 2026 19:52
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 2b93798 to 3342428 Compare April 22, 2026 23:12
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 3342428 to 5e40e1e Compare April 23, 2026 04:06
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 5e40e1e to 1929ac3 Compare April 23, 2026 22:30
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 20a202a to b9d26a4 Compare April 28, 2026 16:31
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from b9d26a4 to b25541d Compare April 29, 2026 05:46
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from b25541d to d44e2c9 Compare April 30, 2026 08:02
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from d44e2c9 to 0c97422 Compare May 1, 2026 00:31
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 0c97422 to d6e30c6 Compare May 1, 2026 05:00
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from d6e30c6 to 9da4eec Compare May 1, 2026 05:04
Copy link
Copy Markdown

@entelligence-ai-pr-reviews entelligence-ai-pr-reviews Bot left a comment

Choose a reason for hiding this comment

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

Release v0.38.0 of the hyperspell Python SDK introducing new API parameters, a custom headers environment variable, and internal utility improvements.

  • Custom headers: Both sync and async clients now parse HYPERSPELL_CUSTOM_HEADERS (newline-delimited Key: Value) and merge into default_headers (src/hyperspell/_client.py)
  • Array format control: extract_files / _extract_items gain an array_format parameter (brackets, indices, repeat, comma) controlling multipart field name suffixes (src/hyperspell/_utils/_utils.py)
  • deepcopy refactor: Replaced deepcopy_minimal with deepcopy_with_paths for path-selective shallow copying; deepcopy_minimal removed from _utils exports (src/hyperspell/_files.py, src/hyperspell/_utils/__init__.py, src/hyperspell/resources/memories.py)
  • New API parameters: date (ISO 8601) added to MemoryUpdateParams and memory update methods; recency_half_life_days added to Options in memory_search_params.py
  • Type aliases relocated: ArrayFormat and NestedFormat moved from _qs.py to _types.py
  • MCP badge URLs: Updated to scoped package name @hyperspell/hyperspell-mcp in README.md
  • Scripts: Bootstrap hardened against set -u; @stdy/cli bumped to 0.22.1 in mock/test scripts
  • Tests: Added coverage for array_format, deepcopy_with_paths, new API params; removed test_deepcopy.py

Comment on lines 142 to +144
index=index,
flattened_key=flattened_key + "[]" if flattened_key is not None else "[]",
flattened_key=(
(flattened_key if flattened_key is not None else "") + _array_suffix(array_format, array_index)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Correctness: When flattened_key is None and _array_suffix returns "" (for "repeat" or "comma" formats), the new code passes flattened_key="" (empty string) to the recursive call instead of None; the downstream dict-handling branch checks if flattened_key is None to decide whether to assign key or append [key], so an empty string takes the else branch and produces a malformed key like "[fieldname]" instead of "fieldname".

🤖 AI Agent Prompt for Cursor/Windsurf

📋 Copy this prompt to your AI coding assistant (Cursor, Windsurf, etc.) to get help fixing this issue

In `src/hyperspell/_utils/_utils.py`, lines 142–144, the new expression `(flattened_key if flattened_key is not None else "") + _array_suffix(array_format, array_index)` converts a `None` flattened_key into an empty string `""` when `_array_suffix` returns `""` (e.g., for `"repeat"` or `"comma"` array formats). The recursive `_extract_items` call then sees `flattened_key=""`, which is not `None`, so the dict branch appends `[key]` instead of just using `key`, producing a leading-bracket malformed key. Fix by preserving `None` when the suffix is empty: use `(flattened_key + suffix) if flattened_key is not None else (suffix if suffix else None)` where `suffix = _array_suffix(array_format, array_index)`.

@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 9da4eec to 8d532eb Compare May 5, 2026 19:31
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 8d532eb to 0ac286c Compare May 6, 2026 19:31
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 0ac286c to 130b15f Compare May 6, 2026 20:31
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 130b15f to eee6d39 Compare May 7, 2026 19:31
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from eee6d39 to c5567dd Compare May 8, 2026 03:31
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from c5567dd to d1ecefc Compare May 8, 2026 17:31
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from d1ecefc to 04df5d3 Compare May 8, 2026 18:31
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 04df5d3 to e7cfe05 Compare May 9, 2026 04:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants