Skip to content

Commit 8ad88db

Browse files
committed
fix(templates): map LITELLM_API_KEY to OPENAI_API_KEY in Temporal workers
The temporal-openai-agents and temporal-pydantic-ai templates' .env.example only set LITELLM_API_KEY. The OpenAI Agents template's acp.py copies it into OPENAI_API_KEY, the Pydantic AI template never does, and in both the model call runs in the Temporal worker, a separate process started by agentex agents run, which never got the mapping. Following either template's own instructions fails in the worker with openai.OpenAIError: Missing credentials after the activity's retries, while the ACP process looks healthy. (temporal-langgraph is fine: graph.py, imported by the worker, already does the mapping.) Apply the same three-line mapping in both run_worker.py templates and add a parametrized test asserting the worker entrypoints carry it. Reproduced and verified on scaffolded agents against a local backend with only LITELLM_API_KEY set: before, no reply and Missing credentials in the worker log; after, the turn completes (gpt-5-nano). Claude-Session: https://claude.ai/code/session_01HCVKnA7LeJZ44nxZz1uzF3
1 parent 0db6037 commit 8ad88db

3 files changed

Lines changed: 37 additions & 0 deletions

File tree

‎src/agentex/lib/cli/templates/temporal-openai-agents/project/run_worker.py.j2‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
import os
2+
3+
# LiteLLM proxy auth: the worker process runs the model calls, so copy
4+
# LITELLM_API_KEY to OPENAI_API_KEY before importing project code (some
5+
# frameworks build their OpenAI client at import time). Without this the
6+
# worker raises "Missing credentials".
7+
_litellm_key = os.environ.get("LITELLM_API_KEY")
8+
if _litellm_key and not os.environ.get("OPENAI_API_KEY"):
9+
os.environ["OPENAI_API_KEY"] = _litellm_key
10+
111
import asyncio
212

313
from agentex.lib.core.temporal.activities import get_all_activities
@@ -15,6 +25,7 @@ from agentex.lib.core.temporal.plugins.openai_agents.models.temporal_streaming_m
1525
from project.workflow import {{ workflow_class }}
1626
from project.activities import get_weather
1727

28+
1829
environment_variables = EnvironmentVariables.refresh()
1930

2031
logger = make_logger(__name__)

‎src/agentex/lib/cli/templates/temporal-pydantic-ai/project/run_worker.py.j2‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ class and registers every model/tool activity the TemporalAgent needs —
88
so we don't have to enumerate activities by hand here.
99
"""
1010

11+
import os
12+
13+
# LiteLLM proxy auth: the worker process runs the model calls, so copy
14+
# LITELLM_API_KEY to OPENAI_API_KEY before importing project code (some
15+
# frameworks build their OpenAI client at import time). Without this the
16+
# worker raises "Missing credentials".
17+
_litellm_key = os.environ.get("LITELLM_API_KEY")
18+
if _litellm_key and not os.environ.get("OPENAI_API_KEY"):
19+
os.environ["OPENAI_API_KEY"] = _litellm_key
20+
21+
1122
import asyncio
1223

1324
from project.workflow import {{ workflow_class }}
@@ -19,6 +30,7 @@ from agentex.lib.environment_variables import EnvironmentVariables
1930
from agentex.lib.core.temporal.activities import get_all_activities
2031
from agentex.lib.core.temporal.workers.worker import AgentexWorker
2132

33+
2234
environment_variables = EnvironmentVariables.refresh()
2335
logger = make_logger(__name__)
2436

‎tests/lib/cli/test_init_templates.py‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,17 @@ def test_requirements_include_langgraph_plugin_and_temporal(self, tmp_path: Path
137137
requirements = (project_dir / "requirements.txt").read_text()
138138
assert "temporalio[langgraph]>=1.27.0" in requirements
139139
assert "langchain-openai" in requirements
140+
141+
142+
@pytest.mark.parametrize("template_type", [TemplateType.TEMPORAL_OPENAI_AGENTS, TemplateType.TEMPORAL_PYDANTIC_AI])
143+
def test_temporal_worker_maps_litellm_key(tmp_path: Path, template_type: TemplateType):
144+
"""Temporal workers that call OpenAI-compatible models must see OPENAI_API_KEY.
145+
146+
These templates' .env.example only set LITELLM_API_KEY. The model call runs
147+
in the worker process, started separately from the ACP process, so the
148+
worker entrypoint needs the LITELLM_API_KEY -> OPENAI_API_KEY mapping or it
149+
fails with "Missing credentials".
150+
"""
151+
project_dir = _render_project(tmp_path, template_type)
152+
src = (project_dir / "project" / "run_worker.py").read_text()
153+
assert 'os.environ["OPENAI_API_KEY"] = _litellm_key' in src, f"{template_type.value} run_worker.py lacks the LITELLM_API_KEY mapping"

0 commit comments

Comments
 (0)