Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1015,23 +1015,21 @@ Boot a sandbox with caller-supplied runtime components mounted, then verify the

```bash
npm run wp-codebox -- agent-runtime-probe \
--component agents-api=../agents-api \
--component data-machine=../data-machine \
--component data-machine-code=../data-machine-code \
--component agent-runtime=../agent-runtime \
--component runtime-tools=../runtime-tools \
--json
```

Use `--component <slug>=<path>` for each runtime component your sandbox needs. The legacy `--agents-api`, `--data-machine`, and `--data-machine-code` flags remain accepted as compatibility aliases, but new automation should use `--component` so WP Codebox core stays portable across agent stacks.
Use `--component <slug>=<path>` for each runtime component your sandbox needs. This is the neutral replacement for component-specific aliases; new automation should use `--component` so WP Codebox core stays portable across agent stacks.

### `agent-sandbox-run`

Run one natural-language task through a sandboxed agent stack.

```bash
npm run wp-codebox -- agent-sandbox-run \
--component agents-api=../agents-api \
--component data-machine=../data-machine \
--component data-machine-code=../data-machine-code \
--component agent-runtime=../agent-runtime \
--component runtime-tools=../runtime-tools \
--agent sandbox-agent \
--task "Add a Dry Rub filter to the wing locations map" \
--provider example-ai \
Expand All @@ -1056,9 +1054,8 @@ Run several task descriptions, one isolated sandbox per task, with bounded concu

```bash
npm run wp-codebox -- agent-sandbox-batch \
--component agents-api=../agents-api \
--component data-machine=../data-machine \
--component data-machine-code=../data-machine-code \
--component agent-runtime=../agent-runtime \
--component runtime-tools=../runtime-tools \
--task "Fix issue A" \
--task "Investigate issue B" \
--concurrency 2 \
Expand Down
10 changes: 5 additions & 5 deletions examples/agent-runtime/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ Set local checkout paths, then run the preset:

```bash
AGENTS_API_PATH=/path/to/agents-api \
DATA_MACHINE_PATH=/path/to/data-machine \
DATA_MACHINE_CODE_PATH=/path/to/data-machine-code \
RUNTIME_ENGINE_PATH=/path/to/runtime-engine \
RUNTIME_TOOLS_PATH=/path/to/runtime-tools \
PROVIDER_PLUGIN_PATH=/path/to/ai-provider-plugin \
npm run wp-codebox -- agent-runtime-probe \
--component agents-api="$AGENTS_API_PATH" \
--component data-machine="$DATA_MACHINE_PATH" \
--component data-machine-code="$DATA_MACHINE_CODE_PATH" \
--component runtime-engine="$RUNTIME_ENGINE_PATH" \
--component runtime-tools="$RUNTIME_TOOLS_PATH" \
--provider-plugin "$PROVIDER_PLUGIN_PATH" \
--artifacts ./artifacts \
--json
```

The preset mounts each `--component` at its declared slug, uses WordPress `7.0` by default, activates the plugins in dependency order, and returns a JSON readiness packet. It intentionally does not require provider credentials or model calls. Legacy stack-specific flags such as `--agents-api` still work as compatibility aliases; new examples should prefer generic `--component` entries.
The preset mounts each `--component` at its declared slug, uses WordPress `7.0` by default, activates the plugins in dependency order, and returns a JSON readiness packet. It intentionally does not require provider credentials or model calls. Stack-specific shortcuts should be replaced with generic `--component` entries.
10 changes: 4 additions & 6 deletions examples/agent-runtime/probe.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

$plugins = array(
'agents-api/agents-api.php',
'data-machine/data-machine.php',
'data-machine-code/data-machine-code.php',
'runtime-engine/runtime-engine.php',
'runtime-tools/runtime-tools.php',
);

