This commit is contained in:
Carl Niklas Rydberg 2026-02-08 09:55:01 +01:00
parent 2f393701fe
commit b450e65453
3 changed files with 73 additions and 31 deletions

View file

@ -74,7 +74,7 @@ AI lane notes:
- Plan and scope guardrails: `docs/ai-plan.md`
- Deterministic seed payload: `ai/fixtures/seed_batch.json`
- Agent loop checkpoints: `ai/runs/agent-run-*.json`
- Agent loop checkpoints: `ai/runs/agent-run-*.json` (updated at start, each planner step, and completion with `status` + timestamps)
Run integration coverage (requires running `amduatd` + `jq`):

View file

@ -70,6 +70,65 @@ append_step() {
steps_json="$(jq -c --argjson step "${step_json}" '. + [$step]' <<<"${steps_json}")"
}
write_run_state() {
local status="$1"
local stop_reason_value="$2"
local final_answer_value="$3"
local now_iso
now_iso="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
local completed_at=""
if [[ "${status}" == "completed" ]]; then
completed_at="${now_iso}"
fi
local run_json_local
run_json_local="$(jq -nc \
--arg run_id "${run_id}" \
--arg started_at "${started_at}" \
--arg updated_at "${now_iso}" \
--arg completed_at "${completed_at}" \
--arg status "${status}" \
--arg question "${question}" \
--arg initial_roots_csv "${initial_roots_csv}" \
--arg initial_goals_csv "${initial_goals_csv}" \
--arg final_roots_csv "${roots_csv}" \
--arg final_goals_csv "${goals_csv}" \
--arg stop_reason "${stop_reason_value}" \
--argjson current_step "${step_no}" \
--argjson max_steps "${max_steps}" \
--argjson require_evidence "$( [[ "${require_evidence}" == "1" ]] && echo true || echo false )" \
--argjson steps "${steps_json}" \
--argjson final_answer "${final_answer_value}" \
'{
run_id:$run_id,
status:$status,
started_at:$started_at,
updated_at:$updated_at,
completed_at:(if $completed_at == "" then null else $completed_at end),
input:{
question:$question,
roots_csv:$initial_roots_csv,
goals_csv:$initial_goals_csv,
require_evidence:$require_evidence
},
planner:{
current_step:$current_step,
max_steps:$max_steps
},
final_query:{
roots_csv:$final_roots_csv,
goals_csv:$final_goals_csv
},
stop_reason:$stop_reason,
steps:$steps,
final_answer:$final_answer
}')"
printf '%s\n' "${run_json_local}" > "${state_file}"
RUN_JSON="${run_json_local}"
}
extract_plan_json() {
local model_out="$1"
local raw_plan
@ -203,6 +262,7 @@ app_init
ensure_daemon_ready
run_id="$(date +%Y%m%d-%H%M%S)-$$"
started_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
if [[ -z "${state_file}" ]]; then
mkdir -p "${ROOT_DIR}/ai/runs"
state_file="${ROOT_DIR}/ai/runs/agent-run-${run_id}.json"
@ -211,11 +271,16 @@ fi
steps_json="[]"
final_answer_json=""
stop_reason="max_steps_reached"
initial_roots_csv="${roots_csv}"
initial_goals_csv="${goals_csv}"
RUN_JSON=""
step_no=1
write_run_state "running" "${stop_reason}" "null"
while (( step_no <= max_steps )); do
retrieve_out="$(app_retrieve_with_fallback "${roots_csv}" "${goals_csv}")" || {
stop_reason="retrieve_failed"
write_run_state "running" "${stop_reason}" "null"
break
}
context_stats="$(jq -c '{nodes:(.nodes // [] | length), edges:(.edges // [] | length)}' <<<"${retrieve_out}")"
@ -233,6 +298,7 @@ while (( step_no <= max_steps )); do
--argjson plan "${plan_json}" \
'{step:$step,roots_csv:$roots_csv,goals_csv:$goals_csv,context:$context,plan:$plan}')"
append_step "${step_record}"
write_run_state "running" "${stop_reason}" "null"
if [[ "${plan_action}" == "refine_query" ]]; then
if [[ -n "${next_roots}" ]]; then
@ -247,15 +313,18 @@ while (( step_no <= max_steps )); do
if [[ "${plan_action}" == "stop" ]]; then
stop_reason="planner_stop"
write_run_state "running" "${stop_reason}" "null"
break
fi
if final_answer_json="$(app_ai_answer_json "${roots_csv}" "${question}" "${goals_csv}" "${require_evidence}")"; then
stop_reason="answered"
write_run_state "running" "${stop_reason}" "${final_answer_json}"
break
fi
stop_reason="answer_failed"
write_run_state "running" "${stop_reason}" "null"
break
done
@ -263,35 +332,8 @@ if [[ -z "${final_answer_json}" ]]; then
final_answer_json="$(jq -nc --arg msg "Agent loop ended without answer (${stop_reason})." '{response:$msg,done_reason:"agent_stopped"}')"
fi
run_json="$(jq -nc \
--arg run_id "${run_id}" \
--arg question "${question}" \
--arg initial_roots_csv "$1" \
--arg initial_goals_csv "${3:-}" \
--arg final_roots_csv "${roots_csv}" \
--arg final_goals_csv "${goals_csv}" \
--arg stop_reason "${stop_reason}" \
--argjson require_evidence "$( [[ "${require_evidence}" == "1" ]] && echo true || echo false )" \
--argjson steps "${steps_json}" \
--argjson final_answer "${final_answer_json}" \
'{
run_id:$run_id,
input:{
question:$question,
roots_csv:$initial_roots_csv,
goals_csv:$initial_goals_csv,
require_evidence:$require_evidence
},
final_query:{
roots_csv:$final_roots_csv,
goals_csv:$final_goals_csv
},
stop_reason:$stop_reason,
steps:$steps,
final_answer:$final_answer
}')"
printf '%s\n' "${run_json}" > "${state_file}"
write_run_state "completed" "${stop_reason}" "${final_answer_json}"
run_json="${RUN_JSON}"
if [[ "${output_mode}" == "json" ]]; then
printf '%s\n' "${run_json}"

2
vendor/amduat-api vendored

@ -1 +1 @@
Subproject commit 4fa7c321174fc4021fc1bc23a9a8d414b3ba2ec8
Subproject commit 0ae2c8d74a85bbcb633e711fb1cf84d0516bdc3b