Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
11f31d4
Add protocol-native trajectory histories
bradhilton Jul 23, 2026
aef9d44
Harden protocol-native trajectory histories
bradhilton Jul 23, 2026
4bbf144
Select exchange models explicitly during training
bradhilton Jul 23, 2026
9bfa78e
Capture tau-bench rollouts as exchanges
bradhilton Jul 24, 2026
ed09e19
Harden trajectory history projection
bradhilton Jul 24, 2026
4643d77
Preserve exact evidence across history splits
bradhilton Jul 24, 2026
2cb0c4e
Represent terminal EOS as an empty assistant turn
bradhilton Jul 24, 2026
54e1fb3
Harden trajectory evidence and model selection
bradhilton Jul 24, 2026
ef75a52
Harden exchange training selection and serialization
bradhilton Jul 24, 2026
3eb8021
Reject ambiguous automatic policy families
bradhilton Jul 24, 2026
0ab1d54
Harden streaming trajectory capture
bradhilton Jul 24, 2026
df889ce
Preserve explicit vLLM chat metadata options
bradhilton Jul 24, 2026
efbfa12
Test explicit vLLM token metadata opt-out
bradhilton Jul 24, 2026
eeb249c
Fix trajectory tokenization evidence
bradhilton Jul 24, 2026
2ed95a4
Handle ambiguous echoed completion evidence
bradhilton Jul 24, 2026
7ce39a0
Use generation-scoped Responses fixtures
bradhilton Jul 24, 2026
1693a2f
Harden projected history tokenization
bradhilton Jul 24, 2026
eb785ad
Exclude routing extras from source fingerprints
bradhilton Jul 24, 2026
3a70b1a
Prefer exact public model selectors
bradhilton Jul 24, 2026
97ce26a
Train projected exchange sources once
bradhilton Jul 24, 2026
64daac2
Type training trace regressions
bradhilton Jul 24, 2026
6d2bef9
Reject training without a causal predecessor
bradhilton Jul 24, 2026
2e7a6d2
Preserve Anthropic prompt lineage metadata
bradhilton Jul 24, 2026
1fffa1f
Fix converted history source attribution
bradhilton Jul 24, 2026
60721cc
Scale Chat projection with captured evidence
bradhilton Jul 24, 2026
0229f30
Format training trace tests
bradhilton Jul 24, 2026
310dc83
Gate Chat projection by captured bytes
bradhilton Jul 24, 2026
09a6492
Disambiguate echoed completion evidence
bradhilton Jul 24, 2026
402d238
Finalize captured streams at terminal events
bradhilton Jul 24, 2026
6c388a7
Keep automatic model selectors literal
bradhilton Jul 24, 2026
a7f0e28
Preserve sources across overlength histories
bradhilton Jul 24, 2026
85fb0de
Capture preloaded HTTPX streams
bradhilton Jul 24, 2026
8c51ff2
Preserve exact multi-generation chat evidence
bradhilton Jul 24, 2026
cbd27e9
Tighten remediation test typing
bradhilton Jul 24, 2026
76aaa2c
Unify Responses fallback trace identity
bradhilton Jul 24, 2026
b01e2a8
Type Responses fallback regression
bradhilton Jul 24, 2026
86dc78d
Fix trajectory CI contract checks
bradhilton Jul 24, 2026
05f21df
refactor trajectories to reduce duplication
bradhilton Jul 24, 2026
1b43785
change chat source to explicit output indices
bradhilton Jul 25, 2026
110c19d
Fix trajectory history projection provenance
bradhilton Jul 25, 2026
fbd5140
fix trajectory token evidence provenance
bradhilton Jul 25, 2026
a8b77a8
avoid duplicating aggregate response evidence
bradhilton Jul 25, 2026
13e7102
preserve outputless response evidence
bradhilton Jul 25, 2026
8c653b7
Preserve composite Responses chat provenance
bradhilton Jul 25, 2026
babbd5a
Trust explicit string completion routing
bradhilton Jul 25, 2026
7755992
Separate request and sampled response sources
bradhilton Jul 25, 2026
76d7aa8
validate split responses source evidence
bradhilton Jul 25, 2026
2877750
fix fallback trajectory token evidence
bradhilton Jul 25, 2026
7d868ad
Harden trajectory fallback token evidence
bradhilton Jul 25, 2026
8e86252
fix trajectory requests stream transparency
bradhilton Jul 25, 2026
200304c
Prove sampled chat evidence boundaries
bradhilton Jul 25, 2026
32afa2d
Harden sampled token attribution
bradhilton Jul 25, 2026
d99a480
Preserve textual logprob token identity
bradhilton Jul 25, 2026
6e067a3
Harden fallback probes
bradhilton Jul 25, 2026
ac6ebb3
Preserve zero-width sampled outputs
bradhilton Jul 25, 2026
0ea64ce
Handle trimmed newline samples
bradhilton Jul 25, 2026
4329366
Finish sampled evidence hardening
bradhilton Jul 25, 2026
cb7cd0d
Avoid duplicating preserved whitespace samples
bradhilton Jul 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions docs/features/additional-histories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Some models, like Qwen 3, use chat templates that remove special tokens (such as
By splitting each turn into a separate history, you can preserve these tokens for training:

```python
from art.trajectories import Trajectory, History
from art.trajectories import LegacyHistory, Trajectory

# Instead of a single multi-turn conversation that loses <think> tokens
# Train as separate histories to preserve them
Expand All @@ -41,7 +41,7 @@ trajectory = Trajectory(
{"role": "assistant", "content": "<think>I need to add 2 and 2</think>4"}
],
additional_histories=[
History(
LegacyHistory(
messages_and_choices=[
# The Qwen 3 chat template removes <think> tokens from previous turns
{"role": "user", "content": "What is 2+2?"},
Expand Down Expand Up @@ -82,15 +82,15 @@ trajectory = Trajectory(
],
additional_histories=[
# Sub-agent 1: Code analysis
History(
LegacyHistory(
messages_and_choices=[
{"role": "system", "content": "You are a code analysis expert"},
{"role": "user", "content": "Find potential bugs in main.py"},
{"role": "assistant", "content": "Found 3 potential issues..."}
]
),
# Sub-agent 2: Bug fixing
History(
LegacyHistory(
messages_and_choices=[
{"role": "system", "content": "You are a bug fixing expert"},
{"role": "user", "content": "Fix the null pointer issue on line 42"},
Expand All @@ -116,7 +116,7 @@ trajectory = Trajectory(
],
additional_histories=[
# Previous conversation segment before compaction
History(
LegacyHistory(
messages_and_choices=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Compacted conversation history: the user asked about quantum entanglement, and the assistant explained..."},
Expand Down Expand Up @@ -152,11 +152,11 @@ for history in histories:

### Data Structure

The `History` class structure:
The legacy `LegacyHistory` payload structure:

```python
@dataclass
class History:
class LegacyHistory:
messages_and_choices: list[dict[str, Any]]
tools: list[Tool] | None = None
```
Expand All @@ -168,7 +168,7 @@ The `Trajectory` class with additional histories:
class Trajectory:
messages_and_choices: list[dict[str, Any]]
tools: list[Tool] | None = None
additional_histories: list[History] = field(default_factory=list)
additional_histories: list[LegacyHistory] = field(default_factory=list)
reward: float | None = None
metrics: dict[str, Any] = field(default_factory=dict)
```
Expand All @@ -178,7 +178,7 @@ class Trajectory:
### Creating a Trajectory with Additional Histories

```python
from art.trajectories import Trajectory, History
from art.trajectories import LegacyHistory, Trajectory

# Create the main conversation
main_messages = [
Expand All @@ -188,14 +188,14 @@ main_messages = [
]

# Create additional histories
history1 = History(
history1 = LegacyHistory(
messages_and_choices=[
{"role": "user", "content": "First subtask"},
{"role": "assistant", "content": "Completing first subtask..."}
]
)

history2 = History(
history2 = LegacyHistory(
messages_and_choices=[
{"role": "user", "content": "Second subtask"},
{"role": "assistant", "content": "Completing second subtask..."}
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ plotting = ["matplotlib>=3.10.1", "seaborn>=0.13.2"]
backend = [
"peft>=0.14.0",
"hf-xet>=1.1.0",
"bitsandbytes>=0.45.2",
"bitsandbytes>=0.45.2,!=0.50.0",
"unsloth==2026.3.3",
"unsloth-zoo==2026.3.1",
"torch==2.11.0",
Expand Down
34 changes: 24 additions & 10 deletions src/art/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,28 @@
from .serverless import ServerlessBackend
from .trajectories import (
AnthropicMessagesHistory,
AnthropicMessageSource,
ChatCompletionsExchange,
ChatCompletionsHistory,
ChatCompletionsMessageSource,
CompletionsExchange,
CompletionsHistory,
CompletionsSource,
CompletionsStringHistory,
CompletionsStringSourceSpan,
CompletionsTokenHistory,
CompletionsTokenSourceSpan,
History,
LegacyHistory,
MessagesExchange,
ResponsesExchange,
ResponsesHistory,
ResponsesItemSource,
TokenFlag,
TokenizedHistory,
TokenizedMultiHistoryTrajectory,
TokenizedTrajectory,
TokenizedTrajectoryGroup,
Tokenizer,
Trajectory,
TrajectoryExchanges,
TrajectoryGroup,
Expand All @@ -98,10 +109,6 @@
capture_auto_trajectory, # ty: ignore[deprecated]
current_trajectory,
current_trajectory_group,
tokenize_trajectories,
tokenize_trajectory,
tokenize_trajectory_group,
tokenize_trajectory_groups,
trajectory,
trajectory_group,
)
Expand Down Expand Up @@ -158,24 +165,31 @@
"TrajectoryExchanges",
"TrajectoryGroup",
"History",
"LegacyHistory",
"TrajectoryHistory",
"ChatCompletionsExchange",
"ChatCompletionsHistory",
"ChatCompletionsMessageSource",
"CompletionsExchange",
"CompletionsHistory",
"CompletionsSource",
"CompletionsTokenHistory",
"CompletionsStringHistory",
"CompletionsTokenSourceSpan",
"CompletionsStringSourceSpan",
"ResponsesExchange",
"ResponsesHistory",
"ResponsesItemSource",
"MessagesExchange",
"AnthropicMessagesHistory",
"AnthropicMessageSource",
"TokenFlag",
"Tokenizer",
"TokenizedHistory",
"TokenizedMultiHistoryTrajectory",
"TokenizedTrajectory",
"TokenizedTrajectoryGroup",
"trajectory",
"trajectory_group",
"tokenize_trajectory",
"tokenize_trajectories",
"tokenize_trajectory_group",
"tokenize_trajectory_groups",
"capture_yielded_trajectory",
"yield_trajectory",
]
4 changes: 2 additions & 2 deletions src/art/langgraph/llm_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from langchain_core.utils.function_calling import convert_to_openai_tool
from langchain_openai import ChatOpenAI

from art.trajectories import History, Trajectory
from art.trajectories import LegacyHistory, Trajectory

from .logging import FileLogger
from .message_utils import convert_langgraph_messages
Expand Down Expand Up @@ -89,7 +89,7 @@ def create_messages_from_logs(logger: FileLogger, trajectory: Trajectory):
trajectory.tools = tools[idx]
else:
trajectory.additional_histories.append(
History(messages_and_choices=converted, tools=tools[idx])
LegacyHistory(messages_and_choices=converted, tools=tools[idx])
)
except Exception:
pass
Expand Down
12 changes: 11 additions & 1 deletion src/art/local/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
)
from ..serving_capabilities import ServingCapabilities
from ..trajectories import Trajectory, TrajectoryGroup
from ..trajectories._selection import automatic_training_model_selector
from ..types import (
Choice,
LocalTrainResult,
Expand Down Expand Up @@ -949,6 +950,12 @@ def _get_packed_tensors(
chat_template_tool_schema_format = self._chat_template_tool_schema_format(
internal_config
)
model_max_sequence_length = self._model_max_sequence_length(model)
training_max_sequence_length = (
min(model_max_sequence_length, packed_sequence_length)
if packed_sequence_length is not None
else model_max_sequence_length
)
tokenized_results = list(
tokenize_trajectory_groups(
tokenizer,
Expand All @@ -958,11 +965,14 @@ def _get_packed_tensors(
image_processor=self._image_processors[model.base_model],
chat_template_kwargs=chat_template_kwargs,
chat_template_tool_schema_format=chat_template_tool_schema_format,
model=automatic_training_model_selector(
self._model_inference_name(model)
),
_max_sequence_length=training_max_sequence_length,
)
)
if not tokenized_results:
return None
model_max_sequence_length = self._model_max_sequence_length(model)
too_long_for_model = [
result
for result in tokenized_results
Expand Down
12 changes: 6 additions & 6 deletions src/art/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,14 @@ def update_chat_completion(
tool_call.function.arguments += (
tool_call_delta.function.arguments
)
if getattr(chunk_choice.delta, "reasoning", None):
if not hasattr(choice.message, "reasoning"):
setattr(choice.message, "reasoning", "")
for field in ("reasoning", "reasoning_content"):
value = getattr(chunk_choice.delta, field, None)
if not value:
continue
setattr(
choice.message,
"reasoning",
getattr(choice.message, "reasoning")
+ getattr(chunk_choice.delta, "reasoning"),
field,
(getattr(choice.message, field, None) or "") + value,
)
chat_completion.service_tier = chunk.service_tier
chat_completion.system_fingerprint = chunk.system_fingerprint
Expand Down
Loading
Loading