#!/usr/bin/env bash set -euo pipefail # shellcheck source=/dev/null source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/amduat_v2_client.sh" app_init() { amduat_client_init } app_startup_checks() { amduat_api_call GET "/v2/readyz" || return 1 printf '%s\n' "${AMDUAT_LAST_BODY}" amduat_api_call GET "/v2/graph/capabilities" || return 1 printf '%s\n' "${AMDUAT_LAST_BODY}" } app_ingest_batch() { local payload="$1" amduat_api_call POST "/v2/graph/batch" "${payload}" printf '%s\n' "${AMDUAT_LAST_BODY}" } app_sync_once() { local path="/v2/graph/changes?limit=${SYNC_LIMIT}&wait_ms=${SYNC_WAIT_MS}" local cursor="" if [[ -f "${CURSOR_FILE}" ]]; then cursor="$(cat "${CURSOR_FILE}")" fi if [[ -n "${cursor}" ]]; then path+="&since_cursor=${cursor}" fi if ! amduat_api_call GET "${path}"; then if [[ "${AMDUAT_LAST_STATUS}" == "410" ]]; then rm -f "${CURSOR_FILE}" echo "changes cursor expired (410); cleared ${CURSOR_FILE}" >&2 return 0 fi return 1 fi printf '%s\n' "${AMDUAT_LAST_BODY}" local next next="$(printf '%s\n' "${AMDUAT_LAST_BODY}" | sed -n 's/.*"next_cursor"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')" if [[ -n "${next}" ]]; then printf '%s' "${next}" > "${CURSOR_FILE}" fi } app_sync_loop() { local root_dir root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" echo "app_sync_loop is deprecated; use scripts/changes_consumer.sh" >&2 "${root_dir}/scripts/changes_consumer.sh" } app_retrieve_with_fallback() { local roots_csv="$1" local goals_csv="${2:-}" local roots_json roots_json="$(printf '%s' "${roots_csv}" | awk -F',' 'BEGIN{printf "["} {for(i=1;i<=NF;i++){gsub(/^ +| +$/, "", $i); if (length($i)>0){if (printed) printf ","; printf "\"%s\"", $i; printed=1}}} END{printf "]"}')" local goals_json="[]" if [[ -n "${goals_csv}" ]]; then goals_json="$(printf '%s' "${goals_csv}" | awk -F',' 'BEGIN{printf "["} {for(i=1;i<=NF;i++){gsub(/^ +| +$/, "", $i); if (length($i)>0){if (printed) printf ","; printf "\"%s\"", $i; printed=1}}} END{printf "]"}')" fi local payload payload="{\"roots\":${roots_json},\"goal_predicates\":${goals_json},\"max_depth\":2,\"max_fanout\":256,\"limit_nodes\":200,\"limit_edges\":400,\"max_result_bytes\":1048576}" if amduat_api_call POST "/v2/graph/retrieve" "${payload}"; then printf '%s\n' "${AMDUAT_LAST_BODY}" return 0 fi local first_root first_root="$(printf '%s' "${roots_csv}" | awk -F',' '{gsub(/^ +| +$/, "", $1); printf "%s", $1}')" local fallback_path="/v2/graph/subgraph?roots[]=${first_root}&max_depth=2&dir=outgoing&limit_nodes=200&limit_edges=400&max_result_bytes=1048576" if [[ -n "${goals_csv}" ]]; then local first_goal first_goal="$(printf '%s' "${goals_csv}" | awk -F',' '{gsub(/^ +| +$/, "", $1); printf "%s", $1}')" if [[ -n "${first_goal}" ]]; then fallback_path+="&predicates[]=${first_goal}" fi fi amduat_api_call GET "${fallback_path}" printf '%s\n' "${AMDUAT_LAST_BODY}" } app_tombstone_edge() { local edge_ref="$1" local payload payload="{\"edge_ref\":\"${edge_ref}\"}" amduat_api_call POST "/v2/graph/edges/tombstone" "${payload}" printf '%s\n' "${AMDUAT_LAST_BODY}" }