fix: pin OpenClaw Codex plugin
This commit is contained in:
parent
ba4daa3597
commit
2f2e9d8f9b
@ -18,15 +18,19 @@ gateway_openclaw_binary_path: "{{ gateway_openclaw_home }}/.local/bin/openclaw"
|
||||
gateway_openclaw_install_dir: "{{ gateway_openclaw_home }}/.local/lib/node_modules/openclaw"
|
||||
gateway_openclaw_required_version: "2026.5.28"
|
||||
gateway_openclaw_npm_package_spec: "openclaw@{{ gateway_openclaw_required_version }}"
|
||||
gateway_openclaw_extension_dependency_dirs:
|
||||
- "{{ gateway_openclaw_install_dir }}/dist/extensions/acpx"
|
||||
gateway_openclaw_global_npm_dir: "{{ gateway_openclaw_home }}/.openclaw/npm"
|
||||
gateway_openclaw_required_global_plugins:
|
||||
- name: "@openclaw/codex"
|
||||
version: "{{ gateway_openclaw_required_version }}"
|
||||
gateway_openclaw_removed_global_plugins:
|
||||
- "@openclaw/acpx"
|
||||
gateway_openclaw_extension_dependency_dirs: []
|
||||
gateway_openclaw_config_path: "{{ gateway_openclaw_home }}/.openclaw/openclaw.json"
|
||||
gateway_openclaw_workspace_path: "{{ gateway_openclaw_home }}/.openclaw/workspace"
|
||||
gateway_openclaw_workspace_mode: "0775"
|
||||
gateway_openclaw_compile_cache_dir: /var/tmp/openclaw-compile-cache
|
||||
gateway_openclaw_service_path: "{{ gateway_openclaw_home }}/.nix-profile/bin:{{ gateway_openclaw_home }}/.local/bin:{{ gateway_openclaw_home }}/.npm-global/bin:{{ gateway_openclaw_home }}/bin:/usr/local/bin:/usr/bin:/bin"
|
||||
gateway_openclaw_extension_backup_dir: "{{ gateway_openclaw_home }}/.openclaw/backups/extensions"
|
||||
gateway_openclaw_doctor_repair_enabled: true
|
||||
|
||||
gateway_openclaw_upstream_host: 127.0.0.1
|
||||
gateway_openclaw_upstream_port: 18789
|
||||
|
||||
@ -90,6 +90,105 @@
|
||||
- not ansible_check_mode
|
||||
notify: Restart openclaw gateway
|
||||
|
||||
- name: Ensure OpenClaw global plugin npm directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ gateway_openclaw_global_npm_dir }}"
|
||||
state: directory
|
||||
owner: "{{ gateway_openclaw_service_user }}"
|
||||
group: "{{ gateway_openclaw_service_group }}"
|
||||
mode: "0700"
|
||||
|
||||
- name: Install required OpenClaw global plugin versions
|
||||
ansible.builtin.command:
|
||||
cmd: >-
|
||||
npm install --omit=dev --no-audit --no-fund --save-exact
|
||||
--prefix "{{ gateway_openclaw_global_npm_dir }}"
|
||||
{{ item.name }}@{{ item.version }}
|
||||
environment:
|
||||
HOME: "{{ gateway_openclaw_home }}"
|
||||
PATH: "{{ gateway_openclaw_service_path }}"
|
||||
OPENCLAW_NO_RESPAWN: "1"
|
||||
NODE_COMPILE_CACHE: "{{ gateway_openclaw_compile_cache_dir }}"
|
||||
become: true
|
||||
become_user: "{{ gateway_openclaw_service_user }}"
|
||||
register: gateway_openclaw_required_global_plugin_installs
|
||||
changed_when: >-
|
||||
'added ' in (gateway_openclaw_required_global_plugin_installs.stdout | default('')) or
|
||||
'removed ' in (gateway_openclaw_required_global_plugin_installs.stdout | default('')) or
|
||||
'changed ' in (gateway_openclaw_required_global_plugin_installs.stdout | default(''))
|
||||
loop: "{{ gateway_openclaw_required_global_plugins }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}@{{ item.version }}"
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
notify: Restart openclaw gateway
|
||||
|
||||
- name: Remove unsupported OpenClaw global plugin packages
|
||||
ansible.builtin.command:
|
||||
cmd: >-
|
||||
npm uninstall --no-audit --no-fund
|
||||
--prefix "{{ gateway_openclaw_global_npm_dir }}"
|
||||
{{ item }}
|
||||
environment:
|
||||
HOME: "{{ gateway_openclaw_home }}"
|
||||
PATH: "{{ gateway_openclaw_service_path }}"
|
||||
OPENCLAW_NO_RESPAWN: "1"
|
||||
NODE_COMPILE_CACHE: "{{ gateway_openclaw_compile_cache_dir }}"
|
||||
become: true
|
||||
become_user: "{{ gateway_openclaw_service_user }}"
|
||||
register: gateway_openclaw_removed_global_plugin_packages
|
||||
changed_when: "'removed ' in (gateway_openclaw_removed_global_plugin_packages.stdout | default(''))"
|
||||
loop: "{{ gateway_openclaw_removed_global_plugins }}"
|
||||
loop_control:
|
||||
label: "{{ item }}"
|
||||
when:
|
||||
- gateway_openclaw_removed_global_plugins | length > 0
|
||||
- not ansible_check_mode
|
||||
notify: Restart openclaw gateway
|
||||
|
||||
- name: Reset OpenClaw compile cache after package or plugin changes
|
||||
ansible.builtin.file:
|
||||
path: "{{ gateway_openclaw_compile_cache_dir }}"
|
||||
state: absent
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- >-
|
||||
(gateway_openclaw_package_install.changed | default(false))
|
||||
or
|
||||
(gateway_openclaw_required_global_plugin_installs.changed | default(false))
|
||||
or
|
||||
(gateway_openclaw_removed_global_plugin_packages.changed | default(false))
|
||||
|
||||
- name: Recreate OpenClaw compile cache after package or plugin changes
|
||||
ansible.builtin.file:
|
||||
path: "{{ gateway_openclaw_compile_cache_dir }}"
|
||||
state: directory
|
||||
owner: "{{ gateway_openclaw_service_user }}"
|
||||
group: "{{ gateway_openclaw_service_group }}"
|
||||
mode: "0755"
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- >-
|
||||
(gateway_openclaw_package_install.changed | default(false))
|
||||
or
|
||||
(gateway_openclaw_required_global_plugin_installs.changed | default(false))
|
||||
or
|
||||
(gateway_openclaw_removed_global_plugin_packages.changed | default(false))
|
||||
|
||||
- name: Refresh OpenClaw plugin registry
|
||||
ansible.builtin.command:
|
||||
cmd: "{{ gateway_openclaw_binary_path }} plugins registry --refresh"
|
||||
environment:
|
||||
HOME: "{{ gateway_openclaw_home }}"
|
||||
PATH: "{{ gateway_openclaw_service_path }}"
|
||||
OPENCLAW_NO_RESPAWN: "1"
|
||||
NODE_COMPILE_CACHE: "{{ gateway_openclaw_compile_cache_dir }}"
|
||||
become: true
|
||||
become_user: "{{ gateway_openclaw_service_user }}"
|
||||
changed_when: false
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
|
||||
- name: Move stale OpenClaw plugin backups out of extension scan path
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
@ -198,27 +297,6 @@
|
||||
- item.stat.exists | default(false)
|
||||
- not ansible_check_mode
|
||||
|
||||
- name: Repair OpenClaw 2026.5 route state as service user
|
||||
ansible.builtin.command:
|
||||
cmd: "{{ gateway_openclaw_binary_path }} doctor --fix --non-interactive"
|
||||
environment:
|
||||
HOME: "{{ gateway_openclaw_home }}"
|
||||
PATH: "{{ gateway_openclaw_service_path }}"
|
||||
OPENCLAW_NO_RESPAWN: "1"
|
||||
NODE_COMPILE_CACHE: "{{ gateway_openclaw_compile_cache_dir }}"
|
||||
OPENCLAW_SERVICE_REPAIR_POLICY: external
|
||||
become: true
|
||||
become_user: "{{ gateway_openclaw_service_user }}"
|
||||
register: gateway_openclaw_doctor_repair
|
||||
changed_when: >-
|
||||
((gateway_openclaw_doctor_repair.stdout | default('')) ~ '\n' ~
|
||||
(gateway_openclaw_doctor_repair.stderr | default('')))
|
||||
is search('(?i)(fixed|repaired|migrated|rewrote|removed|set |moved |updated|archived)')
|
||||
when:
|
||||
- gateway_openclaw_doctor_repair_enabled | bool
|
||||
- not ansible_check_mode
|
||||
notify: Restart openclaw gateway
|
||||
|
||||
- name: Restore immutable flag on OpenClaw gateway JSON config
|
||||
ansible.builtin.command:
|
||||
cmd: chattr +i "{{ gateway_openclaw_config_path }}"
|
||||
@ -265,6 +343,45 @@
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
|
||||
- name: Check OpenClaw plugin registry
|
||||
ansible.builtin.command:
|
||||
cmd: "{{ gateway_openclaw_binary_path }} plugins list --json"
|
||||
environment:
|
||||
HOME: "{{ gateway_openclaw_home }}"
|
||||
PATH: "{{ gateway_openclaw_service_path }}"
|
||||
OPENCLAW_NO_RESPAWN: "1"
|
||||
NODE_COMPILE_CACHE: "{{ gateway_openclaw_compile_cache_dir }}"
|
||||
become: true
|
||||
become_user: "{{ gateway_openclaw_service_user }}"
|
||||
register: gateway_openclaw_plugin_registry
|
||||
changed_when: false
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
|
||||
- name: Assert OpenClaw Codex plugin matches gateway version
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- >-
|
||||
(
|
||||
(gateway_openclaw_plugin_registry.stdout | from_json).plugins
|
||||
| selectattr('id', 'equalto', 'codex')
|
||||
| selectattr('version', 'equalto', gateway_openclaw_required_version)
|
||||
| list
|
||||
| length
|
||||
) == 1
|
||||
- >-
|
||||
(
|
||||
(gateway_openclaw_plugin_registry.stdout | from_json).plugins
|
||||
| selectattr('id', 'equalto', 'acpx')
|
||||
| list
|
||||
| length
|
||||
) == 0
|
||||
fail_msg: >-
|
||||
OpenClaw must run @openclaw/codex {{ gateway_openclaw_required_version }}
|
||||
and must not keep stale global @openclaw/acpx.
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
|
||||
- name: Ensure OpenClaw user systemd unit directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ gateway_openclaw_user_service_unit_path | dirname }}"
|
||||
|
||||
@ -116,7 +116,6 @@
|
||||
"nvidia": {"enabled": true},
|
||||
"deepseek": {"enabled": true},
|
||||
"browser": {"enabled": false},
|
||||
"acpx": {"enabled": false},
|
||||
"bonjour": {"enabled": false},
|
||||
"codex": {
|
||||
"enabled": true,
|
||||
|
||||
@ -273,6 +273,22 @@
|
||||
):
|
||||
if code in error_text:
|
||||
raise SystemExit(f"legacy OpenClaw routing error remained: {code}")
|
||||
final_text = json.dumps(final, ensure_ascii=False)
|
||||
for marker in (
|
||||
"Requested agent harness",
|
||||
"provider is not one of",
|
||||
"Agent failed before reply",
|
||||
"ACP_HTTP_",
|
||||
):
|
||||
if marker in final_text:
|
||||
raise SystemExit(f"OpenClaw smoke returned runtime error text: {marker}")
|
||||
result = final.get("result") or final.get("payload") or {}
|
||||
output_text = " ".join(
|
||||
str(result.get(key, ""))
|
||||
for key in ("output", "message", "summary", "resultSummary")
|
||||
)
|
||||
if "pong" not in output_text.lower():
|
||||
raise SystemExit(f"OpenClaw smoke did not return pong: {output_text[:500]}")
|
||||
PY
|
||||
args:
|
||||
executable: /bin/bash
|
||||
@ -340,10 +356,32 @@
|
||||
raise SystemExit("missing accepted SSE event")
|
||||
if elapsed_seconds >= 15 and "xworkmate.bridge.keepalive" not in methods:
|
||||
raise SystemExit("missing keepalive SSE event")
|
||||
if "validate-openclaw-sse" not in ids:
|
||||
final = next(
|
||||
(item for item in payloads if isinstance(item, dict) and item.get("id") == "validate-openclaw-sse"),
|
||||
None,
|
||||
)
|
||||
if final is None:
|
||||
raise SystemExit("missing final SSE result envelope")
|
||||
if not payloads or payloads[-1].get("done") is not True:
|
||||
raise SystemExit("missing SSE done marker")
|
||||
final_text = json.dumps(final, ensure_ascii=False)
|
||||
for marker in (
|
||||
"Requested agent harness",
|
||||
"provider is not one of",
|
||||
"Agent failed before reply",
|
||||
"ACP_HTTP_",
|
||||
"OPENCLAW_GATEWAY_METHOD_NOT_ALLOWED",
|
||||
"OPENCLAW_GATEWAY_CONFLICT",
|
||||
):
|
||||
if marker in final_text:
|
||||
raise SystemExit(f"OpenClaw long-task smoke returned runtime error text: {marker}")
|
||||
result = final.get("result") or final.get("payload") or {}
|
||||
output_text = " ".join(
|
||||
str(result.get(key, ""))
|
||||
for key in ("output", "message", "summary", "resultSummary")
|
||||
)
|
||||
if "pong" not in output_text.lower():
|
||||
raise SystemExit(f"OpenClaw long-task smoke did not return pong: {output_text[:500]}")
|
||||
PY
|
||||
args:
|
||||
executable: /bin/bash
|
||||
|
||||
Loading…
Reference in New Issue
Block a user