Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agentflow-java

CI license

AgentOps for Java: the guard-then-evaluate half of the AgentOps lifecycle in one AgentOpsTask, built on guardflow-java and evalflow-java. The Java counterpart to the Rust agentflow umbrella crate / agentflow-go — but not a mechanical re-export of either.

Why this isn't just a re-export package

Rust's agentflow bundles nine sibling crates behind one dependency via pub use. Java (like Go) has no equivalent of re-exporting another package's full API under a new name, and mechanically wrapping every exported type from eight independent libraries would be both unidiomatic and a maintenance trap. Java code composes small libraries by depending on them directly:

Stage Java library
Orchestrate graphflow-stream-java
Guard guardflow-java
Act-guard actionguard-java
Validate schemaflow-java
Evaluate evalflow-java
Checkpoint rollbackflow-java
Trace traceflow-java
Cache cacheflow-java
Remember memoryflow-java

Add whichever stages you need and nest their Handler decorators — the same way Servlet Filters compose:

Handler handler = TraceFlow.withTrace("call_llm",
    CacheFlow.withCache(myLlmHandler, cache, keyFn, ttl),
    tracer
);

What agentflow-java actually provides is the one piece of the Rust crate that's real glue code, not re-export: AgentOpsTask.

Install

Not published to Maven Central. Build the two dependencies locally, then this repo:

git clone https://github.com/thaicn1712/guardflow-java && (cd guardflow-java && mvn -q install -DskipTests)
git clone https://github.com/thaicn1712/evalflow-java && (cd evalflow-java && mvn -q install -DskipTests)
<dependency>
    <groupId>io.github.thaicn1712</groupId>
    <artifactId>agentflow-java</artifactId>
    <version>0.1.0</version>
</dependency>

Usage

AgentOpsTask task = AgentOpsTask.wrap(myLlmHandler)
    .withGuard(Guard.create().with(new MinLength(15)))
    .withMaxAttempts(3)
    .withMetric(new F1Score());

AgentOpsResult result = task.run(input, "the quick brown fox jumps over a lazy dog");
// result.output()               -- the accepted (possibly retried) response
// result.scores().get("f1_score") -- an evalflow.MetricResult

myLlmHandler is any HandlerString run(String input) throws Exception.

The guard is soft, not a hard failure

If a Guard is set and never passes within maxAttempts, run does not throw — it falls back to the last (still-invalid) attempt, the same as the Rust and Go originals. This is easy to get wrong: check result.scores() yourself, or inspect result.output() against your own validity check, if you need to detect and act on "the guard never actually passed." Don't assume a normal return from run means the output was valid.

Examples

mvn -q compile exec:java -Dexec.mainClass=io.github.thaicn1712.agentflow.examples.FullLifecycleExample

License

MIT

About

AgentOps for Java: guard-then-evaluate task wrapper, built on guardflow-java + evalflow-java

Topics

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages