Skip to content

fix: forward event request context to agents#348

Closed
rpatel-scale wants to merge 1 commit into
mainfrom
codex/agentex-forward-event-request-context
Closed

fix: forward event request context to agents#348
rpatel-scale wants to merge 1 commit into
mainfrom
codex/agentex-forward-event-request-context

Conversation

@rpatel-scale

@rpatel-scale rpatel-scale commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • include safe request context headers in EVENT_SEND JSON-RPC params
  • expose Agentex-generated delegated user headers to agent handlers via params.request.headers
  • keep x-agent-api-key out of params.request while still sending it as the ACP HTTP auth header

Why

The lineage supervisor receives EVENT_SEND over Temporal and reads delegated credentials from SendEventParams.request. Agentex was sending the delegated credentials as HTTP headers to the pod, but serialized SendEventParams with request=None, so the workflow could not call /v5/builds with user credentials and hit 401.

Validation

  • python3 -m py_compile agentex/src/domain/services/agent_acp_service.py agentex/tests/unit/services/test_agent_acp_service.py
  • uv run ruff check agentex/src/domain/services/agent_acp_service.py agentex/tests/unit/services/test_agent_acp_service.py
  • uv run ruff format --check agentex/src/domain/services/agent_acp_service.py agentex/tests/unit/services/test_agent_acp_service.py
  • uv run --group test pytest tests/unit/services/test_agent_acp_service.py::TestAgentACPService::test_send_event_request_context_exposes_delegated_headers_not_agent_auth -q

Note: the full test_agent_acp_service.py file requires Docker/testcontainers locally; Docker is not available on this machine, so the full file could not complete here.

Greptile Summary

This PR fixes a 401 error in the lineage supervisor by forwarding the Agentex-generated delegated user headers into SendEventParams.request.headers so that the Temporal workflow can read them when calling downstream APIs with user credentials.

  • Service refactor: get_request_context_headers is extracted as a new synchronous method returning the safe subset of headers (filtered passthrough + delegation, excluding x-agent-api-key); get_headers now delegates to it before adding auth headers on top.
  • send_event fix: params.request is now populated with {"headers": request_context_headers} instead of None, making delegated credentials available to the serialized SendEventParams that Temporal reads.
  • Tests: Existing tests updated to assert params.request.headers is present; a new isolated unit test (no Docker dependency) verifies agent auth key is kept out of params.request while still reaching the agent pod as an HTTP header.

Confidence Score: 4/5

Safe to merge; the fix is narrow and well-tested, credentials are correctly segregated between params and HTTP headers.

The logic is sound: x-agent-api-key stays out of params.request while delegation headers flow into both the JSON-RPC body and the HTTP headers. The only nit is that get_request_context_headers is computed twice inside send_event (once explicitly, once inside get_headers), which is wasteful but harmless since request state is immutable per call.

agentex/src/domain/services/agent_acp_service.py — the double-computation of context headers in send_event is worth a quick look.

Important Files Changed

Filename Overview
agentex/src/domain/services/agent_acp_service.py Extracts get_request_context_headers (sync) from get_headers (async) and populates SendEventParams.request with safe delegation headers; get_request_context_headers is called twice in send_event (once directly, once inside get_headers) — minor redundancy but no correctness impact.
agentex/tests/unit/services/test_agent_acp_service.py Tests updated and extended to assert params.request.headers is now populated; new isolated unit test (no Docker) covers the agent-auth-key exclusion invariant clearly.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Caller
    participant AgentACPService
    participant get_request_context_headers
    participant get_headers
    participant AgentPod

    Caller->>AgentACPService: send_event(agent, event, task, request_headers)
    AgentACPService->>get_request_context_headers: filter passthrough + delegation headers
    get_request_context_headers-->>AgentACPService: request_context_headers (no agent-api-key)
    Note over AgentACPService: Build SendEventParams<br/>params.request.headers = request_context_headers
    AgentACPService->>get_headers: get_headers(agent, request_headers)
    Note over get_headers: re-calls get_request_context_headers internally
    get_headers-->>AgentACPService: request_context_headers + x-agent-api-key + x-request-id
    AgentACPService->>AgentPod: "POST /api (JSON-RPC EVENT_SEND)<br/>HTTP headers: delegation + x-agent-api-key<br/>params.request.headers: delegation only (no x-agent-api-key)"
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Caller
    participant AgentACPService
    participant get_request_context_headers
    participant get_headers
    participant AgentPod

    Caller->>AgentACPService: send_event(agent, event, task, request_headers)
    AgentACPService->>get_request_context_headers: filter passthrough + delegation headers
    get_request_context_headers-->>AgentACPService: request_context_headers (no agent-api-key)
    Note over AgentACPService: Build SendEventParams<br/>params.request.headers = request_context_headers
    AgentACPService->>get_headers: get_headers(agent, request_headers)
    Note over get_headers: re-calls get_request_context_headers internally
    get_headers-->>AgentACPService: request_context_headers + x-agent-api-key + x-request-id
    AgentACPService->>AgentPod: "POST /api (JSON-RPC EVENT_SEND)<br/>HTTP headers: delegation + x-agent-api-key<br/>params.request.headers: delegation only (no x-agent-api-key)"
Loading

Fix All in Cursor Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
agentex/src/domain/services/agent_acp_service.py:436-447
`get_request_context_headers` is called twice in `send_event` — once explicitly, and again inside `get_headers`. Both calls invoke `get_delegation_headers`, which re-reads `self._request.state` and re-runs `build_delegation_headers`. The result is identical both times, so there is no correctness issue, but the double work is avoidable by passing the already-computed headers into `get_headers`.

```suggestion
        request_context_headers = self.get_request_context_headers(
            agent, request_headers
        )

        params = SendEventParams(
            agent=agent,
            task=task,
            event=event,
            request={"headers": request_context_headers},
        )

        auth_headers = await self.get_agent_auth_headers(agent)
        request_id = ctx_var_request_id.get(uuid4().hex)
        headers = {
            **request_context_headers,
            **auth_headers,
            "x-request-id": request_id,
        }
```

Reviews (1): Last reviewed commit: "fix: forward event request context to ag..." | Re-trigger Greptile

@rpatel-scale
rpatel-scale requested a review from a team as a code owner July 7, 2026 21:29
@rpatel-scale

Copy link
Copy Markdown
Contributor Author

Closing this service change as superseded. The lineage supervisor fix is now agent-only: use the in-cluster EGP public backend URL () like research_report_agent, avoiding service changes for this POC.

@rpatel-scale

Copy link
Copy Markdown
Contributor Author

Closing this service change as superseded. The lineage supervisor fix is now agent-only: use the in-cluster EGP public backend URL via SGP_CLIENT_BASE_URL like research_report_agent, avoiding service changes for this POC.

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.

1 participant