CrewAI
A CrewAI tool (BaseTool) that reads pages through Boxline, used by a one-agent crew on your own OpenAI key. Each page renders in a real browser inside a Boxline sandbox.
How it works
Subclass crewai.tools.BaseTool with name, description, args_schema and _run; give it to an Agent with LLM(model="openai/..."), then Crew(...).kickoff().
| Needs | any plan; your own OpenAI key; Python 3.10 to 3.13 (CrewAI does not support 3.14 yet). |
|---|---|
| Site | books.toscrape.com or quotes.toscrape.com, demo sites made for scraping practice. |
| Environment | BOXLINE_API_KEY, OPENAI_API_KEY (your OpenAI key: CrewAI calls OpenAI itself), CREW_MODEL (the model, as provider/model; default openai/gpt-6-luna), QUESTION (your own question). |
| Packages | boxline-sdk, crewai==1.15.23 |
The code
"""CrewAI with Boxline: a CrewAI tool (BaseTool) that reads pages through Boxline, used by a one-agent crew on yourown OpenAI key. Each page renders in a real browser inside a Boxline sandbox, never on this computer. pip install -r requirements.txt && python main.py (BOXLINE_API_KEY and OPENAI_API_KEY; CREW_MODEL, QUESTION)Writes output/result.json: the answer and every tool call."""import jsonimport osfrom pathlib import Pathfrom crewai import LLM, Agent, Crew, Taskfrom crewai.tools import BaseToolfrom pydantic import BaseModel, Fieldfrom boxline import Boxlineout = Path(os.environ.get("OUTPUT_DIR", "output"))question = os.environ.get("QUESTION", 'On books.toscrape.com, what does "Sapiens: A Brief History of Humankind" cost, and how many are in stock?')bx = Boxline()calls = []class FetchInput(BaseModel): url: str = Field(..., description="an http(s) address")class BoxlineFetchTool(BaseTool): name: str = "boxline_fetch" description: str = "Open a web page in a real browser (in a Boxline sandbox) and return it as Markdown with its links." args_schema: type[BaseModel] = FetchInput def _run(self, url: str) -> str: calls.append({"tool": self.name, "input": {"url": url}}) page = bx.fetch(url, format="markdown", links=True) return json.dumps({"url": page["finalUrl"], "status": page["status"], "title": page["title"], "content": page["content"][:12_000], "links": (page.get("links") or [])[:80]})checker = Agent( role="Web researcher", goal="Answer questions about web pages from what the pages say", backstory="You read pages with the boxline_fetch tool and quote exact figures.", tools=[BoxlineFetchTool()], llm=LLM(model=os.environ.get("CREW_MODEL", "openai/gpt-6-luna")), verbose=False,)task = Task(description=question, expected_output="The answer with the exact figures, and the address of the page they came from.", agent=checker)output = Crew(agents=[checker], tasks=[task], verbose=False).kickoff()answer = output.rawfor c in calls: print(f"-> {c['tool']} {json.dumps(c['input'])}")print(f"\n{answer}")out.mkdir(parents=True, exist_ok=True)usage = output.token_usage.total_tokens if output.token_usage else 0(out / "result.json").write_text(json.dumps({"question": question, "answer": answer, "calls": calls, "usage": {"ownModelTokens": usage}}, indent=2, ensure_ascii=False))Install and run
The packages are pinned at the versions the example’s check ran with. It writes to output/ and stops its session when it finishes.
# Python 3.10 to 3.13 or newerexport BOXLINE_API_KEY=… # your Boxline API keyexport OPENAI_API_KEY=… # your own OpenAI keypip install boxline-sdk crewai==1.15.23python main.pyWhat its check proves
It checks that the crew used the Boxline tool and answered with the price and stock the demo shop shows. To run it from a clone of the examples (git clone https://github.com/Boxline-dev/examples.git), go to examples/integrations/crewai, run the commands above, then check the result from the same folder: npx tsx check.ts output.
Source: github.com/Boxline-dev/examples/integrations/crewai on GitHub. See all integrations.
These docs describe a beta API. Endpoints, fields and SDK methods may change before general availability; breaking changes will be listed in the changelog.