Commit Graph
57 Commits
Author SHA1 Message Date
James Brunton af5f54274d Add defaults to calculations for ToolIO (#7289)
# Description of Changes
Currently when calculating the output file type for some tools, the
system will get it wrong because it doesn't know about what the default
parameters in tools are, so if it doesn't have a value for some key,
it'll just bail out and say "it might not be compatible". This PR adds
logic to `ToolIO` to read the default values set for the parameters if
the tool has `ToolIOCase`s and takes them into account when figuring out
the output type. I've built it with horrible Java reflection magic to
avoid having to specify the default for params twice, which will make it
impossible for the defaults to disagree with each other. This just runs
once at startup so there's negligible performance impact.

The change is easily tested with Change Parameters, which is just
`add-password` behind the scenes but with the password params omitted
(so Change Password is always PDF->PDF, never encrypted like Add
Password).

Also (somewhat hackily) fixes a bug I noticed where saving a Change
Permissions step then leaving and returning to the pipeline will cause
the step to be reloaded as Add Password. I've added a system to
disambiguate tools which share the same endpoint (which is only these
two currently).

## Currently

<img width="455" height="135" alt="image"
src="https://github.com/user-attachments/assets/c8867d6a-599b-4f21-a2db-4a1b6ac22d73"
/>

## Now

<img width="415" height="122" alt="image"
src="https://github.com/user-attachments/assets/bd8d1bab-f00a-421b-8c91-5af0d2ad5335"
/>
2026-08-10 11:00:16 +00:00
dependabot[bot] 94fbc74271 build(deps): bump the uv group across 1 directory with 3 updates (#7287)
Bumps the uv group with 3 updates in the /engine directory:
[cryptography](https://github.com/pyca/cryptography),
[aiohttp](https://github.com/aio-libs/aiohttp) and
[datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator).

Updates `cryptography` from 49.0.0 to 50.0.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst">cryptography's
changelog</a>.</em></p>
<blockquote>
<p>50.0.0 - 2026-07-31</p>
<pre><code>
* **SECURITY ISSUE**:

:func:`~cryptography.hazmat.primitives.serialization.pkcs7.pkcs7_decrypt_der`
and its PEM and S/MIME variants no longer expose distinguishable errors
or
timing when unwrapping a ``RecipientInfo``'s ``encryptedKey``, which
could
act as a Bleichenbacher oracle for callers that decrypt untrusted
messages.
A random key is now substituted on failure, as described in :rfc:`3218`.
  Credit to **@X1AOxiang** for reporting the issue. **CVE-2026-69247**
* Deprecated Diffie-Hellman key exchange over finite fields (FFDH).
  Everything FFDH is deprecated, including the types in
``cryptography.hazmat.primitives.asymmetric.dh`` and loading FFDH keys
or
  parameters with the key loading APIs. Users should migrate to a more
  modern key exchange algorithm.
* Added ``xof()`` class methods to
  :class:`~cryptography.hazmat.primitives.hashes.SHAKE128` and
:class:`~cryptography.hazmat.primitives.hashes.SHAKE256` for
constructing
  algorithm instances configured for use with
  :class:`~cryptography.hazmat.primitives.hashes.XOFHash`.
* The :mod:`X.509 verification &lt;cryptography.x509.verification&gt;`
APIs are now
  considered stable and are subject to our API stability policy.
* Added the :doc:`/cobblestone` recipe, an implementation of the
  Cobblestone-128 and Cobblestone-256 instantiations of the `C2SP
  chunked-encryption specification
&lt;https://c2sp.org/chunked-encryption&gt;`_ for streaming
authenticated
  encryption of large messages.
* Parsing a Signed Certificate Timestamp list now rejects encodings that
carry trailing bytes after the list or after an individual SCT, instead
of
  silently ignoring them.
* Added support for using :class:`~cryptography.x509.Name` as a field
type in
  the :doc:`/hazmat/asn1/index` module.
* Loading a public key or an EC private key now rejects DER where the
``subjectPublicKey`` (or EC ``publicKey``) ``BIT STRING`` declares a
non-zero
  number of unused bits, instead of silently ignoring it.
* Parsing a CRL entry's ``InvalidityDate`` extension now rejects a
``GeneralizedTime`` that carries fractional seconds or another non-DER
form,
matching the strict encoding already required for every other X.509 time
  field.
* :func:`~cryptography.x509.ocsp.load_der_ocsp_request` and
:func:`~cryptography.x509.ocsp.load_der_ocsp_response` now reject a
request
or response whose ``version`` field is not ``v1``, the only version
defined
by RFC 6960, matching the version validation already performed when
loading
  certificates, CSRs and CRLs.
* :class:`~cryptography.hazmat.primitives.hashes.XOFHash` is now
supported
  when building against AWS-LC.
* HMAC (and therefore PBKDF2-HMAC) with SHA-3 hashes is now supported
when
  building against AWS-LC.
* Diffie-Hellman (:doc:`/hazmat/primitives/asymmetric/dh`) is now
supported
  when building against AWS-LC.
&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pyca/cryptography/commit/dcb7050b807b00392fa9fe2eac7cb362fcf355cc"><code>dcb7050</code></a>
Prepare for 50.0.0 release (<a
href="https://redirect.github.com/pyca/cryptography/issues/15372">#15372</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/53fccd93413a8d7f07d6d8999681f27b75cffa3f"><code>53fccd9</code></a>
Don't leak how PKCS#7 encryptedKey decryption failed (<a
href="https://redirect.github.com/pyca/cryptography/issues/15369">#15369</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/d472f978470fbefa521b86d98b2ecccbbb4d1dd8"><code>d472f97</code></a>
Add <code>from __future__ import annotations</code> to all src/ Python
files (<a
href="https://redirect.github.com/pyca/cryptography/issues/15371">#15371</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/908773d53829fb1466c6db364b31321c3cd8eb9a"><code>908773d</code></a>
Bump downstream dependencies in CI (<a
href="https://redirect.github.com/pyca/cryptography/issues/15368">#15368</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/2cc07cc948948211899bcb0cddd1fddf86e95812"><code>2cc07cc</code></a>
Bump BoringSSL, OpenSSL, AWS-LC in CI (<a
href="https://redirect.github.com/pyca/cryptography/issues/15367">#15367</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/c94ede9f040fa44942f7139772603419000acf66"><code>c94ede9</code></a>
chore(deps): bump ruff from 0.16.0 to 0.16.1 (<a
href="https://redirect.github.com/pyca/cryptography/issues/15366">#15366</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/67a8308dc9ea4cce6056e0f1438f903c208c3f35"><code>67a8308</code></a>
chore(deps): bump virtualenv from 21.7.0 to 21.7.1 (<a
href="https://redirect.github.com/pyca/cryptography/issues/15365">#15365</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/95018ffcdbbc510fd92fc872e3a3e80aa6e58596"><code>95018ff</code></a>
Release the GIL in one-shot AEAD encrypt/decrypt (<a
href="https://redirect.github.com/pyca/cryptography/issues/15361">#15361</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/6954733eaf55a0074abf88f06f7242dfca3a5d02"><code>6954733</code></a>
Release the GIL during DH and DSA parameter generation (<a
href="https://redirect.github.com/pyca/cryptography/issues/15364">#15364</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/6893b94c33e948f6240082461424cfb5da2dacc6"><code>6893b94</code></a>
Import _serialization instead of serialization in x509/extensions (<a
href="https://redirect.github.com/pyca/cryptography/issues/15363">#15363</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/pyca/cryptography/compare/49.0.0...50.0.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `aiohttp` from 3.14.1 to 3.14.3
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst">aiohttp's
changelog</a>.</em></p>
<blockquote>
<h1>3.14.3 (2026-07-22)</h1>
<h2>Bug fixes</h2>
<ul>
<li>
<p>Fixed the client dropping only the first <code>Authorization</code>,
<code>Cookie</code> and
<code>Proxy-Authorization</code> header when a redirect crossed an
origin -- by :user:<code>arshsmith1</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em>
:issue:<code>13180</code>.</p>
</li>
<li>
<p>Fixed error message construction in the C HTTP parser -- by
:user:<code>bdraco</code>.</p>
<p><em>Related issues and pull requests on GitHub:</em>
:issue:<code>13222</code>.</p>
</li>
</ul>
<hr />
<h1>3.14.2 (2026-07-20)</h1>
<h2>Bug fixes</h2>
<ul>
<li>
<p>Fixed :py:attr:<code>~aiohttp.web.StreamResponse.last_modified</code>
rounding a
:class:<code>datetime.datetime</code> with a fractional second down.</p>
<p><em>Related issues and pull requests on GitHub:</em>
:issue:<code>5303</code>.</p>
</li>
<li>
<p>Fixed resolving <code>localhost</code> on Windows to fall back
without <code>AI_ADDRCONFIG</code>
when the first lookup fails, so <code>localhost</code> still works
without an active
network.</p>
<p><em>Related issues and pull requests on GitHub:</em>
:issue:<code>5357</code>.</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/5e392ce0456f5235a4ee6ad46f0e806df2f15873"><code>5e392ce</code></a>
Release v3.14.3 (<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13225">#13225</a>)</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/49f65d54150397892f7bcc4aae887767d51c322d"><code>49f65d5</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13222">#13222</a>/f4866933
backport][3.14] Build C parser error message from bounded...</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/240099e5216a01b32919dcd8dd5c6c0b1bf83671"><code>240099e</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13180">#13180</a>/ee53d655
backport][3.14] drop every copy of credential headers on ...</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/d93f30a302f8b930074fe14a2be7b2088ba28111"><code>d93f30a</code></a>
Bump version (<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13202">#13202</a>)</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/c1b9212ad3d93c24b5fc66ad0849597166bc816e"><code>c1b9212</code></a>
Release v3.14.2 (<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13201">#13201</a>)</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/380d4b55e8df48dfd62f1addfb530426f6bc4106"><code>380d4b5</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13054">#13054</a>/ed8b040c
backport][3.14] escape backslashes in digest auth quoted-...</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/e1e1bee363dfba04a9a75c8801717da2ed5bdcb9"><code>e1e1bee</code></a>
Make llhttp method array size dynamic (<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13174">#13174</a>)
(<a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13196">#13196</a>)</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/aa4cf29b6a5ad6f4d21fa1dd3f69193dc2f5d505"><code>aa4cf29</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13170">#13170</a>/2b906869
backport][3.14] Fix StreamResponse.last_modified rounding...</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/71b57b40d85a0723c92b0a5a37ebdf518210d2ea"><code>71b57b4</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13172">#13172</a>/a57747ed
backport][3.14] Fix C parser folding fragment into query_...</li>
<li><a
href="https://github.com/aio-libs/aiohttp/commit/64a03fb620b623e5a5a1b7103c07ae3e536a0d40"><code>64a03fb</code></a>
[PR <a
href="https://redirect.github.com/aio-libs/aiohttp/issues/13169">#13169</a>/1adc0cd7
backport][3.14] Upgrade http:// to https:// in README.rst...</li>
<li>Additional commits viewable in <a
href="https://github.com/aio-libs/aiohttp/compare/v3.14.1...v3.14.3">compare
view</a></li>
</ul>
</details>
<br />

Updates `datamodel-code-generator` from 0.56.0 to 0.64.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/koxudaxi/datamodel-code-generator/releases">datamodel-code-generator's
releases</a>.</em></p>
<blockquote>
<h2>0.64.0</h2>
<h2>Breaking Changes</h2>
<h3>Code Generation Changes</h3>
<ul>
<li>Self-referencing fields are now quoted with
<code>--disable-future-imports</code> - When
<code>--disable-future-imports</code> is set (no <code>from __future__
import annotations</code> and no native PEP 649 deferred evaluation on
Python &lt; 3.14), self-referencing and forward-referencing field
annotations in regular <code>BaseModel</code> classes are now emitted as
quoted forward references instead of bare names. Previously such
annotations were left unquoted, producing invalid code that raised
<code>NameError</code> (Ruff F821) at class-evaluation time. Output for
the common case (with <code>from __future__ import annotations</code> or
Python 3.14 native deferred annotations) is unchanged. Users who
snapshot/golden-file generated output for the
<code>--disable-future-imports</code> configuration with
self-referencing models will see the annotation change from unquoted to
quoted, e.g. <code>children: Optional[List[Node]]</code> →
<code>children: Optional[List[&quot;Node&quot;]]</code>. (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3387">#3387</a>)</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Update CHANGELOG for 0.63.0 by <a
href="https://github.com/dcg-generated-docs"><code>@​dcg-generated-docs</code></a>[bot]
in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3345">koxudaxi/datamodel-code-generator#3345</a></li>
<li>Deduplicate module content builder by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3346">koxudaxi/datamodel-code-generator#3346</a></li>
<li>Deduplicate import reference helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3348">koxudaxi/datamodel-code-generator#3348</a></li>
<li>Refactor jsonschema root model registration by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3352">koxudaxi/datamodel-code-generator#3352</a></li>
<li>Refactor XML Schema literal helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3349">koxudaxi/datamodel-code-generator#3349</a></li>
<li>Move builtin formatter helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3351">koxudaxi/datamodel-code-generator#3351</a></li>
<li>Deduplicate Pydantic v2 config helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3350">koxudaxi/datamodel-code-generator#3350</a></li>
<li>Deduplicate DataType type hint rendering by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3354">koxudaxi/datamodel-code-generator#3354</a></li>
<li>Fix <code>constr()</code> for string fields carrying
minItems/maxItems by <a
href="https://github.com/DarkaMaul"><code>@​DarkaMaul</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3353">koxudaxi/datamodel-code-generator#3353</a></li>
<li>Cover non-finite import idempotence by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3367">koxudaxi/datamodel-code-generator#3367</a></li>
<li>Deduplicate input text detection by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3357">koxudaxi/datamodel-code-generator#3357</a></li>
<li>Remove stale protobuf coverage pragma by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3358">koxudaxi/datamodel-code-generator#3358</a></li>
<li>Cover explicit null OpenAPI media schemas by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3360">koxudaxi/datamodel-code-generator#3360</a></li>
<li>Simplify Python version feature checks by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3361">koxudaxi/datamodel-code-generator#3361</a></li>
<li>Speed up CI checks by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3378">koxudaxi/datamodel-code-generator#3378</a></li>
<li>Add maintainer link to docs footer and README by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3379">koxudaxi/datamodel-code-generator#3379</a></li>
<li>Use builtin formatter in CI by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3380">koxudaxi/datamodel-code-generator#3380</a></li>
<li>Split coverage by OS by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3381">koxudaxi/datamodel-code-generator#3381</a></li>
<li>Simplify import removal cleanup by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3362">koxudaxi/datamodel-code-generator#3362</a></li>
<li>Pin deprecation warning stacklevel by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3363">koxudaxi/datamodel-code-generator#3363</a></li>
<li>Pin public module exports by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3364">koxudaxi/datamodel-code-generator#3364</a></li>
<li>Cover to_hashable branch cases by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3366">koxudaxi/datamodel-code-generator#3366</a></li>
<li>Cover stable toposort behavior by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3369">koxudaxi/datamodel-code-generator#3369</a></li>
<li>Extract registry render helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3371">koxudaxi/datamodel-code-generator#3371</a></li>
<li>Fix minItems for arrays of URI strings by <a
href="https://github.com/sjh9714"><code>@​sjh9714</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3377">koxudaxi/datamodel-code-generator#3377</a></li>
<li>Deduplicate config value validators by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3372">koxudaxi/datamodel-code-generator#3372</a></li>
<li>Cover CLI option metadata helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3374">koxudaxi/datamodel-code-generator#3374</a></li>
<li>Cover Pydantic v2 version fallback by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3368">koxudaxi/datamodel-code-generator#3368</a></li>
<li>Fix nullable JSON Schema const enums by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3355">koxudaxi/datamodel-code-generator#3355</a></li>
<li>Pin patchable generation seams by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3365">koxudaxi/datamodel-code-generator#3365</a></li>
<li>Cover utility helper behavior by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3375">koxudaxi/datamodel-code-generator#3375</a></li>
<li>Cover DefaultPutDict behavior by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3376">koxudaxi/datamodel-code-generator#3376</a></li>
<li>Cover validator config normalization by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3373">koxudaxi/datamodel-code-generator#3373</a></li>
<li>Avoid expensive runtime type checks by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3382">koxudaxi/datamodel-code-generator#3382</a></li>
<li>Avoid eager builtin formatter import by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3383">koxudaxi/datamodel-code-generator#3383</a></li>
<li>Avoid eager TOML parser import by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3384">koxudaxi/datamodel-code-generator#3384</a></li>
<li>Stabilize msgspec payload tests by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3385">koxudaxi/datamodel-code-generator#3385</a></li>
<li>Avoid eager input parser imports by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3386">koxudaxi/datamodel-code-generator#3386</a></li>
<li>Avoid eager parser model imports by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3388">koxudaxi/datamodel-code-generator#3388</a></li>
<li>Avoid eager AsyncAPI converter imports by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3389">koxudaxi/datamodel-code-generator#3389</a></li>
<li>Dispose parser on parse errors by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3390">koxudaxi/datamodel-code-generator#3390</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/koxudaxi/datamodel-code-generator/blob/main/CHANGELOG.md">datamodel-code-generator's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/koxudaxi/datamodel-code-generator/releases/tag/0.64.0">0.64.0</a>
- 2026-06-14</h2>
<h2>Breaking Changes</h2>
<h3>Code Generation Changes</h3>
<ul>
<li>Self-referencing fields are now quoted with
<code>--disable-future-imports</code> - When
<code>--disable-future-imports</code> is set (no <code>from __future__
import annotations</code> and no native PEP 649 deferred evaluation on
Python &lt; 3.14), self-referencing and forward-referencing field
annotations in regular <code>BaseModel</code> classes are now emitted as
quoted forward references instead of bare names. Previously such
annotations were left unquoted, producing invalid code that raised
<code>NameError</code> (Ruff F821) at class-evaluation time. Output for
the common case (with <code>from __future__ import annotations</code> or
Python 3.14 native deferred annotations) is unchanged. Users who
snapshot/golden-file generated output for the
<code>--disable-future-imports</code> configuration with
self-referencing models will see the annotation change from unquoted to
quoted, e.g. <code>children: Optional[List[Node]]</code> →
<code>children: Optional[List[&quot;Node&quot;]]</code>. (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3387">#3387</a>)</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Update CHANGELOG for 0.63.0 by <a
href="https://github.com/dcg-generated-docs"><code>@​dcg-generated-docs</code></a>[bot]
in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3345">koxudaxi/datamodel-code-generator#3345</a></li>
<li>Deduplicate module content builder by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3346">koxudaxi/datamodel-code-generator#3346</a></li>
<li>Deduplicate import reference helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3348">koxudaxi/datamodel-code-generator#3348</a></li>
<li>Refactor jsonschema root model registration by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3352">koxudaxi/datamodel-code-generator#3352</a></li>
<li>Refactor XML Schema literal helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3349">koxudaxi/datamodel-code-generator#3349</a></li>
<li>Move builtin formatter helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3351">koxudaxi/datamodel-code-generator#3351</a></li>
<li>Deduplicate Pydantic v2 config helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3350">koxudaxi/datamodel-code-generator#3350</a></li>
<li>Deduplicate DataType type hint rendering by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3354">koxudaxi/datamodel-code-generator#3354</a></li>
<li>Fix <code>constr()</code> for string fields carrying
minItems/maxItems by <a
href="https://github.com/DarkaMaul"><code>@​DarkaMaul</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3353">koxudaxi/datamodel-code-generator#3353</a></li>
<li>Cover non-finite import idempotence by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3367">koxudaxi/datamodel-code-generator#3367</a></li>
<li>Deduplicate input text detection by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3357">koxudaxi/datamodel-code-generator#3357</a></li>
<li>Remove stale protobuf coverage pragma by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3358">koxudaxi/datamodel-code-generator#3358</a></li>
<li>Cover explicit null OpenAPI media schemas by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3360">koxudaxi/datamodel-code-generator#3360</a></li>
<li>Simplify Python version feature checks by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3361">koxudaxi/datamodel-code-generator#3361</a></li>
<li>Speed up CI checks by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3378">koxudaxi/datamodel-code-generator#3378</a></li>
<li>Add maintainer link to docs footer and README by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3379">koxudaxi/datamodel-code-generator#3379</a></li>
<li>Use builtin formatter in CI by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3380">koxudaxi/datamodel-code-generator#3380</a></li>
<li>Split coverage by OS by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3381">koxudaxi/datamodel-code-generator#3381</a></li>
<li>Simplify import removal cleanup by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3362">koxudaxi/datamodel-code-generator#3362</a></li>
<li>Pin deprecation warning stacklevel by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3363">koxudaxi/datamodel-code-generator#3363</a></li>
<li>Pin public module exports by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3364">koxudaxi/datamodel-code-generator#3364</a></li>
<li>Cover to_hashable branch cases by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3366">koxudaxi/datamodel-code-generator#3366</a></li>
<li>Cover stable toposort behavior by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3369">koxudaxi/datamodel-code-generator#3369</a></li>
<li>Extract registry render helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3371">koxudaxi/datamodel-code-generator#3371</a></li>
<li>Fix minItems for arrays of URI strings by <a
href="https://github.com/sjh9714"><code>@​sjh9714</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3377">koxudaxi/datamodel-code-generator#3377</a></li>
<li>Deduplicate config value validators by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3372">koxudaxi/datamodel-code-generator#3372</a></li>
<li>Cover CLI option metadata helpers by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3374">koxudaxi/datamodel-code-generator#3374</a></li>
<li>Cover Pydantic v2 version fallback by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3368">koxudaxi/datamodel-code-generator#3368</a></li>
<li>Fix nullable JSON Schema const enums by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3355">koxudaxi/datamodel-code-generator#3355</a></li>
<li>Pin patchable generation seams by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3365">koxudaxi/datamodel-code-generator#3365</a></li>
<li>Cover utility helper behavior by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3375">koxudaxi/datamodel-code-generator#3375</a></li>
<li>Cover DefaultPutDict behavior by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3376">koxudaxi/datamodel-code-generator#3376</a></li>
<li>Cover validator config normalization by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3373">koxudaxi/datamodel-code-generator#3373</a></li>
<li>Avoid expensive runtime type checks by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3382">koxudaxi/datamodel-code-generator#3382</a></li>
<li>Avoid eager builtin formatter import by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3383">koxudaxi/datamodel-code-generator#3383</a></li>
<li>Avoid eager TOML parser import by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3384">koxudaxi/datamodel-code-generator#3384</a></li>
<li>Stabilize msgspec payload tests by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3385">koxudaxi/datamodel-code-generator#3385</a></li>
<li>Avoid eager input parser imports by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3386">koxudaxi/datamodel-code-generator#3386</a></li>
<li>Avoid eager parser model imports by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3388">koxudaxi/datamodel-code-generator#3388</a></li>
<li>Avoid eager AsyncAPI converter imports by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3389">koxudaxi/datamodel-code-generator#3389</a></li>
<li>Dispose parser on parse errors by <a
href="https://github.com/koxudaxi"><code>@​koxudaxi</code></a> in <a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/pull/3390">koxudaxi/datamodel-code-generator#3390</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/koxudaxi/datamodel-code-generator/commit/53a25ab8ddb132ac68a2795247fc855b8f445d84"><code>53a25ab</code></a>
Fast path schema output (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3410">#3410</a>)</li>
<li><a
href="https://github.com/koxudaxi/datamodel-code-generator/commit/ee2087f32e6100f5c3642e7ea8506aa38e9df26c"><code>ee2087f</code></a>
Skip discriminator import scan (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3411">#3411</a>)</li>
<li><a
href="https://github.com/koxudaxi/datamodel-code-generator/commit/bdf5ddfc27f94a06ba8d289759193bb09daadd34"><code>bdf5ddf</code></a>
fix: quote self-referencing fields when --disable-future-imports is set
(<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3387">#3387</a>)</li>
<li><a
href="https://github.com/koxudaxi/datamodel-code-generator/commit/ad4ec877fa6708baebdaaf820171d24bfe5bf0cb"><code>ad4ec87</code></a>
Cache payload validation strategies (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3409">#3409</a>)</li>
<li><a
href="https://github.com/koxudaxi/datamodel-code-generator/commit/b191d52a0a1d83edeac9553119f70b2f5c131126"><code>b191d52</code></a>
Shard Python tests (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3408">#3408</a>)</li>
<li><a
href="https://github.com/koxudaxi/datamodel-code-generator/commit/29dd6d74c95dd7799d51f2c707db24862809eb23"><code>29dd6d7</code></a>
Cache parsed sources (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3407">#3407</a>)</li>
<li><a
href="https://github.com/koxudaxi/datamodel-code-generator/commit/93e2fe3cf5774d5e4d2083fac365e5bcbf0a647a"><code>93e2fe3</code></a>
Defer generation refresh (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3406">#3406</a>)</li>
<li><a
href="https://github.com/koxudaxi/datamodel-code-generator/commit/bb01d9c628f9077cc5dd72320ae60a18abd5b790"><code>bb01d9c</code></a>
Lazy root format exports (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3405">#3405</a>)</li>
<li><a
href="https://github.com/koxudaxi/datamodel-code-generator/commit/48237ed8c3af3bb58b5e6b274925ebb646412d3a"><code>48237ed</code></a>
Fast path JSON schemas (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3404">#3404</a>)</li>
<li><a
href="https://github.com/koxudaxi/datamodel-code-generator/commit/b21d106c88ac22f137cd4562389ad95a50c2e912"><code>b21d106</code></a>
Slot generation facts (<a
href="https://redirect.github.com/koxudaxi/datamodel-code-generator/issues/3403">#3403</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/koxudaxi/datamodel-code-generator/compare/0.56.0...0.64.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/Stirling-Tools/Stirling-PDF/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-06 12:20:17 +00:00
James BruntonandAnthony Stirling cd199c8659 Define tool inputs & outputs in a structured way (#7204)
# Description of Changes
Change tool APIs to use structured definitions for input/output/type
info because we need that info to be able to validate whether policies
can actually successfully work based on whether one tool accepts the
output of another. There were various bugs in the previous string
definitions because of either misspellings or just incorrect
definitions, so I've gone through and fixed all that I can find.

<img width="729" height="271" alt="image"
src="https://github.com/user-attachments/assets/08357e96-6fbb-4b9c-ba4d-8995420c7b86"
/>

<img width="749" height="264" alt="image"
src="https://github.com/user-attachments/assets/76f46284-1866-4b64-b1ed-2480e01866e9"
/>

<img width="402" height="636" alt="image"
src="https://github.com/user-attachments/assets/8f7a36ca-2845-4f14-a2df-ec9c772e66f6"
/>

<img width="393" height="317" alt="image"
src="https://github.com/user-attachments/assets/46d8b891-9820-4ce3-8109-a8b782277037"
/>

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2026-08-03 14:13:43 +00:00
dependabot[bot] 47c68af068 build(deps): bump pyasn1 from 0.6.3 to 0.6.4 in /engine in the uv group across 1 directory (#7190)
Bumps the uv group with 1 update in the /engine directory:
[pyasn1](https://github.com/pyasn1/pyasn1).

Updates `pyasn1` from 0.6.3 to 0.6.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pyasn1/pyasn1/releases">pyasn1's
releases</a>.</em></p>
<blockquote>
<h2>Release 0.6.4</h2>
<p>This is a security release.</p>
<ul>
<li>CVE-2026-59885 (GHSA-8ppf-4f7h-5ppj): Fixed quadratic time
complexity in the OBJECT IDENTIFIER and RELATIVE-OID decoders. A small
crafted substrate encoding many arcs could consume excessive CPU.</li>
<li>CVE-2026-59884 (GHSA-m4p7-r5rc-7g4j): Limited BER long-form tag IDs
to 20 octets (140 bits). Unbounded tag IDs allowed a crafted substrate
to consume excessive CPU and memory.</li>
<li>CVE-2026-59886 (GHSA-hm4w-wwcw-mr6r): Fixed excessive memory and CPU
consumption in <code>Real.__float__()</code> for values with large
base-10 exponents.</li>
<li>Pinned PyPI publish GitHub Action to an immutable commit.</li>
</ul>
<p>All changes are noted in the <a
href="https://github.com/pyasn1/pyasn1/blob/main/CHANGES.rst">CHANGELOG</a>.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pyasn1/pyasn1/blob/main/CHANGES.rst">pyasn1's
changelog</a>.</em></p>
<blockquote>
<h2>Revision 0.6.4, released 08-07-2026</h2>
<ul>
<li>CVE-2026-59885 (GHSA-8ppf-4f7h-5ppj): Fixed quadratic time
complexity in the OBJECT IDENTIFIER and RELATIVE-OID decoders.
A small crafted substrate encoding many arcs could consume
excessive CPU. Arcs are now accumulated in linear time; decoded
values are unchanged (thanks for reporting, tynus2)</li>
<li>CVE-2026-59884 (GHSA-m4p7-r5rc-7g4j): Limited BER long-form tag
IDs to 20 octets (140 bits), matching the OID arc limit introduced
in 0.6.2. Unbounded tag IDs allowed a crafted substrate to consume
excessive CPU and memory; longer tag IDs are now rejected with
PyAsn1Error. Also fixed Tag and TagSet repr() failing on huge tag
(thanks for reporting, mikeappsec)
IDs due to the integer-to-string conversion limit (Python 3.11+)</li>
<li>CVE-2026-59886 (GHSA-hm4w-wwcw-mr6r): Fixed excessive memory and
CPU consumption in Real.<strong>float</strong>() for values with large
base-10
exponents. Conversion no longer materializes huge intermediate
integers; values too large to represent as a Python float raise
OverflowError promptly, and prettyPrint() renders them as
'<!-- raw HTML omitted -->' as before. Also fixed base-10 mantissa
normalization
to use exact integer arithmetic; mantissas larger than 2**53
could previously lose precision through float division
(thanks for reporting, gvozdila)</li>
<li>Pinned PyPI publish GitHub Action to an immutable commit
[pr <a
href="https://redirect.github.com/pyasn1/pyasn1/issues/113">#113</a>](<a
href="https://redirect.github.com/pyasn1/pyasn1/pull/113">pyasn1/pyasn1#113</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pyasn1/pyasn1/commit/72e4803405816c371ed3b2cb4be181c47f038406"><code>72e4803</code></a>
Prepare release 0.6.4</li>
<li><a
href="https://github.com/pyasn1/pyasn1/commit/0c19eeb853731db1c717ff125ea001a1e558332d"><code>0c19eeb</code></a>
Pin PyPI publish action to immutable commit (<a
href="https://redirect.github.com/pyasn1/pyasn1/issues/113">#113</a>)</li>
<li><a
href="https://github.com/pyasn1/pyasn1/commit/45bdb19eb7df4b3780fe9c912c63e99bffc39dd9"><code>45bdb19</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/pyasn1/pyasn1/commit/628e36ecbb5277a3f01572ce418ef54271b165a5"><code>628e36e</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/pyasn1/pyasn1/commit/e60c691cb91addb8fcefa2f537e85ede6fb1e886"><code>e60c691</code></a>
Merge commit from fork</li>
<li>See full diff in <a
href="https://github.com/pyasn1/pyasn1/compare/v0.6.3...v0.6.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pyasn1&package-manager=uv&previous-version=0.6.3&new-version=0.6.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/Stirling-Tools/Stirling-PDF/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-01 10:55:16 +00:00
ConnorYoh 46865cd154 Add Auto Rotate tool that detects and fixes page orientation (#7152)
## What

New **Auto Rotate** tool: give it any PDF and it detects each page's
correct orientation and sets `/Rotate` so every page displays upright.
Lossless — only the page rotation metadata changes, content is never
re-rendered.

New endpoint: `POST /api/v1/misc/auto-rotate-pdf`, plus an editor tool
registered next to Rotate.

## How it works

Two-tier detection, per page, both expressed as an additive clockwise
`/Rotate` correction:

1. **Embedded-text fast path** (`AutoRotateDetection`): dominant glyph
direction via `PDFTextStripper`/`TextPosition.getDir()`. Trusted only
with >= 30 glyphs at >= 95% agreement. Near-instant for born-digital
PDFs and needs no external tools. Correction = `(glyphDir -
pageRotation) mod 360` — the sign conventions are pinned by
parameterized fixture tests covering all text-angle x `/Rotate`
combinations.
2. **Tesseract OSD fallback**: pages the text path can't decide are
rendered at 300 DPI grayscale and run through `tesseract --psm 0`.
Corrections apply only above a confidence threshold (default 14.0,
matching OCRmyPDF's `--rotate-pages-threshold`). Rendering honours the
existing `/Rotate`, so the verdict is always additive.

**Conservative by default**: blank pages, mixed-direction pages, and
low-confidence verdicts are skipped, never guessed — the failure mode to
avoid is making a correct page wrong.

### API surface

- `detectionMode`: `auto` (default) | `text` | `osd` — forcing one
method is useful for testing
- `confidenceThreshold`: minimum OSD confidence to apply a correction
- `dryRun=true`: returns a JSON per-page report instead of the PDF
- `pageRotations={"1":90,...}`: applies precomputed corrections without
detection

The frontend uses analyze-then-apply (dryRun, then pageRotations) so
detection runs exactly once per file, and the analysis report can be
shown in the UI.

### UI

The tool's results panel shows a **detection report** for
debugging/tuning: per page — method badge (Text / OCR / Skipped),
confidence score (glyph-dominance % for text, raw OSD score for OCR),
applied rotation, and a skip reason (too little text, mixed directions,
below threshold, OCR not installed...). Settings expose detection mode
and the OSD threshold.

### Dependency handling

Registered in `PageOps` only — deliberately **not** gated on the
`tesseract` group, because the text path works without Tesseract. The
controller checks `isGroupEnabled("tesseract")` at runtime; when it's
missing, scanned pages are skipped with a visible `tesseractUnavailable`
note instead of the whole tool disappearing.

## Testing

- 14 detection unit tests: all text-angle x `/Rotate` fixture
combinations (pins the direction conventions), dominance/glyph-count
guards, OSD output parsing
- 6 controller tests: dryRun report, correction application, explicit
pageRotations, tesseract-unavailable reporting, input validation
- Frontend: typecheck (core/desktop/proprietary), ESLint, Prettier, all
i18n audit tests
- **Live, text path**: fixture with pages at `/Rotate` 0/90/180/270 ->
all pages return upright; report UI verified in the browser
- **Live, OSD path**: image-only "scan" fixture (no text layer) with
pages upright/180/90 -> all detected by OSD at conf ~15-17 and
corrected; closed-loop re-analysis of the output reports 0 pages to
rotate with *higher* confidence than the input

Out of scope: skew correction (that's the OCR tool's `--deskew`); this
fixes 90-degree-multiple orientation only.
2026-07-31 11:27:12 +00:00
dependabot[bot] dff3101ca7 build(deps): bump pillow from 12.2.0 to 12.3.0 in /engine in the uv group across 1 directory (#7119)
Bumps the uv group with 1 update in the /engine directory:
[pillow](https://github.com/python-pillow/Pillow).

Updates `pillow` from 12.2.0 to 12.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/python-pillow/Pillow/releases">pillow's
releases</a>.</em></p>
<blockquote>
<h2>12.3.0</h2>
<p><a
href="https://pillow.readthedocs.io/en/stable/releasenotes/12.3.0.html">https://pillow.readthedocs.io/en/stable/releasenotes/12.3.0.html</a></p>
<h2>Removals</h2>
<ul>
<li>Remove non-image ImageCms modes <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9697">#9697</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
</ul>
<h2>Documentation</h2>
<ul>
<li>Add release notes for SBOM and performance improvements <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9747">#9747</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Add security release notes <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9741">#9741</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Add release notes for Python 3.15 beta wheels <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9696">#9696</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>ImageFont can also be used with ImageText <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9597">#9597</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Additional guidelines for security reports <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9659">#9659</a>
[<a
href="https://github.com/wiredfool"><code>@​wiredfool</code></a>]</li>
<li>Fixed typo <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9636">#9636</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Added CVEs to 12.2.0 release notes <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9591">#9591</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Revise development support information in README <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9583">#9583</a>
[<a
href="https://github.com/aclark4life"><code>@​aclark4life</code></a>]</li>
<li>Add INCIDENT_RESPONSE.md <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9555">#9555</a>
[<a
href="https://github.com/aclark4life"><code>@​aclark4life</code></a>]</li>
<li>Add STRIDE threat model to security docs <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9562">#9562</a>
[<a
href="https://github.com/aclark4life"><code>@​aclark4life</code></a>]</li>
<li>Add CVEs to 12.2.0 release notes <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9556">#9556</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Update README with revised security policy <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9553">#9553</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Update security policy <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9552">#9552</a>
[<a
href="https://github.com/aclark4life"><code>@​aclark4life</code></a>]</li>
<li>Update macOS tested Python versions <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9534">#9534</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
</ul>
<h2>Dependencies</h2>
<ul>
<li>Update dependency harfbuzz to v14.2.1 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9720">#9720</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update dependency mypy to v2 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9653">#9653</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update dependency cibuildwheel to v4 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9665">#9665</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update github-actions <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9655">#9655</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update dependency libavif to v1.4.2 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9652">#9652</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update dependency lcms2 to v2.19.1 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9651">#9651</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update dependency check-jsonschema to v0.37.2 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9650">#9650</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update google/oss-fuzz digest to d872252 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9614">#9614</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update dependency lcms2 to v2.19 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9609">#9609</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update dependency libpng to v1.6.58 - autoclosed <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9608">#9608</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update dependency harfbuzz to v14 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9610">#9610</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update dependency mypy to v1.20.2 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9599">#9599</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update github-actions <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9611">#9611</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Update dependency cibuildwheel to v3.4.1 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9607">#9607</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
<li>Move dependency versions to single JSON and enable Renovate <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9559">#9559</a>
[<a href="https://github.com/hugovk"><code>@​hugovk</code></a>]</li>
<li>Updated raqm to 0.10.5 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9557">#9557</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Update dependency cibuildwheel to v3.4.0 <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9532">#9532</a>
[@<a href="https://github.com/apps/renovate">renovate[bot]</a>]</li>
</ul>
<h2>Testing</h2>
<ul>
<li>Remove matrix.os from benchmark <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9735">#9735</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Remove references to libavif patch <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9734">#9734</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
<li>Add benchmark tests <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9654">#9654</a>
[<a href="https://github.com/akx"><code>@​akx</code></a>]</li>
<li>Use reshape() instead of setting NumPy array shape directly <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9728">#9728</a>
[<a
href="https://github.com/radarhere"><code>@​radarhere</code></a>]</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/python-pillow/Pillow/commit/bb1d8e8ab8d29048624d96e3ee53cecf7c13d13d"><code>bb1d8e8</code></a>
12.3.0 version bump</li>
<li><a
href="https://github.com/python-pillow/Pillow/commit/e63fc481dc2e07e21d5403deafb8f1ed98a513af"><code>e63fc48</code></a>
Add release notes for SBOM and performance improvements (<a
href="https://redirect.github.com/python-pillow/Pillow/issues/9747">#9747</a>)</li>
<li><a
href="https://github.com/python-pillow/Pillow/commit/13b701bbab291eec4bc87ea17ba06c94e5fe3054"><code>13b701b</code></a>
Add release notes for <a
href="https://redirect.github.com/python-pillow/Pillow/issues/9679">#9679</a></li>
<li><a
href="https://github.com/python-pillow/Pillow/commit/5564ca72fcd59d040e270af5dcf17a0d7161c364"><code>5564ca7</code></a>
List methods</li>
<li><a
href="https://github.com/python-pillow/Pillow/commit/a0920fd384f800b5d0ba3dd29ecdeae4f1d4043b"><code>a0920fd</code></a>
Speed up ImageChops operations (<a
href="https://redirect.github.com/python-pillow/Pillow/issues/9738">#9738</a>)</li>
<li><a
href="https://github.com/python-pillow/Pillow/commit/07e9a6cd5336dc6cf8cae9165cd70cdd2b3e42fc"><code>07e9a6c</code></a>
Speed up <code>Image.filter()</code> (<a
href="https://redirect.github.com/python-pillow/Pillow/issues/9736">#9736</a>)</li>
<li><a
href="https://github.com/python-pillow/Pillow/commit/a94578cf9649ea13e426cf7fb2b71b39ffc0dd50"><code>a94578c</code></a>
Speed up <code>Image.getchannel()</code>, <code>Image.merge()</code>,
<code>Image.putalpha()</code> and `Image...</li>
<li><a
href="https://github.com/python-pillow/Pillow/commit/53e02c43c919d149b2a154a5180079f9df18fbbb"><code>53e02c4</code></a>
Speed up <code>Image.fill()</code>, <code>Image.linear_gradient()</code>
and `Image.radial_gradient...</li>
<li><a
href="https://github.com/python-pillow/Pillow/commit/af037475be8634ba739744243164ba9e2c8346a6"><code>af03747</code></a>
Speed up <code>Image.resample()</code> (<a
href="https://redirect.github.com/python-pillow/Pillow/issues/9739">#9739</a>)</li>
<li><a
href="https://github.com/python-pillow/Pillow/commit/5c9ca56c3e5fba52b647809fbb0986c87e73a571"><code>5c9ca56</code></a>
Speed up <code>alpha_composite</code>, <code>matrix</code>,
<code>negative</code>, <code>quantize</code> (<a
href="https://redirect.github.com/python-pillow/Pillow/issues/9740">#9740</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/python-pillow/Pillow/compare/12.2.0...12.3.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pillow&package-manager=uv&previous-version=12.2.0&new-version=12.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/Stirling-Tools/Stirling-PDF/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-29 09:13:22 +00:00
Anthony Stirling 8de94ff152 Ai customization settings (#7069)
# Description of Changes
AI settings customisation in settings menu, as part of this also tested
and fixed ollama and other 3rd party AI integrations

- Adds an admin AI settings UI for customizing AI behaviour, including
per-provider model and API-key configuration
- Backend pushes AI config changes to the Python engine at runtime via a
config-push bridge, so changes apply without a restart
- Config-push is gated off in SaaS; engine now drains background tasks
on shutdown instead of cancelling them
---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-07-23 08:29:06 +00:00
dependabot[bot] 43a6ff3066 build(deps): bump mcp from 1.26.0 to 1.28.1 in /engine in the uv group across 1 directory (#7114)
Bumps the uv group with 1 update in the /engine directory:
[mcp](https://github.com/modelcontextprotocol/python-sdk).

Updates `mcp` from 1.26.0 to 1.28.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/modelcontextprotocol/python-sdk/releases">mcp's
releases</a>.</em></p>
<blockquote>
<h2>v1.28.0</h2>
<h2>Deprecations</h2>
<p>Two API surfaces now emit <code>DeprecationWarning</code> ahead of
their removal in v2. Nothing is removed in 1.x, and the warnings fire
only when the deprecated API is <em>called</em> - importing the modules
stays silent.</p>
<ul>
<li><strong>WebSocket transport</strong> -
<code>mcp.client.websocket.websocket_client</code> and
<code>mcp.server.websocket.websocket_server</code><code>modelcontextprotocol/typescript-sdk#1783</code></li>
<li><strong>Experimental tasks API</strong> -
<code>ClientSession.experimental</code>,
<code>Server.experimental</code>,
<code>ServerSession.experimental</code>, and the
<code>experimental_task_handlers=</code> kwarg on
<code>ClientSession</code>. Tasks (SEP-1686) were removed from the MCP
specification and are expected to return as a separate MCP
extension.</li>
</ul>
<p>If your test suite runs with <code>filterwarnings =
[&quot;error&quot;]</code> and exercises these paths, add a scoped
ignore such as <code>ignore:The experimental tasks API is
deprecated:DeprecationWarning</code> or <code>ignore:The WebSocket .*
transport is deprecated:DeprecationWarning</code>.</p>
<p>See <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/issues/2828">#2828</a>
for full details.</p>
<h2>What's Changed</h2>
<ul>
<li>[v1.x] Support Python 3.14 by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2769">modelcontextprotocol/python-sdk#2769</a></li>
<li>fix: omit null optional fields from task result payloads by <a
href="https://github.com/liuzemei"><code>@​liuzemei</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2809">modelcontextprotocol/python-sdk#2809</a></li>
<li>[v1.x] Deprecate the WebSocket transport and the experimental tasks
entry points by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2828">modelcontextprotocol/python-sdk#2828</a></li>
<li>[v1.x] Add a v2 status banner to the README by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2835">modelcontextprotocol/python-sdk#2835</a></li>
<li>[v1.x] Deflake the child process cleanup tests by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2839">modelcontextprotocol/python-sdk#2839</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/liuzemei"><code>@​liuzemei</code></a>
made their first contribution in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2809">modelcontextprotocol/python-sdk#2809</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.2...v1.28.0">https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.2...v1.28.0</a></p>
<h2>v1.27.2</h2>
<h2>What's Changed</h2>
<ul>
<li>[v1.x] ci: deploy docs to py.sdk.modelcontextprotocol.io via Pages
artifact by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2635">modelcontextprotocol/python-sdk#2635</a></li>
<li>[v1.x] Add subject and claims to AccessToken by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2690">modelcontextprotocol/python-sdk#2690</a></li>
<li>[v1.x] Bind transport sessions to the authenticated principal by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2719">modelcontextprotocol/python-sdk#2719</a></li>
<li>[v1.x] Scope experimental tasks to the session that created them by
<a href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2720">modelcontextprotocol/python-sdk#2720</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.1...v1.27.2">https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.1...v1.27.2</a></p>
<h2>v1.27.1</h2>
<h2>What's Changed</h2>
<ul>
<li>[v1.x] fix: catch PydanticUserError when generating output schema
(pydantic 2.13 compat) by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2435">modelcontextprotocol/python-sdk#2435</a></li>
<li>[v1.x] fix(auth): coerce empty-string optional URL fields to None in
OAuthClientMetadata by <a
href="https://github.com/felixweinberger"><code>@​felixweinberger</code></a>
in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2405">modelcontextprotocol/python-sdk#2405</a></li>
<li>[v1.x] build: restrict httpx to &lt;1.0.0 by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2559">modelcontextprotocol/python-sdk#2559</a></li>
<li>[v1.x] refactor: import SSEError from httpx_sse public API by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2561">modelcontextprotocol/python-sdk#2561</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.0...v1.27.1">https://github.com/modelcontextprotocol/python-sdk/compare/v1.27.0...v1.27.1</a></p>
<h2>v1.27.0</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: remove unused <code>requests</code> dependency from
simple-chatbot example by <a
href="https://github.com/maxisbey"><code>@​maxisbey</code></a> in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/1959">modelcontextprotocol/python-sdk#1959</a></li>
<li>ci: backport conformance tests from main to v1.x by <a
href="https://github.com/felixweinberger"><code>@​felixweinberger</code></a>
in <a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/pull/2068">modelcontextprotocol/python-sdk#2068</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/modelcontextprotocol/python-sdk/commit/777b8d06710c140e3606b0d4598e2aa48546c266"><code>777b8d0</code></a>
[v1.x] Support TransportSecuritySettings in the WebSocket server
transport (#...</li>
<li><a
href="https://github.com/modelcontextprotocol/python-sdk/commit/47204674fb26185c2cf45f065831f27b8e5d5c65"><code>4720467</code></a>
[v1.x] Set Development Status classifier to Production/Stable (<a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/issues/2976">#2976</a>)</li>
<li><a
href="https://github.com/modelcontextprotocol/python-sdk/commit/6df3d734265eb49bf758a5e5eb420937337184e9"><code>6df3d73</code></a>
[v1.x] Buffer per-request StreamableHTTP streams; store priming event
before ...</li>
<li><a
href="https://github.com/modelcontextprotocol/python-sdk/commit/32d32908feb7b15eddeb46872774bf95869cc5f0"><code>32d3290</code></a>
[v1.x] Pass a list to parametrize in test_docs_examples (pytest 9.1.0
compat)...</li>
<li><a
href="https://github.com/modelcontextprotocol/python-sdk/commit/0dca751056dc87d04893d53af129fd00b56a18da"><code>0dca751</code></a>
[v1.x] Deflake the child process cleanup tests (<a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/issues/2839">#2839</a>)</li>
<li><a
href="https://github.com/modelcontextprotocol/python-sdk/commit/52258a95645c66fccbe925289c3382712b9bc68a"><code>52258a9</code></a>
[v1.x] Add a v2 status banner to the README (<a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/issues/2835">#2835</a>)</li>
<li><a
href="https://github.com/modelcontextprotocol/python-sdk/commit/b8f491724c45dbf89d6569364b58d6e8d25d7e42"><code>b8f4917</code></a>
[v1.x] Deprecate the WebSocket transport and the experimental tasks
entry poi...</li>
<li><a
href="https://github.com/modelcontextprotocol/python-sdk/commit/2309e5ef974062748e0268c396eba73cfdb6f5e3"><code>2309e5e</code></a>
fix: omit null optional fields from task result payloads (<a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/issues/2809">#2809</a>)</li>
<li><a
href="https://github.com/modelcontextprotocol/python-sdk/commit/494eb11d36b4238226cc0551da6015e1c73f7f3b"><code>494eb11</code></a>
[v1.x] Support Python 3.14 (<a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/issues/2769">#2769</a>)</li>
<li><a
href="https://github.com/modelcontextprotocol/python-sdk/commit/62137874ff26dd74d2fea80ff528a7fd9ca7a5e7"><code>6213787</code></a>
[v1.x] Scope experimental tasks to the session that created them (<a
href="https://redirect.github.com/modelcontextprotocol/python-sdk/issues/2720">#2720</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/modelcontextprotocol/python-sdk/compare/v1.26.0...v1.28.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mcp&package-manager=uv&previous-version=1.26.0&new-version=1.28.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/Stirling-Tools/Stirling-PDF/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 08:15:15 +00:00
Ludy 0be0c0839b build(docker): pin container base images by digest for reproducible builds (#6797)
# Description of Changes

### What was changed

- Updated `BASE_VERSION` references in:
  - `docker/backend/Dockerfile`
  - `docker/embedded/Dockerfile`
  - `docker/embedded/Dockerfile.fat`
- Pinned `stirlingtools/stirling-pdf-base:1.0.2` to a specific SHA256
digest.
- Pinned the `eclipse-temurin:25-jre-noble` image used in the
`jar-extract` stage to a specific SHA256 digest.
- Pinned the `ghcr.io/astral-sh/uv:python3.13-bookworm-slim` image in
`engine/Dockerfile.dev` to a specific SHA256 digest.
- Removed reliance on mutable image tags alone for these build stages.

### Why the change was made

- Ensure deterministic and reproducible Docker builds.
- Prevent unexpected changes caused by upstream image tag updates.
- Improve supply chain integrity by explicitly defining the exact image
artifacts used during builds.
- Align container build practices with security and compliance
recommendations.

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have run `task check` to verify linters, typechecks, and tests
pass
- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-07-20 12:02:16 +00:00
Anthony Stirling bef83d80a1 Patch CVEs in engine Python dependencies (#6804)
# Description of Changes

- Patch CVEs in engine Python dependencies (43 alerts): `starlette`
1.3.1, `cryptography` 49.0.0, `pyjwt` 2.13.0, `urllib3` 2.7.0, `aiohttp`
3.14.1, `python-multipart` 0.0.32, `langchain-core` 1.4.8, `langsmith`
0.9.1, `authlib` 1.7.2, `requests` 2.34.2, `idna` 3.18, `pytest` 9.1.1,
`pygments` 2.20.0, `pydantic-settings` 2.14.2
- Cap `pydantic-ai` `<2.0.0` and bump to 1.107.0 (1.99.0 patches
CVE-2026-46678; 2.0 is a separate major migration)

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs (if functionality has heavily
changed)
- [ ] I have read the section Add New Translation Tags (for new
translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally
2026-07-15 14:49:33 +00:00
EthanHealy01 7f01bcdc44 Classifier setup as a processor policy (#7012)
## Overview

Adds a **Classification policy** to the processor's policy catalogue,
set up the same way as the Security policy. This moves classifier
configuration out of the editor (where the labels UI landed in #6898 and
was then removed with the rest of the editor's policy-management surface
in #6932) and into the processor, which is now the single place policies
are configured.

## What it does

- **Classification card** in the processor policy catalogue. Always
shown, but **setup is locked until the backend reports the AI engine is
on** — so admins can see the capability they're missing rather than it
being hidden entirely.
- **Setup wizard** mirrors Security: the workflow step shows the team's
**classification label editor** (reused
`LabelsEditor`/`LabelsEditorModal` — add box, chip grid, per-label icon
picker, import/export, reset) instead of tool toggles, since classify is
a single non-configurable step.
- On enable, the team's label vocabulary is **seeded with the 268
built-in defaults** (clobber-safe: only when the team has none). On
upload the document is classified against the team's labels and tagged;
on SaaS with the engine on, files group by category in the editor
sidebar.

## Reuse & consolidation

- Reuses the existing labels table, `labelsFile` helpers, and default
vocabulary. Labels read/write through the processor's own
`apiClient.local` (not the editor's axios client) so auth/base routing
stays explicit; the wire shape is shared.
- Consolidates policy-category icons into a shared, **id-keyed**
`policyCategoryIcon` util (outline glyphs) used by both the editor and
the processor, replacing the processor's emoji-glyph map (and the stray
`schedule` key that rendered a bare dot).

## Testing

- `task frontend:typecheck:{core,proprietary,portal}`,
`frontend:lint:eslint`, `frontend:test` (156 files / 1305 tests) — all
green.
- Verified in Storybook: the Classification card renders, the setup
wizard shows the label editor (268 defaults), and the full labels editor
opens with icons/import/export/reset. Added an MSW handler for the
app-config + labels endpoints and a `Classification` wizard story.

## Notes for reviewers

- The AI-engine gate reads the public `/api/v1/config/app-config`;
classification labels use `/api/v1/classification/labels` (team-scoped,
team-lead/admin-gated, `policies.enabled`); the classify step hits
`/api/v1/ai/tools/classify-and-label` — all pre-existing backend from
#6898.
- Known parity behavior (matches the editor hook): a transient failure
loading team labels falls back to showing the defaults; not changed here
to avoid diverging the two hooks.
2026-07-15 11:04:30 +00:00
EthanHealy01 0570c4c4d9 Create-PDF engine: render from a structured document (#7018) 2026-07-14 12:30:33 +00:00
James Brunton 38d06d3104 Make sqlite backend more resilient when using multiple runners (#6971) 2026-07-11 12:47:29 +01:00
EthanHealy01 c64369e56c Classifier Policy (#6898)
## Overview

Adds **AI document classification** and a **classification-aware Files
sidebar**: uploaded documents are automatically tagged with
document-type labels (Invoice, Contract, Lab report, …), and the sidebar
groups files under editable parent categories so a large library stays
navigable.

> [!IMPORTANT]
> **This feature only runs in the SaaS build.** Classification depends
on the AI engine and team-scoped label storage, so it's gated to SaaS
end-to-end:
> - The sidebar grouping is a `saas/`-layer override of the
`fileSidebarGrouping` seam; every other build (OSS core, self-hosted
proprietary, desktop) gets the null stub and renders the **unchanged
flat, recency-sorted list** — no categories, no "Other", no picker.
> - The classify/labels backend endpoints are gated on
`policies.enabled` (on in SaaS) and live in `app/proprietary`, so
they're absent from pure OSS and dormant in self-hosted unless
explicitly enabled.
> - The Python classifier is reached only via that gated path.
>
> Shared-layer changes that do compile everywhere are inert without the
engine (dormant schema/field additions) or intentional (`GetInfoOnPDF`
surfacing custom metadata).

## What it does

- **Classifier (engine):** reads the first/last two pages of a PDF and
assigns document-type labels from an allowed vocabulary. Labels are
deliberately document-*type* descriptors — no deep-content/PII
detection, since only a page window is read.
- **Team label vocabulary:** ~270 built-in defaults across ~15 families,
seeded per team. Editable by team leaders/admins in the Classification
policy settings (import/export/reset). Team-scoped and shared;
**per-user personal labels are intentionally out of scope** — the
vocabulary is team-level only.
- **Sidebar categories:** files group under parent categories
(Financial, Legal, Medical, …), busiest-first, collapsible, with a
"Recent" group on top and an "Other" group for anything uncategorised.
The category structure (names, icons, membership, custom categories) is
**device-local and user-editable** via a "Customize" picker — the only
per-user personalization; it never changes the team's label vocabulary.
- Classification results are written to PDF metadata
(`StirlingPDFClassification`), read back to keep files in their groups
without re-parsing.

## Architecture

Spans all three layers, mirroring the existing policy/source subsystem
conventions:
- **`frontend/editor`** — sidebar grouping seam + SaaS override,
category manager, labels editor, icon palette, file grouping, tests,
`en-US` i18n.
- **`app/proprietary` + `app/common` + `app/core`** —
`ClassifyLabelController`, team-scoped `ClassificationLabelStore` (Jpa +
in-process impls, same shape as `PolicyStore`/`SourceStore`), metadata
read/write.
- **`engine`** — the document-classifier agent, contracts, routes,
tests.

## Screenshots

**Files sidebar — grouped by category (SaaS)**

### Loading view

<img width="2056" height="1046" alt="Screenshot 2026-07-07 at 5 12
56 PM"
src="https://github.com/user-attachments/assets/1d712da5-50ae-4349-b0cd-e62665c3ec0c"
/>

### Organized in the sidebar

<img width="2056" height="1045" alt="Screenshot 2026-07-07 at 5 14
05 PM"
src="https://github.com/user-attachments/assets/3ea4fe21-da51-4cea-bc3a-18ce040d3d05"
/>

**Customize categories picker**
### Personal settings to change how labels are grouped in an individual
users editor

<img width="2056" height="1044" alt="Screenshot 2026-07-07 at 5 52
42 PM"
src="https://github.com/user-attachments/assets/40be03ce-0f63-4d1e-b58b-cec045d01cb2"
/>

**Classification labels editor (team settings)**

<img width="2056" height="1042" alt="Screenshot 2026-07-07 at 5 53
00 PM"
src="https://github.com/user-attachments/assets/337b0739-15c9-4749-9c6b-22e3b20825b8"
/>

## Testing

- Frontend `task frontend:check` — green (editor + portal tests,
typecheck across all flavors, lint, label-drift guard).
- Backend `task backend:check` (proprietary) and `:saas:test` — green.
- Engine `task engine:check` — green.
2026-07-09 11:47:37 +00:00
James Brunton 20204f0ddc Improve consistency and reliability of tools in Stirling Engine (#6855)
# Description of Changes
A few changes to improve things in the engine:
- Changed the PDF to Markdown code to be a real tool in Java, to remove
the need for the `pdf_ingest` code, which looked a bit like an agent but
wasn't behaving as an agent. It's now just covered automatically by the
edit agent.
- Noticed that 0-parameter-endpoints were previously being ignored by
the `tool_models` generator, so some tools which require no params were
being mistakenly excluded.
- Removed tools which currently never succeed like Add Stamp, Cert Sign,
and Overlay, because they require the supporting files to be sent in a
different location in the API call, which we don't currently do.
Ideally, we'd add proper support for this, but we're better off now
removing support for these tools rather than just have them crash. We
can re-add these tools in a future PR properly.
2026-07-07 11:01:18 +00:00
James Brunton b4f7b1d8a9 Add bidirectional API types to frontend (#6867)
# Description of Changes
Fix https://github.com/Stirling-Tools/Stirling-PDF-SaaS/issues/281. Add
generated backend API mappings to the frontend code, and the logic to
convert from a backend API to frontend parameters objects.

Previously, it was impossible to tell if changing the backend API would
require a change to the frontend to support it because the frontend had
no static type information about the backend API. This PR adds
autogenerated tool API types to the frontend (in `toolApiTypes.ts`) and
adds explicit typed mappings between the frontend parameter types and
the backend API types, so theoretically the type checker should be able
to catch issues when changing one puts us in an invalid state with the
other. During development, it pointed out several inconsistencies that
we have between the frontend and backend types, some of which were
genuine bugs, and others were only happening to work because the backend
is more permissive than its API claims to be.

This also unlocks the ability for us to render the frontend settings on
saved backend API structures, which we've previously had to avoid doing
because we had no reverse mapping.
2026-07-07 07:47:07 +00:00
Anthony Stirling ff3e3bd0fc Add desktop hardware token signing and trust-aware signature validation (#6765)
# Description of Changes

<img width="432" height="800" alt="image"
src="https://github.com/user-attachments/assets/a01ed9ac-220c-4911-9134-b51e0f321be8"
/>

<img width="408" height="859" alt="image"
src="https://github.com/user-attachments/assets/a9c285b6-5b75-493a-95ec-09e08d0f58f1"
/>

<img width="426" height="874" alt="image"
src="https://github.com/user-attachments/assets/a60db96e-be93-4cc5-ba0a-63512c2857ba"
/>

<img width="356" height="1076" alt="image"
src="https://github.com/user-attachments/assets/24d03674-94d3-40ed-99ee-73395bafae6a"
/>


---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-06-30 23:23:58 +01:00
James Brunton 04d68c650a Merge remote-tracking branch 'origin/main' into saas-update
# Conflicts:
#	engine/src/stirling/documents/pgvector_store.py
2026-06-15 14:10:21 +01:00
Anthony Stirling d6a5777c69 Fix pgvector (#6591) 2026-06-15 13:09:40 +01:00
James Brunton d995471a55 Merge remote-tracking branch 'origin/main' into SaaS-update
# Conflicts:
#	frontend/editor/src/proprietary/components/chat/ChatContext.tsx
#	frontend/editor/src/saas/components/shared/TrialStatusBanner.tsx
2026-06-12 09:58:40 +01:00
Anthony Stirling d48017a5b5 Skip engine free-port probe in containers (fixed port) 2026-06-11 20:18:54 +01:00
James Brunton d52c7ced7c Improvements to Stirling Engine to prepare for SaaS release (#6603)
# Description of Changes
- Use pool for postgres connections
- Add ability to require user ID to be set on API calls to the engine
- Add process-wide concurrency cap on AI access (in addition to existing
user caps)
- Allow number of workers (threads) to be specified for stirling engine
- Update env var names to reflect that the DB is not just for RAG
2026-06-11 16:31:35 +01:00
EthanHealy01andAnthony Stirling 88adb7adad create agent (#6520)
Added the create agent. Use [these
prompts](https://github.com/Stirling-Tools/Stirling-PDF-SaaS/blob/main/docgen/backend/default_templates/sample_prompts.md)
to test or try your own :)

Here’s the one I use

```
Hey, I need to generate an employee expense report for reimbursement.
Company: Summit Consulting Partners Company address: 88 Riverside Plaza, Suite 1400, New York, NY 10069 Accounting department email: expenses@example.com
Employee details:
* Employee Name: Michael Tran
* Employee ID: EMP-1047
* Department: Client Services
* Report Date: January 20th, 2026
* Reporting Period: January 5th, 2026 – January 16th, 2026
* Manager Approver: Laura Simmons
Trip purpose: Client onsite meetings with Atlantic Energy Solutions in Boston, MA.
Expense items:
* Flight (NYC to Boston roundtrip) — $325.40 — January 5th, 2026 — Airline ticket
* Hotel (3 nights at Harborview Hotel) — $822.75 — January 5th-8th, 2026
* Taxi from airport to hotel — $48.00 — January 5th, 2026
* Client dinner (3 attendees) — $186.20 — January 6th, 2026
* Parking at JFK Airport — $72.00 — January 5th-8th, 2026
* Breakfast (per diem not used) — $18.50 — January 7th, 2026
* Uber to client office — $22.10 — January 7th, 2026
* Printing + presentation materials — $46.90 — January 8th, 2026
* Lunch with client — $39.75 — January 8th, 2026
* Office supplies (notebooks, pens) — $27.60 — January 10th, 2026
* Mileage reimbursement (client visit in NJ, 42 miles @ $0.67/mile) — $28.14 — January 14th, 2026
* Team lunch meeting (internal) — $64.30 — January 15th, 2026
Reimbursement method should be direct deposit.
Add a notes section stating: "All receipts attached. Expenses are business-related and comply with company travel policy."
```

---------

Co-authored-by: Anthony Stirling <77850077+frooodle@users.noreply.github.com>
2026-06-11 14:18:13 +00:00
Anthony Stirling 9a1804ce04 Merge branch 'main' into SaaS 2026-06-10 14:58:44 +01:00
EthanHealy01 5fca2f199a Feature/pdf ingestion jpdfium (#6525) 2026-06-10 14:51:41 +01:00
Anthony Stirling 2101b4028c Merge branch 'main' into SaaS 2026-06-10 11:42:25 +01:00
Anthony Stirling 3ecd95b779 Add MCP server with OAuth/API-key auth (#6570)
Adds an optional MCP server (proprietary module) that exposes Stirling's
PDF operations and AI capabilities to MCP clients. Off by default, zero
footprint when disabled.

### What
- New `/mcp` endpoint: streamable-HTTP + JSON-RPC 2.0; 8 tools
(describe_operation, pages/convert/misc/security category tools, AI,
upload, download).
- Runs real operations over an internal loopback; results returned
inline as base64 (small) or by fileId (large).

### Auth (two modes)
- OAuth2 resource server: RFC 9728 protected-resource metadata, RFC 8707
audience binding, JWKS, `mcp.tools.read/write` scopes; binds each token
to a provisioned Stirling account.
- API-key mode: reuses Stirling per-user `X-API-KEY` (no IdP needed).

### Security
- Per-user file ownership in FileStorage: async/queued writes scoped to
the submitting user; legacy/owner-less files stay readable.
- Admin allow/block list controls which operations are exposed.
- Python engine gated behind a shared secret (`X-Engine-Auth`).
- MCP filter chain is isolated and cannot weaken the main app's
security.
- Hardened: no upstream error-body leakage, log injection sanitized,
fileId path/sidecar enumeration blocked.

### Config / footprint
- Disabled by default (`mcp.enabled=false`); all beans
`@ConditionalOnProperty`.
---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
2026-06-10 09:46:25 +00:00
Anthony Stirling 1d5ce8a1d2 chore: shorten verbose block comments across SaaS branch 2026-06-08 18:38:00 +01:00
Anthony Stirling 8b2baaf0a0 Merge remote-tracking branch 'origin/saas-docker-split' into SaaS 2026-06-08 18:10:02 +01:00
Anthony Stirling d9651f7065 fix(engine): match Dockerfile layout to root Taskfile dir: engine 2026-06-08 18:02:02 +01:00
EthanHealy01andJames Brunton 35a712a278 smart redaction (#6195)
Co-authored-by: James Brunton <jbrunton96@gmail.com>
2026-06-03 16:16:33 +00:00
James Brunton 1264f4cfed Set up document management for Stirling Engine (#6476)
# Description of Changes
Change Stirling Engine to support deleting documents automatically. This
happens both on user logout and after an amount of time specified by the
Java when ingesting a document (allowing for personal documents to have
short lifetimes but org documents to be left in the db with no expiry
date). Also sets up an [ACL
policy](https://en.wikipedia.org/wiki/Access-control_list) for the
documents so the database knows which users have access to which
documents. This is not fully implemented in the Java, so currently all
docs are treated as having a single owner, the uploader, but
theoretically when we need to support org storage, we shouldn't need to
change the db schema.
2026-06-03 11:52:11 +00:00
Anthony StirlingandConnorYoh 8bd78d2624 Add landscape page size options (#6248)
# Description of Changes

Adds orientation (portrait/landscape) to the Adjust Page Scale tool.

- Orientation as a separate parameter (per review), sent through to the
backend
- ScalePagesController simplified; PDFWithPageSize gains the orientation
field
- Regenerated tool_models.py; frontend + backend tests added

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.

---------

Co-authored-by: ConnorYoh <40631091+ConnorYoh@users.noreply.github.com>
2026-05-28 14:16:15 +00:00
ConnorYoh 017c8d59fa feat(ai): add Contradiction Agent on a new ChunkedMapper primitive (#6369)
## Summary

Adds a new AI specialist that finds **textual contradictions** across
one or more PDFs — conflicting claims, recommendations, points of view,
contested facts — built entirely in Python on top of the new
`DocumentService` + `ChunkedReasoner` stack from #6314. Replaces the
closed #6304, which was started before #6314 landed and therefore
over-engineered (Java orchestrator, two-round handshake, resume
artifact, discriminated-union lift).

Two commits:
1. **`refactor(engine): extract ChunkedMapper[T] from ChunkedReasoner`**
— pure refactor, public API of ChunkedReasoner unchanged. New
`ChunkedMapper[T: BaseModel]` is a generic parallel-chunk primitive
(slicing, semaphore, time-bounded extraction, cancellation drain,
progress events) that's now a peer to ChunkedReasoner rather than locked
inside it. The compression loop stays on ChunkedReasoner where it
belongs.
2. **`feat(ai): add Contradiction Agent on ChunkedMapper`** — the agent
itself, plus integrations into `PdfReviewAgent` and `PdfQuestionAgent`.

## Architecture

- **Python-only.** No Java code. No `AgentToolId.CONTRADICTION_AGENT`.
No dedicated HTTP endpoint. No resume artifact, no discriminated-union
lift in `contracts/common.py`. Detector runs inside the Python engine
and the Python engine alone.
- **Review path** (`PdfReviewAgent`): a new
`ContradictionIntentClassifier` fires on contradiction-flavoured
prompts; agent runs detection synchronously and emits a single
`EditPlanResponse(steps=[ADD_COMMENTS])`. Single-turn flow — no resume.
- **Question path** (`PdfQuestionAgent`): a new
`ContradictionCapability` joins `RagCapability` and
`WholeDocReaderCapability` in the smart-model toolset, exposing
`find_contradictions(query)`. The smart model picks it from the toolset
alongside `search_knowledge` and `read_full_document`.

## Inside `ContradictionDetector.detect()`

1. `DocumentService.read_pages(file_id)` → ordered `list[Page]`.
2. `ChunkedMapper[_ExtractedClaims].map_pages(...)` — char-budgeted
multi-page slicing; each slice runs the claim-extractor LLM in parallel
under a semaphore.
3. Page-traceability: the extractor returns `_ExtractedClaim.page`
(which `[Page N]` marker the claim came from). The wrapper validates
`page ∈ chunk.pages`; if not, mechanical fallback searches the chunk's
page text for the verbatim quote and reassigns. If still no match, drop
the claim.
4. `Claim.anchor_quality: Literal[\"verbatim\", \"paraphrased\"]` is set
by a substring check against the declared page's text. Verbatim quotes
feed `anchor_text` for snap-to-quote add-comments placement; paraphrased
ones fall back to margin geometry.
5. Subject canonicalisation: ONE fast-model LLM call collapses synonyms
across the document. Fails open to lexical bucketing.
6. Pre-filters: drop identical-quote pairs; drop same-page same-polarity
paraphrases.
7. Per-bucket pair detection in parallel (separate semaphore, cap 5).
Buckets > 12 claims chunk into windows of 12 with overlap 2; pairs
deduped across overlapping windows by frozen `(i, j)` index pair.
8. Summary fast-model call with fallback string on error.

## Prompt-injection hardening

Every prompt that interpolates user-supplied or PDF-extracted text wraps
content in `<user_message>` / `<verdict>` / `<content>` tags with an
explicit SECURITY preamble instructing the model to treat tagged content
as data only.

## Limitations

- **Combined math + contradiction intent**: when both intent classifiers
fire on the same prompt, contradiction takes precedence and the math
intent is silently dropped. Documented in the Review module docstring
and pinned by
`test_review_integration.py::test_contradiction_precedence_over_math`.
- **Cross-window contradiction reach**: within a subject bucket, pairs
more than ~10 claim indices apart in the same chunked window may be
missed by the overlap-2 strategy. Documented in `test_detector.py`.
Acceptable for v1.

## Settings (engine/src/stirling/config/settings.py)

```python
contradiction_detect_concurrency = 5     # per-bucket detector semaphore
contradiction_bucket_chunk_size = 12     # max claims per detector call
contradiction_bucket_chunk_overlap = 2   # overlap for >threshold buckets
```

`chars_per_slice` and extraction concurrency are reused from the
existing `chunked_reasoner_*` settings.

## Test plan

- [x] `uv run pytest tests/ -v` — **245/245 pass** (210 pre-existing +
35 new)
- [x] `uv run ruff check src/ tests/` — clean
- [x] `uv run pyright src/stirling/agents/contradiction/
src/stirling/contracts/contradiction.py` — 0 errors
- [x] `./gradlew :proprietary:test` — green; no Java was touched, but
verified untouched
- [x] Page-traceability tests cover: valid page kept, hallucinated page
dropped, mechanical-reassign on misattribution, anchor-quality verbatim
vs paraphrased
- [x] Review integration: ADD_COMMENTS plan with two paired CommentSpecs
per contradiction; NeedIngestResponse precheck; precedence vs math
intent pinned
- [x] Question integration: all three capabilities wired into
smart-model toolset; `find_contradictions` returns formatted report text
- [x] ChunkedMapper standalone: slicing, multi-chunk ordering, worker
failures, timeouts, cancellation drain, semaphore saturation
- [x] ChunkedReasoner regression: all pre-existing tests pass unchanged
after the internal split

## Relationship to closed #6304

#6304 was closed in favour of this PR. The closed PR predated #6314 and
modelled the agent as a Java-orchestrated two-round examine/deliberate
flow with its own HTTP endpoint and a discriminated-union resume
artifact. With #6314 making full ordered page text available to the
engine via `DocumentService.read_pages`, none of that is needed. Net
effect: drop ~600 lines of Java, drop the two-round handshake, drop the
`ToolReportArtifact` lift, while ending up with a more scalable agent
(chunk-based instead of page-based extraction; tested to
ChunkedReasoner-equivalent scale).
2026-05-22 13:23:52 +00:00
James Brunton beb99e273b Improve edit agent's knowledge of tools (#6356)
# Description of Changes
Give Edit Agent access to descriptions of the request from the Java API.
This opens the door to us better documenting our Java APIs to give the
stirling engine better knowledge of what the various tools are and how
to use them.

Also improves the tool selection sub-agent to get the tool parameters
and descriptions so it can more intelligently decide which operations
should be used to fulfil the user's request. Also provides it more
encouragement to string together multiple operations if necessary.
2026-05-14 18:30:39 +00:00
EthanHealy01andJames Brunton ece1bb6865 Feature/pdf to markdown agent (#6271)
Co-authored-by: James Brunton <jbrunton96@gmail.com>
2026-05-14 16:20:45 +00:00
James Brunton 672e81d286 Add ability for Stirling engine to reason across large documents (#6314)
# Description of Changes
Adds storage in the database for full document content alongside the RAG
content (and changes the service to `DocumentService` instead of
`RagService`). Then adds a generic capability that should be usable by
any agent (currently just used by the Question Agent) which allows the
agent to pull out the full contents of the doc, chunks it into various
sections that will fit in the context window, and then processes them in
parallel to create an intermediate result, and then processes the
intermediate result into a final answer. It will re-chunk as many times
as necessary to get the content small enough for the actual answer to be
analysed (I've tested on PDFs ~3500 pages long, which is well above the
context limit and requires maybe 3 rounds of compression to get an
answer).

The new full doc analysis stuff is heavier than the RAG lookup so both
remain. The agents should use RAG for targeted info and the chunked
reasoner for info that requires reading the full doc.
2026-05-14 13:19:38 +00:00
James BruntonandEthanHealy01 575684ee4b Add edit text support to stirling engine (#6245)
# Description of Changes
Hooks up the (alpha) PDF Editor backend to the AI engine Edit Agent via
an intermediary API which is easier for the agent to call. It suffers
from all the same issues that the PDF Editor does in actually editing
the text, but should also benefit from any fixes to that.

It also adds protection against the underlying tools misbehaving by
hanging, and fixes a hanging bug in the PDF Editor.

---------

Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
2026-05-11 09:57:41 +00:00
James BruntonandEthanHealy01 51f5345151 Inform AI engine which endpoints are disabled on the backend (#6251)
# Description of Changes
Have the Java send a list of enabled endpoints to the AI engine so it
can intelligently respond to the user that the tool does exist but is
disabled on the server so it can't acutally run the operation, instead
of the current behaviour where it sends the API call back and then 503
errors because the execution fails when the URL is disabled.

<img width="380" height="208" alt="image"
src="https://github.com/user-attachments/assets/5842fb2e-2e55-45a5-8205-25515636daae"
/>

---------

Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
2026-05-01 14:59:53 +00:00
James Brunton 5541dd666c Flesh out RAG system (#6197)
# Description of Changes
Flesh out the RAG system and connect it to the PDF Question Agent so it
can respond to questions about PDFs of an extremely large size.

I'd expect lots more work will need to be done to finish off the RAG
system to really be what we need, but this should be a reasonable start
which will let us connect it to tools and have the ingestion mostly
handled automatically. I'm leaving file deletion and proper file ID
management to be done in a future PR. We also need to consider whether
all tools should retrieve content exclusively via RAG, or whether it's
beneficial to have tools sometimes fetch the direct content and other
times fetch it from RAG.

A diagram of the expected interaction is as follows:

```mermaid
sequenceDiagram
    autonumber
    actor U as User
    participant FE as Frontend<br/>(ChatPanel)
    participant J as Java<br/>(AiWorkflowService)
    participant O as Engine:<br/>OrchestratorAgent
    participant QA as Engine:<br/>PdfQuestionAgent
    participant RAG as Engine:<br/>RagService + SqliteVecStore
    participant V as VoyageAI<br/>(embeddings)
    participant L as LLM<br/>(Claude / etc.)

    U->>FE: types "Summarise this PDF"<br/>(PDF already uploaded)
    FE->>J: POST /api/v1/ai/orchestrate/stream<br/>multipart: fileInputs[], userMessage
    Note over J: ByteHashFileIdStrategy<br/>id = sha256(bytes)[:16]
    J->>O: POST /api/v1/orchestrator<br/>{ files:[{id,name}], userMessage }

    O->>L: route via fast model
    L-->>O: delegate_pdf_question
    O->>QA: PdfQuestionRequest

    loop for each file
        QA->>RAG: has_collection(file.id)
        RAG-->>QA: false
    end
    QA-->>O: NeedIngestResponse(files_to_ingest)
    O-->>J: { outcome:"need_ingest", filesToIngest:[...] }

    Note over J: onNeedIngest
    loop per file
        J->>J: PDFBox: extract page text
        J->>O: POST /api/v1/rag/documents<br/>(long-running timeout)
        O->>RAG: chunk + stage documents
        O->>V: embed_documents (batches of 256)
        V-->>O: embeddings
        O->>RAG: add_documents
        O-->>J: { chunks_indexed: N }
    end

    Note over J: retry with resumeWith=pdf_question
    J->>O: POST /api/v1/orchestrator
    Note over O: fast-path to PdfQuestionAgent

    O->>QA: PdfQuestionRequest
    Note over QA: build RagCapability<br/>pinned to file IDs
    QA->>L: run(prompt) with search_knowledge tool

    loop up to max_searches
        L->>QA: search_knowledge(query)
        QA->>V: embed_query
        V-->>QA: query vector
        QA->>RAG: search(vector, collections=[file.id])
        RAG-->>QA: top-k chunks
        QA-->>L: formatted chunks
    end

    Note over QA: once budget spent,<br/>prepare() hides the tool
    L-->>QA: PdfQuestionAnswerResponse
    QA-->>O: answer
    O-->>J: { outcome:"answer", answer, evidence }
    J-->>FE: SSE "result"
    FE->>U: assistant bubble
```
2026-05-01 14:11:54 +01:00
ConnorYohandJames Brunton 86774d556e Pdf comment agent (#6196)
Co-authored-by: James Brunton <jbrunton96@gmail.com>
2026-05-01 10:19:38 +01:00
James Brunton 1e3da14081 Change frontend .env files to be committed and have .env.*.local overrides (#6207) 2026-04-25 13:09:59 +01:00
James Brunton 3e94157137 Add document context for edit agent (#6152)
# Description of Changes
Adds the ability for the Edit agent to request the content of the
document before it decides which parameters it needs. This makes it able
to process requests like `Split the document after the page containing
the "My Section" section`, allowing for document context-based requests
for all[^1] tools.

I had to make a few changes elsewhere to make this work, including:
- Moving the requesting of content out of the Question Agent and into a
common location
- Added specific API docs for the Split param because the generic ones
were not specific enough for the AI to be able to reliably perform the
correct operation
- Fixed an issue in the tool models generator which caused the Redact
params to only be half-generated (causing Pydantic to crash when the AI
tried to run Redact)
- Added missing logging to a bunch of tools and hooked it up properly so
it'll print to stderr
- Made the limits for the max pages/chars to extract from PDFs
configurable via env var

[^1]: Many of the tools can't actually do anything useful with the
context at this stage, but will just need the tool API to be extended
with new features like page-specific operations to be automatically able
to do smart operations without needing to change the Edit agent itself.
2026-04-23 13:19:27 +00:00
Ludy e087b54cf0 build(docker): pin base container images to immutable digests (#6173) 2026-04-23 13:31:21 +01:00
James Brunton 975f135217 Move engine/AGENTS.md into root AGENTS.md because Claude doesn't bother to read it (#6151)
# Description of Changes
Move `engine/AGENTS.md` into root `AGENTS.md` because Claude doesn't
bother to read it half the time.
2026-04-22 11:32:03 +02:00
James Brunton 3b2afe0deb Change engine/.env to be committed and have .env.local override (#6150)
# Description of Changes
We keep adding stuff to `engine/config/.env.example` and have to
manually update `.env` because of it, which is really clunky, especially
when working on multiple worktrees at once. This PR changes it so that
we just have a committed `.env` file and have an `.env.local` override
to put the actual private keys into, which should make it a bit easier
to manage.

> [!warning]
>
> After this goes in, be very careful for a little while not to
accidentally commit any keys that you've got inside your `.env` file!
2026-04-21 16:18:25 +01:00
James Brunton 2a856fbc19 Allow chat history to be sent to AI engine (#6128)
# Description of Changes
Add an extra parameter to every agent to receive the conversation
history in addition to the current message. This will make it possible
to answer followup questions from the AI without needing to give full
context in your message.
2026-04-21 15:03:10 +00:00
Anthony Stirling f779085d75 setup RAG (#6146) 2026-04-21 12:42:33 +01:00
EthanHealy01andJames Brunton 089e448cf4 allow deploypr:prototypes comment to spin up the prototypes build (#6144)
Co-authored-by: James Brunton <jbrunton96@gmail.com>
2026-04-20 18:58:33 +01:00
e5767ed58b Change AI engine to execute tools in Java instead of on frontend (#6116)
# Description of Changes
Redesign AI engine so that it autogenerates the `tool_models.py` file
from the OpenAPI spec so the Python has access to the Java API
parameters and the full list of Java tools that it can run. CI ensures
that whenever someone modifies a tool endpoint that the AI enigne tool
models get updated as well (the dev gets told to run `task
engine:tool-models`).

There's loads of advantages to having the Java be the one that actually
executes the tools, rather than the frontend as it was previously set up
to theoretically use:
- The AI gets much better descriptions of the params from the API docs
- It'll be usable headless in the future so a Java daemon could run to
execute ops on files in a folder without the need for the UI to run
- The Java already has all the logic it needs to execute the tools 
- We don't need to parse the TypeScript to find the API (which is hard
because the TS wasn't designed to be computer-read to extract the API)

I've also hooked up the prototype frontend to ensure it's working
properly, and have built it in a way that all the tool names can be
translated properly, which was always an issue with previous prototypes
of this.

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
Co-authored-by: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com>
2026-04-20 15:57:11 +01:00