Skip to main content

Overview

With harness = "langgraph" or harness = "crewai" a session runs your own Python agent against a Veri model. Point the environment at a git repository and the entry to load; Veri clones it into the sandbox, installs its requirements, and turns each message into one run whose messages, tool calls and token usage land in the session transcript. Everything else (egress rules, secrets, MCP servers, checkpoints, pause and resume) works as for every other harness.

LangGraph

A repository in the layout langgraph dev uses works as is:
src/support/graph.py
environment.toml
entry is a graph id from langgraph.json, or a path and attribute directly (src/support/graph.py:graph, support.graph:graph). The attribute can be a compiled graph, a StateGraph, or a function (sync or async) that returns one. Veri compiles or recompiles it with its own checkpointer, so the conversation (the thread named after the session id) survives pauses and resumes and is copied into each fork. The graph’s input state should have a messages key; each message you send is added to it.

CrewAI

support_crew/crew.py
environment.toml
entry is package.module:attribute: a Crew, a function returning one (called again for every message, so each run starts fresh), or a @CrewBase class. Each run’s inputs are {"message": ..., "history": ...}; the history is the session’s earlier turns as text, so a crew can hold a conversation. Task outputs become agent.message events, one per task.

Requirements and the sandbox

  • The repository is cloned into /workspace/agent at the first message (ref is a branch, tag or commit; subdir is the agent’s directory). The repository must be public for now: private repositories need GitHub access, which is coming soon.
  • agent.requirements (default: requirements.txt in the agent directory, when present) and, for LangGraph, the package names in langgraph.json dependencies are installed into /workspace/.veri/venv, on top of the preinstalled LangGraph, langchain-openai, langchain-mcp-adapters and CrewAI. The agent directory and its src/ are importable.
  • A fetch, install or import that fails ends the first turn and fails the session with an error whose source is harness_setup; its message has the git, pip or Python error.
  • Everything lives under /workspace, so a resumed, rolled-back or forked session neither clones nor installs again.
  • Without agent.repo, entry names files already under /workspace, for example ones you uploaded with the session files API before the first message. Without an [agent] block at all, Veri’s built-in example agent runs.
  • What your code prints goes to the harness log, not the transcript.

The model

The environment’s model is wired in for both frameworks, and for code that reads the usual variables: veri_pyagent.chat_model() (a LangChain ChatOpenAI) and veri_pyagent.crewai_llm() (a crewai.LLM) return models already set up, with an output budget that fits the deployment’s served context. Keyword arguments you pass override the defaults.

Tools, MCP and permissions

  • Your graph’s or crew’s own tools run as written. Veri sees their calls and results in the transcript but does not govern them.
  • The environment’s MCP servers: await veri_pyagent.mcp_tools() (LangChain tools) or veri_pyagent.mcp_servers() (for crewai.Agent(mcps=...)). Their credentials are placeholders too. For crewai, address each MCP server by hostname, not IP address.
  • Permission rules apply to those MCP tools only: mcp, mcp.<server> and mcp.<server>.<tool>, last match wins, with default = "allow". A denied tool is never handed to your agent. Shell, file and web rules are refused, and so is ask.

Egress

The session reaches only what its egress rules allow, so plan for every host your agent calls:
  • The repository’s host is allowed automatically, for git’s requests on that repository’s path.
  • PyPI (pypi.org, files.pythonhosted.org) and GitHub are allowed by the default coding preset. With egress_preset = "locked_down", add them as egress_rules if you have requirements to install.
  • Any other API your tools call needs an allowed_hosts entry or an egress_rules rule, and a secret scoped to its host for credentials.
Egress rules and secret scoping are the boundary for everything your code does; see Environments.