Skip to content
This repository was archived by the owner on Sep 11, 2025. It is now read-only.

Conversation

@mattjohnsonpint
Copy link
Contributor

@mattjohnsonpint mattjohnsonpint commented May 7, 2025

This PR provides the initial implementation for Modus Agents.

What are Modus Agents?

Modus Agents are long-running process that can receive messages and maintain state. Contrast this with Modus Functions, which are short-lived and stateless. With this new feature, both capabilities are part of the Modus framework.

Each instance of a Modus agent is backed by an actor, leveraging the GoAkt actor framework. In this initial implementation, advanced features of GoAkt such as clustering and passivation have not been enabled - but we plan to leverage such features in the near future. This will allow Modus Agents to scale out for high availability and performance.

Each actor that backs a Modus agent also has its own WASM memory space, which remains active as long as the actor is alive. State maintaining functions getState / setState are exposed for the user to implement, such that actors can be restarted without losing information.

Importantly, note that actors are single threaded and so is WASM, and thus Modus Agents are also single threaded. That means that only the agent itself can manipulate its state. To interact with an agent, a Modus Function (or another agent) can send messages to the agent based on its ID, using the synchronous SendMessage function, or the asynchronous SendMessageAsync function. Agents then handle those messages in the implementation of their OnMessageReceived method.

Currently, there is only one data structure for the message itself. It has a required string name field, and an optional string data field. Data can be serialized in any format as long as it's handled consistently. In a future implementation, we may decided to leverage GoAkt's protobuf-based message system to allow custom strongly typed messages.

Where's the AI?

Modus Agents can absolutely be used to power an agentic workflow, thus becoming AI agents. However, that is a step that would be built one layer on top of this one. This first step simply adds statefulness capabilities to the system.

We will be doing more in this regard in the near future. Stay Tuned!

TBD

  • Docs
  • Tests
  • More example agents

@linear
Copy link

linear bot commented May 7, 2025

@mattjohnsonpint mattjohnsonpint added the do-not-merge DO NOT MERGE label May 7, 2025
@mattjohnsonpint mattjohnsonpint force-pushed the mjp/hyp-3316-initial-agentactor-system-implementation branch 2 times, most recently from f6e3da2 to de28658 Compare May 13, 2025 02:28
@mattjohnsonpint mattjohnsonpint force-pushed the mjp/hyp-3316-initial-agentactor-system-implementation branch from de28658 to dd4fc0b Compare May 13, 2025 02:30
@mattjohnsonpint mattjohnsonpint changed the title WIP: Initial agent/actor system implementation feat: initial implementation of Modus Agents May 13, 2025
@mattjohnsonpint mattjohnsonpint removed the do-not-merge DO NOT MERGE label May 13, 2025
@mattjohnsonpint mattjohnsonpint marked this pull request as ready for review May 13, 2025 02:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces the initial implementation of Modus Agents to the framework by adding long-running, stateful agent support alongside short-lived functions. Key changes include:

  • Adding logging fields and enhancements to better capture agent context.
  • Removing obsolete functions and updating GraphQL and WASM module integrations to support agent lifecycle management.
  • Introducing new components for actor-based agents, including spawning, messaging, and module reloading.

Reviewed Changes

Copilot reviewed 63 out of 63 changed files in this pull request and generated no comments.

Show a summary per file
File Description
runtime/logger/logger.go Added new logging fields ("agent", "agent_id") for richer context reporting.
runtime/langsupport/wasmadapter.go Removed GetWasmAdapter function and unused import, streamlining WASM adapter usage.
runtime/httpserver/server.go Updated shutdown log message for improved clarity.
runtime/hostfunctions/system.go Improved context safety when retrieving function messages.
runtime/hostfunctions/agents.go Added new host functions to spawn agent actors and send messages to agents.
runtime/graphql/schemagen/filters.go Enhanced GraphQL field filtering by ignoring functions starting with "_" via new helper.
runtime/graphql/graphql.go Updated engine activation and replaced a plain map with an xsync.Map for function output.
runtime/graphql/engine/engine.go Changed Activate API to accept a plugin, adjusting schema generation accordingly.
runtime/graphql/datasource/source.go Updated execution info storage to support xsync.Map usage for concurrency.
runtime/go.mod Updated and added dependencies aligned with the new features.
runtime/functions/registration.go Added conditional logging to exclude internal functions based on naming conventions.
runtime/buf.yaml & runtime/buf.gen.yaml New configuration files for Buf linting and code generation.
runtime/actors/*.go (agents, actorsystem, logger) Introduced a new actor system for managing agent actors including spawning, messaging, and reloading.
.vscode/launch.json, .trunk/configs/cspell.json Updated configuration files to support agents and new vocabulary.
CHANGELOG.md Documented the introduction of Modus Agents.
Comments suppressed due to low confidence (2)

runtime/langsupport/wasmadapter.go:25

  • The removal of the GetWasmAdapter function should be reviewed to ensure that no dependent modules or tests rely on this helper for obtaining a WasmAdapter instance.
func GetWasmAdapter(ctx context.Context) (WasmAdapter, error) {

runtime/graphql/graphql.go:162

  • [nitpick] Consider verifying the performance impact of converting an xsync.Map to a plain map using xsync.ToPlainMap in high-throughput GraphQL responses.
if response, err := addOutputToResponse(resultWriter.Bytes(), xsync.ToPlainMap(output)); err != nil {

@trunk-io
Copy link

trunk-io bot commented May 14, 2025

Code-Quality-on-PRs is deprecated and will soon be removed. Please see the migration guide for more information.

Copy link
Contributor

@kevinmingtarja kevinmingtarja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. tested locally with the Go example and it works.

steps if anyone wants to test:

  1. Build the runtime
cd runtime
make build
sudo mv modus_runtime /usr/local/bin
cd ..
  1. Run the example
cd sdk/go/examples/agents
bash build.sh
MODUS_ENV=dev modus_runtime -appPath ./build
Screenshot 2025-05-14 at 11 18 45 AM

@mattjohnsonpint mattjohnsonpint merged commit 3c4f804 into main May 14, 2025
86 checks passed
@mattjohnsonpint mattjohnsonpint deleted the mjp/hyp-3316-initial-agentactor-system-implementation branch May 14, 2025 19:21
@mattjohnsonpint
Copy link
Contributor Author

Thanks! I'll also publish a preview release with this soon so folks can play without compiling from source.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants