Skip to content

Commit d930e39

Browse files
[BUZZOK-26080] Bump run_agent and dockerfile for GenAI Agents (#1491)
* Squash and rebase * Lint * Reconcile dependencies, updated IDs, tags --------- Co-authored-by: svc-harness-git2 <svc-harness-git2@datarobot.com>
1 parent 2e3137b commit d930e39

File tree

4 files changed

+97
-70
lines changed

4 files changed

+97
-70
lines changed

public_dropin_environments/python311_genai_agents/Dockerfile

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ ARG UNAME=notebooks
1414
ARG UID=10101
1515
ARG GID=10101
1616

17-
FROM datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11-dev AS base
17+
FROM datarobotdev/mirror_chainguard_datarobot.com_python-fips:3.11-dev-drbuild-1328 AS base
1818

1919
ARG UNAME
2020
ARG UID
@@ -27,7 +27,7 @@ USER root
2727

2828
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
2929
# hadolint ignore=DL3018,DL3059
30-
RUN apk add --no-cache graphviz openblas openssh-server gzip zip unzip curl \
30+
RUN apk add --no-cache uv graphviz openblas openssh-server gzip zip unzip curl \
3131
openjdk-11 vim nano procps tzdata poppler-utils
3232
# hadolint ignore=DL3018,DL3059
3333
RUN apk add --no-cache rust sqlite
@@ -42,7 +42,9 @@ ENV PATH="$VENV_PATH/bin:$PATH" \
4242
PYTHONPATH="/home/notebooks/.ipython/extensions:/home/notebooks/storage"
4343

4444
# hadolint ignore=DL3013
45-
RUN python3 -m venv ${VENV_PATH} && pip3 install -U pip setuptools
45+
RUN uv venv ${VENV_PATH} && \
46+
source ${VENV_PATH}/bin/activate && \
47+
uv pip install -U pip setuptools
4648
WORKDIR ${WORKDIR}
4749

4850
COPY ./agent/agent.py ./agent/cgroup_watchers.py ${AGENTDIR}/
@@ -91,13 +93,12 @@ COPY ./requirements.txt ${WORKDIR}/
9193
COPY ./agent/requirements-agent.txt ${WORKDIR}/
9294

9395
# hadolint ignore=DL3013
94-
RUN python3 -m pip install --upgrade pip setuptools && \
95-
python3 -m pip install --no-cache-dir -r ${WORKDIR}/requirements.txt && rm ${WORKDIR}/requirements.txt && \
96-
python3 -m pip install --no-cache-dir -r ${WORKDIR}/requirements-agent.txt && rm ${WORKDIR}/requirements-agent.txt
97-
98-
# Generative AI Agents
99-
RUN python3 -m pip uninstall -y litellm && \
100-
python3 -m pip install --no-cache-dir --no-warn-conflicts git+https://github.com/datarobot-forks/litellm@mattn/add-datarobot-support-to-litellm
96+
RUN source ${VENV_PATH}/bin/activate && \
97+
uv pip install --no-cache-dir -r ${WORKDIR}/requirements.txt && rm ${WORKDIR}/requirements.txt && \
98+
uv pip install --no-cache-dir -r ${WORKDIR}/requirements-agent.txt && rm ${WORKDIR}/requirements-agent.txt && \
99+
# Generative AI Agents
100+
uv pip uninstall litellm && \
101+
uv pip install --no-cache-dir git+https://github.com/BerriAI/litellm@v1.72.1.dev1
101102

102103
# Copy agent runtime into work directory
103104
COPY ./run_agent.py ${WORKDIR}/

public_dropin_environments/python311_genai_agents/Dockerfile.local

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ USER root
6767

6868
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
6969
# hadolint ignore=DL3018,DL3059
70-
RUN apk add --no-cache graphviz openblas openssh-server gzip zip unzip curl \
70+
RUN apk add --no-cache uv graphviz openblas openssh-server gzip zip unzip curl \
7171
openjdk-11 vim nano procps tzdata poppler-utils
7272
# hadolint ignore=DL3018,DL3059
7373
RUN apk add --no-cache rust sqlite
@@ -81,8 +81,10 @@ ENV PYTHONUNBUFFERED=1 \
8181
ENV PATH="$VENV_PATH/bin:$PATH" \
8282
PYTHONPATH="/home/notebooks/.ipython/extensions:/home/notebooks/storage"
8383

84-
# hadolint ignore=DL3013
85-
RUN python3 -m venv ${VENV_PATH} && pip3 install -U pip setuptools
84+
# hadolint ignore=SC1091
85+
RUN uv venv ${VENV_PATH} && \
86+
source ${VENV_PATH}/bin/activate && \
87+
uv pip install -U pip setuptools
8688
WORKDIR ${WORKDIR}
8789

8890
COPY ./agent/agent.py ./agent/cgroup_watchers.py ${AGENTDIR}/
@@ -130,14 +132,13 @@ ARG VENV_PATH
130132
COPY ./requirements.txt ${WORKDIR}/
131133
COPY ./agent/requirements-agent.txt ${WORKDIR}/
132134

133-
# hadolint ignore=DL3013
134-
RUN python3 -m pip install --upgrade pip setuptools && \
135-
python3 -m pip install --no-cache-dir -r ${WORKDIR}/requirements.txt && rm ${WORKDIR}/requirements.txt && \
136-
python3 -m pip install --no-cache-dir -r ${WORKDIR}/requirements-agent.txt && rm ${WORKDIR}/requirements-agent.txt
137-
138-
# Generative AI Agents
139-
RUN python3 -m pip uninstall -y litellm && \
140-
python3 -m pip install --no-cache-dir --no-warn-conflicts git+https://github.com/datarobot-forks/litellm@mattn/add-datarobot-support-to-litellm
135+
# hadolint ignore=SC1091
136+
RUN source ${VENV_PATH}/bin/activate && \
137+
uv pip install --no-cache-dir -r ${WORKDIR}/requirements.txt && rm ${WORKDIR}/requirements.txt && \
138+
uv pip install --no-cache-dir -r ${WORKDIR}/requirements-agent.txt && rm ${WORKDIR}/requirements-agent.txt && \
139+
# Generative AI Agents
140+
uv pip uninstall litellm && \
141+
uv pip install --no-cache-dir git+https://github.com/BerriAI/litellm@v1.72.1.dev1
141142

142143
# Copy agent runtime into work directory
143144
COPY ./run_agent.py ${WORKDIR}/

public_dropin_environments/python311_genai_agents/env_info.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "This template environment can be used to create GenAI-powered agents using CrewAI, LangGraph, or Llama-Index. Similar to other drop-in environments, you can either include a .pth artifact or any other code needed to deserialize your model, and optionally a custom.py file. You can also use this environment in codespaces.",
55
"programmingLanguage": "python",
66
"label": "",
7-
"environmentVersionId": "6839fd8c0c7c49980cd3f879",
7+
"environmentVersionId": "68409da3ebb36a0f9475123a",
88
"environmentVersionDescription": "",
99
"isPublic": true,
1010
"useCases": [
@@ -13,8 +13,8 @@
1313
],
1414
"imageRepository": "env-python-genai-agents",
1515
"tags": [
16-
"v11.1.0-6839fd8c0c7c49980cd3f879",
17-
"6839fd8c0c7c49980cd3f879",
16+
"v11.1.0-68409da3ebb36a0f9475123a",
17+
"68409da3ebb36a0f9475123a",
1818
"v11.1.0-latest"
1919
]
2020
}

