Skip to content

DRAFT: For PR #2035: add /hooks endpoint#2088

Draft
enyst wants to merge 8 commits intosupport-openhands-hooks-json-in-agent-serverfrom
stacked/hooks-endpoint-alternative
Draft

DRAFT: For PR #2035: add /hooks endpoint#2088
enyst wants to merge 8 commits intosupport-openhands-hooks-json-in-agent-serverfrom
stacked/hooks-endpoint-alternative

Conversation

@enyst
Copy link
Collaborator

@enyst enyst commented Feb 15, 2026

Hi! I’m OpenHands-GPT-5.2 (an OpenHands dev assistant agent).

This is a stacked PR targeting PR #2035 (base: support-openhands-hooks-json-in-agent-server) as a friendly alternative proposal.

Motivation

Instead of auto-loading .openhands/hooks.json inside event_service.start() (agent-server), this proposes a skills-style approach:

  • expose an explicit POST /api/hooks endpoint on agent-server
  • app-server can call this endpoint during conversation setup, merge the returned HookConfig into the agent payload, and send it via StartConversationRequest.hook_config
  • app-server can enforce policy centrally (e.g. default load_user=false), and agent-server conversation start stays more deterministic

What’s included

  • openhands-agent-server/openhands/agent_server/hooks_router.py: new /hooks endpoint
  • openhands-agent-server/openhands/agent_server/hooks_service.py: loads {project_dir}/.openhands/hooks.json
  • openhands-agent-server/openhands/agent_server/api.py: wires router under /api
  • Unit test: tests/agent_server/test_hooks_router.py

cc @ak684 — thanks! This PR is meant to be a little incremental change rebased on yours so we can compare designs side-by-side.

Co-authored-by: openhands openhands@all-hands.dev

@enyst can click here to continue refining the PR

\nCo-authored-by: openhands <openhands@all-hands.dev>
@github-actions
Copy link
Contributor

github-actions bot commented Feb 15, 2026

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-agent-server/openhands/agent_server
   api.py1501093%70, 82, 245, 248, 252–254, 256, 262, 303
   hooks_router.py30293%26–27
   hooks_service.py21385%33–35
TOTAL16817731656% 

@enyst enyst changed the title DRAFT: Alternative to PR #2035: add /hooks endpoint (project hooks only) DRAFT: For PR #2035: add /hooks endpoint (project hooks only) Feb 15, 2026
@enyst enyst changed the title DRAFT: For PR #2035: add /hooks endpoint (project hooks only) DRAFT: For PR #2035: add /hooks endpoint Feb 15, 2026
… flags

\nCo-authored-by: openhands <openhands@all-hands.dev>
\nCo-authored-by: openhands <openhands@all-hands.dev>
@enyst enyst requested a review from all-hands-bot February 15, 2026 20:23
Copy link
Collaborator

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taste Rating: 🟡 Acceptable

The core design is clean and simple—router delegates to service, service delegates to SDK. Good separation of concerns. However, there are security and testing gaps that need addressing before this is production-ready.

Key Insight: This is a sensible architectural choice (explicit API vs implicit loading), but the implementation needs hardening around path validation and more comprehensive test coverage.

\nCo-authored-by: openhands <openhands@all-hands.dev>
\nCo-authored-by: openhands <openhands@all-hands.dev>
\nCo-authored-by: openhands <openhands@all-hands.dev>
@enyst enyst requested a review from all-hands-bot February 15, 2026 20:44
Copy link
Collaborator

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Acceptable - Core logic is sound and well-tested, but has unnecessary complexity and weak validation that should be addressed.

\nCo-authored-by: openhands <openhands@all-hands.dev>
@enyst enyst requested a review from all-hands-bot February 15, 2026 21:25
Copy link
Collaborator

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taste Rating: 🟡 Acceptable - Core design is solid and pragmatic, but error handling and path validation need hardening before production use.

[CRITICAL ISSUES]

Path Validation Security: The validation is too permissive and doesn't protect against path traversal or unauthorized access.

Error Handling: Swallowing all exceptions loses critical debugging information when things go wrong.

Test Logic Inconsistency: Test expects rejection of relative paths, but code actually resolves them.

[IMPROVEMENT OPPORTUNITIES]

API Design: Returning None for both "not found" and "invalid path" conflates different failure modes.

Test Coverage: Missing tests for malformed JSON, permission errors, and other failure scenarios.

Unrelated Change: AGENTS.md documentation is useful but unrelated to the hooks feature.


VERDICT: ✅ Worth merging after fixes - The skills-style approach is cleaner than auto-loading. Address the path validation and error handling issues first.

KEY INSIGHT: Good separation of concerns (router/service) and explicit control over loading behavior, but security and observability need attention before this touches production.

…_dir

\nCo-authored-by: openhands <openhands@all-hands.dev>
Copy link
Collaborator Author

enyst commented Feb 15, 2026

Note on path validation / workspace roots

AI review raised concerns about project_dir potentially enabling reads outside the workspace.

Current agent-server patterns:

  • file_router endpoints require absolute paths but do not enforce a single workspace root.
  • git_router currently accepts a Path parameter and does not validate it at all.

What this PR does now:

  • /api/hooks performs lightweight normalization + rejects relative paths (to avoid accidental resolve() turning relative input into an absolute path).
  • We intentionally do not attempt to enforce project_dir under a specific workspace root yet, because agent-server doesn’t have a stable canonical root across runtimes and clients.

Follow-up:

Copy link
Collaborator Author

enyst commented Feb 15, 2026

Path handling patterns in agent-server (context for /hooks)

On the path-safety concern: today agent-server already has multiple endpoints that accept filesystem paths and do not consistently enforce a single workspace-root sandbox policy. The design assumption is that agent-server runs inside the agent-box and client apps (app-server/CLI) provide the right paths + auth, so these are effectively internal APIs within the sandbox boundary.

Examples in current codebase:

  • file_router requires absolute paths but doesn’t enforce a workspace root: it checks Path(path).is_absolute() and then reads/writes that path.
  • git_router accepts a Path parameter and passes it to SDK helpers with no validation.
  • /skills accepts project_dir and passes it through to load_all_skills(..., project_dir=request.project_dir) with no validation.

What we’re doing for /hooks for now:

  • Keep it lightweight and consistent with the above: reject obvious relative inputs (to avoid resolve() implicitly turning a relative into an absolute cwd-based path), normalize absolute paths, and otherwise rely on the agent-box boundary + client auth/policy.

Follow-up:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants