Skip to content

Conversation

mwildehahn
Copy link

LMK how you feel about this -- I want to start on #61 but I wanted to have a more solid foundation of types before adding to that so I installed pyright and then leveraged codex to add the minimal types necessary to get pyright passing. I left out the examples and there were also some issues with dspy since dspy depends on gepa there is a circular import.

I'm not trying to open a can of worms with dynamic vs strictly typed python but I find it much easier to maintain / extend when there are clear typing contracts of the library.

@LakshyAAAgrawal
Copy link
Contributor

Dear @mwildehahn ,

Thank you very much for the PR. I love types!

Pointers:

  1. Can you look at the failing ruff above?
  2. Can you introduce type checking as part of the CI pipeline or tests? I don't want strict type checking, as that can unnecessarily raise the bar to make changes to the code, but I would like to have soft type-checking, such that, the type checker ensures that all the type annotations that are already present are satisfied, but those that aren't are still OK. What do you think?

@mwildehahn
Copy link
Author

mwildehahn commented Oct 6, 2025 via email

"src/gepa/adapters/generic_rag_adapter",
"src/gepa/adapters/anymaths_adapter",
"src/gepa/adapters/terminal_bench_adapter",
"tests/test_rag_adapter/",
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't the entire tests directory be ignored?

assert experiment is not None
assert experiment is not None
assert experiment is not None
assert experiment is not None
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be an error

scores.append(score)

if capture_traces:
if capture_traces and trajectories is not None:
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be an assert instead.

src/gepa/api.py Outdated
Comment on lines 33 to 57
def _is_default_datainst(candidate: object) -> TypeGuard[DefaultDataInst]:
if not isinstance(candidate, dict):
return False
input_text = candidate.get("input")
additional_context = candidate.get("additional_context")
answer = candidate.get("answer")
if not isinstance(input_text, str) or not isinstance(answer, str):
return False
if not isinstance(additional_context, dict):
return False
return all(isinstance(key, str) and isinstance(value, str) for key, value in additional_context.items())


def _is_default_dataset(dataset: Sequence[object]) -> TypeGuard[list[DefaultDataInst]]:
if not isinstance(dataset, list):
return False
return all(_is_default_datainst(item) for item in dataset)


def optimize(
seed_candidate: dict[str, str],
trainset: list[DataInst],
valset: list[DataInst] | None = None,
adapter: GEPAAdapter[DataInst, Trajectory, RolloutOutput] | None = None,
task_lm: str | Callable | None = None,
trainset: list[DataInstT],
valset: list[DataInstT] | None = None,
adapter: GEPAAdapter[DataInstT, TrajectoryT, RolloutOutputT] | None = None,
task_lm: str | TaskModelCallable | None = None,
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please clarify why these methods are created?

RolloutOutputT = TypeVar("RolloutOutputT")


def _is_default_dataset(value: object) -> TypeGuard[list[DefaultDataInst]]:
Copy link
Author

Choose a reason for hiding this comment

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

@LakshyAAAgrawal I couldn't find a way around adding this type guard and the optimize + _optimize_impl. The issue is trying to maintain a fully generic optimize function but then also provide the default adapter if none is provided.

We have to do the type guard to validate the default dataset and then can init the default adapter and pass it.

I was trying to avoid changing the public API for this, lmk if there is something else you'd want to see here.

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