Reactive, professional Java integration layer between Firefly Framework services and
fireflyframework-agentic, the Python GenAI metaframework.
- Overview
- Why a bridge?
- Module Layout
- Requirements
- Installation
- Quick Start
- Configuration
- Conversation API
- Streaming
- Queue Dispatch
- Observability
- Security
- Documentation
- Contributing
- License
fireflyframework-agentic-bridge is the canonical Java client for
fireflyframework-agentic. It speaks every protocol the Python service
exposes — REST, Server-Sent Events, WebSockets, Kafka, RabbitMQ, Redis —
through a single, fluent, reactive façade.
The bridge is not a thin HTTP wrapper. It maps every concept on the agentic side (multimodal prompts, conversations, streaming modes, agent catalog, queue routing) into typed, immutable Java records that fit naturally into Firefly Framework microservices. Resilience patterns, observability, and Spring Boot autoconfiguration are first-class concerns.
graph LR
JAVA[Spring Boot service<br/>WebFlux + Reactor] --> BRIDGE[fireflyframework-agentic-bridge]
BRIDGE -->|REST + SSE| AGENTIC[fireflyframework-agentic<br/>FastAPI host]
BRIDGE -->|WebSocket| AGENTIC
BRIDGE -->|Kafka / RabbitMQ / Redis| QUEUE[Message broker]
QUEUE --> CONSUMER[fireflyframework-agentic<br/>queue consumers]
CONSUMER --> AGENTIC
Java services in the Firefly ecosystem need to integrate with agentic
workloads — RAG pipelines, summarisers, classifiers, multi-step reasoning
agents — without leaking the underlying transport into business logic.
Hand-rolling a WebClient against the agentic REST endpoints works for
single calls but quickly degrades into copy-paste once you need streaming,
conversation IDs, queue dispatch, or distributed tracing.
This module is the professional, batteries-included answer:
- One dependency (
fireflyframework-agentic-bridge-starter) wires everything up via Spring Boot autoconfiguration. - Zero stubs — every public API has a working implementation.
- Faithful protocol — the on-the-wire JSON matches the Pydantic models
in
fireflyframework_agentic.exposure.rest.schemasexactly, so existing agents work without any server-side changes. - Reactive everywhere —
Mono/Fluxend to end; no thread blocking.
| Module | Purpose |
|---|---|
fireflyframework-agentic-bridge-core |
SDK: builders, transports, conversation manager, exception hierarchy. |
fireflyframework-agentic-bridge-autoconfigure |
Spring Boot 3 auto-configuration, properties, Actuator health indicator. |
fireflyframework-agentic-bridge-starter |
Convenience starter that pulls in core, autoconfigure, WebFlux, Actuator. |
fireflyframework-agentic-bridge-samples |
Runnable Spring Boot sample exercising every transport. |
See docs/ARCHITECTURE.md for the full design
document.
- Java 21+ (Java 25 default — compile with
-Pjava21for backwards compat). - Spring Boot 3.5.x.
- A reachable
fireflyframework-agenticdeployment exposing its REST application factory (create_agentic_app).
<dependency>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-agentic-bridge-starter</artifactId>
<version>26.04.01</version>
</dependency><dependency>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-agentic-bridge-core</artifactId>
<version>26.04.01</version>
</dependency>firefly:
agentic-bridge:
primary:
base-url: http://agentic.platform.local:8000
auth:
type: bearer
token: ${AGENTIC_TOKEN}@Service
public class SummariserService {
private final AgenticClient agentic;
public SummariserService(AgenticClient agentic) {
this.agentic = agentic;
}
public Mono<String> summarise(String document) {
return agentic.invoke("summariser", AgentRequest.of(document))
.map(response -> response.outputAsString(/* mapper */));
}
}AgenticClient client = AgenticClient.builder("primary")
.baseUrl("http://agentic.platform.local:8000")
.auth(AuthStrategy.bearer(System.getenv("AGENTIC_TOKEN")))
.timeout(Duration.ofSeconds(60))
.retry(r -> r.maxAttempts(3).initialBackoff(Duration.ofMillis(250)))
.build();
AgentResponse response = client.invoke("summariser", AgentRequest.of("…"))
.block();Every setting lives under firefly.agentic-bridge.*. The complete
reference is in docs/CONFIGURATION.md.
firefly:
agentic-bridge:
enabled: true
primary:
name: primary
base-url: http://agentic.platform.local:8000
connect-timeout: 5s
response-timeout: 60s
write-timeout: 30s
compression: true
follow-redirects: false
require-tls: false
user-agent: my-service/1.0.0
max-in-memory-size: 16777216
auth:
type: bearer # or NONE / API_KEY
token: ${AGENTIC_TOKEN}
retry:
enabled: true
max-attempts: 3
initial-backoff: 250ms
max-backoff: 5s
jitter: true
circuit-breaker:
enabled: false # opt-in; requires resilience4j on the classpath
publishers:
kafka-async:
type: KAFKA
topic: agent-invocations
bootstrap-servers: kafka:9092
rabbit-batch:
type: RABBITMQ
exchange: agent.events
routing-key: summary.long
url: amqp://guest:guest@rabbit:5672
redis-stream:
type: REDIS
channel: agentic.stream
url: redis://redis:6379ConversationManager conversations = client.conversations();
Conversation session = conversations.create().block();
client.invoke("assistant",
AgentRequest.of("Summarise the last call.")
.withConversationId(session.id()))
.block();
List<ConversationMessage> history = conversations.history(session.id())
.collectList()
.block();
conversations.delete(session.id()).block();See docs/CONVERSATION_API.md for the full
walkthrough.
Flux<StreamEvent> stream = client.streamIncremental("writer",
AgentRequest.of("Draft a release note."));
stream.subscribe(event -> {
if (event instanceof TokenEvent t) {
System.out.print(t.text());
} else if (event instanceof DoneEvent) {
System.out.println();
}
});See docs/STREAMING.md.
QueueAgenticPublisher kafka = bridge.publisher("kafka-async").orElseThrow();
kafka.publish(QueueInvocation.of("summariser",
AgentRequest.of(longDocument))
.withRoutingKey("summary.long")
.withHeader("tenant", "acme"))
.block();The bridge ships Micrometer counters and timers for every invocation,
stream, and publish. With Spring Boot Actuator on the classpath you also
get a reactive health indicator at /actuator/health/firefly-agentic-bridge
that aggregates the upstream service and every queue publisher.
See docs/OBSERVABILITY.md for tag reference and
sample dashboards.
- TLS enforcement (
require-tls=truerejectshttp://base URLs). - Pluggable
AuthStrategy: API key, bearer token, supplier-driven for rotating credentials, and a composite chain for multi-header schemes. - W3C Trace Context propagation (
traceparent,tracestate) on every REST request, every WebSocket handshake, and as message headers on every queue dispatch.
See docs/SECURITY.md.
- Architecture — design, layers, dependency flow.
- Quick Start — end-to-end tutorial.
- Configuration — every property reference.
- REST Transport — invoke + SSE streaming.
- WebSocket Transport — multi-turn conversations.
- Queue Transport — Kafka, RabbitMQ, Redis.
- Conversation API — server-side conversation lifecycle.
- Streaming — buffered vs incremental modes, event hierarchy.
- Observability — Micrometer instruments and tags.
- Security — TLS, auth, secret handling.
- Error Handling — exception hierarchy and mapping.
- Examples — copy-paste recipes.
Contributions are welcome! Please open an issue or pull request. The bridge adheres to the same code style, calendar versioning, and release process as the rest of the Firefly Framework.
Copyright 2026 Firefly Software Foundation.
Licensed under the Apache License, Version 2.0. See LICENSE for details.