feat(lib): expose data_converter kwarg on AgentexWorker and Temporal client APIs#372
Open
matteolibrizzi-scale wants to merge 2 commits into
Open
feat(lib): expose data_converter kwarg on AgentexWorker and Temporal client APIs#372matteolibrizzi-scale wants to merge 2 commits into
matteolibrizzi-scale wants to merge 2 commits into
Conversation
…client APIs Adds a `data_converter` kwarg to: - `AgentexWorker.__init__` and `worker.get_temporal_client` - `clients.temporal.utils.get_temporal_client` - `TemporalClient` / `TemporalACP` / `TemporalACPConfig` / `FastACP` This unlocks composing `OpenAIAgentsPlugin` with a payload codec by passing a pre-built `DataConverter(payload_converter_class=OpenAIPayloadConverter, payload_codec=...)`. Previously the plugin would silently drop a standalone `payload_codec` kwarg because its `_data_converter(None)` transformer builds a fresh converter without any codec — the existing guard rejected this combination outright. The guard is refined: it now fires only when both the plugin is present AND `payload_codec` is the standalone kwarg AND no `data_converter` was supplied, and the error message points callers at the working composition path. An additional guard rejects passing `payload_codec` and `data_converter` together as ambiguous. No behavior change for existing callers (none currently pass `data_converter`). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add `model_validator(mode="after")` on `TemporalACPConfig` that rejects setting both `payload_codec` and `data_converter`, mirroring the `get_temporal_client` ambiguity guard at config-construction time (consistent with the existing `plugins` / `interceptors` validators). - Collapse multi-line comments in `worker.py` and `clients/temporal/utils.py` to single-line context — the PR description carries the long-form rationale. - Ruff import-order autofixes on touched files (resolves CI lint). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
data_converterkwarg to the AgentexWorker / TemporalClient / TemporalACP API surface so callers can composeOpenAIAgentsPluginwith a payload codec (e.g. AES-GCM at-rest encryption).Why
Today, passing
payload_codec=...toAgentexWorker(...)together withOpenAIAgentsPluginraises with a hard guard. That guard is correct for the API surface currently exposed: without it, the plugin's_data_converter(None)transformer builds a freshDataConverterand the user's codec is silently dropped — payloads land in Temporal in plain text.But the composition does work if you pre-build a
DataConverterwith bothpayload_converter_class=OpenAIPayloadConverterANDpayload_codec=...and pass it viaClient.connect(data_converter=...). The plugin's transformer has a fourth branch that passes through anyDataConverterwhose payload converter is anOpenAIPayloadConverterinstance (or subclass) unchanged. This PR exposes that working path through the agentex API.The first downstream user is the Emu Deep Research agent, which needs both
OpenAIAgentsPlugin(to dispatch model calls asinvoke_model_activityunder Temporal) and the sharedemu_shared.encryption.codec.get_payload_codec()already used by OneEdge / FDD / VDR.What changed
New
data_converterkwarg on:agentex.lib.core.temporal.workers.worker.get_temporal_clientandAgentexWorker.__init__(worker side)agentex.lib.core.clients.temporal.utils.get_temporal_client(client side)TemporalClient.__init__/TemporalClient.createTemporalACP.__init__/TemporalACP.createTemporalACPConfig(forwarded byFastACP.create_async_acp)Guards in both
get_temporal_clientimplementations:payload_codecANDdata_convertertogether raiseValueError(the codec belongs inside the data converter).OpenAIAgentsPluginis present ANDpayload_codecis the standalone kwarg AND nodata_converterwas supplied. The error message now points callers at the working composition path (DataConverter(payload_converter_class=OpenAIPayloadConverter, payload_codec=...)).No behavior change for existing callers — none currently pass
data_converter.Usage
Test plan
tests/lib/passtests/lib/test_payload_codec.pyfor bothget_temporal_clientpaths:data_converterpass-through withOpenAIAgentsPlugindata_converterpass-through without pluginpayload_codec+data_convertertogether raises ambiguity errordata_converterAgentexWorker,TemporalClient,TemporalACP,TemporalACPConfig,FastACPstoring/forwardingdata_converterdata_converterappears on all five public surfaces🤖 Generated with Claude Code
Greptile Summary
This PR exposes a
data_converterkwarg across all five public surfaces (AgentexWorker,TemporalClient,TemporalACP,TemporalACPConfig,FastACP) to let callers composeOpenAIAgentsPluginwith a payload codec by pre-building a fully-configuredDataConverterand passing it directly, bypassing the conflict that previously blocked this combination.get_temporal_clientimplementations rejectspayload_codec+data_convertertogether; the existing OpenAI-plugin silent-drop guard is tightened to fire only whenpayload_codecis the standalone kwarg (not when a fullDataConverteris supplied).TemporalACPConfiggains amodel_validatorthat enforces mutual exclusion at config construction time, consistent with its existing eager-validation pattern for plugins and interceptors.Client.connectis mocked.Confidence Score: 4/5
Safe to merge for callers who follow the documented usage; the new data_converter path works correctly when the caller supplies a properly-constructed DataConverter.
The change is well-scoped and backwards-compatible. All existing callers are unaffected. The one gap worth noting is that
AgentexWorker.__init__accepts incompatiblepayload_codec+data_convertercombinations silently, only surfacing the error later inrun()after partial startup steps (health check server, agent registration) have already executed — whereasTemporalACPConfigenforces the same constraint eagerly at construction.src/agentex/lib/core/temporal/workers/worker.py —
AgentexWorker.__init__does not validate the mutual exclusion thatget_temporal_clientenforces, so misconfigured workers start partially before failing.Important Files Changed
data_converterkwarg with ambiguity guard and refined OpenAI-plugin guard; passes converter directly to Client.connect when supplied.AgentexWorker.__init__storesdata_converterbut skips the mutual-exclusion check thatTemporalACPConfigenforces at construction.data_convertertoTemporalClient.__init__andcreate; correctly threads it through toget_temporal_client.data_converterfield toTemporalACPConfigwith amodel_validatorenforcing mutual exclusion withpayload_codecat construction time.data_convertertoTemporalACP.__init__andcreate, correctly forwarded toTemporalClient.create.data_converterfrom config toimplementation_class.createusing the samehasattrpattern aspayload_codec.data_converter+ OpenAI-plugin tests mockClient.connectso plugin transformer behavior is not exercised end-to-end.Sequence Diagram
sequenceDiagram participant Caller participant AgentexWorker participant TemporalACP participant TemporalClient participant get_temporal_client participant Client.connect Caller->>AgentexWorker: "__init__(data_converter=dc)" note over AgentexWorker: stores dc, no early validation Caller->>AgentexWorker: "run(activities, workflow=...)" AgentexWorker->>get_temporal_client: "(data_converter=dc, plugins=...)" get_temporal_client->>get_temporal_client: guard: payload_codec+data_converter → ValueError get_temporal_client->>get_temporal_client: guard: has_openai_plugin+payload_codec → ValueError get_temporal_client->>Client.connect: "data_converter=dc (passed through)" Caller->>TemporalACP: "create(data_converter=dc)" TemporalACP->>TemporalClient: "create(data_converter=dc)" TemporalClient->>get_temporal_client: "(data_converter=dc)" get_temporal_client->>Client.connect: "data_converter=dc" Caller->>TemporalACPConfig: "(payload_codec=x, data_converter=dc)" TemporalACPConfig->>TemporalACPConfig: model_validator → ValueError (eager)Prompt To Fix All With AI
Reviews (2): Last reviewed commit: "fix(lib): tighten TemporalACPConfig + co..." | Re-trigger Greptile