Skip to content

Partial WEKA Trace Format Support (without subagents) - #972

Open
SkiHatDuckie wants to merge 27 commits into
vllm-project:mainfrom
SkiHatDuckie:weka-trace
Open

Partial WEKA Trace Format Support (without subagents)#972
SkiHatDuckie wants to merge 27 commits into
vllm-project:mainfrom
SkiHatDuckie:weka-trace

Conversation

@SkiHatDuckie

@SkiHatDuckie SkiHatDuckie commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds WEKA trace format support to GuideLLM. This PR includes basic handling and parsing of the format, updated tests and documentation, as well as some tweaking of preexisting formats. Subagent conversations, tool call events and nonlinear histories are still in active development, and will be added in a separate PR (ideally after #935 is merged).

This include new utilities for unwrapping JSON in utils/json_unwrap.py, used to parse and flatten conversations for trace replay.

Details

trace_weka.py (new)

  • Based off of this spec
  • Handles hash IDs and conversation-scoping
  • Currently missing:
    • Subagent conversations
    • Tool call events
    • Nonlinear histories
    • Handling of fields such as models, block_size, output_types, etc... (variable importance)
  • Accommodates for datasets which may not match the spec exactly by accepting any non-negative hash ID as valid and dropping partially filled hash IDs if they exist

test_trace_weka.py (new)

json_unwrap.py (new)

  • Added VirtualColumnLocation
  • Added functions construct_virtual_column_locations, unzip_virtual_column_locations, try_json_load, is_json_serializable and get_json_column_names

test_json_unwrap.py (new)

trace_common.py

  • Added conversation_id_column to TraceDataArgs
  • Rearranged helper function to fit new required checks
  • Added/updated helper functions to handle wrapped columns
  • Modified TraceExamplesIterable to handle localize relative timestamps to the conversation (if one exists)
  • Added optional method reset to TraceFormatBase
  • Moved dataset loading and validation up to the deserializer instead of the examples iterable.

trace_mooncake.py

  • Switch to storing token blocks as set[tuple[int, ...]] instead of list[list[int]] for minor performance boost
  • Switch to storing hash IDs in a dictionary instead of a lookup table

test_trace_common.py, test_trace_minimal.py & test_trace_mooncake.py

  • Minor tweaks to helper functions
  • New test for input token length matching or bordering the hash ID block size in test_trace_mooncake.py
  • New test for virtual columns in test_trace_common.py

trace_replay.md

  • Added documentation for weka
  • Included a warning about WIP features

datasets.md

  • Updated --data kind options list

Test Plan

  • tox -e lint-check && tox -e type-check
  • tox -e test-unit

Example datasets:
semianalysisai/cc-traces-weka-no-subagents-051226

Related Issues

Partial completion of #967


  • "I certify that all code in this PR is my own, except as noted below."

Use of AI

  • Includes code generated or substantially modified by an AI agent
  • Includes tests generated or substantially modified by an AI agent

NOTE: the Generated-by or Assisted-by trailers should be used in git commit messages when code or tests were generated or substantially modified by an AI agent, as described in the project's DEVELOPING.md file.


git log

commit 8868aaa
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jun 30 13:57:55 2026 -0400

Add files

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 75371ff
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jun 30 14:05:52 2026 -0400

Update field description

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit e049ce8
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jun 30 14:18:54 2026 -0400

Add stubs

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit dc1920e
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jun 30 14:19:39 2026 -0400

Add missing trailing whitespace

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit a965b40
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jun 30 16:32:54 2026 -0400

Implement trace format & args

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 60cfcbd
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Wed Jul 1 11:39:42 2026 -0400

Add tests

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 2e1d969
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Wed Jul 1 12:12:17 2026 -0400

Test prompts matching or bordering block size

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit f28a347
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Wed Jul 1 13:20:29 2026 -0400

Update tests

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 1c37aaf
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Wed Jul 1 13:31:56 2026 -0400

Update trace format docs

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 7fef74a
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Wed Jul 1 14:10:31 2026 -0400

Update trace_replay.md

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 3450fc3
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Mon Jul 13 13:46:03 2026 -0400

Reapir tests

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 4edc5da
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Wed Jul 15 13:52:15 2026 -0400

Indicate private functions

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 58d8dab
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Wed Jul 15 13:56:37 2026 -0400

Update trace_replay.md

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 581f89b
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Wed Jul 15 13:58:55 2026 -0400

Make mdformat happy

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 4d7f58d
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jul 21 15:59:50 2026 -0400

Add json utils + impl in trace_common

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit ee391f0
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jul 21 16:20:35 2026 -0400

Refactor

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 16758aa
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jul 21 16:37:37 2026 -0400

Handle unserializable python dicts

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit fdb864f
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Wed Jul 22 12:00:52 2026 -0400

Improve json_unwrap tests

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 4aec222
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Wed Jul 22 12:45:52 2026 -0400

Improve trace_common test coverage

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 8310217
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Mon Jul 27 14:35:22 2026 -0400

Handle multi-conversation datasets

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit c1e2312
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Mon Jul 27 17:19:45 2026 -0400

Store token blocks as tuples

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 8622c0d
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jul 28 07:50:51 2026 -0400

Repair tests

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 9d04e2b
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jul 28 10:28:24 2026 -0400

Tolerate partially filled hash ID

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit a8872bb
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jul 28 11:40:27 2026 -0400

Improve test coverage

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit de082bb
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jul 28 12:02:54 2026 -0400

Fix linting

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit a833784
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jul 28 14:25:33 2026 -0400

Update docs

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

commit 5fe0d30
Author: SkiHatDuckie SkiHatDuckie@gmail.com
Date: Tue Jul 28 14:54:45 2026 -0400

Fix typo

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>

Signed-off-by: SkiHatDuckie SkiHatDuckie@gmail.com

Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
Signed-off-by: SkiHatDuckie <SkiHatDuckie@gmail.com>
@dbutenhof dbutenhof added internal filed by core contributor or associate priority-critical labels Jul 29, 2026
@dbutenhof dbutenhof added the feature Represents a new user-visible feature label Jul 29, 2026
@dbutenhof dbutenhof added this to the v0.8.0 milestone Jul 29, 2026
@sjmonson sjmonson mentioned this pull request Jul 29, 2026
3 tasks

@jaredoconnell jaredoconnell left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I have a few comments.

Does this automatically support column names t / in / out? Sources like this state that it's what the spec is.

processor,
faker,
)
return prompt + " " + remainder

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either the prompt or the remainder could be empty, right? If so, the logic here needs to return "" if both are empty, the non empty one if only one is non-empty, and use the current logic if both are not empty.

