Reworking OpenJarvis around a hexagonal architecture . would you be open to it? #577
MaliciaInc
started this conversation in
Ideas
Replies: 1 comment
-
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I've been using OpenJarvis for a while and ended up going pretty deep into the internals. I reworked the architecture, and before I take it any further I wanted to ask whether there's any interest in reviewing it as a possible future direction.
Here's what I changed and why.
The package had gotten fairly flat. Modules import each other across concerns, and a lot of the wiring happens by import side effect:
@Registry.registerdecorators that only run if something imports the module first.It works, but it makes a few things painful. It's hard to tell what actually depends on what, hard to test a piece in isolation, and hard to point at the one spot where the system gets assembled.
I moved the internals to a hexagonal layout:
corefor pure types and value objects with no IO,portsfor the protocols,applicationfor the use cases,adaptersfor the concrete integrations (Ollama, the other engines, tools, connectors), and theninterfaces,features,infrastructure.What keeps it honest is an import-linter contract that runs with the tests and enforces the layering, so it can't quietly drift back:
corecan't import anything else in the tree, the application layer doesn't reach into adapters except through the composition root, deleted packages stay deleted, and so on.The second big piece was getting rid of the implicit registration.
Everything is wired in one composition root now, explicitly: engines, tools, agents and memory backends are registered by hand in a single place instead of relying on a decorator having fired during some import.
There's a small test that fails the build if a
@Registry.registerever shows up again, so it can't creep back in.A few things fell out of that. Ports hand back typed value objects now instead of
dict[str, Any]floating around everywhere. And I pulled the runtime toward a scheduler in the middle, where each unit of work (a user message, a model request, a tool result, a deferred task, a memory candidate) becomes a typed work item with state, priority, budget, destination, and a return path. That work item flows through one scheduler and an explicit dispatcher, rather than having a router up front decide everything.It boots,
askandservework, and the suite is green (around 7k tests). I won't pretend it's a clean drop-in. It's an opinionated reshaping of the internals and it touches a lot of the codebase. But it holds together and I've been running it day to day.Is this a direction you'd consider for the project?
I don't want to drop a huge rewrite on you and expect a merge, that isn't fair to whoever has to review it. If there's interest, I can upload it to a specific branch or send it to someone, but the current architecture and the reconstructed tree are not compatible as a direct merge.
And if it doesn't line up with where you want OpenJarvis to go, no hard feelings. I'll keep it on my fork.
Happy to walk through any part or provide more detailed explanations.
Beta Was this translation helpful? Give feedback.
All reactions