fix(web): isolate rectification answers from tool-step planning text
Mastra intermediate text-delta was published as answer.delta, then set-focus domain errors reset the attempt and replayed evidence. Publish only the terminal no-tool step, persist the next probe on the server, and ground batch quotes in the source turn. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
-- User-turn origin for birth-time rectification.
|
||||
-- Typed, choice, suggestion, voice, retry, and recovery writes must be
|
||||
-- distinguishable when a later transcript contains a year the engine never
|
||||
-- produced. Business schema only; do not copy into frontend/db/migrations
|
||||
-- (BUG-127 / BUG-144).
|
||||
|
||||
begin;
|
||||
|
||||
alter table public.agentic_rectification_turns
|
||||
add column if not exists message_origin text;
|
||||
|
||||
alter table public.agentic_rectification_turns
|
||||
add column if not exists client_action_id uuid;
|
||||
|
||||
alter table public.agentic_rectification_turns
|
||||
add column if not exists content_hash text;
|
||||
|
||||
do $$
|
||||
begin
|
||||
if not exists (
|
||||
select 1
|
||||
from pg_constraint
|
||||
where conname = 'agentic_rectification_turns_message_origin_check'
|
||||
and conrelid = 'public.agentic_rectification_turns'::regclass
|
||||
) then
|
||||
alter table public.agentic_rectification_turns
|
||||
add constraint agentic_rectification_turns_message_origin_check
|
||||
check (
|
||||
message_origin is null
|
||||
or message_origin in (
|
||||
'typed',
|
||||
'suggestion_click',
|
||||
'choice_click',
|
||||
'voice_input',
|
||||
'retry_replay',
|
||||
'system_recovery'
|
||||
)
|
||||
);
|
||||
end if;
|
||||
end;
|
||||
$$;
|
||||
|
||||
create unique index if not exists agentic_rectification_turns_case_client_action_uidx
|
||||
on public.agentic_rectification_turns (case_id, client_action_id)
|
||||
where client_action_id is not null;
|
||||
|
||||
create or replace function public.record_agentic_rectification_turn_origin(
|
||||
p_user_id uuid,
|
||||
p_case_id uuid,
|
||||
p_turn_id uuid,
|
||||
p_origin text,
|
||||
p_client_action_id uuid,
|
||||
p_content_hash text
|
||||
)
|
||||
returns jsonb
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = ''
|
||||
as $$
|
||||
declare
|
||||
v_case public.agentic_rectification_cases%rowtype;
|
||||
v_turn public.agentic_rectification_turns%rowtype;
|
||||
begin
|
||||
if p_user_id is null or p_case_id is null or p_turn_id is null
|
||||
or p_origin not in (
|
||||
'typed',
|
||||
'suggestion_click',
|
||||
'choice_click',
|
||||
'voice_input',
|
||||
'retry_replay',
|
||||
'system_recovery'
|
||||
) 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
|
||||
for update;
|
||||
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
|
||||
for update;
|
||||
if not found then
|
||||
raise exception 'agentic_rectification_turn_not_found' using errcode = 'P0001';
|
||||
end if;
|
||||
|
||||
if v_turn.message_origin is not null then
|
||||
if v_turn.message_origin is distinct from p_origin
|
||||
or v_turn.client_action_id is distinct from p_client_action_id
|
||||
or v_turn.content_hash is distinct from p_content_hash then
|
||||
raise exception 'agentic_rectification_request_mismatch' using errcode = 'P0001';
|
||||
end if;
|
||||
return jsonb_build_object(
|
||||
'turn_id', v_turn.id,
|
||||
'origin', v_turn.message_origin,
|
||||
'client_action_id', v_turn.client_action_id,
|
||||
'content_hash', v_turn.content_hash,
|
||||
'idempotent', true
|
||||
);
|
||||
end if;
|
||||
|
||||
update public.agentic_rectification_turns
|
||||
set message_origin = p_origin,
|
||||
client_action_id = p_client_action_id,
|
||||
content_hash = p_content_hash,
|
||||
updated_at = pg_catalog.now()
|
||||
where id = p_turn_id;
|
||||
|
||||
return jsonb_build_object(
|
||||
'turn_id', p_turn_id,
|
||||
'origin', p_origin,
|
||||
'client_action_id', p_client_action_id,
|
||||
'content_hash', p_content_hash,
|
||||
'idempotent', false
|
||||
);
|
||||
end;
|
||||
$$;
|
||||
|
||||
revoke all on function public.record_agentic_rectification_turn_origin(
|
||||
uuid, uuid, uuid, text, uuid, text
|
||||
) from public, anon, authenticated;
|
||||
grant execute on function public.record_agentic_rectification_turn_origin(
|
||||
uuid, uuid, uuid, text, uuid, text
|
||||
) to service_role;
|
||||
|
||||
commit;
|
||||
Reference in New Issue
Block a user