#!/usr/bin/env bash # tools/today/propose.sh # # Orchestrates: collect → System-AI → write candidate YAML files. # Defaults to a local Ollama at 127.0.0.1:11434 with gemma3:4b. # See README.md for env-var overrides. # # Output: ~/.fai/today/proposals//candidate-.yaml # Operator then runs accept.sh with the chosen file. set -euo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" DATE="$(date -u +%Y-%m-%d)" OUT_DIR="${FAI_TODAY_OUT:-$HOME/.fai/today/proposals/$DATE}" N="${FAI_TODAY_N:-3}" API="${FAI_TODAY_API:-http://127.0.0.1:11434/api/generate}" MODEL="${FAI_TODAY_MODEL:-gemma3:4b}" KEY="${FAI_TODAY_KEY:-}" mkdir -p "$OUT_DIR" signals="$("$HERE/collect.sh")" template="$(cat "$HERE/prompt.template.md")" prompt="${template//\{\{SIGNAL_INPUT\}\}/$signals}" call_ollama() { # Streaming off, single completion. The /api/generate endpoint # returns one big JSON; we extract `.response`. jq -n --arg model "$MODEL" --arg prompt "$prompt" \ '{model: $model, prompt: $prompt, stream: false}' \ | curl -fsS -X POST -H 'Content-Type: application/json' \ --data-binary @- "$API" \ | jq -r '.response' } call_openai_compatible() { local body body=$(jq -n --arg model "$MODEL" --arg prompt "$prompt" '{ model: $model, messages: [{role: "user", content: $prompt}], temperature: 0.6 }') local hdr_args=() if [ -n "$KEY" ]; then hdr_args=(-H "Authorization: Bearer $KEY") fi printf '%s' "$body" \ | curl -fsS -X POST -H 'Content-Type: application/json' \ "${hdr_args[@]}" --data-binary @- "$API" \ | jq -r '.choices[0].message.content' } draft_one() { case "$API" in *"/generate"*) call_ollama ;; *"/chat/completions"*) call_openai_compatible ;; *) printf 'unknown API path in %s — aborting\n' "$API" >&2 exit 2 ;; esac } # Strip ```yaml fences if the model adds them despite the prompt. clean_yaml() { sed -e '/^```yaml$/d' -e '/^```$/d' -e 's/^```$//' } for n in $(seq 1 "$N"); do out="$OUT_DIR/candidate-$n.yaml" printf 'Drafting candidate %d/%d via %s (%s)…\n' "$n" "$N" "$API" "$MODEL" draft_one | clean_yaml > "$out" printf ' → %s (%d bytes)\n' "$out" "$(wc -c < "$out")" done printf '\nDone. Skim with:\n ls -la %s\n for f in %s/*.yaml; do echo "=== $f ==="; cat "$f"; done\n' \ "$OUT_DIR" "$OUT_DIR" printf '\nAccept with:\n %s/accept.sh \n' "$HERE"