public_dropin_environments/python311_genai_agents/run_agent.py

Lines changed: 71 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import os
1919
import sys
2020
from pathlib import Path
21-
from typing import Any
21+
from typing import Any, Optional, Union, cast
2222
from urllib.parse import urlparse, urlunparse
2323

2424
import requests
@@ -46,32 +46,51 @@ def argparse_args() -> argparse.Namespace:
4646
required=True,
4747
help="OpenAI ChatCompletion dict as json string",
4848
)
49-
parser.add_argument(
50-
"--default_headers",
51-
type=str,
52-
default="{}",
53-
help="OpenAI default_headers as json string",
54-
)
5549
parser.add_argument(
5650
"--custom_model_dir",
5751
type=str,
5852
required=True,
5953
help="directory containing custom.py location",
6054
)
55+
parser.add_argument(
56+
"--default_headers",
57+
type=str,
58+
default="{}",
59+
help="OpenAI default_headers as json string",
60+
)
6161
parser.add_argument("--output_path", type=str, default=None, help="json output file location")
6262
parser.add_argument("--otlp_entity_id", type=str, default=None, help="Entity ID for tracing")
6363
args = parser.parse_args()
6464
return args
6565

6666

67-
def setup_logging(logger: logging.Logger, log_level: int = logging.INFO) -> None:
67+
def setup_logging(
68+
logger: logging.Logger,
69+
output_path: Optional[Union[Path, str]] = DEFAULT_OUTPUT_LOG_PATH,
70+
log_level: Optional[int] = logging.INFO,
71+
update: Optional[bool] = False,
72+
) -> None:
73+
log_level = cast(int, log_level)
74+
output_path = str(output_path)
75+
6876
logger.setLevel(log_level)
6977
handler_stream = logging.StreamHandler(sys.stdout)
7078
handler_stream.setLevel(log_level)
7179
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
7280
handler_stream.setFormatter(formatter)
7381

