- adapters/README.md: the harness boundary contract (env in, response on stdout, diagnostics stderr, exit 0 success) - adapters/pi: extracted current invocation unchanged - adapters/mock: deterministic MOSAIC_MOCK_RESPONSE echo (test-only) - run-agent.sh: name-validated dispatch to adapters/<name>/adapter.sh - config: optional execution.adapter (pi|mock), default pi, configVersion stays 1 — existing configs remain valid; selection authority is the config file (load_config exports it) - compose: MOSAIC_ADAPTER / MOSAIC_MOCK_RESPONSE passthrough; Containerfile installs adapters read-only; RELEASE -> 0.0.5 Verified: hello unchanged; mock verbatim via config; unknown adapter and path-traversal names refused in-container; invalid adapter exits 2. Closes #16
34 lines
1.0 KiB
Bash
Executable File
34 lines
1.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# One-shot agent dispatcher inside the container.
|
|
#
|
|
# 1. Loads the contract-generated system prompt (contracts + optional
|
|
# mission section from MOSAIC_MISSION_FILE).
|
|
# 2. Dispatches to /opt/mosaic/adapters/<MOSAIC_ADAPTER>/adapter.sh per
|
|
# the contract in /opt/mosaic/adapters/README.md.
|
|
set -eu
|
|
|
|
REQUEST="${*:-Return your startup marker and nothing else.}"
|
|
|
|
ADAPTER="${MOSAIC_ADAPTER:-pi}"
|
|
case "$ADAPTER" in
|
|
# Allowlist mirrors scripts/mosaic-config.mjs; pattern check first so a
|
|
# crafted name cannot escape the adapters directory.
|
|
*[!A-Za-z0-9._-]*|'')
|
|
echo "run-agent: invalid adapter name: '$ADAPTER'" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
ADAPTER_SCRIPT="/opt/mosaic/adapters/$ADAPTER/adapter.sh"
|
|
if [ ! -x "$ADAPTER_SCRIPT" ]; then
|
|
echo "run-agent: unknown or non-executable adapter: $ADAPTER" >&2
|
|
exit 2
|
|
fi
|
|
|
|
/opt/mosaic/src/load-contracts.sh /opt/mosaic/contracts /var/lib/mosaic/system-prompt.md
|
|
|
|
export MOSAIC_SYSTEM_PROMPT_FILE="/var/lib/mosaic/system-prompt.md"
|
|
export MOSAIC_REQUEST="$REQUEST"
|
|
|
|
exec "$ADAPTER_SCRIPT"
|