Jump to content

Recommended Posts

Posted

This week we have ProcessWire 3.0.259 which includes several improvements, but my favorite is the addition of a new module type called "CliModule" which is short for "Command Line Interface Module". CliModules are those that provide the option for running from the command line. 

To list the available actions from command line modules, you can type "php index.php" in ProcessWire's installation directory. If "php" is not in your path, you'll have to type "/path/to/php index.php" instead, or add it to your path. Here's example output on my installation:

image.png

As you can see above, I've got AgentTools, WireTests and an example "Hello World" CliModule showing the available command line options. 

If I want to execute one of the commands, then I just type what it indicates. For example, here I will run `php index.php test FieldtypeText` and here's the output: 

image.png

Here's a simple example of a CliModule:

<?php namespace ProcessWire;

class HelloWorldCli extends WireData implements Module, CliModule {
  public static function getModuleInfo() {
    return [
      'title' => 'Hello World CLI module',
      'description' => 'Just an example',
      'version' => 1,
      'cli' => 'hello', // Example: php index.php hello
    ];
  }
  public function executeCli(array $args) {
    $command = $args[0] ?? '';
    $name = isset($args[1]) ? $args[1] : 'friend';
    if($command === 'hi') {
      echo "Hello there $name!";
    } else if($command === 'bye') {
      echo "Goodbye $name, see you later!";
    } else {
      echo "Specify 'hi' or 'bye' optionally followed by a name";
    }
  }
  public function getCliCommands() {
    return [
      'hi' => 'Say hello',
      'bye' => 'Say goodbye',
    ];
  }
}

For more details on the CliModule format, see wire/core/CliModule.php

Improvements have continued with the AgentTools module. This week we added:

New multi-model support: You can now configure multiple different agents in the module, and choose which one you'd like to use from the Engineer screen. Details

image.png

New agent-memory support: Now when you make a request of the Engineer, it remembers it for follow-up questions and changes. It keeps a conversation history for context of what you are working on. Details

image.png

image.png

New support for subagents: This enables any of the agents to launch additional agents when/where it helps to do so. For instance, specialist agents, or lower cost agents for simple jobs, and who knows what else. Claude requested the feature and also implemented it, so I'll be interested to see how it gets used. Details