class ColumnSearchResult:
status: Status
checked_json_columns: bool
apropos_column_names: Sequence[str | VirtualColumnLocation]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is apropos supposed to mean?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apropos in this case means "relevant". I had some trouble coming up with a good name since the field could either be a list of missing required columns or a list of the locations of all virtual column locations found. Maybe I should just change it to relevant_column_names?

"""Required columns must all be stored within the same column."""
completely_missing = set(target_columns)
for col in json_column_names:
parsed = sample_row[col]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that a call to try_json_load should go here? The AI analysis determined that this could be a JSON string that is then rejected by _is_supported_json_data_type

If so, a matching call in _make_columns_from_virtual may be needed, too.

)


def _create_prompt_from_hash_ids(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be extracted to trace_common and shared with mooncake?

@dbutenhof dbutenhof left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few initial comments. I haven't gotten far: and after spending most of the morning wrestling with AIPCC and GitLab workflows, I'm now heading out to hike (in the rain) before continuing this afternoon. Figured I might as well drop what I already got ...


**NOTE:** :construction: While the format is accepted, some features such as subagent conversations, tool call events and non-linear histories are still in active development. The results from datasets including these features will be unreliable.

The WEKA format expects a column with conversation UUIDs that is not wrapped within another column. The timestamp, input token length, output token length and hash IDs columns will very likely be wrapped inside another column (ex. "requests"), representing an entire conversation. Ensure these four virtual columns are wrapped in the same column. GuideLLM will handle the unwrapping and parsing of these trace sessions internally.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of the predictive "will very likely be", how about a more direct allowance ("may be").

Also, this suggests they "may not be", in which case the following sentence ("ensure [they] are wrapped in the same column") becomes misleading. These conditions should be combined: so maybe, "The [...] columns may be wrapped inside another column [...]: if so, they must all be wrapped inside a single column." And perhaps even followed by saying that if they're not all wrapped inside a single column, they must each appear as a separate column? (That is, it sounds like one cannot combine "some wrapped" with "some not wrapped"?)


The WEKA format expects a column with conversation UUIDs that is not wrapped within another column. The timestamp, input token length, output token length and hash IDs columns will very likely be wrapped inside another column (ex. "requests"), representing an entire conversation. Ensure these four virtual columns are wrapped in the same column. GuideLLM will handle the unwrapping and parsing of these trace sessions internally.

Similar to Mooncake, WEKA uses prefix-based cache hash IDs. The original [specification](https://github.com/callanjfox/agentic-coding-analysis/blob/master/docs/TRACE_FORMAT.md) for the trace requires hash IDs to be 1 or greater, and for trailing hash IDs to be dropped if there are not enough input tokens to fill the hash ID block size. To accommodate for datasets which may not follow the specification exactly (ex. [semianalysisai/cc-traces-weka-no-subagents-051226](https://huggingface.co/datasets/semianalysisai/cc-traces-weka-no-subagents-051226)), GuideLLM will accept any non-negative integer as a valid hash ID, and will drop partially filled hash IDs if they still exist.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the "still" in "if they still exist" operational here? (It's not clear from previous text exactly what might have already removed them.) Should this just be "if they exist".

self.config, row, self.processor, self.faker
)
relative_timestamp = timestamps[row_idx] - timestamps[0]
relative_timestamp = timestamps[row_idx] - (conv_start_ts or timestamps[0])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you have timestamps outside the loop, can't you just set conv_start_ts = timestamps[0] in the first place and avoid the or???

@SkiHatDuckie

Copy link
Copy Markdown
Collaborator Author

Does this automatically support column names t / in / out? Sources like this state that it's what the spec is.

Currently no. I'll change the defaults for WEKA so that it fits the more common names.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Represents a new user-visible feature internal filed by core contributor or associate priority-critical

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants