Commit graph

11 commits

Author SHA1 Message Date
JD Davis
01161fe019
test(openclaw): match inherited PATH shell check (#2821)
## Description

Fix the OpenClaw test failure on `main` by aligning its PATH-launcher
expectation with the intentionally shipped `sh -c` behavior from #1459.

The non-login shell preserves the PATH inherited from the OpenClaw
process. Changing production code back to `sh -lc` would risk a login
shell resetting that PATH and would undo the compatibility fix. This PR
therefore corrects only the stale assertion; runtime behavior and
defaults do not change.

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)

## Changes Made

- Expect `sh -c` for the non-Windows lightweight `command -v headroom`
check.
- Preserve the existing Windows `where.exe` behavior and all launcher
behavior.

## Testing

- [x] Unit tests pass (`npm test`)
- [x] Linting passes (`npm run typecheck`)
- [x] Type checking passes (`npm run typecheck`)
- [ ] New tests added for new functionality
- [x] Manual testing performed

### Test Output

```text
$ npm test
Test Files  6 passed (6)
Tests  75 passed (75)

$ npm run typecheck
> tsc --noEmit

$ npm run build
ESM Build success
DTS Build success

$ npm ci
found 0 vulnerabilities
```

## Real Behavior Proof

- Environment: macOS, Node/npm, clean install from `origin/main` at
`2954e37048`.
- Exact command / steps: `cd plugins/openclaw && npm ci && npm test &&
npm run typecheck && npm run build`.
- Observed result: all 75 OpenClaw tests pass, TypeScript typechecking
succeeds, and both ESM and declaration builds succeed.
- Not tested: Windows execution; its separate `where.exe` expectation
and implementation are unchanged.

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Checklist

- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] I did **not** edit `CHANGELOG.md` — it is generated by
release-please from my Conventional Commit PR title (a CI guard enforces
this)

## Screenshots (if applicable)

N/A — test-only correction with no UI changes.

## Additional Notes

History confirms #1459 deliberately changed `sh -lc` to `sh -c` while
adding explicit uv-tool path detection. Reverting the implementation
would change runtime discovery semantics; updating the stale test
preserves the accepted behavior.

