🚀 Build Conversational Apps with Intentt

PHP Resonance Framework

Build Copilots, Conversational Applications, IO Intensive Services, and more.

Resonance is designed to build IO-intensive web applications from the ground up, making the development and maintenance as predictable and easy as possible.

It provides AI capabilities through llama.cpp and integration with Open Source foundational LLMs, which makes it a great fit for building conversational applications and copilots.

Takes full advantage of asynchronous PHP.

Get Started

Host Rubix ML machine learning models in production

Rubix ML is a high-level machine learning and deep learning library for the PHP language.

  • Simple Things Remain Simple

    Writing HTTP controllers is similar to how it's done in the synchronous code.

    Controllers have new exciting features that take advantage of the asynchronous environment.

    Learn More
        method: RequestMethod::GET,
        pattern: '/',
    function Homepage(ServerRequestInterface $request, ResponseInterface $response): TwigTemplate
        return new TwigTemplate('website/homepage.twig');
  • Chat with Open-Source LLMs

    Create prompt controllers to directly answer user's prompts.

    LLM takes care of determining user's intention, you can focus on taking an appropriate action.

    Learn More
        action: 'adopt',
        subject: 'cat',
    #[Singleton(collection: SingletonCollection::PromptSubjectResponder)]
    readonly class CatAdopt implements PromptSubjectResponderInterface
        public function respondToPromptSubject(PromptSubjectRequest $request, PromptSubjectResponse $response): void
            // Pipes message through WebSocket... 
            $response->write("Here you go:\n\n");
            $response->write("   |\_._/|\n");
            $response->write("   | o o |\n");
            $response->write("   (  T  )\n");
            $response->write("  .^`-^-`^.\n");
            $response->write("  `.  ;  .`\n");
            $response->write("  | | | | |\n");
            $response->write(" ((_((|))_))\n");
  • Serve Machine Learning Models

    Resonance integrates with Rubix ML and allows you to serve Machine Learning models in the same codebase as the rest of your application.

    Resonance allows you to serve inferences from your models through HTTP, WebSocket, and other protocols.

    Learn More
        method: RequestMethod::POST,
        pattern: '/predict',
    #[Singleton(collection: SingletonCollection::HttpResponder)]
    readonly class Predict extends HttpResponder
        private Estimator $model;
        public function __construct()
            $this->model = PersistentModel::load(new Filesystem(DM_ROOT.'/models/iris.model'));
        public function respond(
            ServerRequestInterface $request,
            ResponseInterface $response,
        ): HttpInterceptableInterface
            $dataset = new Unlabeled($request->getParsedBody());
            $predictions = $this->model->predict($dataset);
            return new JsonResponse($predictions);
  • Asynchronous Where it Matters

    Respond asynchronously to incoming RPC or WebSocket messages (or both combined) with little overhead.

    You can set up all the asynchronous features using attributes. No elaborate configuration is needed.

    Learn More
    #[Singleton(collection: SingletonCollection::WebSocketJsonRPCResponder)]
    final readonly class EchoResponder extends WebSocketJsonRPCResponder
        public function getConstraint(): Constraint
            return new StringConstraint();
        public function onRequest(
            WebSocketAuthResolution $webSocketAuthResolution,
            WebSocketConnection $webSocketConnection,
            RPCRequest $rpcRequest,
        ): void {
            $webSocketConnection->push(new RPCResponse(
  • Consistency is Key

    You can keep the same approach to writing software no matter the size of your project.

    There are no growing central configuration files or service dependencies registries. Every relation between code modules is local to those modules.

    Learn More
    #[Singleton(collection: SingletonCollection::EventListener)]
    final readonly class InitializeErrorReporting extends EventListener
        public function handle(object $event): void
            // ...
  • Powerful Dependency Injection

    Your project's files are indexed when the application starts. Relations between services are then set up by using attributes.

    There is no need for an elaborate configuration of services. Everything is handled by the attributes.

    Learn More
    #[Singleton(provides: LoggerInterface::class)]
    readonly class Logger implements LoggerInterface
        public function log($level, string|Stringable $message, array $context = []): void
            // ...
  • Promises in PHP

    Resonance provides a partial implementation of Promise/A+ spec to handle various asynchronous tasks.

    Learn More
    $future1 = new SwooleFuture(function (int $value) {
        assert($value === 1);
        return $value + 2;
    $future2 = $future1->then(new SwooleFuture(function (int $value) {
        assert($value === 3);
        return $value + 4;
    assert($future2->resolve(1)->result === 7);
  • GraphQL Out of the Box

    You can build elaborate GraphQL schemas by using just the PHP attributes.

    Resonance takes care of reusing SQL queries and optimizing the resources' usage.

    All fields can be resolved asynchronously.

    Learn More
        name: 'blogPosts',
        type: GraphQLRootFieldType::Query,
    #[Singleton(collection: SingletonCollection::GraphQLRootField)]
    final readonly class Blog implements GraphQLFieldableInterface
        public function __construct(
            private DatabaseConnectionPoolRepository $connectionPool,
            private BlogPostType $blogPostType,
        ) {}
        public function resolve(): GraphQLReusableDatabaseQueryInterface
            return new SelectBlogPosts($this->connectionPool);
        public function toGraphQLField(): array
            return [
                'type' => new ListOfType($this->blogPostType),
                'resolve' => $this->resolve(...),
Edit on GitHub