Skip to content

feat: enhance query functionality with new filtering options and image rendering capabilities#8

Merged
blizhan merged 3 commits into
mainfrom
003-query-images-terminal-render
Apr 22, 2026
Merged

feat: enhance query functionality with new filtering options and image rendering capabilities#8
blizhan merged 3 commits into
mainfrom
003-query-images-terminal-render

Conversation

@blizhan

@blizhan blizhan commented Apr 22, 2026

Copy link
Copy Markdown
Owner
  • Added support for --epochs flag in query commands to filter results based on epoch ranges.
  • Introduced --head, --tail, and --every flags to limit the number of results returned for both metrics and images.
  • Updated README to reflect new command usage and examples.
  • Improved image rendering in terminal with inline previews and ensured no graphics bytes are output in non-TTY contexts.
  • Enhanced tests to cover new features and ensure stability across query functionalities.

…e rendering capabilities

- Added support for `--epochs` flag in query commands to filter results based on epoch ranges.
- Introduced `--head`, `--tail`, and `--every` flags to limit the number of results returned for both metrics and images.
- Updated README to reflect new command usage and examples.
- Improved image rendering in terminal with inline previews and ensured no graphics bytes are output in non-TTY contexts.
- Enhanced tests to cover new features and ensure stability across query functionalities.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request implements inline terminal image rendering for aimx query images using the textual-image library and introduces new query capabilities including epoch-based filtering and density subsampling (head, tail, every). The changes encompass a new rendering module, lazy image loading from the Aim SDK, and updated CLI argument handling. Review feedback focuses on ensuring compliance with the functional requirement to display the summary table alongside images, improving the robustness of chronological sorting by utilizing direct object attributes, and streamlining the internal rendering API by removing unused parameters.

Comment thread src/aimx/commands/query.py Outdated
Comment on lines +355 to +378
# TTY inline-image extension (US1/US3): only when stdout is a TTY and
# the rendering path is "rich" (not --json / --plain).
from aimx.rendering.image_render import detect_capability, plan_render, render_inline # noqa: PLC0415

capability = detect_capability()
if capability.protocol != "disabled":
plan = plan_render(image_rows, capability, max_images=invocation.max_images)
inline = render_inline(plan)
if inline:
repo = header_info.get("repo", "")
expr = header_info.get("expression", "")
total = len(image_rows)
shown = len(plan.rendered_rows)
compact_header = (
f"Repo: {repo} · {total} matches · images where {expr}"
)
if shown < total:
compact_header += f" · previewing {shown}"
compact_header += "\n"

return QueryCommandResult(exit_status=0, output=compact_header + inline)

summary = render_image_rich_table(image_rows, header_info, no_color=no_color)
return QueryCommandResult(exit_status=0, output=summary)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The current implementation violates functional requirement FR-005 by omitting the summary metadata table when inline images are rendered. The spec explicitly states that the rich summary table MUST be output first, followed by the image blocks. Additionally, the compact_header introduced here is redundant as render_image_rich_table already provides a similar summary header.

    summary = render_image_rich_table(image_rows, header_info, no_color=no_color)

    # TTY inline-image extension (US1/US3): only when stdout is a TTY and
    # the rendering path is "rich" (not --json / --plain).
    from aimx.rendering.image_render import detect_capability, plan_render, render_inline  # noqa: PLC0415

    capability = detect_capability()
    if capability.protocol != "disabled":
        plan = plan_render(image_rows, capability, max_images=invocation.max_images)
        inline = render_inline(plan)
        if inline:
            return QueryCommandResult(exit_status=0, output=summary + "\n" + inline)

    return QueryCommandResult(exit_status=0, output=summary)

Comment on lines +187 to +190
epoch_value = context.get("epoch")
if epoch_value is None:
epoch_value = _first_iter_value(getattr(image, "epochs", None))
step_value = _call_or_value(getattr(image, "first_step", None))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The extraction of epoch and step values for sorting is incomplete. Individual Image objects in Aim 3.x have epoch and step as direct attributes. These should be prioritized over context lookups or sequence-level accessors (like first_step) to ensure that images are correctly sorted chronologically within a run.

Suggested change
epoch_value = context.get("epoch")
if epoch_value is None:
epoch_value = _first_iter_value(getattr(image, "epochs", None))
step_value = _call_or_value(getattr(image, "first_step", None))
epoch_value = getattr(image, "epoch", None)
if epoch_value is None:
epoch_value = context.get("epoch")
if epoch_value is None:
epoch_value = _first_iter_value(getattr(image, "epochs", None))
step_value = getattr(image, "step", None)
if step_value is None:
step_value = _call_or_value(getattr(image, "first_step", None))

Comment on lines +176 to +180
def _render_pil_image(
pil_img: "PILImage.Image",
_target_width: int,
_max_height: int,
) -> "PILImage.Image":

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The parameters _target_width and _max_height are unused in the function body. Since resizing is delegated to textual-image (as noted in the docstring), these parameters should be removed from the signature to simplify the internal API.

def _render_pil_image(
    pil_img: "PILImage.Image",
) -> "PILImage.Image":


try:
pil_img = accessor()
pil_img = _render_pil_image(pil_img, plan.target_width, plan.max_height)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Update the call site to match the simplified signature of _render_pil_image (removing unused width/height arguments).

Suggested change
pil_img = _render_pil_image(pil_img, plan.target_width, plan.max_height)
pil_img = _render_pil_image(pil_img)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 31a4d89955

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/aimx/commands/query.py Outdated
Comment on lines +371 to +375
if shown < total:
compact_header += f" · previewing {shown}"
compact_header += "\n"

return QueryCommandResult(exit_status=0, output=compact_header + inline)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve full image summary when inline previews are shown

When inline rendering succeeds, this branch returns compact_header + inline immediately instead of including render_image_rich_table(...), so interactive TTY users no longer see the full metadata table. With the default --max-images=6, any matches beyond the preview cap become invisible except for a count, which is a functional regression from previous output and prevents inspecting non-previewed rows.

Useful? React with 👍 / 👎.

Comment on lines +216 to +220
console = Console(
file=buf,
force_terminal=True,
width=plan.capability.columns,
highlight=False,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor no-color mode in inline image rendering

Inline rendering always constructs a Console with force_terminal=True and no no_color override, so metadata headers are still ANSI-styled even when users pass --no-color. In TTY runs this breaks the expected contract that no-color disables styled text output, and it also risks leaking escape sequences when users capture interactive output.

Useful? React with 👍 / 👎.

blizhan added 2 commits April 22, 2026 16:46
- Updated version number to 0.3.1 in project files.
- Improved image query command to preserve full rich table while displaying inline previews.
- Added a new test to ensure that interactive inline previews do not hide rows beyond the preview cap.
@blizhan blizhan merged commit 82459f2 into main Apr 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant