document_redaction / agent-redact /agentcore /harness_input_bridge.py
seanpedrickcase's picture
Sync: Fixes on certain review buttons removing visible redaction boxes on review tab
517919c
Raw
History Blame Contribute Delete
4.03 kB
"""Upload task inputs for AgentCore Harness (S3 + presigned URL prompt prefix)."""
from __future__ import annotations
import os
from pathlib import Path
from urllib.parse import urlparse
from session_workspace import session_workspace_dir
def _parse_s3_uri(uri: str) -> tuple[str, str]:
parsed = urlparse((uri or "").strip())
if parsed.scheme != "s3" or not parsed.netloc:
raise ValueError(f"Invalid S3 URI: {uri!r}")
prefix = (parsed.path or "").lstrip("/")
if prefix and not prefix.endswith("/"):
prefix += "/"
return parsed.netloc, prefix
def harness_s3_input_uri(session_hash: str, file_name: str) -> tuple[str, str, str]:
"""
Return ``(bucket, key, s3_uri)`` for a harness input object.
Uses ``AGENTCORE_HARNESS_S3_INPUT_PREFIX`` (``s3://bucket/prefix/``) when set,
otherwise ``s3://{S3_OUTPUTS_BUCKET}/harness-inputs/{session_hash}/``.
"""
explicit = (os.environ.get("AGENTCORE_HARNESS_S3_INPUT_PREFIX") or "").strip()
if explicit:
bucket, prefix = _parse_s3_uri(explicit)
else:
bucket = (os.environ.get("S3_OUTPUTS_BUCKET") or "").strip()
if not bucket:
raise ValueError(
"Set AGENTCORE_HARNESS_S3_INPUT_PREFIX or S3_OUTPUTS_BUCKET for harness file upload."
)
safe_session = (session_hash or "default").strip().replace("/", "_")[:128]
prefix = f"harness-inputs/{safe_session}/"
key = f"{prefix}{Path(file_name).name}"
return bucket, key, f"s3://{bucket}/{key}"
def build_harness_document_prompt_prefix(
session_hash: str,
document_name: str,
) -> str | None:
"""
Upload the task PDF to S3 and return a prompt prefix for the Harness to fetch it.
Returns ``None`` when upload is disabled or the file is missing.
"""
if not document_name:
return None
run_aws = (os.environ.get("RUN_AWS_FUNCTIONS") or "").strip().lower() in {
"1",
"true",
"yes",
"on",
}
if (
not run_aws
and not (os.environ.get("AGENTCORE_HARNESS_S3_INPUT_PREFIX") or "").strip()
):
return (
"**Harness file bridge:** RUN_AWS_FUNCTIONS is off and "
"AGENTCORE_HARNESS_S3_INPUT_PREFIX is unset — upload the document to the Harness "
"workspace manually or enable S3 upload."
)
root = session_workspace_dir(session_hash)
src = root / document_name
if not src.is_file():
return None
try:
import boto3
from botocore.exceptions import BotoCoreError, ClientError
from pi_agent_config import configure_aws_credentials
configure_aws_credentials()
bucket, key, s3_uri = harness_s3_input_uri(session_hash, document_name)
region = (
os.environ.get("AWS_REGION")
or os.environ.get("AWS_DEFAULT_REGION")
or "eu-west-2"
)
client = boto3.client("s3", region_name=region)
client.upload_file(str(src), bucket, key)
presigned = client.generate_presigned_url(
"get_object",
Params={"Bucket": bucket, "Key": key},
ExpiresIn=int(os.environ.get("AGENTCORE_HARNESS_PRESIGN_SECONDS", "3600")),
)
except (BotoCoreError, ClientError, ValueError, OSError) as exc:
return (
f"**Harness file bridge error:** Could not upload `{document_name}` to S3 ({exc}). "
"Place the file on the Harness workspace mount or fix AWS permissions."
)
mount_path = (
os.environ.get("AGENTCORE_HARNESS_S3_MOUNT_PATH") or "/tmp/workspace"
).rstrip("/")
dest = f"{mount_path}/{Path(document_name).name}"
return (
f"**Harness input file (download before Pass 1):**\n"
f"- S3 object: `{s3_uri}`\n"
f"- Presigned URL (expires in 1h): {presigned}\n"
f"- Save to Harness workspace as: `{dest}`\n"
f"- Example: `curl -fsSL -o {dest!r} '<presigned-url>'` then use `{dest}` as INPUT_PATH.\n"
)