$activation_results = array();
Expand All @@ -31,10 +31,8 @@
'signals' => array(
'agents_api_loaded' => defined('AGENTS_API_LOADED'),
'agents_chat_ability_available' => (new WP_Codebox_Agent_Runtime_Invoker())->is_agents_api_ready(),
'data_machine_version' => defined('DATAMACHINE_VERSION') ? DATAMACHINE_VERSION : null,
'data_machine_permission_helper' => class_exists('DataMachine\\Abilities\\PermissionHelper'),
'data_machine_code_version' => defined('DATAMACHINE_CODE_VERSION') ? DATAMACHINE_CODE_VERSION : null,
'data_machine_code_workspace' => class_exists('DataMachineCode\\Workspace\\Workspace'),
'runtime_engine_active' => is_plugin_active('runtime-engine/runtime-engine.php'),
'runtime_tools_active' => is_plugin_active('runtime-tools/runtime-tools.php'),
),
),
JSON_PRETTY_PRINT
Expand Down
8 changes: 4 additions & 4 deletions examples/recipes/cookbook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ files plus dry-run evidence limited to shareable metadata.

### `codex-agent-smoke.json`

Runs a headless Data Machine agent inside a disposable WordPress Playground
Runs a headless agent runtime inside a disposable WordPress Playground
sandbox using the Codex provider. This is the smallest end-to-end recipe for
proving that WP Codebox can mount the agent runtime stack, overlay a
`php-ai-client` branch with provider-supplied request auth, activate a Codex
Expand All @@ -36,8 +36,8 @@ uses explicit placeholder input paths so callers can see the full contract shape
and replace each path with their prepared local checkout or artifact:

- `/sample/prepared-component-stack/agents-api`
- `/sample/prepared-component-stack/data-machine`
- `/sample/prepared-component-stack/data-machine-code`
- `/sample/prepared-component-stack/runtime-engine`
- `/sample/prepared-component-stack/runtime-tools`
- `/sample/prepared-provider-stack/php-ai-client`
- `/sample/prepared-provider-stack/ai-provider-for-openai`

Expand All @@ -49,7 +49,7 @@ a dry-run plan with the sandbox backend, overlays, extra plugins, secret
environment names, and resolved agent command arguments.

