GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — refactor: extract duplicated request validators into core utilities by devin-ai-integration[bot] · Pull Request #53 · AlmanacCode/codealmanac

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 24, 2026

Copy link
Copy Markdown

Summary

Two Pydantic field validators were copy-pasted across request/model modules. This folds them into core/:

  • Non-negative limit — the same validator appeared 6 times (services/search, services/index, services/runs, and three in services/viewer). Consolidated into core.models:

    def _require_non_negative_limit(value): ...  # "limit must be non-negative"
    NonNegativeLimit         = Annotated[int | None, AfterValidator(...)]  # optional, default None
    RequiredNonNegativeLimit = Annotated[int,        AfterValidator(...)]  # required, e.g. default 50

    Fields become limit: NonNegativeLimit = None / limit: RequiredNonNegativeLimit = 50, dropping the per-model @field_validator/@classmethod boilerplate.

  • Optional-text — the if value is None: return None; return required_text(...) pattern appeared 5 times (services/runs/models, workflows/build ×2, workflows/garden, workflows/ingest). Consolidated into core.text.optional_text(value, field_name); each validator now delegates in one line, preserving its per-model error label.

Field-specific validators with distinct messages (page_limit, transcript/filesystem size, harness count/duration) were intentionally left alone — merging them would change error strings and over-abstract.

Why

Reduce copy-paste and give these validators one home so behavior/wording stays consistent as new request types are added. Net −34 lines across 10 files.

Note: the per-source errors.py duplication (unavailable_runtime/first_error_line) was deliberately not touched — tests/test_architecture.py enforces that split-by-responsibility layout.

Verification

uv run pytest        # 564 passed
uv run ruff check .  # All checks passed!

Also confirmed error messages/accept-reject behavior are byte-for-byte identical (negative limit → "limit must be non-negative"; required-int limit=None still rejected; empty title → "build request text must not be empty"; None accepted).

Docs and wiki

  • Not applicable.

Notes for reviewers

NonNegativeLimit keeps the validator inside Annotated[int | None, ...] (rather than Annotated[int, ...] | None) so a single clean ValidationError is produced — matching the previous @field_validator output that surfaces via cli/execution.py.

Link to Devin session: https://app.devin.ai/sessions/2ec4dbc36bd94d9da6e2b3e9ad796454
Requested by: @rohans0509

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@rohans0509 @devin-ai-integration
refactor: extract duplicated request validators into core utilities
8728896
Consolidate the byte-identical non-negative-limit validator (6 copies) into
core.models.NonNegativeLimit / RequiredNonNegativeLimit, and the optional-text
validator (5 copies) into core.text.optional_text. Validation behavior and
error messages are unchanged.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@rohans0509 rohans0509 self-assigned this Jul 24, 2026
@devin-ai-integration

devin-ai-integration Bot commented Jul 24, 2026

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This branch has not been deployed

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

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@rohans0509 rohans0509

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@rohans0509
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.