New agents configuration screen where you can define up to 10 agents (that's plenty, right?). Details

image.png

Also new this week is a new WireTests module testing suite for ProcessWire. This first version focuses on testing all of ProcessWire's Fieldtype modules (including a few ProFields ones as well), but it's easy to add tests for any kind of module type. So we'll be adding more tests and improving existing tests as this module moves forward. For details head on over to: WireTests

Thanks for reading and have a great weekend!

  • Like 9
  • Thanks 5
Posted

Wow. These "ProcessWire as a web application framework"-type updates are coming in strong! Migrations, CLI, Tests, AI. One can wish for a maybe first party queue system too. 😄

  • Like 6
Posted

A lot of things changed in the world. I do not quite like many of them... But this what is happening here right now with ProcessWire is just amazing! Ryan finally found himself a companion to work with and they both are doing really well! I was kind of concerned about PW development, but not anymore.

  • Like 5
Posted

CLI modules sound great, can't wait to play around with that!

Two things I hope ProcessWire will eventually tackle natively (and also the things I currently think are kind of its weak points) are scheduled tasks and queues. For reference: https://laravel.com/docs/13.x/scheduling (or, pardon my french, https://developer.wordpress.org/plugins/cron/ and https://developer.wordpress.org/cli/commands/cron/) and https://laravel.com/docs/13.x/queues.

I would assume that Jonathan was thinking of something similar, but I won't try to speak for him 🙂

  • Like 6
Posted
On 4/25/2026 at 12:42 PM, teppo said:

Two things I hope ProcessWire will eventually tackle natively (and also the things I currently think are kind of its weak points) are scheduled tasks and queues.

Got my vote. I've implemented https://github.com/php-enqueue in a couple projects. 

@ryan Nice to se the Cli interface, just wanted to give a heads up of wire-cli and rockshell. These have been around from quite  a while,  something could be inspired from these libraries or maybe pick up from the current state of the libraries to work on things like scheduling/queue/agenttools

  • Like 6
Posted (edited)

Thank you for adding the multi agent feature.

For me it doesn't work with OpenRouter, because the model should be for example anthropic/claude-sonnet-4-6 instead of claude-sonnet-4-6. But if I change the model manually it messes app the fields, because of the predefined options I think. It mixes values in other fields. Could you please fix this? 🙂

Regards, Andreas

Edited by AndZyk
grammar
  • Like 1
Posted

@AndZyk 

The model field accepts any value — you're not limited to the predefined examples in the dropdown. For OpenRouter, type the full model ID directly (e.g. anthropic/claude-sonnet-4-6) and it will be saved as-is. I'd suggest configuring in Setup > AgentTools > Agents, rather than using the module config settings (though they map to the same things). 

We've added several common OpenRouter model IDs to the suggestions list in the next update, so they'll appear in the dropdown automatically.                                        

As for the fields appearing to mix values — sounds like maybe browser autofill? The API key field uses type="password", which can cause some browsers to try to autofill nearby fields as a user/pass. Disabling browser autofill for the page should prevent that. Or, in Setup > AgentTools > Agents, you could just click the little "reveal API key" button just to make sure something else isn't getting autofilled into it. Please let me know if you still can't get it to work?

Posted

@teppo @elabx The wp-cron looks identical to lazyCron. But the queue stuff does look new. I built out the IftRunner queueing module a long time ago and apparently Apeisa did find it very useful, since he had me build it for them at the time. But I didn't have any good use cases myself, so didn't continue building the module beyond the original scope. But I think we did do some pretty cool stuff it. Though it was so long ago that I think the landscape has changed and if we were to build something now it'd be very different from before. I'll definitely look into it more here. I'm still interested to hear @Jonathan Lahijani use cases too. 

Posted

Ah let's not forget The OG WireQueue

4 minutes ago, ryan said:

But I didn't have any good use cases myself

Couple examples from my own experience, involving FormBuilder:

It would be great to make FormBuilder actions asynchronous, when integrating whatever third party email/list management, some have very simple integrations that can pass as barely noticeable since it normally involves an extra request, but some of these, sometimes require tokens refreshments to a different endpoint for example, and time starts adding, making the forms feel slow. 

Another issue that I actually have right now in a website, is how I integrate FormBuilder to save leads as pages, and before saving new pages, I make a search of existing pages/users to avoid duplication of data. This has worked perfectly for the last 8 years or something, but after a few hundreds of leads saved in the database, the query of users during the request is starting to be noticeable, and the form submissions now feel slow. So I'm going to build FormBuilderActionQueueItem to add this process as a queue item to be processed and migrate all logic to the queue worker. 

Another example that comes to my mind is also building emails that depend on some sort of query, it's not a rare petition that I get to "enrich" emails with related information and data that comes from queries, since the FormBuilder administrator emails' purpose is to help a sales teams make decisions. 

Posted

Hi Ryan,

I'll do my best to explain this, but keep in mind my experience with queues / background jobs is only 2 years old.  But in short, inspiration would be best taken from the classic, "batteries included" big web application frameworks like Laravel (as Teppo pointed out) and Rails.  I like the Laravel page I linked because it gets very in-depth (I've read that page at least 10 times).

Let's use a classic example like this:  Let's say someone wants to upload a video to a field and we want it to be converted to a different file format (let's say that's being handled by ffmpeg).  That's a time intensive task that wouldn't be able to be done within a standard max limit 30 second web request, or even with the memory available to php via php-fpm.  It might take minutes or even hours, and even then, things can go wrong and it might fail.  So, instead we'd want this to happen independent of the web request, therefore a background job dedicated to that task would have to be made and scheduled to be processed.  It could happen immediately, or maybe it can be scheduled for 30 minutes later.  This is not related to cron jobs which are a different concept.

(Another example is for example in an ecommerce checkout; it's generally better practice to send the order notification email as a background job instead of inline with the code that processes the order after it's submitted).

