JaKtA 1.0: a redesign
· 3 min read
JaKtA 1.0 is a rewrite from the ground up. The BDI model is the same, but the engine, the DSL and the module structure are new — and multiplatform.
Why a new engine
JaKtA has its own BDI execution engine instead of reusing an existing one, because of two design goals:
- to explore paradigm blending of agent-oriented programming, and BDI in particular, with mainstream programming languages, and
- to make every aspect of running a BDI system modular and pluggable: reasoning, message passing, concurrency models, and the like.
The DSL is kept apart from the engine, since it is only one possible syntax for specifying BDI multi-agent systems: other languages could be plugged on top of the same engine.
What changed
- Kotlin Multiplatform. The core libraries run on the JVM, in JavaScript (browser and Node.js, also on npm as
@jakta/*) and natively. - A coroutine engine. Each intention is a coroutine and plan bodies are ordinary
suspendKotlin code: call functions,delay, wait for events, and return results from sub-goals. - Pluggable knowledge representation. The engine is generic over beliefs and goals. An incarnation fixes them: Prolog terms through 2P-Kt, plain strings, or your own Kotlin types.
- Skills instead of actions. What an agent can do is a Kotlin object given to its plans through context parameters, checked by the compiler.
- Nodes instead of environments. Agents live in nodes that deliver perceptions and messages, with Jason-style KQML messaging in the Prolog incarnation.
- Simulation. The Alchemist incarnation runs JaKtA agents in simulated time.
Before and after
// JaKtA 0.x
mas {
agent("myAgent") {
goals { achieve("sayHello") }
plans {
+achieve("sayHello") then { execute("print"("Hello, World!")) }
}
}
}.start()
// JaKtA 1.x (Prolog incarnation)
val helloWorldAgent = agent<PrologBelief, PrologGoal, Any> {
embodiedAs { Any() }
hasInitialGoals { !initialGoal { Atom.of("sayHello") } }
hasPlanLibrary {
prologPlan {
adding.goal { matchingGoal { Atom.of("sayHello") } } triggers {
agent.print("Hello, world!")
}
}
}
}
fun main(): Unit = runBlocking {
mas(NodeBuilders.baseNode()) {
node { withAgents(helloWorldAgent) }
}.runLocally()
}
Getting started
The documentation has been rewritten for 1.x, and the examples now live in the main repository. JaKtA 0.x is deprecated; if you are reading one of our earlier papers, the JaKtA 0.x page collects the old resources. For how JaKtA moved away from Jason, read Jason-like Kotlin Agents.
