35e5781e66
Public can_adopt follows session_outcome; reverse_verify reuses the persisted question id; offer cards settle on the owning message with a status-bar handoff. Co-authored-by: Cursor <cursoragent@cursor.com>
171 lines
5.6 KiB
PL/PgSQL
171 lines
5.6 KiB
PL/PgSQL
-- Expose per-tool started_at / elapsed_ms / failure reason on turn receipts.
|
|
-- Timing is derived from the started row vs the terminal row; no new columns.
|
|
|
|
begin;
|
|
|
|
create or replace function public.get_agentic_rectification_turn_receipt(
|
|
p_user_id uuid,
|
|
p_case_id uuid,
|
|
p_turn_id uuid
|
|
)
|
|
returns jsonb
|
|
language plpgsql
|
|
security definer
|
|
set search_path = ''
|
|
as $$
|
|
declare
|
|
v_turn public.agentic_rectification_turns%rowtype;
|
|
v_case public.agentic_rectification_cases%rowtype;
|
|
v_attempt_id uuid;
|
|
v_phases jsonb;
|
|
v_tool_activities jsonb;
|
|
v_tools jsonb;
|
|
v_methods jsonb;
|
|
v_engine_version text;
|
|
begin
|
|
if p_user_id is null or p_case_id is null or p_turn_id is null then
|
|
raise exception 'agentic_rectification_invalid_input' using errcode = 'P0001';
|
|
end if;
|
|
select * into v_case
|
|
from public.agentic_rectification_cases
|
|
where id = p_case_id and user_id = p_user_id;
|
|
if not found then
|
|
raise exception 'agentic_rectification_case_not_found' using errcode = 'P0001';
|
|
end if;
|
|
select * into v_turn
|
|
from public.agentic_rectification_turns
|
|
where id = p_turn_id and case_id = p_case_id;
|
|
if not found then
|
|
raise exception 'agentic_rectification_turn_not_found' using errcode = 'P0001';
|
|
end if;
|
|
|
|
v_attempt_id := v_turn.successful_attempt_id;
|
|
if v_attempt_id is null then
|
|
select id into v_attempt_id
|
|
from public.agentic_rectification_run_attempts
|
|
where turn_id = p_turn_id
|
|
order by attempt_number desc
|
|
limit 1;
|
|
end if;
|
|
|
|
select coalesce(jsonb_agg(
|
|
jsonb_build_object('phase', rp.phase, 'tool', rp.tool_name)
|
|
order by rp.sequence, rp.created_at, rp.id
|
|
), '[]'::jsonb) into v_phases
|
|
from public.agentic_rectification_run_phases rp
|
|
where rp.turn_id = p_turn_id
|
|
and (
|
|
(v_attempt_id is not null and rp.attempt_id = v_attempt_id)
|
|
or (v_attempt_id is null and rp.attempt_id is null)
|
|
);
|
|
|
|
with latest_terminal as materialized (
|
|
select distinct on (tr.tool_name)
|
|
tr.id,
|
|
tr.tool_name,
|
|
tr.status,
|
|
tr.executed_methods,
|
|
tr.started_at,
|
|
tr.safe_error_code,
|
|
tr.result_fingerprint
|
|
from public.agentic_rectification_tool_receipts tr
|
|
where tr.turn_id = p_turn_id
|
|
and tr.status in ('completed', 'failed')
|
|
and (
|
|
(v_attempt_id is not null and tr.attempt_id = v_attempt_id)
|
|
or (v_attempt_id is null and tr.attempt_id is null)
|
|
)
|
|
order by tr.tool_name, tr.started_at desc, tr.id desc
|
|
),
|
|
latest_started as materialized (
|
|
select distinct on (tr.tool_name)
|
|
tr.tool_name,
|
|
tr.started_at
|
|
from public.agentic_rectification_tool_receipts tr
|
|
where tr.turn_id = p_turn_id
|
|
and tr.status = 'started'
|
|
and (
|
|
(v_attempt_id is not null and tr.attempt_id = v_attempt_id)
|
|
or (v_attempt_id is null and tr.attempt_id is null)
|
|
)
|
|
order by tr.tool_name, tr.started_at desc, tr.id desc
|
|
)
|
|
select
|
|
coalesce(jsonb_agg(
|
|
jsonb_strip_nulls(jsonb_build_object(
|
|
'tool', terminal.tool_name,
|
|
'status', terminal.status,
|
|
'methods', case
|
|
when terminal.status = 'completed' then terminal.executed_methods
|
|
else '[]'::jsonb
|
|
end,
|
|
'started_at', coalesce(started.started_at, terminal.started_at),
|
|
'elapsed_ms', greatest(
|
|
0,
|
|
(extract(epoch from (
|
|
terminal.started_at - coalesce(started.started_at, terminal.started_at)
|
|
)) * 1000)::int
|
|
),
|
|
'error', terminal.safe_error_code,
|
|
'result_fingerprint', terminal.result_fingerprint
|
|
)) order by coalesce(started.started_at, terminal.started_at), terminal.id
|
|
), '[]'::jsonb),
|
|
coalesce(jsonb_agg(terminal.tool_name order by coalesce(started.started_at, terminal.started_at), terminal.id)
|
|
filter (where terminal.status = 'completed'), '[]'::jsonb)
|
|
into v_tool_activities, v_tools
|
|
from latest_terminal terminal
|
|
left join latest_started started on started.tool_name = terminal.tool_name;
|
|
|
|
with latest_terminal as materialized (
|
|
select distinct on (tr.tool_name)
|
|
tr.tool_name,
|
|
tr.status,
|
|
tr.executed_methods
|
|
from public.agentic_rectification_tool_receipts tr
|
|
where tr.turn_id = p_turn_id
|
|
and tr.status in ('completed', 'failed')
|
|
and (
|
|
(v_attempt_id is not null and tr.attempt_id = v_attempt_id)
|
|
or (v_attempt_id is null and tr.attempt_id is null)
|
|
)
|
|
order by tr.tool_name, tr.started_at desc, tr.id desc
|
|
)
|
|
select coalesce(jsonb_agg(method order by method), '[]'::jsonb) into v_methods
|
|
from (
|
|
select distinct jsonb_array_elements_text(terminal.executed_methods) as method
|
|
from latest_terminal terminal
|
|
where terminal.status = 'completed'
|
|
) methods;
|
|
|
|
select max(tr.engine_version) into v_engine_version
|
|
from public.agentic_rectification_tool_receipts tr
|
|
where tr.turn_id = p_turn_id and tr.engine_version is not null
|
|
and (
|
|
(v_attempt_id is not null and tr.attempt_id = v_attempt_id)
|
|
or (v_attempt_id is null and tr.attempt_id is null)
|
|
);
|
|
|
|
return jsonb_build_object(
|
|
'turn_id', v_turn.id,
|
|
'attempt_id', v_attempt_id,
|
|
'status', v_turn.status,
|
|
'skill_name', v_case.skill_name,
|
|
'skill_version', v_case.skill_version,
|
|
'engine_version', v_engine_version,
|
|
'phases', v_phases,
|
|
'tool_activities', v_tool_activities,
|
|
'tools', v_tools,
|
|
'methods', v_methods,
|
|
'started_at', v_turn.created_at,
|
|
'completed_at', v_turn.completed_at
|
|
);
|
|
end;
|
|
$$;
|
|
|
|
revoke all on function public.get_agentic_rectification_turn_receipt(uuid, uuid, uuid)
|
|
from public, anon, authenticated;
|
|
grant execute on function public.get_agentic_rectification_turn_receipt(uuid, uuid, uuid)
|
|
to service_role;
|
|
|
|
commit;
|