- The component stack provides the WordPress plugins needed by the sandbox agent
runtime: `agents-api`, `data-machine`, and `data-machine-code`.
runtime: `agents-api`, `runtime-engine`, and `runtime-tools`.
- The provider stack provides the `php-ai-client` overlay and provider plugin
selected by `provider=codex` and
`provider-plugin-slugs=ai-provider-for-openai`.
Expand Down
8 changes: 4 additions & 4 deletions examples/recipes/cookbook/claude-code-agent-smoke.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
"activate": true
},
{
"source": "/sample/prepared-component-stack/data-machine",
"slug": "data-machine",
"source": "/sample/prepared-component-stack/runtime-engine",
"slug": "runtime-engine",
"activate": true
},
{
"source": "/sample/prepared-component-stack/data-machine-code",
"slug": "data-machine-code",
"source": "/sample/prepared-component-stack/runtime-tools",
"slug": "runtime-tools",
"activate": true
},
{
Expand Down
8 changes: 4 additions & 4 deletions examples/recipes/cookbook/codex-agent-smoke.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
"activate": true
},
{
"source": "/sample/prepared-component-stack/data-machine",
"slug": "data-machine",
"source": "/sample/prepared-component-stack/runtime-engine",
"slug": "runtime-engine",
"activate": true
},
{
"source": "/sample/prepared-component-stack/data-machine-code",
"slug": "data-machine-code",
"source": "/sample/prepared-component-stack/runtime-tools",
"slug": "runtime-tools",
"activate": true
},
{
Expand Down
6 changes: 0 additions & 6 deletions packages/cli/src/agent-sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,6 @@ export function parseAgentRuntimeProbeOptions(args: string[], parseMount: (value
case "--agents-api":
options.components = [...(options.components ?? []), componentFromPath(value, "agents-api", undefined, "mu-plugin", "component")]
break
case "--data-machine":
options.components = [...(options.components ?? []), componentFromPath(value, "data-machine", undefined, "mu-plugin", "component")]
break
case "--data-machine-code":
options.components = [...(options.components ?? []), componentFromPath(value, "data-machine-code", undefined, "mu-plugin", "component")]
break
case "--provider-plugin":
options.providerPluginPaths = [...(options.providerPluginPaths ?? []), value]
break
Expand Down
4 changes: 2 additions & 2 deletions packages/wordpress-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ transport, task input, status, diagnostics, and evidence refs.
{
"goal": "Run the provider-owned bundle task.",
"agent_bundles": [
{ "source": "/path/to/site-generator-agent.json", "slug": "site-generator", "on_conflict": "upgrade" }
{ "source": "/path/to/sample-agent.json", "slug": "sample-agent", "on_conflict": "upgrade" }
],
"runtime_task": {
"ability": "runtime/run-agent-bundle",
"input": {
"source": "/wordpress/wp-content/wp-codebox-inputs/site-generator-agent.json",
"source": "/wordpress/wp-content/wp-codebox-inputs/sample-agent.json",
"flow": "static-site-manual-flow",
"wait_for_completion": true
}
Expand Down
20 changes: 10 additions & 10 deletions scripts/agent-runtime-diagnostics-summary-smoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ try {
const metadataPath = join(directory, "metadata.json")
await writeFile(metadataPath, `${JSON.stringify({
context: {
preparedComponentContracts: [{ slug: "wp-site-generator", requestedPath: "/host/wpsg", preparedPath: "/tmp/prepared-plugins/wp-site-generator", pluginFile: "wp-site-generator/wp-site-generator.php", loadAs: "mu-plugin", activate: true, status: "prepared" }],
preparedWorkspaces: [{ target: "/workspace/wp-site-generator", mode: "readwrite", metadata: { repo: "wp-site-generator" } }],
preparedComponentContracts: [{ slug: "sample-runtime", requestedPath: "/host/sample-runtime", preparedPath: "/tmp/prepared-plugins/sample-runtime", pluginFile: "sample-runtime/sample-runtime.php", loadAs: "mu-plugin", activate: true, status: "prepared" }],
preparedWorkspaces: [{ target: "/workspace/sample-runtime", mode: "readwrite", metadata: { repo: "sample-runtime" } }],
preparedStagedFiles: [{ sourceRef: "bundle.json", target: "/workspace/bundle.json", type: "file" }],
preparedRuntimeOverlays: [{ target: "/wordpress/wp-content/mu-plugins/runtime.php", type: "file", mode: "readonly" }],
recipe: { inputs: { component_contracts: [{ slug: "wp-site-generator", path: "/host/wpsg", loadAs: "mu-plugin", activate: true }] } },
recipe: { inputs: { component_contracts: [{ slug: "sample-runtime", path: "/host/sample-runtime", loadAs: "mu-plugin", activate: true }] } },
},
}, null, 2)}\n`)

Expand All @@ -27,21 +27,21 @@ try {
},
stack: {
plugins: {
"wp-site-generator/wp-site-generator.php": { active: true, load_as: "mu-plugin", error: null },
"sample-runtime/sample-runtime.php": { active: true, load_as: "mu-plugin", error: null },
},
signals: {
provider_plugins: ["ai-provider-for-opencode/ai-provider-for-opencode.php"],
provider_plugin_files: [{ slug: "ai-provider-for-opencode", plugin_file: "ai-provider-for-opencode/ai-provider-for-opencode.php", mounted_path: "/wordpress/wp-content/mu-plugins/wp-codebox-runtime/ai-provider-for-opencode/ai-provider-for-opencode.php", load_as: "mu-plugin", mounted: true }],
},
abilities: { count: 2, ids: ["agents/chat", "wp-site-generator/run"], requested: "agents/chat", requested_available: true },
abilities: { count: 2, ids: ["agents/chat", "sample-runtime/run"], requested: "agents/chat", requested_available: true },
},
error: { code: "expected-test-error", message: "synthetic" },
},
}

const summary = await buildAgentRuntimeDiagnostics({
artifacts: { metadataPath },
componentContracts: [{ slug: "wp-site-generator", requestedPath: "/host/wpsg", preparedPath: "/tmp/prepared-plugins/wp-site-generator", pluginFile: "wp-site-generator/wp-site-generator.php", loadAs: "mu-plugin", activationStatus: "loaded", status: "loaded" }],
componentContracts: [{ slug: "sample-runtime", requestedPath: "/host/sample-runtime", preparedPath: "/tmp/prepared-plugins/sample-runtime", pluginFile: "sample-runtime/sample-runtime.php", loadAs: "mu-plugin", activationStatus: "loaded", status: "loaded" }],
phaseEvidence: [{ name: "mount_plugins", status: "completed", data: { count: 2 } }, { name: "activate_plugins", status: "completed" }],
executions: [
{ recipePhase: "setup", recipeCommand: "extra-plugin.install-mu-loader", command: "wordpress.run-php", exitCode: 0 },
Expand All @@ -61,13 +61,13 @@ try {
})

assert.equal(summary.schema, "wp-codebox/agent-runtime-diagnostics/v1")
assert.match(JSON.stringify(summary.component_contracts), /wp-site-generator/)
assert.match(JSON.stringify(summary.component_contracts), /sample-runtime/)
assert.match(JSON.stringify(summary.prepared_paths), /prepared-plugins/)
assert.match(JSON.stringify(summary.loader_entries), /ai-provider-for-opencode/)
assert.match(JSON.stringify(summary.loaded_entrypoints), /wp-site-generator.php/)
assert.match(JSON.stringify(summary.loaded_entrypoints), /sample-runtime.php/)
assert.match(JSON.stringify(summary.lifecycle_actions), /mount_plugins/)
assert.deepEqual(summary.registered_abilities, { count: 2, ids: ["agents/chat", "wp-site-generator/run"], requested: "agents/chat", requested_available: true })
assert.deepEqual(summary.resolved_tool_ids, { before_filtering: ["workspace.grep", "workspace.read", "workspace.write"], after_filtering: ["workspace.grep", "workspace.read"] })
assert.deepEqual(summary.registered_abilities, { count: 2, ids: ["agents/chat", "sample-runtime/run"], requested: "agents/chat", requested_available: true })
assert.deepEqual(summary.resolved_tool_ids, { before_filtering: ["workspace.read", "workspace.grep", "workspace.write"], after_filtering: ["workspace.grep", "workspace.read"] })

console.log("agent-runtime-diagnostics-summary-smoke: ok")
} finally {
Expand Down
10 changes: 7 additions & 3 deletions scripts/component-plugin-entrypoint-contract-smoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ throw new RuntimeException('explicit pluginFile resolution must not read plugin

const sandboxOptions = parseAgentRuntimeProbeOptions([
"--component", `agents-api=${explicitSource}`,
"--component", `data-machine=${explicitSource}`,
"--component", `data-machine-code=${explicitSource}`,
"--component", `runtime-engine=${explicitSource}`,
"--component", `runtime-tools=${explicitSource}`,
], (value) => JSON.parse(value))
assert.deepEqual(sandboxOptions.components.map((component) => component.slug), ["agents-api", "data-machine", "data-machine-code"])
assert.deepEqual(sandboxOptions.components.map((component) => component.slug), ["agents-api", "runtime-engine", "runtime-tools"])

const portableOptions = parseAgentRuntimeProbeOptions([
"--component", `custom-runtime=${explicitSource}`,
Expand All @@ -82,6 +82,10 @@ throw new RuntimeException('explicit pluginFile resolution must not read plugin
], (value) => JSON.parse(value))
assert.deepEqual(compatibilityOptions.components.map((component) => component.slug), ["agents-api"])

assert.throws(() => parseAgentRuntimeProbeOptions([
"--runtime-engine", explicitSource,
], (value) => JSON.parse(value)), /Unknown option: --runtime-engine/)

const explicitFile = readFileSync(join(explicitSource, "custom-entry.php"), "utf8")
assert.match(explicitFile, /must not read plugin contents/)

Expand Down
8 changes: 4 additions & 4 deletions tests/fixtures/task-input-normalization.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
],
"agent_bundles": [
{
"source": "/tmp/site-generator-agent.json",
"slug": "site-generator",
"source": "/tmp/sample-agent.json",
"slug": "sample-agent",
"on_conflict": "upgrade",
"owner_id": 1,
"import_principal": {
Expand Down Expand Up @@ -92,8 +92,8 @@
],
"agent_bundles": [
{
"source": "/tmp/site-generator-agent.json",
"slug": "site-generator",
"source": "/tmp/sample-agent.json",
"slug": "sample-agent",
"on_conflict": "upgrade",
"owner_id": 1,
"import_principal": {
Expand Down
2 changes: 2 additions & 0 deletions tests/production-boundary-enforcement.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const productionExtensions = new Set([".cjs", ".js", ".json", ".jsx", ".mjs", ".
const forbiddenTerms = [
/datamachine/i,
/data machine/i,
/data-machine/i,
/data-machine-code/i,
/homeboy/i,
/\bwpsg\b/i,
/wp-site-generator/i,
Expand Down
20 changes: 10 additions & 10 deletions tests/runtime-recipe-resolver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ function apply_filters( $hook, $value, ...$args ) {
),
'placement_capabilities' => array( 'agents.runtime' ),
);
$value['data-machine'] = array(
'id' => 'data-machine',
'provides' => array( 'data-machine.runtime' ),
$value['sample-runtime'] = array(
'id' => 'sample-runtime',
'provides' => array( 'sample.runtime' ),
'requires' => array( 'agents' ),
'runtime' => array(
'components' => array( 'data-machine', 'data-machine-code' ),
'components' => array( 'sample-runtime', 'sample-runtime-tools' ),
'plugins' => array(
array( 'slug' => 'data-machine', 'url' => 'https://example.test/data-machine.zip', 'activate' => true ),
array( 'slug' => 'data-machine-code', 'url' => 'https://example.test/data-machine-code.zip', 'activate' => true ),
array( 'slug' => 'sample-runtime', 'url' => 'https://example.test/sample-runtime.zip', 'activate' => true ),
array( 'slug' => 'sample-runtime-tools', 'url' => 'https://example.test/sample-runtime-tools.zip', 'activate' => true ),
),
'bootstrap' => array( array( 'operation' => 'set_option', 'args' => array( 'name' => 'datamachine_runtime', 'value' => 'sandbox' ) ) ),
'bootstrap' => array( array( 'operation' => 'set_option', 'args' => array( 'name' => 'sample_runtime', 'value' => 'sandbox' ) ) ),
),
);
$value['provider-connector'] = array(
Expand All @@ -73,7 +73,7 @@ require ${phpStringLiteral(`${repoRoot}/packages/wordpress-plugin/src/class-wp-c

$input = array(
'runtime_recipe' => array(
'capabilities' => array( 'data-machine.runtime', 'provider.connector' ),
'capabilities' => array( 'sample.runtime', 'provider.connector' ),
),
'runtime' => array(
'plugins' => array( array( 'slug' => 'caller-plugin', 'url' => 'https://example.test/caller.zip' ) ),
Expand All @@ -91,8 +91,8 @@ $local_task = WP_Codebox_Browser_Task_Builder::local_browser_task_input( array(
echo json_encode( array( 'resolved' => $resolved, 'local_task' => $local_task ), JSON_UNESCAPED_SLASHES );
`)

assert.deepEqual(result.resolved.runtime.components, ["agents-api", "data-machine", "data-machine-code"])
assert.deepEqual(result.resolved.runtime.plugins.map((plugin: { slug: string }) => plugin.slug), ["caller-plugin", "agents-api", "data-machine", "data-machine-code"])
assert.deepEqual(result.resolved.runtime.components, ["agents-api", "sample-runtime", "sample-runtime-tools"])
assert.deepEqual(result.resolved.runtime.plugins.map((plugin: { slug: string }) => plugin.slug), ["caller-plugin", "agents-api", "sample-runtime", "sample-runtime-tools"])
assert.deepEqual(result.resolved.inherit.connectors, ["existing", "primary-ai"])
assert.deepEqual(result.resolved.provider_plugin_paths, ["/opt/provider-plugin"])
assert.deepEqual(result.resolved.secret_env, ["PROVIDER_TOKEN"])
Expand Down