82+
if os.path.exists(output_path):
83+
os.remove(output_path)
84+
handler_file = logging.FileHandler(output_path)
85+
handler_file.setLevel(log_level)
86+
formatter_file = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
87+
handler_file.setFormatter(formatter_file)
88+
89+
if update:
90+
logger.handlers.clear()
91+
7492
logger.addHandler(handler_stream)
93+
logger.addHandler(handler_file)
7594

7695

7796
def setup_otlp_env_variables(entity_id: str | None = None) -> None:
@@ -145,7 +164,8 @@ def execute_drum(
145164

146165
def construct_prompt(chat_completion: str) -> CompletionCreateParamsBase:
147166
chat_completion_dict = json.loads(chat_completion)
148-
if "model" not in chat_completion_dict:
167+
model = chat_completion_dict.get("model")
168+
if model is None or len(str(model)) == 0:
149169
chat_completion_dict["model"] = "unknown"
150170
validator = TypeAdapter(CompletionCreateParamsBase)
151171
validator.validate_python(chat_completion_dict)
@@ -162,49 +182,54 @@ def store_result(result: ChatCompletion, output_path: Path) -> None:
162182

163183

164184
def main() -> Any:
165-
with open(DEFAULT_OUTPUT_LOG_PATH, "w") as f:
166-
sys.stdout = f
167-
sys.stderr = f
168-
print("Parsing args")
169-
args = argparse_args()
170-
171-
output_log_path = (
172-
Path(args.output_path + ".log") if args.output_path else DEFAULT_OUTPUT_LOG_PATH
173-
)
174-
with open(output_log_path, "a") as f:
175-
sys.stdout = f
176-
sys.stderr = f
177-
185+
# During failures logs will be dumped to the default output log path
186+
setup_logging(logger=root, log_level=logging.INFO)
187+
try:
188+
root.info("Parsing args")
178189
try:
179-
print("Setting up logging")
180-
setup_logging(logger=root, log_level=logging.INFO)
181-
root.info("Parsing args")
182-
183-
# Parse input to fail early if it's not valid
184-
chat_completion = construct_prompt(args.chat_completion)
185-
default_headers = json.loads(args.default_headers)
186-
root.info(f"Chat completion: {chat_completion}")
187-
root.info(f"Default headers: {default_headers}")
188-
189-
# Setup tracing
190-
print("Setting up tracing")
191-
setup_otlp_env_variables(args.otlp_entity_id)
192-
193-
root.info(f"Executing request in directory {args.custom_model_dir}")
194-
result = execute_drum(
195-
chat_completion=chat_completion,
196-
default_headers=default_headers,
197-
custom_model_dir=args.custom_model_dir,
190+
# Attempt to parse arguments and setup logging
191+
args = argparse_args()
192+
193+
root.info("Setting up logging")
194+
output_log_path = str(
195+
Path(args.output_path + ".log") if args.output_path else DEFAULT_OUTPUT_LOG_PATH
198196
)
199-
root.info(f"Result: {result}")
200-
store_result(
201-
result,
202-
Path(args.output_path) if args.output_path else DEFAULT_OUTPUT_JSON_PATH,
197+
setup_logging(
198+
logger=root,
199+
output_path=output_log_path,
200+
log_level=logging.INFO,
201+
update=True,
203202
)
204203
except Exception as e:
205-
root.exception(f"Error executing agent: {e}")
204+
root.exception(f"Error parsing arguments: {e}")
205+
sys.exit(1)
206+
207+
# Parse input to fail early if it's not valid
208+
chat_completion = construct_prompt(args.chat_completion)
209+
default_headers = json.loads(args.default_headers)
210+
root.info(f"Chat completion: {chat_completion}")
211+
root.info(f"Default headers: {default_headers}")
212+
213+
# Setup tracing
214+
root.info("Setting up tracing")
215+
setup_otlp_env_variables(args.otlp_entity_id)
216+
217+
root.info(f"Executing request in directory {args.custom_model_dir}")
218+
result = execute_drum(
219+
chat_completion=chat_completion,
220+
default_headers=default_headers,
221+
custom_model_dir=args.custom_model_dir,
222+
)
223+
root.info(f"Result: {result}")
224+
store_result(
225+
result,
226+
Path(args.output_path) if args.output_path else DEFAULT_OUTPUT_JSON_PATH,
227+
)
228+
except Exception as e:
229+
root.exception(f"Error executing agent: {e}")
206230

207231

232+
# Agent execution
208233
if __name__ == "__main__":
209234
stdout = sys.stdout
210235
stderr = sys.stderr

0 commit comments

Comments
 (0)