Co-authored-by: JD Davis <jd@jds-macbook-air.tail2a279.ts.net>
2026-08-06 19:21:52 -07:00
felixboenkost-droid
6d116b15f1
Harden OpenClaw plugin proxy routing (#1074)
## Description

Hardens the bundled OpenClaw plugin so configured proxy routing is
fail-closed and `autoStart` is opt-in.

Closes: N/A

This follow-up is intentionally separate from the ContentRouter cache
fix because it changes plugin/gateway behavior rather than core
compression routing.

The plugin should not mutate upstream provider routing unless a
configured proxy URL is reachable and looks like Headroom. It should
also avoid unhandled startup promise rejections when proxy startup is
fire-and-forget.

Why this shape:

- `autoStart: false` by default matches deployments where Headroom is
supervised externally, for example by systemd. The plugin should not
silently start or assume ownership of a proxy unless the operator opted
in.
- Provider routing is fail-closed: a configured URL must first respond
like Headroom, not merely expose a generic liveness endpoint. This
prevents accidentally routing model traffic through the wrong local
service.
- `/readyz` is treated as liveness, not identity. Identity comes from
Headroom-shaped stats endpoints (`/v1/retrieve/stats` or `/stats`)
because those are harder for unrelated services to satisfy by accident.
- Startup remains asynchronous, but errors are captured and exposed
instead of becoming unhandled promise rejections.
- This is a separate PR because the core cache fix is about compression
correctness, while this patch is about integration safety around
OpenClaw gateway routing.

## Type of Change

- [x] Bug fix (non-breaking change fixes issue)
- [ ] New feature (non-breaking change adds functionality)
- [ ] Breaking change (fix or feature would cause existing functionality
change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)

## Changes Made

- Make proxy `autoStart` opt-in (`default: false`).
- Probe configured `proxyUrl` before applying provider routing.
- Treat `/readyz` as liveness only; require Headroom-shaped
`/v1/retrieve/stats` or `/stats` for identity.
- Observe fire-and-forget startup promise rejection and expose startup
error for callers.
- Isolate proxy-ready listener failures.
- Keep provider routing deferred when no active/probed Headroom proxy
exists.
- Register retrieve tool with explicit `headroom_retrieve` name.
- Extend plugin/unit tests for configured proxy failures, generic
non-Headroom endpoints, path collisions, and routing behavior.

Changed files:

- `plugins/openclaw/README.md`
- `plugins/openclaw/openclaw.plugin.json`
- `plugins/openclaw/src/engine.ts`
- `plugins/openclaw/src/plugin/index.ts`
- `plugins/openclaw/src/proxy-manager.ts`
- `plugins/openclaw/test/engine.test.ts`
- `plugins/openclaw/test/gateway-config.test.ts`
- `plugins/openclaw/test/plugin-runtime-routing.test.ts`
- `plugins/openclaw/test/proxy-manager.test.ts`

## Testing

- [x] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check .`)
- [x] Type checking passes (`mypy headroom`)
- [x] New tests added new functionality
- [x] Manual testing performed

### Test Output

```text
$ npm test

Test Files  6 passed (6)
Tests  74 passed (74)

$ npm run typecheck
tsc --noEmit

$ npm run build
tsup && node prepare-dist.mjs
Build success
```

## Real Behavior Proof

- Environment: local OpenClaw plugin package in the Headroom repo.
- Exact command / steps:
  - Run plugin test suite.
  - Run TypeScript typecheck.
  - Run plugin build.
- Observed result:
  - Tests passed: `74/74`.
  - Typecheck passed.
  - Build passed.
- Not tested:
- Full OpenClaw Gateway integration as part of this standalone PR prep.

## Review Readiness

- [x] I performed self-review
- [x] This PR ready for human review

## Checklist

- [x] My code follows project's style guidelines
- [x] I performed self-review my code
- [ ] I commented my code, particularly in hard-to-understand areas
- [x] I made corresponding changes documentation
- [x] My changes generate no new warnings
- [x] I added tests prove fix is effective or feature works
- [x] New and existing unit tests pass locally my changes
- [ ] I updated CHANGELOG.md if applicable

## Screenshots (if applicable)

N/A.

## Additional Notes

Checklist items left unchecked intentionally:

- No CHANGELOG update included.
- No extra comments were needed beyond existing code structure.

Co-authored-by: Björn-Christian Bönkost <bjoern@v2202603344248440850.hotsrv.de>
2026-06-22 22:52:59 -05:00
JerrettDavis
f63cfe7a1e fix: lazy-load proxy startup dependencies
Keep the default Headroom proxy startup path lightweight so OpenClaw can launch it reliably on Windows. This defers heavyweight provider, cache, transform, pricing, and detector imports until they are actually needed, adds a lightweight version module, and keeps the OpenClaw launcher on the configured Python path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-10 20:33:46 -05:00
JerrettDavis
d4f6e3938f fix(proxy): add fast-fail launch settings
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-08 22:03:21 -05:00
JerrettDavis
4d8b76f7da fix(openclaw): use lightweight headroom launcher checks
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-08 21:39:14 -05:00
JerrettDavis
afb339059b fix(openclaw): launch Windows headroom shims via shell
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-08 21:16:32 -05:00
JerrettDavis
3e368f13c8 refactor(openclaw): DRY up duplicate code across plugin
- Extract shared defaultLogger constant, use in both ProxyManager and
  HeadroomContextEngine (was duplicated inline in both constructors)
- Extract parseProxyUrl() helper, reused by normalizeAndValidateProxyUrl
  and withDefaultPort (eliminates redundant URL parsing)
- Add test helpers: stubProbeSuccess/NonHeadroom/Unreachable to replace
  6 identical inline fetch mock constructions
- Remove duplicate probe tests from engine.test.ts (already covered in
  proxy-manager.test.ts)
- Clean up unused probeHeadroomProxy import from engine.test.ts

Net: -26 lines, same coverage (28 tests)
2026-04-03 10:30:10 -05:00
JerrettDavis
89f3e5f01f fix(openclaw): proxyPort only applies to local URLs, consistency pass
- proxyPort default (8787) now only applied to local URLs; remote URLs
  use their protocol default (80/443) as expected
- Remove redundant localhost-only entries from network capabilities
  (covered by http://*:* and https://*:* wildcards)
- Sync package.json capabilities with openclaw.plugin.json
- Export isLocalProxyUrl from barrel index
- Fix JSDoc indentation in start() method
- Rename "Required Proxy Setup" to "Manual Proxy Setup" with accurate
  description for remote proxy users
- Clarify autoStart description: local-only, ignored for remote
- Add test: remote URL does not get proxyPort applied

Build: tsc clean, 30 tests passed
2026-04-03 10:30:10 -05:00
JerrettDavis
4c3d9c4e28 feat(openclaw): support remote Headroom proxy (connect-only)
Remove localhost-only restriction from proxyUrl validation. Remote URLs
are connect-only: the plugin probes and uses them but never attempts to
spawn a subprocess. Auto-start remains available for local addresses
(127.0.0.1/localhost) only.

- Accept http:// and https:// URLs for any hostname
- Add isLocalProxyUrl() helper to gate auto-start on local addresses
- Remote URLs that fail probe get a clear "Remote proxy not reachable"
  error instead of falling through to auto-start
- Update plugin.json schema, network capabilities, and UI hints
- Update plugin README with local vs remote proxy sections
- Add tests: remote connect, remote fail-fast, isLocalProxyUrl

Build: tsc --noEmit clean
Tests: 29 passed (0 skipped)
2026-04-03 10:30:09 -05:00
JerrettDavis
fa99ba785e docs: add OpenClaw plugin section to main README
Add dedicated OpenClaw plugin section with install instructions,
explanation of --dangerously-force-unsafe-install requirement (proxy
subprocess spawning), and quick config example. Links to plugin README
for full details. Update integration tables to reference new section.

Also fix proxy port handling: apply default proxyPort when explicit
proxyUrl omits port, and allow trailing slash in proxyUrl validation
pattern. Add test coverage for port defaulting behavior.
2026-04-03 10:30:09 -05:00
JerrettDavis
3569eabdbd Add comprehensive tests for proxy detection and launcher logic 2026-04-02 22:28:48 -05:00