clams-python 1.7.2__tar.gz → 1.7.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {clams_python-1.7.2 → clams_python-1.7.4}/CHANGELOG.md +21 -0
- {clams_python-1.7.2/clams_python.egg-info → clams_python-1.7.4}/PKG-INFO +2 -2
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/app/__init__.py +140 -39
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/app/Containerfile.template +1 -1
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/app/cli.py.template +21 -4
- {clams_python-1.7.2 → clams_python-1.7.4/clams_python.egg-info}/PKG-INFO +2 -2
- {clams_python-1.7.2 → clams_python-1.7.4}/clams_python.egg-info/requires.txt +1 -1
- {clams_python-1.7.2 → clams_python-1.7.4}/clams_python.egg-info/scm_file_list.json +67 -67
- clams_python-1.7.4/clams_python.egg-info/scm_version.json +8 -0
- clams_python-1.7.4/container/ffmpeg-torch2.containerfile +13 -0
- clams_python-1.7.4/container/opencv4-torch2.containerfile +13 -0
- clams_python-1.7.4/container/torch2.containerfile +13 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/app-baseclasses.rst +66 -1
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/clamsapp.rst +12 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/conf.py +3 -1
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/introduction.rst +1 -1
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/runtime-params.rst +9 -1
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/target-versions.csv +2 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/pyproject.toml +1 -1
- {clams_python-1.7.2 → clams_python-1.7.4}/tests/test_clamsapp.py +77 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/tests/test_envelope.py +13 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/tests/test_promptable.py +22 -0
- clams_python-1.7.2/clams_python.egg-info/scm_version.json +0 -8
- clams_python-1.7.2/container/ffmpeg-torch2.containerfile +0 -6
- clams_python-1.7.2/container/opencv4-torch2.containerfile +0 -6
- clams_python-1.7.2/container/torch2.containerfile +0 -6
- {clams_python-1.7.2 → clams_python-1.7.4}/.github/workflows/codecov.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/.github/workflows/container.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/.github/workflows/containers.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/.github/workflows/issue-assign.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/.github/workflows/issue-close.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/.github/workflows/issue-infra-project.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/.github/workflows/publish.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/.github/workflows/release-check.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/.gitignore +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/.pytype.cfg +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/CONTRIBUTING.md +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/LICENSE +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/README.md +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/build-tools/build.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/build-tools/clean.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/build-tools/docs.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/build-tools/prep_release.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/build-tools/publish.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/build-tools/test.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/appmetadata/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/backends/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/backends/hf.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/app/.dockerignore.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/app/.gitignore.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/app/LICENSE.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/app/README.md.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/app/app.py.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/app/metadata.py.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/app/requirements.txt.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/gha/for-clams-team.md.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/gha/workflows/issue-apps-project.yml.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/gha/workflows/issue-assign.yml.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/gha/workflows/issue-close.yml.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/gha/workflows/publish.yml.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/utl-tf/__init__.py.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/utl-tf/timeframe.py.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/envelop/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/restify/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/serve/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams/ver/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams_python.egg-info/SOURCES.txt +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams_python.egg-info/dependency_links.txt +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams_python.egg-info/entry_points.txt +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/clams_python.egg-info/top_level.txt +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/Containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/ffmpeg-hf.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/ffmpeg-hf4.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/ffmpeg-hf5.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/ffmpeg-tf2.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/ffmpeg.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/generate_containers_yml.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/hf.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/hf4.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/hf5.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/jdk8.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/opencv4-hf.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/opencv4-hf4.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/opencv4-hf5.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/opencv4-tf2.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/opencv4.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/container/tf2.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/appdirectory.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/appmetadata.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/autodoc/clams.app.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/autodoc/clams.appmetadata.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/autodoc/clams.backends.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/autodoc/clams.mmif_utils.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/autodoc/clams.restify.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/cli.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/gpu-apps.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/index.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/input-output.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/modules.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/documentation/tutorial.md +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/setup.cfg +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/tests/metadata.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/tests/pillow-logo.png +0 -0
- {clams_python-1.7.2 → clams_python-1.7.4}/tests/test_backends_hf.py +0 -0
|
@@ -1,4 +1,25 @@
|
|
|
1
1
|
|
|
2
|
+
## releasing 1.7.3 (2026-07-09)
|
|
3
|
+
### Overview
|
|
4
|
+
This patch includes critical bugfixes. See changes below.
|
|
5
|
+
|
|
6
|
+
### Changes
|
|
7
|
+
* fixes handling of error during `annotate()` (and `_annotate()`) when running an app via cli.py (#297)
|
|
8
|
+
* added the `useReasoning` common parameter for promptable apps (#299) Note that release 1.7.2 was supposed to include this parameter (and the release note says so), but it was omitted by mistake.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## releasing 1.7.2 (2026-07-07)
|
|
12
|
+
### Overview
|
|
13
|
+
This patch adds experimental handling of "reasoning traces" of propmtable apps
|
|
14
|
+
|
|
15
|
+
### Additions
|
|
16
|
+
* common parameter `useReasoning` (bool) is added
|
|
17
|
+
* when reasoning is on, in-line tagged reasoning traces (commonly within `<think>...</think>`) are separately stored in `modelReasoningTrace` of the TextDocument
|
|
18
|
+
|
|
19
|
+
> [!NOTE]
|
|
20
|
+
> The new names are tentative and can be changed in the near future.
|
|
21
|
+
|
|
22
|
+
|
|
2
23
|
## releasing 1.7.1 (2026-06-19)
|
|
3
24
|
### Overview
|
|
4
25
|
Updates the `mmif-python` SDK dependency to 1.5.1 to incorporate a bugfix in VDH, with some other minor documentation generation improvements.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clams-python
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.4
|
|
4
4
|
Summary: A collection of APIs to develop CLAMS app for python
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: homepage, https://clams.ai
|
|
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
13
13
|
Requires-Python: >=3.10
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
|
-
Requires-Dist: mmif-python==1.5.
|
|
16
|
+
Requires-Dist: mmif-python==1.5.3
|
|
17
17
|
Requires-Dist: Flask>=2
|
|
18
18
|
Requires-Dist: Flask-RESTful>=0.3.9
|
|
19
19
|
Requires-Dist: gunicorn>=20
|
|
@@ -49,6 +49,10 @@ falsy_values = [
|
|
|
49
49
|
]
|
|
50
50
|
|
|
51
51
|
|
|
52
|
+
class EmptyOutputWarning(UserWarning):
|
|
53
|
+
"""Raised when an app's ``_annotate()`` produces no non-empty views."""
|
|
54
|
+
|
|
55
|
+
|
|
52
56
|
class ClamsApp(ABC):
|
|
53
57
|
"""
|
|
54
58
|
An abstract class to define API's for ClamsApps. A CLAMS app should inherit
|
|
@@ -191,6 +195,15 @@ class ClamsApp(ABC):
|
|
|
191
195
|
t = datetime.now()
|
|
192
196
|
with warnings.catch_warnings(record=True) as ws:
|
|
193
197
|
annotated, cuda_profiler = self._profile_cuda_memory(self._annotate)(mmif, **refined)
|
|
198
|
+
new_views = [v for v in annotated.views if v.id not in existing_view_ids]
|
|
199
|
+
is_empty = lambda v: len(v.annotations) == 0 and not v.has_error() and not v.has_warnings()
|
|
200
|
+
for v in new_views:
|
|
201
|
+
if is_empty(v):
|
|
202
|
+
del annotated.views._items[v.id] # no public API to remove a view (mmif-python)
|
|
203
|
+
if all(is_empty(v) for v in new_views):
|
|
204
|
+
warnings.warn(f'App "{self.metadata.identifier}" produced no annotations for this '
|
|
205
|
+
f'input; the input may lack expected content, or there may genuinely '
|
|
206
|
+
f'be nothing to annotate.', EmptyOutputWarning)
|
|
194
207
|
if ws:
|
|
195
208
|
issued_warnings.extend(ws)
|
|
196
209
|
if issued_warnings:
|
|
@@ -301,35 +314,81 @@ class ClamsApp(ABC):
|
|
|
301
314
|
"""
|
|
302
315
|
A method to "sign" a new view that this app creates at the beginning of annotation.
|
|
303
316
|
Signing will populate the view metadata with information and configuration of this app.
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
317
|
+
|
|
318
|
+
The ``runtime_conf`` argument can be either "refined" or "raw" parameters,
|
|
319
|
+
and what ends up recorded in the view metadata differs accordingly:
|
|
320
|
+
|
|
321
|
+
* "refined" params: the output of :meth:`~clams.app.ClamsApp._refine_params`,
|
|
322
|
+
identifiable by the presence of the internal ``_RAW_PARAMS_KEY`` marker.
|
|
323
|
+
These carry both the user's raw input and the fully resolved configuration
|
|
324
|
+
(declared parameters with their defaults filled in). Signing then populates
|
|
325
|
+
**two** metadata fields: ``parameters`` with the raw user input (before
|
|
326
|
+
defaults), and ``appConfiguration`` with the resolved configuration,
|
|
327
|
+
including the universal parameters (e.g. ``pretty``, ``runningTime``,
|
|
328
|
+
``hwFetch``, ``tfSamplingMode``).
|
|
329
|
+
* "raw" params: an unrefined ``Dict[str, List[str]]``. Only the
|
|
330
|
+
``parameters`` field is populated; there is no resolved configuration
|
|
331
|
+
to record. See :meth:`~clams.app.ClamsApp.add_parameters_to_metadata`
|
|
332
|
+
for the input channels these values come from and how each is recorded.
|
|
333
|
+
|
|
334
|
+
These two cases exist because of two distinct execution paths. On the normal
|
|
335
|
+
annotation path, :meth:`~clams.app.ClamsApp.annotate` refines the parameters
|
|
336
|
+
before invoking :meth:`~clams.app.ClamsApp._annotate`, so a well-behaved app
|
|
337
|
+
forwards those already-refined params here and gets the full two-field record.
|
|
338
|
+
On the error path (:meth:`~clams.app.ClamsApp.set_error_view`), refinement may
|
|
339
|
+
be exactly what failed (:meth:`~clams.app.ClamsApp._refine_params` raises on a
|
|
340
|
+
missing required parameter or an invalid choice) so the error view is signed
|
|
341
|
+
with the raw params to guarantee the error is still recorded.
|
|
342
|
+
|
|
308
343
|
:param view: a view to sign
|
|
309
|
-
:param runtime_conf: runtime configuration of the app
|
|
344
|
+
:param runtime_conf: runtime configuration of the app, either refined
|
|
345
|
+
(output of :meth:`~clams.app.ClamsApp._refine_params`) or raw k-v pairs
|
|
310
346
|
"""
|
|
311
347
|
view.metadata.app = str(self.metadata.identifier)
|
|
312
348
|
if self.metadata.app_tags:
|
|
313
349
|
view.metadata.set_additional_property('appTags', list(self.metadata.app_tags))
|
|
314
|
-
params_map = {p.name: p for p in self.metadata.parameters}
|
|
315
350
|
if self._RAW_PARAMS_KEY in runtime_conf:
|
|
316
351
|
for k, v in runtime_conf.items():
|
|
317
352
|
if k == self._RAW_PARAMS_KEY:
|
|
318
|
-
|
|
319
|
-
if orik in params_map and params_map[orik].multivalued:
|
|
320
|
-
view.metadata.add_parameter(orik, str(oriv))
|
|
321
|
-
else:
|
|
322
|
-
view.metadata.add_parameter(orik, oriv[0])
|
|
353
|
+
self.add_parameters_to_metadata(view, v)
|
|
323
354
|
else:
|
|
324
355
|
view.metadata.add_app_configuration(k, v)
|
|
325
356
|
else:
|
|
326
|
-
#
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
357
|
+
# unrefined params passed directly (no _RAW_PARAMS_KEY marker), e.g.
|
|
358
|
+
# the error path; values are lists
|
|
359
|
+
self.add_parameters_to_metadata(view, runtime_conf)
|
|
360
|
+
|
|
361
|
+
def add_parameters_to_metadata(self, view: View, parameters: dict):
|
|
362
|
+
"""
|
|
363
|
+
Record raw runtime parameters into the view's ``parameters`` metadata.
|
|
364
|
+
|
|
365
|
+
The ``parameters`` argument reaches an app through one of three channels:
|
|
366
|
+
|
|
367
|
+
#. a query string, when the app runs as an HTTP server (``app.py``, via
|
|
368
|
+
:class:`~clams.restify.Restifier`);
|
|
369
|
+
#. shell arguments, when the app runs as a CLI program (``cli.py``);
|
|
370
|
+
#. a JSON envelope built with the ``clams envelop`` command (see
|
|
371
|
+
:mod:`clams.envelop`), whose values are flattened by
|
|
372
|
+
:func:`~clams.envelop.normalize_params`.
|
|
373
|
+
|
|
374
|
+
In every case the values arrive as ``List[str]`` (the shape
|
|
375
|
+
:meth:`~clams.app.ClamsApp._refine_params` consumes). A single value is
|
|
376
|
+
recorded bare with the ``List`` wrapper stripped, multiple values as the
|
|
377
|
+
serialized list, and an empty list skipped as unset (only an envelope
|
|
378
|
+
such as ``{"x": []}`` produces one, guarding against an ``IndexError``
|
|
379
|
+
on ``v[0]``).
|
|
380
|
+
|
|
381
|
+
:param view: the view being signed
|
|
382
|
+
:param parameters: raw runtime parameters as ``Dict[str, List[str]]``
|
|
383
|
+
"""
|
|
384
|
+
for k, v in parameters.items():
|
|
385
|
+
if len(v) == 0:
|
|
386
|
+
continue
|
|
387
|
+
elif len(v) == 1:
|
|
388
|
+
view.metadata.add_parameter(k, v[0])
|
|
389
|
+
else:
|
|
390
|
+
view.metadata.add_parameter(k, str(v))
|
|
391
|
+
|
|
333
392
|
def set_error_view(self, mmif: Union[str, dict, Mmif], **runtime_conf: List[str]) -> Mmif:
|
|
334
393
|
"""
|
|
335
394
|
A method to record an error instead of annotation results in the view
|
|
@@ -711,6 +770,26 @@ class ClamsPromptableApp(ClamsApp):
|
|
|
711
770
|
'values grow the KV cache linearly and increase GPU memory '
|
|
712
771
|
'usage; reduce if VRAM is constrained.',
|
|
713
772
|
},
|
|
773
|
+
{
|
|
774
|
+
'name': 'useReasoning', 'type': 'boolean', 'default': False,
|
|
775
|
+
'description':
|
|
776
|
+
'Request the model\'s reasoning ("thinking") mode. Off by '
|
|
777
|
+
'default. Honored only by apps whose backing model has a '
|
|
778
|
+
'distinct reasoning mode; apps without one ignore it. When '
|
|
779
|
+
'honored and enabled, the reasoning trace is split from the '
|
|
780
|
+
'answer and stored in the ``modelReasoningTrace`` property of '
|
|
781
|
+
'the output ``TextDocument`` (kept out of the document text). '
|
|
782
|
+
'Reasoning is markedly slower and far more token-hungry: the '
|
|
783
|
+
'whole trace is generated before the answer and drawn from the '
|
|
784
|
+
'same budget capped by ``maxNewTokens``, so raise '
|
|
785
|
+
'``maxNewTokens`` substantially (thousands of tokens, not '
|
|
786
|
+
'hundreds) when enabling this, or the trace may consume the '
|
|
787
|
+
'entire budget and the answer be truncated or empty. Small '
|
|
788
|
+
'reasoning models (as a rule of thumb, roughly 4B parameters '
|
|
789
|
+
'and under) are especially prone to non-terminating "thinking '
|
|
790
|
+
'loops" that exhaust the budget without producing an answer; '
|
|
791
|
+
'validate termination per model before relying on it.',
|
|
792
|
+
},
|
|
714
793
|
{
|
|
715
794
|
'name': 'temperature', 'type': 'number', 'default': 0.0,
|
|
716
795
|
'description':
|
|
@@ -1109,37 +1188,56 @@ class ClamsPromptableApp(ClamsApp):
|
|
|
1109
1188
|
text: str,
|
|
1110
1189
|
open_tag: str = '<think>',
|
|
1111
1190
|
close_tag: str = '</think>',
|
|
1191
|
+
assume_open: bool = False,
|
|
1112
1192
|
) -> Tuple[str, Optional[str]]:
|
|
1113
1193
|
"""
|
|
1114
1194
|
Split a reasoning model's output into ``(answer, trace)`` for the
|
|
1115
|
-
inline XML-tag style: a
|
|
1116
|
-
``
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
``answer`` is
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1195
|
+
inline XML-tag style: a reasoning block delimited by ``open_tag`` /
|
|
1196
|
+
``close_tag`` (default ``<think>`` / ``</think>``), e.g. as emitted
|
|
1197
|
+
by DeepSeek-R1 or Qwen3.5.
|
|
1198
|
+
|
|
1199
|
+
Prefilled opening tags: some chat templates inject the OPENING tag
|
|
1200
|
+
into the prompt when reasoning is enabled (Qwen3.5 does this), so the
|
|
1201
|
+
decoded output carries only the CLOSING tag -- the model never emits
|
|
1202
|
+
the opener. Pass ``assume_open=True`` in that situation (typically
|
|
1203
|
+
wired to the app's reasoning toggle) so the trace is still recovered.
|
|
1204
|
+
The cases:
|
|
1205
|
+
|
|
1206
|
+
* close tag present: ``answer`` is the text after it; ``trace`` is the
|
|
1207
|
+
text between the tags, or everything before the close tag when the
|
|
1208
|
+
opening tag is absent (prefilled).
|
|
1209
|
+
* close tag absent, ``assume_open=True``: the output is unterminated
|
|
1210
|
+
reasoning (e.g. the trace overran ``maxNewTokens`` before closing) --
|
|
1211
|
+
there is no answer, so returns ``('', text.strip())``.
|
|
1212
|
+
* close tag absent, ``assume_open=False`` (default): treated as a
|
|
1213
|
+
plain, non-reasoning answer -- returns ``(text.strip(), None)``.
|
|
1214
|
+
|
|
1215
|
+
Only the inline-tag style is handled; models that isolate reasoning in
|
|
1216
|
+
a separate token-delimited channel (e.g. gpt-oss, Gemma) need their own
|
|
1217
|
+
parsing in the app.
|
|
1130
1218
|
|
|
1131
1219
|
:param text: raw decoded model output.
|
|
1132
1220
|
:param open_tag: opening marker of the inline reasoning block.
|
|
1133
1221
|
:param close_tag: closing marker of the inline reasoning block.
|
|
1222
|
+
:param assume_open: treat the text as the body of a reasoning block
|
|
1223
|
+
whose opening tag was prefilled into the prompt, so a missing close
|
|
1224
|
+
tag means unterminated reasoning (empty answer) rather than a plain
|
|
1225
|
+
answer.
|
|
1134
1226
|
:return: ``(answer, trace_or_None)``.
|
|
1135
1227
|
"""
|
|
1136
1228
|
ci = text.rfind(close_tag)
|
|
1137
1229
|
if ci == -1:
|
|
1138
|
-
return text.strip(), None
|
|
1230
|
+
return ('', text.strip()) if assume_open else (text.strip(), None)
|
|
1139
1231
|
answer = text[ci + len(close_tag):].strip()
|
|
1140
1232
|
oi = text.find(open_tag)
|
|
1141
|
-
|
|
1142
|
-
|
|
1233
|
+
if oi != -1 and oi < ci:
|
|
1234
|
+
trace = text[oi + len(open_tag):ci].strip()
|
|
1235
|
+
elif assume_open:
|
|
1236
|
+
# opening tag was prefilled into the prompt (not generated), so the
|
|
1237
|
+
# trace is everything up to the close tag
|
|
1238
|
+
trace = text[:ci].strip()
|
|
1239
|
+
else:
|
|
1240
|
+
trace = None
|
|
1143
1241
|
return answer, trace
|
|
1144
1242
|
class ClamsHFPromptableApp(ClamsPromptableApp):
|
|
1145
1243
|
"""
|
|
@@ -1511,10 +1609,13 @@ class ClamsHFPromptableApp(ClamsPromptableApp):
|
|
|
1511
1609
|
implementation returns ``{}``.
|
|
1512
1610
|
|
|
1513
1611
|
Override to inject model-specific chat-template controls without
|
|
1514
|
-
having to reimplement :py:meth:`generate`.
|
|
1612
|
+
having to reimplement :py:meth:`generate`. This is where an app
|
|
1613
|
+
honors the SDK ``useReasoning`` parameter, mapping it onto the
|
|
1614
|
+
backend's reasoning switch. Common cases:
|
|
1515
1615
|
|
|
1516
|
-
* ``{'enable_thinking':
|
|
1517
|
-
|
|
1616
|
+
* ``{'enable_thinking': bool(generation_params.get('use_reasoning'))}``
|
|
1617
|
+
to bind ``useReasoning`` to a reasoning ("thinking") model's
|
|
1618
|
+
template switch;
|
|
1518
1619
|
* ``{'tools': [...]}`` or ``{'documents': [...]}`` for tool-use /
|
|
1519
1620
|
RAG chat templates.
|
|
1520
1621
|
|
{clams_python-1.7.2 → clams_python-1.7.4}/clams/develop/templates/app/Containerfile.template
RENAMED
|
@@ -3,7 +3,7 @@ FROM ghcr.io/clamsproject/clams-python:$CLAMS_VERSION
|
|
|
3
3
|
# See https://github.com/orgs/clamsproject/packages?tab=packages&q=clams-python for more base images
|
|
4
4
|
# IF you want to automatically publish this image to the clamsproject organization,
|
|
5
5
|
# 1. you should have generated this template without --no-github-actions flag
|
|
6
|
-
# 1. to add arm64 support,
|
|
6
|
+
# 1. to add arm64 support, set `arm64: true` in .github/workflows/publish.yml
|
|
7
7
|
# * NOTE that a lots of software doesn't install/compile or run on arm64 architecture out of the box
|
|
8
8
|
# * make sure you locally test the compatibility of all software dependencies before using arm64 support
|
|
9
9
|
# 1. use a git tag to trigger the github action. You need to use git tag to properly set app version anyway
|
|
@@ -6,13 +6,17 @@ DO NOT CHANGE the name of the file
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import argparse
|
|
9
|
+
import json
|
|
9
10
|
import sys
|
|
10
11
|
from contextlib import redirect_stdout
|
|
11
12
|
|
|
13
|
+
import jsonschema
|
|
14
|
+
|
|
12
15
|
import app
|
|
13
16
|
|
|
14
17
|
import clams.app
|
|
15
18
|
from clams import AppMetadata
|
|
19
|
+
from clams.envelop import EnvelopeError
|
|
16
20
|
|
|
17
21
|
|
|
18
22
|
def metadata_to_argparser(app_metadata: AppMetadata) -> argparse.ArgumentParser:
|
|
@@ -81,11 +85,24 @@ if __name__ == "__main__":
|
|
|
81
85
|
params[pname] = pvalue
|
|
82
86
|
else:
|
|
83
87
|
params[pname] = [pvalue]
|
|
84
|
-
|
|
85
|
-
|
|
88
|
+
# Mirror the HTTP server's error handling (see clams.restify): an invalid
|
|
89
|
+
# input is reported and exits non-zero, while an app-level failure is
|
|
90
|
+
# recorded as an error view instead of crashing with a raw traceback.
|
|
91
|
+
try:
|
|
92
|
+
if args.OUT_MMIF_FILE.name == '<stdout>':
|
|
93
|
+
with redirect_stdout(sys.stderr):
|
|
94
|
+
out_mmif = clamsapp.annotate(in_data, **params)
|
|
95
|
+
else:
|
|
86
96
|
out_mmif = clamsapp.annotate(in_data, **params)
|
|
87
|
-
|
|
88
|
-
|
|
97
|
+
except (jsonschema.exceptions.ValidationError, json.JSONDecodeError, EnvelopeError) as e:
|
|
98
|
+
detail = e.message if isinstance(e, jsonschema.exceptions.ValidationError) else str(e)
|
|
99
|
+
print(f"Invalid input data. See below for validation error.\n\n{detail}", file=sys.stderr)
|
|
100
|
+
sys.exit(1)
|
|
101
|
+
except Exception:
|
|
102
|
+
clamsapp.logger.exception("Error in annotation")
|
|
103
|
+
out_mmif = clamsapp.record_error(in_data, **params).serialize(pretty=True)
|
|
104
|
+
args.OUT_MMIF_FILE.write(out_mmif)
|
|
105
|
+
sys.exit(1)
|
|
89
106
|
args.OUT_MMIF_FILE.write(out_mmif)
|
|
90
107
|
else:
|
|
91
108
|
arg_parser.print_help()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clams-python
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.4
|
|
4
4
|
Summary: A collection of APIs to develop CLAMS app for python
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: homepage, https://clams.ai
|
|
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
13
13
|
Requires-Python: >=3.10
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
|
-
Requires-Dist: mmif-python==1.5.
|
|
16
|
+
Requires-Dist: mmif-python==1.5.3
|
|
17
17
|
Requires-Dist: Flask>=2
|
|
18
18
|
Requires-Dist: Flask-RESTful>=0.3.9
|
|
19
19
|
Requires-Dist: gunicorn>=20
|
|
@@ -1,96 +1,96 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": [
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
".github/workflows/codecov.yml",
|
|
4
|
+
".github/workflows/container.yml",
|
|
5
|
+
".github/workflows/containers.yml",
|
|
6
|
+
".github/workflows/issue-assign.yml",
|
|
7
|
+
".github/workflows/issue-close.yml",
|
|
8
|
+
".github/workflows/issue-infra-project.yml",
|
|
9
|
+
".github/workflows/publish.yml",
|
|
10
|
+
".github/workflows/release-check.yml",
|
|
11
|
+
".gitignore",
|
|
6
12
|
".pytype.cfg",
|
|
7
13
|
"CHANGELOG.md",
|
|
8
14
|
"CONTRIBUTING.md",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"build-tools/prep_release.py",
|
|
15
|
+
"LICENSE",
|
|
16
|
+
"README.md",
|
|
12
17
|
"build-tools/build.py",
|
|
13
|
-
"build-tools/docs.py",
|
|
14
18
|
"build-tools/clean.py",
|
|
19
|
+
"build-tools/docs.py",
|
|
20
|
+
"build-tools/prep_release.py",
|
|
21
|
+
"build-tools/publish.py",
|
|
15
22
|
"build-tools/test.py",
|
|
16
23
|
"clams/__init__.py",
|
|
24
|
+
"clams/app/__init__.py",
|
|
25
|
+
"clams/appmetadata/__init__.py",
|
|
26
|
+
"clams/backends/__init__.py",
|
|
27
|
+
"clams/backends/hf.py",
|
|
17
28
|
"clams/develop/__init__.py",
|
|
29
|
+
"clams/develop/templates/app/.dockerignore.template",
|
|
30
|
+
"clams/develop/templates/app/.gitignore.template",
|
|
31
|
+
"clams/develop/templates/app/Containerfile.template",
|
|
32
|
+
"clams/develop/templates/app/LICENSE.template",
|
|
33
|
+
"clams/develop/templates/app/README.md.template",
|
|
34
|
+
"clams/develop/templates/app/app.py.template",
|
|
35
|
+
"clams/develop/templates/app/cli.py.template",
|
|
36
|
+
"clams/develop/templates/app/metadata.py.template",
|
|
37
|
+
"clams/develop/templates/app/requirements.txt.template",
|
|
18
38
|
"clams/develop/templates/gha/for-clams-team.md.template",
|
|
19
|
-
"clams/develop/templates/gha/workflows/issue-assign.yml.template",
|
|
20
|
-
"clams/develop/templates/gha/workflows/publish.yml.template",
|
|
21
39
|
"clams/develop/templates/gha/workflows/issue-apps-project.yml.template",
|
|
40
|
+
"clams/develop/templates/gha/workflows/issue-assign.yml.template",
|
|
22
41
|
"clams/develop/templates/gha/workflows/issue-close.yml.template",
|
|
42
|
+
"clams/develop/templates/gha/workflows/publish.yml.template",
|
|
23
43
|
"clams/develop/templates/utl-tf/__init__.py.template",
|
|
24
44
|
"clams/develop/templates/utl-tf/timeframe.py.template",
|
|
25
|
-
"clams/develop/templates/app/Containerfile.template",
|
|
26
|
-
"clams/develop/templates/app/metadata.py.template",
|
|
27
|
-
"clams/develop/templates/app/README.md.template",
|
|
28
|
-
"clams/develop/templates/app/.dockerignore.template",
|
|
29
|
-
"clams/develop/templates/app/requirements.txt.template",
|
|
30
|
-
"clams/develop/templates/app/LICENSE.template",
|
|
31
|
-
"clams/develop/templates/app/.gitignore.template",
|
|
32
|
-
"clams/develop/templates/app/app.py.template",
|
|
33
|
-
"clams/develop/templates/app/cli.py.template",
|
|
34
|
-
"clams/restify/__init__.py",
|
|
35
45
|
"clams/envelop/__init__.py",
|
|
36
|
-
"clams/
|
|
37
|
-
"clams/app/__init__.py",
|
|
46
|
+
"clams/restify/__init__.py",
|
|
38
47
|
"clams/serve/__init__.py",
|
|
39
48
|
"clams/ver/__init__.py",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
49
|
+
"container/Containerfile",
|
|
50
|
+
"container/ffmpeg-hf.containerfile",
|
|
51
|
+
"container/ffmpeg-hf4.containerfile",
|
|
52
|
+
"container/ffmpeg-hf5.containerfile",
|
|
53
|
+
"container/ffmpeg-tf2.containerfile",
|
|
54
|
+
"container/ffmpeg-torch2.containerfile",
|
|
55
|
+
"container/ffmpeg.containerfile",
|
|
56
|
+
"container/generate_containers_yml.py",
|
|
57
|
+
"container/hf.containerfile",
|
|
58
|
+
"container/hf4.containerfile",
|
|
59
|
+
"container/hf5.containerfile",
|
|
60
|
+
"container/jdk8.containerfile",
|
|
61
|
+
"container/opencv4-hf.containerfile",
|
|
62
|
+
"container/opencv4-hf4.containerfile",
|
|
63
|
+
"container/opencv4-hf5.containerfile",
|
|
64
|
+
"container/opencv4-tf2.containerfile",
|
|
65
|
+
"container/opencv4-torch2.containerfile",
|
|
66
|
+
"container/opencv4.containerfile",
|
|
67
|
+
"container/tf2.containerfile",
|
|
68
|
+
"container/torch2.containerfile",
|
|
44
69
|
"documentation/app-baseclasses.rst",
|
|
45
|
-
"documentation/gpu-apps.rst",
|
|
46
|
-
"documentation/clamsapp.rst",
|
|
47
70
|
"documentation/appdirectory.rst",
|
|
48
|
-
"documentation/index.rst",
|
|
49
|
-
"documentation/tutorial.md",
|
|
50
|
-
"documentation/introduction.rst",
|
|
51
71
|
"documentation/appmetadata.rst",
|
|
52
|
-
"documentation/cli.rst",
|
|
53
|
-
"documentation/runtime-params.rst",
|
|
54
|
-
"documentation/input-output.rst",
|
|
55
|
-
"documentation/conf.py",
|
|
56
|
-
"documentation/autodoc/clams.restify.rst",
|
|
57
72
|
"documentation/autodoc/clams.app.rst",
|
|
73
|
+
"documentation/autodoc/clams.appmetadata.rst",
|
|
58
74
|
"documentation/autodoc/clams.backends.rst",
|
|
59
75
|
"documentation/autodoc/clams.mmif_utils.rst",
|
|
60
|
-
"documentation/autodoc/clams.
|
|
61
|
-
"
|
|
76
|
+
"documentation/autodoc/clams.restify.rst",
|
|
77
|
+
"documentation/clamsapp.rst",
|
|
78
|
+
"documentation/cli.rst",
|
|
79
|
+
"documentation/conf.py",
|
|
80
|
+
"documentation/gpu-apps.rst",
|
|
81
|
+
"documentation/index.rst",
|
|
82
|
+
"documentation/input-output.rst",
|
|
83
|
+
"documentation/introduction.rst",
|
|
84
|
+
"documentation/modules.rst",
|
|
85
|
+
"documentation/runtime-params.rst",
|
|
86
|
+
"documentation/target-versions.csv",
|
|
87
|
+
"documentation/tutorial.md",
|
|
88
|
+
"pyproject.toml",
|
|
89
|
+
"tests/metadata.py",
|
|
62
90
|
"tests/pillow-logo.png",
|
|
63
91
|
"tests/test_backends_hf.py",
|
|
64
|
-
"tests/test_envelope.py",
|
|
65
|
-
"tests/metadata.py",
|
|
66
92
|
"tests/test_clamsapp.py",
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"container/torch2.containerfile",
|
|
70
|
-
"container/opencv4-hf4.containerfile",
|
|
71
|
-
"container/Containerfile",
|
|
72
|
-
"container/hf4.containerfile",
|
|
73
|
-
"container/ffmpeg-hf.containerfile",
|
|
74
|
-
"container/ffmpeg-tf2.containerfile",
|
|
75
|
-
"container/generate_containers_yml.py",
|
|
76
|
-
"container/opencv4-tf2.containerfile",
|
|
77
|
-
"container/opencv4-torch2.containerfile",
|
|
78
|
-
"container/hf.containerfile",
|
|
79
|
-
"container/jdk8.containerfile",
|
|
80
|
-
"container/hf5.containerfile",
|
|
81
|
-
"container/ffmpeg.containerfile",
|
|
82
|
-
"container/ffmpeg-hf5.containerfile",
|
|
83
|
-
"container/ffmpeg-hf4.containerfile",
|
|
84
|
-
"container/opencv4-hf5.containerfile",
|
|
85
|
-
"container/ffmpeg-torch2.containerfile",
|
|
86
|
-
"container/opencv4.containerfile",
|
|
87
|
-
".github/workflows/container.yml",
|
|
88
|
-
".github/workflows/containers.yml",
|
|
89
|
-
".github/workflows/issue-close.yml",
|
|
90
|
-
".github/workflows/codecov.yml",
|
|
91
|
-
".github/workflows/release-check.yml",
|
|
92
|
-
".github/workflows/issue-infra-project.yml",
|
|
93
|
-
".github/workflows/issue-assign.yml",
|
|
94
|
-
".github/workflows/publish.yml"
|
|
93
|
+
"tests/test_envelope.py",
|
|
94
|
+
"tests/test_promptable.py"
|
|
95
95
|
]
|
|
96
96
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ARG clams_version
|
|
2
|
+
FROM ghcr.io/clamsproject/clams-python-ffmpeg:$clams_version
|
|
3
|
+
LABEL org.opencontainers.image.description="clams-python-ffmpeg-torch2 image is shipped with clams-python, ffmpeg, and PyTorch2"
|
|
4
|
+
|
|
5
|
+
RUN pip install --no-cache-dir torch==2.*
|
|
6
|
+
|
|
7
|
+
# PyTorch ships Triton, which JIT-compiles a small host-side CUDA driver shim
|
|
8
|
+
# at runtime -- that needs a C compiler + libc headers. Keep it minimal
|
|
9
|
+
# (gcc + libc6-dev); build-essential is not required.
|
|
10
|
+
RUN apt-get update \
|
|
11
|
+
&& apt-get install -y --no-install-recommends gcc libc6-dev \
|
|
12
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
13
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ARG clams_version
|
|
2
|
+
FROM ghcr.io/clamsproject/clams-python-opencv4:$clams_version
|
|
3
|
+
LABEL org.opencontainers.image.description="clams-python-opencv4-torch2 image is shipped with clams-python, opencv4 (ffmpeg backend), and PyTorch2"
|
|
4
|
+
|
|
5
|
+
RUN pip install --no-cache-dir torch==2.*
|
|
6
|
+
|
|
7
|
+
# PyTorch ships Triton, which JIT-compiles a small host-side CUDA driver shim
|
|
8
|
+
# at runtime -- that needs a C compiler + libc headers. Keep it minimal
|
|
9
|
+
# (gcc + libc6-dev); build-essential is not required.
|
|
10
|
+
RUN apt-get update \
|
|
11
|
+
&& apt-get install -y --no-install-recommends gcc libc6-dev \
|
|
12
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
13
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ARG clams_version
|
|
2
|
+
FROM ghcr.io/clamsproject/clams-python:$clams_version
|
|
3
|
+
LABEL org.opencontainers.image.description="clams-python-torch2 image is shipped with clams-python and PyTorch2"
|
|
4
|
+
|
|
5
|
+
RUN pip install --no-cache-dir torch==2.*
|
|
6
|
+
|
|
7
|
+
# PyTorch ships Triton, which JIT-compiles a small host-side CUDA driver shim
|
|
8
|
+
# at runtime -- that needs a C compiler + libc headers. Keep it minimal
|
|
9
|
+
# (gcc + libc6-dev); build-essential is not required.
|
|
10
|
+
RUN apt-get update \
|
|
11
|
+
&& apt-get install -y --no-install-recommends gcc libc6-dev \
|
|
12
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
13
|
+
|