Skip to content

test(plan_actions): repair _InputStub after model_copy/model_dump usage#929

Merged
rrajan94 merged 1 commit intoTracer-Cloud:mainfrom
mayankbharati-ops:fix/plan-actions-input-stub-model-copy
Apr 25, 2026
Merged

test(plan_actions): repair _InputStub after model_copy/model_dump usage#929
rrajan94 merged 1 commit intoTracer-Cloud:mainfrom
mayankbharati-ops:fix/plan-actions-input-stub-model-copy

Conversation

@mayankbharati-ops
Copy link
Copy Markdown
Contributor

Summary

PR #807 added a masking round-trip in node_plan_actions:

```python
input_data = input_data.model_copy(
update={k: masking_ctx.mask_value(v) for k, v in input_data.model_dump().items()}
)
```

The matching test (`test_node_plan_actions_emits_retrieval_controls`) was not updated, so its `_InputStub` — which only defines `tool_budget = 10` — raises on every CI run since #807 landed:

```
E AttributeError: '_InputStub' object has no attribute 'model_copy'
app/nodes/plan_actions/node.py:55: AttributeError
```

This breaks the `test (ubuntu-latest)` CI job for every PR currently in flight against `main` and blocks merges.

Fix

Add the two pydantic-surface methods the production code path uses, keeping `_InputStub` a thin stub rather than dragging in a full `BaseModel`:

  • `model_dump()` returns a dict carrying `tool_budget`.
  • `model_copy(update=...)` returns a new `_InputStub` with the update applied via `setattr`.

Verification

  • `pytest tests/nodes/plan_actions/test_node_plan_actions.py`: 1 passed.
  • `ruff check` and `ruff format --check`: clean.

Scope

One file (the test), 14 inserted lines, 0 production-code change.

PR Tracer-Cloud#807 added a masking round-trip in ``node_plan_actions``:

    input_data = input_data.model_copy(
        update={k: masking_ctx.mask_value(v) for k, v in input_data.model_dump().items()}
    )

The matching test (``test_node_plan_actions_emits_retrieval_controls``)
was not updated, so its ``_InputStub`` (which only defines
``tool_budget = 10``) raises:

    AttributeError: '_InputStub' object has no attribute 'model_copy'

This breaks the ``test (ubuntu-latest)`` CI job for every PR opened
against ``main`` after Tracer-Cloud#807.

Add the two pydantic-surface methods the production code path uses,
keeping ``_InputStub`` as a thin stub rather than dragging in a full
``BaseModel``:

- ``model_dump`` returns a dict carrying ``tool_budget``.
- ``model_copy(update=...)`` returns a new ``_InputStub`` with the
  update applied via ``setattr``.

After the fix the test passes locally; ruff check + format clean.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 25, 2026

Greptile Summary

This test-only PR repairs _InputStub in test_node_plan_actions_emits_retrieval_controls by adding thin model_dump() and model_copy() implementations that mirror the pydantic surface called by node_plan_actions since PR #807, unblocking CI for all in-flight PRs against main.

Confidence Score: 5/5

Safe to merge — single test file change, no production code modified, fixes a broken CI gate.

The fix is minimal, correct, and scoped entirely to the test. Both added methods faithfully replicate the pydantic surface (model_dump / model_copy) that production code invokes, the forward-reference annotation -> _InputStub is valid because from future import annotations is already in scope, and the PR author confirms the test passes. No P0/P1 findings exist.

No files require special attention.

Important Files Changed

Filename Overview
tests/nodes/plan_actions/test_node_plan_actions.py Adds model_dump() and model_copy() stubs to _InputStub so it satisfies the pydantic-surface calls introduced in node_plan_actions by PR #807; one clean, targeted fix.

Sequence Diagram

sequenceDiagram
    participant Test as test_node_plan_actions_emits_retrieval_controls
    participant Node as node_plan_actions
    participant Stub as _InputStub
    participant Mask as MaskingContext
    participant Builder as build_plan_actions (monkeypatched)

    Test->>Node: call with state dict
    Node->>Stub: InvestigateInput.from_state(state) → _InputStub()
    Node->>Mask: MaskingContext.from_state(state)
    Node->>Stub: input_data.model_dump() → {"tool_budget": 10}
    Node->>Mask: mask_value(v) for each field
    Node->>Stub: input_data.model_copy(update={...}) → new _InputStub
    Node->>Builder: build_plan_actions(input_data=...) → (plan, ...)
    Node->>Test: return {planned_actions, retrieval_controls, ...}
    Test->>Test: assert retrieval_controls emitted correctly
Loading

Reviews (1): Last reviewed commit: "test(plan_actions): repair _InputStub af..." | Re-trigger Greptile

@rrajan94
Copy link
Copy Markdown
Collaborator

This looks good to me. The stub now correctly mirrors the model_dump / model_copy usage in node_plan_actions without pulling in full Pydantic, and it fixes the broken test while staying tightly scoped to the test file.

CI is green and there are no production code changes. Merging ✅

@rrajan94 rrajan94 merged commit 0a7356b into Tracer-Cloud:main Apr 25, 2026
7 checks 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.

2 participants