Skip to content

release: 2.5.0#253

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

release: 2.5.0#253
stainless-app[bot] wants to merge 37 commits intomainfrom
release-please--branches--main--changes--next

Conversation

@stainless-app
Copy link
Copy Markdown
Contributor

@stainless-app stainless-app bot commented Apr 8, 2026

Automated Release PR

2.5.0 (2026-04-10)

Full Changelog: v2.4.0...v2.5.0

Features

  • api: Deprecate AI Detection, Medical Comprehend, and Context-Aware Text Splitting (c6bee06)
  • client: add custom JSON encoder for extended type support (a855555)
  • client: add support for binary request streaming (56bd96e)
  • internal: implement indices array format for query and form serialization (898e230)

Bug Fixes

  • client: preserve hardcoded query params when merging with user params (70761a4)
  • deps: bump minimum typing-extensions version (e8e396e)
  • docs: fix mcp installation instructions for remote servers (b448904)
  • ensure file data are only sent as 1 parameter (ae4c4ad)
  • pydantic: do not pass by_alias unless set (f8a82fe)
  • remove custom binary_request handling superseded by codegen (#28) (763afaf)
  • resolve duplicate code (#29) (57837bc)
  • sanitize endpoint path params (e87c2a0)

Chores

  • ci: skip lint on metadata-only changes (e8479c1)
  • ci: skip uploading artifacts on stainless-internal branches (f8763df)
  • ci: upgrade actions/github-script (aa28320)
  • format all api.md files (0d10457)
  • internal: add request options to SSE classes (fead372)
  • internal: bump dependencies (6d39e6e)
  • internal: fix lint error on Python 3.14 (0cf9c5f)
  • internal: make test_proxy_environment_variables more resilient (00a019f)
  • internal: make test_proxy_environment_variables more resilient to env (2ec43af)
  • internal: tweak CI branches (cff7016)
  • internal: update actions/checkout version (4de949f)
  • internal: update gitignore (c1351cf)
  • internal: version bump (6733bea)
  • test: do not count install time for mock server timeout (ca18be8)
  • tests: bump steady to v0.19.4 (57552b1)
  • tests: bump steady to v0.19.5 (ec60cc4)
  • tests: bump steady to v0.19.6 (54e2229)
  • tests: bump steady to v0.19.7 (9b78194)
  • tests: bump steady to v0.20.1 (09fa209)
  • tests: bump steady to v0.20.2 (4bb6605)
  • update mock server docs (dd5b8a9)
  • update placeholder string (3d66005)

Documentation

  • api: updates to API spec (832318c)

Refactors

  • tests: switch from prism to steady (b63e313)

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

* fix: remove custom binary_request handling superseded by codegen

The codegen now natively supports a `content` parameter for binary
request streaming. Remove the custom `binary_request` parameter and
content routing that conflicts with this new codegen feature. Move
file transformation to the call site in resources/files.py.

* style: fix import ordering
stainless-app bot added 28 commits April 9, 2026 19:30
Note that we still want to run tests, as these depend on the metadata.
@stainless-app stainless-app bot force-pushed the release-please--branches--main--changes--next branch from 1fc4567 to 2493bf0 Compare April 9, 2026 19:32
@stainless-app stainless-app bot changed the title release: 2.4.1 release: 2.5.0 Apr 9, 2026
@stainless-app stainless-app bot force-pushed the release-please--branches--main--changes--next branch 2 times, most recently from aac51c1 to 7431f87 Compare April 9, 2026 19:33
@pullrequest
Copy link
Copy Markdown

pullrequest bot commented Apr 9, 2026

HackerOne Code Security Review

🟢 Scan Complete: 4 Issue(s)
🟢 Validation Complete: Any Issues detected were validated by one of our engineers. None were determined to require immediate action.

Here's how the code changes were interpreted and info about the tools used for scanning.

📖 Summary of Changes The update introduces version 2.5.0 with several key changes. The workflow files were updated to use newer GitHub Actions versions. A new tools resource was added, while AI detect and context-aware splitting tools were removed. The codebase saw improvements in binary request streaming, JSON encoding, and URL path generation. Dependency versions were bumped, and minor refactoring was performed across various modules to enhance type hinting and compatibility.
File Summary
.github/workflows/ci.yml The workflow file was updated with changes to branch filtering, GitHub Actions versions, and added conditions for skipping certain jobs. Modifications include updating checkout and GitHub script actions, and adding more specific branch and commit message filters.
.github/workflows/publish-pypi.yml The workflow file was updated to use actions/checkout@v6 instead of actions/checkout@v4, with all other content remaining the same.
.github/workflows/release-doctor.yml The GitHub Actions workflow file was updated to use actions/checkout@v6 instead of actions/checkout@v4, with all other content remaining the same.
.gitignore The .gitignore file now includes an additional log file (.stdy.log) alongside the existing .prism.log, with all other contents remaining unchanged.
.release-please-manifest.json The version number has been incremented from 2.4.0 to 2.5.0, indicating a minor version update.
.stats.yml The configuration shows a reduction in configured endpoints from 33 to 30, and a change in the OpenAPI specification URL and hash, while the config hash remains unchanged.
CHANGELOG.md The changelog has been updated to version 2.5.0, adding new features like custom JSON encoder, binary request streaming support, and indices array format serialization. It also includes various bug fixes, chores, and documentation updates.
CONTRIBUTING.md The changes include updating the mock server reference from Prism to Steady and modifying the mock server setup command from using npx to a local script ./scripts/mock.
README.md The changes include updates to the installation command, removing the '--pre' flag, and adding environment variables to the Cursor and VS Code MCP installation links. The core documentation and functionality remain largely the same.
api.md The changes include removing AI detect and context-aware splitting tools, consolidating tools import, and modifying the tools resource import path from tools/tools.py to tools.py.
pyproject.toml Version updated from 2.4.0 to 2.5.0, typing-extensions dependency updated to >=4.14, and a minor change to the format:docs script to use bash and find command for locating api.md files.
requirements-dev.lock The lockfile was updated with version bumps for several dependencies, including aiohttp from 3.13.2 to 3.13.3, httpx-aiohttp from 0.1.9 to 0.1.12, and ruff from 0.14.7 to 0.14.13, along with minor version updates to other packages.
requirements.lock Version updates for several dependencies: aiohttp from 3.13.2 to 3.13.3, anyio from 4.12.0 to 4.12.1, certifi from 2025.11.12 to 2026.1.4, and httpx-aiohttp from 0.1.9 to 0.1.12.
scripts/mock The script was updated to replace Prism mock server with Steady mock server, adding pre-installation, specific host and port configuration, health endpoint checking, and more detailed startup timeout and error handling.
src/writerai/_base_client.py The changes include adding warnings for deprecated byte body handling, introducing new type hints for binary content (BinaryTypes, AsyncBinaryTypes), preserving hard-coded query parameters from URLs, and adding a new JSON serialization utility function (openapi_dumps).
src/writerai/_client.py The files are nearly identical, with a minor change in the import order for the resources. The tools import has been moved earlier in the import block, but the functionality remains the same.
src/writerai/_compat.py Added a new TypedDict _ModelDumpKwargs and modified the model_dump function to support an optional by_alias parameter, with handling for both Pydantic v1 and v2 compatibility.
src/writerai/_models.py The changes include adding a new content field to the FinalRequestOptionsInput and FinalRequestOptions classes with support for bytes, bytearray, file-like objects, and iterable/async iterable byte types, and duplicating the content field in the FinalRequestOptions class.
src/writerai/_qs.py The code now implements the "indices" array format in the _stringify_item method, adding support for generating query strings with indexed array notation by iterating through array items and using their index in the key.
src/writerai/_response.py Minor changes to the BaseAPIResponse._parse method, specifically adding an options parameter when initializing stream classes and adjusting the stream class initialization logic.
src/writerai/_streaming.py Added an optional options parameter to Stream and AsyncStream constructors, and imported FinalRequestOptions in the type checking block. The _options attribute is now an optional attribute on both stream classes.
src/writerai/_types.py The file has been updated to include new type definitions for binary data types, specifically adding BinaryTypes and AsyncBinaryTypes to support raw binary and streaming data in request bodies.
src/writerai/_utils/init.py A new import for path_template from ._path module was added at the beginning of the import list, while all other imports remained unchanged.
src/writerai/_utils/_compat.py A type ignore comment was added to the is_union function for the types.UnionType comparison, addressing potential type checking warnings or errors in the code.
src/writerai/_utils/_json.py A new Python file has been added that defines a custom JSON encoder for serializing objects, with support for datetime and Pydantic models, and includes an openapi_dumps function for converting objects to UTF-8 encoded JSON bytes.
src/writerai/_utils/_path.py A new file has been added that provides a utility function path_template for safely interpolating and percent-encoding URI templates with placeholders, including handling of path, query, and fragment components while preventing dot-segment attacks.
src/writerai/_version.py The version number was incremented from 2.4.0 to 2.5.0, indicating a minor version update to the package.
src/writerai/resources/applications/applications.py The file now uses path_template() function for constructing URL paths in retrieve() and generate_content() methods, replacing direct string interpolation. This change likely improves URL path generation and potentially adds more robust parameter handling.
src/writerai/resources/applications/graphs.py The file now imports the path_template function and uses it to construct URL paths in the update and list methods for both sync and async graph resources, replacing direct string formatting.
src/writerai/resources/applications/jobs.py The file now uses path_template() for URL generation instead of direct string formatting, which provides a more robust way of constructing API endpoint URLs with dynamic parameters.
src/writerai/resources/files.py The file has been updated to use a new path_template function for constructing URL paths with dynamic parameters, replacing direct string formatting. Additional imports from _files module were added, but the core functionality of the file remains largely unchanged.
src/writerai/resources/graphs.py Added path_template import and replaced hardcoded URL string concatenations with path_template function calls in various methods like retrieve, update, delete, add_file_to_graph, and remove_file_from_graph.
src/writerai/resources/tools.py The file is a newly added Python module for a tools resource, containing synchronous and asynchronous classes for PDF parsing and web searching, with deprecated method annotations and extensive type hinting and parameter support.
src/writerai/resources/tools/init.py The file has been deleted. The previous version contained import statements and exports for Comprehend and Tools resources with various synchronous and asynchronous response types.
src/writerai/resources/tools/comprehend.py The file has been completely deleted. No content remains in the new version of the file, indicating a total removal of the previous implementation of the comprehend medical resource.
src/writerai/types/init.py The file has had two import lines removed: one for ToolAIDetectParams and another for ToolAIDetectResponse, and one line for ToolContextAwareSplittingParams and its corresponding response. No other changes were made to the file.
src/writerai/types/tool_ai_detect_params.py The file has been deleted. It previously contained a TypedDict class definition for ToolAIDetectParams with a required input parameter for AI detection, including a character length requirement.
src/writerai/types/tool_ai_detect_response.py The file has been deleted. It previously contained a Python class definition for ToolAIDetectResponse with a label literal type and a score float attribute, generated from an OpenAPI specification.
src/writerai/types/tool_context_aware_splitting_params.py The file has been deleted. The original file contained a TypedDict class definition for ToolContextAwareSplittingParams with strategy and text parameters, specifying splitting strategies for text processing.
src/writerai/types/tool_context_aware_splitting_response.py The file has been deleted. It previously contained a Python class definition for ToolContextAwareSplittingResponse with a list of string chunks, generated from an OpenAPI specification.
src/writerai/types/tools/init.py The updated file removes import statements for ComprehendMedicalParams and ComprehendMedicalResponse, leaving only the future annotations import and the file generation comment.
src/writerai/types/tools/comprehend_medical_params.py The file has been deleted. The original file defined a TypedDict for Comprehend Medical parameters with required fields for content and response type, specifying medical analysis response structures.
src/writerai/types/tools/comprehend_medical_response.py The file has been completely deleted. The deletion removes all class definitions related to Comprehend Medical response models, including entity, attribute, concept, and trait classes.
ℹ️ Issues Detected

NOTE: These may not require action!

Below are unvalidated results from the Analysis Tools that ran during the latest scan for transparency. We investigate each of these for accuracy and relevance before surfacing them as a potential problem.

How will I know if something is a problem?
When validation completes, any concerns that warrant attention prior to merge will be posted as inline comments. These will show up in 2 ways:

  • Expert review (most cases): Issues will be posted by experts who manually reviewed and validated them. These are real HackerOne engineers (not bots) reviewing through an integrated IDE-like tool. You can communicate with them like any other reviewer. They'll stay assigned and get notified with commit & comment updates.
  • Automatically: In cases where our validation checks have highest confidence the problem is legitimate and urgent. These will include a description of contextual reasoning why & actionable next steps.
File & Line Issue
README.md Line 16 The changed MCP install links on lines 16 and 17 now embed a placeholder API key value ('My API Key') directly in the URL configuration parameters. Specifically, the base64/URL-encoded config payloads contain "WRITER_API_KEY":"My API Key" (visible in the decoded JSON of the cursor.com deeplink on line 16 and the VS Code install link on line 17). While this is a placeholder string rather than a real secret, embedding API key values directly in publicly visible install links in documentation normalizes the pattern of hardcoding credentials in URLs and configuration strings. If a real key were accidentally substituted here, it would be exposed in the public README. Additionally, users following these one-click install links will have a literal string 'My API Key' injected into their MCP client environment configuration, which could cause confusion or misconfiguration. The previous version of these links did not include any env/API key configuration at all. This change should be reviewed to ensure no real credentials are ever embedded in these URLs, and the documentation should clearly indicate these are placeholder values only.
src/writerai/_models.py Line 825 The content field is declared twice in both FinalRequestOptionsInput (TypedDict) and FinalRequestOptions (Pydantic model). The new duplicate declaration at lines 805 and 825 redefines content with a broader type (Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None]) that supersedes the earlier declaration (Union[HttpxFileContent, None]). In Python, a duplicate key in a TypedDict silently overwrites the previous definition, and a duplicate field in a Pydantic model similarly overrides the prior one. This means any type-level validation or constraints associated with the original content field (e.g., HttpxFileContent) are silently discarded. If downstream code relies on the original type constraint for security-relevant validation (e.g., ensuring only certain content types are accepted), this bypass could allow unexpected or malicious content types to be passed through without validation. This is a logic/type-safety issue that could weaken input validation.
src/writerai/resources/graphs.py Line 133 The change replaces direct f-string URL construction (e.g., f"/v1/graphs/{graph_id}") with a path_template helper function (e.g., path_template("/v1/graphs/{graph_id}", graph_id=graph_id)). The security posture depends entirely on whether path_template properly URL-encodes/sanitizes the interpolated values. If path_template does not percent-encode special characters in graph_id or file_id (such as /, ?, #, ..), a caller-supplied value like ../../admin or foo/bar could manipulate the resolved URL path, potentially targeting unintended API endpoints (path traversal / URL manipulation). The previous f-string approach had the same issue, but the introduction of a named helper implies an expectation of safe encoding — if that encoding is absent or incomplete, this is a newly introduced or newly surfaced vulnerability. The implementation of path_template in _utils should be audited to confirm it URL-encodes path segment values before interpolation.
src/writerai/resources/files.py Line 85 The path_template function is used to interpolate user-supplied file_id values directly into URL paths (e.g., /v1/files/{file_id}, /v1/files/{file_id}/download). If path_template does not properly URL-encode or sanitize the file_id value, a caller could supply a crafted file_id containing path traversal sequences (e.g., ../admin, %2F..%2F) or other special characters that alter the intended API endpoint. While there is a non-empty check (if not file_id), this only guards against empty strings and does not prevent path manipulation. The security of this pattern depends entirely on whether path_template encodes special characters — which is not visible in this diff. This is a potential URL/path injection concern that should be verified.
🧰 Analysis tools

⏱️ Latest scan covered changes up to commit 7431f87 (latest)

@pullrequest
Copy link
Copy Markdown

pullrequest bot commented Apr 9, 2026

✅ Graham C reviewed all the included code changes and associated automation findings and determined that there were no immediately actionable security flaws. Note that they will continue to be notified of any new commits or comments and follow up as needed throughout the duration of this pull request's lifecycle.

Image of Graham C Graham C


Reviewed with ❤️ by HackerOne Code

…are Text Splitting

Remove AI Detection, Medical Comprehend, text to graph, and Context-Aware Text Splitting from SDKs.
@stainless-app stainless-app bot force-pushed the release-please--branches--main--changes--next branch from 7431f87 to 79972e3 Compare April 9, 2026 19:46
@stainless-app stainless-app bot force-pushed the release-please--branches--main--changes--next branch from 79972e3 to 87d59e2 Compare April 9, 2026 20:18
@pullrequest
Copy link
Copy Markdown

pullrequest bot commented Apr 9, 2026

HackerOne Code reviewed the updates made to #253 up until the latest commit (87d59e2). No further issues were found.

Reviewed by:

Image of Graham C Graham C

@stainless-app stainless-app bot force-pushed the release-please--branches--main--changes--next branch from 87d59e2 to d28e7e2 Compare April 10, 2026 15:01
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.

1 participant