ia_dev/ai_working_help/notary-ai/write-response-notary-ai.sh
Nicolas Cantu 61cec6f430 Sync ia_dev: token resolution via .secrets/<env>/ia_token, doc updates
**Motivations:**
- Align master with current codebase (token from projects/<id>/.secrets/<env>/ia_token)
- Id resolution by mail To or by API token; no slug

**Root causes:**
- Token moved from conf.json to .secrets/<env>/ia_token; env from directory name

**Correctifs:**
- Server and scripts resolve project+env by scanning all projects and envs

**Evolutions:**
- tickets-fetch-inbox routes by To address; notary-ai agents and API doc updated

**Pages affectées:**
- ai_working_help/server.js, docs, project_config.py, lib/project_config.sh
- projects/README.md, lecoffreio/docs/API.md, gitea-issues/tickets-fetch-inbox.py
2026-03-16 15:00:23 +01:00

82 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Write agent response to responded/ and remove the pending file.
# Usage:
# --pending-path <path> --response-json <json_string>
# or --request-uid <uid> --answer "..." [--next-actions-table "..." ] [--members-info-sheet "..."] [--synthesis-recommendation "..."]
set -euo pipefail
NOTARY_AI_DIR="${NOTARY_AI_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
export NOTARY_AI_DIR
ROOT="$(cd "${NOTARY_AI_DIR}/../../.." && pwd)"
cd "$ROOT"
# shellcheck source=lib.sh
source "${NOTARY_AI_DIR}/lib.sh"
if [[ -z "${DATA_NOTARY_AI_RESPONDED_DIR:-}" || ! -d "${DATA_NOTARY_AI_RESPONDED_DIR}" ]]; then
echo "[notary-ai] DATA_NOTARY_AI_RESPONDED_DIR not set or not a directory." >&2
exit 1
fi
require_jq() {
command -v jq &>/dev/null || { echo "[notary-ai] jq is required." >&2; return 1; }
}
PENDING_PATH=""
RESPONSE_JSON=""
REQUEST_UID=""
ANSWER=""
NEXT_ACTIONS_TABLE=""
MEMBERS_INFO_SHEET=""
SYNTHESIS_RECOMMENDATION=""
while [[ $# -gt 0 ]]; do
case "$1" in
--pending-path) PENDING_PATH="$2"; shift 2 ;;
--response-json) RESPONSE_JSON="$2"; shift 2 ;;
--request-uid) REQUEST_UID="$2"; shift 2 ;;
--answer) ANSWER="$2"; shift 2 ;;
--next-actions-table) NEXT_ACTIONS_TABLE="$2"; shift 2 ;;
--members-info-sheet) MEMBERS_INFO_SHEET="$2"; shift 2 ;;
--synthesis-recommendation) SYNTHESIS_RECOMMENDATION="$2"; shift 2 ;;
*) echo "[notary-ai] Unknown option: $1" >&2; exit 1 ;;
esac
done
if [[ -n "${PENDING_PATH:-}" && -n "${RESPONSE_JSON:-}" ]]; then
require_jq || exit 1
[[ -f "$PENDING_PATH" ]] || { echo "[notary-ai] Pending file not found: $PENDING_PATH" >&2; exit 1; }
BASE="$(basename "$PENDING_PATH" .json)"
RESPONDED_PATH="${DATA_NOTARY_AI_RESPONDED_DIR}/${BASE}.json"
PENDING_DATA="$(jq -c . "$PENDING_PATH")"
RESPONSE_OBJ="$(printf '%s' "$RESPONSE_JSON" | jq -c .)"
# Merge: pending payload + status responded + response object
printf '%s' "$PENDING_DATA" | jq -c --argjson resp "$RESPONSE_OBJ" '. + { status: "responded", response: $resp }' > "${RESPONDED_PATH}"
rm -f "$PENDING_PATH"
echo "[notary-ai] Wrote ${RESPONDED_PATH}, removed pending."
exit 0
fi
if [[ -n "${REQUEST_UID:-}" && -n "${ANSWER:-}" ]]; then
require_jq || exit 1
# Find pending file containing this request_uid
FOUND=""
for f in "${DATA_NOTARY_AI_PENDING_DIR}"/*.json; do
[[ -f "$f" ]] || continue
if [[ "$(jq -r '.request_uid // ""' "$f")" = "$REQUEST_UID" ]]; then
FOUND="$f"
break
fi
done
[[ -n "$FOUND" ]] || { echo "[notary-ai] No pending file with request_uid=$REQUEST_UID" >&2; exit 1; }
RESPONSE_OBJ=$(jq -n \
--arg a "$ANSWER" \
--arg nat "${NEXT_ACTIONS_TABLE:-}" \
--arg mis "${MEMBERS_INFO_SHEET:-}" \
--arg sr "${SYNTHESIS_RECOMMENDATION:-}" \
'{ answer: $a, nextActionsTable: $nat, membersInfoSheet: $mis, synthesisRecommendation: $sr }')
PENDING_PATH="$FOUND"
RESPONSE_JSON="$RESPONSE_OBJ"
BASE="$(basename "$PENDING_PATH" .json)"
RESPONDED_PATH="${DATA_NOTARY_AI_RESPONDED_DIR}/${BASE}.json"
PENDING_DATA="$(jq -c . "$PENDING_PATH")"
printf '%s' "$PENDING_DATA" | jq -c --argjson resp "$RESPONSE_OBJ" '. + { status: "responded", response: $resp }' > "${RESPONDED_PATH}"
rm -f "$PENDING_PATH"
echo "[notary-ai] Wrote ${RESPONDED_PATH}, removed pending."
exit 0
fi
echo "[notary-ai] Use --pending-path + --response-json or --request-uid + --answer (and optional fields)." >&2
exit 1