With that, queue systems are typically powered by a different dedicated database or system, with Redis being a popular choice.  The reason for this is to limit load on the primary database; many large systems may have millions of jobs per day so offloading that to a separate database saves resources. However the big web application frameworks I mentioned also allow the option for the main database itself to store the jobs (Rails enabled this in Nov 2024), which is typically fast enough and probably good enough for a ProcessWire-based solution.

You then have workers which act on the jobs.  You can define there to be one or multiple workers.  Let's say you have a powerful server and want to transcode multiple videos at a time, then having multiple workers would allow more jobs to be done in parallel and take advantage of your system resources.  Obviously you don't want a worker to act on a job more than once, or two different workers to act on the same job.  So this gets into jobs have statuses, being locked, and avoiding race conditions.

The Laravel documentation gets into all of that, but I think reading up on queues/background jobs/workers and experimenting with it would be tremendously helpful.

In regards to my print-on-demand system, I'm not using a queue system as I described above and I did experiment with WireQueue and IftRunner a while ago, but it didn't really... fit?  It was a while ago and I was still wrapping my head around queues; also I came to realize that what I needed was even deeper than that (ie, durable workflows, but that's unrelated to what we're talking about here).  I eventually put something together that relies on "fake" jobs using cron jobs and progressing through a durable workflow; it's not the most efficient way to do it, but I got it working.  I've been meaning to rewrite that part of the system one day and having a native / first-party queue system (which dovetails with the CLI commands), would be the best approach.

  • Like 4
Posted

Hi, team. Lately, Claude and I 😁have been working on a series of modules for a new project at my company. This set includes a module for queue management. They aren't finished or ready for production yet; in fact, I’ve had few opportunities to test some of them, as I haven't reached those specific stages of the project yet.

With these implementations, I’m not aiming to create anything overly complex—after all, there are already plenty of libraries available for that purpose. The idea is for them to be easy to use, free of external dependencies, and equipped with the basic functionality required for the tasks at hand—always adhering to the language and philosophy of ProcessWire.

Would you be interested in having me upload some of them to GitHub for a look?

  • Like 5
Posted
17 hours ago, ryan said:

Please let me know if you still can't get it to work?

@ryan

Thank you for the explanation. When I try to enter all values manually in the primary agent:

image.jpeg.94ed4c6715b887002571f1dbb6600401.jpeg

It mixes the values after saving:

image.jpeg.62db0abc829532e763ee340f3706dab6.jpeg

I cannot leave all fields empty, because then it throws an error.

My module config is correct, but ignored because of the primary agent setting.

image.jpeg.c39f13077008d16415041a88c1b2f5d7.jpeg

I hope this helps.

  • Like 1
Posted

@AndZyk I was able to duplicate the issue when using openrouter. It turned out that because the openrouter string starts with "anthropic", it was getting interpreted as a line having a "provider" property, which is something that we deprecated, but still supported for backwards compatibility, and so it was causing the properties to get mixed up.  I've updated the detection logic so that it shouldn't happen anymore. Thanks .

  • Like 1
  • Thanks 1
Posted

@WireCodex It sounds like a lot of people here would be interested. Is it something where you'd want to make it a public and supported module in the modules directory, or more interested in sharing as a proof of concept? 

Posted

Hi @ryan there are a lot of modules I was working on. I began creating them even before the company project itself got underway (these are apps intended for internal use), anticipating what I would need based on the initial requirements and my prior experience with ProcessWire projects. I wanted to avoid conflating module development with the development of the core application itself.

That said, this meant I was able to test some of the modules incrementally, as the need arose; however, a significant portion of the project remains to be completed, and there are other modules—on which I performed only limited initial testing—that I haven't actually put into use yet.

In fact, they could be considered by the community as proofs of concept, given that I am not strictly a "professional" developer; I'm a graphic designer, and my role within the company is as Webmaster. Nevertheless—thanks to ProcessWire's ease of use—I have spent years implementing tools that assist the various departments in their daily operations.

All these modules were built around a philosophy of "Simple": they get straight to the point regarding my specific needs, though I am not sure whether they would prove useful to others. I have never worked with Git or a version control system, nor have I ever published modules before, so I have no idea what the best way to proceed would be; if you could offer me any guidance, I would be very grateful.

  • Like 5
