clams-python 1.7.2__tar.gz → 1.7.3__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.3}/CHANGELOG.md +12 -0
- {clams_python-1.7.2/clams_python.egg-info → clams_python-1.7.3}/PKG-INFO +2 -2
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/app/__init__.py +63 -21
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/cli.py.template +21 -4
- {clams_python-1.7.2 → clams_python-1.7.3/clams_python.egg-info}/PKG-INFO +2 -2
- {clams_python-1.7.2 → clams_python-1.7.3}/clams_python.egg-info/requires.txt +1 -1
- clams_python-1.7.3/clams_python.egg-info/scm_version.json +8 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/app-baseclasses.rst +61 -1
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/conf.py +3 -1
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/target-versions.csv +1 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/pyproject.toml +1 -1
- {clams_python-1.7.2 → clams_python-1.7.3}/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 → clams_python-1.7.3}/.github/workflows/codecov.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/.github/workflows/container.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/.github/workflows/containers.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/.github/workflows/issue-assign.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/.github/workflows/issue-close.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/.github/workflows/issue-infra-project.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/.github/workflows/publish.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/.github/workflows/release-check.yml +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/.gitignore +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/.pytype.cfg +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/CONTRIBUTING.md +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/LICENSE +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/README.md +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/build-tools/build.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/build-tools/clean.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/build-tools/docs.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/build-tools/prep_release.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/build-tools/publish.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/build-tools/test.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/appmetadata/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/backends/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/backends/hf.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/.dockerignore.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/.gitignore.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/Containerfile.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/LICENSE.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/README.md.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/app.py.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/metadata.py.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/requirements.txt.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/gha/for-clams-team.md.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/gha/workflows/issue-apps-project.yml.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/gha/workflows/issue-assign.yml.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/gha/workflows/issue-close.yml.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/gha/workflows/publish.yml.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/utl-tf/__init__.py.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/utl-tf/timeframe.py.template +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/envelop/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/restify/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/serve/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams/ver/__init__.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams_python.egg-info/SOURCES.txt +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams_python.egg-info/dependency_links.txt +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams_python.egg-info/entry_points.txt +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams_python.egg-info/scm_file_list.json +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/clams_python.egg-info/top_level.txt +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/Containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/ffmpeg-hf.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/ffmpeg-hf4.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/ffmpeg-hf5.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/ffmpeg-tf2.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/ffmpeg-torch2.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/ffmpeg.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/generate_containers_yml.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/hf.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/hf4.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/hf5.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/jdk8.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/opencv4-hf.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/opencv4-hf4.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/opencv4-hf5.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/opencv4-tf2.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/opencv4-torch2.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/opencv4.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/tf2.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/container/torch2.containerfile +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/appdirectory.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/appmetadata.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/autodoc/clams.app.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/autodoc/clams.appmetadata.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/autodoc/clams.backends.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/autodoc/clams.mmif_utils.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/autodoc/clams.restify.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/clamsapp.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/cli.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/gpu-apps.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/index.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/input-output.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/introduction.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/modules.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/runtime-params.rst +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/documentation/tutorial.md +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/setup.cfg +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/tests/metadata.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/tests/pillow-logo.png +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/tests/test_backends_hf.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/tests/test_clamsapp.py +0 -0
- {clams_python-1.7.2 → clams_python-1.7.3}/tests/test_envelope.py +0 -0
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
|
|
2
|
+
## releasing 1.7.2 (2026-07-07)
|
|
3
|
+
### Overview
|
|
4
|
+
This patch adds experimental handling of "reasoning traces" of propmtable apps
|
|
5
|
+
|
|
6
|
+
### Additions
|
|
7
|
+
* common parameter `useReasoning` (bool) is added
|
|
8
|
+
* when reasoning is on, in-line tagged reasoning traces (commonly within `<think>...</think>`) are separately stored in `modelReasoningTrace` of the TextDocument
|
|
9
|
+
|
|
10
|
+
> [!NOTE]
|
|
11
|
+
> The new names are tentative and can be changed in the near future.
|
|
12
|
+
|
|
13
|
+
|
|
2
14
|
## releasing 1.7.1 (2026-06-19)
|
|
3
15
|
### Overview
|
|
4
16
|
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.3
|
|
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
|
|
@@ -711,6 +711,26 @@ class ClamsPromptableApp(ClamsApp):
|
|
|
711
711
|
'values grow the KV cache linearly and increase GPU memory '
|
|
712
712
|
'usage; reduce if VRAM is constrained.',
|
|
713
713
|
},
|
|
714
|
+
{
|
|
715
|
+
'name': 'useReasoning', 'type': 'boolean', 'default': False,
|
|
716
|
+
'description':
|
|
717
|
+
'Request the model\'s reasoning ("thinking") mode. Off by '
|
|
718
|
+
'default. Honored only by apps whose backing model has a '
|
|
719
|
+
'distinct reasoning mode; apps without one ignore it. When '
|
|
720
|
+
'honored and enabled, the reasoning trace is split from the '
|
|
721
|
+
'answer and stored in the ``modelReasoningTrace`` property of '
|
|
722
|
+
'the output ``TextDocument`` (kept out of the document text). '
|
|
723
|
+
'Reasoning is markedly slower and far more token-hungry: the '
|
|
724
|
+
'whole trace is generated before the answer and drawn from the '
|
|
725
|
+
'same budget capped by ``maxNewTokens``, so raise '
|
|
726
|
+
'``maxNewTokens`` substantially (thousands of tokens, not '
|
|
727
|
+
'hundreds) when enabling this, or the trace may consume the '
|
|
728
|
+
'entire budget and the answer be truncated or empty. Small '
|
|
729
|
+
'reasoning models (as a rule of thumb, roughly 4B parameters '
|
|
730
|
+
'and under) are especially prone to non-terminating "thinking '
|
|
731
|
+
'loops" that exhaust the budget without producing an answer; '
|
|
732
|
+
'validate termination per model before relying on it.',
|
|
733
|
+
},
|
|
714
734
|
{
|
|
715
735
|
'name': 'temperature', 'type': 'number', 'default': 0.0,
|
|
716
736
|
'description':
|
|
@@ -1109,37 +1129,56 @@ class ClamsPromptableApp(ClamsApp):
|
|
|
1109
1129
|
text: str,
|
|
1110
1130
|
open_tag: str = '<think>',
|
|
1111
1131
|
close_tag: str = '</think>',
|
|
1132
|
+
assume_open: bool = False,
|
|
1112
1133
|
) -> Tuple[str, Optional[str]]:
|
|
1113
1134
|
"""
|
|
1114
1135
|
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
|
-
|
|
1136
|
+
inline XML-tag style: a reasoning block delimited by ``open_tag`` /
|
|
1137
|
+
``close_tag`` (default ``<think>`` / ``</think>``), e.g. as emitted
|
|
1138
|
+
by DeepSeek-R1 or Qwen3.5.
|
|
1139
|
+
|
|
1140
|
+
Prefilled opening tags: some chat templates inject the OPENING tag
|
|
1141
|
+
into the prompt when reasoning is enabled (Qwen3.5 does this), so the
|
|
1142
|
+
decoded output carries only the CLOSING tag -- the model never emits
|
|
1143
|
+
the opener. Pass ``assume_open=True`` in that situation (typically
|
|
1144
|
+
wired to the app's reasoning toggle) so the trace is still recovered.
|
|
1145
|
+
The cases:
|
|
1146
|
+
|
|
1147
|
+
* close tag present: ``answer`` is the text after it; ``trace`` is the
|
|
1148
|
+
text between the tags, or everything before the close tag when the
|
|
1149
|
+
opening tag is absent (prefilled).
|
|
1150
|
+
* close tag absent, ``assume_open=True``: the output is unterminated
|
|
1151
|
+
reasoning (e.g. the trace overran ``maxNewTokens`` before closing) --
|
|
1152
|
+
there is no answer, so returns ``('', text.strip())``.
|
|
1153
|
+
* close tag absent, ``assume_open=False`` (default): treated as a
|
|
1154
|
+
plain, non-reasoning answer -- returns ``(text.strip(), None)``.
|
|
1155
|
+
|
|
1156
|
+
Only the inline-tag style is handled; models that isolate reasoning in
|
|
1157
|
+
a separate token-delimited channel (e.g. gpt-oss, Gemma) need their own
|
|
1158
|
+
parsing in the app.
|
|
1130
1159
|
|
|
1131
1160
|
:param text: raw decoded model output.
|
|
1132
1161
|
:param open_tag: opening marker of the inline reasoning block.
|
|
1133
1162
|
:param close_tag: closing marker of the inline reasoning block.
|
|
1163
|
+
:param assume_open: treat the text as the body of a reasoning block
|
|
1164
|
+
whose opening tag was prefilled into the prompt, so a missing close
|
|
1165
|
+
tag means unterminated reasoning (empty answer) rather than a plain
|
|
1166
|
+
answer.
|
|
1134
1167
|
:return: ``(answer, trace_or_None)``.
|
|
1135
1168
|
"""
|
|
1136
1169
|
ci = text.rfind(close_tag)
|
|
1137
1170
|
if ci == -1:
|
|
1138
|
-
return text.strip(), None
|
|
1171
|
+
return ('', text.strip()) if assume_open else (text.strip(), None)
|
|
1139
1172
|
answer = text[ci + len(close_tag):].strip()
|
|
1140
1173
|
oi = text.find(open_tag)
|
|
1141
|
-
|
|
1142
|
-
|
|
1174
|
+
if oi != -1 and oi < ci:
|
|
1175
|
+
trace = text[oi + len(open_tag):ci].strip()
|
|
1176
|
+
elif assume_open:
|
|
1177
|
+
# opening tag was prefilled into the prompt (not generated), so the
|
|
1178
|
+
# trace is everything up to the close tag
|
|
1179
|
+
trace = text[:ci].strip()
|
|
1180
|
+
else:
|
|
1181
|
+
trace = None
|
|
1143
1182
|
return answer, trace
|
|
1144
1183
|
class ClamsHFPromptableApp(ClamsPromptableApp):
|
|
1145
1184
|
"""
|
|
@@ -1511,10 +1550,13 @@ class ClamsHFPromptableApp(ClamsPromptableApp):
|
|
|
1511
1550
|
implementation returns ``{}``.
|
|
1512
1551
|
|
|
1513
1552
|
Override to inject model-specific chat-template controls without
|
|
1514
|
-
having to reimplement :py:meth:`generate`.
|
|
1553
|
+
having to reimplement :py:meth:`generate`. This is where an app
|
|
1554
|
+
honors the SDK ``useReasoning`` parameter, mapping it onto the
|
|
1555
|
+
backend's reasoning switch. Common cases:
|
|
1515
1556
|
|
|
1516
|
-
* ``{'enable_thinking':
|
|
1517
|
-
|
|
1557
|
+
* ``{'enable_thinking': bool(generation_params.get('use_reasoning'))}``
|
|
1558
|
+
to bind ``useReasoning`` to a reasoning ("thinking") model's
|
|
1559
|
+
template switch;
|
|
1518
1560
|
* ``{'tools': [...]}`` or ``{'documents': [...]}`` for tool-use /
|
|
1519
1561
|
RAG chat templates.
|
|
1520
1562
|
|
|
@@ -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.3
|
|
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
|
|
@@ -174,6 +174,17 @@ from :class:`~clams.app.ClamsApp`. These names are reserved; see
|
|
|
174
174
|
- Maximum number of new tokens generated per inference call. Larger values
|
|
175
175
|
grow the KV cache linearly and add to GPU memory usage; reduce if VRAM
|
|
176
176
|
is constrained.
|
|
177
|
+
* - ``useReasoning``
|
|
178
|
+
- boolean
|
|
179
|
+
- ``false``
|
|
180
|
+
- no
|
|
181
|
+
- Request the model's reasoning ("thinking") mode. Off by default;
|
|
182
|
+
honored only by apps whose model has a distinct reasoning mode
|
|
183
|
+
(others ignore it). Much slower and more token-hungry -- the trace is
|
|
184
|
+
generated before the answer and drawn from the ``maxNewTokens`` budget,
|
|
185
|
+
and small models can loop without terminating. When honored, the trace
|
|
186
|
+
is stored in the ``modelReasoningTrace`` property of the output
|
|
187
|
+
``TextDocument``. See :ref:`promptable-reasoning`.
|
|
177
188
|
* - ``temperature``
|
|
178
189
|
- number
|
|
179
190
|
- ``0.0``
|
|
@@ -320,6 +331,52 @@ inferences, final reply returned.
|
|
|
320
331
|
``turn-taking`` is the default because it costs a single inference call
|
|
321
332
|
and is the more common multi-element pattern.
|
|
322
333
|
|
|
334
|
+
.. _promptable-reasoning:
|
|
335
|
+
|
|
336
|
+
Reasoning traces (``useReasoning``)
|
|
337
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
338
|
+
|
|
339
|
+
Some models expose a distinct reasoning ("thinking") mode that emits an
|
|
340
|
+
intermediate reasoning trace before the answer. ``useReasoning`` is the
|
|
341
|
+
standard toggle for that mode. It is inert unless the app honors it, and
|
|
342
|
+
honoring is a per-app choice with three wiring points:
|
|
343
|
+
|
|
344
|
+
- map ``useReasoning`` onto the backend's reasoning switch (for HF chat
|
|
345
|
+
templates, typically ``enable_thinking``) by overriding
|
|
346
|
+
:meth:`~clams.app.ClamsHFPromptableApp.build_template_kwargs`;
|
|
347
|
+
- split the trace from the answer with
|
|
348
|
+
:meth:`~clams.app.ClamsPromptableApp.split_tagged_reasoning_trace`
|
|
349
|
+
(inline ``<think>...</think>``-style traces only; channel-delimited
|
|
350
|
+
formats need app-specific parsing). Many chat templates prefill the
|
|
351
|
+
opening ``<think>`` into the prompt, so only the closing tag appears in
|
|
352
|
+
the output; pass ``assume_open=True`` (wired to the reasoning toggle) so
|
|
353
|
+
the trace is still recovered and a missing close tag is read as
|
|
354
|
+
unterminated reasoning (empty answer) rather than a plain answer;
|
|
355
|
+
- pass the trace to
|
|
356
|
+
:meth:`~clams.app.ClamsPromptableApp.response_to_grounded_textdocument`
|
|
357
|
+
through its ``reasoning_trace`` argument, which stores it in the
|
|
358
|
+
``modelReasoningTrace`` property of the produced ``TextDocument``,
|
|
359
|
+
separate from the document text.
|
|
360
|
+
|
|
361
|
+
An app whose model has no reasoning mode leaves ``useReasoning`` unwired;
|
|
362
|
+
callers may still set it and it has no effect, like ``topK`` under greedy
|
|
363
|
+
decoding.
|
|
364
|
+
|
|
365
|
+
Cost and failure modes
|
|
366
|
+
""""""""""""""""""""""
|
|
367
|
+
|
|
368
|
+
Reasoning is much slower and far more token-hungry than a direct answer:
|
|
369
|
+
the entire trace is generated first, from the same budget capped by
|
|
370
|
+
``maxNewTokens``. Enabling ``useReasoning`` without raising ``maxNewTokens``
|
|
371
|
+
substantially (thousands of tokens, not hundreds) risks the trace consuming
|
|
372
|
+
the whole budget, leaving the answer truncated or empty. Small reasoning
|
|
373
|
+
models (as a rule of thumb, roughly 4B parameters and under) are especially
|
|
374
|
+
prone to non-terminating "thinking loops" that never reach an answer; budget
|
|
375
|
+
generously and validate termination per model. When the trace overruns the
|
|
376
|
+
budget before closing, ``assume_open=True`` yields an empty answer plus the
|
|
377
|
+
unterminated trace -- an app should surface that (e.g. a warning and an empty
|
|
378
|
+
``TextDocument``) rather than emitting the raw reasoning as the answer.
|
|
379
|
+
|
|
323
380
|
Helpers
|
|
324
381
|
^^^^^^^
|
|
325
382
|
|
|
@@ -512,7 +569,10 @@ supplies:
|
|
|
512
569
|
* a default
|
|
513
570
|
:py:meth:`~clams.app.ClamsHFPromptableApp.build_gen_kwargs` that
|
|
514
571
|
maps the SDK promptable parameters to HF ``model.generate()``
|
|
515
|
-
kwargs
|
|
572
|
+
kwargs;
|
|
573
|
+
* a :py:meth:`~clams.app.ClamsHFPromptableApp.build_template_kwargs`
|
|
574
|
+
hook for chat-template controls, the override point for honoring
|
|
575
|
+
``useReasoning`` (see :ref:`promptable-reasoning`).
|
|
516
576
|
|
|
517
577
|
See each method's docstring for full details.
|
|
518
578
|
|
|
@@ -26,7 +26,9 @@ sys.path.insert(0, str(proj_root_dir))
|
|
|
26
26
|
|
|
27
27
|
# -- Project information -----------------------------------------------------
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
# The canonical package name — NOT derived from the checkout directory,
|
|
30
|
+
# which is `clone-repo` when the shared docs-publish workflow builds here.
|
|
31
|
+
project = 'clams-python'
|
|
30
32
|
blob_base_url = f'https://github.com/clamsproject/{project}/blob'
|
|
31
33
|
copyright = f'{datetime.date.today().year}, Brandeis LLC'
|
|
32
34
|
author = 'Brandeis LLC'
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"``clams-python`` version","``mmif-python`` version","Target MMIF Specification"
|
|
2
|
+
`1.7.3 <https://pypi.org/project/clams-python/1.7.3/>`__,`1.5.1 <https://pypi.org/project/mmif-python/1.5.1/>`__,`1.2.0 <https://mmif.clams.ai/1.2.0/>`__
|
|
2
3
|
`1.7.2 <https://pypi.org/project/clams-python/1.7.2/>`__,`1.5.1 <https://pypi.org/project/mmif-python/1.5.1/>`__,`1.2.0 <https://mmif.clams.ai/1.2.0/>`__
|
|
3
4
|
`1.7.1 <https://pypi.org/project/clams-python/1.7.1/>`__,`1.5.1 <https://pypi.org/project/mmif-python/1.5.1/>`__,`1.2.0 <https://mmif.clams.ai/1.2.0/>`__
|
|
4
5
|
`1.7.0 <https://pypi.org/project/clams-python/1.7.0/>`__,`1.5.0 <https://pypi.org/project/mmif-python/1.5.0/>`__,`1.2.0 <https://mmif.clams.ai/1.2.0/>`__
|
|
@@ -446,6 +446,28 @@ class TestSplitReasoningTrace(unittest.TestCase):
|
|
|
446
446
|
self.assertEqual(answer, 'plain caption')
|
|
447
447
|
self.assertIsNone(trace)
|
|
448
448
|
|
|
449
|
+
def test_assume_open_close_present_open_absent(self):
|
|
450
|
+
# Prefilled opening tag (e.g. Qwen3.5): only the close tag is emitted.
|
|
451
|
+
answer, trace = self.split(
|
|
452
|
+
'reasoning body</think>The answer.', assume_open=True)
|
|
453
|
+
self.assertEqual(answer, 'The answer.')
|
|
454
|
+
self.assertEqual(trace, 'reasoning body')
|
|
455
|
+
|
|
456
|
+
def test_assume_open_no_close_is_unterminated_reasoning(self):
|
|
457
|
+
# Trace overran the budget before closing: empty answer, whole text is
|
|
458
|
+
# the unterminated trace.
|
|
459
|
+
raw = 'still thinking, never closed'
|
|
460
|
+
answer, trace = self.split(raw, assume_open=True)
|
|
461
|
+
self.assertEqual(answer, '')
|
|
462
|
+
self.assertEqual(trace, raw)
|
|
463
|
+
|
|
464
|
+
def test_open_absent_default_keeps_backward_compatible(self):
|
|
465
|
+
# Without assume_open, a lone close tag is not treated as a prefilled
|
|
466
|
+
# block: answer after the close, no trace.
|
|
467
|
+
answer, trace = self.split('reasoning body</think>The answer.')
|
|
468
|
+
self.assertEqual(answer, 'The answer.')
|
|
469
|
+
self.assertIsNone(trace)
|
|
470
|
+
|
|
449
471
|
|
|
450
472
|
# ---------------------------------------------------------------------------
|
|
451
473
|
# Transport-neutral parameter casting
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/.dockerignore.template
RENAMED
|
File without changes
|
|
File without changes
|
{clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/Containerfile.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/app/requirements.txt.template
RENAMED
|
File without changes
|
{clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/gha/for-clams-team.md.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/gha/workflows/publish.yml.template
RENAMED
|
File without changes
|
{clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/utl-tf/__init__.py.template
RENAMED
|
File without changes
|
{clams_python-1.7.2 → clams_python-1.7.3}/clams/develop/templates/utl-tf/timeframe.py.template
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|