Skip to content

Make loom.agent importable without a contract package - #1

Open
Arunima1405 wants to merge 1 commit into
mainfrom
fix/loom-agent-imports
Open

Make loom.agent importable without a contract package#1
Arunima1405 wants to merge 1 commit into
mainfrom
fix/loom-agent-imports

Conversation

@Arunima1405

Copy link
Copy Markdown
Collaborator

Problem

Three defects found while building an end-to-end example of AgentLoop
against a failing contract (companion PR in the Graphite repository). Two
are import bugs; both were reproduced before fixing.

1. loom.agent cannot be imported from a clean install

loom/agent/task_gen.py did from graphite import ContractException at
module scope, and loom/agent/__init__.py imports task_gen. Loom declares
no graphite dependency — pyproject.toml lists pydantic and pydantic-ai
— and the README states that Graph-IR support and Contracts live in the
separate Graphite package. So after pip install loom-workflow:

>>> from loom.agent import AgentLoop
ImportError: No module named 'graphite'

loom.core imports fine; the whole agent half of the package is
unreachable. Reproduced by blocking graphite on sys.meta_path.

The import existed only to recognise a contract failure inside
TaskGen._prompt. That is now duck-typed:

@staticmethod
def _contract_failures(failure):
    failures = getattr(failure, "failures", None)
    return failures if isinstance(failures, Mapping) and failures else None

ContractException.failures is already dict[str, ContractResult], so the
rendered feedback is byte-identical for a real ContractException, and a
non-contract exception still renders as Task/runtime exception: ...
exactly as before. _prompt becomes a classmethod to reach the helper;
its signature and output are otherwise unchanged.

This also restores the architecture the README describes — Loom core stays
domain-neutral and requires no graph, IR, or contract package — and keeps
Provider/TaskGen usable by a caller whose contracts come from somewhere
other than Graphite.

2. Path used in an annotation but never imported

loom/agent/agent.py annotates AgentContext.draft as Mapping[str, Path]
with no from pathlib import Path. from __future__ import annotations
defers it, so it stays hidden until something resolves the annotation:

>>> typing.get_type_hints(AgentContext.draft.fget)
NameError: name 'Path' is not defined

One-line fix.

3. Stale example reference

examples/agent moved to the Graphite repository in eedcb52, but the
README still described it as living here, and still told the reader to
uncomment lines by hand to reach the successful task. It now points at
Graphite, where the example runs the loop through the contract failure to
convergence rather than stopping at it.

What is deliberately not here

Bug fixes only — no new abstractions, no new dependencies, no behaviour
change to AgentLoop, PipelineRunner, or Provider. The example itself,
including the agents that drive the loop, lives in the companion Graphite PR
so it stays out of this package.

Verification

With graphite blocked on sys.meta_path:

from loom.agent import AgentLoop                    # imports
typing.get_type_hints(AgentContext.draft.fget)      # {'return': Mapping[str, Path]}
TaskGen._prompt("lower-dense", src, contract_exc)   # same feedback text
TaskGen._prompt("lower-dense", src, ValueError())   # Task/runtime exception: ...

Downstream, the Graphite example's pytest examples/agent/test_agent_loop.py
passes 3/3 against this branch.

`loom.agent.task_gen` imported `graphite.ContractException` at module import
time, so `from loom.agent import AgentLoop` raised ImportError on a plain
`pip install loom-workflow` — Loom declares no graphite dependency, and
contracts live outside this package by design. The contract-failure shape is
now duck-typed, which keeps the same feedback text without the import.

Also import `Path` in `loom.agent.agent`, where it was used in an annotation
but never imported (`get_type_hints(AgentContext.draft.fget)` raised
NameError), and point the README at the agent example's current home in the
Graphite repository.
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