Skip to content

Folder structure ​

OpenFlow splits workflow execution, provider transport, application services, and presentation into workspace packages. The architecture contract defines their dependencies; the orchestration layout locates individual services and adapters.

Workspace ​

Five Rust workspace members and one TypeScript frontend package:

PathResponsibility
crates/engineWorkflow models, validation, execution semantics, prompts, ports, and tool policy.
crates/providersModel transport, auth, streaming, wire mapping, and provider specifications.
crates/orchestrationApplication services, run hosting, persistence, tools, and provider construction.
crates/desktopTauri commands, event bridge, and app bootstrap.
crates/workspace-checksArchitecture and source-boundary verification.
crates/uiSolidJS/TypeScript frontend with an isolated React Flow canvas.
scriptsDevelopment, build, verification, and release entry points.
docsProduct guides, reference, architecture, and contributor documentation.
examplesExample workflows and their instructions.

Read the nearest AGENTS.md before changing an area. UI and desktop have their own boundaries; both are part of the architecture contract.

Application services and adapters ​

Orchestration groups services by app concern. Small ones stay single files (agent.rs, chat.rs); larger ones get folders (workflow/, project/, settings/, run/, tool/). Group details that share a responsibility, but don't add an application/ layer to hold one service.

Concrete I/O lives in crates/orchestration/src/adapters/:

FolderOwns
storage/Workflow, chat, project, agent, settings, attachment, and checkpoint storage; skill discovery.
tool_impl/File, search, shell, edit, and other built-in tool implementations.
mcp/MCP connections, discovery, package installation, and secrets.
infrastructure/Git, LSP, and shared subprocess support.

backend/ constructs and connects services and adapters. Run hosting and engine construction belong in run/execution/; the run coordinator manages lifecycle and interactions.

The providers crate is itself an adapter crate: rig_adapter/ and mapping/ sit directly under crates/providers/src/, not in an adapters/ai_provider/ tree.

Ports and public boundaries ​

Add a trait only when a consumer depends on it. Engine exports AiPort and ToolPort. Orchestration store/catalog traits sit beside their consumers, usually in ports.rs; AgentStore is in agent.rs.

Adapters implement those interfaces. Entity services use their ports; backend/ supplies concrete stores. Don't add a trait per helper or expose an internal module just to mirror its path.

Orchestration gets provider clients via create_provider() and Box<dyn AiPort>. Desktop uses orchestration's public API and re-exported types. UI Tauri calls go through crates/ui/src/api.ts; DTO types are in crates/ui/src/lib/types/index.ts.

UI layout ​

PathPurpose
crates/ui/src/context/AppProvider / AppContext - app state, run listeners, navigation
crates/ui/src/screens/Full-page routes: EditorScreen, AgentsScreen, SettingsScreen
crates/ui/src/components/Shared chrome: AppHeader, sidebar primitives, conversation UI
crates/ui/src/panels/Editor overlays: InspectorPanel, WorkflowSettingsPanel, DockPanel
crates/ui/src/canvas/Workflow graph rendering
crates/ui/src/forms/Node/agent configuration editors
crates/ui/src/lib/types/index.tsFrontend DTO mirror types
crates/ui/src/api.tsTyped Tauri invoke/event wrappers

App.tsx is a thin shell: provider, toaster, sidebar, header, and ScreenRouter.

Verify structural changes ​

After changing dependencies or boundaries:

bash
./scripts/check-architecture.sh

The rules file holds exact import allowlists and engine construction scope. Intentional engine public API changes also need ./scripts/check-engine-public-api.sh.

Development lanes maps behavior changes to checks; coding patterns names the owning files.

Released under the MIT License.