Posted
On 4/27/2026 at 5:45 PM, ryan said:

@teppo @elabx The wp-cron looks identical to lazyCron.

Hey @ryan!

In my case the main benefit of wp-cron is that the system keeps track of registered/queued jobs and lets me disable the request based execution and run them via real cron. This is a common practice, and I would even go as far as say that the request-based way of running queued tasks is mostly intended for shared hosting etc. where real cron may not be available.

For this purpose wp-cron keeps track of scheduled jobs in the database, and has a config setting for disabling the "lazy" (request based) execution:

define('DISABLE_WP_CRON', true)

Once you've done this, you can set up a cron job, systemd task, or something similar that runs queued jobs, typically on a short interval (e.g. once a minute), so that you have almost-exact executions:

* * * * * wp cron event run --due-now

Basically wp-cron is a standard, system-wide way to register jobs to a queue, and keep track of which jobs have been registered and when, how often they should run, and when the next run time is. Those with no access to real cron (or some reason not to use it) can keep using the lazy approach, while those that don't want the jobs tied to web requests can set up a single cron job instead of e.g. many task-specific jobs.

(And this also makes it a bit easier to e.g. set up a separate worker machine that just runs cron jobs.)

I have a feeling that you may have looked at their default way to run jobs; you are right that at the surface level that looks very similar to LazyCron. But in my opinion this is actually the least important part of wp-cron 🙂

We have modules for setting something like this up. And it can be done by e.g. short-circuiting hooks unless some param is present, and so on. But a core way to do this would be most impactful. What we are missing is essentially a) a way for sites to disable request based job triggering globally (and I mean in a way that each module etc. adding these hooks doesn't have to know, e.g. $config->disableLazyCron), b) likely an option to store registered tasks in database so that they can be easily triggered and upcoming executions are made visible, and c) a way to execute scheduled tasks (something like WP-CLI cron command).

Does this explain better what I meant? 🙂

  • Like 2
Posted

@teppo  If I understand correctly, it sounds like you are primarily looking for a way to disable LazyCron from running during regular web requests?  And to be triggered from a real CRON job (via CLI command) or from some other condition, like the presence of a GET variable or something? We already have conditions in the module that prevent it from during during ajax requests, file requests, redirect requests, path hook requests, etc., so it'd be a simple matter to have an option to prevent it from running during web requests and instead delegate to CLI or similar. I'll go ahead and add this. Though let me know if I've misunderstood any part. 

  • Like 1
Posted (edited)

@ryan One suggestion:

What do you think about adding a file field to the engineer for asking questions with files?
For example: Create me a page with the contents of this Word file.

Also it I noticed that questions that take longer will end in an internal server error because of the long execution time.
In this case one would better use the terminal, because I think there is no easy solution around this except for increasing the server time limits?

 

Very interesting development. I just created a homepage and a subpage on a fresh install without writing a single line of code. 😅

 

One issue Claude Sonnet 4.6 had was the concept of Markup Regions. It had problems with the main-tags and disabled Markup Regions in the end. 😄

But maybe it can understand Markup Regions better with a more precise prompt. I have no tested that yet.

Edited by AndZyk
  • Like 1
Posted

@ryan the AgentTools module looks really promising. Really interested to see how this develops.

I wanted to share that I tried it out today with a fresh Claude API token and the response was quite strange and weirdly formatted. (See screenshots). This was in a local dev environment using MAMP/localhost

Screenshot 2026-05-05 at 16.13.11.png

Screenshot 2026-05-05 at 16.13.21.png

Posted
On 5/2/2026 at 9:12 PM, ryan said:

@teppo  If I understand correctly, it sounds like you are primarily looking for a way to disable LazyCron from running during regular web requests?  And to be triggered from a real CRON job (via CLI command) or from some other condition, like the presence of a GET variable or something?

Sounds just about right to me, yes. At least for my use cases that would be a big leap forward; it would put me/us to control of when and where scheduled tasks run 🙂

I do like the database approach of WP cron because it gives me clear view of the landscape, so to speak, but honestly that may not be necessary at all. And perhaps something very similar can already be achieved.

  • Thanks 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   1 member

×
×
  • Create New...